]> git.lizzy.rs Git - rust.git/commitdiff
rollup merge of #18407 : thestinger/arena
authorAlex Crichton <alex@alexcrichton.com>
Thu, 30 Oct 2014 15:57:30 +0000 (08:57 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Thu, 30 Oct 2014 16:29:23 +0000 (09:29 -0700)
672 files changed:
.mailmap
configure
mk/cfg/arm-apple-ios [new file with mode: 0644]
mk/cfg/arm-linux-androideabi [new file with mode: 0644]
mk/cfg/arm-unknown-linux-gnueabi [new file with mode: 0644]
mk/cfg/arm-unknown-linux-gnueabihf [new file with mode: 0644]
mk/cfg/i386-apple-ios [new file with mode: 0644]
mk/cfg/i586-mingw32msvc [new file with mode: 0644]
mk/cfg/i686-apple-darwin [new file with mode: 0644]
mk/cfg/i686-unknown-linux-gnu [new file with mode: 0644]
mk/cfg/i686-w64-mingw32 [new file with mode: 0644]
mk/cfg/mips-unknown-linux-gnu [new file with mode: 0644]
mk/cfg/mipsel-linux [new file with mode: 0644]
mk/cfg/x86_64-apple-darwin [new file with mode: 0644]
mk/cfg/x86_64-unknown-dragonfly [new file with mode: 0644]
mk/cfg/x86_64-unknown-freebsd [new file with mode: 0644]
mk/cfg/x86_64-unknown-linux-gnu [new file with mode: 0644]
mk/cfg/x86_64-w64-mingw32 [new file with mode: 0644]
mk/docs.mk
mk/llvm.mk
mk/main.mk
mk/platform.mk
mk/tests.mk
src/compiletest/compiletest.rs
src/compiletest/header.rs
src/compiletest/runtest.rs
src/compiletest/util.rs
src/doc/complement-design-faq.md
src/doc/complement-lang-faq.md
src/doc/guide-crates.md
src/doc/guide-ffi.md
src/doc/guide-lifetimes.md
src/doc/guide-macros.md
src/doc/guide-plugin.md
src/doc/guide-pointers.md
src/doc/guide-strings.md
src/doc/guide-tasks.md
src/doc/guide-testing.md
src/doc/guide-unsafe.md
src/doc/guide.md
src/doc/index.md
src/doc/po4a.conf
src/doc/reference.md
src/doc/rustdoc.md
src/etc/emacs/rust-mode-tests.el
src/etc/rustup.sh [new file with mode: 0644]
src/grammar/verify.rs
src/liballoc/arc.rs
src/liballoc/boxed.rs
src/libarena/lib.rs
src/libcollections/btree/map.rs
src/libcollections/btree/node.rs
src/libcollections/dlist.rs
src/libcollections/lib.rs
src/libcollections/ringbuf.rs
src/libcollections/slice.rs
src/libcollections/smallintmap.rs
src/libcollections/str.rs
src/libcollections/string.rs
src/libcollections/treemap.rs
src/libcollections/trie.rs
src/libcollections/vec.rs
src/libcore/atomic.rs
src/libcore/cell.rs
src/libcore/char.rs
src/libcore/failure.rs [deleted file]
src/libcore/finally.rs
src/libcore/fmt/float.rs
src/libcore/fmt/num.rs
src/libcore/intrinsics.rs
src/libcore/lib.rs
src/libcore/macros.rs
src/libcore/num/mod.rs
src/libcore/option.rs
src/libcore/panicking.rs [new file with mode: 0644]
src/libcore/ptr.rs
src/libcore/raw.rs
src/libcore/result.rs
src/libcore/slice.rs
src/libcore/str.rs
src/libcoretest/any.rs
src/libcoretest/finally.rs
src/libcoretest/iter.rs
src/libcoretest/option.rs
src/libcoretest/result.rs
src/libgetopts/lib.rs
src/libgreen/basic.rs
src/libgreen/context.rs
src/libgreen/lib.rs
src/libgreen/sched.rs
src/libgreen/simple.rs
src/libgreen/stack.rs
src/libgreen/task.rs
src/liblog/lib.rs
src/libnative/io/file_unix.rs
src/libnative/io/pipe_windows.rs
src/libnative/io/process.rs
src/libnative/io/timer_unix.rs
src/libnative/lib.rs
src/libnative/task.rs
src/librand/chacha.rs
src/librand/distributions/mod.rs
src/librand/lib.rs
src/librbml/lib.rs
src/libregex/compile.rs
src/libregex/lib.rs
src/libregex/parse.rs
src/libregex/re.rs
src/libregex/test/bench.rs
src/libregex/test/mod.rs
src/libregex/test/tests.rs
src/libregex_macros/lib.rs
src/librustc/back/write.rs
src/librustc/diagnostics.rs
src/librustc/driver/config.rs
src/librustc/driver/mod.rs
src/librustc/driver/pretty.rs
src/librustc/lint/builtin.rs
src/librustc/lint/context.rs
src/librustc/metadata/creader.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/filesearch.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/move_error.rs
src/librustc/middle/borrowck/mod.rs
src/librustc/middle/cfg/construct.rs
src/librustc/middle/check_const.rs
src/librustc/middle/check_match.rs
src/librustc/middle/check_static_recursion.rs
src/librustc/middle/const_eval.rs
src/librustc/middle/dataflow.rs
src/librustc/middle/def.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/intrinsicck.rs
src/librustc/middle/lang_items.rs
src/librustc/middle/liveness.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/region.rs
src/librustc/middle/resolve.rs
src/librustc/middle/save/mod.rs
src/librustc/middle/save/span_utils.rs
src/librustc/middle/subst.rs
src/librustc/middle/traits/coherence.rs
src/librustc/middle/traits/doc.rs
src/librustc/middle/traits/fulfill.rs
src/librustc/middle/traits/select.rs
src/librustc/middle/trans/_match.rs
src/librustc/middle/trans/adt.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/build.rs
src/librustc/middle/trans/cabi_arm.rs
src/librustc/middle/trans/cabi_mips.rs
src/librustc/middle/trans/cabi_x86_64.rs
src/librustc/middle/trans/callee.rs
src/librustc/middle/trans/cleanup.rs
src/librustc/middle/trans/closure.rs
src/librustc/middle/trans/common.rs
src/librustc/middle/trans/context.rs
src/librustc/middle/trans/controlflow.rs
src/librustc/middle/trans/datum.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/doc.rs
src/librustc/middle/trans/expr.rs
src/librustc/middle/trans/foreign.rs
src/librustc/middle/trans/glue.rs
src/librustc/middle/trans/intrinsic.rs
src/librustc/middle/trans/meth.rs
src/librustc/middle/trans/tvec.rs
src/librustc/middle/trans/type_.rs
src/librustc/middle/trans/type_of.rs
src/librustc/middle/ty.rs
src/librustc/middle/ty_fold.rs
src/librustc/middle/typeck/astconv.rs
src/librustc/middle/typeck/check/_match.rs
src/librustc/middle/typeck/check/method.rs
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/check/regionck.rs
src/librustc/middle/typeck/check/regionmanip.rs
src/librustc/middle/typeck/check/vtable.rs [new file with mode: 0644]
src/librustc/middle/typeck/check/vtable2.rs [deleted file]
src/librustc/middle/typeck/check/wf.rs
src/librustc/middle/typeck/coherence/mod.rs
src/librustc/middle/typeck/collect.rs
src/librustc/middle/typeck/infer/combine.rs
src/librustc/middle/typeck/infer/equate.rs
src/librustc/middle/typeck/infer/glb.rs
src/librustc/middle/typeck/infer/lattice.rs
src/librustc/middle/typeck/infer/mod.rs
src/librustc/middle/typeck/infer/region_inference/mod.rs
src/librustc/middle/typeck/infer/resolve.rs
src/librustc/middle/typeck/infer/skolemize.rs
src/librustc/middle/typeck/infer/sub.rs
src/librustc/middle/typeck/infer/test.rs
src/librustc/middle/typeck/infer/type_variable.rs
src/librustc/middle/typeck/infer/unify.rs
src/librustc/middle/typeck/mod.rs
src/librustc/middle/typeck/variance.rs
src/librustc/middle/weak_lang_items.rs
src/librustc/plugin/registry.rs
src/librustc/util/ppaux.rs
src/librustc/util/snapshot_vec.rs
src/librustc_back/archive.rs
src/librustc_back/rpath.rs
src/librustc_back/sha2.rs
src/librustc_back/svh.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/flock.rs
src/librustdoc/html/format.rs
src/librustdoc/html/highlight.rs
src/librustdoc/html/render.rs
src/librustdoc/lib.rs
src/librustdoc/test.rs
src/librustdoc/visit_ast.rs
src/librustrt/args.rs
src/librustrt/c_str.rs
src/librustrt/lib.rs
src/librustrt/local_data.rs
src/librustrt/mutex.rs
src/librustrt/stack_overflow.rs
src/librustrt/task.rs
src/librustrt/thread.rs
src/librustrt/unwind.rs
src/libserialize/base64.rs
src/libserialize/json.rs
src/libserialize/serialize.rs
src/libstd/ascii.rs
src/libstd/c_vec.rs
src/libstd/collections/hashmap/map.rs
src/libstd/collections/hashmap/set.rs
src/libstd/collections/hashmap/table.rs
src/libstd/dynamic_lib.rs
src/libstd/failure.rs
src/libstd/io/buffered.rs
src/libstd/io/comm_adapters.rs
src/libstd/io/extensions.rs
src/libstd/io/fs.rs
src/libstd/io/mem.rs
src/libstd/io/mod.rs
src/libstd/io/net/pipe.rs
src/libstd/io/net/tcp.rs
src/libstd/io/net/udp.rs
src/libstd/io/process.rs
src/libstd/io/result.rs
src/libstd/io/stdio.rs
src/libstd/io/test.rs
src/libstd/io/timer.rs
src/libstd/io/util.rs
src/libstd/lib.rs
src/libstd/macros.rs
src/libstd/num/strconv.rs
src/libstd/os.rs
src/libstd/path/posix.rs
src/libstd/path/windows.rs
src/libstd/prelude.rs
src/libstd/rand/mod.rs
src/libstd/rand/os.rs
src/libstd/rand/reader.rs
src/libstd/rt/backtrace.rs
src/libstd/rt/mod.rs
src/libstd/rt/util.rs
src/libstd/sync/future.rs
src/libstd/sync/task_pool.rs
src/libstd/task.rs
src/libstd/time/duration.rs
src/libsync/comm/mod.rs
src/libsync/comm/oneshot.rs
src/libsync/comm/select.rs
src/libsync/comm/shared.rs
src/libsync/comm/sync.rs
src/libsync/deque.rs
src/libsync/lock.rs
src/libsync/mpsc_queue.rs
src/libsync/raw.rs
src/libsync/spsc_queue.rs
src/libsyntax/ast.rs
src/libsyntax/ast_map/blocks.rs
src/libsyntax/ast_map/mod.rs
src/libsyntax/ast_util.rs
src/libsyntax/codemap.rs
src/libsyntax/config.rs
src/libsyntax/diagnostic.rs
src/libsyntax/diagnostics/plugin.rs
src/libsyntax/ext/asm.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/cfg.rs
src/libsyntax/ext/concat_idents.rs
src/libsyntax/ext/deriving/generic/mod.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/format.rs
src/libsyntax/ext/log_syntax.rs
src/libsyntax/ext/mtwt.rs
src/libsyntax/ext/quote.rs
src/libsyntax/ext/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/owned_slice.rs
src/libsyntax/parse/attr.rs
src/libsyntax/parse/lexer/comments.rs
src/libsyntax/parse/lexer/mod.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/obsolete.rs
src/libsyntax/parse/parser.rs
src/libsyntax/parse/token.rs
src/libsyntax/print/pp.rs
src/libsyntax/print/pprust.rs
src/libsyntax/util/small_vector.rs
src/libsyntax/visit.rs
src/libterm/lib.rs
src/libterm/terminfo/mod.rs
src/libterm/terminfo/parm.rs
src/libterm/win.rs
src/libtest/lib.rs
src/libtime/lib.rs
src/libunicode/u_str.rs
src/snapshots.txt
src/test/auxiliary/cci_nested_lib.rs
src/test/auxiliary/check_static_recursion_foreign_helper.rs [new file with mode: 0644]
src/test/auxiliary/issue_2723_a.rs
src/test/auxiliary/lang-item-public.rs
src/test/auxiliary/logging_right_crate.rs
src/test/auxiliary/regions-bounded-method-type-parameters-cross-crate-lib.rs
src/test/auxiliary/roman_numerals.rs
src/test/auxiliary/static-methods-crate.rs
src/test/auxiliary/weak-lang-items.rs
src/test/bench/core-std.rs
src/test/bench/shootout-chameneos-redux.rs
src/test/bench/shootout-k-nucleotide.rs
src/test/bench/shootout-meteor.rs
src/test/bench/shootout-pfib.rs
src/test/bench/shootout-reverse-complement.rs
src/test/bench/sudoku.rs
src/test/bench/task-perf-alloc-unwind.rs
src/test/bench/task-perf-jargon-metal-smoke.rs
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/bind-by-move-neither-can-live-while-the-other-survives-2.rs
src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-3.rs
src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-4.rs
src/test/compile-fail/bind-by-move-no-guards.rs
src/test/compile-fail/binop-fail-3.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-anon-fields-variant.rs
src/test/compile-fail/borrowck-autoref-3261.rs
src/test/compile-fail/borrowck-borrow-from-owned-ptr.rs
src/test/compile-fail/borrowck-borrow-from-stack-variable.rs
src/test/compile-fail/borrowck-closures-unique.rs
src/test/compile-fail/borrowck-lend-flow-if.rs
src/test/compile-fail/borrowck-lend-flow-loop.rs
src/test/compile-fail/borrowck-lend-flow.rs
src/test/compile-fail/borrowck-loan-local-as-both-mut-and-imm.rs
src/test/compile-fail/borrowck-ref-into-rvalue.rs
src/test/compile-fail/borrowck-vec-pattern-element-loan.rs
src/test/compile-fail/borrowck-vec-pattern-tail-element-loan.rs
src/test/compile-fail/closure-that-fails.rs
src/test/compile-fail/coherence-blanket-conflicts-with-specific-multidispatch.rs
src/test/compile-fail/dead-code-closure-bang.rs
src/test/compile-fail/deref-non-pointer.rs
src/test/compile-fail/fail-no-dead-code-core.rs
src/test/compile-fail/fail-no-dead-code.rs
src/test/compile-fail/fail-simple.rs
src/test/compile-fail/generic-lifetime-trait-impl.rs
src/test/compile-fail/index-bot.rs
src/test/compile-fail/issue-10392-2.rs
src/test/compile-fail/issue-10392.rs
src/test/compile-fail/issue-11844.rs
src/test/compile-fail/issue-12116.rs
src/test/compile-fail/issue-12187-1.rs
src/test/compile-fail/issue-12187-2.rs
src/test/compile-fail/issue-12863.rs [new file with mode: 0644]
src/test/compile-fail/issue-13466.rs
src/test/compile-fail/issue-13847.rs
src/test/compile-fail/issue-14721.rs [new file with mode: 0644]
src/test/compile-fail/issue-15207.rs
src/test/compile-fail/issue-15965.rs
src/test/compile-fail/issue-16683.rs [new file with mode: 0644]
src/test/compile-fail/issue-17373.rs
src/test/compile-fail/issue-17458.rs [new file with mode: 0644]
src/test/compile-fail/issue-17551.rs [new file with mode: 0644]
src/test/compile-fail/issue-18118.rs [new file with mode: 0644]
src/test/compile-fail/issue-18252.rs [new file with mode: 0644]
src/test/compile-fail/issue-18294.rs [new file with mode: 0644]
src/test/compile-fail/issue-18343.rs [new file with mode: 0644]
src/test/compile-fail/issue-2149.rs
src/test/compile-fail/issue-2150.rs
src/test/compile-fail/issue-2151.rs
src/test/compile-fail/issue-2330.rs
src/test/compile-fail/issue-2354.rs
src/test/compile-fail/issue-2611-4.rs
src/test/compile-fail/issue-2611-5.rs
src/test/compile-fail/issue-3021.rs
src/test/compile-fail/issue-3601.rs
src/test/compile-fail/issue-3668.rs
src/test/compile-fail/issue-5100.rs
src/test/compile-fail/issue-5500-1.rs
src/test/compile-fail/issue-5500.rs [new file with mode: 0644]
src/test/compile-fail/issue-6458-1.rs
src/test/compile-fail/issue-6991.rs [new file with mode: 0644]
src/test/compile-fail/issue-7867.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/lifetime-elision-return-type-requires-explicit-lifetime.rs
src/test/compile-fail/lint-unused-unsafe.rs
src/test/compile-fail/lint-visible-private-types.rs
src/test/compile-fail/liveness-bad-bang-2.rs
src/test/compile-fail/liveness-use-after-send.rs
src/test/compile-fail/loop-does-not-diverge.rs
src/test/compile-fail/lub-match.rs
src/test/compile-fail/match-join.rs
src/test/compile-fail/moves-based-on-type-exprs.rs
src/test/compile-fail/moves-based-on-type-match-bindings.rs
src/test/compile-fail/moves-based-on-type-no-recursive-stack-closure.rs
src/test/compile-fail/non-exhaustive-match-nested.rs
src/test/compile-fail/not-enough-arguments.rs
src/test/compile-fail/pattern-tyvar-2.rs
src/test/compile-fail/pattern-tyvar.rs
src/test/compile-fail/qquote-1.rs
src/test/compile-fail/qquote-2.rs
src/test/compile-fail/region-object-lifetime-in-coercion.rs
src/test/compile-fail/regions-fn-bound.rs
src/test/compile-fail/regions-fn-subtyping-return-static.rs
src/test/compile-fail/regions-fn-subtyping.rs
src/test/compile-fail/regions-free-region-ordering-callee.rs
src/test/compile-fail/removed-syntax-record.rs
src/test/compile-fail/selftype-traittype.rs [deleted file]
src/test/compile-fail/tag-that-dare-not-speak-its-name.rs
src/test/compile-fail/tag-type-args.rs
src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs
src/test/compile-fail/trait-objects.rs [new file with mode: 0644]
src/test/compile-fail/trait-test-2.rs
src/test/compile-fail/unboxed-closure-immutable-capture.rs [new file with mode: 0644]
src/test/compile-fail/unused-result.rs
src/test/compile-fail/weak-lang-item.rs
src/test/debuginfo/basic-types-metadata.rs
src/test/pretty/issue-929.rs
src/test/pretty/struct-pattern.rs [new file with mode: 0644]
src/test/run-fail/args-fail.rs
src/test/run-fail/assert-macro-explicit.rs
src/test/run-fail/assert-macro-fmt.rs
src/test/run-fail/assert-macro-owned.rs
src/test/run-fail/assert-macro-static.rs
src/test/run-fail/binop-fail-3.rs [deleted file]
src/test/run-fail/binop-fail.rs
src/test/run-fail/bug-2470-bounds-check-overflow-2.rs
src/test/run-fail/bug-2470-bounds-check-overflow-3.rs
src/test/run-fail/bug-2470-bounds-check-overflow.rs
src/test/run-fail/bug-811.rs
src/test/run-fail/by-value-self-objects-fail.rs [deleted file]
src/test/run-fail/die-macro-expr.rs
src/test/run-fail/die-macro-pure.rs
src/test/run-fail/die-macro.rs
src/test/run-fail/doublefail.rs
src/test/run-fail/explicit-fail-msg.rs
src/test/run-fail/explicit-fail.rs
src/test/run-fail/expr-fn-fail.rs
src/test/run-fail/expr-if-fail-fn.rs
src/test/run-fail/expr-if-fail.rs
src/test/run-fail/expr-match-fail-fn.rs
src/test/run-fail/expr-match-fail.rs
src/test/run-fail/extern-fail.rs
src/test/run-fail/fail-arg.rs
src/test/run-fail/fail-macro-any-wrapped.rs
src/test/run-fail/fail-macro-any.rs
src/test/run-fail/fail-macro-explicit.rs
src/test/run-fail/fail-macro-fmt.rs
src/test/run-fail/fail-macro-owned.rs
src/test/run-fail/fail-macro-static.rs
src/test/run-fail/fail-main.rs
src/test/run-fail/fail-non-utf8.rs
src/test/run-fail/fail-parens.rs
src/test/run-fail/fail-task-name-none.rs
src/test/run-fail/fail-task-name-owned.rs
src/test/run-fail/fail-task-name-send-str.rs
src/test/run-fail/fail-task-name-static.rs
src/test/run-fail/fmt-fail.rs
src/test/run-fail/for-each-loop-fail.rs
src/test/run-fail/glob-use-std.rs
src/test/run-fail/if-check-fail.rs
src/test/run-fail/if-cond-bot.rs
src/test/run-fail/issue-12920.rs
src/test/run-fail/issue-13202.rs
src/test/run-fail/issue-2444.rs
src/test/run-fail/issue-3029.rs
src/test/run-fail/issue-5500.rs [deleted file]
src/test/run-fail/issue-948.rs
src/test/run-fail/main-fail.rs
src/test/run-fail/match-bot-fail.rs
src/test/run-fail/match-disc-bot.rs
src/test/run-fail/match-wildcards.rs
src/test/run-fail/native-failure.rs
src/test/run-fail/rhs-type.rs
src/test/run-fail/rt-set-exit-status-fail.rs
src/test/run-fail/rt-set-exit-status-fail2.rs
src/test/run-fail/rt-set-exit-status.rs
src/test/run-fail/run-unexported-tests.rs
src/test/run-fail/str-overrun.rs
src/test/run-fail/task-spawn-barefn.rs
src/test/run-fail/test-fail.rs
src/test/run-fail/tls-exit-status.rs
src/test/run-fail/too-much-recursion-unwinding.rs
src/test/run-fail/unique-fail.rs
src/test/run-fail/unwind-interleaved.rs
src/test/run-fail/unwind-rec.rs
src/test/run-fail/unwind-rec2.rs
src/test/run-fail/unwind-unique.rs
src/test/run-fail/vec-overrun.rs
src/test/run-fail/while-body-fails.rs
src/test/run-fail/while-fail.rs
src/test/run-make/no-duplicate-libs/bar.rs
src/test/run-make/no-duplicate-libs/foo.rs
src/test/run-make/static-unwinding/main.rs
src/test/run-pass/attr-main-2.rs
src/test/run-pass/backtrace.rs
src/test/run-pass/binary-minus-without-space.rs
src/test/run-pass/bind-by-move.rs
src/test/run-pass/borrowck-macro-interaction-issue-6304.rs
src/test/run-pass/by-value-self-objects.rs [deleted file]
src/test/run-pass/byte-literals.rs
src/test/run-pass/cell-does-not-clone.rs
src/test/run-pass/check-static-recursion-foreign.rs [new file with mode: 0644]
src/test/run-pass/class-impl-very-parameterized-trait.rs
src/test/run-pass/cleanup-rvalue-temp-during-incomplete-alloc.rs
src/test/run-pass/closure-return-bang.rs
src/test/run-pass/closure-syntax.rs
src/test/run-pass/conditional-compile.rs
src/test/run-pass/conditional-debug-macro-off.rs
src/test/run-pass/conditional-debug-macro-on.rs
src/test/run-pass/const-big-enum.rs
src/test/run-pass/const-enum-byref-self.rs
src/test/run-pass/const-enum-byref.rs
src/test/run-pass/const-enum-ptr.rs
src/test/run-pass/const-enum-structlike.rs
src/test/run-pass/const-enum-vec-index.rs
src/test/run-pass/const-enum-vec-ptr.rs
src/test/run-pass/const-enum-vector.rs
src/test/run-pass/const-nullary-enum.rs
src/test/run-pass/core-run-destroy.rs
src/test/run-pass/deriving-cmp-shortcircuit.rs
src/test/run-pass/die-macro.rs
src/test/run-pass/drop-trait-enum.rs
src/test/run-pass/dst-coercions.rs
src/test/run-pass/dst-deref-mut.rs
src/test/run-pass/enum-alignment.rs
src/test/run-pass/enum-nullable-simplifycfg-misopt.rs
src/test/run-pass/expr-if-fail-all.rs
src/test/run-pass/expr-if-fail.rs
src/test/run-pass/expr-match-fail-all.rs
src/test/run-pass/expr-match-fail.rs
src/test/run-pass/expr-match-generic-unique1.rs
src/test/run-pass/expr-match-generic-unique2.rs
src/test/run-pass/expr-match-generic.rs
src/test/run-pass/expr-match-struct.rs
src/test/run-pass/expr-match-unique.rs
src/test/run-pass/fail-during-tld-destroy.rs
src/test/run-pass/fail-in-dtor-drops-fields.rs
src/test/run-pass/for-loop-fail.rs
src/test/run-pass/getopts_ref.rs
src/test/run-pass/hygienic-labels.rs
src/test/run-pass/if-bot.rs
src/test/run-pass/if-check.rs
src/test/run-pass/if-let.rs
src/test/run-pass/inherent-trait-method-order.rs
src/test/run-pass/issue-10392.rs
src/test/run-pass/issue-10734.rs
src/test/run-pass/issue-11267.rs
src/test/run-pass/issue-11552.rs
src/test/run-pass/issue-11709.rs
src/test/run-pass/issue-12028.rs [new file with mode: 0644]
src/test/run-pass/issue-13259-windows-tcb-trash.rs
src/test/run-pass/issue-13352.rs
src/test/run-pass/issue-14865.rs
src/test/run-pass/issue-14901.rs [new file with mode: 0644]
src/test/run-pass/issue-1516.rs
src/test/run-pass/issue-15763.rs
src/test/run-pass/issue-16560.rs [new file with mode: 0644]
src/test/run-pass/issue-16668.rs [new file with mode: 0644]
src/test/run-pass/issue-17361.rs [new file with mode: 0644]
src/test/run-pass/issue-17458.rs [deleted file]
src/test/run-pass/issue-18352.rs [new file with mode: 0644]
src/test/run-pass/issue-2311-2.rs
src/test/run-pass/issue-2312.rs
src/test/run-pass/issue-2611-3.rs
src/test/run-pass/issue-2718.rs
src/test/run-pass/issue-2904.rs
src/test/run-pass/issue-3895.rs
src/test/run-pass/issue-4016.rs
src/test/run-pass/issue-4241.rs
src/test/run-pass/issue-5521.rs
src/test/run-pass/issue-6128.rs
src/test/run-pass/issue-6449.rs
src/test/run-pass/issue-8351-1.rs
src/test/run-pass/issue-8351-2.rs
src/test/run-pass/last-use-in-block.rs
src/test/run-pass/logging-enabled-debug.rs
src/test/run-pass/logging-enabled.rs
src/test/run-pass/logging-right-crate.rs
src/test/run-pass/loop-no-reinit-needed-post-bot.rs
src/test/run-pass/macro-interpolation.rs
src/test/run-pass/match-bot-2.rs
src/test/run-pass/match-bot.rs
src/test/run-pass/match-enum-struct-0.rs
src/test/run-pass/match-enum-struct-1.rs
src/test/run-pass/match-pattern-lit.rs
src/test/run-pass/match-pipe-binding.rs
src/test/run-pass/match-range.rs
src/test/run-pass/match-ref-binding-in-guard-3256.rs
src/test/run-pass/match-str.rs
src/test/run-pass/match-struct-0.rs
src/test/run-pass/negative.rs
src/test/run-pass/nested-block-comment.rs
src/test/run-pass/nested-class.rs
src/test/run-pass/nested-matchs.rs
src/test/run-pass/nested-pattern.rs
src/test/run-pass/no-landing-pads.rs
src/test/run-pass/nullable-pointer-iotareduction.rs
src/test/run-pass/option-unwrap.rs
src/test/run-pass/out-pointer-aliasing.rs [new file with mode: 0644]
src/test/run-pass/overload-index-operator.rs
src/test/run-pass/overloaded-autoderef.rs
src/test/run-pass/overloaded-deref.rs
src/test/run-pass/parse-fail.rs
src/test/run-pass/process-detach.rs
src/test/run-pass/realloc-16687.rs
src/test/run-pass/regions-bot.rs
src/test/run-pass/regions-dependent-addr-of.rs
src/test/run-pass/regions-early-bound-trait-param.rs
src/test/run-pass/regions-return-interior-of-option.rs
src/test/run-pass/ret-bang.rs
src/test/run-pass/return-from-closure.rs
src/test/run-pass/running-with-no-runtime.rs
src/test/run-pass/sepcomp-unwind.rs
src/test/run-pass/signal-exit-status.rs
src/test/run-pass/size-and-align.rs
src/test/run-pass/slice-fail-2.rs
src/test/run-pass/smallest-hello-world.rs
src/test/run-pass/syntax-extension-cfg.rs
src/test/run-pass/task-stderr.rs
src/test/run-pass/tcp-accept-stress.rs
src/test/run-pass/tcp-connect-timeouts.rs
src/test/run-pass/tcp-stress.rs
src/test/run-pass/tempfile.rs
src/test/run-pass/terminate-in-initializer.rs
src/test/run-pass/test-runner-hides-main.rs
src/test/run-pass/trait-cache-issue-18209.rs [new file with mode: 0644]
src/test/run-pass/trait-cast-generic.rs [deleted file]
src/test/run-pass/trait-default-method-xc.rs
src/test/run-pass/trans-tag-static-padding.rs
src/test/run-pass/typeck-macro-interaction-issue-8852.rs
src/test/run-pass/unboxed-closures-monomorphization.rs [new file with mode: 0644]
src/test/run-pass/unboxed-closures-move-mutable.rs [new file with mode: 0644]
src/test/run-pass/unique-containing-tag.rs
src/test/run-pass/unique-decl.rs
src/test/run-pass/unique-pat.rs
src/test/run-pass/unit-like-struct-drop-run.rs
src/test/run-pass/unix-process-spawn-errno.rs
src/test/run-pass/unreachable-code-1.rs
src/test/run-pass/unreachable-code.rs
src/test/run-pass/unwind-resource.rs
src/test/run-pass/unwind-unique.rs
src/test/run-pass/use-uninit-match2.rs
src/test/run-pass/vec-dst.rs
src/test/run-pass/vec-matching-autoslice.rs
src/test/run-pass/vec-matching.rs
src/test/run-pass/vector-sort-failure-safe.rs
src/test/run-pass/weird-exprs.rs
src/test/run-pass/while-label.rs
src/test/run-pass/writealias.rs

index 637b9ec8c4efb78e6751cf39aae7c0555e8b44a6..f529fe1bb78c3e6b9643e2f4e6d318bbaf12a2b7 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -5,8 +5,104 @@
 # email addresses.
 #
 
-Elly Jones <elly@leptoquark.net>
-ILyoan <ilyoan@gmail.com>
+Aaron Todd <github@opprobrio.us>
+Ahmed Charles <ahmedcharles@gmail.com> <acharles@outlook.com>
+Alex Lyon <arcterus@mail.com> <Arcterus@mail.com>
+Alex Rønne Petersen <alex@lycus.org>
+Andreas Gal <gal@mozilla.com> <andreas.gal@gmail.com>
+Andrew Poelstra <asp11@sfu.ca> <apoelstra@wpsoftware.net>
+Anton Löfgren <anton.lofgren@gmail.com> <alofgren@op5.com>
+Ariel Ben-Yehuda <arielb1@mail.tau.ac.il> <ariel.byd@gmail.com>
+Austin Seipp <mad.one@gmail.com> <as@hacks.yi.org>
+Ben Alpert <ben@benalpert.com> <spicyjalapeno@gmail.com>
+Benjamin Jackman <ben@jackman.biz>
+Björn Steinbrink <bsteinbr@gmail.com> <B.Steinbrink@gmx.de>
+blake2-ppc <ulrik.sverdrup@gmail.com> <blake2-ppc>
+Boris Egorov <jightuse@gmail.com> <egorov@linux.com>
+Brian Anderson <banderson@mozilla.com> <andersrb@gmail.com>
+Brian Dawn <brian.t.dawn@gmail.com>
+Carl-Anton Ingmarsson <mail@carlanton.se> <ca.ingmarsson@gmail.com>
+Carol Willing <carolcode@willingconsulting.com>
+Chris Pressey <cpressey@gmail.com>
+Clark Gaebel <cg.wowus.cg@gmail.com> <cgaebel@mozilla.com>
+David Klein <david.klein@baesystemsdetica.com>
+David Manescu <david.manescu@gmail.com> <dman2626@uni.sydney.edu.au>
+Damien Schoof <damien.schoof@gmail.com>
+Derek Chiang <derekchiang93@gmail.com> Derek Chiang (Enchi Jiang) <derekchiang93@gmail.com>
+Dylan Braithwaite <dylanbraithwaite1@gmail.com> <mail@dylanb.me>
+Eduardo Bautista <me@eduardobautista.com> <mail@eduardobautista.com>
+Eduardo Bautista <me@eduardobautista.com> <=>
+Elliott Slaughter <elliottslaughter@gmail.com> <eslaughter@mozilla.com>
+Elly Fong-Jones <elly@leptoquark.net>
+Eric Holk <eric.holk@gmail.com> <eholk@mozilla.com>
+Eric Holk <eric.holk@gmail.com> <eholk@cs.indiana.edu>
+Eric Holmes <eric@ejholmes.net>
+Eric Reed <ecreed@cs.washington.edu> <ereed@mozilla.com>
+Erick Tryzelaar <erick.tryzelaar@gmail.com> <etryzelaar@iqt.org>
+Evgeny Sologubov
+Falco Hirschenberger <falco.hirschenberger@gmail.com> <hirschen@itwm.fhg.de>
+Gareth Daniel Smith <garethdanielsmith@gmail.com>
+Georges Dubus <georges.dubus@gmail.com> <georges.dubus@compiletoi.net>
+Graham Fawcett <fawcett@uwindsor.ca> <graham.fawcett@gmail.com>
+Graydon Hoare <graydon@mozilla.com> <graydon@pobox.com>
+Heather <heather@cynede.net> <Heather@cynede.net>
+Heather <heather@cynede.net> <Cynede@Gentoo.org>
+Ilyong Cho <ilyoan@gmail.com>
+J. J. Weber <jjweber@gmail.com>
+Jakub Bukaj <jakub@jakub.cc>
+Jakub Bukaj <jakub@jakub.cc> <jakubw@jakubw.net>
+James Deng <cnjamesdeng@gmail.com> <cnJamesDeng@gmail.com>
+James Miller <bladeon@gmail.com> <james@aatch.net>
+Jason Orendorff <jorendorff@mozilla.com> <jason@mozmac-2.local>
+Jason Orendorff <jorendorff@mozilla.com> <jason.orendorff@gmail.com>
+Jeremy Letang <letang.jeremy@gmail.com>
+Jihyun Yu <jihyun@nclab.kaist.ac.kr> jihyun <jihyun@nablecomm.com>
+Jihyun Yu <jihyun@nclab.kaist.ac.kr> <yjh0502@gmail.com>
+John Clements <clements@racket-lang.org> <clements@brinckerhoff.org>
+Jorge Aparicio <japaric@linux.com> <japaricious@gmail.com>
+Jonathan Bailey <jbailey@mozilla.com> <jbailey@jbailey-20809.local>
 Junyoung Cho <june0.cho@samsung.com>
+Jyun-Yan You <jyyou.tw@gmail.com> <jyyou@cs.nctu.edu.tw>
+Kang Seonghoon <kang.seonghoon@mearie.org> <public+git@mearie.org>
+Keegan McAllister <kmcallister@mozilla.com> <mcallister.keegan@gmail.com>
+Kyeongwoon Lee <kyeongwoon.lee@samsung.com>
+Lee Wondong <wdlee91@gmail.com>
+Lennart Kudling <github@kudling.de>
+Lindsey Kuper <lindsey@composition.al> <lindsey@rockstargirl.org>
+Lindsey Kuper <lindsey@composition.al> <lkuper@mozilla.com>
+Luqman Aden <me@luqman.ca> <laden@mozilla.com>
+Luqman Aden <me@luqman.ca> <laden@csclub.uwaterloo.ca>
+Luke Metz <luke.metz@students.olin.edu>
+Makoto Nakashima <makoto.nksm+github@gmail.com> <makoto.nksm@gmail.com>
+Makoto Nakashima <makoto.nksm+github@gmail.com> gifnksm <makoto.nksm+github@gmail.com>
+Margaret Meyerhofer <mmeyerho@andrew.cmu.edu> <mmeyerho@andrew>
+Mark Sinclair <mark.edward.x@gmail.com>
+Mark Sinclair <mark.edward.x@gmail.com> =Mark Sinclair <=125axel125@gmail.com>
+Matt Brubeck <mbrubeck@limpet.net> <mbrubeck@cs.hmc.edu>
+Matthew Auld <matthew.auld@intel.com>
+Matthew McPherrin <matthew@mcpherrin.ca> <matt@mcpherrin.ca>
 Matthijs Hofstra <thiezz@gmail.com>
+Michael Williams <m.t.williams@live.com>
+Michael Woerister <michaelwoerister@gmail> <michaelwoerister@gmail.com>
+Michael Woerister <michaelwoerister@gmail> <michaelwoerister@posteo>
+Neil Pankey <npankey@gmail.com> <neil@wire.im>
+Philipp Brüschweiler <blei42@gmail.com> <blei42@gmail.com>
+Philipp Brüschweiler <blei42@gmail.com> <bruphili@student.ethz.ch>
+Pradeep Kumar <gohanpra@gmail.com>
+Richard Diamond <wichard@vitalitystudios.com> <wichard@hahbee.co>
 Rob Arnold <robarnold@cs.cmu.edu>
+Robert Gawdzik <rgawdzik@hotmail.com> Robert Gawdzik ☢ <rgawdzik@hotmail.com>
+Robert Millar <robert.millar@cantab.net>
+Ryan Scheel <ryan.havvy@gmail.com>
+Seonghyun Kim <sh8281.kim@samsung.com>
+Simon Barber-Dueck <sbarberdueck@gmail.com> Simon BD <simon@server>
+Simon Sapin <simon@exyr.org> <simon.sapin@exyr.org>
+startling <tdixon51793@gmail.com>
+Steven Fackler <sfackler@gmail.com> <sfackler@palantir.com>
+Steven Stewart-Gallus <sstewartgallus00@langara.bc.ca> <sstewartgallus00@mylangara.bc.ca>
+Tim Chevalier <chevalier@alum.wellesley.edu> <catamorphism@gmail.com>
+Torsten Weber <TorstenWeber12@gmail.com> <torstenweber12@gmail.com>
+William Ting <io@williamting.com> <william.h.ting@gmail.com>
+Youngsoo Son <ysson83@gmail.com> <ysoo.son@samsung.com>
+Zack Corr <zack@z0w0.me> <zackcorr95@gmail.com>
+Zack Slayton <zack.slayton@gmail.com>
index 0bd37bc485d865ae4715ee87049390d958a63811..59e51356c6ca28504ec6b0bb0c7c336aff5fbc73 100755 (executable)
--- a/configure
+++ b/configure
@@ -842,7 +842,7 @@ CFG_PREFIX=${CFG_PREFIX%/}
 CFG_MANDIR=${CFG_MANDIR%/}
 CFG_HOST="$(echo $CFG_HOST | tr ',' ' ')"
 CFG_TARGET="$(echo $CFG_TARGET | tr ',' ' ')"
-CFG_SUPPORTED_TARGET="$(grep ^CC_*=* ${CFG_SRC_DIR}mk/platform.mk | sed -e 's/^CC_//' -e 's/\([^=]*\).*/\1/' | xargs)"
+CFG_SUPPORTED_TARGET="$(ls ${CFG_SRC_DIR}mk/cfg)"
 
 # copy host-triples to target-triples so that hosts are a subset of targets
 V_TEMP=""
@@ -989,6 +989,7 @@ do
     make_dir $h/test/doc-guide-container
     make_dir $h/test/doc-guide-tasks
     make_dir $h/test/doc-guide-plugin
+    make_dir $h/test/doc-guide-crates
     make_dir $h/test/doc-rust
 done
 
diff --git a/mk/cfg/arm-apple-ios b/mk/cfg/arm-apple-ios
new file mode 100644 (file)
index 0000000..b2ce37a
--- /dev/null
@@ -0,0 +1,34 @@
+# arm-apple-ios configuration
+CFG_SDK_NAME_arm-apple-ios = iphoneos
+CFG_SDK_ARCHS_arm-apple-ios = armv7
+ifneq ($(findstring darwin,$(CFG_OSTYPE)),)
+CFG_IOS_SDK = $(shell xcrun --show-sdk-path -sdk iphoneos 2>/dev/null)
+CFG_IOS_FLAGS = -target armv7-apple-darwin -isysroot $(CFG_IOS_SDK) -mios-version-min=7.0
+CC_arm-apple-ios = $(shell xcrun -find -sdk iphoneos clang)
+CXX_arm-apple-ios = $(shell xcrun -find -sdk iphoneos clang++)
+CPP_arm-apple-ios = $(shell xcrun -find -sdk iphoneos clang++)
+AR_arm-apple-ios = $(shell xcrun -find -sdk iphoneos ar)
+endif
+CFG_LIB_NAME_arm-apple-ios = lib$(1).a
+CFG_LIB_GLOB_arm-apple-ios = lib$(1)-*.a
+CFG_STATIC_LIB_NAME_arm-apple-ios=lib$(1).a
+CFG_LIB_DSYM_GLOB_arm-apple-ios = lib$(1)-*.a.dSYM
+CFG_CFLAGS_arm-apple-ios := -arch armv7 -mfpu=vfp3 $(CFG_IOS_FLAGS)
+CFG_GCCISH_CFLAGS_arm-apple-ios := -Wall -Werror -g -fPIC $(CFG_IOS_FLAGS) -mfpu=vfp3 -arch armv7
+CFG_GCCISH_CXXFLAGS_arm-apple-ios := -fno-rtti $(CFG_IOS_FLAGS) -I$(CFG_IOS_SDK)/usr/include/c++/4.2.1
+CFG_GCCISH_LINK_FLAGS_arm-apple-ios := -lpthread -syslibroot $(CFG_IOS_SDK) -Wl,-no_compact_unwind
+CFG_GCCISH_DEF_FLAG_arm-apple-ios := -Wl,-exported_symbols_list,
+CFG_GCCISH_PRE_LIB_FLAGS_arm-apple-ios :=
+CFG_GCCISH_POST_LIB_FLAGS_arm-apple-ios :=
+CFG_DEF_SUFFIX_arm-apple-ios := .darwin.def
+CFG_LLC_FLAGS_arm-apple-ios := -mattr=+vfp3,+v7,+thumb2,+neon -march=arm
+CFG_INSTALL_NAME_arm-apple-ios = -Wl,-install_name,@rpath/$(1)
+CFG_EXE_SUFFIX_arm-apple-ios :=
+CFG_WINDOWSY_arm-apple-ios :=
+CFG_UNIXY_arm-apple-ios := 1
+CFG_PATH_MUNGE_arm-apple-ios := true
+CFG_LDPATH_arm-apple-ios :=
+CFG_RUN_arm-apple-ios = $(2)
+CFG_RUN_TARG_arm-apple-ios = $(call CFG_RUN_arm-apple-ios,,$(2))
+RUSTC_FLAGS_arm-apple-ios := -C relocation_model=pic
+RUSTC_CROSS_FLAGS_arm-apple-ios :=-C relocation_model=pic
diff --git a/mk/cfg/arm-linux-androideabi b/mk/cfg/arm-linux-androideabi
new file mode 100644 (file)
index 0000000..bf7ec39
--- /dev/null
@@ -0,0 +1,28 @@
+# arm-linux-androideabi configuration
+CC_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-gcc
+CXX_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-g++
+CPP_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-gcc -E
+AR_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-ar
+CFG_LIB_NAME_arm-linux-androideabi=lib$(1).so
+CFG_STATIC_LIB_NAME_arm-linux-androideabi=lib$(1).a
+CFG_LIB_GLOB_arm-linux-androideabi=lib$(1)-*.so
+CFG_LIB_DSYM_GLOB_arm-linux-androideabi=lib$(1)-*.dylib.dSYM
+CFG_CFLAGS_arm-linux-androideabi := -D__arm__ -DANDROID -D__ANDROID__ $(CFLAGS)
+CFG_GCCISH_CFLAGS_arm-linux-androideabi := -Wall -g -fPIC -D__arm__ -DANDROID -D__ANDROID__ $(CFLAGS)
+CFG_GCCISH_CXXFLAGS_arm-linux-androideabi := -fno-rtti $(CXXFLAGS)
+CFG_GCCISH_LINK_FLAGS_arm-linux-androideabi := -shared -fPIC -ldl -g -lm -lsupc++
+CFG_GCCISH_DEF_FLAG_arm-linux-androideabi := -Wl,--export-dynamic,--dynamic-list=
+CFG_GCCISH_PRE_LIB_FLAGS_arm-linux-androideabi := -Wl,-whole-archive
+CFG_GCCISH_POST_LIB_FLAGS_arm-linux-androideabi := -Wl,-no-whole-archive
+CFG_DEF_SUFFIX_arm-linux-androideabi := .android.def
+CFG_LLC_FLAGS_arm-linux-androideabi :=
+CFG_INSTALL_NAME_arm-linux-androideabi =
+CFG_EXE_SUFFIX_arm-linux-androideabi :=
+CFG_WINDOWSY_arm-linux-androideabi :=
+CFG_UNIXY_arm-linux-androideabi := 1
+CFG_PATH_MUNGE_arm-linux-androideabi := true
+CFG_LDPATH_arm-linux-androideabi :=
+CFG_RUN_arm-linux-androideabi=
+CFG_RUN_TARG_arm-linux-androideabi=
+RUSTC_FLAGS_arm-linux-androideabi :=
+RUSTC_CROSS_FLAGS_arm-linux-androideabi :=
diff --git a/mk/cfg/arm-unknown-linux-gnueabi b/mk/cfg/arm-unknown-linux-gnueabi
new file mode 100644 (file)
index 0000000..e76ce27
--- /dev/null
@@ -0,0 +1,29 @@
+# arm-unknown-linux-gnueabi configuration
+CROSS_PREFIX_arm-unknown-linux-gnueabi=arm-linux-gnueabi-
+CC_arm-unknown-linux-gnueabi=gcc
+CXX_arm-unknown-linux-gnueabi=g++
+CPP_arm-unknown-linux-gnueabi=gcc -E
+AR_arm-unknown-linux-gnueabi=ar
+CFG_LIB_NAME_arm-unknown-linux-gnueabi=lib$(1).so
+CFG_STATIC_LIB_NAME_arm-unknown-linux-gnueabi=lib$(1).a
+CFG_LIB_GLOB_arm-unknown-linux-gnueabi=lib$(1)-*.so
+CFG_LIB_DSYM_GLOB_arm-unknown-linux-gnueabi=lib$(1)-*.dylib.dSYM
+CFG_CFLAGS_arm-unknown-linux-gnueabi := -D__arm__ -mfpu=vfp $(CFLAGS)
+CFG_GCCISH_CFLAGS_arm-unknown-linux-gnueabi := -Wall -g -fPIC -D__arm__ -mfpu=vfp $(CFLAGS)
+CFG_GCCISH_CXXFLAGS_arm-unknown-linux-gnueabi := -fno-rtti $(CXXFLAGS)
+CFG_GCCISH_LINK_FLAGS_arm-unknown-linux-gnueabi := -shared -fPIC -g
+CFG_GCCISH_DEF_FLAG_arm-unknown-linux-gnueabi := -Wl,--export-dynamic,--dynamic-list=
+CFG_GCCISH_PRE_LIB_FLAGS_arm-unknown-linux-gnueabi := -Wl,-whole-archive
+CFG_GCCISH_POST_LIB_FLAGS_arm-unknown-linux-gnueabi := -Wl,-no-whole-archive
+CFG_DEF_SUFFIX_arm-unknown-linux-gnueabi := .linux.def
+CFG_LLC_FLAGS_arm-unknown-linux-gnueabi :=
+CFG_INSTALL_NAME_arm-unknown-linux-gnueabi =
+CFG_EXE_SUFFIX_arm-unknown-linux-gnueabi :=
+CFG_WINDOWSY_arm-unknown-linux-gnueabi :=
+CFG_UNIXY_arm-unknown-linux-gnueabi := 1
+CFG_PATH_MUNGE_arm-unknown-linux-gnueabi := true
+CFG_LDPATH_arm-unknown-linux-gnueabi :=
+CFG_RUN_arm-unknown-linux-gnueabi=$(2)
+CFG_RUN_TARG_arm-unknown-linux-gnueabi=$(call CFG_RUN_arm-unknown-linux-gnueabi,,$(2))
+RUSTC_FLAGS_arm-unknown-linux-gnueabi :=
+RUSTC_CROSS_FLAGS_arm-unknown-linux-gnueabi :=
diff --git a/mk/cfg/arm-unknown-linux-gnueabihf b/mk/cfg/arm-unknown-linux-gnueabihf
new file mode 100644 (file)
index 0000000..22bfc25
--- /dev/null
@@ -0,0 +1,29 @@
+# arm-unknown-linux-gnueabihf configuration
+CROSS_PREFIX_arm-unknown-linux-gnueabihf=arm-linux-gnueabihf-
+CC_arm-unknown-linux-gnueabihf=gcc
+CXX_arm-unknown-linux-gnueabihf=g++
+CPP_arm-unknown-linux-gnueabihf=gcc -E
+AR_arm-unknown-linux-gnueabihf=ar
+CFG_LIB_NAME_arm-unknown-linux-gnueabihf=lib$(1).so
+CFG_STATIC_LIB_NAME_arm-unknown-linux-gnueabihf=lib$(1).a
+CFG_LIB_GLOB_arm-unknown-linux-gnueabihf=lib$(1)-*.so
+CFG_LIB_DSYM_GLOB_arm-unknown-linux-gnueabihf=lib$(1)-*.dylib.dSYM
+CFG_CFLAGS_arm-unknown-linux-gnueabihf := -D__arm__ $(CFLAGS)
+CFG_GCCISH_CFLAGS_arm-unknown-linux-gnueabihf := -Wall -g -fPIC -D__arm__ $(CFLAGS)
+CFG_GCCISH_CXXFLAGS_arm-unknown-linux-gnueabihf := -fno-rtti $(CXXFLAGS)
+CFG_GCCISH_LINK_FLAGS_arm-unknown-linux-gnueabihf := -shared -fPIC -g
+CFG_GCCISH_DEF_FLAG_arm-unknown-linux-gnueabihf := -Wl,--export-dynamic,--dynamic-list=
+CFG_GCCISH_PRE_LIB_FLAGS_arm-unknown-linux-gnueabihf := -Wl,-whole-archive
+CFG_GCCISH_POST_LIB_FLAGS_arm-unknown-linux-gnueabihf := -Wl,-no-whole-archive
+CFG_DEF_SUFFIX_arm-unknown-linux-gnueabihf := .linux.def
+CFG_LLC_FLAGS_arm-unknown-linux-gnueabihf :=
+CFG_INSTALL_NAME_ar,-unknown-linux-gnueabihf =
+CFG_EXE_SUFFIX_arm-unknown-linux-gnueabihf :=
+CFG_WINDOWSY_arm-unknown-linux-gnueabihf :=
+CFG_UNIXY_arm-unknown-linux-gnueabihf := 1
+CFG_PATH_MUNGE_arm-unknown-linux-gnueabihf := true
+CFG_LDPATH_arm-unknown-linux-gnueabihf :=
+CFG_RUN_arm-unknown-linux-gnueabihf=$(2)
+CFG_RUN_TARG_arm-unknown-linux-gnueabihf=$(call CFG_RUN_arm-unknown-linux-gnueabihf,,$(2))
+RUSTC_FLAGS_arm-unknown-linux-gnueabihf := -C target-feature=+v6,+vfp2
+RUSTC_CROSS_FLAGS_arm-unknown-linux-gnueabihf :=
diff --git a/mk/cfg/i386-apple-ios b/mk/cfg/i386-apple-ios
new file mode 100644 (file)
index 0000000..c71d664
--- /dev/null
@@ -0,0 +1,33 @@
+# i386-apple-ios configuration
+CFG_SDK_NAME_i386-apple-ios = iphonesimulator
+CFG_SDK_ARCHS_i386-apple-ios = i386
+ifneq ($(findstring darwin,$(CFG_OSTYPE)),)
+CFG_IOSSIM_SDK = $(shell xcrun --show-sdk-path -sdk iphonesimulator 2>/dev/null)
+CFG_IOSSIM_FLAGS = -target i386-apple-ios -isysroot $(CFG_IOSSIM_SDK) -mios-simulator-version-min=7.0
+CC_i386-apple-ios = $(shell xcrun -find -sdk iphonesimulator clang)
+CXX_i386-apple-ios = $(shell xcrun -find -sdk iphonesimulator clang++)
+CPP_i386-apple-ios = $(shell xcrun -find -sdk iphonesimulator clang++)
+AR_i386-apple-ios = $(shell xcrun -find -sdk iphonesimulator ar)
+endif
+CFG_LIB_NAME_i386-apple-ios = lib$(1).a
+CFG_LIB_GLOB_i386-apple-ios = lib$(1)-*.dylib
+CFG_STATIC_LIB_NAME_i386-apple-ios=lib$(1).a
+CFG_LIB_DSYM_GLOB_i386-apple-ios = lib$(1)-*.dylib.dSYM
+CFG_CFLAGS_i386-apple-ios = $(CFG_IOSSIM_FLAGS)
+CFG_GCCISH_CFLAGS_i386-apple-ios = -Wall -Werror -g -fPIC -m32 $(CFG_IOSSIM_FLAGS)
+CFG_GCCISH_CXXFLAGS_i386-apple-ios = -fno-rtti $(CFG_IOSSIM_FLAGS) -I$(CFG_IOSSIM_SDK)/usr/include/c++/4.2.1
+CFG_GCCISH_LINK_FLAGS_i386-apple-ios = -lpthread -Wl,-no_compact_unwind -m32 -Wl,-syslibroot $(CFG_IOSSIM_SDK)
+CFG_GCCISH_DEF_FLAG_i386-apple-ios = -Wl,-exported_symbols_list,
+CFG_GCCISH_PRE_LIB_FLAGS_i386-apple-ios =
+CFG_GCCISH_POST_LIB_FLAGS_i386-apple-ios =
+CFG_DEF_SUFFIX_i386-apple-ios = .darwin.def
+CFG_LLC_FLAGS_i386-apple-ios =
+CFG_INSTALL_NAME_i386-apple-ios = -Wl,-install_name,@rpath/$(1)
+CFG_EXE_SUFFIX_i386-apple-ios =
+CFG_WINDOWSY_i386-apple-ios =
+CFG_UNIXY_i386-apple-ios = 1
+CFG_PATH_MUNGE_i386-apple-ios = true
+CFG_LDPATH_i386-apple-ios =
+CFG_RUN_i386-apple-ios = $(2)
+CFG_RUN_TARG_i386-apple-ios = $(call CFG_RUN_i386-apple-ios,,$(2))
+CFG_JEMALLOC_CFLAGS_i386-apple-ios = -target i386-apple-ios -Wl,-syslibroot $(CFG_IOSSIM_SDK) -Wl,-no_compact_unwind
diff --git a/mk/cfg/i586-mingw32msvc b/mk/cfg/i586-mingw32msvc
new file mode 100644 (file)
index 0000000..30ebbb3
--- /dev/null
@@ -0,0 +1,29 @@
+# i586-mingw32msvc configuration
+CC_i586-mingw32msvc=$(CFG_MINGW32_CROSS_PATH)/bin/i586-mingw32msvc-gcc
+CXX_i586-mingw32msvc=$(CFG_MINGW32_CROSS_PATH)/bin/i586-mingw32msvc-g++
+CPP_i586-mingw32msvc=$(CFG_MINGW32_CROSS_PATH)/bin/i586-mingw32msvc-cpp
+AR_i586-mingw32msvc=$(CFG_MINGW32_CROSS_PATH)/bin/i586-mingw32msvc-ar
+CFG_LIB_NAME_i586-mingw32msvc=$(1).dll
+CFG_STATIC_LIB_NAME_i586-mingw32msvc=$(1).lib
+CFG_LIB_GLOB_i586-mingw32msvc=$(1)-*.dll
+CFG_LIB_DSYM_GLOB_i586-mingw32msvc=$(1)-*.dylib.dSYM
+CFG_CFLAGS_i586-mingw32msvc := -march=i586 -m32 $(CFLAGS)
+CFG_GCCISH_CFLAGS_i586-mingw32msvc := -Wall -Werror -g -march=i586 -m32 $(CFLAGS)
+CFG_GCCISH_CXXFLAGS_i586-mingw32msvc := -fno-rtti $(CXXFLAGS)
+CFG_GCCISH_LINK_FLAGS_i586-mingw32msvc := -shared -g -m32
+CFG_GCCISH_DEF_FLAG_i586-mingw32msvc :=
+CFG_GCCISH_PRE_LIB_FLAGS_i586-mingw32msvc :=
+CFG_GCCISH_POST_LIB_FLAGS_i586-mingw32msvc :=
+CFG_DEF_SUFFIX_i586-mingw32msvc := .mingw32.def
+CFG_LLC_FLAGS_i586-mingw32msvc :=
+CFG_INSTALL_NAME_i586-mingw32msvc =
+CFG_EXE_SUFFIX_i586-mingw32msvc := .exe
+CFG_WINDOWSY_i586-mingw32msvc := 1
+CFG_UNIXY_i586-mingw32msvc :=
+CFG_PATH_MUNGE_i586-mingw32msvc := $(strip perl -i.bak -p \
+                             -e 's@\\(\S)@/\1@go;' \
+                             -e 's@^/([a-zA-Z])/@\1:/@o;')
+CFG_LDPATH_i586-mingw32msvc :=
+CFG_RUN_i586-mingw32msvc=
+CFG_RUN_TARG_i586-mingw32msvc=
+
diff --git a/mk/cfg/i686-apple-darwin b/mk/cfg/i686-apple-darwin
new file mode 100644 (file)
index 0000000..0f8a773
--- /dev/null
@@ -0,0 +1,27 @@
+# i686-apple-darwin configuration
+CC_i686-apple-darwin=$(CC)
+CXX_i686-apple-darwin=$(CXX)
+CPP_i686-apple-darwin=$(CPP)
+AR_i686-apple-darwin=$(AR)
+CFG_LIB_NAME_i686-apple-darwin=lib$(1).dylib
+CFG_STATIC_LIB_NAME_i686-apple-darwin=lib$(1).a
+CFG_LIB_GLOB_i686-apple-darwin=lib$(1)-*.dylib
+CFG_LIB_DSYM_GLOB_i686-apple-darwin=lib$(1)-*.dylib.dSYM
+CFG_CFLAGS_i686-apple-darwin := -m32 -arch i386 $(CFLAGS)
+CFG_GCCISH_CFLAGS_i686-apple-darwin := -Wall -Werror -g -fPIC -m32 -arch i386 $(CFLAGS)
+CFG_GCCISH_CXXFLAGS_i686-apple-darwin := -fno-rtti $(CXXFLAGS)
+CFG_GCCISH_LINK_FLAGS_i686-apple-darwin := -dynamiclib -pthread  -framework CoreServices -m32
+CFG_GCCISH_DEF_FLAG_i686-apple-darwin := -Wl,-exported_symbols_list,
+CFG_GCCISH_PRE_LIB_FLAGS_i686-apple-darwin :=
+CFG_GCCISH_POST_LIB_FLAGS_i686-apple-darwin :=
+CFG_DEF_SUFFIX_i686-apple-darwin := .darwin.def
+CFG_LLC_FLAGS_i686-apple-darwin :=
+CFG_INSTALL_NAME_i686-apple-darwin = -Wl,-install_name,@rpath/$(1)
+CFG_EXE_SUFFIX_i686-apple-darwin :=
+CFG_WINDOWSY_i686-apple-darwin :=
+CFG_UNIXY_i686-apple-darwin := 1
+CFG_PATH_MUNGE_i686-apple-darwin := true
+CFG_LDPATH_i686-apple-darwin :=
+CFG_RUN_i686-apple-darwin=$(2)
+CFG_RUN_TARG_i686-apple-darwin=$(call CFG_RUN_i686-apple-darwin,,$(2))
+
diff --git a/mk/cfg/i686-unknown-linux-gnu b/mk/cfg/i686-unknown-linux-gnu
new file mode 100644 (file)
index 0000000..0b34e0f
--- /dev/null
@@ -0,0 +1,27 @@
+# i686-unknown-linux-gnu configuration
+CC_i686-unknown-linux-gnu=$(CC)
+CXX_i686-unknown-linux-gnu=$(CXX)
+CPP_i686-unknown-linux-gnu=$(CPP)
+AR_i686-unknown-linux-gnu=$(AR)
+CFG_LIB_NAME_i686-unknown-linux-gnu=lib$(1).so
+CFG_STATIC_LIB_NAME_i686-unknown-linux-gnu=lib$(1).a
+CFG_LIB_GLOB_i686-unknown-linux-gnu=lib$(1)-*.so
+CFG_LIB_DSYM_GLOB_i686-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
+CFG_CFLAGS_i686-unknown-linux-gnu := -m32 $(CFLAGS)
+CFG_GCCISH_CFLAGS_i686-unknown-linux-gnu := -Wall -Werror -g -fPIC -m32 $(CFLAGS)
+CFG_GCCISH_CXXFLAGS_i686-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
+CFG_GCCISH_LINK_FLAGS_i686-unknown-linux-gnu := -shared -fPIC -ldl -pthread  -lrt -g -m32
+CFG_GCCISH_DEF_FLAG_i686-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
+CFG_GCCISH_PRE_LIB_FLAGS_i686-unknown-linux-gnu := -Wl,-whole-archive
+CFG_GCCISH_POST_LIB_FLAGS_i686-unknown-linux-gnu := -Wl,-no-whole-archive
+CFG_DEF_SUFFIX_i686-unknown-linux-gnu := .linux.def
+CFG_LLC_FLAGS_i686-unknown-linux-gnu :=
+CFG_INSTALL_NAME_i686-unknown-linux-gnu =
+CFG_EXE_SUFFIX_i686-unknown-linux-gnu =
+CFG_WINDOWSY_i686-unknown-linux-gnu :=
+CFG_UNIXY_i686-unknown-linux-gnu := 1
+CFG_PATH_MUNGE_i686-unknown-linux-gnu := true
+CFG_LDPATH_i686-unknown-linux-gnu :=
+CFG_RUN_i686-unknown-linux-gnu=$(2)
+CFG_RUN_TARG_i686-unknown-linux-gnu=$(call CFG_RUN_i686-unknown-linux-gnu,,$(2))
+
diff --git a/mk/cfg/i686-w64-mingw32 b/mk/cfg/i686-w64-mingw32
new file mode 100644 (file)
index 0000000..b62b805
--- /dev/null
@@ -0,0 +1,31 @@
+# i686-w64-mingw32 configuration
+CROSS_PREFIX_i686-w64-mingw32=i686-w64-mingw32-
+CC_i686-w64-mingw32=gcc
+CXX_i686-w64-mingw32=g++
+CPP_i686-w64-mingw32=gcc -E
+AR_i686-w64-mingw32=ar
+CFG_LIB_NAME_i686-w64-mingw32=$(1).dll
+CFG_STATIC_LIB_NAME_i686-w64-mingw32=$(1).lib
+CFG_LIB_GLOB_i686-w64-mingw32=$(1)-*.dll
+CFG_LIB_DSYM_GLOB_i686-w64-mingw32=$(1)-*.dylib.dSYM
+CFG_CFLAGS_i686-w64-mingw32 := -march=i686 -m32 -D_WIN32_WINNT=0x0600 $(CFLAGS)
+CFG_GCCISH_CFLAGS_i686-w64-mingw32 := -Wall -Werror -g -m32 -D_WIN32_WINNT=0x0600 $(CFLAGS)
+CFG_GCCISH_CXXFLAGS_i686-w64-mingw32 := -fno-rtti $(CXXFLAGS)
+CFG_GCCISH_LINK_FLAGS_i686-w64-mingw32 := -shared -g -m32
+CFG_GCCISH_DEF_FLAG_i686-w64-mingw32 :=
+CFG_GCCISH_PRE_LIB_FLAGS_i686-w64-mingw32 :=
+CFG_GCCISH_POST_LIB_FLAGS_i686-w64-mingw32 :=
+CFG_DEF_SUFFIX_i686-w64-mingw32 := .mingw32.def
+CFG_LLC_FLAGS_i686-w64-mingw32 :=
+CFG_INSTALL_NAME_i686-w64-mingw32 =
+CFG_EXE_SUFFIX_i686-w64-mingw32 := .exe
+CFG_WINDOWSY_i686-w64-mingw32 := 1
+CFG_UNIXY_i686-w64-mingw32 :=
+CFG_PATH_MUNGE_i686-w64-mingw32 :=
+CFG_LDPATH_i686-w64-mingw32 :=$(CFG_LDPATH_i686-w64-mingw32):$(PATH)
+CFG_RUN_i686-w64-mingw32=PATH="$(CFG_LDPATH_i686-w64-mingw32):$(1)" $(2)
+CFG_RUN_TARG_i686-w64-mingw32=$(call CFG_RUN_i686-w64-mingw32,$(HLIB$(1)_H_$(CFG_BUILD)),$(2))
+# Stop rustc from OOMing when building itself (I think)
+RUSTC_FLAGS_i686-w64-mingw32=-C link-args="-Wl,--large-address-aware"
+RUSTC_CROSS_FLAGS_i686-w64-mingw32 :=
+
diff --git a/mk/cfg/mips-unknown-linux-gnu b/mk/cfg/mips-unknown-linux-gnu
new file mode 100644 (file)
index 0000000..c01fdf0
--- /dev/null
@@ -0,0 +1,27 @@
+# mips-unknown-linux-gnu configuration
+CC_mips-unknown-linux-gnu=mips-linux-gnu-gcc
+CXX_mips-unknown-linux-gnu=mips-linux-gnu-g++
+CPP_mips-unknown-linux-gnu=mips-linux-gnu-gcc -E
+AR_mips-unknown-linux-gnu=mips-linux-gnu-ar
+CFG_LIB_NAME_mips-unknown-linux-gnu=lib$(1).so
+CFG_STATIC_LIB_NAME_mips-unknown-linux-gnu=lib$(1).a
+CFG_LIB_GLOB_mips-unknown-linux-gnu=lib$(1)-*.so
+CFG_LIB_DSYM_GLOB_mips-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
+CFG_CFLAGS_mips-unknown-linux-gnu := -mips32r2 -msoft-float -mabi=32 -mno-compact-eh $(CFLAGS)
+CFG_GCCISH_CFLAGS_mips-unknown-linux-gnu := -Wall -g -fPIC -mips32r2 -msoft-float -mabi=32 -mno-compact-eh $(CFLAGS)
+CFG_GCCISH_CXXFLAGS_mips-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
+CFG_GCCISH_LINK_FLAGS_mips-unknown-linux-gnu := -shared -fPIC -g -mips32r2 -msoft-float -mabi=32
+CFG_GCCISH_DEF_FLAG_mips-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
+CFG_GCCISH_PRE_LIB_FLAGS_mips-unknown-linux-gnu := -Wl,-whole-archive
+CFG_GCCISH_POST_LIB_FLAGS_mips-unknown-linux-gnu := -Wl,-no-whole-archive
+CFG_DEF_SUFFIX_mips-unknown-linux-gnu := .linux.def
+CFG_LLC_FLAGS_mips-unknown-linux-gnu :=
+CFG_INSTALL_NAME_mips-unknown-linux-gnu =
+CFG_EXE_SUFFIX_mips-unknown-linux-gnu :=
+CFG_WINDOWSY_mips-unknown-linux-gnu :=
+CFG_UNIXY_mips-unknown-linux-gnu := 1
+CFG_PATH_MUNGE_mips-unknown-linux-gnu := true
+CFG_LDPATH_mips-unknown-linux-gnu :=
+CFG_RUN_mips-unknown-linux-gnu=
+CFG_RUN_TARG_mips-unknown-linux-gnu=
+RUSTC_FLAGS_mips-unknown-linux-gnu := -C target-cpu=mips32r2 -C target-feature="+mips32r2,+o32" -C soft-float
diff --git a/mk/cfg/mipsel-linux b/mk/cfg/mipsel-linux
new file mode 100644 (file)
index 0000000..963965c
--- /dev/null
@@ -0,0 +1,27 @@
+# mipsel-linux configuration
+CC_mipsel-linux=mipsel-linux-gcc
+CXX_mipsel-linux=mipsel-linux-g++
+CPP_mipsel-linux=mipsel-linux-gcc
+AR_mipsel-linux=mipsel-linux-ar
+CFG_LIB_NAME_mipsel-linux=lib$(1).so
+CFG_STATIC_LIB_NAME_mipsel-linux=lib$(1).a
+CFG_LIB_GLOB_mipsel-linux=lib$(1)-*.so
+CFG_LIB_DSYM_GLOB_mipsel-linux=lib$(1)-*.dylib.dSYM
+CFG_CFLAGS_mipsel-linux := -mips32 -mabi=32 $(CFLAGS)
+CFG_GCCISH_CFLAGS_mipsel-linux := -Wall -g -fPIC -mips32 -mabi=32 $(CFLAGS)
+CFG_GCCISH_CXXFLAGS_mipsel-linux := -fno-rtti $(CXXFLAGS)
+CFG_GCCISH_LINK_FLAGS_mipsel-linux := -shared -fPIC -g -mips32
+CFG_GCCISH_DEF_FLAG_mipsel-linux := -Wl,--export-dynamic,--dynamic-list=
+CFG_GCCISH_PRE_LIB_FLAGS_mipsel-linux := -Wl,-whole-archive
+CFG_GCCISH_POST_LIB_FLAGS_mipsel-linux := -Wl,-no-whole-archive
+CFG_DEF_SUFFIX_mipsel-linux := .linux.def
+CFG_LLC_FLAGS_mipsel-linux :=
+CFG_INSTALL_NAME_mipsel-linux =
+CFG_EXE_SUFFIX_mipsel-linux :=
+CFG_WINDOWSY_mipsel-linux :=
+CFG_UNIXY_mipsel-linux := 1
+CFG_PATH_MUNGE_mipsel-linux := true
+CFG_LDPATH_mipsel-linux :=
+CFG_RUN_mipsel-linux=
+CFG_RUN_TARG_mipsel-linux=
+RUSTC_FLAGS_mipsel-linux := -C target-cpu=mips32 -C target-feature="+mips32,+o32"
diff --git a/mk/cfg/x86_64-apple-darwin b/mk/cfg/x86_64-apple-darwin
new file mode 100644 (file)
index 0000000..67b32a6
--- /dev/null
@@ -0,0 +1,26 @@
+# x86_64-apple-darwin configuration
+CC_x86_64-apple-darwin=$(CC)
+CXX_x86_64-apple-darwin=$(CXX)
+CPP_x86_64-apple-darwin=$(CPP)
+AR_x86_64-apple-darwin=$(AR)
+CFG_LIB_NAME_x86_64-apple-darwin=lib$(1).dylib
+CFG_STATIC_LIB_NAME_x86_64-apple-darwin=lib$(1).a
+CFG_LIB_GLOB_x86_64-apple-darwin=lib$(1)-*.dylib
+CFG_LIB_DSYM_GLOB_x86_64-apple-darwin=lib$(1)-*.dylib.dSYM
+CFG_CFLAGS_x86_64-apple-darwin := -m64 -arch x86_64 $(CFLAGS)
+CFG_GCCISH_CFLAGS_x86_64-apple-darwin := -Wall -Werror -g -fPIC -m64 -arch x86_64 $(CFLAGS)
+CFG_GCCISH_CXXFLAGS_x86_64-apple-darwin := -fno-rtti $(CXXFLAGS)
+CFG_GCCISH_LINK_FLAGS_x86_64-apple-darwin := -dynamiclib -pthread  -framework CoreServices -m64
+CFG_GCCISH_DEF_FLAG_x86_64-apple-darwin := -Wl,-exported_symbols_list,
+CFG_GCCISH_PRE_LIB_FLAGS_x86_64-apple-darwin :=
+CFG_GCCISH_POST_LIB_FLAGS_x86_64-apple-darwin :=
+CFG_DEF_SUFFIX_x86_64-apple-darwin := .darwin.def
+CFG_LLC_FLAGS_x86_64-apple-darwin :=
+CFG_INSTALL_NAME_x86_64-apple-darwin = -Wl,-install_name,@rpath/$(1)
+CFG_EXE_SUFFIX_x86_64-apple-darwin :=
+CFG_WINDOWSY_x86_64-apple-darwin :=
+CFG_UNIXY_x86_64-apple-darwin := 1
+CFG_PATH_MUNGE_x86_64-apple-darwin := true
+CFG_LDPATH_x86_64-apple-darwin :=
+CFG_RUN_x86_64-apple-darwin=$(2)
+CFG_RUN_TARG_x86_64-apple-darwin=$(call CFG_RUN_x86_64-apple-darwin,,$(2))
diff --git a/mk/cfg/x86_64-unknown-dragonfly b/mk/cfg/x86_64-unknown-dragonfly
new file mode 100644 (file)
index 0000000..48e872c
--- /dev/null
@@ -0,0 +1,25 @@
+# x86_64-pc-dragonfly-elf configuration
+CC_x86_64-unknown-dragonfly=$(CC)
+CXX_x86_64-unknown-dragonfly=$(CXX)
+CPP_x86_64-unknown-dragonfly=$(CPP)
+AR_x86_64-unknown-dragonfly=$(AR)
+CFG_LIB_NAME_x86_64-unknown-dragonfly=lib$(1).so
+CFG_STATIC_LIB_NAME_x86_64-unknown-dragonfly=lib$(1).a
+CFG_LIB_GLOB_x86_64-unknown-dragonfly=lib$(1)-*.so
+CFG_LIB_DSYM_GLOB_x86_64-unknown-dragonfly=$(1)-*.dylib.dSYM
+CFG_CFLAGS_x86_64-unknown-dragonfly := -I/usr/include -I/usr/local/include $(CFLAGS)
+CFG_GCCISH_CFLAGS_x86_64-unknown-dragonfly := -Wall -Werror -g -fPIC -I/usr/include -I/usr/local/include $(CFLAGS)
+CFG_GCCISH_LINK_FLAGS_x86_64-unknown-dragonfly := -shared -fPIC -g -pthread  -lrt
+CFG_GCCISH_DEF_FLAG_x86_64-unknown-dragonfly := -Wl,--export-dynamic,--dynamic-list=
+CFG_GCCISH_PRE_LIB_FLAGS_x86_64-unknown-dragonfly := -Wl,-whole-archive
+CFG_GCCISH_POST_LIB_FLAGS_x86_64-unknown-dragonfly := -Wl,-no-whole-archive
+CFG_DEF_SUFFIX_x86_64-unknown-dragonfly := .bsd.def
+CFG_LLC_FLAGS_x86_64-unknown-dragonfly :=
+CFG_INSTALL_NAME_x86_64-unknown-dragonfly =
+CFG_EXE_SUFFIX_x86_64-unknown-dragonfly :=
+CFG_WINDOWSY_x86_64-unknown-dragonfly :=
+CFG_UNIXY_x86_64-unknown-dragonfly := 1
+CFG_PATH_MUNGE_x86_64-unknown-dragonfly :=
+CFG_LDPATH_x86_64-unknown-dragonfly :=
+CFG_RUN_x86_64-unknown-dragonfly=$(2)
+CFG_RUN_TARG_x86_64-unknown-dragonfly=$(call CFG_RUN_x86_64-unknown-dragonfly,,$(2))
diff --git a/mk/cfg/x86_64-unknown-freebsd b/mk/cfg/x86_64-unknown-freebsd
new file mode 100644 (file)
index 0000000..8ad42d2
--- /dev/null
@@ -0,0 +1,25 @@
+# x86_64-unknown-freebsd configuration
+CC_x86_64-unknown-freebsd=$(CC)
+CXX_x86_64-unknown-freebsd=$(CXX)
+CPP_x86_64-unknown-freebsd=$(CPP)
+AR_x86_64-unknown-freebsd=$(AR)
+CFG_LIB_NAME_x86_64-unknown-freebsd=lib$(1).so
+CFG_STATIC_LIB_NAME_x86_64-unknown-freebsd=lib$(1).a
+CFG_LIB_GLOB_x86_64-unknown-freebsd=lib$(1)-*.so
+CFG_LIB_DSYM_GLOB_x86_64-unknown-freebsd=$(1)-*.dylib.dSYM
+CFG_CFLAGS_x86_64-unknown-freebsd := -I/usr/local/include $(CFLAGS)
+CFG_GCCISH_CFLAGS_x86_64-unknown-freebsd := -Wall -Werror -g -fPIC -I/usr/local/include $(CFLAGS)
+CFG_GCCISH_LINK_FLAGS_x86_64-unknown-freebsd := -shared -fPIC -g -pthread  -lrt
+CFG_GCCISH_DEF_FLAG_x86_64-unknown-freebsd := -Wl,--export-dynamic,--dynamic-list=
+CFG_GCCISH_PRE_LIB_FLAGS_x86_64-unknown-freebsd := -Wl,-whole-archive
+CFG_GCCISH_POST_LIB_FLAGS_x86_64-unknown-freebsd := -Wl,-no-whole-archive
+CFG_DEF_SUFFIX_x86_64-unknown-freebsd := .bsd.def
+CFG_LLC_FLAGS_x86_64-unknown-freebsd :=
+CFG_INSTALL_NAME_x86_64-unknown-freebsd =
+CFG_EXE_SUFFIX_x86_64-unknown-freebsd :=
+CFG_WINDOWSY_x86_64-unknown-freebsd :=
+CFG_UNIXY_x86_64-unknown-freebsd := 1
+CFG_PATH_MUNGE_x86_64-unknown-freebsd :=
+CFG_LDPATH_x86_64-unknown-freebsd :=
+CFG_RUN_x86_64-unknown-freebsd=$(2)
+CFG_RUN_TARG_x86_64-unknown-freebsd=$(call CFG_RUN_x86_64-unknown-freebsd,,$(2))
diff --git a/mk/cfg/x86_64-unknown-linux-gnu b/mk/cfg/x86_64-unknown-linux-gnu
new file mode 100644 (file)
index 0000000..d6d0fd7
--- /dev/null
@@ -0,0 +1,26 @@
+# x86_64-unknown-linux-gnu configuration
+CC_x86_64-unknown-linux-gnu=$(CC)
+CXX_x86_64-unknown-linux-gnu=$(CXX)
+CPP_x86_64-unknown-linux-gnu=$(CPP)
+AR_x86_64-unknown-linux-gnu=$(AR)
+CFG_LIB_NAME_x86_64-unknown-linux-gnu=lib$(1).so
+CFG_STATIC_LIB_NAME_x86_64-unknown-linux-gnu=lib$(1).a
+CFG_LIB_GLOB_x86_64-unknown-linux-gnu=lib$(1)-*.so
+CFG_LIB_DSYM_GLOB_x86_64-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
+CFG_CFLAGS_x86_64-unknown-linux-gnu := -m64
+CFG_GCCISH_CFLAGS_x86_64-unknown-linux-gnu := -Wall -Werror -g -fPIC -m64
+CFG_GCCISH_CXXFLAGS_x86_64-unknown-linux-gnu := -fno-rtti
+CFG_GCCISH_LINK_FLAGS_x86_64-unknown-linux-gnu := -shared -fPIC -ldl -pthread  -lrt -g -m64
+CFG_GCCISH_DEF_FLAG_x86_64-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
+CFG_GCCISH_PRE_LIB_FLAGS_x86_64-unknown-linux-gnu := -Wl,-whole-archive
+CFG_GCCISH_POST_LIB_FLAGS_x86_64-unknown-linux-gnu := -Wl,-no-whole-archive
+CFG_DEF_SUFFIX_x86_64-unknown-linux-gnu := .linux.def
+CFG_LLC_FLAGS_x86_64-unknown-linux-gnu :=
+CFG_INSTALL_NAME_x86_64-unknown-linux-gnu =
+CFG_EXE_SUFFIX_x86_64-unknown-linux-gnu =
+CFG_WINDOWSY_x86_64-unknown-linux-gnu :=
+CFG_UNIXY_x86_64-unknown-linux-gnu := 1
+CFG_PATH_MUNGE_x86_64-unknown-linux-gnu := true
+CFG_LDPATH_x86_64-unknown-linux-gnu :=
+CFG_RUN_x86_64-unknown-linux-gnu=$(2)
+CFG_RUN_TARG_x86_64-unknown-linux-gnu=$(call CFG_RUN_x86_64-unknown-linux-gnu,,$(2))
diff --git a/mk/cfg/x86_64-w64-mingw32 b/mk/cfg/x86_64-w64-mingw32
new file mode 100644 (file)
index 0000000..b292a83
--- /dev/null
@@ -0,0 +1,28 @@
+# x86_64-w64-mingw32 configuration
+CROSS_PREFIX_x86_64-w64-mingw32=x86_64-w64-mingw32-
+CC_x86_64-w64-mingw32=gcc
+CXX_x86_64-w64-mingw32=g++
+CPP_x86_64-w64-mingw32=gcc -E
+AR_x86_64-w64-mingw32=ar
+CFG_LIB_NAME_x86_64-w64-mingw32=$(1).dll
+CFG_STATIC_LIB_NAME_x86_64-w64-mingw32=$(1).lib
+CFG_LIB_GLOB_x86_64-w64-mingw32=$(1)-*.dll
+CFG_LIB_DSYM_GLOB_x86_64-w64-mingw32=$(1)-*.dylib.dSYM
+CFG_CFLAGS_x86_64-w64-mingw32 := -m64 -D_WIN32_WINNT=0x0600 $(CFLAGS)
+CFG_GCCISH_CFLAGS_x86_64-w64-mingw32 := -Wall -Werror -g -m64 -D_WIN32_WINNT=0x0600 $(CFLAGS)
+CFG_GCCISH_CXXFLAGS_x86_64-w64-mingw32 := -fno-rtti $(CXXFLAGS)
+CFG_GCCISH_LINK_FLAGS_x86_64-w64-mingw32 := -shared -g -m64
+CFG_GCCISH_DEF_FLAG_x86_64-w64-mingw32 :=
+CFG_GCCISH_PRE_LIB_FLAGS_x86_64-w64-mingw32 :=
+CFG_GCCISH_POST_LIB_FLAGS_x86_64-w64-mingw32 :=
+CFG_DEF_SUFFIX_x86_64-w64-mingw32 := .mingw32.def
+CFG_LLC_FLAGS_x86_64-w64-mingw32 :=
+CFG_INSTALL_NAME_x86_64-w64-mingw32 =
+CFG_EXE_SUFFIX_x86_64-w64-mingw32 := .exe
+CFG_WINDOWSY_x86_64-w64-mingw32 := 1
+CFG_UNIXY_x86_64-w64-mingw32 :=
+CFG_PATH_MUNGE_x86_64-w64-mingw32 :=
+CFG_LDPATH_x86_64-w64-mingw32 :=$(CFG_LDPATH_x86_64-w64-mingw32):$(PATH)
+CFG_RUN_x86_64-w64-mingw32=PATH="$(CFG_LDPATH_x86_64-w64-mingw32):$(1)" $(2)
+CFG_RUN_TARG_x86_64-w64-mingw32=$(call CFG_RUN_x86_64-w64-mingw32,$(HLIB$(1)_H_$(CFG_BUILD)),$(2))
+RUSTC_CROSS_FLAGS_x86_64-w64-mingw32 :=
index ab73a72f00a83af1caea333fd202d8bff06fd554..9dbcb2c9bbcd567f56ff905d890e7d8db61cbd9c 100644 (file)
@@ -27,7 +27,7 @@
 ######################################################################
 DOCS := index intro tutorial guide guide-ffi guide-macros guide-lifetimes \
        guide-tasks guide-container guide-pointers guide-testing \
-       guide-plugin complement-bugreport \
+       guide-plugin guide-crates complement-bugreport \
        complement-lang-faq complement-design-faq complement-project-faq rust \
     rustdoc guide-unsafe guide-strings reference
 
index 177e4de310324dd6f2d3c1e35f0e50d5b80d8119..bce43902056267131d668cc48b8727664a0d5e8e 100644 (file)
@@ -38,7 +38,7 @@ endif
 # the stamp in the source dir.
 $$(LLVM_STAMP_$(1)): $(S)src/rustllvm/llvm-auto-clean-trigger
        @$$(call E, make: cleaning llvm)
-       $(Q)$(MAKE) clean-llvm
+       $(Q)$(MAKE) clean-llvm$(1)
        @$$(call E, make: done cleaning llvm)
        touch $$@
 
index e927f6ad468fa0cc8e3f9f31ad57071d59cab72d..cd08228978e15daf0f4db59268f5a4dd12ed7520 100644 (file)
@@ -157,13 +157,6 @@ RUSTFLAGS_STAGE1 += -C prefer-dynamic
 # by not emitting them.
 RUSTFLAGS_STAGE0 += -Z no-landing-pads
 
-# Go fast for stage0, and also for stage1/stage2 if optimization is off.
-RUSTFLAGS_STAGE0 += -C codegen-units=4
-ifdef CFG_DISABLE_OPTIMIZE
-       RUSTFLAGS_STAGE1 += -C codegen-units=4
-       RUSTFLAGS_STAGE2 += -C codegen-units=4
-endif
-
 # platform-specific auto-configuration
 include $(CFG_SRC_DIR)mk/platform.mk
 
index 9db9138d5e9efebde691820fd644f88d91144b16..6da01efcaaad24e1a089d1b366e2ac25515482bf 100644 (file)
@@ -113,470 +113,7 @@ $(foreach cvar,CC CXX CPP CFLAGS CXXFLAGS CPPFLAGS, \
 
 CFG_RLIB_GLOB=lib$(1)-*.rlib
 
-# x86_64-unknown-linux-gnu configuration
-CC_x86_64-unknown-linux-gnu=$(CC)
-CXX_x86_64-unknown-linux-gnu=$(CXX)
-CPP_x86_64-unknown-linux-gnu=$(CPP)
-AR_x86_64-unknown-linux-gnu=$(AR)
-CFG_LIB_NAME_x86_64-unknown-linux-gnu=lib$(1).so
-CFG_STATIC_LIB_NAME_x86_64-unknown-linux-gnu=lib$(1).a
-CFG_LIB_GLOB_x86_64-unknown-linux-gnu=lib$(1)-*.so
-CFG_LIB_DSYM_GLOB_x86_64-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
-CFG_CFLAGS_x86_64-unknown-linux-gnu := -m64
-CFG_GCCISH_CFLAGS_x86_64-unknown-linux-gnu := -Wall -Werror -g -fPIC -m64
-CFG_GCCISH_CXXFLAGS_x86_64-unknown-linux-gnu := -fno-rtti
-CFG_GCCISH_LINK_FLAGS_x86_64-unknown-linux-gnu := -shared -fPIC -ldl -pthread  -lrt -g -m64
-CFG_GCCISH_DEF_FLAG_x86_64-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
-CFG_GCCISH_PRE_LIB_FLAGS_x86_64-unknown-linux-gnu := -Wl,-whole-archive
-CFG_GCCISH_POST_LIB_FLAGS_x86_64-unknown-linux-gnu := -Wl,-no-whole-archive
-CFG_DEF_SUFFIX_x86_64-unknown-linux-gnu := .linux.def
-CFG_LLC_FLAGS_x86_64-unknown-linux-gnu :=
-CFG_INSTALL_NAME_x86_64-unknown-linux-gnu =
-CFG_EXE_SUFFIX_x86_64-unknown-linux-gnu =
-CFG_WINDOWSY_x86_64-unknown-linux-gnu :=
-CFG_UNIXY_x86_64-unknown-linux-gnu := 1
-CFG_PATH_MUNGE_x86_64-unknown-linux-gnu := true
-CFG_LDPATH_x86_64-unknown-linux-gnu :=
-CFG_RUN_x86_64-unknown-linux-gnu=$(2)
-CFG_RUN_TARG_x86_64-unknown-linux-gnu=$(call CFG_RUN_x86_64-unknown-linux-gnu,,$(2))
-
-# i686-unknown-linux-gnu configuration
-CC_i686-unknown-linux-gnu=$(CC)
-CXX_i686-unknown-linux-gnu=$(CXX)
-CPP_i686-unknown-linux-gnu=$(CPP)
-AR_i686-unknown-linux-gnu=$(AR)
-CFG_LIB_NAME_i686-unknown-linux-gnu=lib$(1).so
-CFG_STATIC_LIB_NAME_i686-unknown-linux-gnu=lib$(1).a
-CFG_LIB_GLOB_i686-unknown-linux-gnu=lib$(1)-*.so
-CFG_LIB_DSYM_GLOB_i686-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
-CFG_CFLAGS_i686-unknown-linux-gnu := -m32 $(CFLAGS)
-CFG_GCCISH_CFLAGS_i686-unknown-linux-gnu := -Wall -Werror -g -fPIC -m32 $(CFLAGS)
-CFG_GCCISH_CXXFLAGS_i686-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
-CFG_GCCISH_LINK_FLAGS_i686-unknown-linux-gnu := -shared -fPIC -ldl -pthread  -lrt -g -m32
-CFG_GCCISH_DEF_FLAG_i686-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
-CFG_GCCISH_PRE_LIB_FLAGS_i686-unknown-linux-gnu := -Wl,-whole-archive
-CFG_GCCISH_POST_LIB_FLAGS_i686-unknown-linux-gnu := -Wl,-no-whole-archive
-CFG_DEF_SUFFIX_i686-unknown-linux-gnu := .linux.def
-CFG_LLC_FLAGS_i686-unknown-linux-gnu :=
-CFG_INSTALL_NAME_i686-unknown-linux-gnu =
-CFG_EXE_SUFFIX_i686-unknown-linux-gnu =
-CFG_WINDOWSY_i686-unknown-linux-gnu :=
-CFG_UNIXY_i686-unknown-linux-gnu := 1
-CFG_PATH_MUNGE_i686-unknown-linux-gnu := true
-CFG_LDPATH_i686-unknown-linux-gnu :=
-CFG_RUN_i686-unknown-linux-gnu=$(2)
-CFG_RUN_TARG_i686-unknown-linux-gnu=$(call CFG_RUN_i686-unknown-linux-gnu,,$(2))
-
-# arm-apple-ios configuration
-CFG_SDK_NAME_arm-apple-ios = iphoneos
-CFG_SDK_ARCHS_arm-apple-ios = armv7
-ifneq ($(findstring darwin,$(CFG_OSTYPE)),)
-CFG_IOS_SDK = $(shell xcrun --show-sdk-path -sdk iphoneos 2>/dev/null)
-CFG_IOS_FLAGS = -target armv7-apple-darwin -isysroot $(CFG_IOS_SDK) -mios-version-min=7.0
-CC_arm-apple-ios = $(shell xcrun -find -sdk iphoneos clang)
-CXX_arm-apple-ios = $(shell xcrun -find -sdk iphoneos clang++)
-CPP_arm-apple-ios = $(shell xcrun -find -sdk iphoneos clang++)
-AR_arm-apple-ios = $(shell xcrun -find -sdk iphoneos ar)
-endif
-CFG_LIB_NAME_arm-apple-ios = lib$(1).a
-CFG_LIB_GLOB_arm-apple-ios = lib$(1)-*.a
-CFG_STATIC_LIB_NAME_arm-apple-ios=lib$(1).a
-CFG_LIB_DSYM_GLOB_arm-apple-ios = lib$(1)-*.a.dSYM
-CFG_CFLAGS_arm-apple-ios := -arch armv7 -mfpu=vfp3 $(CFG_IOS_FLAGS)
-CFG_GCCISH_CFLAGS_arm-apple-ios := -Wall -Werror -g -fPIC $(CFG_IOS_FLAGS) -mfpu=vfp3 -arch armv7
-CFG_GCCISH_CXXFLAGS_arm-apple-ios := -fno-rtti $(CFG_IOS_FLAGS) -I$(CFG_IOS_SDK)/usr/include/c++/4.2.1
-CFG_GCCISH_LINK_FLAGS_arm-apple-ios := -lpthread -syslibroot $(CFG_IOS_SDK) -Wl,-no_compact_unwind
-CFG_GCCISH_DEF_FLAG_arm-apple-ios := -Wl,-exported_symbols_list,
-CFG_GCCISH_PRE_LIB_FLAGS_arm-apple-ios :=
-CFG_GCCISH_POST_LIB_FLAGS_arm-apple-ios :=
-CFG_DEF_SUFFIX_arm-apple-ios := .darwin.def
-CFG_LLC_FLAGS_arm-apple-ios := -mattr=+vfp3,+v7,+thumb2,+neon -march=arm
-CFG_INSTALL_NAME_arm-apple-ios = -Wl,-install_name,@rpath/$(1)
-CFG_EXE_SUFFIX_arm-apple-ios :=
-CFG_WINDOWSY_arm-apple-ios :=
-CFG_UNIXY_arm-apple-ios := 1
-CFG_PATH_MUNGE_arm-apple-ios := true
-CFG_LDPATH_arm-apple-ios :=
-CFG_RUN_arm-apple-ios = $(2)
-CFG_RUN_TARG_arm-apple-ios = $(call CFG_RUN_arm-apple-ios,,$(2))
-RUSTC_FLAGS_arm-apple-ios := -C relocation_model=pic
-RUSTC_CROSS_FLAGS_arm-apple-ios :=-C relocation_model=pic
-
-# i386-apple-ios configuration
-CFG_SDK_NAME_i386-apple-ios = iphonesimulator
-CFG_SDK_ARCHS_i386-apple-ios = i386
-ifneq ($(findstring darwin,$(CFG_OSTYPE)),)
-CFG_IOSSIM_SDK = $(shell xcrun --show-sdk-path -sdk iphonesimulator 2>/dev/null)
-CFG_IOSSIM_FLAGS = -target i386-apple-ios -isysroot $(CFG_IOSSIM_SDK) -mios-simulator-version-min=7.0
-CC_i386-apple-ios = $(shell xcrun -find -sdk iphonesimulator clang)
-CXX_i386-apple-ios = $(shell xcrun -find -sdk iphonesimulator clang++)
-CPP_i386-apple-ios = $(shell xcrun -find -sdk iphonesimulator clang++)
-AR_i386-apple-ios = $(shell xcrun -find -sdk iphonesimulator ar)
-endif
-CFG_LIB_NAME_i386-apple-ios = lib$(1).a
-CFG_LIB_GLOB_i386-apple-ios = lib$(1)-*.dylib
-CFG_STATIC_LIB_NAME_i386-apple-ios=lib$(1).a
-CFG_LIB_DSYM_GLOB_i386-apple-ios = lib$(1)-*.dylib.dSYM
-CFG_CFLAGS_i386-apple-ios = $(CFG_IOSSIM_FLAGS)
-CFG_GCCISH_CFLAGS_i386-apple-ios = -Wall -Werror -g -fPIC -m32 $(CFG_IOSSIM_FLAGS)
-CFG_GCCISH_CXXFLAGS_i386-apple-ios = -fno-rtti $(CFG_IOSSIM_FLAGS) -I$(CFG_IOSSIM_SDK)/usr/include/c++/4.2.1
-CFG_GCCISH_LINK_FLAGS_i386-apple-ios = -lpthread -Wl,-no_compact_unwind -m32 -Wl,-syslibroot $(CFG_IOSSIM_SDK)
-CFG_GCCISH_DEF_FLAG_i386-apple-ios = -Wl,-exported_symbols_list,
-CFG_GCCISH_PRE_LIB_FLAGS_i386-apple-ios =
-CFG_GCCISH_POST_LIB_FLAGS_i386-apple-ios =
-CFG_DEF_SUFFIX_i386-apple-ios = .darwin.def
-CFG_LLC_FLAGS_i386-apple-ios =
-CFG_INSTALL_NAME_i386-apple-ios = -Wl,-install_name,@rpath/$(1)
-CFG_EXE_SUFFIX_i386-apple-ios =
-CFG_WINDOWSY_i386-apple-ios =
-CFG_UNIXY_i386-apple-ios = 1
-CFG_PATH_MUNGE_i386-apple-ios = true
-CFG_LDPATH_i386-apple-ios =
-CFG_RUN_i386-apple-ios = $(2)
-CFG_RUN_TARG_i386-apple-ios = $(call CFG_RUN_i386-apple-ios,,$(2))
-CFG_JEMALLOC_CFLAGS_i386-apple-ios = -target i386-apple-ios -Wl,-syslibroot $(CFG_IOSSIM_SDK) -Wl,-no_compact_unwind
-
-# x86_64-apple-darwin configuration
-CC_x86_64-apple-darwin=$(CC)
-CXX_x86_64-apple-darwin=$(CXX)
-CPP_x86_64-apple-darwin=$(CPP)
-AR_x86_64-apple-darwin=$(AR)
-CFG_LIB_NAME_x86_64-apple-darwin=lib$(1).dylib
-CFG_STATIC_LIB_NAME_x86_64-apple-darwin=lib$(1).a
-CFG_LIB_GLOB_x86_64-apple-darwin=lib$(1)-*.dylib
-CFG_LIB_DSYM_GLOB_x86_64-apple-darwin=lib$(1)-*.dylib.dSYM
-CFG_CFLAGS_x86_64-apple-darwin := -m64 -arch x86_64 $(CFLAGS)
-CFG_GCCISH_CFLAGS_x86_64-apple-darwin := -Wall -Werror -g -fPIC -m64 -arch x86_64 $(CFLAGS)
-CFG_GCCISH_CXXFLAGS_x86_64-apple-darwin := -fno-rtti $(CXXFLAGS)
-CFG_GCCISH_LINK_FLAGS_x86_64-apple-darwin := -dynamiclib -pthread  -framework CoreServices -m64
-CFG_GCCISH_DEF_FLAG_x86_64-apple-darwin := -Wl,-exported_symbols_list,
-CFG_GCCISH_PRE_LIB_FLAGS_x86_64-apple-darwin :=
-CFG_GCCISH_POST_LIB_FLAGS_x86_64-apple-darwin :=
-CFG_DEF_SUFFIX_x86_64-apple-darwin := .darwin.def
-CFG_LLC_FLAGS_x86_64-apple-darwin :=
-CFG_INSTALL_NAME_x86_64-apple-darwin = -Wl,-install_name,@rpath/$(1)
-CFG_EXE_SUFFIX_x86_64-apple-darwin :=
-CFG_WINDOWSY_x86_64-apple-darwin :=
-CFG_UNIXY_x86_64-apple-darwin := 1
-CFG_PATH_MUNGE_x86_64-apple-darwin := true
-CFG_LDPATH_x86_64-apple-darwin :=
-CFG_RUN_x86_64-apple-darwin=$(2)
-CFG_RUN_TARG_x86_64-apple-darwin=$(call CFG_RUN_x86_64-apple-darwin,,$(2))
-
-# i686-apple-darwin configuration
-CC_i686-apple-darwin=$(CC)
-CXX_i686-apple-darwin=$(CXX)
-CPP_i686-apple-darwin=$(CPP)
-AR_i686-apple-darwin=$(AR)
-CFG_LIB_NAME_i686-apple-darwin=lib$(1).dylib
-CFG_STATIC_LIB_NAME_i686-apple-darwin=lib$(1).a
-CFG_LIB_GLOB_i686-apple-darwin=lib$(1)-*.dylib
-CFG_LIB_DSYM_GLOB_i686-apple-darwin=lib$(1)-*.dylib.dSYM
-CFG_CFLAGS_i686-apple-darwin := -m32 -arch i386 $(CFLAGS)
-CFG_GCCISH_CFLAGS_i686-apple-darwin := -Wall -Werror -g -fPIC -m32 -arch i386 $(CFLAGS)
-CFG_GCCISH_CXXFLAGS_i686-apple-darwin := -fno-rtti $(CXXFLAGS)
-CFG_GCCISH_LINK_FLAGS_i686-apple-darwin := -dynamiclib -pthread  -framework CoreServices -m32
-CFG_GCCISH_DEF_FLAG_i686-apple-darwin := -Wl,-exported_symbols_list,
-CFG_GCCISH_PRE_LIB_FLAGS_i686-apple-darwin :=
-CFG_GCCISH_POST_LIB_FLAGS_i686-apple-darwin :=
-CFG_DEF_SUFFIX_i686-apple-darwin := .darwin.def
-CFG_LLC_FLAGS_i686-apple-darwin :=
-CFG_INSTALL_NAME_i686-apple-darwin = -Wl,-install_name,@rpath/$(1)
-CFG_EXE_SUFFIX_i686-apple-darwin :=
-CFG_WINDOWSY_i686-apple-darwin :=
-CFG_UNIXY_i686-apple-darwin := 1
-CFG_PATH_MUNGE_i686-apple-darwin := true
-CFG_LDPATH_i686-apple-darwin :=
-CFG_RUN_i686-apple-darwin=$(2)
-CFG_RUN_TARG_i686-apple-darwin=$(call CFG_RUN_i686-apple-darwin,,$(2))
-
-# arm-linux-androideabi configuration
-CC_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-gcc
-CXX_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-g++
-CPP_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-gcc -E
-AR_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-ar
-CFG_LIB_NAME_arm-linux-androideabi=lib$(1).so
-CFG_STATIC_LIB_NAME_arm-linux-androideabi=lib$(1).a
-CFG_LIB_GLOB_arm-linux-androideabi=lib$(1)-*.so
-CFG_LIB_DSYM_GLOB_arm-linux-androideabi=lib$(1)-*.dylib.dSYM
-CFG_CFLAGS_arm-linux-androideabi := -D__arm__ -DANDROID -D__ANDROID__ $(CFLAGS)
-CFG_GCCISH_CFLAGS_arm-linux-androideabi := -Wall -g -fPIC -D__arm__ -DANDROID -D__ANDROID__ $(CFLAGS)
-CFG_GCCISH_CXXFLAGS_arm-linux-androideabi := -fno-rtti $(CXXFLAGS)
-CFG_GCCISH_LINK_FLAGS_arm-linux-androideabi := -shared -fPIC -ldl -g -lm -lsupc++
-CFG_GCCISH_DEF_FLAG_arm-linux-androideabi := -Wl,--export-dynamic,--dynamic-list=
-CFG_GCCISH_PRE_LIB_FLAGS_arm-linux-androideabi := -Wl,-whole-archive
-CFG_GCCISH_POST_LIB_FLAGS_arm-linux-androideabi := -Wl,-no-whole-archive
-CFG_DEF_SUFFIX_arm-linux-androideabi := .android.def
-CFG_LLC_FLAGS_arm-linux-androideabi :=
-CFG_INSTALL_NAME_arm-linux-androideabi =
-CFG_EXE_SUFFIX_arm-linux-androideabi :=
-CFG_WINDOWSY_arm-linux-androideabi :=
-CFG_UNIXY_arm-linux-androideabi := 1
-CFG_PATH_MUNGE_arm-linux-androideabi := true
-CFG_LDPATH_arm-linux-androideabi :=
-CFG_RUN_arm-linux-androideabi=
-CFG_RUN_TARG_arm-linux-androideabi=
-RUSTC_FLAGS_arm-linux-androideabi :=
-RUSTC_CROSS_FLAGS_arm-linux-androideabi :=
-
-# arm-unknown-linux-gnueabihf configuration
-CROSS_PREFIX_arm-unknown-linux-gnueabihf=arm-linux-gnueabihf-
-CC_arm-unknown-linux-gnueabihf=gcc
-CXX_arm-unknown-linux-gnueabihf=g++
-CPP_arm-unknown-linux-gnueabihf=gcc -E
-AR_arm-unknown-linux-gnueabihf=ar
-CFG_LIB_NAME_arm-unknown-linux-gnueabihf=lib$(1).so
-CFG_STATIC_LIB_NAME_arm-unknown-linux-gnueabihf=lib$(1).a
-CFG_LIB_GLOB_arm-unknown-linux-gnueabihf=lib$(1)-*.so
-CFG_LIB_DSYM_GLOB_arm-unknown-linux-gnueabihf=lib$(1)-*.dylib.dSYM
-CFG_CFLAGS_arm-unknown-linux-gnueabihf := -D__arm__ $(CFLAGS)
-CFG_GCCISH_CFLAGS_arm-unknown-linux-gnueabihf := -Wall -g -fPIC -D__arm__ $(CFLAGS)
-CFG_GCCISH_CXXFLAGS_arm-unknown-linux-gnueabihf := -fno-rtti $(CXXFLAGS)
-CFG_GCCISH_LINK_FLAGS_arm-unknown-linux-gnueabihf := -shared -fPIC -g
-CFG_GCCISH_DEF_FLAG_arm-unknown-linux-gnueabihf := -Wl,--export-dynamic,--dynamic-list=
-CFG_GCCISH_PRE_LIB_FLAGS_arm-unknown-linux-gnueabihf := -Wl,-whole-archive
-CFG_GCCISH_POST_LIB_FLAGS_arm-unknown-linux-gnueabihf := -Wl,-no-whole-archive
-CFG_DEF_SUFFIX_arm-unknown-linux-gnueabihf := .linux.def
-CFG_LLC_FLAGS_arm-unknown-linux-gnueabihf :=
-CFG_INSTALL_NAME_ar,-unknown-linux-gnueabihf =
-CFG_EXE_SUFFIX_arm-unknown-linux-gnueabihf :=
-CFG_WINDOWSY_arm-unknown-linux-gnueabihf :=
-CFG_UNIXY_arm-unknown-linux-gnueabihf := 1
-CFG_PATH_MUNGE_arm-unknown-linux-gnueabihf := true
-CFG_LDPATH_arm-unknown-linux-gnueabihf :=
-CFG_RUN_arm-unknown-linux-gnueabihf=$(2)
-CFG_RUN_TARG_arm-unknown-linux-gnueabihf=$(call CFG_RUN_arm-unknown-linux-gnueabihf,,$(2))
-RUSTC_FLAGS_arm-unknown-linux-gnueabihf := -C target-feature=+v6,+vfp2
-RUSTC_CROSS_FLAGS_arm-unknown-linux-gnueabihf :=
-
-# arm-unknown-linux-gnueabi configuration
-CROSS_PREFIX_arm-unknown-linux-gnueabi=arm-linux-gnueabi-
-CC_arm-unknown-linux-gnueabi=gcc
-CXX_arm-unknown-linux-gnueabi=g++
-CPP_arm-unknown-linux-gnueabi=gcc -E
-AR_arm-unknown-linux-gnueabi=ar
-CFG_LIB_NAME_arm-unknown-linux-gnueabi=lib$(1).so
-CFG_STATIC_LIB_NAME_arm-unknown-linux-gnueabi=lib$(1).a
-CFG_LIB_GLOB_arm-unknown-linux-gnueabi=lib$(1)-*.so
-CFG_LIB_DSYM_GLOB_arm-unknown-linux-gnueabi=lib$(1)-*.dylib.dSYM
-CFG_CFLAGS_arm-unknown-linux-gnueabi := -D__arm__ -mfpu=vfp $(CFLAGS)
-CFG_GCCISH_CFLAGS_arm-unknown-linux-gnueabi := -Wall -g -fPIC -D__arm__ -mfpu=vfp $(CFLAGS)
-CFG_GCCISH_CXXFLAGS_arm-unknown-linux-gnueabi := -fno-rtti $(CXXFLAGS)
-CFG_GCCISH_LINK_FLAGS_arm-unknown-linux-gnueabi := -shared -fPIC -g
-CFG_GCCISH_DEF_FLAG_arm-unknown-linux-gnueabi := -Wl,--export-dynamic,--dynamic-list=
-CFG_GCCISH_PRE_LIB_FLAGS_arm-unknown-linux-gnueabi := -Wl,-whole-archive
-CFG_GCCISH_POST_LIB_FLAGS_arm-unknown-linux-gnueabi := -Wl,-no-whole-archive
-CFG_DEF_SUFFIX_arm-unknown-linux-gnueabi := .linux.def
-CFG_LLC_FLAGS_arm-unknown-linux-gnueabi :=
-CFG_INSTALL_NAME_arm-unknown-linux-gnueabi =
-CFG_EXE_SUFFIX_arm-unknown-linux-gnueabi :=
-CFG_WINDOWSY_arm-unknown-linux-gnueabi :=
-CFG_UNIXY_arm-unknown-linux-gnueabi := 1
-CFG_PATH_MUNGE_arm-unknown-linux-gnueabi := true
-CFG_LDPATH_arm-unknown-linux-gnueabi :=
-CFG_RUN_arm-unknown-linux-gnueabi=$(2)
-CFG_RUN_TARG_arm-unknown-linux-gnueabi=$(call CFG_RUN_arm-unknown-linux-gnueabi,,$(2))
-RUSTC_FLAGS_arm-unknown-linux-gnueabi :=
-RUSTC_CROSS_FLAGS_arm-unknown-linux-gnueabi :=
-
-# mipsel-linux configuration
-CC_mipsel-linux=mipsel-linux-gcc
-CXX_mipsel-linux=mipsel-linux-g++
-CPP_mipsel-linux=mipsel-linux-gcc
-AR_mipsel-linux=mipsel-linux-ar
-CFG_LIB_NAME_mipsel-linux=lib$(1).so
-CFG_STATIC_LIB_NAME_mipsel-linux=lib$(1).a
-CFG_LIB_GLOB_mipsel-linux=lib$(1)-*.so
-CFG_LIB_DSYM_GLOB_mipsel-linux=lib$(1)-*.dylib.dSYM
-CFG_CFLAGS_mipsel-linux := -mips32 -mabi=32 $(CFLAGS)
-CFG_GCCISH_CFLAGS_mipsel-linux := -Wall -g -fPIC -mips32 -mabi=32 $(CFLAGS)
-CFG_GCCISH_CXXFLAGS_mipsel-linux := -fno-rtti $(CXXFLAGS)
-CFG_GCCISH_LINK_FLAGS_mipsel-linux := -shared -fPIC -g -mips32
-CFG_GCCISH_DEF_FLAG_mipsel-linux := -Wl,--export-dynamic,--dynamic-list=
-CFG_GCCISH_PRE_LIB_FLAGS_mipsel-linux := -Wl,-whole-archive
-CFG_GCCISH_POST_LIB_FLAGS_mipsel-linux := -Wl,-no-whole-archive
-CFG_DEF_SUFFIX_mipsel-linux := .linux.def
-CFG_LLC_FLAGS_mipsel-linux :=
-CFG_INSTALL_NAME_mipsel-linux =
-CFG_EXE_SUFFIX_mipsel-linux :=
-CFG_WINDOWSY_mipsel-linux :=
-CFG_UNIXY_mipsel-linux := 1
-CFG_PATH_MUNGE_mipsel-linux := true
-CFG_LDPATH_mipsel-linux :=
-CFG_RUN_mipsel-linux=
-CFG_RUN_TARG_mipsel-linux=
-RUSTC_FLAGS_mipsel-linux := -C target-cpu=mips32 -C target-feature="+mips32,+o32"
-
-
-# mips-unknown-linux-gnu configuration
-CC_mips-unknown-linux-gnu=mips-linux-gnu-gcc
-CXX_mips-unknown-linux-gnu=mips-linux-gnu-g++
-CPP_mips-unknown-linux-gnu=mips-linux-gnu-gcc -E
-AR_mips-unknown-linux-gnu=mips-linux-gnu-ar
-CFG_LIB_NAME_mips-unknown-linux-gnu=lib$(1).so
-CFG_STATIC_LIB_NAME_mips-unknown-linux-gnu=lib$(1).a
-CFG_LIB_GLOB_mips-unknown-linux-gnu=lib$(1)-*.so
-CFG_LIB_DSYM_GLOB_mips-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
-CFG_CFLAGS_mips-unknown-linux-gnu := -mips32r2 -msoft-float -mabi=32 -mno-compact-eh $(CFLAGS)
-CFG_GCCISH_CFLAGS_mips-unknown-linux-gnu := -Wall -g -fPIC -mips32r2 -msoft-float -mabi=32 -mno-compact-eh $(CFLAGS)
-CFG_GCCISH_CXXFLAGS_mips-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
-CFG_GCCISH_LINK_FLAGS_mips-unknown-linux-gnu := -shared -fPIC -g -mips32r2 -msoft-float -mabi=32
-CFG_GCCISH_DEF_FLAG_mips-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
-CFG_GCCISH_PRE_LIB_FLAGS_mips-unknown-linux-gnu := -Wl,-whole-archive
-CFG_GCCISH_POST_LIB_FLAGS_mips-unknown-linux-gnu := -Wl,-no-whole-archive
-CFG_DEF_SUFFIX_mips-unknown-linux-gnu := .linux.def
-CFG_LLC_FLAGS_mips-unknown-linux-gnu :=
-CFG_INSTALL_NAME_mips-unknown-linux-gnu =
-CFG_EXE_SUFFIX_mips-unknown-linux-gnu :=
-CFG_WINDOWSY_mips-unknown-linux-gnu :=
-CFG_UNIXY_mips-unknown-linux-gnu := 1
-CFG_PATH_MUNGE_mips-unknown-linux-gnu := true
-CFG_LDPATH_mips-unknown-linux-gnu :=
-CFG_RUN_mips-unknown-linux-gnu=
-CFG_RUN_TARG_mips-unknown-linux-gnu=
-RUSTC_FLAGS_mips-unknown-linux-gnu := -C target-cpu=mips32r2 -C target-feature="+mips32r2,+o32" -C soft-float
-
-# i586-mingw32msvc configuration
-CC_i586-mingw32msvc=$(CFG_MINGW32_CROSS_PATH)/bin/i586-mingw32msvc-gcc
-CXX_i586-mingw32msvc=$(CFG_MINGW32_CROSS_PATH)/bin/i586-mingw32msvc-g++
-CPP_i586-mingw32msvc=$(CFG_MINGW32_CROSS_PATH)/bin/i586-mingw32msvc-cpp
-AR_i586-mingw32msvc=$(CFG_MINGW32_CROSS_PATH)/bin/i586-mingw32msvc-ar
-CFG_LIB_NAME_i586-mingw32msvc=$(1).dll
-CFG_STATIC_LIB_NAME_i586-mingw32msvc=$(1).lib
-CFG_LIB_GLOB_i586-mingw32msvc=$(1)-*.dll
-CFG_LIB_DSYM_GLOB_i586-mingw32msvc=$(1)-*.dylib.dSYM
-CFG_CFLAGS_i586-mingw32msvc := -march=i586 -m32 $(CFLAGS)
-CFG_GCCISH_CFLAGS_i586-mingw32msvc := -Wall -Werror -g -march=i586 -m32 $(CFLAGS)
-CFG_GCCISH_CXXFLAGS_i586-mingw32msvc := -fno-rtti $(CXXFLAGS)
-CFG_GCCISH_LINK_FLAGS_i586-mingw32msvc := -shared -g -m32
-CFG_GCCISH_DEF_FLAG_i586-mingw32msvc :=
-CFG_GCCISH_PRE_LIB_FLAGS_i586-mingw32msvc :=
-CFG_GCCISH_POST_LIB_FLAGS_i586-mingw32msvc :=
-CFG_DEF_SUFFIX_i586-mingw32msvc := .mingw32.def
-CFG_LLC_FLAGS_i586-mingw32msvc :=
-CFG_INSTALL_NAME_i586-mingw32msvc =
-CFG_EXE_SUFFIX_i586-mingw32msvc := .exe
-CFG_WINDOWSY_i586-mingw32msvc := 1
-CFG_UNIXY_i586-mingw32msvc :=
-CFG_PATH_MUNGE_i586-mingw32msvc := $(strip perl -i.bak -p \
-                             -e 's@\\(\S)@/\1@go;' \
-                             -e 's@^/([a-zA-Z])/@\1:/@o;')
-CFG_LDPATH_i586-mingw32msvc :=
-CFG_RUN_i586-mingw32msvc=
-CFG_RUN_TARG_i586-mingw32msvc=
-
-# i686-w64-mingw32 configuration
-CROSS_PREFIX_i686-w64-mingw32=i686-w64-mingw32-
-CC_i686-w64-mingw32=gcc
-CXX_i686-w64-mingw32=g++
-CPP_i686-w64-mingw32=gcc -E
-AR_i686-w64-mingw32=ar
-CFG_LIB_NAME_i686-w64-mingw32=$(1).dll
-CFG_STATIC_LIB_NAME_i686-w64-mingw32=$(1).lib
-CFG_LIB_GLOB_i686-w64-mingw32=$(1)-*.dll
-CFG_LIB_DSYM_GLOB_i686-w64-mingw32=$(1)-*.dylib.dSYM
-CFG_CFLAGS_i686-w64-mingw32 := -march=i686 -m32 -D_WIN32_WINNT=0x0600 $(CFLAGS)
-CFG_GCCISH_CFLAGS_i686-w64-mingw32 := -Wall -Werror -g -m32 -D_WIN32_WINNT=0x0600 $(CFLAGS)
-CFG_GCCISH_CXXFLAGS_i686-w64-mingw32 := -fno-rtti $(CXXFLAGS)
-CFG_GCCISH_LINK_FLAGS_i686-w64-mingw32 := -shared -g -m32
-CFG_GCCISH_DEF_FLAG_i686-w64-mingw32 :=
-CFG_GCCISH_PRE_LIB_FLAGS_i686-w64-mingw32 :=
-CFG_GCCISH_POST_LIB_FLAGS_i686-w64-mingw32 :=
-CFG_DEF_SUFFIX_i686-w64-mingw32 := .mingw32.def
-CFG_LLC_FLAGS_i686-w64-mingw32 :=
-CFG_INSTALL_NAME_i686-w64-mingw32 =
-CFG_EXE_SUFFIX_i686-w64-mingw32 := .exe
-CFG_WINDOWSY_i686-w64-mingw32 := 1
-CFG_UNIXY_i686-w64-mingw32 :=
-CFG_PATH_MUNGE_i686-w64-mingw32 :=
-CFG_LDPATH_i686-w64-mingw32 :=$(CFG_LDPATH_i686-w64-mingw32):$(PATH)
-CFG_RUN_i686-w64-mingw32=PATH="$(CFG_LDPATH_i686-w64-mingw32):$(1)" $(2)
-CFG_RUN_TARG_i686-w64-mingw32=$(call CFG_RUN_i686-w64-mingw32,$(HLIB$(1)_H_$(CFG_BUILD)),$(2))
-# Stop rustc from OOMing when building itself (I think)
-RUSTC_FLAGS_i686-w64-mingw32=-C link-args="-Wl,--large-address-aware"
-RUSTC_CROSS_FLAGS_i686-w64-mingw32 :=
-
-# x86_64-w64-mingw32 configuration
-CROSS_PREFIX_x86_64-w64-mingw32=x86_64-w64-mingw32-
-CC_x86_64-w64-mingw32=gcc
-CXX_x86_64-w64-mingw32=g++
-CPP_x86_64-w64-mingw32=gcc -E
-AR_x86_64-w64-mingw32=ar
-CFG_LIB_NAME_x86_64-w64-mingw32=$(1).dll
-CFG_STATIC_LIB_NAME_x86_64-w64-mingw32=$(1).lib
-CFG_LIB_GLOB_x86_64-w64-mingw32=$(1)-*.dll
-CFG_LIB_DSYM_GLOB_x86_64-w64-mingw32=$(1)-*.dylib.dSYM
-CFG_CFLAGS_x86_64-w64-mingw32 := -m64 -D_WIN32_WINNT=0x0600 $(CFLAGS)
-CFG_GCCISH_CFLAGS_x86_64-w64-mingw32 := -Wall -Werror -g -m64 -D_WIN32_WINNT=0x0600 $(CFLAGS)
-CFG_GCCISH_CXXFLAGS_x86_64-w64-mingw32 := -fno-rtti $(CXXFLAGS)
-CFG_GCCISH_LINK_FLAGS_x86_64-w64-mingw32 := -shared -g -m64
-CFG_GCCISH_DEF_FLAG_x86_64-w64-mingw32 :=
-CFG_GCCISH_PRE_LIB_FLAGS_x86_64-w64-mingw32 :=
-CFG_GCCISH_POST_LIB_FLAGS_x86_64-w64-mingw32 :=
-CFG_DEF_SUFFIX_x86_64-w64-mingw32 := .mingw32.def
-CFG_LLC_FLAGS_x86_64-w64-mingw32 :=
-CFG_INSTALL_NAME_x86_64-w64-mingw32 =
-CFG_EXE_SUFFIX_x86_64-w64-mingw32 := .exe
-CFG_WINDOWSY_x86_64-w64-mingw32 := 1
-CFG_UNIXY_x86_64-w64-mingw32 :=
-CFG_PATH_MUNGE_x86_64-w64-mingw32 :=
-CFG_LDPATH_x86_64-w64-mingw32 :=$(CFG_LDPATH_x86_64-w64-mingw32):$(PATH)
-CFG_RUN_x86_64-w64-mingw32=PATH="$(CFG_LDPATH_x86_64-w64-mingw32):$(1)" $(2)
-CFG_RUN_TARG_x86_64-w64-mingw32=$(call CFG_RUN_x86_64-w64-mingw32,$(HLIB$(1)_H_$(CFG_BUILD)),$(2))
-RUSTC_CROSS_FLAGS_x86_64-w64-mingw32 :=
-
-# x86_64-unknown-freebsd configuration
-CC_x86_64-unknown-freebsd=$(CC)
-CXX_x86_64-unknown-freebsd=$(CXX)
-CPP_x86_64-unknown-freebsd=$(CPP)
-AR_x86_64-unknown-freebsd=$(AR)
-CFG_LIB_NAME_x86_64-unknown-freebsd=lib$(1).so
-CFG_STATIC_LIB_NAME_x86_64-unknown-freebsd=lib$(1).a
-CFG_LIB_GLOB_x86_64-unknown-freebsd=lib$(1)-*.so
-CFG_LIB_DSYM_GLOB_x86_64-unknown-freebsd=$(1)-*.dylib.dSYM
-CFG_CFLAGS_x86_64-unknown-freebsd := -I/usr/local/include $(CFLAGS)
-CFG_GCCISH_CFLAGS_x86_64-unknown-freebsd := -Wall -Werror -g -fPIC -I/usr/local/include $(CFLAGS)
-CFG_GCCISH_LINK_FLAGS_x86_64-unknown-freebsd := -shared -fPIC -g -pthread  -lrt
-CFG_GCCISH_DEF_FLAG_x86_64-unknown-freebsd := -Wl,--export-dynamic,--dynamic-list=
-CFG_GCCISH_PRE_LIB_FLAGS_x86_64-unknown-freebsd := -Wl,-whole-archive
-CFG_GCCISH_POST_LIB_FLAGS_x86_64-unknown-freebsd := -Wl,-no-whole-archive
-CFG_DEF_SUFFIX_x86_64-unknown-freebsd := .bsd.def
-CFG_LLC_FLAGS_x86_64-unknown-freebsd :=
-CFG_INSTALL_NAME_x86_64-unknown-freebsd =
-CFG_EXE_SUFFIX_x86_64-unknown-freebsd :=
-CFG_WINDOWSY_x86_64-unknown-freebsd :=
-CFG_UNIXY_x86_64-unknown-freebsd := 1
-CFG_PATH_MUNGE_x86_64-unknown-freebsd :=
-CFG_LDPATH_x86_64-unknown-freebsd :=
-CFG_RUN_x86_64-unknown-freebsd=$(2)
-CFG_RUN_TARG_x86_64-unknown-freebsd=$(call CFG_RUN_x86_64-unknown-freebsd,,$(2))
-
-# x86_64-pc-dragonfly-elf configuration
-CC_x86_64-unknown-dragonfly=$(CC)
-CXX_x86_64-unknown-dragonfly=$(CXX)
-CPP_x86_64-unknown-dragonfly=$(CPP)
-AR_x86_64-unknown-dragonfly=$(AR)
-CFG_LIB_NAME_x86_64-unknown-dragonfly=lib$(1).so
-CFG_STATIC_LIB_NAME_x86_64-unknown-dragonfly=lib$(1).a
-CFG_LIB_GLOB_x86_64-unknown-dragonfly=lib$(1)-*.so
-CFG_LIB_DSYM_GLOB_x86_64-unknown-dragonfly=$(1)-*.dylib.dSYM
-CFG_CFLAGS_x86_64-unknown-dragonfly := -I/usr/include -I/usr/local/include $(CFLAGS)
-CFG_GCCISH_CFLAGS_x86_64-unknown-dragonfly := -Wall -Werror -g -fPIC -I/usr/include -I/usr/local/include $(CFLAGS)
-CFG_GCCISH_LINK_FLAGS_x86_64-unknown-dragonfly := -shared -fPIC -g -pthread  -lrt
-CFG_GCCISH_DEF_FLAG_x86_64-unknown-dragonfly := -Wl,--export-dynamic,--dynamic-list=
-CFG_GCCISH_PRE_LIB_FLAGS_x86_64-unknown-dragonfly := -Wl,-whole-archive
-CFG_GCCISH_POST_LIB_FLAGS_x86_64-unknown-dragonfly := -Wl,-no-whole-archive
-CFG_DEF_SUFFIX_x86_64-unknown-dragonfly := .bsd.def
-CFG_LLC_FLAGS_x86_64-unknown-dragonfly :=
-CFG_INSTALL_NAME_x86_64-unknown-dragonfly =
-CFG_EXE_SUFFIX_x86_64-unknown-dragonfly :=
-CFG_WINDOWSY_x86_64-unknown-dragonfly :=
-CFG_UNIXY_x86_64-unknown-dragonfly := 1
-CFG_PATH_MUNGE_x86_64-unknown-dragonfly :=
-CFG_LDPATH_x86_64-unknown-dragonfly :=
-CFG_RUN_x86_64-unknown-dragonfly=$(2)
-CFG_RUN_TARG_x86_64-unknown-dragonfly=$(call CFG_RUN_x86_64-unknown-dragonfly,,$(2))
-
+include $(wildcard $(CFG_SRC_DIR)mk/cfg/*)
 
 # The -Qunused-arguments sidesteps spurious warnings from clang
 define FILTER_FLAGS
index 3bbd871e5be77a1757a250b1ff8b10c121a805bc..45b618cb75841f007d3214c9fb562ac899b03011 100644 (file)
@@ -633,10 +633,6 @@ CTEST_RUSTC_FLAGS := $$(subst -O,,$$(CTEST_RUSTC_FLAGS))
 ifndef CFG_DISABLE_OPTIMIZE_TESTS
 CTEST_RUSTC_FLAGS += -O
 endif
-# Force codegen-units=1 for compiletest tests.  compiletest does its own
-# parallelization internally, so rustc's default codegen-units=2 will actually
-# slow things down.
-CTEST_RUSTC_FLAGS += -C codegen-units=1
 
 
 CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3) := \
index 018d77b67cdd6b8d95bfc608ace968a2b7455590..caf1c8c314dbb1186722eddb92d0a12d5f91b811 100644 (file)
@@ -41,7 +41,7 @@ pub fn main() {
     let config = parse_config(args);
 
     if config.valgrind_path.is_none() && config.force_valgrind {
-        fail!("Can't find Valgrind to run Valgrind tests");
+        panic!("Can't find Valgrind to run Valgrind tests");
     }
 
     log_config(&config);
@@ -94,20 +94,20 @@ pub fn parse_config(args: Vec<String> ) -> Config {
         let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
         println!("{}", getopts::usage(message.as_slice(), groups.as_slice()));
         println!("");
-        fail!()
+        panic!()
     }
 
     let matches =
         &match getopts::getopts(args_.as_slice(), groups.as_slice()) {
           Ok(m) => m,
-          Err(f) => fail!("{}", f)
+          Err(f) => panic!("{}", f)
         };
 
     if matches.opt_present("h") || matches.opt_present("help") {
         let message = format!("Usage: {} [OPTIONS]  [TESTNAME...]", argv0);
         println!("{}", getopts::usage(message.as_slice(), groups.as_slice()));
         println!("");
-        fail!()
+        panic!()
     }
 
     fn opt_path(m: &getopts::Matches, nm: &str) -> Path {
@@ -120,7 +120,7 @@ fn opt_path(m: &getopts::Matches, nm: &str) -> Path {
             Ok(re) => Some(re),
             Err(e) => {
                 println!("failed to parse filter /{}/: {}", s, e);
-                fail!()
+                panic!()
             }
         }
     } else {
@@ -263,7 +263,7 @@ pub fn run_tests(config: &Config) {
     let res = test::run_tests_console(&opts, tests.into_iter().collect());
     match res {
         Ok(true) => {}
-        Ok(false) => fail!("Some tests failed"),
+        Ok(false) => panic!("Some tests failed"),
         Err(e) => {
             println!("I/O failure during tests: {}", e);
         }
index a9c984d8061df8f6d97feee053cfd47eeb3f3cee..b7b94ca6d0df5673dabdb43dd06eb646bb8336cc 100644 (file)
@@ -305,7 +305,7 @@ fn parse_exec_env(line: &str) -> Option<(String, String)> {
               let end = strs.pop().unwrap();
               (strs.pop().unwrap(), end)
           }
-          n => fail!("Expected 1 or 2 strings, not {}", n)
+          n => panic!("Expected 1 or 2 strings, not {}", n)
         }
     })
 }
@@ -350,7 +350,7 @@ pub fn gdb_version_to_int(version_string: &str) -> int {
     let components: Vec<&str> = version_string.trim().split('.').collect();
 
     if components.len() != 2 {
-        fail!("{}", error_string);
+        panic!("{}", error_string);
     }
 
     let major: int = FromStr::from_str(components[0]).expect(error_string);
index 34129dedbd8271c3a1c6d13294ef2bcd00f4dfe1..a9edad3add61e47babf1862a5f50101cff4abed0 100644 (file)
@@ -39,7 +39,7 @@ pub fn run(config: Config, testfile: String) {
 
         "arm-linux-androideabi" => {
             if !config.adb_device_status {
-                fail!("android device not available");
+                panic!("android device not available");
             }
         }
 
@@ -316,7 +316,7 @@ fn compare_source(expected: &str, actual: &str) {
 ------------------------------------------\n\
 \n",
                      expected, actual);
-            fail!();
+            panic!();
         }
     }
 
@@ -1453,7 +1453,7 @@ fn maybe_dump_to_stdout(config: &Config, out: &str, err: &str) {
 
 fn error(err: &str) { println!("\nerror: {}", err); }
 
-fn fatal(err: &str) -> ! { error(err); fail!(); }
+fn fatal(err: &str) -> ! { error(err); panic!(); }
 
 fn fatal_proc_rec(err: &str, proc_res: &ProcRes) -> ! {
     print!("\n\
@@ -1471,7 +1471,7 @@ fn fatal_proc_rec(err: &str, proc_res: &ProcRes) -> ! {
 \n",
              err, proc_res.status, proc_res.cmdline, proc_res.stdout,
              proc_res.stderr);
-    fail!();
+    panic!();
 }
 
 fn _arm_exec_compiled_test(config: &Config,
index 22b5600d5bfcc197e61b9d844805e194be1a0c3c..a116cc33690db101236ef9d512e12ec1c6759045 100644 (file)
@@ -31,7 +31,7 @@ pub fn get_os(triple: &str) -> &'static str {
             return os
         }
     }
-    fail!("Cannot determine OS from triple");
+    panic!("Cannot determine OS from triple");
 }
 
 #[cfg(target_os = "windows")]
index 6cdaf96d3f50e3c7dc19fce994ac23887d32e094..9a2531f094c17e5b0e2773b4fd2292278970ce5a 100644 (file)
@@ -94,9 +94,9 @@ code should need to run is a stack.
 
 `match` being exhaustive has some useful properties. First, if every
 possibility is covered by the `match`, adding further variants to the `enum`
-in the future will prompt a compilation failure, rather than runtime failure.
+in the future will prompt a compilation failure, rather than runtime panic.
 Second, it makes cost explicit. In general, only safe way to have a
-non-exhaustive match would be to fail the task if nothing is matched, though
+non-exhaustive match would be to panic the task if nothing is matched, though
 it could fall through if the type of the `match` expression is `()`. This sort
 of hidden cost and special casing is against the language's philosophy. It's
 easy to ignore certain cases by using the `_` wildcard:
index 8db7ba9424fc128beb9c1e4bdcb06f3cdf7bc15e..0a8f9b2ffaa6548f5d74485e7ed7bd992cfeb1ce 100644 (file)
@@ -65,14 +65,15 @@ Data values in the language can only be constructed through a fixed set of initi
 * There is no global inter-crate namespace; all name management occurs within a crate.
  * Using another crate binds the root of _its_ namespace into the user's namespace.
 
-## Why is failure unwinding non-recoverable within a task? Why not try to "catch exceptions"?
+## Why is panic unwinding non-recoverable within a task? Why not try to "catch exceptions"?
 
 In short, because too few guarantees could be made about the dynamic environment of the catch block, as well as invariants holding in the unwound heap, to be able to safely resume; we believe that other methods of signalling and logging errors are more appropriate, with tasks playing the role of a "hard" isolation boundary between separate heaps.
 
 Rust provides, instead, three predictable and well-defined options for handling any combination of the three main categories of "catch" logic:
 
 * Failure _logging_ is done by the integrated logging subsystem.
-* _Recovery_ after a failure is done by trapping a task failure from _outside_ the task, where other tasks are known to be unaffected.
+* _Recovery_ after a panic is done by trapping a task panic from _outside_
+  the task, where other tasks are known to be unaffected.
 * _Cleanup_ of resources is done by RAII-style objects with destructors.
 
 Cleanup through RAII-style destructors is more likely to work than in catch blocks anyways, since it will be better tested (part of the non-error control paths, so executed all the time).
index 8705bdd278ec7b384eb5a54bd0290e4d69d71ea2..50d76371cc51e3ce760e83ba17ccf7815e8b6e80 100644 (file)
@@ -452,7 +452,7 @@ fn main() {
 
 Rust will give us a compile-time error:
 
-```{rust,ignore}
+```{notrust,ignore}
    Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
 /home/you/projects/phrases/src/main.rs:4:5: 4:40 error: a value named `hello` has already been imported in this module
 /home/you/projects/phrases/src/main.rs:4 use phrases::japanese::greetings::hello;
index 0b0a6b7b697170ba6d21ef2addabe37997ac9120..3a87271ede7d85572c4ac36225f8678bdaf1c6c0 100644 (file)
@@ -191,7 +191,7 @@ the stack of the task which is spawned.
 
 Foreign libraries often hand off ownership of resources to the calling code.
 When this occurs, we must use Rust's destructors to provide safety and guarantee
-the release of these resources (especially in the case of failure).
+the release of these resources (especially in the case of panic).
 
 # Callbacks from C code to Rust functions
 
index dd79d63d514536425e58df0ca8c0cc76dffdb282..b6ea1ddb3949d3e3d7c83a1558a275ae546ed770 100644 (file)
@@ -56,7 +56,7 @@ a reference.
 fn compute_distance(p1: &Point, p2: &Point) -> f64 {
     let x_d = p1.x - p2.x;
     let y_d = p1.y - p2.y;
-    sqrt(x_d * x_d + y_d * y_d)
+    (x_d * x_d + y_d * y_d).sqrt()
 }
 ~~~
 
index ed4e924ce8a8af0728b36db7645fea7aec9c0c00..ae020037bc594ee6c2eb37156e57ac5cac3cd6a3 100644 (file)
@@ -240,7 +240,7 @@ match x {
                 // complicated stuff goes here
                 return result + val;
             },
-            _ => fail!("Didn't get good_2")
+            _ => panic!("Didn't get good_2")
         }
     }
     _ => return 0 // default value
@@ -284,7 +284,7 @@ macro_rules! biased_match (
 biased_match!((x)       ~ (Good1(g1, val)) else { return 0 };
               binds g1, val )
 biased_match!((g1.body) ~ (Good2(result) )
-                  else { fail!("Didn't get good_2") };
+                  else { panic!("Didn't get good_2") };
               binds result )
 // complicated stuff goes here
 return result + val;
@@ -397,7 +397,7 @@ macro_rules! biased_match (
 # fn f(x: T1) -> uint {
 biased_match!(
     (x)       ~ (Good1(g1, val)) else { return 0 };
-    (g1.body) ~ (Good2(result) ) else { fail!("Didn't get Good2") };
+    (g1.body) ~ (Good2(result) ) else { panic!("Didn't get Good2") };
     binds val, result )
 // complicated stuff goes here
 return result + val;
index 3830a2126e172709ac58831657891e65a1d3b22e..eb3e4ce75c4708b98e2d7907c24c721e5e40d579 100644 (file)
@@ -55,8 +55,8 @@ extern crate syntax;
 extern crate rustc;
 
 use syntax::codemap::Span;
-use syntax::parse::token::{IDENT, get_ident};
-use syntax::ast::{TokenTree, TTTok};
+use syntax::parse::token;
+use syntax::ast::{TokenTree, TtToken};
 use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacExpr};
 use syntax::ext::build::AstBuilder;  // trait for expr_uint
 use rustc::plugin::Registry;
@@ -71,7 +71,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
         ("I",    1)];
 
     let text = match args {
-        [TTTok(_, IDENT(s, _))] => get_ident(s).to_string(),
+        [TtToken(_, token::Ident(s, _))] => token::get_ident(s).to_string(),
         _ => {
             cx.span_err(sp, "argument should be a single identifier");
             return DummyResult::any(sp);
@@ -151,8 +151,7 @@ higher-level syntax elements like expressions:
 fn expand_foo(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
         -> Box<MacResult+'static> {
 
-    let mut parser =
-        parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(), args.to_slice())
+    let mut parser = cx.new_parser_from_tts(args);
 
     let expr: P<Expr> = parser.parse_expr();
 ```
index dd9c687172247425a74dc68e6811d6c3764348b4..87eb91d3ec7ff730ed85e3ec5f7a53eba3d85eca 100644 (file)
@@ -416,7 +416,7 @@ great detail, so if you want the full details, check that out.
 
 In general, prefer stack allocation over heap allocation. Using references to
 stack allocated information is preferred whenever possible. Therefore,
-references are the default pointer type you should use, unless you have
+references are the default pointer type you should use, unless you have a
 specific reason to use a different type. The other types of pointers cover when
 they're appropriate to use in their own best practices sections.
 
index 44fc0d830447513daaf0b1a29fd51baff71a7756..1c7cb1a3b4eb9e80890014cbbc8c8a357deef584 100644 (file)
@@ -14,8 +14,8 @@ Rust has two main types of strings: `&str` and `String`.
 
 # &str
 
-The first kind is a `&str`. This is pronounced a 'string slice.' String literals
-are of the type `&str`:
+The first kind is a `&str`. This is pronounced a 'string slice'.
+String literals are of the type `&str`:
 
 ```{rust}
 let string = "Hello there.";
@@ -121,8 +121,8 @@ Both of these lines will print `12`.
 To compare a String to a constant string, prefer `as_slice()`...
 
 ```{rust}
-fn compare(string: String) {
-    if string.as_slice() == "Hello" {
+fn compare(x: String) {
+    if x.as_slice() == "Hello" {
         println!("yes");
     }
 }
@@ -131,8 +131,8 @@ fn compare(string: String) {
 ... over `to_string()`:
 
 ```{rust}
-fn compare(string: String) {
-    if string == "Hello".to_string() {
+fn compare(x: String) {
+    if x == "Hello".to_string() {
         println!("yes");
     }
 }
index 1d1e9171b8f500ccd577082d4bcd20891809e316..4eaca64560ca21d3b677c7d891d96f57996e2034 100644 (file)
@@ -8,10 +8,10 @@ relates to the Rust type system, and introduce the fundamental library
 abstractions for constructing concurrent programs.
 
 Tasks provide failure isolation and recovery. When a fatal error occurs in Rust
-code as a result of an explicit call to `fail!()`, an assertion failure, or
+code as a result of an explicit call to `panic!()`, an assertion failure, or
 another invalid operation, the runtime system destroys the entire task. Unlike
 in languages such as Java and C++, there is no way to `catch` an exception.
-Instead, tasks may monitor each other for failure.
+Instead, tasks may monitor each other to see if they panic.
 
 Tasks use Rust's type system to provide strong memory safety guarantees.  In
 particular, the type system guarantees that tasks cannot induce a data race
@@ -317,19 +317,19 @@ spawn(proc() {
 # }
 ```
 
-# Handling task failure
+# Handling task panics
 
-Rust has a built-in mechanism for raising exceptions. The `fail!()` macro
-(which can also be written with an error string as an argument: `fail!(
-~reason)`) and the `assert!` construct (which effectively calls `fail!()` if a
+Rust has a built-in mechanism for raising exceptions. The `panic!()` macro
+(which can also be written with an error string as an argument: `panic!(
+~reason)`) and the `assert!` construct (which effectively calls `panic!()` if a
 boolean expression is false) are both ways to raise exceptions. When a task
 raises an exception, the task unwinds its stack—running destructors and
 freeing memory along the way—and then exits. Unlike exceptions in C++,
-exceptions in Rust are unrecoverable within a single task: once a task fails,
+exceptions in Rust are unrecoverable within a single task: once a task panics,
 there is no way to "catch" the exception.
 
-While it isn't possible for a task to recover from failure, tasks may notify
-each other of failure. The simplest way of handling task failure is with the
+While it isn't possible for a task to recover from panicking, tasks may notify
+each other if they panic. The simplest way of handling a panic is with the
 `try` function, which is similar to `spawn`, but immediately blocks and waits
 for the child task to finish. `try` returns a value of type
 `Result<T, Box<Any + Send>>`. `Result` is an `enum` type with two variants:
@@ -346,7 +346,7 @@ let result: Result<int, Box<std::any::Any + Send>> = task::try(proc() {
     if some_condition() {
         calculate_result()
     } else {
-        fail!("oops!");
+        panic!("oops!");
     }
 });
 assert!(result.is_err());
@@ -355,18 +355,18 @@ assert!(result.is_err());
 Unlike `spawn`, the function spawned using `try` may return a value, which
 `try` will dutifully propagate back to the caller in a [`Result`] enum. If the
 child task terminates successfully, `try` will return an `Ok` result; if the
-child task fails, `try` will return an `Error` result.
+child task panics, `try` will return an `Error` result.
 
 [`Result`]: std/result/index.html
 
-> *Note:* A failed task does not currently produce a useful error
+> *Note:* A panicked task does not currently produce a useful error
 > value (`try` always returns `Err(())`). In the
 > future, it may be possible for tasks to intercept the value passed to
-> `fail!()`.
+> `panic!()`.
 
-But not all failures are created equal. In some cases you might need to abort
+But not all panics are created equal. In some cases you might need to abort
 the entire program (perhaps you're writing an assert which, if it trips,
 indicates an unrecoverable logic error); in other cases you might want to
-contain the failure at a certain boundary (perhaps a small piece of input from
+contain the panic at a certain boundary (perhaps a small piece of input from
 the outside world, which you happen to be processing in parallel, is malformed
 such that the processing task cannot proceed).
index 07813855d9b9bb1e95a61bd7301f84c14c3927aa..9d15f55f33f69c3b46ac4d3c2e5cc3cb5b3c6a63 100644 (file)
@@ -49,7 +49,7 @@ value. To run the tests in a crate, it must be compiled with the
 `--test` flag: `rustc myprogram.rs --test -o myprogram-tests`. Running
 the resulting executable will run all the tests in the crate. A test
 is considered successful if its function returns; if the task running
-the test fails, through a call to `fail!`, a failed `assert`, or some
+the test fails, through a call to `panic!`, a failed `assert`, or some
 other (`assert_eq`, ...) means, then the test fails.
 
 When compiling a crate with the `--test` flag `--cfg test` is also
@@ -77,7 +77,7 @@ test on windows you can write `#[cfg_attr(windows, ignore)]`.
 
 Tests that are intended to fail can be annotated with the
 `should_fail` attribute. The test will be run, and if it causes its
-task to fail then the test will be counted as successful; otherwise it
+task to panic then the test will be counted as successful; otherwise it
 will be counted as a failure. For example:
 
 ~~~test_harness
index 7756abc8020142b31f1fcd9e484b4e938de0a996..4d6dde7f57fb97662cebf4bfa433f83279b25edc 100644 (file)
@@ -182,7 +182,7 @@ code:
 - implement the `Drop` for resource clean-up via a destructor, and use
   RAII (Resource Acquisition Is Initialization). This reduces the need
   for any manual memory management by users, and automatically ensures
-  that clean-up is always run, even when the task fails.
+  that clean-up is always run, even when the task panics.
 - ensure that any data stored behind a raw pointer is destroyed at the
   appropriate time.
 
@@ -462,7 +462,7 @@ fn start(_argc: int, _argv: *const *const u8) -> int {
 // provided by libstd.
 #[lang = "stack_exhausted"] extern fn stack_exhausted() {}
 #[lang = "eh_personality"] extern fn eh_personality() {}
-#[lang = "fail_fmt"] fn fail_fmt() -> ! { loop {} }
+#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
 # // fn main() {} tricked you, rustdoc!
 ```
 
@@ -485,7 +485,7 @@ pub extern fn main(argc: int, argv: *const *const u8) -> int {
 
 #[lang = "stack_exhausted"] extern fn stack_exhausted() {}
 #[lang = "eh_personality"] extern fn eh_personality() {}
-#[lang = "fail_fmt"] fn fail_fmt() -> ! { loop {} }
+#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
 # // fn main() {} tricked you, rustdoc!
 ```
 
@@ -504,8 +504,8 @@ The second of these three functions, `eh_personality`, is used by the
 failure mechanisms of the compiler. This is often mapped to GCC's
 personality function (see the
 [libstd implementation](std/rt/unwind/index.html) for more
-information), but crates which do not trigger failure can be assured
-that this function is never called. The final function, `fail_fmt`, is
+information), but crates which do not trigger a panic can be assured
+that this function is never called. The final function, `panic_fmt`, is
 also used by the failure mechanisms of the compiler.
 
 ## Using libcore
@@ -565,8 +565,8 @@ pub extern fn dot_product(a: *const u32, a_len: u32,
     return ret;
 }
 
-#[lang = "fail_fmt"]
-extern fn fail_fmt(args: &core::fmt::Arguments,
+#[lang = "panic_fmt"]
+extern fn panic_fmt(args: &core::fmt::Arguments,
                        file: &str,
                        line: uint) -> ! {
     loop {}
@@ -579,9 +579,9 @@ extern fn fail_fmt(args: &core::fmt::Arguments,
 ```
 
 Note that there is one extra lang item here which differs from the examples
-above, `fail_fmt`. This must be defined by consumers of libcore because the
-core library declares failure, but it does not define it. The `fail_fmt`
-lang item is this crate's definition of failure, and it must be guaranteed to
+above, `panic_fmt`. This must be defined by consumers of libcore because the
+core library declares panics, but it does not define it. The `panic_fmt`
+lang item is this crate's definition of panic, and it must be guaranteed to
 never return.
 
 As can be seen in this example, the core library is intended to provide the
@@ -686,7 +686,7 @@ fn main(argc: int, argv: *const *const u8) -> int {
 
 #[lang = "stack_exhausted"] extern fn stack_exhausted() {}
 #[lang = "eh_personality"] extern fn eh_personality() {}
-#[lang = "fail_fmt"] fn fail_fmt() -> ! { loop {} }
+#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
 ```
 
 Note the use of `abort`: the `exchange_malloc` lang item is assumed to
index c7b8e42b28cde24c6f10f488cb32c14910d01e2b..53ed2af9cd9aa30694f41c936e6e4c5903d2b7ee 100644 (file)
@@ -1130,12 +1130,12 @@ fn main() {
     let y = Missing;
 
     match x {
-        Value(n) => println!("x is {:d}", n),
+        Value(n) => println!("x is {}", n),
         Missing  => println!("x is missing!"),
     }
 
     match y {
-        Value(n) => println!("y is {:d}", n),
+        Value(n) => println!("y is {}", n),
         Missing  => println!("y is missing!"),
     }
 }
@@ -1301,7 +1301,7 @@ Instead, it looks like this:
 
 ```{rust}
 for x in range(0i, 10i) {
-    println!("{:d}", x);
+    println!("{}", x);
 }
 ```
 
@@ -1408,7 +1408,7 @@ iteration: This will only print the odd numbers:
 for x in range(0i, 10i) {
     if x % 2 == 0 { continue; }
 
-    println!("{:d}", x);
+    println!("{}", x);
 }
 ```
 
@@ -1677,12 +1677,12 @@ fn main() {
     let y = Missing;
 
     match x {
-        Value(n) => println!("x is {:d}", n),
+        Value(n) => println!("x is {}", n),
         Missing  => println!("x is missing!"),
     }
 
     match y {
-        Value(n) => println!("y is {:d}", n),
+        Value(n) => println!("y is {}", n),
         Missing  => println!("y is missing!"),
     }
 }
@@ -1793,7 +1793,7 @@ Finally, Cargo generated a hello, world for us. Check out `src/main.rs`:
 
 ```{rust}
 fn main() {
-    println!("Hello, world!");
+    println!("Hello, world!")
 }
 ```
 
@@ -2682,12 +2682,12 @@ like this:
 
 ```
 fn main() {
-    println!("Hello, world!");
+    println!("Hello, world!")
 }
 
 mod hello {
     fn print_hello() {
-        println!("Hello, world!");
+        println!("Hello, world!")
     }
 }
 ```
@@ -2721,7 +2721,7 @@ fn main() {
 
 mod hello {
     fn print_hello() {
-        println!("Hello, world!");
+        println!("Hello, world!")
     }
 }
 ```
@@ -2744,7 +2744,7 @@ fn main() {
 
 mod hello {
     pub fn print_hello() {
-        println!("Hello, world!");
+        println!("Hello, world!")
     }
 }
 ```
@@ -2921,15 +2921,11 @@ it `false`, so this test should fail. Let's try it!
 ```{notrust,ignore}
 $ cargo test
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
-/home/you/projects/testing/src/main.rs:1:1: 3:2 warning: code is never used: `main`, #[warn(dead_code)] on by default
+/home/you/projects/testing/src/main.rs:1:1: 3:2 warning: function is never used: `main`, #[warn(dead_code)] on by default
 /home/you/projects/testing/src/main.rs:1 fn main() {
-/home/you/projects/testing/src/main.rs:2     println!("Hello, world");
+/home/you/projects/testing/src/main.rs:2     println!("Hello, world!")
 /home/you/projects/testing/src/main.rs:3 }
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
+     Running target/lib-654ce120f310a3a5
 
 running 1 test
 test foo ... FAILED
@@ -2946,7 +2942,7 @@ failures:
 
 test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured
 
-task '<main>' failed at 'Some tests failed', /home/you/src/rust/src/libtest/lib.rs:242
+task '<main>' failed at 'Some tests failed', /home/you/src/rust/src/libtest/lib.rs:243
 ```
 
 Lots of output! Let's break this down:
@@ -2960,9 +2956,9 @@ You can run all of your tests with `cargo test`. This runs both your tests in
 `tests`, as well as the tests you put inside of your crate.
 
 ```{notrust,ignore}
-/home/you/projects/testing/src/main.rs:1:1: 3:2 warning: code is never used: `main`, #[warn(dead_code)] on by default
+/home/you/projects/testing/src/main.rs:1:1: 3:2 warning: function is never used: `main`, #[warn(dead_code)] on by default
 /home/you/projects/testing/src/main.rs:1 fn main() {
-/home/you/projects/testing/src/main.rs:2     println!("Hello, world");
+/home/you/projects/testing/src/main.rs:2     println!("Hello, world!")
 /home/you/projects/testing/src/main.rs:3 }
 ```
 
@@ -2974,18 +2970,8 @@ We'll turn this lint off for just this function soon. For now, just ignore this
 output.
 
 ```{notrust,ignore}
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-```
+     Running target/lib-654ce120f310a3a5
 
-Wait a minute, zero tests? Didn't we define one? Yup. This output is from
-attempting to run the tests in our crate, of which we don't have any.
-You'll note that Rust reports on several kinds of tests: passed, failed,
-ignored, and measured. The 'measured' tests refer to benchmark tests, which
-we'll cover soon enough!
-
-```{notrust,ignore}
 running 1 test
 test foo ... FAILED
 ```
@@ -3008,7 +2994,7 @@ failures:
 
 test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured
 
-task '<main>' failed at 'Some tests failed', /home/you/src/rust/src/libtest/lib.rs:242
+task '<main>' failed at 'Some tests failed', /home/you/src/rust/src/libtest/lib.rs:243
 ```
 
 After all the tests run, Rust will show us any output from our failed tests.
@@ -3029,29 +3015,30 @@ And then try to run our tests again:
 ```{notrust,ignore}
 $ cargo test
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
-/home/you/projects/testing/src/main.rs:1:1: 3:2 warning: code is never used: `main`, #[warn(dead_code)] on by default
-/home/you/projects/testing/src/main.rs:1 fn main() {
-/home/you/projects/testing/src/main.rs:2     println!("Hello, world");
-/home/you/projects/testing/src/main.rs:3 }
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
+     Running target/lib-654ce120f310a3a5
 
 running 1 test
 test foo ... ok
 
 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+     Running target/testing-6d7518593c7c3ee5
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 ```
 
-Nice! Our test passes, as we expected. Let's get rid of that warning for our `main`
-function. Change your `src/main.rs` to look like this:
+Nice! Our test passes, as we expected. Note how we didn't get the
+`main` warning this time? This is because `src/main.rs` didn't
+need recompiling, but we'll get that warning again if we
+change (and recompile) that file. Let's get rid of that
+warning; change your `src/main.rs` to look like this:
 
 ```{rust}
 #[cfg(not(test))]
 fn main() {
-    println!("Hello, world");
+    println!("Hello, world!")
 }
 ```
 
@@ -3062,21 +3049,24 @@ our tests, it sets things up so that `cfg(test)` is true. But we want to only
 include `main` when it's _not_ true. So we use `not` to negate things:
 `cfg(not(test))` will only compile our code when the `cfg(test)` is false.
 
-With this attribute, we won't get the warning:
+With this attribute we won't get the warning (even
+though `src/main.rs` gets recompiled this time):
 
 ```{notrust,ignore}
 $ cargo test
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
+     Running target/lib-654ce120f310a3a5
 
 running 1 test
 test foo ... ok
 
 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+     Running target/testing-6d7518593c7c3ee5
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 ```
 
 Nice. Okay, let's write a real test now. Change your `tests/lib.rs`
@@ -3133,7 +3123,7 @@ extern crate testing;
 
 #[cfg(not(test))]
 fn main() {
-    println!("Hello, world");
+    println!("Hello, world!")
 }
 ```
 
@@ -3156,21 +3146,30 @@ Let's give it a run:
 ```{ignore,notrust}
 $ cargo test
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
+     Running target/lib-654ce120f310a3a5
+
+running 1 test
+test math_checks_out ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+     Running target/testing-6d7518593c7c3ee5
 
 running 0 tests
 
 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 
+     Running target/testing-8a94b31f7fd2e8fe
 
 running 0 tests
 
 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 
+   Doc-tests testing
 
-running 1 test
-test math_checks_out ... ok
+running 0 tests
 
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 ```
 
 Great! One test passed. We've got an integration test showing that our public
@@ -3196,21 +3195,30 @@ If you run `cargo test`, you should get the same output:
 ```{ignore,notrust}
 $ cargo test
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
+     Running target/lib-654ce120f310a3a5
+
+running 1 test
+test math_checks_out ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+     Running target/testing-6d7518593c7c3ee5
 
 running 0 tests
 
 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 
+     Running target/testing-8a94b31f7fd2e8fe
 
 running 0 tests
 
 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 
+   Doc-tests testing
 
-running 1 test
-test math_checks_out ... ok
+running 0 tests
 
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 ```
 
 If we tried to write a test for these two new functions, it wouldn't
@@ -3283,6 +3291,20 @@ Let's give it a shot:
 ```{ignore,notrust}
 $ cargo test
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
+     Running target/lib-654ce120f310a3a5
+
+running 1 test
+test math_checks_out ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+     Running target/testing-6d7518593c7c3ee5
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+     Running target/testing-8a94b31f7fd2e8fe
 
 running 2 tests
 test test::test_times_four ... ok
@@ -3290,16 +3312,11 @@ test test::test_add_three ... ok
 
 test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured
 
+   Doc-tests testing
 
 running 0 tests
 
 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test math_checks_out ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
 ```
 
 Cool! We now have two tests of our internal functions. You'll note that there
@@ -3637,40 +3654,72 @@ pub fn as_maybe_owned(&self) -> MaybeOwned<'a> { ... }
 
 ## Boxes
 
-All of our references so far have been to variables we've created on the stack.
-In Rust, the simplest way to allocate heap variables is using a *box*.  To
-create a box, use the `box` keyword:
+Most of the types we've seen so far have a fixed size or number of components.
+The compiler needs this fact to lay out values in memory. However, some data
+structures, such as a linked list, do not have a fixed size. You might think to
+implement a linked list with an enum that's either a `Node` or the end of the
+list (`Nil`), like this:
+
+```{rust,ignore}
+enum List {             // error: illegal recursive enum type
+    Node(u32, List),
+    Nil
+}
+```
+
+But the compiler complains that the type is recursive, that is, it could be
+arbitrarily large. To remedy this, Rust provides a fixed-size container called
+a **box** that can hold any type. You can box up any value with the `box`
+keyword. Our boxed List gets the type `Box<List>` (more on the notation when we
+get to generics):
 
 ```{rust}
-let x = box 5i;
+enum List {
+    Node(u32, Box<List>),
+    Nil
+}
+
+fn main() {
+    let list = Node(0, box Node(1, box Nil));
+}
 ```
 
-This allocates an integer `5` on the heap, and creates a binding `x` that
-refers to it. The great thing about boxed pointers is that we don't have to
-manually free this allocation! If we write
+A box dynamically allocates memory to hold its contents. The great thing about
+Rust is that that memory is *automatically*, *efficiently*, and *predictably*
+deallocated when you're done with the box.
+
+A box is a pointer type, and you access what's inside using the `*` operator,
+just like regular references. This (rather silly) example dynamically allocates
+an integer `5` and makes `x` a pointer to it:
 
 ```{rust}
 {
     let x = box 5i;
-    // do stuff
+    println!("{}", *x);     // Prints 5
 }
 ```
 
-then Rust will automatically free `x` at the end of the block. This isn't
-because Rust has a garbage collector -- it doesn't. Instead, when `x` goes out
-of scope, Rust `free`s `x`. This Rust code will do the same thing as the
-following C code:
+The great thing about boxes is that we don't have to manually free this
+allocation! Instead, when `x` reaches the end of its lifetime -- in this case,
+when it goes out of scope at the end of the block -- Rust `free`s `x`. This
+isn't because Rust has a garbage collector (it doesn't). Instead, by tracking
+the ownership and lifetime of a variable (with a little help from you, the
+programmer), the compiler knows precisely when it is no longer used.
+
+The Rust code above will do the same thing as the following C code:
 
 ```{c,ignore}
 {
     int *x = (int *)malloc(sizeof(int));
-    // do stuff
+    if (!x) abort();
+    *x = 5;
+    printf("%d\n", *x);
     free(x);
 }
 ```
 
-This means we get the benefits of manual memory management, but the compiler
-ensures that we don't do something wrong. We can't forget to `free` our memory.
+We get the benefits of manual memory management, while ensuring we don't
+introduce any bugs. We can't forget to `free` our memory.
 
 Boxes are the sole owner of their contents, so you cannot take a mutable
 reference to them and then use the original box:
@@ -3706,48 +3755,50 @@ let mut x = box 5i;
 *x;
 ```
 
-## Rc and Arc
-
-Sometimes, you need to allocate something on the heap, but give out multiple
-references to the memory. Rust's `Rc<T>` (pronounced 'arr cee tee') and
-`Arc<T>` types (again, the `T` is for generics, we'll learn more later) provide
-you with this ability.  **Rc** stands for 'reference counted,' and **Arc** for
-'atomically reference counted.' This is how Rust keeps track of the multiple
-owners: every time we make a new reference to the `Rc<T>`, we add one to its
-internal 'reference count.' Every time a reference goes out of scope, we
-subtract one from the count. When the count is zero, the `Rc<T>` can be safely
-deallocated. `Arc<T>` is almost identical to `Rc<T>`, except for one thing: The
-'atomically' in 'Arc' means that increasing and decreasing the count uses a
-thread-safe mechanism to do so. Why two types? `Rc<T>` is faster, so if you're
-not in a multi-threaded scenario, you can have that advantage. Since we haven't
-talked about threading yet in Rust, we'll show you `Rc<T>` for the rest of this
-section.
+Boxes are simple and efficient pointers to dynamically allocated values with a
+single owner. They are useful for tree-like structures where the lifetime of a
+child depends solely on the lifetime of its (single) parent. If you need a
+value that must persist as long as any of several referrers, read on.
 
-To create an `Rc<T>`, use `Rc::new()`:
+## Rc and Arc
 
-```{rust}
-use std::rc::Rc;
+Sometimes, you need a variable that is referenced from multiple places
+(immutably!), lasting as long as any of those places, and disappearing when it
+is no longer referenced. For instance, in a graph-like data structure, a node
+might be referenced from all of its neighbors. In this case, it is not possible
+for the compiler to determine ahead of time when the value can be freed -- it
+needs a little run-time support.
 
-let x = Rc::new(5i);
-```
+Rust's **Rc** type provides shared ownership of a dynamically allocated value
+that is automatically freed at the end of its last owner's lifetime. (`Rc`
+stands for 'reference counted,' referring to the way these library types are
+implemented.) This provides more flexibility than single-owner boxes, but has
+some runtime overhead.
 
-To create a second reference, use the `.clone()` method:
+To create an `Rc` value, use `Rc::new()`. To create a second owner, use the
+`.clone()` method:
 
 ```{rust}
 use std::rc::Rc;
 
 let x = Rc::new(5i);
 let y = x.clone();
+
+println!("{} {}", *x, *y);      // Prints 5 5
 ```
 
-The `Rc<T>` will live as long as any of its references are alive. After they
-all go out of scope, the memory will be `free`d.
+The `Rc` will live as long as any of its owners are alive. After that, the
+memory will be `free`d.
+
+**Arc** is an 'atomically reference counted' value, identical to `Rc` except
+that ownership can be safely shared among multiple threads. Why two types?
+`Arc` has more overhead, so if you're not in a multi-threaded scenario, you
+don't have to pay the price.
 
-If you use `Rc<T>` or `Arc<T>`, you have to be careful about introducing
-cycles. If you have two `Rc<T>`s that point to each other, the reference counts
-will never drop to zero, and you'll have a memory leak. To learn more, check
-out [the section on `Rc<T>` and `Arc<T>` in the pointers
-guide](guide-pointers.html#rc-and-arc).
+If you use `Rc` or `Arc`, you have to be careful about introducing cycles. If
+you have two `Rc`s that point to each other, they will happily keep each other
+alive forever, creating a memory leak. To learn more, check out [the section on
+`Rc` and `Arc` in the pointers guide](guide-pointers.html#rc-and-arc).
 
 # Patterns
 
@@ -4010,8 +4061,8 @@ syntax.
 
 # Closures
 
-So far, we've made lots of functions in Rust. But we've given them all names.
-Rust also allows us to create anonymous functions too. Rust's anonymous
+So far, we've made lots of functions in Rust, but we've given them all names.
+Rust also allows us to create anonymous functions. Rust's anonymous
 functions are called **closure**s. By themselves, closures aren't all that
 interesting, but when you combine them with functions that take closures as
 arguments, really powerful things are possible.
@@ -4040,7 +4091,7 @@ don't need to declare one. This is different from named functions, which
 default to returning unit (`()`).
 
 There's one big difference between a closure and named functions, and it's in
-the name: a closure "closes over its environment." What's that mean? It means
+the name: a closure "closes over its environment." What does that mean? It means
 this:
 
 ```{rust}
@@ -4056,8 +4107,8 @@ fn main() {
 The `||` syntax means this is an anonymous closure that takes no arguments.
 Without it, we'd just have a block of code in `{}`s.
 
-In other words, a closure has access to variables in the scope that it's
-defined. The closure borrows any variables that it uses. This will error:
+In other words, a closure has access to variables in the scope where it's
+defined. The closure borrows any variables it uses, so this will error:
 
 ```{rust,ignore}
 fn main() {
@@ -4081,7 +4132,7 @@ let p = proc() { x * x };
 println!("{}", p()); // prints 25
 ```
 
-Procs have a big difference from closures: they may only be called once. This
+There is a big difference between procs and closures: procs may only be called once. This
 will error when we try to compile:
 
 ```{rust,ignore}
@@ -4174,10 +4225,10 @@ before. And we pass in our `x` argument to each one. Hence 'twice.'
 If you do the math, `(5 * 5) + (5 * 5) == 50`, so that's the output we get.
 
 Play around with this concept until you're comfortable with it. Rust's standard
-library uses lots of closures, where appropriate, so you'll be using
+library uses lots of closures where appropriate, so you'll be using
 this technique a lot.
 
-If we didn't want to give `square` a name, we could also just define it inline.
+If we didn't want to give `square` a name, we could just define it inline.
 This example is the same as the previous one:
 
 ```{rust}
@@ -4205,12 +4256,12 @@ fn main() {
 }
 ```
 
-Doing this is not particularly common, but every once in a while, it's useful.
+Doing this is not particularly common, but it's useful every once in a while.
 
 That's all you need to get the hang of closures! Closures are a little bit
-strange at first, but once you're used to using them, you'll miss them in any
-language that doesn't have them. Passing functions to other functions is
-incredibly powerful. Next, let's look at one of those things: iterators.
+strange at first, but once you're used to them, you'll miss them
+in other languages. Passing functions to other functions is
+incredibly powerful, as you will see in the following chapter about iterators.
 
 # Iterators
 
@@ -4220,7 +4271,7 @@ Remember Rust's `for` loop? Here's an example:
 
 ```{rust}
 for x in range(0i, 10i) {
-    println!("{:d}", x);
+    println!("{}", x);
 }
 ```
 
@@ -4353,7 +4404,7 @@ is one:
 
 ```{rust}
 let greater_than_forty_two = range(0i, 100i)
-                             .find(|x| *x >= 42);
+                             .find(|x| *x > 42);
 
 match greater_than_forty_two {
     Some(_) => println!("We got some numbers!"),
@@ -4474,7 +4525,7 @@ range(1i, 100i).map(|x| x + 1i);
 
 `map` is called upon another iterator, and produces a new iterator where each
 element reference has the closure it's been given as an argument called on it.
-So this would give us the numbers from `2-101`. Well, almost! If you
+So this would give us the numbers from `2-100`. Well, almost! If you
 compile the example, you'll get a warning:
 
 ```{notrust,ignore}
@@ -4494,9 +4545,10 @@ range(1i, 100i).map(|x| println!("{}", x));
 If you are trying to execute a closure on an iterator for its side effects,
 just use `for` instead.
 
-There are tons of interesting iterator adapters. `take(n)` will get the
-first `n` items out of an iterator, and return them as a list. Let's
-try it out with our infinite iterator from before, `count()`:
+There are tons of interesting iterator adapters. `take(n)` will return an
+iterator over the next `n` elements of the original iterator, note that this
+has no side effect on the original iterator. Let's try it out with our infinite
+iterator from before, `count()`:
 
 ```{rust}
 for i in std::iter::count(1i, 5i).take(5) {
@@ -5161,17 +5213,17 @@ immediately.
 
 ## Success and failure
 
-Tasks don't always succeed, they can also fail. A task that wishes to fail
-can call the `fail!` macro, passing a message:
+Tasks don't always succeed, they can also panic. A task that wishes to panic 
+can call the `panic!` macro, passing a message:
 
 ```{rust}
 spawn(proc() {
-    fail!("Nope.");
+    panic!("Nope.");
 });
 ```
 
-If a task fails, it is not possible for it to recover. However, it can
-notify other tasks that it has failed. We can do this with `task::try`:
+If a task panics, it is not possible for it to recover. However, it can
+notify other tasks that it has panicked. We can do this with `task::try`:
 
 ```{rust}
 use std::task;
@@ -5181,14 +5233,14 @@ let result = task::try(proc() {
     if rand::random() {
         println!("OK");
     } else {
-        fail!("oops!");
+        panic!("oops!");
     }
 });
 ```
 
-This task will randomly fail or succeed. `task::try` returns a `Result`
+This task will randomly panic or succeed. `task::try` returns a `Result`
 type, so we can handle the response like any other computation that may
-fail.
+panic.
 
 # Macros
 
@@ -5288,9 +5340,9 @@ There are two circumstances where Rust's safety provisions don't work well.
 The first is when interfacing with C code, and the second is when building
 certain kinds of abstractions.
 
-Rust has support for FFI (which you can read about in the [FFI
-Guide](guide-ffi.html)), but can't guarantee that the C code will be safe.
-Therefore, Rust marks such functions with the `unsafe`
+Rust has support for [FFI](http://en.wikipedia.org/wiki/Foreign_function_interface)
+(which you can read about in the [FFI Guide](guide-ffi.html)), but can't guarantee
+that the C code will be safe. Therefore, Rust marks such functions with the `unsafe`
 keyword, which indicates that the function may not behave properly.
 
 Second, if you'd like to create some sort of shared-memory data structure, Rust
index ad548d3a8f93c331c0d64928087cccdece7c1a8e..8d54550a9f988d7e62f1d307e84f72d71db515ba 100644 (file)
@@ -57,6 +57,7 @@ a guide that can help you out:
 * [Strings](guide-strings.html)
 * [Pointers](guide-pointers.html)
 * [References and Lifetimes](guide-lifetimes.html)
+* [Crates and modules](guide-crates.html)
 * [Tasks and Communication](guide-tasks.html)
 * [Foreign Function Interface](guide-ffi.html)
 * [Writing Unsafe and Low-Level Code](guide-unsafe.html)
index 6fd4c95794ee7e96b72b1b79b7271a0abc275ac1..25f1a5fd3e2e40582b2c8c6d5890c5c9caabeda7 100644 (file)
@@ -19,6 +19,7 @@
 [type: text] src/doc/guide-tasks.md $lang:doc/l10n/$lang/guide-tasks.md
 [type: text] src/doc/guide-testing.md $lang:doc/l10n/$lang/guide-testing.md
 [type: text] src/doc/guide-unsafe.md $lang:doc/l10n/$lang/guide-unsafe.md
+[type: text] src/doc/guide-unsafe.md $lang:doc/l10n/$lang/guide-crates.md
 [type: text] src/doc/guide.md $lang:doc/l10n/$lang/guide.md
 [type: text] src/doc/index.md $lang:doc/l10n/$lang/index.md
 [type: text] src/doc/intro.md $lang:doc/l10n/$lang/intro.md
index 11bf895341b90619a4c36308b224e55ecbbf1cf3..fab4697123072c5bbe49257d8c2650744d9774a7 100644 (file)
@@ -185,28 +185,29 @@ grammar as double-quoted strings. Other tokens have exact rules given.
 
 ### Keywords
 
-<p id="keyword-table-marker">The keywords are the following strings, organized by first letter:</p>
-
-|          |        |        |       |
-|----------|--------|--------|-------|
-| as       |        |        |       |
-| box      | break  |        |       |
-| continue | crate  |        |       |
-| else     | enum   | extern |       |
-| false    | fn     | for    |       |
-| if       | impl   | in     |       |
-| let      | loop   |        |       |
-| match    | mod    | mut    |       |
-| priv     | proc   | pub    |       |
-| ref      | return |        |       |
-| self     | static | struct | super |
-| trait    | true   | type   |       |
-| unsafe   | use    |        |       |
-| while    |        |        |       |
+<p id="keyword-table-marker"></p>
+
+|          |          |          |          |        |
+|----------|----------|----------|----------|--------|
+| abstract | alignof  | as       | be       | box    |
+| break    | const    | continue | crate    | do     |
+| else     | enum     | extern   | false    | final  |
+| fn       | for      | if       | impl     | in     |
+| let      | loop     | match    | mod      | move   |
+| mut      | offsetof | once     | override | priv   |
+| proc     | pub      | pure     | ref      | return |
+| sizeof   | static   | self     | struct   | super  |
+| true     | trait    | type     | typeof   | unsafe |
+| unsized  | use      | virtual  | where    | while  |
+| yield    |          |          |          |        |
+
 
 Each of these keywords has special meaning in its grammar, and all of them are
 excluded from the `ident` rule.
 
+Note that some of these keywords are reserved, and do not currently do
+anything.
+
 ### Literals
 
 A literal is an expression consisting of a single token, rather than a sequence
@@ -817,15 +818,15 @@ mod math {
     type Complex = (f64, f64);
     fn sin(f: f64) -> f64 {
         /* ... */
-# fail!();
+# panic!();
     }
     fn cos(f: f64) -> f64 {
         /* ... */
-# fail!();
+# panic!();
     }
     fn tan(f: f64) -> f64 {
         /* ... */
-# fail!();
+# panic!();
     }
 }
 ```
@@ -1194,12 +1195,12 @@ output slot type would normally be. For example:
 ```
 fn my_err(s: &str) -> ! {
     println!("{}", s);
-    fail!();
+    panic!();
 }
 ```
 
 We call such functions "diverging" because they never return a value to the
-caller. Every control path in a diverging function must end with a `fail!()` or
+caller. Every control path in a diverging function must end with a `panic!()` or
 a call to another diverging function on every control path. The `!` annotation
 does *not* denote a type. Rather, the result type of a diverging function is a
 special type called $\bot$ ("bottom") that unifies with any type. Rust has no
@@ -1212,7 +1213,7 @@ were declared without the `!` annotation, the following code would not
 typecheck:
 
 ```
-# fn my_err(s: &str) -> ! { fail!() }
+# fn my_err(s: &str) -> ! { panic!() }
 
 fn f(i: int) -> int {
    if i == 42 {
@@ -2259,7 +2260,7 @@ These types help drive the compiler's analysis
   : Allocate memory on the exchange heap.
 * `closure_exchange_malloc`
   : ___Needs filling in___
-* `fail_`
+* `panic`
   : Abort the program with an error.
 * `fail_bounds_check`
   : Abort the program with a bounds check error.
@@ -2866,11 +2867,11 @@ be assigned to.
 
 Indices are zero-based, and may be of any integral type. Vector access is
 bounds-checked at run-time. When the check fails, it will put the task in a
-_failing state_.
+_panicked state_.
 
 ```{should-fail}
 ([1, 2, 3, 4])[0];
-(["a", "b"])[10]; // fails
+(["a", "b"])[10]; // panics
 ```
 
 ### Unary operator expressions
@@ -3300,9 +3301,9 @@ enum List<X> { Nil, Cons(X, Box<List<X>>) }
 let x: List<int> = Cons(10, box Cons(11, box Nil));
 
 match x {
-    Cons(_, box Nil) => fail!("singleton list"),
+    Cons(_, box Nil) => panic!("singleton list"),
     Cons(..)         => return,
-    Nil              => fail!("empty list")
+    Nil              => panic!("empty list")
 }
 ```
 
@@ -3373,7 +3374,7 @@ match x {
         return;
     }
     _ => {
-        fail!();
+        panic!();
     }
 }
 ```
@@ -3395,7 +3396,7 @@ fn is_sorted(list: &List) -> bool {
         Cons(x, ref r @ box Cons(_, _)) => {
             match *r {
                 box Cons(y, _) => (x <= y) && is_sorted(&**r),
-                _ => fail!()
+                _ => panic!()
             }
         }
     }
@@ -3459,7 +3460,7 @@ may refer to the variables bound within the pattern they follow.
 let message = match maybe_digit {
   Some(x) if x < 10 => process_digit(x),
   Some(x) => process_other(x),
-  None => fail!()
+  None => panic!()
 };
 ```
 
@@ -4091,7 +4092,7 @@ cause transitions between the states. The lifecycle states of a task are:
 
 * running
 * blocked
-* failing
+* panicked 
 * dead
 
 A task begins its lifecycle &mdash; once it has been spawned &mdash; in the
@@ -4103,21 +4104,21 @@ it makes a blocking communication call. When the call can be completed &mdash;
 when a message arrives at a sender, or a buffer opens to receive a message
 &mdash; then the blocked task will unblock and transition back to *running*.
 
-A task may transition to the *failing* state at any time, due being killed by
-some external event or internally, from the evaluation of a `fail!()` macro.
-Once *failing*, a task unwinds its stack and transitions to the *dead* state.
+A task may transition to the *panicked* state at any time, due being killed by
+some external event or internally, from the evaluation of a `panic!()` macro.
+Once *panicking*, a task unwinds its stack and transitions to the *dead* state.
 Unwinding the stack of a task is done by the task itself, on its own control
 stack. If a value with a destructor is freed during unwinding, the code for the
 destructor is run, also on the task's control stack. Running the destructor
 code causes a temporary transition to a *running* state, and allows the
 destructor code to cause any subsequent state transitions. The original task
-of unwinding and failing thereby may suspend temporarily, and may involve
+of unwinding and panicking thereby may suspend temporarily, and may involve
 (recursive) unwinding of the stack of a failed destructor. Nonetheless, the
 outermost unwinding activity will continue until the stack is unwound and the
 task transitions to the *dead* state. There is no way to "recover" from task
-failure. Once a task has temporarily suspended its unwinding in the *failing*
-state, failure occurring from within this destructor results in *hard* failure.
-A hard failure currently results in the process aborting.
+panics. Once a task has temporarily suspended its unwinding in the *panicking*
+state, a panic occurring from within this destructor results in *hard* panic.
+A hard panic currently results in the process aborting.
 
 A task in the *dead* state cannot transition to other states; it exists only to
 have its termination status inspected by other tasks, and/or to await
index f5fbad960a3f5a0b0250de42ba50099af4332ea4..05475c605ea7214a11eb9901c3b65f1d40264136 100644 (file)
@@ -169,7 +169,7 @@ directive.
 
 ~~~md
 ```should_fail
-// This code block is expected to generate a failure when run
+// This code block is expected to generate a panic when run
 ```
 ~~~
 
@@ -189,7 +189,7 @@ were passed to the compiler using the `test_harness` directive.
 ```test_harness
 #[test]
 fn foo() {
-    fail!("oops! (will run & register as failure)")
+    panic!("oops! (will run & register as a failed test)")
 }
 ```
 ~~~
@@ -221,7 +221,7 @@ testing this code, the `fib` function will be included (so it can compile).
 
 Running tests often requires some special configuration to filter tests, find
 libraries, or try running ignored examples. The testing framework that rustdoc
-uses is build on crate `test`, which is also used when you compile crates with
+uses is built on crate `test`, which is also used when you compile crates with
 rustc's `--test` flag. Extra arguments can be passed to rustdoc's test harness
 with the `--test-args` flag.
 
index 1b6794e77f9f45484d7071eb760c5c77e5256996..f255dbf15071b6dc3852bace3c21aa7d706ab759 100644 (file)
@@ -376,7 +376,7 @@ fn bar(   a:int,
           -> int
 { }
 
-fn baz(   a:int,  // shoudl work with a comment here
+fn baz(   a:int,  // should work with a comment here
           b:char)
           -> int
 { }
diff --git a/src/etc/rustup.sh b/src/etc/rustup.sh
new file mode 100644 (file)
index 0000000..4829e15
--- /dev/null
@@ -0,0 +1,476 @@
+#!/bin/sh
+# Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+# file at the top-level directory of this distribution and at
+# http://rust-lang.org/COPYRIGHT.
+#
+# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+# option. This file may not be copied, modified, or distributed
+# except according to those terms.
+
+
+msg() {
+    echo "rustup: $1"
+}
+
+step_msg() {
+    msg
+    msg "$1"
+    msg
+}
+
+warn() {
+    echo "rustup: WARNING: $1"
+}
+
+err() {
+    echo "rustup: error: $1"
+    exit 1
+}
+
+need_ok() {
+    if [ $? -ne 0 ]
+    then
+        err "$1"
+    fi
+}
+
+
+putvar() {
+    local T
+    eval T=\$$1
+    eval TLEN=\${#$1}
+    if [ $TLEN -gt 35 ]
+    then
+        printf "rustup: %-20s := %.35s ...\n" $1 "$T"
+    else
+        printf "rustup: %-20s := %s %s\n" $1 "$T" "$2"
+    fi
+}
+
+probe() {
+    local V=$1
+    shift
+    local P
+    local T
+    for P
+    do
+        T=$(which $P 2>&1)
+        if [ $? -eq 0 ]
+        then
+            VER0=$($P --version 2>/dev/null | head -1 \
+                |  sed -e 's/[^0-9]*\([vV]\?[0-9.]\+[^ ]*\).*/\1/' )
+            if [ $? -eq 0 -a "x${VER0}" != "x" ]
+            then
+              VER="($VER0)"
+            else
+              VER=""
+            fi
+            break
+        else
+            VER=""
+            T=""
+        fi
+    done
+    eval $V=\$T
+    putvar $V "$VER"
+}
+
+probe_need() {
+    local V=$1
+    probe $*
+    eval VV=\$$V
+    if [ -z "$VV" ]
+    then
+        err "needed, but unable to find any of: $*"
+    fi
+}
+
+
+valopt() {
+    VAL_OPTIONS="$VAL_OPTIONS $1"
+
+    local OP=$1
+    local DEFAULT=$2
+    shift
+    shift
+    local DOC="$*"
+    if [ $HELP -eq 0 ]
+    then
+        local UOP=$(echo $OP | tr '[:lower:]' '[:upper:]' | tr '\-' '\_')
+        local V="CFG_${UOP}"
+        eval $V="$DEFAULT"
+        for arg in $CFG_ARGS
+        do
+            if echo "$arg" | grep -q -- "--$OP="
+            then
+                val=$(echo "$arg" | cut -f2 -d=)
+                eval $V=$val
+            fi
+        done
+        putvar $V
+    else
+        if [ -z "$DEFAULT" ]
+        then
+            DEFAULT="<none>"
+        fi
+        OP="${OP}=[${DEFAULT}]"
+        printf "    --%-30s %s\n" "$OP" "$DOC"
+    fi
+}
+
+opt() {
+    BOOL_OPTIONS="$BOOL_OPTIONS $1"
+
+    local OP=$1
+    local DEFAULT=$2
+    shift
+    shift
+    local DOC="$*"
+    local FLAG=""
+
+    if [ $DEFAULT -eq 0 ]
+    then
+        FLAG="enable"
+    else
+        FLAG="disable"
+        DOC="don't $DOC"
+    fi
+
+    if [ $HELP -eq 0 ]
+    then
+        for arg in $CFG_ARGS
+        do
+            if [ "$arg" = "--${FLAG}-${OP}" ]
+            then
+                OP=$(echo $OP | tr 'a-z-' 'A-Z_')
+                FLAG=$(echo $FLAG | tr 'a-z' 'A-Z')
+                local V="CFG_${FLAG}_${OP}"
+                eval $V=1
+                putvar $V
+            fi
+        done
+    else
+        if [ ! -z "$META" ]
+        then
+            OP="$OP=<$META>"
+        fi
+        printf "    --%-30s %s\n" "$FLAG-$OP" "$DOC"
+     fi
+}
+
+flag() {
+    BOOL_OPTIONS="$BOOL_OPTIONS $1"
+
+    local OP=$1
+    shift
+    local DOC="$*"
+
+    if [ $HELP -eq 0 ]
+    then
+        for arg in $CFG_ARGS
+        do
+            if [ "$arg" = "--${OP}" ]
+            then
+                OP=$(echo $OP | tr 'a-z-' 'A-Z_')
+                local V="CFG_${OP}"
+                eval $V=1
+                putvar $V
+            fi
+        done
+    else
+        if [ ! -z "$META" ]
+        then
+            OP="$OP=<$META>"
+        fi
+        printf "    --%-30s %s\n" "$OP" "$DOC"
+     fi
+}
+
+validate_opt () {
+    for arg in $CFG_ARGS
+    do
+        isArgValid=0
+        for option in $BOOL_OPTIONS
+        do
+            if test --disable-$option = $arg
+            then
+                isArgValid=1
+            fi
+            if test --enable-$option = $arg
+            then
+                isArgValid=1
+            fi
+            if test --$option = $arg
+            then
+                isArgValid=1
+            fi
+        done
+        for option in $VAL_OPTIONS
+        do
+            if echo "$arg" | grep -q -- "--$option="
+            then
+                isArgValid=1
+            fi
+        done
+        if [ "$arg" = "--help" ]
+        then
+            echo
+            echo "No more help available for Configure options,"
+            echo "check the Wiki or join our IRC channel"
+            break
+        else
+            if test $isArgValid -eq 0
+            then
+                err "Option '$arg' is not recognized"
+            fi
+        fi
+    done
+}
+
+probe_need CFG_CURL  curl
+
+CFG_SRC_DIR="$(cd $(dirname $0) && pwd)/"
+CFG_SELF="$0"
+CFG_ARGS="$@"
+
+HELP=0
+if [ "$1" = "--help" ]
+then
+    HELP=1
+    shift
+    echo
+    echo "Usage: $CFG_SELF [options]"
+    echo
+    echo "Options:"
+    echo
+else
+    step_msg "processing $CFG_SELF args"
+fi
+
+OPTIONS=""
+BOOL_OPTIONS=""
+VAL_OPTIONS=""
+
+flag uninstall "only uninstall from the installation prefix"
+valopt prefix "" "set installation prefix"
+opt cargo 1 "install cargo with rust"
+
+if [ $HELP -eq 1 ]
+then
+    echo
+    exit 0
+fi
+
+step_msg "validating $CFG_SELF args"
+validate_opt
+
+
+# Platform detection copied from `configure`
+
+CFG_OSTYPE=$(uname -s)
+CFG_CPUTYPE=$(uname -m)
+
+if [ $CFG_OSTYPE = Darwin -a $CFG_CPUTYPE = i386 ]
+then
+    # Darwin's `uname -s` lies and always returns i386. We have to use sysctl
+    # instead.
+    if sysctl hw.optional.x86_64 | grep -q ': 1'
+    then
+        CFG_CPUTYPE=x86_64
+    fi
+fi
+
+# The goal here is to come up with the same triple as LLVM would,
+# at least for the subset of platforms we're willing to target.
+
+case $CFG_OSTYPE in
+
+    Linux)
+        CFG_OSTYPE=unknown-linux-gnu
+        ;;
+
+    FreeBSD)
+        CFG_OSTYPE=unknown-freebsd
+        ;;
+
+    Darwin)
+        CFG_OSTYPE=apple-darwin
+        ;;
+
+    MINGW32*)
+        CFG_OSTYPE=pc-mingw32
+        ;;
+# Thad's Cygwin identifers below
+
+#   Vista 32 bit
+    CYGWIN_NT-6.0)
+        CFG_OSTYPE=pc-mingw32
+        CFG_CPUTYPE=i686
+        ;;
+
+#   Vista 64 bit
+    CYGWIN_NT-6.0-WOW64)
+        CFG_OSTYPE=w64-mingw32
+        CFG_CPUTYPE=x86_64
+        ;;
+
+#   Win 7 32 bit
+    CYGWIN_NT-6.1)
+        CFG_OSTYPE=pc-mingw32
+        CFG_CPUTYPE=i686
+        ;;
+
+#   Win 7 64 bit
+    CYGWIN_NT-6.1-WOW64)
+        CFG_OSTYPE=w64-mingw32
+        CFG_CPUTYPE=x86_64
+        ;;
+
+# We do not detect other OS such as XP/2003 using 64 bit using uname.
+# If we want to in the future, we will need to use Cygwin
+# Chuck's csih helper in /usr/lib/csih/winProductName.exe or alternative.
+    *)
+        err "unknown OS type: $CFG_OSTYPE"
+        ;;
+esac
+
+
+case $CFG_CPUTYPE in
+
+    i386 | i486 | i686 | i786 | x86)
+        CFG_CPUTYPE=i686
+        ;;
+
+    xscale | arm)
+        CFG_CPUTYPE=arm
+        ;;
+
+    x86_64 | x86-64 | x64 | amd64)
+        CFG_CPUTYPE=x86_64
+        ;;
+
+    *)
+        err "unknown CPU type: $CFG_CPUTYPE"
+esac
+
+# Detect 64 bit linux systems with 32 bit userland and force 32 bit compilation
+if [ $CFG_OSTYPE = unknown-linux-gnu -a $CFG_CPUTYPE = x86_64 ]
+then
+    file -L "$SHELL" | grep -q "x86[_-]64"
+    if [ $? != 0 ]; then
+        CFG_CPUTYPE=i686
+    fi
+fi
+
+HOST_TRIPLE="${CFG_CPUTYPE}-${CFG_OSTYPE}"
+
+# Is this a triple we have nightlies for?
+case $HOST_TRIPLE in
+
+        x86_64-unknown-linux-gnu)
+                ;;
+
+        i686-unknown-linux-gnu)
+                ;;
+
+        x86_64-apple-darwin)
+                ;;
+
+        i686-apple-darwin)
+                ;;
+
+        *)
+                err "rustup.sh doesn't work for host $HOST_TRIPLE"
+
+esac
+
+msg "host triple: ${HOST_TRIPLE}"
+
+PACKAGE_NAME=rust-nightly
+PACKAGE_NAME_AND_TRIPLE="${PACKAGE_NAME}-${HOST_TRIPLE}"
+TARBALL_NAME="${PACKAGE_NAME_AND_TRIPLE}.tar.gz"
+REMOTE_TARBALL="https://static.rust-lang.org/dist/${TARBALL_NAME}"
+TMP_DIR="./rustup-tmp-install"
+LOCAL_TARBALL="${TMP_DIR}/${TARBALL_NAME}"
+LOCAL_INSTALL_DIR="${TMP_DIR}/${PACKAGE_NAME_AND_TRIPLE}"
+LOCAL_INSTALL_SCRIPT="${LOCAL_INSTALL_DIR}/install.sh"
+
+CARGO_PACKAGE_NAME=cargo-nightly
+CARGO_PACKAGE_NAME_AND_TRIPLE="${CARGO_PACKAGE_NAME}-${HOST_TRIPLE}"
+CARGO_TARBALL_NAME="${CARGO_PACKAGE_NAME_AND_TRIPLE}.tar.gz"
+CARGO_REMOTE_TARBALL="https://static.rust-lang.org/cargo-dist/${CARGO_TARBALL_NAME}"
+CARGO_LOCAL_TARBALL="${TMP_DIR}/${CARGO_TARBALL_NAME}"
+CARGO_LOCAL_INSTALL_DIR="${TMP_DIR}/${CARGO_PACKAGE_NAME_AND_TRIPLE}"
+CARGO_LOCAL_INSTALL_SCRIPT="${CARGO_LOCAL_INSTALL_DIR}/install.sh"
+
+rm -Rf "${TMP_DIR}"
+need_ok "failed to remove temporary installation directory"
+
+mkdir -p "${TMP_DIR}"
+need_ok "failed to create create temporary installation directory"
+
+msg "downloading rust installer"
+"${CFG_CURL}" "${REMOTE_TARBALL}" > "${LOCAL_TARBALL}"
+if [ $? -ne 0 ]
+then
+        rm -Rf "${TMP_DIR}"
+        err "failed to download installer"
+fi
+
+if [ -z "${CFG_DISABLE_CARGO}" ]; then
+    msg "downloading cargo installer"
+    "${CFG_CURL}" "${CARGO_REMOTE_TARBALL}" > "${CARGO_LOCAL_TARBALL}"
+    if [ $? -ne 0 ]
+    then
+            rm -Rf "${TMP_DIR}"
+            err "failed to download cargo installer"
+    fi
+fi
+
+
+(cd "${TMP_DIR}" && tar xzf "${TARBALL_NAME}")
+if [ $? -ne 0 ]
+then
+        rm -Rf "${TMP_DIR}"
+        err "failed to unpack installer"
+fi
+
+MAYBE_UNINSTALL=
+if [ -n "${CFG_UNINSTALL}" ]
+then
+        MAYBE_UNINSTALL="--uninstall"
+fi
+
+MAYBE_PREFIX=
+if [ -n "${CFG_PREFIX}" ]
+then
+        MAYBE_PREFIX="--prefix=${CFG_PREFIX}"
+fi
+
+sh "${LOCAL_INSTALL_SCRIPT}" "${MAYBE_UNINSTALL}" "${MAYBE_PREFIX}"
+if [ $? -ne 0 ]
+then
+        rm -Rf "${TMP_DIR}"
+        err "failed to install Rust"
+fi
+
+if [ -z "${CFG_DISABLE_CARGO}" ]; then
+    (cd "${TMP_DIR}" && tar xzf "${CARGO_TARBALL_NAME}")
+    if [ $? -ne 0 ]
+    then
+            rm -Rf "${TMP_DIR}"
+            err "failed to unpack cargo installer"
+    fi
+
+    sh "${CARGO_LOCAL_INSTALL_SCRIPT}" "${MAYBE_UNINSTALL}" "${MAYBE_PREFIX}"
+    if [ $? -ne 0 ]
+    then
+            rm -Rf "${TMP_DIR}"
+            err "failed to install Cargo"
+    fi
+fi
+
+rm -Rf "${TMP_DIR}"
+need_ok "couldn't rm temporary installation directory"
index a95eeb3c97dc2c4dfff6530d0a4bbf64df251d6c..a4345e061640db7a38cee5783f350956d2a2ab6c 100644 (file)
 
 use syntax::ast;
 use syntax::ast::Name;
-use syntax::parse::token::*;
+use syntax::parse::token;
 use syntax::parse::lexer::TokenAndSpan;
 
 fn parse_token_list(file: &str) -> HashMap<String, Token> {
     fn id() -> Token {
-        IDENT(ast::Ident { name: Name(0), ctxt: 0, }, false)
+        token::Ident(ast::Ident { name: Name(0), ctxt: 0, }, token::Plain)
     }
 
     let mut res = HashMap::new();
@@ -52,64 +52,64 @@ fn id() -> Token {
         let num = line.slice_from(eq + 1);
 
         let tok = match val {
-            "SHR" => BINOP(SHR),
-            "DOLLAR" => DOLLAR,
-            "LT" => LT,
-            "STAR" => BINOP(STAR),
-            "FLOAT_SUFFIX" => id(),
-            "INT_SUFFIX" => id(),
-            "SHL" => BINOP(SHL),
-            "LBRACE" => LBRACE,
-            "RARROW" => RARROW,
-            "LIT_STR" => LIT_STR(Name(0)),
-            "DOTDOT" => DOTDOT,
-            "MOD_SEP" => MOD_SEP,
-            "DOTDOTDOT" => DOTDOTDOT,
-            "NOT" => NOT,
-            "AND" => BINOP(AND),
-            "LPAREN" => LPAREN,
-            "ANDAND" => ANDAND,
-            "AT" => AT,
-            "LBRACKET" => LBRACKET,
-            "LIT_STR_RAW" => LIT_STR_RAW(Name(0), 0),
-            "RPAREN" => RPAREN,
-            "SLASH" => BINOP(SLASH),
-            "COMMA" => COMMA,
-            "LIFETIME" => LIFETIME(ast::Ident { name: Name(0), ctxt: 0 }),
-            "CARET" => BINOP(CARET),
-            "TILDE" => TILDE,
-            "IDENT" => id(),
-            "PLUS" => BINOP(PLUS),
-            "LIT_CHAR" => LIT_CHAR(Name(0)),
-            "LIT_BYTE" => LIT_BYTE(Name(0)),
-            "EQ" => EQ,
-            "RBRACKET" => RBRACKET,
-            "COMMENT" => COMMENT,
-            "DOC_COMMENT" => DOC_COMMENT(Name(0)),
-            "DOT" => DOT,
-            "EQEQ" => EQEQ,
-            "NE" => NE,
-            "GE" => GE,
-            "PERCENT" => BINOP(PERCENT),
-            "RBRACE" => RBRACE,
-            "BINOP" => BINOP(PLUS),
-            "POUND" => POUND,
-            "OROR" => OROR,
-            "LIT_INTEGER" => LIT_INTEGER(Name(0)),
-            "BINOPEQ" => BINOPEQ(PLUS),
-            "LIT_FLOAT" => LIT_FLOAT(Name(0)),
-            "WHITESPACE" => WS,
-            "UNDERSCORE" => UNDERSCORE,
-            "MINUS" => BINOP(MINUS),
-            "SEMI" => SEMI,
-            "COLON" => COLON,
-            "FAT_ARROW" => FAT_ARROW,
-            "OR" => BINOP(OR),
-            "GT" => GT,
-            "LE" => LE,
-            "LIT_BINARY" => LIT_BINARY(Name(0)),
-            "LIT_BINARY_RAW" => LIT_BINARY_RAW(Name(0), 0),
-            _ => continue
+            "SHR"               => token::BinOp(token::Shr),
+            "DOLLAR"            => token::Dollar,
+            "LT"                => token::Lt,
+            "STAR"              => token::BinOp(token::Star),
+            "FLOAT_SUFFIX"      => id(),
+            "INT_SUFFIX"        => id(),
+            "SHL"               => token::BinOp(token::Shl),
+            "LBRACE"            => token::LBrace,
+            "RARROW"            => token::Rarrow,
+            "LIT_STR"           => token::LitStr(Name(0)),
+            "DOTDOT"            => token::DotDot,
+            "MOD_SEP"           => token::ModSep,
+            "DOTDOTDOT"         => token::DotDotDot,
+            "NOT"               => token::Not,
+            "AND"               => token::BinOp(token::And),
+            "LPAREN"            => token::LParen,
+            "ANDAND"            => token::AndAnd,
+            "AT"                => token::At,
+            "LBRACKET"          => token::LBracket,
+            "LIT_STR_RAW"       => token::LitStrRaw(Name(0), 0),
+            "RPAREN"            => token::RParen,
+            "SLASH"             => token::BinOp(token::Slash),
+            "COMMA"             => token::Comma,
+            "LIFETIME"          => token::Lifetime(ast::Ident { name: Name(0), ctxt: 0 }),
+            "CARET"             => token::BinOp(token::Caret),
+            "TILDE"             => token::Tilde,
+            "IDENT"             => token::Id(),
+            "PLUS"              => token::BinOp(token::Plus),
+            "LIT_CHAR"          => token::LitChar(Name(0)),
+            "LIT_BYTE"          => token::LitByte(Name(0)),
+            "EQ"                => token::Eq,
+            "RBRACKET"          => token::RBracket,
+            "COMMENT"           => token::Comment,
+            "DOC_COMMENT"       => token::DocComment(Name(0)),
+            "DOT"               => token::Dot,
+            "EQEQ"              => token::EqEq,
+            "NE"                => token::Ne,
+            "GE"                => token::Ge,
+            "PERCENT"           => token::BinOp(token::Percent),
+            "RBRACE"            => token::RBrace,
+            "BINOP"             => token::BinOp(token::Plus),
+            "POUND"             => token::Pound,
+            "OROR"              => token::OrOr,
+            "LIT_INTEGER"       => token::LitInteger(Name(0)),
+            "BINOPEQ"           => token::BinOpEq(token::Plus),
+            "LIT_FLOAT"         => token::LitFloat(Name(0)),
+            "WHITESPACE"        => token::Whitespace,
+            "UNDERSCORE"        => token::Underscore,
+            "MINUS"             => token::BinOp(token::Minus),
+            "SEMI"              => token::Semi,
+            "COLON"             => token::Colon,
+            "FAT_ARROW"         => token::FatArrow,
+            "OR"                => token::BinOp(token::Or),
+            "GT"                => token::Gt,
+            "LE"                => token::Le,
+            "LIT_BINARY"        => token::LitBinary(Name(0)),
+            "LIT_BINARY_RAW"    => token::LitBinaryRaw(Name(0), 0),
+            _                   => continue,
         };
 
         res.insert(num.to_string(), tok);
@@ -119,19 +119,19 @@ fn id() -> Token {
     res
 }
 
-fn str_to_binop(s: &str) -> BinOp {
+fn str_to_binop(s: &str) -> BinOpToken {
     match s {
-        "+" => PLUS,
-        "/" => SLASH,
-        "-" => MINUS,
-        "*" => STAR,
-        "%" => PERCENT,
-        "^" => CARET,
-        "&" => AND,
-        "|" => OR,
-        "<<" => SHL,
-        ">>" => SHR,
-        _ => fail!("Bad binop str `{}`", s)
+        "+"     => token::Plus,
+        "/"     => token::Slash,
+        "-"     => token::Minus,
+        "*"     => token::Star,
+        "%"     => token::Percent,
+        "^"     => token::Caret,
+        "&"     => token::And,
+        "|"     => token::Or,
+        "<<"    => token::Shl,
+        ">>"    => token::Shr,
+        _       => panic!("Bad binop str `{}`", s),
     }
 }
 
@@ -186,19 +186,21 @@ fn parse_antlr_token(s: &str, tokens: &HashMap<String, Token>) -> TokenAndSpan {
     debug!("What we got: content (`{}`), proto: {}", content, proto_tok);
 
     let real_tok = match *proto_tok {
-        BINOP(..) => BINOP(str_to_binop(content)),
-        BINOPEQ(..) => BINOPEQ(str_to_binop(content.slice_to(content.len() - 1))),
-        LIT_STR(..) => LIT_STR(fix(content)),
-        LIT_STR_RAW(..) => LIT_STR_RAW(fix(content), count(content)),
-        LIT_CHAR(..) => LIT_CHAR(fixchar(content)),
-        LIT_BYTE(..) => LIT_BYTE(fixchar(content)),
-        DOC_COMMENT(..) => DOC_COMMENT(nm),
-        LIT_INTEGER(..) => LIT_INTEGER(nm),
-        LIT_FLOAT(..) => LIT_FLOAT(nm),
-        LIT_BINARY(..) => LIT_BINARY(nm),
-        LIT_BINARY_RAW(..) => LIT_BINARY_RAW(fix(content), count(content)),
-        IDENT(..) => IDENT(ast::Ident { name: nm, ctxt: 0 }, true),
-        LIFETIME(..) => LIFETIME(ast::Ident { name: nm, ctxt: 0 }),
+        token::BinOp(..)           => token::BinOp(str_to_binop(content)),
+        token::BinOpEq(..)         => token::BinOpEq(str_to_binop(content.slice_to(
+                                                                    content.len() - 1))),
+        token::LitStr(..)          => token::LitStr(fix(content)),
+        token::LitStrRaw(..)       => token::LitStrRaw(fix(content), count(content)),
+        token::LitChar(..)         => token::LitChar(fixchar(content)),
+        token::LitByte(..)         => token::LitByte(fixchar(content)),
+        token::DocComment(..)      => token::DocComment(nm),
+        token::LitInteger(..)      => token::LitInteger(nm),
+        token::LitFloat(..)        => token::LitFloat(nm),
+        token::LitBinary(..)       => token::LitBinary(nm),
+        token::LitBinaryRaw(..)    => token::LitBinaryRaw(fix(content), count(content)),
+        token::Ident(..)           => token::Ident(ast::Ident { name: nm, ctxt: 0 },
+                                                   token::ModName),
+        token::Lifetime(..)        => token::Lifetime(ast::Ident { name: nm, ctxt: 0 }),
         ref t => t.clone()
     };
 
@@ -222,8 +224,8 @@ fn parse_antlr_token(s: &str, tokens: &HashMap<String, Token>) -> TokenAndSpan {
 
 fn tok_cmp(a: &Token, b: &Token) -> bool {
     match a {
-        &IDENT(id, _) => match b {
-                &IDENT(id2, _) => id == id2,
+        &token::Ident(id, _) => match b {
+                &token::Ident(id2, _) => id == id2,
                 _ => false
         },
         _ => a == b
@@ -274,26 +276,27 @@ macro_rules! matches (
                                 warn!("Different names for {} and {}", rustc_tok, antlr_tok);
                             }
                         }
-                        _ => fail!("{} is not {}", antlr_tok, rustc_tok)
+                        _ => panic!("{} is not {}", antlr_tok, rustc_tok)
                     },)*
                     ref c => assert!(c == &antlr_tok.tok, "{} is not {}", rustc_tok, antlr_tok)
                 }
             )
         )
 
-        matches!(LIT_BYTE(..),
-            LIT_CHAR(..),
-            LIT_INTEGER(..),
-            LIT_FLOAT(..),
-            LIT_STR(..),
-            LIT_STR_RAW(..),
-            LIT_BINARY(..),
-            LIT_BINARY_RAW(..),
-            IDENT(..),
-            LIFETIME(..),
-            INTERPOLATED(..),
-            DOC_COMMENT(..),
-            SHEBANG(..)
+        matches!(
+            LitByte(..),
+            LitChar(..),
+            LitInteger(..),
+            LitFloat(..),
+            LitStr(..),
+            LitStrRaw(..),
+            LitBinary(..),
+            LitBinaryRaw(..),
+            Ident(..),
+            Lifetime(..),
+            Interpolated(..),
+            DocComment(..),
+            Shebang(..)
         );
     }
 }
index c447cb46c532a81c07b76849d4386f01b70d4620..f543826fe01878a2ff58ab70dfccb4a20523bc4b 100644 (file)
 
 use core::atomic;
 use core::clone::Clone;
+use core::fmt::{mod, Show};
+use core::cmp::{Eq, Ord, PartialEq, PartialOrd, Ordering};
+use core::default::Default;
 use core::kinds::{Sync, Send};
 use core::mem::{min_align_of, size_of, drop};
 use core::mem;
 use core::ops::{Drop, Deref};
 use core::option::{Some, None, Option};
-use core::ptr;
 use core::ptr::RawPtr;
+use core::ptr;
 use heap::deallocate;
 
 /// An atomically reference counted wrapper for shared state.
@@ -91,16 +94,6 @@ pub fn new(data: T) -> Arc<T> {
         Arc { _ptr: unsafe { mem::transmute(x) } }
     }
 
-    #[inline]
-    fn inner(&self) -> &ArcInner<T> {
-        // This unsafety is ok because while this arc is alive we're guaranteed
-        // that the inner pointer is valid. Furthermore, we know that the
-        // `ArcInner` structure itself is `Sync` because the inner data is
-        // `Sync` as well, so we're ok loaning out an immutable pointer to
-        // these contents.
-        unsafe { &*self._ptr }
-    }
-
     /// Downgrades a strong pointer to a weak pointer.
     ///
     /// Weak pointers will not keep the data alive. Once all strong references
@@ -114,8 +107,20 @@ pub fn downgrade(&self) -> Weak<T> {
     }
 }
 
+impl<T> Arc<T> {
+    #[inline]
+    fn inner(&self) -> &ArcInner<T> {
+        // This unsafety is ok because while this arc is alive we're guaranteed
+        // that the inner pointer is valid. Furthermore, we know that the
+        // `ArcInner` structure itself is `Sync` because the inner data is
+        // `Sync` as well, so we're ok loaning out an immutable pointer to
+        // these contents.
+        unsafe { &*self._ptr }
+    }
+}
+
 #[unstable = "waiting on stability of Clone"]
-impl<T: Sync + Send> Clone for Arc<T> {
+impl<T> Clone for Arc<T> {
     /// Duplicate an atomically reference counted wrapper.
     ///
     /// The resulting two `Arc` objects will point to the same underlying data
@@ -140,7 +145,7 @@ fn clone(&self) -> Arc<T> {
 }
 
 #[experimental = "Deref is experimental."]
-impl<T: Send + Sync> Deref<T> for Arc<T> {
+impl<T> Deref<T> for Arc<T> {
     #[inline]
     fn deref(&self) -> &T {
         &self.inner().data
@@ -222,9 +227,9 @@ fn drop(&mut self) {
 impl<T: Sync + Send> Weak<T> {
     /// Attempts to upgrade this weak reference to a strong reference.
     ///
-    /// This method will fail to upgrade this reference if the strong reference
-    /// count has already reached 0, but if there are still other active strong
-    /// references this function will return a new strong reference to the data.
+    /// This method will not upgrade this reference if the strong reference count has already
+    /// reached 0, but if there are still other active strong references this function will return
+    /// a new strong reference to the data.
     pub fn upgrade(&self) -> Option<Arc<T>> {
         // We use a CAS loop to increment the strong count instead of a
         // fetch_add because once the count hits 0 is must never be above 0.
@@ -272,6 +277,38 @@ fn drop(&mut self) {
     }
 }
 
+#[unstable = "waiting on PartialEq"]
+impl<T: PartialEq> PartialEq for Arc<T> {
+    fn eq(&self, other: &Arc<T>) -> bool { *(*self) == *(*other) }
+    fn ne(&self, other: &Arc<T>) -> bool { *(*self) != *(*other) }
+}
+#[unstable = "waiting on PartialOrd"]
+impl<T: PartialOrd> PartialOrd for Arc<T> {
+    fn partial_cmp(&self, other: &Arc<T>) -> Option<Ordering> {
+        (**self).partial_cmp(&**other)
+    }
+    fn lt(&self, other: &Arc<T>) -> bool { *(*self) < *(*other) }
+    fn le(&self, other: &Arc<T>) -> bool { *(*self) <= *(*other) }
+    fn ge(&self, other: &Arc<T>) -> bool { *(*self) >= *(*other) }
+    fn gt(&self, other: &Arc<T>) -> bool { *(*self) > *(*other) }
+}
+#[unstable = "waiting on Ord"]
+impl<T: Ord> Ord for Arc<T> {
+    fn cmp(&self, other: &Arc<T>) -> Ordering { (**self).cmp(&**other) }
+}
+#[unstable = "waiting on Eq"]
+impl<T: Eq> Eq for Arc<T> {}
+
+impl<T: fmt::Show> fmt::Show for Arc<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        (**self).fmt(f)
+    }
+}
+
+impl<T: Default + Sync + Send> Default for Arc<T> {
+    fn default() -> Arc<T> { Arc::new(Default::default()) }
+}
+
 #[cfg(test)]
 #[allow(experimental)]
 mod tests {
@@ -280,6 +317,7 @@ mod tests {
     use std::mem::drop;
     use std::ops::Drop;
     use std::option::{Option, Some, None};
+    use std::str::Str;
     use std::sync::atomic;
     use std::task;
     use std::vec::Vec;
@@ -426,4 +464,14 @@ fn drop_arc_weak() {
         assert!(canary.load(atomic::Acquire) == 1);
         drop(arc_weak);
     }
+
+    #[test]
+    fn show_arc() {
+        let a = Arc::new(5u32);
+        assert!(format!("{}", a).as_slice() == "5")
+    }
+
+    // Make sure deriving works with Arc<T>
+    #[deriving(Eq, Ord, PartialEq, PartialOrd, Clone, Show, Default)]
+    struct Foo { inner: Arc<int> }
 }
index 168d0daeb3845d915a2fb734c6bcca442a768fa2..09404af70273381330b2701b4b16531744f775f5 100644 (file)
@@ -148,11 +148,11 @@ fn any_move() {
 
         match a.downcast::<uint>() {
             Ok(a) => { assert!(a == box 8u); }
-            Err(..) => fail!()
+            Err(..) => panic!()
         }
         match b.downcast::<Test>() {
             Ok(a) => { assert!(a == box Test); }
-            Err(..) => fail!()
+            Err(..) => panic!()
         }
 
         let a = box 8u as Box<Any>;
index 5682bb76d55605ffe7a8bf12b3fda4a81d79abaf..1528c313b738e804ff4b012ab8351be473e4b114 100644 (file)
@@ -69,7 +69,7 @@ unsafe fn as_ptr(&self) -> *const u8 {
 /// element). When the arena is destroyed, it iterates through all of its
 /// chunks, and uses the tydesc information to trace through the objects,
 /// calling the destructors on them. One subtle point that needs to be
-/// addressed is how to handle failures while running the user provided
+/// addressed is how to handle panics while running the user provided
 /// initializer function. It is important to not run the destructor on
 /// uninitialized objects, but how to detect them is somewhat subtle. Since
 /// `alloc()` can be invoked recursively, it is not sufficient to simply exclude
@@ -162,7 +162,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
 
 // We encode whether the object a tydesc describes has been
 // initialized in the arena in the low bit of the tydesc pointer. This
-// is necessary in order to properly do cleanup if a failure occurs
+// is necessary in order to properly do cleanup if a panic occurs
 // during an initializer.
 #[inline]
 fn bitpack_tydesc_ptr(p: *const TyDesc, is_done: bool) -> uint {
@@ -337,10 +337,9 @@ fn test_arena_destructors_fail() {
         // things interesting.
         arena.alloc(|| { [0u8, 1u8, 2u8] });
     }
-    // Now, fail while allocating
+    // Now, panic while allocating
     arena.alloc::<Rc<int>>(|| {
-        // Now fail.
-        fail!();
+        panic!();
     });
 }
 
index dbbff61b8dd50c139154eb800a05892f7a6843d3..77fb6d4a1203b360fa4e624cb382168fed73f62f 100644 (file)
 /// the BST strategy.
 ///
 /// A B-Tree instead makes each node contain B-1 to 2B-1 elements in a contiguous array. By doing
-/// this, we reduce the number of allocations by a factor of B, and improve cache effeciency in
+/// this, we reduce the number of allocations by a factor of B, and improve cache efficiency in
 /// searches. However, this does mean that searches will have to do *more* comparisons on average.
 /// The precise number of comparisons depends on the node search strategy used. For optimal cache
-/// effeciency, one could search the nodes linearly. For optimal comparisons, one could search
+/// efficiency, one could search the nodes linearly. For optimal comparisons, one could search
 /// the node using binary search. As a compromise, one could also perform a linear search
 /// that initially only checks every i<sup>th</sup> element for some choice of i.
 ///
index e30b29f8767d3aa26d7857de2f8a187ab83875c3..6b491096e7da47c9d74805030aba2db07d6ef004 100644 (file)
@@ -53,7 +53,7 @@ pub struct Node<K, V> {
     // hard. For now, we accept this cost in the name of correctness and simplicity.
     //
     // As a compromise, keys and vals could be merged into one Vec<(K, V)>, which would shave
-    // off 3 words, but possibly hurt our cache effeciency during search, which only cares about
+    // off 3 words, but possibly hurt our cache efficiency during search, which only cares about
     // keys. This would also avoid the Zip we use in our iterator implementations. This is
     // probably worth investigating.
     //
@@ -68,11 +68,11 @@ pub struct Node<K, V> {
 
 impl<K: Ord, V> Node<K, V> {
     /// Searches for the given key in the node. If it finds an exact match,
-    /// `Found` will be yielded with the matching index. If it fails to find an exact match,
+    /// `Found` will be yielded with the matching index. If it doesn't find an exact match,
     /// `GoDown` will be yielded with the index of the subtree the key must lie in.
     pub fn search(&self, key: &K) -> SearchResult {
         // FIXME(Gankro): Tune when to search linear or binary based on B (and maybe K/V).
-        // For the B configured as of this writing (B = 6), binary search was *singnificantly*
+        // For the B configured as of this writing (B = 6), binary search was *significantly*
         // worse for uints.
         self.search_linear(key)
     }
@@ -375,7 +375,7 @@ unsafe fn handle_underflow_to_right(&mut self, underflowed_child_index: uint) {
         }
     }
 
-    /// Steal! Stealing is roughly analagous to a binary tree rotation.
+    /// Steal! Stealing is roughly analogous to a binary tree rotation.
     /// In this case, we're "rotating" right.
     unsafe fn steal_to_left(&mut self, underflowed_child_index: uint) {
         // Take the biggest stuff off left
@@ -387,7 +387,7 @@ unsafe fn steal_to_left(&mut self, underflowed_child_index: uint) {
             }
         };
 
-        // Swap the parent's seperating key-value pair with left's
+        // Swap the parent's separating key-value pair with left's
         self.unsafe_swap(underflowed_child_index - 1, &mut key, &mut val);
 
         // Put them at the start of right
@@ -402,7 +402,7 @@ unsafe fn steal_to_left(&mut self, underflowed_child_index: uint) {
         }
     }
 
-    /// Steal! Stealing is roughly analagous to a binary tree rotation.
+    /// Steal! Stealing is roughly analogous to a binary tree rotation.
     /// In this case, we're "rotating" left.
     unsafe fn steal_to_right(&mut self, underflowed_child_index: uint) {
         // Take the smallest stuff off right
@@ -414,7 +414,7 @@ unsafe fn steal_to_right(&mut self, underflowed_child_index: uint) {
             }
         };
 
-        // Swap the parent's seperating key-value pair with right's
+        // Swap the parent's separating key-value pair with right's
         self.unsafe_swap(underflowed_child_index, &mut key, &mut val);
 
         // Put them at the end of left
@@ -430,9 +430,9 @@ unsafe fn steal_to_right(&mut self, underflowed_child_index: uint) {
     }
 
     /// Merge! Left and right will be smooshed into one node, along with the key-value
-    /// pair that seperated them in their parent.
+    /// pair that separated them in their parent.
     unsafe fn merge_children(&mut self, left_index: uint) {
-        // Permanently remove right's index, and the key-value pair that seperates
+        // Permanently remove right's index, and the key-value pair that separates
         // left and right
         let (key, val, right) = {
             match (self.keys.remove(left_index),
@@ -448,7 +448,7 @@ unsafe fn merge_children(&mut self, left_index: uint) {
         left.absorb(key, val, right);
     }
 
-    /// Take all the values from right, seperated by the given key and value
+    /// Take all the values from right, separated by the given key and value
     fn absorb(&mut self, key: K, val: V, right: Node<K, V>) {
         // Just as a sanity check, make sure we can fit this guy in
         debug_assert!(self.len() + right.len() <= self.capacity())
index e751084addd77d72323b52a9c857ec20d934be15..22d487bd3a0dbf36c15204578915395b234acab0 100644 (file)
@@ -760,11 +760,11 @@ pub fn check_links<T>(list: &DList<T>) {
         loop {
             match (last_ptr, node_ptr.prev.resolve_immut()) {
                 (None   , None      ) => {}
-                (None   , _         ) => fail!("prev link for list_head"),
+                (None   , _         ) => panic!("prev link for list_head"),
                 (Some(p), Some(pptr)) => {
                     assert_eq!(p as *const Node<T>, pptr as *const Node<T>);
                 }
-                _ => fail!("prev link is none, not good"),
+                _ => panic!("prev link is none, not good"),
             }
             match node_ptr.next {
                 Some(ref next) => {
index e1806dae31dbe56b7595111a23cf6cea39a32a6e..20ad5b6334f323cf2ff39619bc4b33f4e19b6309 100644 (file)
@@ -527,8 +527,8 @@ pub fn fixme_14344_be_sure_to_link_to_collections() {}
 
 #[cfg(not(test))]
 mod std {
-    pub use core::fmt;      // necessary for fail!()
-    pub use core::option;   // necessary for fail!()
+    pub use core::fmt;      // necessary for panic!()
+    pub use core::option;   // necessary for panic!()
     pub use core::clone;    // deriving(Clone)
     pub use core::cmp;      // deriving(Eq, Ord, etc.)
     pub use hash;           // deriving(Hash)
index e32e8145d172e2087edb08907062510b275da049..5f05ab7a9069394916c31ed5f669cf59bbe323d5 100644 (file)
@@ -152,7 +152,7 @@ pub fn with_capacity(n: uint) -> RingBuf<T> {
     pub fn get_mut<'a>(&'a mut self, i: uint) -> &'a mut T {
         let idx = self.raw_index(i);
         match *self.elts.get_mut(idx) {
-            None => fail!(),
+            None => panic!(),
             Some(ref mut v) => v
         }
     }
@@ -460,7 +460,7 @@ impl<A> Index<uint, A> for RingBuf<A> {
     fn index<'a>(&'a self, i: &uint) -> &'a A {
         let idx = self.raw_index(*i);
         match self.elts[idx] {
-            None => fail!(),
+            None => panic!(),
             Some(ref v) => v,
         }
     }
index d061e60a42265d95f97e298a2c34f377225a8897..3f60a6d633097bf6bf7bfce73057e23825c42a42 100644 (file)
@@ -89,6 +89,7 @@
 
 use alloc::boxed::Box;
 use core::cmp;
+use core::kinds::Sized;
 use core::mem::size_of;
 use core::mem;
 use core::prelude::{Clone, Collection, Greater, Iterator, Less, None, Option};
 // Functional utilities
 
 #[allow(missing_doc)]
-pub trait VectorVector<T> {
+pub trait VectorVector<T> for Sized? {
     // FIXME #5898: calling these .concat and .connect conflicts with
     // StrVector::con{cat,nect}, since they have generic contents.
     /// Flattens a vector of vectors of `T` into a single `Vec<T>`.
@@ -119,7 +120,7 @@ pub trait VectorVector<T> {
     fn connect_vec(&self, sep: &T) -> Vec<T>;
 }
 
-impl<'a, T: Clone, V: AsSlice<T>> VectorVector<T> for &'a [V] {
+impl<T: Clone, V: AsSlice<T>> VectorVector<T> for [V] {
     fn concat_vec(&self) -> Vec<T> {
         let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
         let mut result = Vec::with_capacity(size);
@@ -267,17 +268,17 @@ fn size_hint(&self) -> (uint, Option<uint>) {
 }
 
 /// Extension methods for vector slices with cloneable elements
-pub trait CloneableVector<T> {
+pub trait CloneableVector<T> for Sized? {
     /// Copies `self` into a new `Vec`.
     fn to_vec(&self) -> Vec<T>;
 }
 
-impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
+impl<T: Clone> CloneableVector<T> for [T] {
     /// Returns a copy of `v`.
     #[inline]
     fn to_vec(&self) -> Vec<T> {
         let mut vector = Vec::with_capacity(self.len());
-        vector.push_all(*self);
+        vector.push_all(self);
         vector
     }
 }
@@ -292,7 +293,7 @@ impl<T> BoxedSlice<T> for Box<[T]> {
     #[experimental]
     fn into_vec(mut self) -> Vec<T> {
         unsafe {
-            let xs = Vec::from_raw_parts(self.len(), self.len(), self.as_mut_ptr());
+            let xs = Vec::from_raw_parts(self.as_mut_ptr(), self.len(), self.len());
             mem::forget(self);
             xs
         }
@@ -300,7 +301,7 @@ fn into_vec(mut self) -> Vec<T> {
 }
 
 /// Extension methods for vectors containing `Clone` elements.
-pub trait ImmutableCloneableVector<T> {
+pub trait ImmutableCloneableVector<T> for Sized? {
     /// Partitions the vector into two vectors `(a, b)`, where all
     /// elements of `a` satisfy `f` and all elements of `b` do not.
     fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>);
@@ -329,10 +330,10 @@ pub trait ImmutableCloneableVector<T> {
     /// assert_eq!(Some(vec![1i, 3, 2]), perms.next());
     /// assert_eq!(Some(vec![3i, 1, 2]), perms.next());
     /// ```
-    fn permutations(self) -> Permutations<T>;
+    fn permutations(&self) -> Permutations<T>;
 }
 
-impl<'a,T:Clone> ImmutableCloneableVector<T> for &'a [T] {
+impl<T: Clone> ImmutableCloneableVector<T> for [T] {
     #[inline]
     fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
         let mut lefts  = Vec::new();
@@ -350,7 +351,7 @@ fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
     }
 
     /// Returns an iterator over all permutations of a vector.
-    fn permutations(self) -> Permutations<T> {
+    fn permutations(&self) -> Permutations<T> {
         Permutations{
             swaps: ElementSwaps::new(self.len()),
             v: self.to_vec(),
@@ -564,7 +565,7 @@ unsafe fn step<T>(ptr: &mut *mut T) -> *mut T {
 
 /// Extension methods for vectors such that their elements are
 /// mutable.
-pub trait MutableSliceAllocating<'a, T> {
+pub trait MutableSliceAllocating<T> for Sized? {
     /// Sorts the slice, in place, using `compare` to compare
     /// elements.
     ///
@@ -582,7 +583,7 @@ pub trait MutableSliceAllocating<'a, T> {
     /// v.sort_by(|a, b| b.cmp(a));
     /// assert!(v == [5, 4, 3, 2, 1]);
     /// ```
-    fn sort_by(self, compare: |&T, &T| -> Ordering);
+    fn sort_by(&mut self, compare: |&T, &T| -> Ordering);
 
     /// Consumes `src` and moves as many elements as it can into `self`
     /// from the range [start,end).
@@ -605,17 +606,17 @@ pub trait MutableSliceAllocating<'a, T> {
     /// assert_eq!(num_moved, 3);
     /// assert!(a == [6i, 7, 8, 4, 5]);
     /// ```
-    fn move_from(self, src: Vec<T>, start: uint, end: uint) -> uint;
+    fn move_from(&mut self, src: Vec<T>, start: uint, end: uint) -> uint;
 }
 
-impl<'a,T> MutableSliceAllocating<'a, T> for &'a mut [T] {
+impl<T> MutableSliceAllocating<T> for [T] {
     #[inline]
-    fn sort_by(self, compare: |&T, &T| -> Ordering) {
+    fn sort_by(&mut self, compare: |&T, &T| -> Ordering) {
         merge_sort(self, compare)
     }
 
     #[inline]
-    fn move_from(self, mut src: Vec<T>, start: uint, end: uint) -> uint {
+    fn move_from(&mut self, mut src: Vec<T>, start: uint, end: uint) -> uint {
         for (a, b) in self.iter_mut().zip(src[mut start..end].iter_mut()) {
             mem::swap(a, b);
         }
@@ -625,7 +626,7 @@ fn move_from(self, mut src: Vec<T>, start: uint, end: uint) -> uint {
 
 /// Methods for mutable vectors with orderable elements, such as
 /// in-place sorting.
-pub trait MutableOrdSlice<T> {
+pub trait MutableOrdSlice<T> for Sized? {
     /// Sorts the slice, in place.
     ///
     /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`.
@@ -638,7 +639,7 @@ pub trait MutableOrdSlice<T> {
     /// v.sort();
     /// assert!(v == [-5i, -3, 1, 2, 4]);
     /// ```
-    fn sort(self);
+    fn sort(&mut self);
 
     /// Mutates the slice to the next lexicographic permutation.
     ///
@@ -656,7 +657,7 @@ pub trait MutableOrdSlice<T> {
     /// let b: &mut [_] = &mut [1i, 0, 2];
     /// assert!(v == b);
     /// ```
-    fn next_permutation(self) -> bool;
+    fn next_permutation(&mut self) -> bool;
 
     /// Mutates the slice to the previous lexicographic permutation.
     ///
@@ -674,16 +675,16 @@ pub trait MutableOrdSlice<T> {
     /// let b: &mut [_] = &mut [0i, 1, 2];
     /// assert!(v == b);
     /// ```
-    fn prev_permutation(self) -> bool;
+    fn prev_permutation(&mut self) -> bool;
 }
 
-impl<'a, T: Ord> MutableOrdSlice<T> for &'a mut [T] {
+impl<T: Ord> MutableOrdSlice<T> for [T] {
     #[inline]
-    fn sort(self) {
-        self.sort_by(|a,b| a.cmp(b))
+    fn sort(&mut self) {
+        self.sort_by(|a, b| a.cmp(b))
     }
 
-    fn next_permutation(self) -> bool {
+    fn next_permutation(&mut self) -> bool {
         // These cases only have 1 permutation each, so we can't do anything.
         if self.len() < 2 { return false; }
 
@@ -713,7 +714,7 @@ fn next_permutation(self) -> bool {
         true
     }
 
-    fn prev_permutation(self) -> bool {
+    fn prev_permutation(&mut self) -> bool {
         // These cases only have 1 permutation each, so we can't do anything.
         if self.len() < 2 { return false; }
 
@@ -1180,7 +1181,7 @@ fn test_element_swaps() {
                 3 => assert!(v == [2, 3, 1]),
                 4 => assert!(v == [2, 1, 3]),
                 5 => assert!(v == [1, 2, 3]),
-                _ => fail!(),
+                _ => panic!(),
             }
         }
     }
@@ -1390,7 +1391,7 @@ fn test_sort() {
             }
         }
 
-        // shouldn't fail/crash
+        // shouldn't panic
         let mut v: [uint, .. 0] = [];
         v.sort();
 
@@ -1544,7 +1545,7 @@ fn test_slice_2() {
     #[should_fail]
     fn test_from_fn_fail() {
         Vec::from_fn(100, |v| {
-            if v == 50 { fail!() }
+            if v == 50 { panic!() }
             box 0i
         });
     }
@@ -1561,7 +1562,7 @@ struct S {
         impl Clone for S {
             fn clone(&self) -> S {
                 self.f.set(self.f.get() + 1);
-                if self.f.get() == 10 { fail!() }
+                if self.f.get() == 10 { panic!() }
                 S { f: self.f, boxes: self.boxes.clone() }
             }
         }
@@ -1576,7 +1577,7 @@ fn test_grow_fn_fail() {
         let mut v = vec![];
         v.grow_fn(100, |i| {
             if i == 50 {
-                fail!()
+                panic!()
             }
             (box 0i, Rc::new(0i))
         })
@@ -1590,7 +1591,7 @@ fn test_permute_fail() {
         let mut i = 0u;
         for _ in v.permutations() {
             if i == 2 {
-                fail!()
+                panic!()
             }
             i += 1;
         }
@@ -2188,7 +2189,7 @@ fn iterator(b: &mut Bencher) {
                 sum += *x;
             }
             // sum == 11806, to stop dead code elimination.
-            if sum == 0 {fail!()}
+            if sum == 0 {panic!()}
         })
     }
 
index 498f86a8bf1e41e493c9679ec9d6c42f314c1579..3b509f37c47053b85531d75a22703c6e4bb09bf2 100644 (file)
@@ -511,7 +511,7 @@ fn test_find_mut() {
         assert!(m.insert(5, 14));
         let new = 100;
         match m.find_mut(&5) {
-            None => fail!(), Some(x) => *x = new
+            None => panic!(), Some(x) => *x = new
         }
         assert_eq!(m.find(&5), Some(&new));
     }
index 901f8add73c1aee5acb6cbe06e2bc370528b3e7e..5dd3be4ec8fd4daff1ac9d1f80b790efdf5e9553 100644 (file)
@@ -58,6 +58,7 @@
 use core::fmt;
 use core::cmp;
 use core::iter::AdditiveIterator;
+use core::kinds::Sized;
 use core::prelude::{Char, Clone, Collection, Eq, Equiv, ImmutableSlice};
 use core::prelude::{Iterator, MutableSlice, None, Option, Ord, Ordering};
 use core::prelude::{PartialEq, PartialOrd, Result, AsSlice, Some, Tuple2};
@@ -84,7 +85,7 @@
 */
 
 /// Methods for vectors of strings.
-pub trait StrVector {
+pub trait StrVector for Sized? {
     /// Concatenates a vector of strings.
     ///
     /// # Example
@@ -110,7 +111,7 @@ pub trait StrVector {
     fn connect(&self, sep: &str) -> String;
 }
 
-impl<'a, S: Str> StrVector for &'a [S] {
+impl<S: Str> StrVector for [S] {
     fn concat(&self) -> String {
         if self.is_empty() {
             return String::new();
@@ -157,7 +158,7 @@ fn connect(&self, sep: &str) -> String {
     }
 }
 
-impl<'a, S: Str> StrVector for Vec<S> {
+impl<S: Str> StrVector for Vec<S> {
     #[inline]
     fn concat(&self) -> String {
         self.as_slice().concat()
@@ -1366,7 +1367,7 @@ fn test_as_bytes_fail() {
         // original problem code path anymore.)
         let s = String::from_str("");
         let _bytes = s.as_bytes();
-        fail!();
+        panic!();
     }
 
     #[test]
@@ -1585,7 +1586,7 @@ fn test_chars_decoding() {
             let len = c.encode_utf8(bytes).unwrap_or(0);
             let s = ::core::str::from_utf8(bytes[..len]).unwrap();
             if Some(c) != s.chars().next() {
-                fail!("character {:x}={} does not decode correctly", c as u32, c);
+                panic!("character {:x}={} does not decode correctly", c as u32, c);
             }
         }
     }
@@ -1597,7 +1598,7 @@ fn test_chars_rev_decoding() {
             let len = c.encode_utf8(bytes).unwrap_or(0);
             let s = ::core::str::from_utf8(bytes[..len]).unwrap();
             if Some(c) != s.chars().rev().next() {
-                fail!("character {:x}={} does not decode correctly", c as u32, c);
+                panic!("character {:x}={} does not decode correctly", c as u32, c);
             }
         }
     }
index fa45dee7cdea7c2756b692add3cf3ef9d5d59ec9..b61f26688a2ee3cb78fba64e7a5d00e675d53b0a 100644 (file)
@@ -504,7 +504,7 @@ pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
     /// assert_eq!(s.as_slice(), "he");
     /// ```
     #[inline]
-    #[unstable = "the failure conventions for strings are under development"]
+    #[unstable = "the panic conventions for strings are under development"]
     pub fn truncate(&mut self, new_len: uint) {
         assert!(self.as_slice().is_char_boundary(new_len));
         self.vec.truncate(new_len)
@@ -545,10 +545,10 @@ pub fn pop(&mut self) -> Option<char> {
     /// This is a O(n) operation as it requires copying every element in the
     /// buffer.
     ///
-    /// # Failure
+    /// # Panics
     ///
     /// If `idx` does not lie on a character boundary, then this function will
-    /// fail.
+    /// panic.
     ///
     /// # Example
     ///
@@ -559,7 +559,7 @@ pub fn pop(&mut self) -> Option<char> {
     /// assert_eq!(s.remove(0), Some('o'));
     /// assert_eq!(s.remove(0), None);
     /// ```
-    #[unstable = "the failure semantics of this function and return type \
+    #[unstable = "the panic semantics of this function and return type \
                   may change"]
     pub fn remove(&mut self, idx: uint) -> Option<char> {
         let len = self.len();
@@ -582,11 +582,11 @@ pub fn remove(&mut self, idx: uint) -> Option<char> {
     /// This is a O(n) operation as it requires copying every element in the
     /// buffer.
     ///
-    /// # Failure
+    /// # Panics
     ///
     /// If `idx` does not lie on a character boundary or is out of bounds, then
-    /// this function will fail.
-    #[unstable = "the failure semantics of this function are uncertain"]
+    /// this function will panic.
+    #[unstable = "the panic semantics of this function are uncertain"]
     pub fn insert(&mut self, idx: uint, ch: char) {
         let len = self.len();
         assert!(idx <= len);
@@ -780,7 +780,7 @@ pub mod raw {
     #[inline]
     pub unsafe fn from_parts(buf: *mut u8, length: uint, capacity: uint) -> String {
         String {
-            vec: Vec::from_raw_parts(length, capacity, buf),
+            vec: Vec::from_raw_parts(buf, length, capacity),
         }
     }
 
index ee01cd343c3ae52e3b66524a46b272c3a7e98427..feb4c11a061a576be42e63e9d4b4ee6441b6c0b1 100644 (file)
@@ -490,7 +490,7 @@ pub fn find_with<'a>(&'a self, f:|&K| -> Ordering) -> Option<&'a V> {
     /// let new_ua = "Safari/156.0";
     /// match t.find_with_mut(|k| "User-Agent".cmp(k)) {
     ///    Some(x) => *x = new_ua,
-    ///    None => fail!(),
+    ///    None => panic!(),
     /// }
     ///
     /// assert_eq!(t.find(&"User-Agent"), Some(&new_ua));
@@ -1616,7 +1616,7 @@ fn heir_swap<K: Ord, V>(node: &mut Box<TreeNode<K, V>>,
       }
     }
     return match node.take() {
-        Some(box TreeNode{value, ..}) => Some(value), None => fail!()
+        Some(box TreeNode{value, ..}) => Some(value), None => panic!()
     };
 }
 
@@ -1726,7 +1726,7 @@ fn test_find_mut() {
         assert!(m.insert(5, 14));
         let new = 100;
         match m.find_mut(&5) {
-          None => fail!(), Some(x) => *x = new
+          None => panic!(), Some(x) => *x = new
         }
         assert_eq!(m.find(&5), Some(&new));
     }
@@ -1739,7 +1739,7 @@ fn test_find_with_mut() {
         assert!(m.insert("t5", 14));
         let new = 100;
         match m.find_with_mut(|k| "t5".cmp(k)) {
-          None => fail!(), Some(x) => *x = new
+          None => panic!(), Some(x) => *x = new
         }
         assert_eq!(m.find_with(|k| "t5".cmp(k)), Some(&new));
     }
index 1b5c5dbc0a20bab1cc080dd369a8fabbcb4d2361..d02190e08247e0ca1c2deafd2e68e4f9d28c1102 100644 (file)
@@ -834,7 +834,7 @@ fn insert<T>(count: &mut uint, child: &mut Child<T>, key: uint, value: T,
             *child = Internal(new);
             return ret;
         }
-        _ => fail!("unreachable code"),
+        _ => panic!("unreachable code"),
     }
 }
 
@@ -844,7 +844,7 @@ fn remove<T>(count: &mut uint, child: &mut Child<T>, key: uint,
       External(stored, _) if stored == key => {
         match mem::replace(child, Nothing) {
             External(_, value) => (Some(value), true),
-            _ => fail!()
+            _ => panic!()
         }
       }
       External(..) => (None, false),
@@ -1057,7 +1057,7 @@ fn test_find_mut() {
         assert!(m.insert(5u, 14i));
         let new = 100;
         match m.find_mut(&5) {
-            None => fail!(), Some(x) => *x = new
+            None => panic!(), Some(x) => *x = new
         }
         assert_eq!(m.find(&5), Some(&new));
     }
index e608a7d22dcf5e8a8fe33bf3fbf969974157ae93..759f9ec7d3f0361780f7edb0eb5c08f5327f5a12 100644 (file)
 #[unsafe_no_drop_flag]
 #[stable]
 pub struct Vec<T> {
+    ptr: *mut T,
     len: uint,
     cap: uint,
-    ptr: *mut T
 }
 
 impl<T> Vec<T> {
@@ -125,7 +125,7 @@ pub fn new() -> Vec<T> {
         // non-null value which is fine since we never call deallocate on the ptr
         // if cap is 0. The reason for this is because the pointer of a slice
         // being NULL would break the null pointer optimization for enums.
-        Vec { len: 0, cap: 0, ptr: EMPTY as *mut T }
+        Vec { ptr: EMPTY as *mut T, len: 0, cap: 0 }
     }
 
     /// Constructs a new, empty `Vec` with the specified capacity.
@@ -159,14 +159,14 @@ pub fn new() -> Vec<T> {
     #[stable]
     pub fn with_capacity(capacity: uint) -> Vec<T> {
         if mem::size_of::<T>() == 0 {
-            Vec { len: 0, cap: uint::MAX, ptr: EMPTY as *mut T }
+            Vec { ptr: EMPTY as *mut T, len: 0, cap: uint::MAX }
         } else if capacity == 0 {
             Vec::new()
         } else {
             let size = capacity.checked_mul(&mem::size_of::<T>())
                                .expect("capacity overflow");
             let ptr = unsafe { allocate(size, mem::min_align_of::<T>()) };
-            Vec { len: 0, cap: capacity, ptr: ptr as *mut T }
+            Vec { ptr: ptr as *mut T, len: 0, cap: capacity }
         }
     }
 
@@ -231,15 +231,15 @@ pub fn from_fn(length: uint, op: |uint| -> T) -> Vec<T> {
     ///         }
     ///
     ///         // Put everything back together into a Vec
-    ///         let rebuilt = Vec::from_raw_parts(len, cap, p);
+    ///         let rebuilt = Vec::from_raw_parts(p, len, cap);
     ///         assert_eq!(rebuilt, vec![4i, 5i, 6i]);
     ///     }
     /// }
     /// ```
     #[experimental]
-    pub unsafe fn from_raw_parts(length: uint, capacity: uint,
-                                 ptr: *mut T) -> Vec<T> {
-        Vec { len: length, cap: capacity, ptr: ptr }
+    pub unsafe fn from_raw_parts(ptr: *mut T, length: uint,
+                                 capacity: uint) -> Vec<T> {
+        Vec { ptr: ptr, len: length, cap: capacity }
     }
 
     /// Consumes the `Vec`, partitioning it based on a predicate.
@@ -583,7 +583,7 @@ pub fn capacity(&self) -> uint {
     pub fn reserve_additional(&mut self, extra: uint) {
         if self.cap - self.len < extra {
             match self.len.checked_add(&extra) {
-                None => fail!("Vec::reserve_additional: `uint` overflow"),
+                None => panic!("Vec::reserve_additional: `uint` overflow"),
                 Some(new_cap) => self.reserve(new_cap)
             }
         }
@@ -636,13 +636,18 @@ pub fn reserve_exact(&mut self, capacity: uint) {
         }
     }
 
-    /// Shrinks the capacity of the vector as much as possible.
+    /// Shrinks the capacity of the vector as much as possible. It will drop
+    /// down as close as possible to the length but the allocator may still
+    /// inform the vector that there is space for a few more elements.
     ///
     /// # Example
     ///
     /// ```
-    /// let mut vec = vec![1i, 2, 3];
+    /// let mut vec: Vec<int> = Vec::with_capacity(10);
+    /// vec.push_all([1, 2, 3]);
+    /// assert_eq!(vec.capacity(), 10);
     /// vec.shrink_to_fit();
+    /// assert!(vec.capacity() >= 3);
     /// ```
     #[stable]
     pub fn shrink_to_fit(&mut self) {
@@ -694,12 +699,12 @@ pub fn into_boxed_slice(mut self) -> Box<[T]> {
     /// vec.truncate(2);
     /// assert_eq!(vec, vec![1, 2]);
     /// ```
-    #[unstable = "waiting on failure semantics"]
+    #[unstable = "waiting on panic semantics"]
     pub fn truncate(&mut self, len: uint) {
         unsafe {
             // drop any extra elements
             while len < self.len {
-                // decrement len before the read(), so a failure on Drop doesn't
+                // decrement len before the read(), so a panic on Drop doesn't
                 // re-drop the just-failed value.
                 self.len -= 1;
                 ptr::read(self.as_slice().unsafe_get(self.len));
@@ -830,6 +835,7 @@ pub fn iter<'a>(&'a self) -> Items<'a,T> {
     /// for num in vec.iter_mut() {
     ///     *num = 0;
     /// }
+    /// assert_eq!(vec, vec![0i, 0, 0]);
     /// ```
     #[inline]
     pub fn iter_mut<'a>(&'a mut self) -> MutItems<'a,T> {
@@ -954,9 +960,9 @@ pub fn swap_remove(&mut self, index: uint) -> Option<T> {
     /// Inserts an element at position `index` within the vector, shifting all
     /// elements after position `i` one position to the right.
     ///
-    /// # Failure
+    /// # Panics
     ///
-    /// Fails if `index` is not between `0` and the vector's length (both
+    /// Panics if `index` is not between `0` and the vector's length (both
     /// bounds inclusive).
     ///
     /// # Example
@@ -968,7 +974,7 @@ pub fn swap_remove(&mut self, index: uint) -> Option<T> {
     /// vec.insert(4, 5);
     /// assert_eq!(vec, vec![1, 4, 2, 3, 5]);
     /// ```
-    #[unstable = "failure semantics need settling"]
+    #[unstable = "panic semantics need settling"]
     pub fn insert(&mut self, index: uint, element: T) {
         let len = self.len();
         assert!(index <= len);
@@ -1005,7 +1011,7 @@ pub fn insert(&mut self, index: uint, element: T) {
     /// // v is unchanged:
     /// assert_eq!(v, vec![1, 3]);
     /// ```
-    #[unstable = "failure semantics need settling"]
+    #[unstable = "panic semantics need settling"]
     pub fn remove(&mut self, index: uint) -> Option<T> {
         let len = self.len();
         if index < len {
@@ -1347,7 +1353,7 @@ pub fn contains(&self, x: &T) -> bool {
     pub fn dedup(&mut self) {
         unsafe {
             // Although we have a mutable reference to `self`, we cannot make
-            // *arbitrary* changes. The `PartialEq` comparisons could fail, so we
+            // *arbitrary* changes. The `PartialEq` comparisons could panic, so we
             // must ensure that the vector is in a valid state at all time.
             //
             // The way that we handle this is by using swaps; we iterate
@@ -1514,7 +1520,7 @@ fn push(&mut self, value: T) {
         if self.len == self.cap {
             let old_size = self.cap * mem::size_of::<T>();
             let size = max(old_size, 2 * mem::size_of::<T>()) * 2;
-            if old_size > size { fail!("capacity overflow") }
+            if old_size > size { panic!("capacity overflow") }
             unsafe {
                 self.ptr = alloc_or_realloc(self.ptr, old_size, size);
             }
@@ -1680,7 +1686,7 @@ fn drop(&mut self) {
 pub fn as_vec<'a, T>(x: &'a [T]) -> DerefVec<'a, T> {
     unsafe {
         DerefVec {
-            x: Vec::from_raw_parts(x.len(), x.len(), x.as_ptr() as *mut T),
+            x: Vec::from_raw_parts(x.as_ptr() as *mut T, x.len(), x.len()),
             l: ContravariantLifetime::<'a>
         }
     }
@@ -1871,7 +1877,7 @@ pub fn map_in_place<U>(self, f: |T| -> U) -> Vec<U> {
                     // +-+-+-+-+-+-+-+-+-+
                     //          |         |
                     //          end_u     end_t
-                    // We must not fail here, one cell is marked as `T`
+                    // We must not panic here, one cell is marked as `T`
                     // although it is not `T`.
 
                     pv.start_t = pv.start_t.offset(1);
@@ -1882,9 +1888,9 @@ pub fn map_in_place<U>(self, f: |T| -> U) -> Vec<U> {
                     // +-+-+-+-+-+-+-+-+-+
                     //          |         |
                     //          end_u     end_t
-                    // We may fail again.
+                    // We may panic again.
 
-                    // The function given by the user might fail.
+                    // The function given by the user might panic.
                     let u = f(t);
 
                     ptr::write(pv.end_u, u);
@@ -1895,7 +1901,7 @@ pub fn map_in_place<U>(self, f: |T| -> U) -> Vec<U> {
                     // +-+-+-+-+-+-+-+-+-+
                     //          |         |
                     //          end_u     end_t
-                    // We should not fail here, because that would leak the `U`
+                    // We should not panic here, because that would leak the `U`
                     // pointed to by `end_u`.
 
                     pv.end_u = pv.end_u.offset(1);
@@ -1906,7 +1912,7 @@ pub fn map_in_place<U>(self, f: |T| -> U) -> Vec<U> {
                     // +-+-+-+-+-+-+-+-+-+
                     //            |       |
                     //            end_u   end_t
-                    // We may fail again.
+                    // We may panic again.
                 }
             }
 
@@ -1920,16 +1926,16 @@ pub fn map_in_place<U>(self, f: |T| -> U) -> Vec<U> {
             //              end_u
             // Extract `vec` and prevent the destructor of
             // `PartialVecNonZeroSized` from running. Note that none of the
-            // function calls can fail, thus no resources can be leaked (as the
+            // function calls can panic, thus no resources can be leaked (as the
             // `vec` member of `PartialVec` is the only one which holds
             // allocations -- and it is returned from this function. None of
-            // this can fail.
+            // this can panic.
             unsafe {
                 let vec_len = pv.vec.len();
                 let vec_cap = pv.vec.capacity();
                 let vec_ptr = pv.vec.as_mut_ptr() as *mut U;
                 mem::forget(pv);
-                Vec::from_raw_parts(vec_len, vec_cap, vec_ptr)
+                Vec::from_raw_parts(vec_ptr, vec_len, vec_cap)
             }
         } else {
             // Put the `Vec` into the `PartialVecZeroSized` structure and
@@ -1947,24 +1953,24 @@ pub fn map_in_place<U>(self, f: |T| -> U) -> Vec<U> {
             while pv.num_t != 0 {
                 unsafe {
                     // Create a `T` out of thin air and decrement `num_t`. This
-                    // must not fail between these steps, as otherwise a
+                    // must not panic between these steps, as otherwise a
                     // destructor of `T` which doesn't exist runs.
                     let t = mem::uninitialized();
                     pv.num_t -= 1;
 
-                    // The function given by the user might fail.
+                    // The function given by the user might panic.
                     let u = f(t);
 
                     // Forget the `U` and increment `num_u`. This increment
                     // cannot overflow the `uint` as we only do this for a
                     // number of times that fits into a `uint` (and start with
-                    // `0`). Again, we should not fail between these steps.
+                    // `0`). Again, we should not panic between these steps.
                     mem::forget(u);
                     pv.num_u += 1;
                 }
             }
             // Create a `Vec` from our `PartialVecZeroSized` and make sure the
-            // destructor of the latter will not run. None of this can fail.
+            // destructor of the latter will not run. None of this can panic.
             let mut result = Vec::new();
             unsafe { result.set_len(pv.num_u); }
             result
@@ -2286,7 +2292,7 @@ impl Drop for BadElem {
             fn drop(&mut self) {
                 let BadElem(ref mut x) = *self;
                 if *x == 0xbadbeef {
-                    fail!("BadElem failure: 0xbadbeef")
+                    panic!("BadElem panic: 0xbadbeef")
                 }
             }
         }
index cc6fe06665bc823cc5dc23f070eb7bc6036f4a3e..c3172a66f6b26540311f7d51c8bc5205f4d4474f 100644 (file)
@@ -94,6 +94,7 @@ pub enum Ordering {
 #[stable]
 impl AtomicBool {
     /// Create a new `AtomicBool`
+    #[inline]
     pub fn new(v: bool) -> AtomicBool {
         let val = if v { UINT_TRUE } else { 0 };
         AtomicBool { v: UnsafeCell::new(val), nocopy: marker::NoCopy }
@@ -305,6 +306,7 @@ pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
 #[stable]
 impl AtomicInt {
     /// Create a new `AtomicInt`
+    #[inline]
     pub fn new(v: int) -> AtomicInt {
         AtomicInt {v: UnsafeCell::new(v), nocopy: marker::NoCopy}
     }
@@ -426,6 +428,7 @@ pub fn fetch_xor(&self, val: int, order: Ordering) -> int {
 #[stable]
 impl AtomicUint {
     /// Create a new `AtomicUint`
+    #[inline]
     pub fn new(v: uint) -> AtomicUint {
         AtomicUint { v: UnsafeCell::new(v), nocopy: marker::NoCopy }
     }
@@ -547,6 +550,7 @@ pub fn fetch_xor(&self, val: uint, order: Ordering) -> uint {
 #[stable]
 impl<T> AtomicPtr<T> {
     /// Create a new `AtomicPtr`
+    #[inline]
     pub fn new(p: *mut T) -> AtomicPtr<T> {
         AtomicPtr { p: UnsafeCell::new(p as uint), nocopy: marker::NoCopy }
     }
@@ -599,8 +603,8 @@ unsafe fn atomic_store<T>(dst: *mut T, val: T, order:Ordering) {
         Release => intrinsics::atomic_store_rel(dst, val),
         Relaxed => intrinsics::atomic_store_relaxed(dst, val),
         SeqCst  => intrinsics::atomic_store(dst, val),
-        Acquire => fail!("there is no such thing as an acquire store"),
-        AcqRel  => fail!("there is no such thing as an acquire/release store"),
+        Acquire => panic!("there is no such thing as an acquire store"),
+        AcqRel  => panic!("there is no such thing as an acquire/release store"),
     }
 }
 
@@ -610,8 +614,8 @@ unsafe fn atomic_load<T>(dst: *const T, order:Ordering) -> T {
         Acquire => intrinsics::atomic_load_acq(dst),
         Relaxed => intrinsics::atomic_load_relaxed(dst),
         SeqCst  => intrinsics::atomic_load(dst),
-        Release => fail!("there is no such thing as a release load"),
-        AcqRel  => fail!("there is no such thing as an acquire/release load"),
+        Release => panic!("there is no such thing as a release load"),
+        AcqRel  => panic!("there is no such thing as an acquire/release load"),
     }
 }
 
@@ -737,7 +741,7 @@ pub fn fence(order: Ordering) {
             Release => intrinsics::atomic_fence_rel(),
             AcqRel  => intrinsics::atomic_fence_acqrel(),
             SeqCst  => intrinsics::atomic_fence(),
-            Relaxed => fail!("there is no such thing as a relaxed fence")
+            Relaxed => panic!("there is no such thing as a relaxed fence")
         }
     }
 }
index 8a4b9f6e51b60bef2cec0cf3714d826bbc540277..9d3fa9deed7739025b8ce2c56197aebb731c105b 100644 (file)
@@ -31,7 +31,7 @@
 //! tracked statically, at compile time. Because `RefCell` borrows are
 //! dynamic it is possible to attempt to borrow a value that is
 //! already mutably borrowed; when this happens it results in task
-//! failure.
+//! panic.
 //!
 //! # When to choose interior mutability
 //!
 //!         // Recursive call to return the just-cached value.
 //!         // Note that if we had not let the previous borrow
 //!         // of the cache fall out of scope then the subsequent
-//!         // recursive borrow would cause a dynamic task failure.
+//!         // recursive borrow would cause a dynamic task panic.
 //!         // This is the major hazard of using `RefCell`.
 //!         self.minimum_spanning_tree()
 //!     }
@@ -281,7 +281,7 @@ pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
     pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
         match self.try_borrow() {
             Some(ptr) => ptr,
-            None => fail!("RefCell<T> already mutably borrowed")
+            None => panic!("RefCell<T> already mutably borrowed")
         }
     }
 
@@ -314,7 +314,7 @@ pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
     pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
         match self.try_borrow_mut() {
             Some(ptr) => ptr,
-            None => fail!("RefCell<T> already borrowed")
+            None => panic!("RefCell<T> already borrowed")
         }
     }
 
index f507556909c8f14f4c001ffe7533d3bf07c5d46d..5d9553cbbbd570acfa5c904f434163a967934b48 100644 (file)
@@ -120,7 +120,7 @@ pub fn is_digit_radix(c: char, radix: uint) -> bool {
 #[inline]
 pub fn to_digit(c: char, radix: uint) -> Option<uint> {
     if radix > 36 {
-        fail!("to_digit: radix is too high (maximum 36)");
+        panic!("to_digit: radix is too high (maximum 36)");
     }
     let val = match c {
       '0' ... '9' => c as uint - ('0' as uint),
@@ -147,7 +147,7 @@ pub fn to_digit(c: char, radix: uint) -> Option<uint> {
 #[inline]
 pub fn from_digit(num: uint, radix: uint) -> Option<char> {
     if radix > 36 {
-        fail!("from_digit: radix is too high (maximum 36)");
+        panic!("from_digit: radix is to high (maximum 36)");
     }
     if num < radix {
         unsafe {
diff --git a/src/libcore/failure.rs b/src/libcore/failure.rs
deleted file mode 100644 (file)
index 9b63d32..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Failure support for libcore
-//!
-//! The core library cannot define failure, but it does *declare* failure. This
-//! means that the functions inside of libcore are allowed to fail, but to be
-//! useful an upstream crate must define failure for libcore to use. The current
-//! interface for failure is:
-//!
-//! ```ignore
-//! fn fail_impl(fmt: &fmt::Arguments, &(&'static str, uint)) -> !;
-//! ```
-//!
-//! This definition allows for failing with any general message, but it does not
-//! allow for failing with a `~Any` value. The reason for this is that libcore
-//! is not allowed to allocate.
-//!
-//! This module contains a few other failure functions, but these are just the
-//! necessary lang items for the compiler. All failure is funneled through this
-//! one function. Currently, the actual symbol is declared in the standard
-//! library, but the location of this may change over time.
-
-#![allow(dead_code, missing_doc)]
-
-use fmt;
-use intrinsics;
-
-#[cold] #[inline(never)] // this is the slow path, always
-#[lang="fail"]
-pub fn fail(expr_file_line: &(&'static str, &'static str, uint)) -> ! {
-    let (expr, file, line) = *expr_file_line;
-    let ref file_line = (file, line);
-    format_args!(|args| -> () {
-        fail_fmt(args, file_line);
-    }, "{}", expr);
-
-    unsafe { intrinsics::abort() }
-}
-
-#[cold] #[inline(never)]
-#[lang="fail_bounds_check"]
-fn fail_bounds_check(file_line: &(&'static str, uint),
-                     index: uint, len: uint) -> ! {
-    format_args!(|args| -> () {
-        fail_fmt(args, file_line);
-    }, "index out of bounds: the len is {} but the index is {}", len, index);
-    unsafe { intrinsics::abort() }
-}
-
-#[cold] #[inline(never)]
-pub fn fail_fmt(fmt: &fmt::Arguments, file_line: &(&'static str, uint)) -> ! {
-    #[allow(ctypes)]
-    extern {
-        #[lang = "fail_fmt"]
-        fn fail_impl(fmt: &fmt::Arguments, file: &'static str,
-                        line: uint) -> !;
-
-    }
-    let (file, line) = *file_line;
-    unsafe { fail_impl(fmt, file, line) }
-}
index 9b59b410e7cc450022c10031e83dd50859068f96..a17169f62c8be16b36c9477b06025b6e46cce42f 100644 (file)
@@ -60,7 +60,7 @@ fn finally(&mut self, dtor: ||) -> T {
 
 /**
  * The most general form of the `finally` functions. The function
- * `try_fn` will be invoked first; whether or not it fails, the
+ * `try_fn` will be invoked first; whether or not it panics, the
  * function `finally_fn` will be invoked next. The two parameters
  * `mutate` and `drop` are used to thread state through the two
  * closures. `mutate` is used for any shared, mutable state that both
@@ -69,7 +69,7 @@ fn finally(&mut self, dtor: ||) -> T {
  *
  * **WARNING:** While shared, mutable state between the try and finally
  * function is often necessary, one must be very careful; the `try`
- * function could have failed at any point, so the values of the shared
+ * function could have panicked at any point, so the values of the shared
  * state may be inconsistent.
  *
  * # Example
index 343ab7cfd28b98e7ec9733dc11a10f7dd5aa3166..79191c5a2b426183ee0cf11253e8b5f2ad101188 100644 (file)
@@ -94,7 +94,7 @@ pub fn float_to_str_bytes_common<T: Primitive + Float, U>(
     assert!(2 <= radix && radix <= 36);
     match exp_format {
         ExpDec if radix >= DIGIT_E_RADIX       // decimal exponent 'e'
-          => fail!("float_to_str_bytes_common: radix {} incompatible with \
+          => panic!("float_to_str_bytes_common: radix {} incompatible with \
                     use of 'e' as decimal exponent", radix),
         _ => ()
     }
@@ -127,7 +127,7 @@ pub fn float_to_str_bytes_common<T: Primitive + Float, U>(
         ExpDec => {
             let (exp, exp_base) = match exp_format {
                 ExpDec => (num.abs().log10().floor(), cast::<f64, T>(10.0f64).unwrap()),
-                ExpNone => fail!("unreachable"),
+                ExpNone => panic!("unreachable"),
             };
 
             (num / exp_base.powf(exp), cast::<T, i32>(exp).unwrap())
@@ -299,7 +299,7 @@ pub fn float_to_str_bytes_common<T: Primitive + Float, U>(
             buf[end] = match exp_format {
                 ExpDec if exp_upper => 'E',
                 ExpDec if !exp_upper => 'e',
-                _ => fail!("unreachable"),
+                _ => panic!("unreachable"),
             } as u8;
             end += 1;
 
index e57c499948362576932b274fd6721d0f1c1374af..22d8ba63b20ecd3e4bbf6a56846238c18a471dc4 100644 (file)
@@ -92,7 +92,7 @@ fn prefix(&self) -> &'static str { $prefix }
             fn digit(&self, x: u8) -> u8 {
                 match x {
                     $($x => $conv,)+
-                    x => fail!("number not in the range 0..{}: {}", self.base() - 1, x),
+                    x => panic!("number not in the range 0..{}: {}", self.base() - 1, x),
                 }
             }
         }
@@ -126,7 +126,7 @@ fn digit(&self, x: u8) -> u8 {
         match x {
             x @  0 ... 9 => b'0' + x,
             x if x < self.base() => b'a' + (x - 10),
-            x => fail!("number not in the range 0..{}: {}", self.base() - 1, x),
+            x => panic!("number not in the range 0..{}: {}", self.base() - 1, x),
         }
     }
 }
index 8486535d188762ec261a87066fb83667f05da4b0..68b3ca96de14715dbe14abee4b099d2078e103b3 100644 (file)
@@ -149,7 +149,7 @@ fn visit_enter_fn(&mut self, purity: uint, proto: uint,
     fn visit_fn_input(&mut self, i: uint, mode: uint,
                       inner: *const TyDesc) -> bool;
     fn visit_fn_output(&mut self, retstyle: uint, variadic: bool,
-                       inner: *const TyDesc) -> bool;
+                       converging: bool, inner: *const TyDesc) -> bool;
     fn visit_leave_fn(&mut self, purity: uint, proto: uint,
                       n_inputs: uint, retstyle: uint) -> bool;
 
index 62a4fbd2e08cdc5a3c1e287b94d0d601bfd19e83..6370e55332efb75faa848fb2a4e68f78f6059a8b 100644 (file)
@@ -40,8 +40,8 @@
 //!
 //! * `rust_begin_unwind` - This function takes three arguments, a
 //!   `&fmt::Arguments`, a `&str`, and a `uint`. These three arguments dictate
-//!   the failure message, the file at which failure was invoked, and the line.
-//!   It is up to consumers of this core library to define this failure
+//!   the panic message, the file at which panic was invoked, and the line.
+//!   It is up to consumers of this core library to define this panic
 //!   function; it is only required to never return.
 
 // Since libcore defines many fundamental lang items, all tests live in a
 pub mod bool;
 pub mod cell;
 pub mod char;
-pub mod failure;
+pub mod panicking;
 pub mod finally;
 pub mod iter;
 pub mod option;
 
 #[doc(hidden)]
 mod core {
-    pub use failure;
+    pub use panicking;
 }
 
 #[doc(hidden)]
index 17fcf0254575df3f81824492ee6327d7b6f035a8..9ba67bb2e47dca2d283c17bbfd1f97a44f86873c 100644 (file)
 
 #![macro_escape]
 
-/// Entry point of failure, for details, see std::macros
+/// Entry point of task panic, for details, see std::macros
 #[macro_export]
-macro_rules! fail(
+macro_rules! panic(
     () => (
-        fail!("{}", "explicit failure")
+        panic!("{}", "explicit panic")
     );
     ($msg:expr) => ({
         static _MSG_FILE_LINE: (&'static str, &'static str, uint) = ($msg, file!(), line!());
-        ::core::failure::fail(&_MSG_FILE_LINE)
+        ::core::panicking::panic(&_MSG_FILE_LINE)
     });
     ($fmt:expr, $($arg:tt)*) => ({
         // a closure can't have return type !, so we need a full
@@ -31,7 +31,7 @@ macro_rules! fail(
         // as returning !. We really do want this to be inlined, however,
         // because it's just a tiny wrapper. Small wins (156K to 149K in size)
         // were seen when forcing this to be inlined, and that number just goes
-        // up with the number of calls to fail!()
+        // up with the number of calls to panic!()
         //
         // The leading _'s are to avoid dead code warnings if this is
         // used inside a dead function. Just `#[allow(dead_code)]` is
@@ -40,7 +40,7 @@ macro_rules! fail(
         #[inline(always)]
         fn _run_fmt(fmt: &::std::fmt::Arguments) -> ! {
             static _FILE_LINE: (&'static str, uint) = (file!(), line!());
-            ::core::failure::fail_fmt(fmt, &_FILE_LINE)
+            ::core::panicking::panic_fmt(fmt, &_FILE_LINE)
         }
         format_args!(_run_fmt, $fmt, $($arg)*)
     });
@@ -51,12 +51,12 @@ fn _run_fmt(fmt: &::std::fmt::Arguments) -> ! {
 macro_rules! assert(
     ($cond:expr) => (
         if !$cond {
-            fail!(concat!("assertion failed: ", stringify!($cond)))
+            panic!(concat!("assertion failed: ", stringify!($cond)))
         }
     );
     ($cond:expr, $($arg:tt)*) => (
         if !$cond {
-            fail!($($arg)*)
+            panic!($($arg)*)
         }
     );
 )
@@ -78,7 +78,7 @@ macro_rules! assert_eq(
         let c1 = $cond1;
         let c2 = $cond2;
         if c1 != c2 || c2 != c1 {
-            fail!("expressions not equal, left: {}, right: {}", c1, c2);
+            panic!("expressions not equal, left: {}, right: {}", c1, c2);
         }
     })
 )
@@ -130,4 +130,4 @@ macro_rules! write(
 )
 
 #[macro_export]
-macro_rules! unreachable( () => (fail!("unreachable code")) )
+macro_rules! unreachable( () => (panic!("unreachable code")) )
index 3dceb42e206532681616b253a62fd5f4b7421322..3d05fd060d2b32f1d46b534036b49c7a5229b0c5 100644 (file)
@@ -1349,7 +1349,7 @@ pub trait CheckedMul: Mul<Self, Self> {
 checked_impl!(CheckedMul, checked_mul, i32, intrinsics::i32_mul_with_overflow)
 checked_impl!(CheckedMul, checked_mul, i64, intrinsics::i64_mul_with_overflow)
 
-/// Performs division that returns `None` instead of failing on division by zero and instead of
+/// Performs division that returns `None` instead of panicking on division by zero and instead of
 /// wrapping around on underflow and overflow.
 pub trait CheckedDiv: Div<Self, Self> {
     /// Divides two numbers, checking for underflow, overflow and division by zero. If any of that
@@ -1502,7 +1502,7 @@ pub trait Float: Signed + Primitive {
 
     /// Take the square root of a number.
     ///
-    /// Returns NaN if `self` is not a non-negative number.
+    /// Returns NaN if `self` is negative number.
     fn sqrt(self) -> Self;
     /// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
     fn rsqrt(self) -> Self;
index dd55c92097e940b2b1fcebd49ea25962d12e7194..522eb8336376e28327c3448dc38167665bb4145a 100644 (file)
@@ -291,9 +291,9 @@ pub fn as_mut_slice<'r>(&'r mut self) -> &'r mut [T] {
 
     /// Unwraps an option, yielding the content of a `Some`
     ///
-    /// # Failure
+    /// # Panics
     ///
-    /// Fails if the value is a `None` with a custom failure message provided by
+    /// Fails if the value is a `None` with a custom panic message provided by
     /// `msg`.
     ///
     /// # Example
@@ -312,19 +312,19 @@ pub fn as_mut_slice<'r>(&'r mut self) -> &'r mut [T] {
     pub fn expect(self, msg: &str) -> T {
         match self {
             Some(val) => val,
-            None => fail!("{}", msg),
+            None => panic!("{}", msg),
         }
     }
 
     /// Returns the inner `T` of a `Some(T)`.
     ///
-    /// # Failure
+    /// # Panics
     ///
-    /// Fails if the self value equals `None`.
+    /// Panics if the self value equals `None`.
     ///
     /// # Safety note
     ///
-    /// In general, because this function may fail, its use is discouraged.
+    /// In general, because this function may panic, its use is discouraged.
     /// Instead, prefer to use pattern matching and handle the `None`
     /// case explicitly.
     ///
@@ -344,7 +344,7 @@ pub fn expect(self, msg: &str) -> T {
     pub fn unwrap(self) -> T {
         match self {
             Some(val) => val,
-            None => fail!("called `Option::unwrap()` on a `None` value"),
+            None => panic!("called `Option::unwrap()` on a `None` value"),
         }
     }
 
diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs
new file mode 100644 (file)
index 0000000..62c9d90
--- /dev/null
@@ -0,0 +1,116 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Panic support for libcore
+//!
+//! The core library cannot define panicking, but it does *declare* panicking. This
+//! means that the functions inside of libcore are allowed to panic, but to be
+//! useful an upstream crate must define panicking for libcore to use. The current
+//! interface for panicking is:
+//!
+//! ```ignore
+//! fn panic_impl(fmt: &fmt::Arguments, &(&'static str, uint)) -> !;
+//! ```
+//!
+//! This definition allows for panicking with any general message, but it does not
+//! allow for failing with a `Box<Any>` value. The reason for this is that libcore
+//! is not allowed to allocate.
+//!
+//! This module contains a few other panicking functions, but these are just the
+//! necessary lang items for the compiler. All panics are funneled through this
+//! one function. Currently, the actual symbol is declared in the standard
+//! library, but the location of this may change over time.
+
+#![allow(dead_code, missing_doc)]
+
+use fmt;
+use intrinsics;
+
+// NOTE(stage0): remove after a snapshot
+#[cfg(stage0)]
+#[cold] #[inline(never)] // this is the slow path, always
+#[lang="fail"]
+pub fn panic(expr_file_line: &(&'static str, &'static str, uint)) -> ! {
+    let (expr, file, line) = *expr_file_line;
+    let ref file_line = (file, line);
+    format_args!(|args| -> () {
+        panic_fmt(args, file_line);
+    }, "{}", expr);
+
+    unsafe { intrinsics::abort() }
+}
+
+// NOTE(stage0): remove after a snapshot
+#[cfg(stage0)]
+#[cold] #[inline(never)]
+#[lang="fail_bounds_check"]
+fn panic_bounds_check(file_line: &(&'static str, uint),
+                     index: uint, len: uint) -> ! {
+    format_args!(|args| -> () {
+        panic_fmt(args, file_line);
+    }, "index out of bounds: the len is {} but the index is {}", len, index);
+    unsafe { intrinsics::abort() }
+}
+
+// NOTE(stage0): remove after a snapshot
+#[cfg(stage0)]
+#[cold] #[inline(never)]
+pub fn panic_fmt(fmt: &fmt::Arguments, file_line: &(&'static str, uint)) -> ! {
+    #[allow(ctypes)]
+    extern {
+        #[lang = "fail_fmt"]
+        fn panic_impl(fmt: &fmt::Arguments, file: &'static str,
+                        line: uint) -> !;
+
+    }
+    let (file, line) = *file_line;
+    unsafe { panic_impl(fmt, file, line) }
+}
+
+// NOTE(stage0): remove cfg after a snapshot
+#[cfg(not(stage0))]
+#[cold] #[inline(never)] // this is the slow path, always
+#[lang="panic"]
+pub fn panic(expr_file_line: &(&'static str, &'static str, uint)) -> ! {
+    let (expr, file, line) = *expr_file_line;
+    let ref file_line = (file, line);
+    format_args!(|args| -> () {
+        panic_fmt(args, file_line);
+    }, "{}", expr);
+
+    unsafe { intrinsics::abort() }
+}
+
+// NOTE(stage0): remove cfg after a snapshot
+#[cfg(not(stage0))]
+#[cold] #[inline(never)]
+#[lang="panic_bounds_check"]
+fn panic_bounds_check(file_line: &(&'static str, uint),
+                     index: uint, len: uint) -> ! {
+    format_args!(|args| -> () {
+        panic_fmt(args, file_line);
+    }, "index out of bounds: the len is {} but the index is {}", len, index);
+    unsafe { intrinsics::abort() }
+}
+
+// NOTE(stage0): remove cfg after a snapshot
+#[cfg(not(stage0))]
+#[cold] #[inline(never)]
+pub fn panic_fmt(fmt: &fmt::Arguments, file_line: &(&'static str, uint)) -> ! {
+    #[allow(ctypes)]
+    extern {
+        #[lang = "panic_fmt"]
+        fn panic_impl(fmt: &fmt::Arguments, file: &'static str,
+                        line: uint) -> !;
+
+    }
+    let (file, line) = *file_line;
+    unsafe { panic_impl(fmt, file, line) }
+}
index f0cd8402b1424384c46102d37041d8251a65d206..5e2f5529e8d4971d80b149fb0ea65e97ba7a5405 100644 (file)
@@ -76,7 +76,7 @@
 //!     unsafe {
 //!         let my_num: *mut int = libc::malloc(mem::size_of::<int>() as libc::size_t) as *mut int;
 //!         if my_num.is_null() {
-//!             fail!("failed to allocate memory");
+//!             panic!("failed to allocate memory");
 //!         }
 //!         libc::free(my_num as *mut libc::c_void);
 //!     }
index a62e2ecdca0328d9e22b392b7dd7904acbdb986d..16342dcae779fd2ede7ea2e4deb24c3a288d16c5 100644 (file)
 //! Their definition should always match the ABI defined in `rustc::back::abi`.
 
 use mem;
+use kinds::Sized;
 
 /// The representation of a Rust slice
+#[repr(C)]
 pub struct Slice<T> {
     pub data: *const T,
     pub len: uint,
 }
 
 /// The representation of a Rust closure
+#[repr(C)]
 pub struct Closure {
     pub code: *mut (),
     pub env: *mut (),
 }
 
 /// The representation of a Rust procedure (`proc()`)
+#[repr(C)]
 pub struct Procedure {
     pub code: *mut (),
     pub env: *mut (),
@@ -42,6 +46,7 @@ pub struct Procedure {
 ///
 /// This struct does not have a `Repr` implementation
 /// because there is no way to refer to all trait objects generically.
+#[repr(C)]
 pub struct TraitObject {
     pub data: *mut (),
     pub vtable: *mut (),
@@ -49,15 +54,14 @@ pub struct TraitObject {
 
 /// This trait is meant to map equivalences between raw structs and their
 /// corresponding rust values.
-pub trait Repr<T> {
+pub trait Repr<T> for Sized? {
     /// This function "unwraps" a rust value (without consuming it) into its raw
     /// struct representation. This can be used to read/write different values
     /// for the struct. This is a safe method because by default it does not
     /// enable write-access to the fields of the return value in safe code.
     #[inline]
-    fn repr(&self) -> T { unsafe { mem::transmute_copy(self) } }
+    fn repr(&self) -> T { unsafe { mem::transmute_copy(&self) } }
 }
 
-impl<'a, T> Repr<Slice<T>> for &'a [T] {}
-impl<'a> Repr<Slice<u8>> for &'a str {}
-
+impl<T> Repr<Slice<T>> for [T] {}
+impl Repr<Slice<u8>> for str {}
index 27bb649d1d99bfaa5c43a89675ea1c002d7307cc..82da972f68a3568ca0785ea664b105a3073e22be 100644 (file)
 //! warning (by default, controlled by the `unused_must_use` lint).
 //!
 //! You might instead, if you don't want to handle the error, simply
-//! fail, by converting to an `Option` with `ok`, then asserting
-//! success with `expect`. This will fail if the write fails, proving
+//! panic, by converting to an `Option` with `ok`, then asserting
+//! success with `expect`. This will panic if the write fails, proving
 //! a marginally useful message indicating why:
 //!
 //! ```{.no_run}
 //! let mut t = Timer::new().ok().expect("failed to create timer!");
 //! ```
 //!
-//! # `Result` vs. `fail!`
+//! # `Result` vs. `panic!`
 //!
-//! `Result` is for recoverable errors; `fail!` is for unrecoverable
-//! errors. Callers should always be able to avoid failure if they
+//! `Result` is for recoverable errors; `panic!` is for unrecoverable
+//! errors. Callers should always be able to avoid panics if they
 //! take the proper precautions, for example, calling `is_some()`
 //! on an `Option` type before calling `unwrap`.
 //!
-//! The suitability of `fail!` as an error handling mechanism is
+//! The suitability of `panic!` as an error handling mechanism is
 //! limited by Rust's lack of any way to "catch" and resume execution
-//! from a thrown exception. Therefore using failure for error
-//! handling requires encapsulating fallible code in a task. Calling
-//! the `fail!` macro, or invoking `fail!` indirectly should be
-//! avoided as an error reporting strategy. Failure is only for
-//! unrecoverable errors and a failing task is typically the sign of
+//! from a thrown exception. Therefore using panics for error
+//! handling requires encapsulating code that may panic in a task.
+//! Calling the `panic!` macro, or invoking `panic!` indirectly should be
+//! avoided as an error reporting strategy. Panics is only for
+//! unrecoverable errors and a panicking task is typically the sign of
 //! a bug.
 //!
 //! A module that instead returns `Results` is alerting the caller
-//! that failure is possible, and providing precise control over how
+//! that panics are possible, and providing precise control over how
 //! it is handled.
 //!
-//! Furthermore, failure may not be recoverable at all, depending on
-//! the context. The caller of `fail!` should assume that execution
-//! will not resume after failure, that failure is catastrophic.
+//! Furthermore, panics may not be recoverable at all, depending on
+//! the context. The caller of `panic!` should assume that execution
+//! will not resume after the panic, that a panic is catastrophic.
 
 #![stable]
 
@@ -764,9 +764,9 @@ pub fn unwrap_or_else(self, op: |E| -> T) -> T {
 impl<T, E: Show> Result<T, E> {
     /// Unwraps a result, yielding the content of an `Ok`.
     ///
-    /// # Failure
+    /// # Panics
     ///
-    /// Fails if the value is an `Err`, with a custom failure message provided
+    /// Panics if the value is an `Err`, with a custom panic message provided
     /// by the `Err`'s value.
     ///
     /// # Example
@@ -778,7 +778,7 @@ impl<T, E: Show> Result<T, E> {
     ///
     /// ```{.should_fail}
     /// let x: Result<uint, &str> = Err("emergency failure");
-    /// x.unwrap(); // fails with `emergency failure`
+    /// x.unwrap(); // panics with `emergency failure`
     /// ```
     #[inline]
     #[unstable = "waiting for conventions"]
@@ -786,7 +786,7 @@ pub fn unwrap(self) -> T {
         match self {
             Ok(t) => t,
             Err(e) =>
-                fail!("called `Result::unwrap()` on an `Err` value: {}", e)
+                panic!("called `Result::unwrap()` on an `Err` value: {}", e)
         }
     }
 }
@@ -794,16 +794,16 @@ pub fn unwrap(self) -> T {
 impl<T: Show, E> Result<T, E> {
     /// Unwraps a result, yielding the content of an `Err`.
     ///
-    /// # Failure
+    /// # Panics
     ///
-    /// Fails if the value is an `Ok`, with a custom failure message provided
+    /// Panics if the value is an `Ok`, with a custom panic message provided
     /// by the `Ok`'s value.
     ///
     /// # Example
     ///
     /// ```{.should_fail}
     /// let x: Result<uint, &str> = Ok(2u);
-    /// x.unwrap_err(); // fails with `2`
+    /// x.unwrap_err(); // panics with `2`
     /// ```
     ///
     /// ```
@@ -815,7 +815,7 @@ impl<T: Show, E> Result<T, E> {
     pub fn unwrap_err(self) -> E {
         match self {
             Ok(t) =>
-                fail!("called `Result::unwrap_err()` on an `Ok` value: {}", t),
+                panic!("called `Result::unwrap_err()` on an `Ok` value: {}", t),
             Err(e) => e
         }
     }
index 88d64a1e669c1aad4610215e1cdf0bdf027ae22d..aadf540afbe20f6abb1cb11fdf6f34eb521f9b8e 100644 (file)
@@ -48,7 +48,7 @@
 use ptr::RawPtr;
 use mem;
 use mem::size_of;
-use kinds::marker;
+use kinds::{Sized, marker};
 use raw::Repr;
 // Avoid conflicts with *both* the Slice trait (buggy) and the `slice::raw` module.
 use raw::Slice as RawSlice;
@@ -60,7 +60,7 @@
 
 /// Extension methods for immutable slices.
 #[unstable = "may merge with other traits; region parameter may disappear"]
-pub trait ImmutableSlice<'a, T> {
+pub trait ImmutableSlice<T> for Sized? {
     /// Returns a subslice spanning the interval [`start`, `end`).
     ///
     /// Fails when the end of the new slice lies beyond the end of the
@@ -68,7 +68,7 @@ pub trait ImmutableSlice<'a, T> {
     ///
     /// Slicing with `start` equal to `end` yields an empty slice.
     #[unstable = "waiting on final error conventions/slicing syntax"]
-    fn slice(&self, start: uint, end: uint) -> &'a [T];
+    fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [T];
 
     /// Returns a subslice from `start` to the end of the slice.
     ///
@@ -76,7 +76,7 @@ pub trait ImmutableSlice<'a, T> {
     ///
     /// Slicing from `self.len()` yields an empty slice.
     #[unstable = "waiting on final error conventions/slicing syntax"]
-    fn slice_from(&self, start: uint) -> &'a [T];
+    fn slice_from<'a>(&'a self, start: uint) -> &'a [T];
 
     /// Returns a subslice from the start of the slice to `end`.
     ///
@@ -84,7 +84,7 @@ pub trait ImmutableSlice<'a, T> {
     ///
     /// Slicing to `0` yields an empty slice.
     #[unstable = "waiting on final error conventions/slicing syntax"]
-    fn slice_to(&self, end: uint) -> &'a [T];
+    fn slice_to<'a>(&'a self, end: uint) -> &'a [T];
 
     /// Divides one slice into two at an index.
     ///
@@ -94,29 +94,29 @@ pub trait ImmutableSlice<'a, T> {
     ///
     /// Fails if `mid > len`.
     #[unstable = "waiting on final error conventions"]
-    fn split_at(&self, mid: uint) -> (&'a [T], &'a [T]);
+    fn split_at<'a>(&'a self, mid: uint) -> (&'a [T], &'a [T]);
 
     /// Returns an iterator over the slice
     #[unstable = "iterator type may change"]
-    fn iter(self) -> Items<'a, T>;
+    fn iter<'a>(&'a self) -> Items<'a, T>;
 
     /// Returns an iterator over subslices separated by elements that match
     /// `pred`.  The matched element is not contained in the subslices.
     #[unstable = "iterator type may change, waiting on unboxed closures"]
-    fn split(self, pred: |&T|: 'a -> bool) -> Splits<'a, T>;
+    fn split<'a>(&'a self, pred: |&T|: 'a -> bool) -> Splits<'a, T>;
 
     /// Returns an iterator over subslices separated by elements that match
     /// `pred`, limited to splitting at most `n` times.  The matched element is
     /// not contained in the subslices.
     #[unstable = "iterator type may change"]
-    fn splitn(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>>;
+    fn splitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>>;
 
     /// Returns an iterator over subslices separated by elements that match
     /// `pred` limited to splitting at most `n` times. This starts at the end of
     /// the slice and works backwards.  The matched element is not contained in
     /// the subslices.
     #[unstable = "iterator type may change"]
-    fn rsplitn(self,  n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>>;
+    fn rsplitn<'a>(&'a self,  n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>>;
 
     /// Returns an iterator over all contiguous windows of length
     /// `size`. The windows overlap. If the slice is shorter than
@@ -138,7 +138,7 @@ pub trait ImmutableSlice<'a, T> {
     /// }
     /// ```
     #[unstable = "iterator type may change"]
-    fn windows(self, size: uint) -> Windows<'a, T>;
+    fn windows<'a>(&'a self, size: uint) -> Windows<'a, T>;
 
     /// Returns an iterator over `size` elements of the slice at a
     /// time. The chunks do not overlap. If `size` does not divide the
@@ -161,33 +161,33 @@ pub trait ImmutableSlice<'a, T> {
     /// }
     /// ```
     #[unstable = "iterator type may change"]
-    fn chunks(self, size: uint) -> Chunks<'a, T>;
+    fn chunks<'a>(&'a self, size: uint) -> Chunks<'a, T>;
 
     /// Returns the element of a slice at the given index, or `None` if the
     /// index is out of bounds.
     #[unstable = "waiting on final collection conventions"]
-    fn get(&self, index: uint) -> Option<&'a T>;
+    fn get<'a>(&'a self, index: uint) -> Option<&'a T>;
 
     /// Returns the first element of a slice, or `None` if it is empty.
     #[unstable = "name may change"]
-    fn head(&self) -> Option<&'a T>;
+    fn head<'a>(&'a self) -> Option<&'a T>;
 
     /// Returns all but the first element of a slice.
     #[unstable = "name may change"]
-    fn tail(&self) -> &'a [T];
+    fn tail<'a>(&'a self) -> &'a [T];
 
     /// Returns all but the last element of a slice.
     #[unstable = "name may change"]
-    fn init(&self) -> &'a [T];
+    fn init<'a>(&'a self) -> &'a [T];
 
     /// Returns the last element of a slice, or `None` if it is empty.
     #[unstable = "name may change"]
-    fn last(&self) -> Option<&'a T>;
+    fn last<'a>(&'a self) -> Option<&'a T>;
 
     /// Returns a pointer to the element at the given index, without doing
     /// bounds checking.
     #[unstable]
-    unsafe fn unsafe_get(self, index: uint) -> &'a T;
+    unsafe fn unsafe_get<'a>(&'a self, index: uint) -> &'a T;
 
     /// Returns an unsafe pointer to the slice's buffer
     ///
@@ -237,9 +237,9 @@ pub trait ImmutableSlice<'a, T> {
 }
 
 #[unstable]
-impl<'a,T> ImmutableSlice<'a, T> for &'a [T] {
+impl<T> ImmutableSlice<T> for [T] {
     #[inline]
-    fn slice(&self, start: uint, end: uint) -> &'a [T] {
+    fn slice(&self, start: uint, end: uint) -> &[T] {
         assert!(start <= end);
         assert!(end <= self.len());
         unsafe {
@@ -251,22 +251,22 @@ fn slice(&self, start: uint, end: uint) -> &'a [T] {
     }
 
     #[inline]
-    fn slice_from(&self, start: uint) -> &'a [T] {
+    fn slice_from(&self, start: uint) -> &[T] {
         self.slice(start, self.len())
     }
 
     #[inline]
-    fn slice_to(&self, end: uint) -> &'a [T] {
+    fn slice_to(&self, end: uint) -> &[T] {
         self.slice(0, end)
     }
 
     #[inline]
-    fn split_at(&self, mid: uint) -> (&'a [T], &'a [T]) {
-        ((*self)[..mid], (*self)[mid..])
+    fn split_at(&self, mid: uint) -> (&[T], &[T]) {
+        (self[..mid], self[mid..])
     }
 
     #[inline]
-    fn iter(self) -> Items<'a, T> {
+    fn iter<'a>(&'a self) -> Items<'a, T> {
         unsafe {
             let p = self.as_ptr();
             if mem::size_of::<T>() == 0 {
@@ -282,7 +282,7 @@ fn iter(self) -> Items<'a, T> {
     }
 
     #[inline]
-    fn split(self, pred: |&T|: 'a -> bool) -> Splits<'a, T> {
+    fn split<'a>(&'a self, pred: |&T|: 'a -> bool) -> Splits<'a, T> {
         Splits {
             v: self,
             pred: pred,
@@ -291,7 +291,7 @@ fn split(self, pred: |&T|: 'a -> bool) -> Splits<'a, T> {
     }
 
     #[inline]
-    fn splitn(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>> {
+    fn splitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>> {
         SplitsN {
             iter: self.split(pred),
             count: n,
@@ -300,7 +300,7 @@ fn splitn(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>> {
     }
 
     #[inline]
-    fn rsplitn(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>> {
+    fn rsplitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>> {
         SplitsN {
             iter: self.split(pred),
             count: n,
@@ -309,42 +309,42 @@ fn rsplitn(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>> {
     }
 
     #[inline]
-    fn windows(self, size: uint) -> Windows<'a, T> {
+    fn windows(&self, size: uint) -> Windows<T> {
         assert!(size != 0);
         Windows { v: self, size: size }
     }
 
     #[inline]
-    fn chunks(self, size: uint) -> Chunks<'a, T> {
+    fn chunks(&self, size: uint) -> Chunks<T> {
         assert!(size != 0);
         Chunks { v: self, size: size }
     }
 
     #[inline]
-    fn get(&self, index: uint) -> Option<&'a T> {
+    fn get(&self, index: uint) -> Option<&T> {
         if index < self.len() { Some(&self[index]) } else { None }
     }
 
     #[inline]
-    fn head(&self) -> Option<&'a T> {
+    fn head(&self) -> Option<&T> {
         if self.len() == 0 { None } else { Some(&self[0]) }
     }
 
     #[inline]
-    fn tail(&self) -> &'a [T] { (*self)[1..] }
+    fn tail(&self) -> &[T] { self[1..] }
 
     #[inline]
-    fn init(&self) -> &'a [T] {
-        (*self)[..self.len() - 1]
+    fn init(&self) -> &[T] {
+        self[..self.len() - 1]
     }
 
     #[inline]
-    fn last(&self) -> Option<&'a T> {
+    fn last(&self) -> Option<&T> {
         if self.len() == 0 { None } else { Some(&self[self.len() - 1]) }
     }
 
     #[inline]
-    unsafe fn unsafe_get(self, index: uint) -> &'a T {
+    unsafe fn unsafe_get(&self, index: uint) -> &T {
         transmute(self.repr().data.offset(index as int))
     }
 
@@ -436,14 +436,14 @@ fn slice_or_fail_mut<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T]
 /// Extension methods for slices such that their elements are
 /// mutable.
 #[experimental = "may merge with other traits; may lose region param; needs review"]
-pub trait MutableSlice<'a, T> {
+pub trait MutableSlice<T> for Sized? {
     /// Returns a mutable reference to the element at the given index,
     /// or `None` if the index is out of bounds
     #[unstable = "waiting on final error conventions"]
-    fn get_mut(self, index: uint) -> Option<&'a mut T>;
+    fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut T>;
     /// Work with `self` as a mut slice.
     /// Primarily intended for getting a &mut [T] from a [T, ..N].
-    fn as_mut_slice(self) -> &'a mut [T];
+    fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T];
 
     /// Returns a mutable subslice spanning the interval [`start`, `end`).
     ///
@@ -452,7 +452,7 @@ pub trait MutableSlice<'a, T> {
     ///
     /// Slicing with `start` equal to `end` yields an empty slice.
     #[unstable = "waiting on final error conventions"]
-    fn slice_mut(self, start: uint, end: uint) -> &'a mut [T];
+    fn slice_mut<'a>(&'a mut self, start: uint, end: uint) -> &'a mut [T];
 
     /// Returns a mutable subslice from `start` to the end of the slice.
     ///
@@ -460,7 +460,7 @@ pub trait MutableSlice<'a, T> {
     ///
     /// Slicing from `self.len()` yields an empty slice.
     #[unstable = "waiting on final error conventions"]
-    fn slice_from_mut(self, start: uint) -> &'a mut [T];
+    fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [T];
 
     /// Returns a mutable subslice from the start of the slice to `end`.
     ///
@@ -468,45 +468,45 @@ pub trait MutableSlice<'a, T> {
     ///
     /// Slicing to `0` yields an empty slice.
     #[unstable = "waiting on final error conventions"]
-    fn slice_to_mut(self, end: uint) -> &'a mut [T];
+    fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [T];
 
     /// Returns an iterator that allows modifying each value
     #[unstable = "waiting on iterator type name conventions"]
-    fn iter_mut(self) -> MutItems<'a, T>;
+    fn iter_mut<'a>(&'a mut self) -> MutItems<'a, T>;
 
     /// Returns a mutable pointer to the first element of a slice, or `None` if it is empty
     #[unstable = "name may change"]
-    fn head_mut(self) -> Option<&'a mut T>;
+    fn head_mut<'a>(&'a mut self) -> Option<&'a mut T>;
 
     /// Returns all but the first element of a mutable slice
     #[unstable = "name may change"]
-    fn tail_mut(self) -> &'a mut [T];
+    fn tail_mut<'a>(&'a mut self) -> &'a mut [T];
 
     /// Returns all but the last element of a mutable slice
     #[unstable = "name may change"]
-    fn init_mut(self) -> &'a mut [T];
+    fn init_mut<'a>(&'a mut self) -> &'a mut [T];
 
     /// Returns a mutable pointer to the last item in the slice.
     #[unstable = "name may change"]
-    fn last_mut(self) -> Option<&'a mut T>;
+    fn last_mut<'a>(&'a mut self) -> Option<&'a mut T>;
 
     /// Returns an iterator over mutable subslices separated by elements that
     /// match `pred`.  The matched element is not contained in the subslices.
     #[unstable = "waiting on unboxed closures, iterator type name conventions"]
-    fn split_mut(self, pred: |&T|: 'a -> bool) -> MutSplits<'a, T>;
+    fn split_mut<'a>(&'a mut self, pred: |&T|: 'a -> bool) -> MutSplits<'a, T>;
 
     /// Returns an iterator over subslices separated by elements that match
     /// `pred`, limited to splitting at most `n` times.  The matched element is
     /// not contained in the subslices.
     #[unstable = "waiting on unboxed closures, iterator type name conventions"]
-    fn splitn_mut(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>>;
+    fn splitn_mut<'a>(&'a mut self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>>;
 
     /// Returns an iterator over subslices separated by elements that match
     /// `pred` limited to splitting at most `n` times. This starts at the end of
     /// the slice and works backwards.  The matched element is not contained in
     /// the subslices.
     #[unstable = "waiting on unboxed closures, iterator type name conventions"]
-    fn rsplitn_mut(self,  n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>>;
+    fn rsplitn_mut<'a>(&'a mut self,  n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>>;
 
     /// Returns an iterator over `chunk_size` elements of the slice at a time.
     /// The chunks are mutable and do not overlap. If `chunk_size` does
@@ -517,7 +517,7 @@ pub trait MutableSlice<'a, T> {
     ///
     /// Fails if `chunk_size` is 0.
     #[unstable = "waiting on iterator type name conventions"]
-    fn chunks_mut(self, chunk_size: uint) -> MutChunks<'a, T>;
+    fn chunks_mut<'a>(&'a mut self, chunk_size: uint) -> MutChunks<'a, T>;
 
     /// Swaps two elements in a slice.
     ///
@@ -536,7 +536,7 @@ pub trait MutableSlice<'a, T> {
     /// assert!(v == ["a", "d", "c", "b"]);
     /// ```
     #[unstable = "waiting on final error conventions"]
-    fn swap(self, a: uint, b: uint);
+    fn swap(&mut self, a: uint, b: uint);
 
     /// Divides one `&mut` into two at an index.
     ///
@@ -571,7 +571,7 @@ pub trait MutableSlice<'a, T> {
     /// }
     /// ```
     #[unstable = "waiting on final error conventions"]
-    fn split_at_mut(self, mid: uint) -> (&'a mut [T], &'a mut [T]);
+    fn split_at_mut<'a>(&'a mut self, mid: uint) -> (&'a mut [T], &'a mut [T]);
 
     /// Reverse the order of elements in a slice, in place.
     ///
@@ -583,11 +583,11 @@ pub trait MutableSlice<'a, T> {
     /// assert!(v == [3i, 2, 1]);
     /// ```
     #[experimental = "may be moved to iterators instead"]
-    fn reverse(self);
+    fn reverse(&mut self);
 
     /// Returns an unsafe mutable pointer to the element in index
     #[experimental = "waiting on unsafe conventions"]
-    unsafe fn unsafe_mut(self, index: uint) -> &'a mut T;
+    unsafe fn unsafe_mut<'a>(&'a mut self, index: uint) -> &'a mut T;
 
     /// Return an unsafe mutable pointer to the slice's buffer.
     ///
@@ -598,43 +598,43 @@ pub trait MutableSlice<'a, T> {
     /// would also make any pointers to it invalid.
     #[inline]
     #[unstable]
-    fn as_mut_ptr(self) -> *mut T;
+    fn as_mut_ptr(&mut self) -> *mut T;
 }
 
 #[experimental = "trait is experimental"]
-impl<'a,T> MutableSlice<'a, T> for &'a mut [T] {
+impl<T> MutableSlice<T> for [T] {
     #[inline]
-    fn get_mut(self, index: uint) -> Option<&'a mut T> {
+    fn get_mut(&mut self, index: uint) -> Option<&mut T> {
         if index < self.len() { Some(&mut self[index]) } else { None }
     }
 
     #[inline]
-    fn as_mut_slice(self) -> &'a mut [T] { self }
+    fn as_mut_slice(&mut self) -> &mut [T] { self }
 
-    fn slice_mut(self, start: uint, end: uint) -> &'a mut [T] {
+    fn slice_mut(&mut self, start: uint, end: uint) -> &mut [T] {
         self[mut start..end]
     }
 
     #[inline]
-    fn slice_from_mut(self, start: uint) -> &'a mut [T] {
+    fn slice_from_mut(&mut self, start: uint) -> &mut [T] {
         self[mut start..]
     }
 
     #[inline]
-    fn slice_to_mut(self, end: uint) -> &'a mut [T] {
+    fn slice_to_mut(&mut self, end: uint) -> &mut [T] {
         self[mut ..end]
     }
 
     #[inline]
-    fn split_at_mut(self, mid: uint) -> (&'a mut [T], &'a mut [T]) {
+    fn split_at_mut(&mut self, mid: uint) -> (&mut [T], &mut [T]) {
         unsafe {
-            let self2: &'a mut [T] = mem::transmute_copy(&self);
+            let self2: &mut [T] = mem::transmute_copy(&self);
             (self[mut ..mid], self2[mut mid..])
         }
     }
 
     #[inline]
-    fn iter_mut(self) -> MutItems<'a, T> {
+    fn iter_mut<'a>(&'a mut self) -> MutItems<'a, T> {
         unsafe {
             let p = self.as_mut_ptr();
             if mem::size_of::<T>() == 0 {
@@ -652,36 +652,36 @@ fn iter_mut(self) -> MutItems<'a, T> {
     }
 
     #[inline]
-    fn last_mut(self) -> Option<&'a mut T> {
+    fn last_mut(&mut self) -> Option<&mut T> {
         let len = self.len();
         if len == 0 { return None; }
         Some(&mut self[len - 1])
     }
 
     #[inline]
-    fn head_mut(self) -> Option<&'a mut T> {
+    fn head_mut(&mut self) -> Option<&mut T> {
         if self.len() == 0 { None } else { Some(&mut self[0]) }
     }
 
     #[inline]
-    fn tail_mut(self) -> &'a mut [T] {
+    fn tail_mut(&mut self) -> &mut [T] {
         let len = self.len();
         self[mut 1..len]
     }
 
     #[inline]
-    fn init_mut(self) -> &'a mut [T] {
+    fn init_mut(&mut self) -> &mut [T] {
         let len = self.len();
         self[mut 0..len - 1]
     }
 
     #[inline]
-    fn split_mut(self, pred: |&T|: 'a -> bool) -> MutSplits<'a, T> {
+    fn split_mut<'a>(&'a mut self, pred: |&T|: 'a -> bool) -> MutSplits<'a, T> {
         MutSplits { v: self, pred: pred, finished: false }
     }
 
     #[inline]
-    fn splitn_mut(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>> {
+    fn splitn_mut<'a>(&'a mut self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>> {
         SplitsN {
             iter: self.split_mut(pred),
             count: n,
@@ -690,7 +690,7 @@ fn splitn_mut(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>
     }
 
     #[inline]
-    fn rsplitn_mut(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>> {
+    fn rsplitn_mut<'a>(&'a mut self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>> {
         SplitsN {
             iter: self.split_mut(pred),
             count: n,
@@ -699,12 +699,12 @@ fn rsplitn_mut(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T
    }
 
     #[inline]
-    fn chunks_mut(self, chunk_size: uint) -> MutChunks<'a, T> {
+    fn chunks_mut(&mut self, chunk_size: uint) -> MutChunks<T> {
         assert!(chunk_size > 0);
         MutChunks { v: self, chunk_size: chunk_size }
     }
 
-    fn swap(self, a: uint, b: uint) {
+    fn swap(&mut self, a: uint, b: uint) {
         unsafe {
             // Can't take two mutable loans from one vector, so instead just cast
             // them to their raw pointers to do the swap
@@ -714,7 +714,7 @@ fn swap(self, a: uint, b: uint) {
         }
     }
 
-    fn reverse(self) {
+    fn reverse(&mut self) {
         let mut i: uint = 0;
         let ln = self.len();
         while i < ln / 2 {
@@ -729,19 +729,19 @@ fn reverse(self) {
     }
 
     #[inline]
-    unsafe fn unsafe_mut(self, index: uint) -> &'a mut T {
+    unsafe fn unsafe_mut(&mut self, index: uint) -> &mut T {
         transmute((self.repr().data as *mut T).offset(index as int))
     }
 
     #[inline]
-    fn as_mut_ptr(self) -> *mut T {
+    fn as_mut_ptr(&mut self) -> *mut T {
         self.repr().data as *mut T
     }
 }
 
 /// Extension methods for slices containing `PartialEq` elements.
 #[unstable = "may merge with other traits"]
-pub trait ImmutablePartialEqSlice<T:PartialEq> {
+pub trait ImmutablePartialEqSlice<T: PartialEq> for Sized? {
     /// Find the first index containing a matching value.
     fn position_elem(&self, t: &T) -> Option<uint>;
 
@@ -759,7 +759,7 @@ pub trait ImmutablePartialEqSlice<T:PartialEq> {
 }
 
 #[unstable = "trait is unstable"]
-impl<'a,T:PartialEq> ImmutablePartialEqSlice<T> for &'a [T] {
+impl<T: PartialEq> ImmutablePartialEqSlice<T> for [T] {
     #[inline]
     fn position_elem(&self, x: &T) -> Option<uint> {
         self.iter().position(|y| *x == *y)
@@ -778,19 +778,19 @@ fn contains(&self, x: &T) -> bool {
     #[inline]
     fn starts_with(&self, needle: &[T]) -> bool {
         let n = needle.len();
-        self.len() >= n && needle == (*self)[..n]
+        self.len() >= n && needle == self[..n]
     }
 
     #[inline]
     fn ends_with(&self, needle: &[T]) -> bool {
         let (m, n) = (self.len(), needle.len());
-        m >= n && needle == (*self)[m-n..]
+        m >= n && needle == self[m-n..]
     }
 }
 
 /// Extension methods for slices containing `Ord` elements.
 #[unstable = "may merge with other traits"]
-pub trait ImmutableOrdSlice<T: Ord> {
+pub trait ImmutableOrdSlice<T: Ord> for Sized? {
     /// Binary search a sorted slice for a given element.
     ///
     /// If the value is found then `Found` is returned, containing the
@@ -820,7 +820,7 @@ pub trait ImmutableOrdSlice<T: Ord> {
 }
 
 #[unstable = "trait is unstable"]
-impl<'a, T: Ord> ImmutableOrdSlice<T> for &'a [T] {
+impl<T: Ord> ImmutableOrdSlice<T> for [T] {
     #[unstable]
     fn binary_search_elem(&self, x: &T) -> BinarySearchResult {
         self.binary_search(|p| p.cmp(x))
@@ -829,7 +829,7 @@ fn binary_search_elem(&self, x: &T) -> BinarySearchResult {
 
 /// Trait for &[T] where T is Cloneable
 #[unstable = "may merge with other traits"]
-pub trait MutableCloneableSlice<T> {
+pub trait MutableCloneableSlice<T> for Sized? {
     /// Copies as many elements from `src` as it can into `self` (the
     /// shorter of `self.len()` and `src.len()`). Returns the number
     /// of elements copied.
@@ -849,13 +849,13 @@ pub trait MutableCloneableSlice<T> {
     /// assert!(dst.clone_from_slice(src2) == 3);
     /// assert!(dst == [3i, 4, 5]);
     /// ```
-    fn clone_from_slice(self, &[T]) -> uint;
+    fn clone_from_slice(&mut self, &[T]) -> uint;
 }
 
 #[unstable = "trait is unstable"]
-impl<'a, T: Clone> MutableCloneableSlice<T> for &'a mut [T] {
+impl<T: Clone> MutableCloneableSlice<T> for [T] {
     #[inline]
-    fn clone_from_slice(self, src: &[T]) -> uint {
+    fn clone_from_slice(&mut self, src: &[T]) -> uint {
         let min = cmp::min(self.len(), src.len());
         let dst = self.slice_to_mut(min);
         let src = src.slice_to(min);
@@ -1509,19 +1509,20 @@ pub unsafe fn pop_ptr<T>(slice: &mut Slice<T>) -> Option<*const T> {
 #[experimental = "needs review"]
 pub mod bytes {
     use collections::Collection;
+    use kinds::Sized;
     use ptr;
     use slice::{ImmutableSlice, MutableSlice};
 
     /// A trait for operations on mutable `[u8]`s.
-    pub trait MutableByteVector {
+    pub trait MutableByteVector for Sized? {
         /// Sets all bytes of the receiver to the given value.
-        fn set_memory(self, value: u8);
+        fn set_memory(&mut self, value: u8);
     }
 
-    impl<'a> MutableByteVector for &'a mut [u8] {
+    impl MutableByteVector for [u8] {
         #[inline]
         #[allow(experimental)]
-        fn set_memory(self, value: u8) {
+        fn set_memory(&mut self, value: u8) {
             unsafe { ptr::set_memory(self.as_mut_ptr(), value, self.len()) };
         }
     }
@@ -1623,53 +1624,51 @@ fn gt(&self, other: & &'a [T]) -> bool {
 
 /// Extension methods for immutable slices containing integers.
 #[experimental]
-pub trait ImmutableIntSlice<'a, U, S> {
+pub trait ImmutableIntSlice<U, S> for Sized? {
     /// Converts the slice to an immutable slice of unsigned integers with the same width.
-    fn as_unsigned(self) -> &'a [U];
+    fn as_unsigned<'a>(&'a self) -> &'a [U];
     /// Converts the slice to an immutable slice of signed integers with the same width.
-    fn as_signed(self) -> &'a [S];
+    fn as_signed<'a>(&'a self) -> &'a [S];
 }
 
 /// Extension methods for mutable slices containing integers.
 #[experimental]
-pub trait MutableIntSlice<'a, U, S>: ImmutableIntSlice<'a, U, S> {
+pub trait MutableIntSlice<U, S> for Sized?: ImmutableIntSlice<U, S> {
     /// Converts the slice to a mutable slice of unsigned integers with the same width.
-    fn as_unsigned_mut(self) -> &'a mut [U];
+    fn as_unsigned_mut<'a>(&'a mut self) -> &'a mut [U];
     /// Converts the slice to a mutable slice of signed integers with the same width.
-    fn as_signed_mut(self) -> &'a mut [S];
+    fn as_signed_mut<'a>(&'a mut self) -> &'a mut [S];
 }
 
 macro_rules! impl_immut_int_slice {
     ($u:ty, $s:ty, $t:ty) => {
         #[experimental]
-        impl<'a> ImmutableIntSlice<'a, $u, $s> for $t {
+        impl ImmutableIntSlice<$u, $s> for [$t] {
             #[inline]
-            fn as_unsigned(self) -> &'a [$u] { unsafe { transmute(self) } }
+            fn as_unsigned(&self) -> &[$u] { unsafe { transmute(self) } }
             #[inline]
-            fn as_signed(self) -> &'a [$s] { unsafe { transmute(self) } }
+            fn as_signed(&self) -> &[$s] { unsafe { transmute(self) } }
         }
     }
 }
 macro_rules! impl_mut_int_slice {
     ($u:ty, $s:ty, $t:ty) => {
         #[experimental]
-        impl<'a> MutableIntSlice<'a, $u, $s> for $t {
+        impl MutableIntSlice<$u, $s> for [$t] {
             #[inline]
-            fn as_unsigned_mut(self) -> &'a mut [$u] { unsafe { transmute(self) } }
+            fn as_unsigned_mut(&mut self) -> &mut [$u] { unsafe { transmute(self) } }
             #[inline]
-            fn as_signed_mut(self) -> &'a mut [$s] { unsafe { transmute(self) } }
+            fn as_signed_mut(&mut self) -> &mut [$s] { unsafe { transmute(self) } }
         }
     }
 }
 
 macro_rules! impl_int_slice {
     ($u:ty, $s:ty) => {
-        impl_immut_int_slice!($u, $s, &'a [$u])
-        impl_immut_int_slice!($u, $s, &'a [$s])
-        impl_immut_int_slice!($u, $s, &'a mut [$u])
-        impl_immut_int_slice!($u, $s, &'a mut [$s])
-        impl_mut_int_slice!($u, $s, &'a mut [$u])
-        impl_mut_int_slice!($u, $s, &'a mut [$s])
+        impl_immut_int_slice!($u, $s, $u)
+        impl_immut_int_slice!($u, $s, $s)
+        impl_mut_int_slice!($u, $s, $u)
+        impl_mut_int_slice!($u, $s, $s)
     }
 }
 
index e8cd93ba7dc4248c5e513bd338fb4fb6ee1fe68a..ff1db992844d6f3382ec1e7389e03dd0802db6cb 100644 (file)
@@ -27,6 +27,7 @@
 use iter::{Map, Iterator};
 use iter::{DoubleEndedIterator, ExactSize};
 use iter::range;
+use kinds::Sized;
 use num::{CheckedMul, Saturating};
 use option::{Option, None, Some};
 use raw::Repr;
@@ -1206,7 +1207,7 @@ fn len(&self) -> uint {
 }
 
 /// Methods for string slices
-pub trait StrSlice<'a> {
+pub trait StrSlice for Sized? {
     /// Returns true if one string contains another
     ///
     /// # Arguments
@@ -1218,7 +1219,7 @@ pub trait StrSlice<'a> {
     /// ```rust
     /// assert!("bananas".contains("nana"));
     /// ```
-    fn contains<'a>(&self, needle: &'a str) -> bool;
+    fn contains(&self, needle: &str) -> bool;
 
     /// Returns true if a string contains a char.
     ///
@@ -1242,7 +1243,7 @@ pub trait StrSlice<'a> {
     /// let v: Vec<char> = "abc åäö".chars().collect();
     /// assert_eq!(v, vec!['a', 'b', 'c', ' ', 'å', 'ä', 'ö']);
     /// ```
-    fn chars(&self) -> Chars<'a>;
+    fn chars<'a>(&'a self) -> Chars<'a>;
 
     /// An iterator over the bytes of `self`
     ///
@@ -1252,10 +1253,10 @@ pub trait StrSlice<'a> {
     /// let v: Vec<u8> = "bors".bytes().collect();
     /// assert_eq!(v, b"bors".to_vec());
     /// ```
-    fn bytes(&self) -> Bytes<'a>;
+    fn bytes<'a>(&'a self) -> Bytes<'a>;
 
     /// An iterator over the characters of `self` and their byte offsets.
-    fn char_indices(&self) -> CharOffsets<'a>;
+    fn char_indices<'a>(&'a self) -> CharOffsets<'a>;
 
     /// An iterator over substrings of `self`, separated by characters
     /// matched by `sep`.
@@ -1275,7 +1276,7 @@ pub trait StrSlice<'a> {
     /// let v: Vec<&str> = "".split('X').collect();
     /// assert_eq!(v, vec![""]);
     /// ```
-    fn split<Sep: CharEq>(&self, sep: Sep) -> CharSplits<'a, Sep>;
+    fn split<'a, Sep: CharEq>(&'a self, sep: Sep) -> CharSplits<'a, Sep>;
 
     /// An iterator over substrings of `self`, separated by characters
     /// matched by `sep`, restricted to splitting at most `count`
@@ -1299,7 +1300,7 @@ pub trait StrSlice<'a> {
     /// let v: Vec<&str> = "".splitn(1, 'X').collect();
     /// assert_eq!(v, vec![""]);
     /// ```
-    fn splitn<Sep: CharEq>(&self, count: uint, sep: Sep) -> CharSplitsN<'a, Sep>;
+    fn splitn<'a, Sep: CharEq>(&'a self, count: uint, sep: Sep) -> CharSplitsN<'a, Sep>;
 
     /// An iterator over substrings of `self`, separated by characters
     /// matched by `sep`.
@@ -1325,7 +1326,7 @@ pub trait StrSlice<'a> {
     /// let v: Vec<&str> = "lionXXtigerXleopard".split('X').rev().collect();
     /// assert_eq!(v, vec!["leopard", "tiger", "", "lion"]);
     /// ```
-    fn split_terminator<Sep: CharEq>(&self, sep: Sep) -> CharSplits<'a, Sep>;
+    fn split_terminator<'a, Sep: CharEq>(&'a self, sep: Sep) -> CharSplits<'a, Sep>;
 
     /// An iterator over substrings of `self`, separated by characters
     /// matched by `sep`, starting from the end of the string.
@@ -1343,7 +1344,7 @@ pub trait StrSlice<'a> {
     /// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(2, 'X').collect();
     /// assert_eq!(v, vec!["leopard", "tiger", "lionX"]);
     /// ```
-    fn rsplitn<Sep: CharEq>(&self, count: uint, sep: Sep) -> CharSplitsN<'a, Sep>;
+    fn rsplitn<'a, Sep: CharEq>(&'a self, count: uint, sep: Sep) -> CharSplitsN<'a, Sep>;
 
     /// An iterator over the start and end indices of the disjoint
     /// matches of `sep` within `self`.
@@ -1365,7 +1366,7 @@ pub trait StrSlice<'a> {
     /// let v: Vec<(uint, uint)> = "ababa".match_indices("aba").collect();
     /// assert_eq!(v, vec![(0, 3)]); // only the first `aba`
     /// ```
-    fn match_indices(&self, sep: &'a str) -> MatchIndices<'a>;
+    fn match_indices<'a>(&'a self, sep: &'a str) -> MatchIndices<'a>;
 
     /// An iterator over the substrings of `self` separated by `sep`.
     ///
@@ -1378,7 +1379,7 @@ pub trait StrSlice<'a> {
     /// let v: Vec<&str> = "1abcabc2".split_str("abc").collect();
     /// assert_eq!(v, vec!["1", "", "2"]);
     /// ```
-    fn split_str(&self, &'a str) -> StrSplits<'a>;
+    fn split_str<'a>(&'a self, &'a str) -> StrSplits<'a>;
 
     /// An iterator over the lines of a string (subsequences separated
     /// by `\n`). This does not include the empty string after a
@@ -1391,7 +1392,7 @@ pub trait StrSlice<'a> {
     /// let v: Vec<&str> = four_lines.lines().collect();
     /// assert_eq!(v, vec!["foo", "bar", "", "baz"]);
     /// ```
-    fn lines(&self) -> CharSplits<'a, char>;
+    fn lines<'a>(&'a self) -> CharSplits<'a, char>;
 
     /// An iterator over the lines of a string, separated by either
     /// `\n` or `\r\n`. As with `.lines()`, this does not include an
@@ -1404,7 +1405,7 @@ pub trait StrSlice<'a> {
     /// let v: Vec<&str> = four_lines.lines_any().collect();
     /// assert_eq!(v, vec!["foo", "bar", "", "baz"]);
     /// ```
-    fn lines_any(&self) -> AnyLines<'a>;
+    fn lines_any<'a>(&'a self) -> AnyLines<'a>;
 
     /// Returns the number of Unicode code points (`char`) that a
     /// string holds.
@@ -1459,7 +1460,7 @@ pub trait StrSlice<'a> {
     ///
     /// assert_eq!(s.slice(1, 9), "öwe 老");
     ///
-    /// // these will fail:
+    /// // these will panic:
     /// // byte 2 lies within `ö`:
     /// // s.slice(2, 3);
     ///
@@ -1469,7 +1470,7 @@ pub trait StrSlice<'a> {
     /// // byte 100 is outside the string
     /// // s.slice(3, 100);
     /// ```
-    fn slice(&self, begin: uint, end: uint) -> &'a str;
+    fn slice<'a>(&'a self, begin: uint, end: uint) -> &'a str;
 
     /// Returns a slice of the string from `begin` to its end.
     ///
@@ -1479,7 +1480,7 @@ pub trait StrSlice<'a> {
     /// out of bounds.
     ///
     /// See also `slice`, `slice_to` and `slice_chars`.
-    fn slice_from(&self, begin: uint) -> &'a str;
+    fn slice_from<'a>(&'a self, begin: uint) -> &'a str;
 
     /// Returns a slice of the string from the beginning to byte
     /// `end`.
@@ -1490,7 +1491,7 @@ pub trait StrSlice<'a> {
     /// out of bounds.
     ///
     /// See also `slice`, `slice_from` and `slice_chars`.
-    fn slice_to(&self, end: uint) -> &'a str;
+    fn slice_to<'a>(&'a self, end: uint) -> &'a str;
 
     /// Returns a slice of the string from the character range
     /// [`begin`..`end`).
@@ -1515,7 +1516,7 @@ pub trait StrSlice<'a> {
     /// assert_eq!(s.slice_chars(0, 4), "Löwe");
     /// assert_eq!(s.slice_chars(5, 7), "老虎");
     /// ```
-    fn slice_chars(&self, begin: uint, end: uint) -> &'a str;
+    fn slice_chars<'a>(&'a self, begin: uint, end: uint) -> &'a str;
 
     /// Returns true if `needle` is a prefix of the string.
     ///
@@ -1549,7 +1550,7 @@ pub trait StrSlice<'a> {
     /// assert_eq!("12foo1bar12".trim_chars(x), "foo1bar")
     /// assert_eq!("123foo1bar123".trim_chars(|c: char| c.is_digit()), "foo1bar")
     /// ```
-    fn trim_chars<C: CharEq>(&self, to_trim: C) -> &'a str;
+    fn trim_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str;
 
     /// Returns a string with leading `chars_to_trim` removed.
     ///
@@ -1565,7 +1566,7 @@ pub trait StrSlice<'a> {
     /// assert_eq!("12foo1bar12".trim_left_chars(x), "foo1bar12")
     /// assert_eq!("123foo1bar123".trim_left_chars(|c: char| c.is_digit()), "foo1bar123")
     /// ```
-    fn trim_left_chars<C: CharEq>(&self, to_trim: C) -> &'a str;
+    fn trim_left_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str;
 
     /// Returns a string with trailing `chars_to_trim` removed.
     ///
@@ -1581,7 +1582,7 @@ pub trait StrSlice<'a> {
     /// assert_eq!("12foo1bar12".trim_right_chars(x), "12foo1bar")
     /// assert_eq!("123foo1bar123".trim_right_chars(|c: char| c.is_digit()), "123foo1bar")
     /// ```
-    fn trim_right_chars<C: CharEq>(&self, to_trim: C) -> &'a str;
+    fn trim_right_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str;
 
     /// Check that `index`-th byte lies at the start and/or end of a
     /// UTF-8 code point sequence.
@@ -1707,7 +1708,7 @@ pub trait StrSlice<'a> {
     /// ```rust
     /// assert_eq!("bors".as_bytes(), b"bors");
     /// ```
-    fn as_bytes(&self) -> &'a [u8];
+    fn as_bytes<'a>(&'a self) -> &'a [u8];
 
     /// Returns the byte index of the first character of `self` that
     /// matches `search`.
@@ -1798,7 +1799,7 @@ pub trait StrSlice<'a> {
     /// assert_eq!(c, Some('ö'));
     /// assert_eq!(s2, "we 老虎 Léopard");
     /// ```
-    fn slice_shift_char(&self) -> (Option<char>, &'a str);
+    fn slice_shift_char<'a>(&'a self) -> (Option<char>, &'a str);
 
     /// Returns the byte offset of an inner slice relative to an enclosing outer slice.
     ///
@@ -1825,19 +1826,19 @@ pub trait StrSlice<'a> {
     fn as_ptr(&self) -> *const u8;
 
     /// Return an iterator of `u16` over the string encoded as UTF-16.
-    fn utf16_units(&self) -> Utf16CodeUnits<'a>;
+    fn utf16_units<'a>(&'a self) -> Utf16CodeUnits<'a>;
 }
 
 #[inline(never)]
 fn slice_error_fail(s: &str, begin: uint, end: uint) -> ! {
     assert!(begin <= end);
-    fail!("index {} and/or {} in `{}` do not lie on character boundary",
+    panic!("index {} and/or {} in `{}` do not lie on character boundary",
           begin, end, s);
 }
 
-impl<'a> StrSlice<'a> for &'a str {
+impl StrSlice for str {
     #[inline]
-    fn contains<'a>(&self, needle: &'a str) -> bool {
+    fn contains(&self, needle: &str) -> bool {
         self.find_str(needle).is_some()
     }
 
@@ -1847,24 +1848,24 @@ fn contains_char(&self, needle: char) -> bool {
     }
 
     #[inline]
-    fn chars(&self) -> Chars<'a> {
+    fn chars(&self) -> Chars {
         Chars{iter: self.as_bytes().iter()}
     }
 
     #[inline]
-    fn bytes(&self) -> Bytes<'a> {
+    fn bytes(&self) -> Bytes {
         self.as_bytes().iter().map(|&b| b)
     }
 
     #[inline]
-    fn char_indices(&self) -> CharOffsets<'a> {
+    fn char_indices(&self) -> CharOffsets {
         CharOffsets{front_offset: 0, iter: self.chars()}
     }
 
     #[inline]
-    fn split<Sep: CharEq>(&self, sep: Sep) -> CharSplits<'a, Sep> {
+    fn split<Sep: CharEq>(&self, sep: Sep) -> CharSplits<Sep> {
         CharSplits {
-            string: *self,
+            string: self,
             only_ascii: sep.only_ascii(),
             sep: sep,
             allow_trailing_empty: true,
@@ -1874,7 +1875,7 @@ fn split<Sep: CharEq>(&self, sep: Sep) -> CharSplits<'a, Sep> {
 
     #[inline]
     fn splitn<Sep: CharEq>(&self, count: uint, sep: Sep)
-        -> CharSplitsN<'a, Sep> {
+        -> CharSplitsN<Sep> {
         CharSplitsN {
             iter: self.split(sep),
             count: count,
@@ -1884,7 +1885,7 @@ fn splitn<Sep: CharEq>(&self, count: uint, sep: Sep)
 
     #[inline]
     fn split_terminator<Sep: CharEq>(&self, sep: Sep)
-        -> CharSplits<'a, Sep> {
+        -> CharSplits<Sep> {
         CharSplits {
             allow_trailing_empty: false,
             ..self.split(sep)
@@ -1893,7 +1894,7 @@ fn split_terminator<Sep: CharEq>(&self, sep: Sep)
 
     #[inline]
     fn rsplitn<Sep: CharEq>(&self, count: uint, sep: Sep)
-        -> CharSplitsN<'a, Sep> {
+        -> CharSplitsN<Sep> {
         CharSplitsN {
             iter: self.split(sep),
             count: count,
@@ -1902,17 +1903,17 @@ fn rsplitn<Sep: CharEq>(&self, count: uint, sep: Sep)
     }
 
     #[inline]
-    fn match_indices(&self, sep: &'a str) -> MatchIndices<'a> {
+    fn match_indices<'a>(&'a self, sep: &'a str) -> MatchIndices<'a> {
         assert!(!sep.is_empty())
         MatchIndices {
-            haystack: *self,
+            haystack: self,
             needle: sep,
             searcher: Searcher::new(self.as_bytes(), sep.as_bytes())
         }
     }
 
     #[inline]
-    fn split_str(&self, sep: &'a str) -> StrSplits<'a> {
+    fn split_str<'a>(&'a self, sep: &'a str) -> StrSplits<'a> {
         StrSplits {
             it: self.match_indices(sep),
             last_end: 0,
@@ -1921,11 +1922,11 @@ fn split_str(&self, sep: &'a str) -> StrSplits<'a> {
     }
 
     #[inline]
-    fn lines(&self) -> CharSplits<'a, char> {
+    fn lines(&self) -> CharSplits<char> {
         self.split_terminator('\n')
     }
 
-    fn lines_any(&self) -> AnyLines<'a> {
+    fn lines_any(&self) -> AnyLines {
         self.lines().map(|line| {
             let l = line.len();
             if l > 0 && line.as_bytes()[l - 1] == b'\r' { line.slice(0, l - 1) }
@@ -1937,38 +1938,38 @@ fn lines_any(&self) -> AnyLines<'a> {
     fn char_len(&self) -> uint { self.chars().count() }
 
     #[inline]
-    fn slice(&self, begin: uint, end: uint) -> &'a str {
+    fn slice(&self, begin: uint, end: uint) -> &str {
         // is_char_boundary checks that the index is in [0, .len()]
         if begin <= end &&
            self.is_char_boundary(begin) &&
            self.is_char_boundary(end) {
-            unsafe { raw::slice_unchecked(*self, begin, end) }
+            unsafe { raw::slice_unchecked(self, begin, end) }
         } else {
-            slice_error_fail(*self, begin, end)
+            slice_error_fail(self, begin, end)
         }
     }
 
     #[inline]
-    fn slice_from(&self, begin: uint) -> &'a str {
+    fn slice_from(&self, begin: uint) -> &str {
         // is_char_boundary checks that the index is in [0, .len()]
         if self.is_char_boundary(begin) {
-            unsafe { raw::slice_unchecked(*self, begin, self.len()) }
+            unsafe { raw::slice_unchecked(self, begin, self.len()) }
         } else {
-            slice_error_fail(*self, begin, self.len())
+            slice_error_fail(self, begin, self.len())
         }
     }
 
     #[inline]
-    fn slice_to(&self, end: uint) -> &'a str {
+    fn slice_to(&self, end: uint) -> &str {
         // is_char_boundary checks that the index is in [0, .len()]
         if self.is_char_boundary(end) {
-            unsafe { raw::slice_unchecked(*self, 0, end) }
+            unsafe { raw::slice_unchecked(self, 0, end) }
         } else {
-            slice_error_fail(*self, 0, end)
+            slice_error_fail(self, 0, end)
         }
     }
 
-    fn slice_chars(&self, begin: uint, end: uint) -> &'a str {
+    fn slice_chars(&self, begin: uint, end: uint) -> &str {
         assert!(begin <= end);
         let mut count = 0;
         let mut begin_byte = None;
@@ -1985,14 +1986,14 @@ fn slice_chars(&self, begin: uint, end: uint) -> &'a str {
         if end_byte.is_none() && count == end { end_byte = Some(self.len()) }
 
         match (begin_byte, end_byte) {
-            (None, _) => fail!("slice_chars: `begin` is beyond end of string"),
-            (_, None) => fail!("slice_chars: `end` is beyond end of string"),
-            (Some(a), Some(b)) => unsafe { raw::slice_bytes(*self, a, b) }
+            (None, _) => panic!("slice_chars: `begin` is beyond end of string"),
+            (_, None) => panic!("slice_chars: `end` is beyond end of string"),
+            (Some(a), Some(b)) => unsafe { raw::slice_bytes(self, a, b) }
         }
     }
 
     #[inline]
-    fn starts_with<'a>(&self, needle: &'a str) -> bool {
+    fn starts_with(&self, needle: &str) -> bool {
         let n = needle.len();
         self.len() >= n && needle.as_bytes() == self.as_bytes()[..n]
     }
@@ -2004,10 +2005,10 @@ fn ends_with(&self, needle: &str) -> bool {
     }
 
     #[inline]
-    fn trim_chars<C: CharEq>(&self, mut to_trim: C) -> &'a str {
+    fn trim_chars<C: CharEq>(&self, mut to_trim: C) -> &str {
         let cur = match self.find(|c: char| !to_trim.matches(c)) {
             None => "",
-            Some(i) => unsafe { raw::slice_bytes(*self, i, self.len()) }
+            Some(i) => unsafe { raw::slice_bytes(self, i, self.len()) }
         };
         match cur.rfind(|c: char| !to_trim.matches(c)) {
             None => "",
@@ -2019,20 +2020,20 @@ fn trim_chars<C: CharEq>(&self, mut to_trim: C) -> &'a str {
     }
 
     #[inline]
-    fn trim_left_chars<C: CharEq>(&self, mut to_trim: C) -> &'a str {
+    fn trim_left_chars<C: CharEq>(&self, mut to_trim: C) -> &str {
         match self.find(|c: char| !to_trim.matches(c)) {
             None => "",
-            Some(first) => unsafe { raw::slice_bytes(*self, first, self.len()) }
+            Some(first) => unsafe { raw::slice_bytes(self, first, self.len()) }
         }
     }
 
     #[inline]
-    fn trim_right_chars<C: CharEq>(&self, mut to_trim: C) -> &'a str {
+    fn trim_right_chars<C: CharEq>(&self, mut to_trim: C) -> &str {
         match self.rfind(|c: char| !to_trim.matches(c)) {
             None => "",
             Some(last) => {
                 let next = self.char_range_at(last).next;
-                unsafe { raw::slice_bytes(*self, 0u, next) }
+                unsafe { raw::slice_bytes(self, 0u, next) }
             }
         }
     }
@@ -2066,7 +2067,7 @@ fn multibyte_char_range_at(s: &str, i: uint) -> CharRange {
             return CharRange {ch: unsafe { mem::transmute(val) }, next: i + w};
         }
 
-        return multibyte_char_range_at(*self, i);
+        return multibyte_char_range_at(self, i);
     }
 
     #[inline]
@@ -2097,7 +2098,7 @@ fn multibyte_char_range_at_reverse(s: &str, mut i: uint) -> CharRange {
             return CharRange {ch: unsafe { mem::transmute(val) }, next: i};
         }
 
-        return multibyte_char_range_at_reverse(*self, prev);
+        return multibyte_char_range_at_reverse(self, prev);
     }
 
     #[inline]
@@ -2111,8 +2112,8 @@ fn char_at_reverse(&self, i: uint) -> char {
     }
 
     #[inline]
-    fn as_bytes(&self) -> &'a [u8] {
-        unsafe { mem::transmute(*self) }
+    fn as_bytes(&self) -> &[u8] {
+        unsafe { mem::transmute(self) }
     }
 
     fn find<C: CharEq>(&self, mut search: C) -> Option<uint> {
@@ -2148,12 +2149,12 @@ fn find_str(&self, needle: &str) -> Option<uint> {
     }
 
     #[inline]
-    fn slice_shift_char(&self) -> (Option<char>, &'a str) {
+    fn slice_shift_char(&self) -> (Option<char>, &str) {
         if self.is_empty() {
-            return (None, *self);
+            return (None, self);
         } else {
             let CharRange {ch, next} = self.char_range_at(0u);
-            let next_s = unsafe { raw::slice_bytes(*self, next, self.len()) };
+            let next_s = unsafe { raw::slice_bytes(self, next, self.len()) };
             return (Some(ch), next_s);
         }
     }
@@ -2175,7 +2176,7 @@ fn as_ptr(&self) -> *const u8 {
     }
 
     #[inline]
-    fn utf16_units(&self) -> Utf16CodeUnits<'a> {
+    fn utf16_units(&self) -> Utf16CodeUnits {
         Utf16CodeUnits{ chars: self.chars(), extra: 0}
     }
 }
index 9656a6caba08c845d5037d32138609e8a7b16eb7..7c832e90ed96bac6bcf18e6aaa92ecbdcd577134 100644 (file)
@@ -56,12 +56,12 @@ fn any_downcast_ref() {
 
     match a.downcast_ref::<uint>() {
         Some(&5) => {}
-        x => fail!("Unexpected value {}", x)
+        x => panic!("Unexpected value {}", x)
     }
 
     match a.downcast_ref::<Test>() {
         None => {}
-        x => fail!("Unexpected value {}", x)
+        x => panic!("Unexpected value {}", x)
     }
 }
 
@@ -79,7 +79,7 @@ fn any_downcast_mut() {
             assert_eq!(*x, 5u);
             *x = 612;
         }
-        x => fail!("Unexpected value {}", x)
+        x => panic!("Unexpected value {}", x)
     }
 
     match b_r.downcast_mut::<uint>() {
@@ -87,27 +87,27 @@ fn any_downcast_mut() {
             assert_eq!(*x, 7u);
             *x = 413;
         }
-        x => fail!("Unexpected value {}", x)
+        x => panic!("Unexpected value {}", x)
     }
 
     match a_r.downcast_mut::<Test>() {
         None => (),
-        x => fail!("Unexpected value {}", x)
+        x => panic!("Unexpected value {}", x)
     }
 
     match b_r.downcast_mut::<Test>() {
         None => (),
-        x => fail!("Unexpected value {}", x)
+        x => panic!("Unexpected value {}", x)
     }
 
     match a_r.downcast_mut::<uint>() {
         Some(&612) => {}
-        x => fail!("Unexpected value {}", x)
+        x => panic!("Unexpected value {}", x)
     }
 
     match b_r.downcast_mut::<uint>() {
         Some(&413) => {}
-        x => fail!("Unexpected value {}", x)
+        x => panic!("Unexpected value {}", x)
     }
 }
 
index 5da004086d27f84dfe97922cba49f27c9911d976..032f5f7194117e8d8596075b1b8c18c4382a2d75 100644 (file)
@@ -35,7 +35,7 @@ fn test_fail() {
         &mut i, (),
         |i, ()| {
             *i = 10;
-            fail!();
+            panic!();
         },
         |i| {
             assert!(failing());
index 476a2b50fcc8130b5f746391440a0c4a9fb4ccd7..98db377b0d576aa46cc18b56ca7d9714f0620070 100644 (file)
@@ -373,7 +373,7 @@ fn test_all() {
     assert!(v.iter().all(|&x| x < 10));
     assert!(!v.iter().all(|&x| x % 2 == 0));
     assert!(!v.iter().all(|&x| x > 100));
-    assert!(v.slice_or_fail(&0, &0).iter().all(|_| fail!()));
+    assert!(v.slice_or_fail(&0, &0).iter().all(|_| panic!()));
 }
 
 #[test]
@@ -382,7 +382,7 @@ fn test_any() {
     assert!(v.iter().any(|&x| x < 10));
     assert!(v.iter().any(|&x| x % 2 == 0));
     assert!(!v.iter().any(|&x| x > 100));
-    assert!(!v.slice_or_fail(&0, &0).iter().any(|_| fail!()));
+    assert!(!v.slice_or_fail(&0, &0).iter().any(|_| panic!()));
 }
 
 #[test]
@@ -528,13 +528,13 @@ fn test_rposition() {
 
 #[test]
 #[should_fail]
-fn test_rposition_fail() {
+fn test_rposition_panic() {
     let v = [(box 0i, box 0i), (box 0i, box 0i),
              (box 0i, box 0i), (box 0i, box 0i)];
     let mut i = 0i;
     v.iter().rposition(|_elt| {
         if i == 2 {
-            fail!()
+            panic!()
         }
         i += 1;
         false
@@ -678,12 +678,12 @@ fn test_random_access_cycle() {
 fn test_double_ended_range() {
     assert!(range(11i, 14).rev().collect::<Vec<int>>() == vec![13i, 12, 11]);
     for _ in range(10i, 0).rev() {
-        fail!("unreachable");
+        panic!("unreachable");
     }
 
     assert!(range(11u, 14).rev().collect::<Vec<uint>>() == vec![13u, 12, 11]);
     for _ in range(10u, 0).rev() {
-        fail!("unreachable");
+        panic!("unreachable");
     }
 }
 
index 71e9270fe4b0cba6df22453a51f7f3533e51477e..18444fc424082d4d56e4a44dd109b089b0b3733c 100644 (file)
@@ -139,14 +139,14 @@ fn test_unwrap() {
 
 #[test]
 #[should_fail]
-fn test_unwrap_fail1() {
+fn test_unwrap_panic1() {
     let x: Option<int> = None;
     x.unwrap();
 }
 
 #[test]
 #[should_fail]
-fn test_unwrap_fail2() {
+fn test_unwrap_panic2() {
     let x: Option<String> = None;
     x.unwrap();
 }
@@ -233,7 +233,7 @@ fn test_collect() {
     assert!(v == None);
 
     // test that it does not take more elements than it needs
-    let mut functions = [|| Some(()), || None, || fail!()];
+    let mut functions = [|| Some(()), || None, || panic!()];
 
     let v: Option<Vec<()>> = functions.iter_mut().map(|f| (*f)()).collect();
 
index 1cb72bd9eac78b3cca4d5def36e2602a4fe928e8..92124e2f299cd9c730ac793a6e468ca3ef2e8311 100644 (file)
@@ -81,7 +81,7 @@ fn test_collect() {
     assert!(v == Err(2));
 
     // test that it does not take more elements than it needs
-    let mut functions = [|| Ok(()), || Err(1i), || fail!()];
+    let mut functions = [|| Ok(()), || Err(1i), || panic!()];
 
     let v: Result<Vec<()>, int> = functions.iter_mut().map(|f| (*f)()).collect();
     assert!(v == Err(1));
@@ -113,7 +113,7 @@ fn handler(msg: &'static str) -> int {
         if msg == "I got this." {
             50i
         } else {
-            fail!("BadBad")
+            panic!("BadBad")
         }
     }
 
@@ -126,12 +126,12 @@ fn handler(msg: &'static str) -> int {
 
 #[test]
 #[should_fail]
-pub fn test_unwrap_or_else_failure() {
+pub fn test_unwrap_or_else_panic() {
     fn handler(msg: &'static str) -> int {
         if msg == "I got this." {
             50i
         } else {
-            fail!("BadBad")
+            panic!("BadBad")
         }
     }
 
index a73f7ddf7f7edf1a26634b508a8c9a244f2a96a6..24b7802097409cedecb09e0a0f48d5a05b5e30a5 100644 (file)
@@ -61,7 +61,7 @@
 //!     ];
 //!     let matches = match getopts(args.tail(), opts) {
 //!         Ok(m) => { m }
-//!         Err(f) => { fail!(f.to_string()) }
+//!         Err(f) => { panic!(f.to_string()) }
 //!     };
 //!     if matches.opt_present("h") {
 //!         print_usage(program.as_slice(), opts);
@@ -243,7 +243,7 @@ pub fn long_to_short(&self) -> Opt {
         } = (*self).clone();
 
         match (short_name.len(), long_name.len()) {
-            (0,0) => fail!("this long-format option was given no name"),
+            (0,0) => panic!("this long-format option was given no name"),
             (0,_) => Opt {
                 name: Long((long_name)),
                 hasarg: hasarg,
@@ -269,7 +269,7 @@ pub fn long_to_short(&self) -> Opt {
                     }
                 )
             },
-            (_,_) => fail!("something is wrong with the long-form opt")
+            (_,_) => panic!("something is wrong with the long-form opt")
         }
     }
 }
@@ -278,7 +278,7 @@ impl Matches {
     fn opt_vals(&self, nm: &str) -> Vec<Optval> {
         match find_opt(self.opts.as_slice(), Name::from_str(nm)) {
             Some(id) => self.vals[id].clone(),
-            None => fail!("No option '{}' defined", nm)
+            None => panic!("No option '{}' defined", nm)
         }
     }
 
@@ -530,8 +530,10 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 /// Parse command line arguments according to the provided options.
 ///
 /// On success returns `Ok(Matches)`. Use methods such as `opt_present`
-/// `opt_str`, etc. to interrogate results.  Returns `Err(Fail_)` on
-/// failure: use the `Show` implementation of `Fail_` to display
+/// `opt_str`, etc. to interrogate results.
+/// # Failure
+///
+/// Returns `Err(Fail_)` on failure: use the `Show` implementation of `Fail_` to display
 /// information about it.
 pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
     let opts: Vec<Opt> = optgrps.iter().map(|x| x.long_to_short()).collect();
@@ -688,7 +690,7 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String {
                 row.push_str(short_name.as_slice());
                 row.push(' ');
             }
-            _ => fail!("the short name should only be 1 ascii char long"),
+            _ => panic!("the short name should only be 1 ascii char long"),
         }
 
         // long option
@@ -852,7 +854,7 @@ enum LengthLimit {
 
             (B, Cr, UnderLim) => { B }
             (B, Cr, OverLim)  if (i - last_start + 1) > lim
-                            => fail!("word starting with {} longer than limit!",
+                            => panic!("word starting with {} longer than limit!",
                                     ss.slice(last_start, i + 1)),
             (B, Cr, OverLim)  => {
                 *cont = it(ss.slice(slice_start, last_end));
@@ -951,7 +953,7 @@ fn test_reqopt() {
             assert!(m.opt_present("t"));
             assert_eq!(m.opt_str("t").unwrap(), "20".to_string());
           }
-          _ => { fail!("test_reqopt failed (long arg)"); }
+          _ => { panic!("test_reqopt failed (long arg)"); }
         }
         let short_args = vec!("-t".to_string(), "20".to_string());
         match getopts(short_args.as_slice(), opts.as_slice()) {
@@ -961,7 +963,7 @@ fn test_reqopt() {
             assert!((m.opt_present("t")));
             assert_eq!(m.opt_str("t").unwrap(), "20".to_string());
           }
-          _ => { fail!("test_reqopt failed (short arg)"); }
+          _ => { panic!("test_reqopt failed (short arg)"); }
         }
     }
 
@@ -972,7 +974,7 @@ fn test_reqopt_missing() {
         let rs = getopts(args.as_slice(), opts.as_slice());
         match rs {
           Err(f) => check_fail_type(f, OptionMissing_),
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -983,12 +985,12 @@ fn test_reqopt_no_arg() {
         let rs = getopts(long_args.as_slice(), opts.as_slice());
         match rs {
           Err(f) => check_fail_type(f, ArgumentMissing_),
-          _ => fail!()
+          _ => panic!()
         }
         let short_args = vec!("-t".to_string());
         match getopts(short_args.as_slice(), opts.as_slice()) {
           Err(f) => check_fail_type(f, ArgumentMissing_),
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -999,7 +1001,7 @@ fn test_reqopt_multi() {
         let rs = getopts(args.as_slice(), opts.as_slice());
         match rs {
           Err(f) => check_fail_type(f, OptionDuplicated_),
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1016,7 +1018,7 @@ fn test_optopt() {
             assert!((m.opt_present("t")));
             assert_eq!(m.opt_str("t").unwrap(), "20".to_string());
           }
-          _ => fail!()
+          _ => panic!()
         }
         let short_args = vec!("-t".to_string(), "20".to_string());
         match getopts(short_args.as_slice(), opts.as_slice()) {
@@ -1026,7 +1028,7 @@ fn test_optopt() {
             assert!((m.opt_present("t")));
             assert_eq!(m.opt_str("t").unwrap(), "20".to_string());
           }
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1040,7 +1042,7 @@ fn test_optopt_missing() {
             assert!(!m.opt_present("test"));
             assert!(!m.opt_present("t"));
           }
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1051,12 +1053,12 @@ fn test_optopt_no_arg() {
         let rs = getopts(long_args.as_slice(), opts.as_slice());
         match rs {
           Err(f) => check_fail_type(f, ArgumentMissing_),
-          _ => fail!()
+          _ => panic!()
         }
         let short_args = vec!("-t".to_string());
         match getopts(short_args.as_slice(), opts.as_slice()) {
           Err(f) => check_fail_type(f, ArgumentMissing_),
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1067,7 +1069,7 @@ fn test_optopt_multi() {
         let rs = getopts(args.as_slice(), opts.as_slice());
         match rs {
           Err(f) => check_fail_type(f, OptionDuplicated_),
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1082,7 +1084,7 @@ fn test_optflag() {
             assert!(m.opt_present("test"));
             assert!(m.opt_present("t"));
           }
-          _ => fail!()
+          _ => panic!()
         }
         let short_args = vec!("-t".to_string());
         match getopts(short_args.as_slice(), opts.as_slice()) {
@@ -1090,7 +1092,7 @@ fn test_optflag() {
             assert!(m.opt_present("test"));
             assert!(m.opt_present("t"));
           }
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1104,7 +1106,7 @@ fn test_optflag_missing() {
             assert!(!m.opt_present("test"));
             assert!(!m.opt_present("t"));
           }
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1117,7 +1119,7 @@ fn test_optflag_long_arg() {
           Err(f) => {
             check_fail_type(f, UnexpectedArgument_);
           }
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1128,7 +1130,7 @@ fn test_optflag_multi() {
         let rs = getopts(args.as_slice(), opts.as_slice());
         match rs {
           Err(f) => check_fail_type(f, OptionDuplicated_),
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1143,7 +1145,7 @@ fn test_optflag_short_arg() {
 
             assert!(m.free[0] == "20".to_string());
           }
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1157,7 +1159,7 @@ fn test_optflagmulti_short1() {
           Ok(ref m) => {
             assert_eq!(m.opt_count("v"), 1);
           }
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1170,7 +1172,7 @@ fn test_optflagmulti_short2a() {
           Ok(ref m) => {
             assert_eq!(m.opt_count("v"), 2);
           }
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1183,7 +1185,7 @@ fn test_optflagmulti_short2b() {
           Ok(ref m) => {
             assert_eq!(m.opt_count("v"), 2);
           }
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1196,7 +1198,7 @@ fn test_optflagmulti_long1() {
           Ok(ref m) => {
             assert_eq!(m.opt_count("verbose"), 1);
           }
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1209,7 +1211,7 @@ fn test_optflagmulti_long2() {
           Ok(ref m) => {
             assert_eq!(m.opt_count("verbose"), 2);
           }
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1224,7 +1226,7 @@ fn test_optflagmulti_mix() {
             assert_eq!(m.opt_count("verbose"), 4);
             assert_eq!(m.opt_count("v"), 4);
           }
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1241,7 +1243,7 @@ fn test_optmulti() {
             assert!((m.opt_present("t")));
             assert_eq!(m.opt_str("t").unwrap(), "20".to_string());
           }
-          _ => fail!()
+          _ => panic!()
         }
         let short_args = vec!("-t".to_string(), "20".to_string());
         match getopts(short_args.as_slice(), opts.as_slice()) {
@@ -1251,7 +1253,7 @@ fn test_optmulti() {
             assert!((m.opt_present("t")));
             assert_eq!(m.opt_str("t").unwrap(), "20".to_string());
           }
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1265,7 +1267,7 @@ fn test_optmulti_missing() {
             assert!(!m.opt_present("test"));
             assert!(!m.opt_present("t"));
           }
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1276,12 +1278,12 @@ fn test_optmulti_no_arg() {
         let rs = getopts(long_args.as_slice(), opts.as_slice());
         match rs {
           Err(f) => check_fail_type(f, ArgumentMissing_),
-          _ => fail!()
+          _ => panic!()
         }
         let short_args = vec!("-t".to_string());
         match getopts(short_args.as_slice(), opts.as_slice()) {
           Err(f) => check_fail_type(f, ArgumentMissing_),
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1300,7 +1302,7 @@ fn test_optmulti_multi() {
               assert!(pair[0] == "20".to_string());
               assert!(pair[1] == "30".to_string());
           }
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1311,12 +1313,12 @@ fn test_unrecognized_option() {
         let rs = getopts(long_args.as_slice(), opts.as_slice());
         match rs {
           Err(f) => check_fail_type(f, UnrecognizedOption_),
-          _ => fail!()
+          _ => panic!()
         }
         let short_args = vec!("-u".to_string());
         match getopts(short_args.as_slice(), opts.as_slice()) {
           Err(f) => check_fail_type(f, UnrecognizedOption_),
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1365,7 +1367,7 @@ fn test_combined() {
             assert!(pair[1] == "-60 70".to_string());
             assert!((!m.opt_present("notpresent")));
           }
-          _ => fail!()
+          _ => panic!()
         }
     }
 
@@ -1379,7 +1381,7 @@ fn test_multi() {
         let matches_single = &match getopts(args_single.as_slice(),
                                             opts.as_slice()) {
           result::Ok(m) => m,
-          result::Err(_) => fail!()
+          result::Err(_) => panic!()
         };
         assert!(matches_single.opts_present(["e".to_string()]));
         assert!(matches_single.opts_present(["encrypt".to_string(), "e".to_string()]));
@@ -1399,7 +1401,7 @@ fn test_multi() {
         let matches_both = &match getopts(args_both.as_slice(),
                                           opts.as_slice()) {
           result::Ok(m) => m,
-          result::Err(_) => fail!()
+          result::Err(_) => panic!()
         };
         assert!(matches_both.opts_present(["e".to_string()]));
         assert!(matches_both.opts_present(["encrypt".to_string()]));
@@ -1424,7 +1426,7 @@ fn test_nospace() {
                      optmulti("M", "", "something", "MMMM"));
         let matches = &match getopts(args.as_slice(), opts.as_slice()) {
           result::Ok(m) => m,
-          result::Err(_) => fail!()
+          result::Err(_) => panic!()
         };
         assert!(matches.opts_present(["L".to_string()]));
         assert_eq!(matches.opts_str(["L".to_string()]).unwrap(), "foo".to_string());
@@ -1440,7 +1442,7 @@ fn test_nospace_conflict() {
                      optflagmulti("v", "verbose", "Verbose"));
         let matches = &match getopts(args.as_slice(), opts.as_slice()) {
           result::Ok(m) => m,
-          result::Err(e) => fail!( "{}", e )
+          result::Err(e) => panic!( "{}", e )
         };
         assert!(matches.opts_present(["L".to_string()]));
         assert_eq!(matches.opts_str(["L".to_string()]).unwrap(), "verbose".to_string());
index b592ba477c2a16bfcdfafce0246306c305db35e4..b476f46833bdb04e8df531807b4f3826a228e3cf 100644 (file)
@@ -73,13 +73,13 @@ fn message(&mut self, message: Message) {
             RunRemote(i) => {
                 match self.remotes.iter_mut().find(|& &(id, _)| id == i) {
                     Some(&(_, ref mut f)) => f.call(),
-                    None => fail!("bad remote: {}", i),
+                    None => panic!("bad remote: {}", i),
                 }
             }
             RemoveRemote(i) => {
                 match self.remotes.iter().position(|&(id, _)| id == i) {
                     Some(i) => { self.remotes.remove(i).unwrap(); }
-                    None => fail!("bad remote: {}", i),
+                    None => panic!("bad remote: {}", i),
                 }
             }
         }
index a665d41aadf96531ec64a067366fb98358201547..2d3e85cc833f3460a4ebb4b5f30332ef4269dded 100644 (file)
@@ -102,14 +102,14 @@ pub fn swap(out_context: &mut Context, in_context: &Context) {
             // Right before we switch to the new context, set the new context's
             // stack limit in the OS-specified TLS slot. This also  means that
             // we cannot call any more rust functions after record_stack_bounds
-            // returns because they would all likely fail due to the limit being
+            // returns because they would all likely panic due to the limit being
             // invalid for the current task. Lucky for us `rust_swap_registers`
             // is a C function so we don't have to worry about that!
             match in_context.stack_bounds {
                 Some((lo, hi)) => stack::record_rust_managed_stack_bounds(lo, hi),
                 // If we're going back to one of the original contexts or
                 // something that's possibly not a "normal task", then reset
-                // the stack limit to 0 to make morestack never fail
+                // the stack limit to 0 to make morestack never panic
                 None => stack::record_rust_managed_stack_bounds(0, uint::MAX),
             }
             rust_swap_registers(out_regs, in_regs);
index 5435a6f74d38bc33ef54a42663b5a09e415b56e4..fcebfeac292987f4c12c24d3766a817daf0da1fa 100644 (file)
 //! drop(handle);
 //!
 //! // Required to shut down this scheduler pool.
-//! // The task will fail if `shutdown` is not called.
+//! // The task will panic if `shutdown` is not called.
 //! pool.shutdown();
 //! # }
 //! ```
@@ -511,7 +511,7 @@ fn decrement(&mut self) {
 impl Drop for SchedPool {
     fn drop(&mut self) {
         if self.threads.len() > 0 {
-            fail!("dropping a M:N scheduler pool that wasn't shut down");
+            panic!("dropping a M:N scheduler pool that wasn't shut down");
         }
     }
 }
index c465aad3e3b5be7f59cd350efbe62f26a672b25c..b1c2695ac7d276826e88774487925455a33becbb 100644 (file)
@@ -761,7 +761,7 @@ pub fn switch_running_tasks_and_then(self: Box<Scheduler>,
         // task-local lock around this block. The resumption of the task in
         // context switching will bounce on the lock, thereby waiting for this
         // block to finish, eliminating the race mentioned above.
-        // fail!("should never return!");
+        // panic!("should never return!");
         //
         // To actually maintain a handle to the lock, we use an unsafe pointer
         // to it, but we're guaranteed that the task won't exit until we've
@@ -806,7 +806,7 @@ pub fn terminate_current_task(mut self: Box<Scheduler>,
             coroutine.recycle(&mut sched.stack_pool);
             sched.task_state.decrement();
         });
-        fail!("should never return!");
+        panic!("should never return!");
     }
 
     pub fn run_task(self: Box<Scheduler>,
@@ -1054,7 +1054,7 @@ fn sched_id() -> uint {
                 task.put_runtime(green);
                 return ret;
             }
-            None => fail!()
+            None => panic!()
         }
     }
 
@@ -1202,8 +1202,8 @@ fn on_appropriate_sched() -> bool {
                     }))) => {
                         *id == sched_id
                     }
-                    TypeGreen(None) => { fail!("task without home"); }
-                    TypeSched => { fail!("expected green task"); }
+                    TypeGreen(None) => { panic!("task without home"); }
+                    TypeSched => { panic!("expected green task"); }
                 };
                 task.put();
                 ret
index 686a039d6d600758d9b348b95b1bac12e6d74892..6c33e7cc619fde8c5874783ae9e0e8b5b505f732 100644 (file)
@@ -67,23 +67,23 @@ fn reawaken(mut self: Box<SimpleTask>, mut to_wake: Box<Task>) {
         }
     }
 
-    // These functions are all unimplemented and fail as a result. This is on
+    // These functions are all unimplemented and panic as a result. This is on
     // purpose. A "simple task" is just that, a very simple task that can't
     // really do a whole lot. The only purpose of the task is to get us off our
     // feet and running.
-    fn yield_now(self: Box<SimpleTask>, _cur_task: Box<Task>) { fail!() }
-    fn maybe_yield(self: Box<SimpleTask>, _cur_task: Box<Task>) { fail!() }
+    fn yield_now(self: Box<SimpleTask>, _cur_task: Box<Task>) { panic!() }
+    fn maybe_yield(self: Box<SimpleTask>, _cur_task: Box<Task>) { panic!() }
     fn spawn_sibling(self: Box<SimpleTask>,
                      _cur_task: Box<Task>,
                      _opts: TaskOpts,
                      _f: proc():Send) {
-        fail!()
+        panic!()
     }
     fn local_io<'a>(&'a mut self) -> Option<rtio::LocalIo<'a>> { None }
-    fn stack_bounds(&self) -> (uint, uint) { fail!() }
-    fn stack_guard(&self) -> Option<uint> { fail!() }
+    fn stack_bounds(&self) -> (uint, uint) { panic!() }
+    fn stack_guard(&self) -> Option<uint> { panic!() }
     fn can_block(&self) -> bool { true }
-    fn wrap(self: Box<SimpleTask>) -> Box<Any+'static> { fail!() }
+    fn wrap(self: Box<SimpleTask>) -> Box<Any+'static> { panic!() }
 }
 
 pub fn task() -> Box<Task> {
index cccf0ec698779af0e0962f5b395e9464e36a7d5f..7d6c82cb0c325f9c64c9b6979419a9cc83e335c2 100644 (file)
@@ -24,7 +24,7 @@ pub struct Stack {
 // Try to use MAP_STACK on platforms that support it (it's what we're doing
 // anyway), but some platforms don't support it at all. For example, it appears
 // that there's a bug in freebsd that MAP_STACK implies MAP_FIXED (so it always
-// fails): http://lists.freebsd.org/pipermail/freebsd-bugs/2011-July/044840.html
+// panics): http://lists.freebsd.org/pipermail/freebsd-bugs/2011-July/044840.html
 //
 // DragonFly BSD also seems to suffer from the same problem. When MAP_STACK is
 // used, it returns the same `ptr` multiple times.
@@ -37,7 +37,7 @@ pub struct Stack {
 static STACK_FLAGS: libc::c_int = 0;
 
 impl Stack {
-    /// Allocate a new stack of `size`. If size = 0, this will fail. Use
+    /// Allocate a new stack of `size`. If size = 0, this will panic. Use
     /// `dummy_stack` if you want a zero-sized stack.
     pub fn new(size: uint) -> Stack {
         // Map in a stack. Eventually we might be able to handle stack
@@ -47,7 +47,7 @@ pub fn new(size: uint) -> Stack {
         let stack = match MemoryMap::new(size, [MapReadable, MapWritable,
                                          MapNonStandardFlags(STACK_FLAGS)]) {
             Ok(map) => map,
-            Err(e) => fail!("mmap for stack of size {} failed: {}", size, e)
+            Err(e) => panic!("mmap for stack of size {} failed: {}", size, e)
         };
 
         // Change the last page to be inaccessible. This is to provide safety;
@@ -55,7 +55,7 @@ pub fn new(size: uint) -> Stack {
         // page. It isn't guaranteed, but that's why FFI is unsafe. buf.data is
         // guaranteed to be aligned properly.
         if !protect_last_page(&stack) {
-            fail!("Could not memory-protect guard page. stack={}, errno={}",
+            panic!("Could not memory-protect guard page. stack={}, errno={}",
                   stack.data(), errno());
         }
 
index f151e00f56d567c1c2febab9f4929d31a988ed58..0c549fa66c10335752ea794950eab537384d6457 100644 (file)
@@ -443,7 +443,7 @@ fn spawn_sibling(mut self: Box<GreenTask>,
         self.put_task(cur_task);
 
         // First, set up a bomb which when it goes off will restore the local
-        // task unless its disarmed. This will allow us to gracefully fail from
+        // task unless its disarmed. This will allow us to gracefully panic from
         // inside of `configure` which allocates a new task.
         struct Bomb { inner: Option<Box<GreenTask>> }
         impl Drop for Bomb {
@@ -529,11 +529,11 @@ fn smoke() {
     }
 
     #[test]
-    fn smoke_fail() {
+    fn smoke_panic() {
         let (tx, rx) = channel::<int>();
         spawn_opts(TaskOpts::new(), proc() {
             let _tx = tx;
-            fail!()
+            panic!()
         });
         assert_eq!(rx.recv_opt(), Err(()));
     }
@@ -550,11 +550,11 @@ fn smoke_opts() {
     }
 
     #[test]
-    fn smoke_opts_fail() {
+    fn smoke_opts_panic() {
         let mut opts = TaskOpts::new();
         let (tx, rx) = channel();
         opts.on_exit = Some(proc(r) tx.send(r));
-        spawn_opts(opts, proc() { fail!() });
+        spawn_opts(opts, proc() { panic!() });
         assert!(rx.recv().is_err());
     }
 
@@ -597,7 +597,7 @@ fn spawn_inherits() {
                     Some(ops) => {
                         task.put_runtime(ops);
                     }
-                    None => fail!(),
+                    None => panic!(),
                 }
                 Local::put(task);
                 tx.send(());
index 9d5080522c26ea9bf3f27328c6740235d966f6d1..832f61d8d663d6cfaabd956e03f3a2710e8bbc61 100644 (file)
@@ -255,7 +255,7 @@ fn log(&mut self, record: &LogRecord) {
                        record.level,
                        record.module_path,
                        record.args) {
-            Err(e) => fail!("failed to log: {}", e),
+            Err(e) => panic!("failed to log: {}", e),
             Ok(()) => {}
         }
     }
@@ -263,9 +263,9 @@ fn log(&mut self, record: &LogRecord) {
 
 impl Drop for DefaultLogger {
     fn drop(&mut self) {
-        // FIXME(#12628): is failure the right thing to do?
+        // FIXME(#12628): is panicking the right thing to do?
         match self.handle.flush() {
-            Err(e) => fail!("failed to flush a logger: {}", e),
+            Err(e) => panic!("failed to flush a logger: {}", e),
             Ok(()) => {}
         }
     }
index 88f5061bbef1713f7d3c1456402b3e9e96f66aac..f616295c73d1b1aafbcf7e6b61b684ea97d6e4ef 100644 (file)
@@ -523,7 +523,7 @@ fn test_file_desc() {
                 assert_eq!(buf[2], 's' as u8);
                 assert_eq!(buf[3], 't' as u8);
             }
-            r => fail!("invalid read: {}", r)
+            r => panic!("invalid read: {}", r),
         }
 
         assert!(writer.inner_read(buf).is_err());
@@ -547,7 +547,7 @@ fn test_cfile() {
                     assert_eq!(buf[2], 's' as u8);
                     assert_eq!(buf[3], 't' as u8);
                 }
-                r => fail!("invalid read: {}", r)
+                r => panic!("invalid read: {}", r)
             }
         }
     }
index bc08ede39f7695ec80accd63bb11ea6c1a34b397..f764470f37d89051743484485c322383adb79875 100644 (file)
@@ -710,7 +710,7 @@ pub fn native_accept(&mut self) -> IoResult<UnixStream> {
         if new_handle == libc::INVALID_HANDLE_VALUE {
             let ret = Err(super::last_error());
             // If our disconnection fails, then there's not really a whole lot
-            // that we can do, so fail the task.
+            // that we can do, so panic
             let err = unsafe { libc::DisconnectNamedPipe(handle) };
             assert!(err != 0);
             return ret;
index d69042175f7ccbecd215edf3d5a58aa6f7c0c346..fed4a46b9df7fc8376e0bf6a44e0871fa337c84f 100644 (file)
@@ -600,7 +600,7 @@ unsafe fn set_cloexec(fd: c_int) {
                             handle: ptr::null_mut()
                         })
                     }
-                    Ok(..) => fail!("short read on the cloexec pipe"),
+                    Ok(..) => panic!("short read on the cloexec pipe"),
                 };
             }
             // And at this point we've reached a special time in the life of the
@@ -944,7 +944,7 @@ fn waitpid(pid: pid_t, deadline: u64) -> IoResult<rtio::ProcessExit> {
     let mut status = 0 as c_int;
     if deadline == 0 {
         return match retry(|| unsafe { c::waitpid(pid, &mut status, 0) }) {
-            -1 => fail!("unknown waitpid error: {}", super::last_error().code),
+            -1 => panic!("unknown waitpid error: {}", super::last_error().code),
             _ => Ok(translate_status(status)),
         }
     }
@@ -1069,7 +1069,7 @@ fn waitpid_helper(input: libc::c_int,
                     continue
                 }
 
-                n => fail!("error in select {} ({})", os::errno(), n),
+                n => panic!("error in select {} ({})", os::errno(), n),
             }
 
             // Process any pending messages
@@ -1149,7 +1149,7 @@ fn drain(fd: libc::c_int) -> bool {
                 n if n > 0 => { ret = true; }
                 0 => return true,
                 -1 if util::wouldblock() => return ret,
-                n => fail!("bad read {} ({})", os::last_os_error(), n),
+                n => panic!("bad read {} ({})", os::last_os_error(), n),
             }
         }
     }
@@ -1172,7 +1172,7 @@ fn drain(fd: libc::c_int) -> bool {
         } {
             1 => {}
             -1 if util::wouldblock() => {} // see above comments
-            n => fail!("bad error on write fd: {} {}", n, os::errno()),
+            n => panic!("bad error on write fd: {} {}", n, os::errno()),
         }
     }
 }
@@ -1192,7 +1192,7 @@ fn waitpid_os(pid: pid_t) -> Option<rtio::ProcessExit> {
         }) {
             n if n == pid => Some(translate_status(status)),
             0 => None,
-            n => fail!("unknown waitpid error `{}`: {}", n,
+            n => panic!("unknown waitpid error `{}`: {}", n,
                        super::last_error().code),
         }
     }
index 6f57a5e88ba14f1c337cd0a9a26417b18d31cdea..38895f2a8f96a90b56061600e70a3f6a142af893 100644 (file)
@@ -194,7 +194,7 @@ fn signal(active: &mut Vec<Box<Inner>>,
             }
 
             -1 if os::errno() == libc::EINTR as int => {}
-            n => fail!("helper thread failed in select() with error: {} ({})",
+            n => panic!("helper thread panicked in select() with error: {} ({})",
                        n, os::last_os_error())
         }
     }
@@ -227,7 +227,7 @@ pub fn sleep(ms: u64) {
         };
         while unsafe { libc::nanosleep(&to_sleep, &mut to_sleep) } != 0 {
             if os::errno() as int != libc::EINTR as int {
-                fail!("failed to sleep, but not because of EINTR?");
+                panic!("failed to sleep, but not because of EINTR?");
             }
         }
     }
index c99143f0a5d7b05d844f011ea5510c35dafb26a8..4da088cccb334e6955f9c2a2d580736fc5cef285 100644 (file)
@@ -142,7 +142,7 @@ pub fn start(argc: int, argv: *const *const u8, main: proc()) -> int {
         exit_code = Some(run(main.take().unwrap()));
     }).destroy());
     unsafe { rt::cleanup(); }
-    // If the exit code wasn't set, then the task block must have failed.
+    // If the exit code wasn't set, then the task block must have panicked.
     return exit_code.unwrap_or(rt::DEFAULT_ERROR_CODE);
 }
 
index 455656c09d493279a45975b40c99c53e6771f094..e702c12bdffe384cf2e7e5d38bc920c4334a152d 100644 (file)
@@ -297,11 +297,11 @@ fn smoke() {
     }
 
     #[test]
-    fn smoke_fail() {
+    fn smoke_panic() {
         let (tx, rx) = channel::<()>();
         spawn(proc() {
             let _tx = tx;
-            fail!()
+            panic!()
         });
         assert_eq!(rx.recv_opt(), Err(()));
     }
@@ -318,11 +318,11 @@ fn smoke_opts() {
     }
 
     #[test]
-    fn smoke_opts_fail() {
+    fn smoke_opts_panic() {
         let mut opts = TaskOpts::new();
         let (tx, rx) = channel();
         opts.on_exit = Some(proc(r) tx.send(r));
-        NativeSpawner.spawn(opts, proc() { fail!() });
+        NativeSpawner.spawn(opts, proc() { panic!() });
         assert!(rx.recv().is_err());
     }
 
@@ -365,7 +365,7 @@ fn spawn_inherits() {
                     Some(ops) => {
                         task.put_runtime(ops);
                     }
-                    None => fail!(),
+                    None => panic!(),
                 }
                 Local::put(task);
                 tx.send(());
index 83d03bb265e95f87208eb333b91963d4f1099662..97e68bcbb2c6ca52d0c316b8e6cebc199152f7c6 100644 (file)
@@ -173,7 +173,7 @@ impl<'a> SeedableRng<&'a [u32]> for ChaChaRng {
     fn reseed(&mut self, seed: &'a [u32]) {
         // reset state
         self.init(&[0u32, ..KEY_WORDS]);
-        // set key inplace
+        // set key in place
         let key = self.state.slice_mut(4, 4+KEY_WORDS);
         for (k, s) in key.iter_mut().zip(seed.iter()) {
             *k = *s;
index 89c8e90f2c38b35afb285b5b201af80b214934ca..06bd04814c00b4784069f3a5abf5a5c15e8c960d 100644 (file)
@@ -129,7 +129,7 @@ pub fn new<'a>(items: &'a mut [Weighted<T>]) -> WeightedChoice<'a, T> {
         for item in items.iter_mut() {
             running_total = match running_total.checked_add(&item.weight) {
                 Some(n) => n,
-                None => fail!("WeightedChoice::new called with a total weight \
+                None => panic!("WeightedChoice::new called with a total weight \
                                larger than a uint can contain")
             };
 
index ebaa0349f5b72a221823a8b092aecc2117224ffa..405b70492a3aa4c9a0f722ca1a03cdb05aa75d17 100644 (file)
@@ -92,7 +92,7 @@ fn next_u64(&mut self) -> u64 {
     /// not be relied upon.
     ///
     /// This method should guarantee that `dest` is entirely filled
-    /// with new data, and may fail if this is impossible
+    /// with new data, and may panic if this is impossible
     /// (e.g. reading past the end of a file that is being used as the
     /// source of randomness).
     ///
@@ -375,7 +375,7 @@ fn next_u32(&mut self) -> u32 {
 }
 
 impl SeedableRng<[u32, .. 4]> for XorShiftRng {
-    /// Reseed an XorShiftRng. This will fail if `seed` is entirely 0.
+    /// Reseed an XorShiftRng. This will panic if `seed` is entirely 0.
     fn reseed(&mut self, seed: [u32, .. 4]) {
         assert!(!seed.iter().all(|&x| x == 0),
                 "XorShiftRng.reseed called with an all zero seed.");
@@ -386,7 +386,7 @@ fn reseed(&mut self, seed: [u32, .. 4]) {
         self.w = seed[3];
     }
 
-    /// Create a new XorShiftRng. This will fail if `seed` is entirely 0.
+    /// Create a new XorShiftRng. This will panic if `seed` is entirely 0.
     fn from_seed(seed: [u32, .. 4]) -> XorShiftRng {
         assert!(!seed.iter().all(|&x| x == 0),
                 "XorShiftRng::from_seed called with an all zero seed.");
@@ -446,7 +446,7 @@ fn rand<R: Rng>(rng: &mut R) -> XorShiftRng {
 
 #[cfg(not(test))]
 mod std {
-    pub use core::{option, fmt}; // fail!()
+    pub use core::{option, fmt}; // panic!()
 }
 
 #[cfg(test)]
index 07474a9f105876b259de3128ee1fdcd59b367741..3410a8745b1f4a481dd705f0f38bc9893d59e74d 100644 (file)
@@ -244,7 +244,7 @@ pub fn get_doc<'a>(d: Doc<'a>, tg: uint) -> Doc<'a> {
             Some(d) => d,
             None => {
                 error!("failed to find block with tag {}", tg);
-                fail!();
+                panic!();
             }
         }
     }
index a32dfcf5d2a2b89121332272a8ab45c81cb3a323..53d2ea62a2ad060e4617ee87d8c22561fb539776 100644 (file)
@@ -240,13 +240,13 @@ fn empty_split(&mut self) -> InstIdx {
     /// Sets the left and right locations of a `Split` instruction at index
     /// `i` to `pc1` and `pc2`, respectively.
     /// If the instruction at index `i` isn't a `Split` instruction, then
-    /// `fail!` is called.
+    /// `panic!` is called.
     #[inline]
     fn set_split(&mut self, i: InstIdx, pc1: InstIdx, pc2: InstIdx) {
         let split = self.insts.get_mut(i);
         match *split {
             Split(_, _) => *split = Split(pc1, pc2),
-            _ => fail!("BUG: Invalid split index."),
+            _ => panic!("BUG: Invalid split index."),
         }
     }
 
@@ -260,13 +260,13 @@ fn empty_jump(&mut self) -> InstIdx {
 
     /// Sets the location of a `Jump` instruction at index `i` to `pc`.
     /// If the instruction at index `i` isn't a `Jump` instruction, then
-    /// `fail!` is called.
+    /// `panic!` is called.
     #[inline]
     fn set_jump(&mut self, i: InstIdx, pc: InstIdx) {
         let jmp = self.insts.get_mut(i);
         match *jmp {
             Jump(_) => *jmp = Jump(pc),
-            _ => fail!("BUG: Invalid jump index."),
+            _ => panic!("BUG: Invalid jump index."),
         }
     }
 }
index bb6df26dab4f5ddf4b349a860ce87f4207771388..691dd2a3a6ced434fb2f101c32b03213434241c7 100644 (file)
@@ -31,7 +31,7 @@
 //! use regex::Regex;
 //! let re = match Regex::new(r"^\d{4}-\d{2}-\d{2}$") {
 //!     Ok(re) => re,
-//!     Err(err) => fail!("{}", err),
+//!     Err(err) => panic!("{}", err),
 //! };
 //! assert_eq!(re.is_match("2014-01-01"), true);
 //! ```
index 1d1d1a0e9c5cab3668f09052cdff7d8187d392aa..d71cc9cb511ffed3bb94915e0781765f7543ef73 100644 (file)
@@ -117,7 +117,7 @@ fn paren(&self) -> bool {
     fn flags(&self) -> Flags {
         match *self {
             Paren(flags, _, _) => flags,
-            _ => fail!("Cannot get flags from {}", self),
+            _ => panic!("Cannot get flags from {}", self),
         }
     }
 
@@ -125,7 +125,7 @@ fn capture(&self) -> Option<uint> {
         match *self {
             Paren(_, 0, _) => None,
             Paren(_, c, _) => Some(c),
-            _ => fail!("Cannot get capture group from {}", self),
+            _ => panic!("Cannot get capture group from {}", self),
         }
     }
 
@@ -139,7 +139,7 @@ fn capture_name(&self) -> Option<String> {
                     Some(name.clone())
                 }
             }
-            _ => fail!("Cannot get capture name from {}", self),
+            _ => panic!("Cannot get capture name from {}", self),
         }
     }
 
@@ -153,7 +153,7 @@ fn bar(&self) -> bool {
     fn unwrap(self) -> Result<Ast, Error> {
         match self {
             Expr(x) => Ok(x),
-            _ => fail!("Tried to unwrap non-AST item: {}", self),
+            _ => panic!("Tried to unwrap non-AST item: {}", self),
         }
     }
 }
@@ -321,7 +321,7 @@ fn push_repeater(&mut self, c: char) -> Result<(), Error> {
         }
         let rep: Repeater = match c {
             '?' => ZeroOne, '*' => ZeroMore, '+' => OneMore,
-            _ => fail!("Not a valid repeater operator."),
+            _ => panic!("Not a valid repeater operator."),
         };
 
         match self.peek(1) {
@@ -374,16 +374,12 @@ fn parse_class(&mut self) -> Result<(), Error> {
         let mut ranges: Vec<(char, char)> = vec!();
         let mut alts: Vec<Ast> = vec!();
 
-        if self.peek_is(1, ']') {
-            try!(self.expect(']'))
-            ranges.push((']', ']'))
-        }
         while self.peek_is(1, '-') {
-            try!(self.expect('-'))
+            try!(self.expect('-'));
             ranges.push(('-', '-'))
         }
         loop {
-            try!(self.noteof("a closing ']' or a non-empty character class)"))
+            try!(self.noteof("a closing ']' or a non-empty character class)"));
             let mut c = self.cur();
             match c {
                 '[' =>
@@ -393,7 +389,7 @@ fn parse_class(&mut self) -> Result<(), Error> {
                             continue
                         }
                         Some(ast) =>
-                            fail!("Expected Class AST but got '{}'", ast),
+                            panic!("Expected Class AST but got '{}'", ast),
                         // Just drop down and try to add as a regular character.
                         None => {},
                     },
@@ -408,13 +404,10 @@ fn parse_class(&mut self) -> Result<(), Error> {
                             return self.err(
                                 "\\A, \\z, \\b and \\B are not valid escape \
                                  sequences inside a character class."),
-                        ast => fail!("Unexpected AST item '{}'", ast),
+                        ast => panic!("Unexpected AST item '{}'", ast),
                     }
                 }
-                _ => {},
-            }
-            match c {
-                ']' => {
+                ']' if ranges.len() > 0 || alts.len() > 0 => {
                     if ranges.len() > 0 {
                         let flags = negated | (self.flags & FLAG_NOCASE);
                         let mut ast = AstClass(combine_ranges(ranges), flags);
@@ -431,22 +424,32 @@ fn parse_class(&mut self) -> Result<(), Error> {
                     }
                     return Ok(())
                 }
-                c => {
-                    if self.peek_is(1, '-') && !self.peek_is(2, ']') {
-                        try!(self.expect('-'))
-                        try!(self.noteof("not a ']'"))
-                        let c2 = self.cur();
-                        if c2 < c {
-                            return self.err(format!("Invalid character class \
-                                                     range '{}-{}'",
-                                                    c,
-                                                    c2).as_slice())
-                        }
-                        ranges.push((c, self.cur()))
-                    } else {
-                        ranges.push((c, c))
+                _ => {}
+            }
+
+            if self.peek_is(1, '-') && !self.peek_is(2, ']') {
+                try!(self.expect('-'));
+                // The regex can't end here.
+                try!(self.noteof("not a ']'"));
+                // End the range with a single character or character escape.
+                let mut c2 = self.cur();
+                if c2 == '\\' {
+                    match try!(self.parse_escape()) {
+                        Literal(c3, _) => c2 = c3, // allow literal escapes below
+                        ast =>
+                            return self.err(format!("Expected a literal, but got {}.",
+                                                    ast).as_slice()),
                     }
                 }
+                if c2 < c {
+                    return self.err(format!("Invalid character class \
+                                             range '{}-{}'",
+                                            c,
+                                            c2).as_slice())
+                }
+                ranges.push((c, self.cur()))
+            } else {
+                ranges.push((c, c))
             }
         }
     }
index eebe9b85e3b9daaf070898df0ef56cf5ec990b41..d352739f853e969615e8acacfa621a11f7c67810 100644 (file)
@@ -76,7 +76,7 @@ pub fn is_match(regex: &str, text: &str) -> Result<bool, parse::Error> {
 /// # use regex::Regex;
 /// let re = match Regex::new("[0-9]{3}-[0-9]{3}-[0-9]{4}") {
 ///     Ok(re) => re,
-///     Err(err) => fail!("{}", err),
+///     Err(err) => panic!("{}", err),
 /// };
 /// assert_eq!(re.find("phone: 111-222-3333"), Some((7, 19)));
 /// ```
index be8e12b09f020e757b1348512a789ddbbd76f22d..e1c24a902fa10deb19da5f74d735c638c99ebc54 100644 (file)
@@ -15,7 +15,7 @@
 use regex::{Regex, NoExpand};
 
 fn bench_assert_match(b: &mut Bencher, re: Regex, text: &str) {
-    b.iter(|| if !re.is_match(text) { fail!("no match") });
+    b.iter(|| if !re.is_match(text) { panic!("no match") });
 }
 
 #[bench]
@@ -143,7 +143,7 @@ macro_rules! throughput(
         fn $name(b: &mut Bencher) {
             let text = gen_text($size);
             b.bytes = $size;
-            b.iter(|| if $regex.is_match(text.as_slice()) { fail!("match") });
+            b.iter(|| if $regex.is_match(text.as_slice()) { panic!("match") });
         }
     );
 )
index 96c600b0fda3a4a50f0a5dc04345b1b604d322c1..7f014b4eb68a699817393a27e1c59d158b1dc7be 100644 (file)
@@ -30,7 +30,7 @@ macro_rules! regex(
     ($re:expr) => (
         match ::regex::Regex::new($re) {
             Ok(re) => re,
-            Err(err) => fail!("{}", err),
+            Err(err) => panic!("{}", err),
         }
     );
 )
index 088425c08885533916fb2b0abb8f735b93cf2cce..52a97703042f36407cab5e38bda4b66759681c0f 100644 (file)
@@ -43,6 +43,30 @@ fn empty_regex_nonempty_match() {
     assert_eq!(ms, vec![(0, 0), (1, 1), (2, 2), (3, 3)]);
 }
 
+#[test]
+fn quoted_bracket_set() {
+    let re = regex!(r"([\x{5b}\x{5d}])");
+    let ms = re.find_iter("[]").collect::<Vec<(uint, uint)>>();
+    assert_eq!(ms, vec![(0, 1), (1, 2)]);
+    let re = regex!(r"([\[\]])");
+    let ms = re.find_iter("[]").collect::<Vec<(uint, uint)>>();
+    assert_eq!(ms, vec![(0, 1), (1, 2)]);
+}
+
+#[test]
+fn first_range_starts_with_left_bracket() {
+    let re = regex!(r"([[-z])");
+    let ms = re.find_iter("[]").collect::<Vec<(uint, uint)>>();
+    assert_eq!(ms, vec![(0, 1), (1, 2)]);
+}
+
+#[test]
+fn range_ends_with_escape() {
+    let re = regex!(r"([\[-\x{5d}])");
+    let ms = re.find_iter("[]").collect::<Vec<(uint, uint)>>();
+    assert_eq!(ms, vec![(0, 1), (1, 2)]);
+}
+
 macro_rules! replace(
     ($name:ident, $which:ident, $re:expr,
      $search:expr, $replace:expr, $result:expr) => (
@@ -75,7 +99,7 @@ fn $name() {
             let re = $re;
             match Regex::new(re) {
                 Err(_) => {},
-                Ok(_) => fail!("Regex '{}' should cause a parse error.", re),
+                Ok(_) => panic!("Regex '{}' should cause a parse error.", re),
             }
         }
     );
@@ -114,6 +138,10 @@ fn $name() {
 noparse!(fail_neg_empty, "(?i-)")
 noparse!(fail_empty_group, "()")
 noparse!(fail_dupe_named, "(?P<a>.)(?P<a>.)")
+noparse!(fail_range_end_no_class, "[a-[:lower:]]")
+noparse!(fail_range_end_no_begin, r"[a-\A]")
+noparse!(fail_range_end_no_end, r"[a-\z]")
+noparse!(fail_range_end_no_boundary, r"[a-\b]")
 
 macro_rules! mat(
     ($name:ident, $re:expr, $text:expr, $($loc:tt)+) => (
@@ -133,7 +161,7 @@ fn $name() {
                 sgot = sgot[0..sexpect.len()]
             }
             if sexpect != sgot {
-                fail!("For RE '{}' against '{}', expected '{}' but got '{}'",
+                panic!("For RE '{}' against '{}', expected '{}' but got '{}'",
                       $re, text, sexpect, sgot);
             }
         }
index 04c0e7cc21fb1390b9862c796654b0797b1999b0..28b18ef0bf901f73066213ba1e3a1dfc300d282c 100644 (file)
@@ -634,7 +634,7 @@ fn parse(cx: &mut ExtCtxt, tts: &[ast::TokenTree]) -> Option<String> {
             return None
         }
     };
-    if !parser.eat(&token::EOF) {
+    if !parser.eat(&token::Eof) {
         cx.span_err(parser.span, "only one string literal allowed");
         return None;
     }
index f1cd8b52e5ed3103fa8e2b0a09c87dcecfdae0d0..1a53db89196b8fbdb7f79376f5006faa4476ecdb 100644 (file)
@@ -85,7 +85,7 @@ struct Diagnostic {
 
 // We use an Arc instead of just returning a list of diagnostics from the
 // child task because we need to make sure that the messages are seen even
-// if the child task fails (for example, when `fatal` is called).
+// if the child task panics (for example, when `fatal` is called).
 #[deriving(Clone)]
 struct SharedEmitter {
     buffer: Arc<Mutex<Vec<Diagnostic>>>,
@@ -133,7 +133,7 @@ fn emit(&mut self, cmsp: Option<(&codemap::CodeMap, codemap::Span)>,
 
     fn custom_emit(&mut self, _cm: &codemap::CodeMap,
                    _sp: diagnostic::RenderSpan, _msg: &str, _lvl: Level) {
-        fail!("SharedEmitter doesn't support custom_emit");
+        panic!("SharedEmitter doesn't support custom_emit");
     }
 }
 
@@ -714,7 +714,13 @@ pub fn run_passes(sess: &Session,
            .stdout(::std::io::process::InheritFd(1))
            .stderr(::std::io::process::InheritFd(2));
         match cmd.status() {
-            Ok(_) => {},
+            Ok(status) => {
+                if !status.success() {
+                    sess.err(format!("linking of {} with `{}` failed",
+                                     output_path.display(), cmd).as_slice());
+                    sess.abort_if_errors();
+                }
+            },
             Err(e) => {
                 sess.err(format!("could not exec the linker `{}`: {}",
                                  pname,
@@ -891,19 +897,19 @@ fn run_work_multithreaded(sess: &Session,
         futures.push(future);
     }
 
-    let mut failed = false;
+    let mut panicked = false;
     for future in futures.into_iter() {
         match future.unwrap() {
             Ok(()) => {},
             Err(_) => {
-                failed = true;
+                panicked = true;
             },
         }
         // Display any new diagnostics.
         diag_emitter.dump(sess.diagnostic().handler());
     }
-    if failed {
-        sess.fatal("aborting due to worker thread failure");
+    if panicked {
+        sess.fatal("aborting due to worker thread panic");
     }
 }
 
index 601a9a73c3d3aa67035021e54e92d579b8931dcd..c4e213790880f894c7269dd3190f03204e339326 100644 (file)
@@ -36,6 +36,7 @@
     E0015,
     E0016,
     E0017,
+    E0018,
     E0019,
     E0020,
     E0022,
@@ -52,7 +53,6 @@
     E0035,
     E0036,
     E0038,
-    E0039,
     E0040,
     E0044,
     E0045,
     E0162,
     E0163,
     E0164,
-    E0165
+    E0165,
+    E0166
 )
index d6798d59ecb3d90424016d6d29b4cbf7e10d924a..43687a31453d013a4fd4dd515620e24cf6703542 100644 (file)
@@ -780,20 +780,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         early_warn("the --crate-file-name argument has been renamed to \
                     --print-file-name");
     }
-
-    let mut cg = build_codegen_options(matches);
-
-    if cg.codegen_units == 0 {
-        match opt_level {
-            // `-C lto` doesn't work with multiple codegen units.
-            _ if cg.lto => cg.codegen_units = 1,
-
-            No | Less => cg.codegen_units = 2,
-            Default | Aggressive => cg.codegen_units = 1,
-        }
-    }
-    let cg = cg;
-
+    let cg = build_codegen_options(matches);
 
     if !cg.remark.is_empty() && debuginfo == NoDebugInfo {
         early_warn("-C remark will not show source locations without --debuginfo");
@@ -911,7 +898,7 @@ fn test_switch_implies_cfg_test() {
         let matches =
             &match getopts(["--test".to_string()], optgroups().as_slice()) {
               Ok(m) => m,
-              Err(f) => fail!("test_switch_implies_cfg_test: {}", f)
+              Err(f) => panic!("test_switch_implies_cfg_test: {}", f)
             };
         let registry = diagnostics::registry::Registry::new([]);
         let sessopts = build_session_options(matches);
@@ -929,7 +916,7 @@ fn test_switch_implies_cfg_test_unless_cfg_test() {
                            optgroups().as_slice()) {
               Ok(m) => m,
               Err(f) => {
-                fail!("test_switch_implies_cfg_test_unless_cfg_test: {}", f)
+                panic!("test_switch_implies_cfg_test_unless_cfg_test: {}", f)
               }
             };
         let registry = diagnostics::registry::Registry::new([]);
index 4a2e209f56282a26fc2929a6fd404612cd002175..fbdc0db166524df8a971c43f932d0b65b9be00d4 100644 (file)
@@ -269,7 +269,7 @@ fn sort_lint_groups(lints: Vec<(&'static str, Vec<lint::LintId>, bool)>)
             println!("Compiler plugins can provide additional lints and lint groups. To see a \
                       listing of these, re-run `rustc -W help` with a crate filename.");
         }
-        (false, _, _) => fail!("didn't load lint plugins but got them anyway!"),
+        (false, _, _) => panic!("didn't load lint plugins but got them anyway!"),
         (true, 0, 0) => println!("This crate does not load any lint plugins or lint groups."),
         (true, l, g) => {
             if l > 0 {
@@ -424,7 +424,7 @@ fn parse_crate_attrs(sess: &Session, input: &Input) ->
 pub fn early_error(msg: &str) -> ! {
     let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto, None);
     emitter.emit(None, msg, None, diagnostic::Fatal);
-    fail!(diagnostic::FatalError);
+    panic!(diagnostic::FatalError);
 }
 
 pub fn early_warn(msg: &str) {
@@ -466,7 +466,7 @@ pub fn monitor(f: proc():Send) {
     match task.try(f) {
         Ok(()) => { /* fallthrough */ }
         Err(value) => {
-            // Task failed without emitting a fatal diagnostic
+            // Task panicked without emitting a fatal diagnostic
             if !value.is::<diagnostic::FatalError>() {
                 let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto, None);
 
@@ -475,13 +475,13 @@ pub fn monitor(f: proc():Send) {
                 if !value.is::<diagnostic::ExplicitBug>() {
                     emitter.emit(
                         None,
-                        "unexpected failure",
+                        "unexpected panic",
                         None,
                         diagnostic::Bug);
                 }
 
                 let xs = [
-                    "the compiler hit an unexpected failure path. this is a bug.".to_string(),
+                    "the compiler unexpectedly panicked. this is a bug.".to_string(),
                     format!("we would appreciate a bug report: {}",
                             BUG_REPORT_URL),
                     "run with `RUST_BACKTRACE=1` for a backtrace".to_string(),
@@ -503,11 +503,11 @@ pub fn monitor(f: proc():Send) {
                 }
             }
 
-            // Fail so the process returns a failure code, but don't pollute the
+            // Panic so the process returns a failure code, but don't pollute the
             // output with some unnecessary failure messages, we've already
             // printed everything that we needed to.
             io::stdio::set_stderr(box io::util::NullWriter);
-            fail!();
+            panic!();
         }
     }
 }
index 19cd03f10a781738859532c4e84d1bd39e861f34..0a7cfdeeadc2abb63ebd81b3755312881e3dc9be 100644 (file)
@@ -444,7 +444,7 @@ pub fn pretty_print_input(sess: Session,
             let r = io::File::create(&p);
             match r {
                 Ok(w) => box w as Box<Writer+'static>,
-                Err(e) => fail!("print-print failed to open {} due to {}",
+                Err(e) => panic!("print-print failed to open {} due to {}",
                                 p.display(), e),
             }
         }
index 8c44adc55d288cd8f5c87e0a699c48885ea52c3a..35754fc584ffd02d6bf6db31a2a04bf0127b75a8 100644 (file)
@@ -190,7 +190,7 @@ fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
                                     return;
                                 }
                             }
-                            _ => fail!()
+                            _ => panic!()
                         };
                     },
                     ty::ty_uint(t) => {
@@ -201,7 +201,7 @@ fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
                         let lit_val: u64 = match lit.node {
                             ast::LitByte(_v) => return,  // _v is u8, within range by definition
                             ast::LitInt(v, _) => v,
-                            _ => fail!()
+                            _ => panic!()
                         };
                         if  lit_val < min || lit_val > max {
                             cx.span_lint(OVERFLOWING_LITERALS, e.span,
@@ -216,7 +216,7 @@ fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
                                 Some(f) => f,
                                 None => return
                             },
-                            _ => fail!()
+                            _ => panic!()
                         };
                         if lit_val < min || lit_val > max {
                             cx.span_lint(OVERFLOWING_LITERALS, e.span,
@@ -237,7 +237,7 @@ fn is_valid<T:cmp::PartialOrd>(binop: ast::BinOp, v: T,
                 ast::BiGt => v >= min && v <  max,
                 ast::BiGe => v >  min && v <= max,
                 ast::BiEq | ast::BiNe => v >= min && v <= max,
-                _ => fail!()
+                _ => panic!()
             }
         }
 
@@ -301,7 +301,7 @@ fn check_limits(tcx: &ty::ctxt, binop: ast::BinOp,
                             ast::LitInt(v, ast::UnsuffixedIntLit(ast::Minus)) => -(v as i64),
                             _ => return true
                         },
-                        _ => fail!()
+                        _ => panic!()
                     };
                     is_valid(norm_binop, lit_val, min, max)
                 }
@@ -312,7 +312,7 @@ fn check_limits(tcx: &ty::ctxt, binop: ast::BinOp,
                             ast::LitInt(v, _) => v,
                             _ => return true
                         },
-                        _ => fail!()
+                        _ => panic!()
                     };
                     is_valid(norm_binop, lit_val, min, max)
                 }
@@ -353,7 +353,7 @@ fn check_def(&mut self, sp: Span, ty_id: ast::NodeId, path_id: ast::NodeId) {
             def::DefTy(..) => {
                 let tty = match self.cx.tcx.ast_ty_to_ty_cache.borrow().find(&ty_id) {
                     Some(&ty::atttce_resolved(t)) => t,
-                    _ => fail!("ast_ty_to_ty_cache was incomplete after typeck!")
+                    _ => panic!("ast_ty_to_ty_cache was incomplete after typeck!")
                 };
 
                 if !ty::is_ffi_safe(self.cx.tcx, tty) {
@@ -683,7 +683,7 @@ fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
         let t = ty::expr_ty(cx.tcx, expr);
         let mut warned = false;
         match ty::get(t).sty {
-            ty::ty_nil | ty::ty_bot | ty::ty_bool => return,
+            ty::ty_nil | ty::ty_bool => return,
             ty::ty_struct(did, _) |
             ty::ty_enum(did, _) => {
                 if ast_util::is_local(did) {
index 4cdca9e536595e62138612239dda93b0384d88f7..8e4095df45a8fa5e9457f94a7bbc0e9d70507dae 100644 (file)
@@ -166,7 +166,7 @@ pub fn register_group(&mut self, sess: Option<&Session>,
     fn register_renamed(&mut self, old_name: &str, new_name: &str) {
         let target = match self.by_name.find_equiv(&new_name) {
             Some(&Id(lint_id)) => lint_id.clone(),
-            _ => fail!("invalid lint renaming of {} to {}", old_name, new_name)
+            _ => panic!("invalid lint renaming of {} to {}", old_name, new_name)
         };
         self.by_name.insert(old_name.to_string(), Renamed(new_name.to_string(), target));
     }
@@ -388,7 +388,7 @@ pub fn raw_emit_lint(sess: &Session, lint: &'static Lint,
             format!("{} [-{} {}]", msg,
                     match level {
                         Warn => 'W', Deny => 'D', Forbid => 'F',
-                        Allow => fail!()
+                        Allow => panic!()
                     }, name.replace("_", "-"))
         },
         Node(src) => {
index e2d997a93fe0410b980c68d67c51c71a9fb0bdfe..43d0156d72770f8e080341a783936ed7334ee1c1 100644 (file)
@@ -174,7 +174,7 @@ fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> {
 pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
     let err = |s: &str| {
         match (sp, sess) {
-            (_, None) => fail!("{}", s),
+            (_, None) => panic!("{}", s),
             (Some(sp), Some(sess)) => sess.span_err(sp, s),
             (None, Some(sess)) => sess.err(s),
         }
index fd71e4f7b1fbacfa430e10cf241e8ca46c64c495..e9e7d1de59db38bf4fe2b6acaaebf35bc535949d 100644 (file)
@@ -94,7 +94,7 @@ fn eq_item(bytes: &[u8], item_id: ast::NodeId) -> bool {
 
 fn find_item<'a>(item_id: ast::NodeId, items: rbml::Doc<'a>) -> rbml::Doc<'a> {
     match maybe_find_item(item_id, items) {
-       None => fail!("lookup_item: id not found: {}", item_id),
+       None => panic!("lookup_item: id not found: {}", item_id),
        Some(d) => d
     }
 }
@@ -153,7 +153,7 @@ fn item_family(item: rbml::Doc) -> Family {
       'S' => Struct,
       'g' => PublicField,
       'N' => InheritedField,
-       c => fail!("unexpected family char: {}", c)
+       c => panic!("unexpected family char: {}", c)
     }
 }
 
@@ -164,7 +164,7 @@ fn item_visibility(item: rbml::Doc) -> ast::Visibility {
             match reader::doc_as_u8(visibility_doc) as char {
                 'y' => ast::Public,
                 'i' => ast::Inherited,
-                _ => fail!("unknown visibility character")
+                _ => panic!("unknown visibility character")
             }
         }
     }
@@ -707,7 +707,7 @@ fn get_mutability(ch: u8) -> ast::Mutability {
         match ch as char {
             'i' => ast::MutImmutable,
             'm' => ast::MutMutable,
-            _ => fail!("unknown mutability character: `{}`", ch as char),
+            _ => panic!("unknown mutability character: `{}`", ch as char),
         }
     }
 
@@ -725,7 +725,7 @@ fn get_mutability(ch: u8) -> ast::Mutability {
                 ty::ReEmpty,
                 get_mutability(string.as_bytes()[1]))
         }
-        _ => fail!("unknown self type code: `{}`", explicit_self_kind as char)
+        _ => panic!("unknown self type code: `{}`", explicit_self_kind as char)
     }
 }
 
@@ -739,7 +739,7 @@ pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
         match item_sort(doc) {
             'r' | 'p' => impl_items.push(ty::MethodTraitItemId(def_id)),
             't' => impl_items.push(ty::TypeTraitItemId(def_id)),
-            _ => fail!("unknown impl item sort"),
+            _ => panic!("unknown impl item sort"),
         }
         true
     });
@@ -760,7 +760,7 @@ pub fn get_trait_item_name_and_kind(intr: Rc<IdentInterner>,
         }
         't' => (name, TypeTraitItemKind),
         c => {
-            fail!("get_trait_item_name_and_kind(): unknown trait item kind \
+            panic!("get_trait_item_name_and_kind(): unknown trait item kind \
                    in metadata: `{}`", c)
         }
     }
@@ -811,7 +811,7 @@ pub fn get_impl_or_trait_item(intr: Rc<IdentInterner>,
                 container: container,
             }))
         }
-        _ => fail!("unknown impl/trait item sort"),
+        _ => panic!("unknown impl/trait item sort"),
     }
 }
 
@@ -825,7 +825,7 @@ pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId)
         match item_sort(mth) {
             'r' | 'p' => result.push(ty::MethodTraitItemId(def_id)),
             't' => result.push(ty::TypeTraitItemId(def_id)),
-            _ => fail!("unknown trait item sort"),
+            _ => panic!("unknown trait item sort"),
         }
         true
     });
@@ -937,7 +937,7 @@ pub fn get_static_methods_if_impl(intr: Rc<IdentInterner>,
                 match item_family(impl_method_doc) {
                     StaticMethod => fn_style = ast::NormalFn,
                     UnsafeStaticMethod => fn_style = ast::UnsafeFn,
-                    _ => fail!()
+                    _ => panic!()
                 }
 
                 static_impl_methods.push(StaticMethodInfo {
@@ -998,7 +998,7 @@ fn struct_field_family_to_visibility(family: Family) -> ast::Visibility {
     match family {
       PublicField => ast::Public,
       InheritedField => ast::Inherited,
-      _ => fail!()
+      _ => panic!()
     }
 }
 
@@ -1207,7 +1207,7 @@ pub fn translate_def_id(cdata: Cmd, did: ast::DefId) -> ast::DefId {
                 node: did.node,
             }
         }
-        None => fail!("didn't find a crate in the cnum_map")
+        None => panic!("didn't find a crate in the cnum_map")
     }
 }
 
@@ -1314,7 +1314,7 @@ pub fn get_dylib_dependency_formats(cdata: Cmd)
         let cnum = from_str(cnum).unwrap();
         let cnum = match cdata.cnum_map.find(&cnum) {
             Some(&n) => n,
-            None => fail!("didn't find a crate in the cnum_map")
+            None => panic!("didn't find a crate in the cnum_map")
         };
         result.push((cnum, if link == "d" {
             cstore::RequireDynamic
index 34aa9310ef236e6f2ead31fa0536b121f8ad5d4f..98ce6942d4818e5fae8f6e6ec6e6d27d367af25c 100644 (file)
@@ -187,13 +187,13 @@ fn canonicalize(path: Option<Path>) -> Option<Path> {
         path.and_then(|path|
             match myfs::realpath(&path) {
                 Ok(canon) => Some(canon),
-                Err(e) => fail!("failed to get realpath: {}", e),
+                Err(e) => panic!("failed to get realpath: {}", e),
             })
     }
 
     match canonicalize(os::self_exe_name()) {
         Some(mut p) => { p.pop(); p.pop(); p }
-        None => fail!("can't determine value for sysroot")
+        None => panic!("can't determine value for sysroot")
     }
 }
 
index 0e57341a559ff6888d507a232207125e34965290..a52d02ccca77375e17c7a9840ebc63440d778a23 100644 (file)
@@ -260,7 +260,7 @@ fn parse_region_substs(st: &mut PState, conv: conv_did) -> subst::RegionSubsts {
                 parse_vec_per_param_space(
                     st, |st| parse_region(st, |x,y| conv(x,y))))
         }
-        _ => fail!("parse_bound_region: bad input")
+        _ => panic!("parse_bound_region: bad input")
     }
 }
 
@@ -282,7 +282,7 @@ fn parse_bound_region(st: &mut PState, conv: conv_did) -> ty::BoundRegion {
             ty::BrFresh(id)
         }
         'e' => ty::BrEnv,
-        _ => fail!("parse_bound_region: bad input")
+        _ => panic!("parse_bound_region: bad input")
     }
 }
 
@@ -327,7 +327,7 @@ fn parse_region(st: &mut PState, conv: conv_did) -> ty::Region {
       'e' => {
         ty::ReStatic
       }
-      _ => fail!("parse_region: bad input")
+      _ => panic!("parse_region: bad input")
     }
 }
 
@@ -335,7 +335,7 @@ fn parse_opt<T>(st: &mut PState, f: |&mut PState| -> T) -> Option<T> {
     match next(st) {
       'n' => None,
       's' => Some(f(st)),
-      _ => fail!("parse_opt: bad input")
+      _ => panic!("parse_opt: bad input")
     }
 }
 
@@ -359,7 +359,6 @@ fn parse_trait_ref(st: &mut PState, conv: conv_did) -> ty::TraitRef {
 fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
     match next(st) {
       'n' => return ty::mk_nil(),
-      'z' => return ty::mk_bot(),
       'b' => return ty::mk_bool(),
       'i' => return ty::mk_int(),
       'u' => return ty::mk_uint(),
@@ -375,7 +374,7 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
           'D' => return ty::mk_mach_int(ast::TyI64),
           'f' => return ty::mk_mach_float(ast::TyF32),
           'F' => return ty::mk_mach_float(ast::TyF64),
-          _ => fail!("parse_ty: bad numeric type")
+          _ => panic!("parse_ty: bad numeric type")
         }
       }
       'c' => return ty::mk_char(),
@@ -465,14 +464,17 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
           return ty::mk_struct(st.tcx, did, substs);
       }
       'k' => {
+          assert_eq!(next(st), '[');
           let did = parse_def(st, NominalType, |x,y| conv(x,y));
-          let region = parse_region(st, conv);
-          return ty::mk_unboxed_closure(st.tcx, did, region);
+          let region = parse_region(st, |x,y| conv(x,y));
+          let substs = parse_substs(st, |x,y| conv(x,y));
+          assert_eq!(next(st), ']');
+          return ty::mk_unboxed_closure(st.tcx, did, region, substs);
       }
       'e' => {
           return ty::mk_err();
       }
-      c => { fail!("unexpected char in type string: {}", c);}
+      c => { panic!("unexpected char in type string: {}", c);}
     }
 }
 
@@ -525,7 +527,7 @@ fn parse_fn_style(c: char) -> FnStyle {
     match c {
         'u' => UnsafeFn,
         'n' => NormalFn,
-        _ => fail!("parse_fn_style: bad fn_style {}", c)
+        _ => panic!("parse_fn_style: bad fn_style {}", c)
     }
 }
 
@@ -541,7 +543,7 @@ fn parse_onceness(c: char) -> ast::Onceness {
     match c {
         'o' => ast::Once,
         'm' => ast::Many,
-        _ => fail!("parse_onceness: bad onceness")
+        _ => panic!("parse_onceness: bad onceness")
     }
 }
 
@@ -585,12 +587,18 @@ fn parse_sig(st: &mut PState, conv: conv_did) -> ty::FnSig {
     let variadic = match next(st) {
         'V' => true,
         'N' => false,
-        r => fail!(format!("bad variadic: {}", r)),
+        r => panic!(format!("bad variadic: {}", r)),
+    };
+    let output = match peek(st) {
+        'z' => {
+          st.pos += 1u;
+          ty::FnDiverging
+        }
+        _ => ty::FnConverging(parse_ty(st, |x,y| conv(x,y)))
     };
-    let ret_ty = parse_ty(st, |x,y| conv(x,y));
     ty::FnSig {binder_id: id,
                inputs: inputs,
-               output: ret_ty,
+               output: output,
                variadic: variadic}
 }
 
@@ -601,7 +609,7 @@ pub fn parse_def_id(buf: &[u8]) -> ast::DefId {
     while colon_idx < len && buf[colon_idx] != ':' as u8 { colon_idx += 1u; }
     if colon_idx == len {
         error!("didn't find ':' when parsing def id");
-        fail!();
+        panic!();
     }
 
     let crate_part = buf[0u..colon_idx];
@@ -609,12 +617,12 @@ pub fn parse_def_id(buf: &[u8]) -> ast::DefId {
 
     let crate_num = match uint::parse_bytes(crate_part, 10u) {
        Some(cn) => cn as ast::CrateNum,
-       None => fail!("internal error: parse_def_id: crate number expected, found {}",
+       None => panic!("internal error: parse_def_id: crate number expected, found {}",
                      crate_part)
     };
     let def_num = match uint::parse_bytes(def_part, 10u) {
        Some(dn) => dn as ast::NodeId,
-       None => fail!("internal error: parse_def_id: id expected, found {}",
+       None => panic!("internal error: parse_def_id: id expected, found {}",
                      def_part)
     };
     ast::DefId { krate: crate_num, node: def_num }
@@ -680,7 +688,7 @@ fn parse_builtin_bounds(st: &mut PState, _conv: conv_did) -> ty::BuiltinBounds {
                 return builtin_bounds;
             }
             c => {
-                fail!("parse_bounds: bad builtin bounds ('{}')", c)
+                panic!("parse_bounds: bad builtin bounds ('{}')", c)
             }
         }
     }
@@ -706,7 +714,7 @@ fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds {
                 return param_bounds;
             }
             c => {
-                fail!("parse_bounds: bad bounds ('{}')", c)
+                panic!("parse_bounds: bad bounds ('{}')", c)
             }
         }
     }
index e11385654ccc04458b998e4df62a07ab8f2f6ddd..5fb1fec53400cfe2b47f3deae2e51dc92740f62e 100644 (file)
@@ -200,7 +200,6 @@ pub fn enc_trait_store(w: &mut SeekableMemWriter, cx: &ctxt, s: ty::TraitStore)
 fn enc_sty(w: &mut SeekableMemWriter, cx: &ctxt, st: &ty::sty) {
     match *st {
         ty::ty_nil => mywrite!(w, "n"),
-        ty::ty_bot => mywrite!(w, "z"),
         ty::ty_bool => mywrite!(w, "b"),
         ty::ty_char => mywrite!(w, "c"),
         ty::ty_int(t) => {
@@ -285,9 +284,11 @@ fn enc_sty(w: &mut SeekableMemWriter, cx: &ctxt, st: &ty::sty) {
             enc_substs(w, cx, substs);
             mywrite!(w, "]");
         }
-        ty::ty_unboxed_closure(def, region) => {
-            mywrite!(w, "k{}", (cx.ds)(def));
+        ty::ty_unboxed_closure(def, region, ref substs) => {
+            mywrite!(w, "k[{}|", (cx.ds)(def));
             enc_region(w, cx, region);
+            enc_substs(w, cx, substs);
+            mywrite!(w, "]");
         }
         ty::ty_err => {
             mywrite!(w, "e");
@@ -344,7 +345,14 @@ fn enc_fn_sig(w: &mut SeekableMemWriter, cx: &ctxt, fsig: &ty::FnSig) {
     } else {
         mywrite!(w, "N");
     }
-    enc_ty(w, cx, fsig.output);
+    match fsig.output {
+        ty::FnConverging(result_type) => {
+            enc_ty(w, cx, result_type);
+        }
+        ty::FnDiverging => {
+            mywrite!(w, "z");
+        }
+    }
 }
 
 pub fn enc_builtin_bounds(w: &mut SeekableMemWriter, _cx: &ctxt, bs: &ty::BuiltinBounds) {
index aa88de756552385cf1b3dcd0a3f237ca00ee3365..f6d85a8eb018f68ccb2c746aa997148b84adac7d 100644 (file)
@@ -341,7 +341,7 @@ fn fold_block(&mut self, blk: P<ast::Block>) -> P<ast::Block> {
                             ast::DeclItem(_) => false,
                         }
                     }
-                    ast::StmtMac(..) => fail!("unexpanded macro in astencode")
+                    ast::StmtMac(..) => panic!("unexpanded macro in astencode")
                 };
                 if use_stmt {
                     Some(stmt)
@@ -795,7 +795,7 @@ fn read_vtable_origin(&mut self,
                   3 => {
                     typeck::vtable_error
                   }
-                  _ => fail!("bad enum variant")
+                  _ => panic!("bad enum variant")
                 })
             })
         }).unwrap()
@@ -1488,7 +1488,7 @@ fn read_method_origin(&mut self, dcx: &DecodeContext)
                         }).unwrap()
                     }
 
-                    _ => fail!("..")
+                    _ => panic!("..")
                 })
             })
         }).unwrap()
@@ -1618,7 +1618,7 @@ fn read_auto_adjustment(&mut self, dcx: &DecodeContext) -> ty::AutoAdjustment {
 
                         ty::AdjustDerefRef(auto_deref_ref)
                     }
-                    _ => fail!("bad enum variant for ty::AutoAdjustment")
+                    _ => panic!("bad enum variant for ty::AutoAdjustment")
                 })
             })
         }).unwrap()
@@ -1695,7 +1695,7 @@ fn read_autoref(&mut self, dcx: &DecodeContext) -> ty::AutoRef {
 
                         ty::AutoUnsafe(m, a)
                     }
-                    _ => fail!("bad enum variant for ty::AutoRef")
+                    _ => panic!("bad enum variant for ty::AutoRef")
                 })
             })
         }).unwrap()
@@ -1736,7 +1736,7 @@ fn read_unsize_kind(&mut self, dcx: &DecodeContext) -> ty::UnsizeKind {
                                                      substs: substs };
                         ty::UnsizeVtable(ty_trait, self_ty)
                     }
-                    _ => fail!("bad enum variant for ty::UnsizeKind")
+                    _ => panic!("bad enum variant for ty::UnsizeKind")
                 })
             })
         }).unwrap()
@@ -1762,7 +1762,7 @@ fn read_unboxed_closure(&mut self, dcx: &DecodeContext)
                 0 => ty::FnUnboxedClosureKind,
                 1 => ty::FnMutUnboxedClosureKind,
                 2 => ty::FnOnceUnboxedClosureKind,
-                _ => fail!("bad enum variant for ty::UnboxedClosureKind"),
+                _ => panic!("bad enum variant for ty::UnboxedClosureKind"),
             })
         }).unwrap();
         ty::UnboxedClosure {
@@ -2032,6 +2032,6 @@ fn new_int_alist<B>() -> alist<int, B> {
         assert!(pprust::item_to_string(&*item_out) ==
                 pprust::item_to_string(&*item_exp));
       }
-      _ => fail!()
+      _ => panic!()
     }
 }
index f5e849f41967da8d5b28a4b37834a44901a9d8fd..de61f4f2b404c78a46b7defe3b9d719c2e572e9c 100644 (file)
@@ -777,13 +777,28 @@ fn check_assignment(&self,
         // Otherwise, just a plain error.
         match assignee_cmt.note {
             mc::NoteClosureEnv(upvar_id) => {
-                self.bccx.span_err(
-                    assignment_span,
-                    format!("cannot assign to {}",
-                            self.bccx.cmt_to_string(&*assignee_cmt)).as_slice());
-                self.bccx.span_note(
-                    self.tcx().map.span(upvar_id.closure_expr_id),
-                    "consider changing this closure to take self by mutable reference");
+                // If this is an `Fn` closure, it simply can't mutate upvars.
+                // If it's an `FnMut` closure, the original variable was declared immutable.
+                // We need to determine which is the case here.
+                let kind = match assignee_cmt.upvar().unwrap().cat {
+                    mc::cat_upvar(mc::Upvar { kind, .. }) => kind,
+                    _ => unreachable!()
+                };
+                if kind == ty::FnUnboxedClosureKind {
+                    self.bccx.span_err(
+                        assignment_span,
+                        format!("cannot assign to {}",
+                                self.bccx.cmt_to_string(&*assignee_cmt)).as_slice());
+                    self.bccx.span_note(
+                        self.tcx().map.span(upvar_id.closure_expr_id),
+                        "consider changing this closure to take self by mutable reference");
+                } else {
+                    self.bccx.span_err(
+                        assignment_span,
+                        format!("cannot assign to {} {}",
+                                assignee_cmt.mutbl.to_user_str(),
+                                self.bccx.cmt_to_string(&*assignee_cmt)).as_slice());
+                }
             }
             _ => match opt_loan_path(&assignee_cmt) {
                 Some(lp) => {
@@ -825,12 +840,20 @@ fn mark_variable_as_used_mut(this: &CheckLoanCtxt,
                     mc::cat_rvalue(..) |
                     mc::cat_static_item |
                     mc::cat_deref(_, _, mc::UnsafePtr(..)) |
-                    mc::cat_deref(_, _, mc::BorrowedPtr(..)) |
                     mc::cat_deref(_, _, mc::Implicit(..)) => {
                         assert_eq!(cmt.mutbl, mc::McDeclared);
                         return;
                     }
 
+                    mc::cat_deref(_, _, mc::BorrowedPtr(..)) => {
+                        assert_eq!(cmt.mutbl, mc::McDeclared);
+                        // We need to drill down to upvar if applicable
+                        match cmt.upvar() {
+                            Some(b) => cmt = b,
+                            None => return
+                        }
+                    }
+
                     mc::cat_deref(b, _, mc::OwnedPtr) => {
                         assert_eq!(cmt.mutbl, mc::McInherited);
                         cmt = b;
index 887c6bc3e3fdfb48c34e3424fe5bb43c4f368b84..9d4d9fcf9a9d74714975ff7848e028c5940d06d7 100644 (file)
@@ -133,10 +133,10 @@ fn report_cannot_move_out_of(bccx: &BorrowckCtxt, move_from: mc::cmt) {
                                  which defines the `Drop` trait",
                                 b.ty.user_string(bccx.tcx)).as_slice());
                 },
-                _ => fail!("this path should not cause illegal move")
+                _ => panic!("this path should not cause illegal move")
             }
         }
-        _ => fail!("this path should not cause illegal move")
+        _ => panic!("this path should not cause illegal move")
     }
 }
 
index 4620b8b00f470cb6a425a73120ec38bc0d693a2c..ae8e975e843b00e4ca50f7ae1c64503775256003 100644 (file)
@@ -284,9 +284,9 @@ pub fn closure_to_block(closure_id: ast::NodeId,
             ast::ExprProc(_, ref block) |
             ast::ExprFnBlock(_, _, ref block) |
             ast::ExprUnboxedFn(_, _, _, ref block) => { block.id }
-            _ => fail!("encountered non-closure id: {}", closure_id)
+            _ => panic!("encountered non-closure id: {}", closure_id)
         },
-        _ => fail!("encountered non-expr id: {}", closure_id)
+        _ => panic!("encountered non-expr id: {}", closure_id)
     }
 }
 
@@ -625,7 +625,7 @@ pub fn bckerr_to_string(&self, err: &BckError) -> String {
         match err.code {
             err_mutbl => {
                 let descr = match err.cmt.note {
-                    mc::NoteClosureEnv(_) => {
+                    mc::NoteClosureEnv(_) | mc::NoteUpvarRef(_) => {
                         self.cmt_to_string(&*err.cmt)
                     }
                     _ => match opt_loan_path(&err.cmt) {
@@ -761,11 +761,20 @@ pub fn note_and_explain_bckerr(&self, err: BckError) {
         match code {
             err_mutbl(..) => {
                 match err.cmt.note {
-                    mc::NoteClosureEnv(upvar_id) => {
-                        self.tcx.sess.span_note(
-                            self.tcx.map.span(upvar_id.closure_expr_id),
-                            "consider changing this closure to take \
-                             self by mutable reference");
+                    mc::NoteClosureEnv(upvar_id) | mc::NoteUpvarRef(upvar_id) => {
+                        // If this is an `Fn` closure, it simply can't mutate upvars.
+                        // If it's an `FnMut` closure, the original variable was declared immutable.
+                        // We need to determine which is the case here.
+                        let kind = match err.cmt.upvar().unwrap().cat {
+                            mc::cat_upvar(mc::Upvar { kind, .. }) => kind,
+                            _ => unreachable!()
+                        };
+                        if kind == ty::FnUnboxedClosureKind {
+                            self.tcx.sess.span_note(
+                                self.tcx.map.span(upvar_id.closure_expr_id),
+                                "consider changing this closure to take \
+                                 self by mutable reference");
+                        }
                     }
                     _ => {}
                 }
index f63dafe861e10197ae5932783809e0bb744e29a8..146891825d6846a2b01dc2b7206efea5e4a9c9de 100644 (file)
@@ -511,12 +511,15 @@ fn call<'a, I: Iterator<&'a ast::Expr>>(&mut self,
             pred: CFGIndex,
             func_or_rcvr: &ast::Expr,
             args: I) -> CFGIndex {
+        let method_call = typeck::MethodCall::expr(call_expr.id);
+        let return_ty = ty::ty_fn_ret(match self.tcx.method_map.borrow().find(&method_call) {
+            Some(method) => method.ty,
+            None => ty::expr_ty(self.tcx, func_or_rcvr)
+        });
+
         let func_or_rcvr_exit = self.expr(func_or_rcvr, pred);
         let ret = self.straightline(call_expr, func_or_rcvr_exit, args);
-
-        let return_ty = ty::node_id_to_type(self.tcx, call_expr.id);
-        let fails = ty::type_is_bot(return_ty);
-        if fails {
+        if return_ty == ty::FnDiverging {
             self.add_node(ast::DUMMY_NODE_ID, [])
         } else {
             ret
index d6b9bbded4ff89e7050b85770ee1e1ad56302523..6cf1a93b40b7b85d52eeb276653c1d1ce019646a 100644 (file)
@@ -119,12 +119,18 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) -> bool {
             }
         }
         ExprLit(_) => (),
-        ExprCast(_, _) => {
-            let ety = ty::expr_ty(v.tcx, e);
-            if !ty::type_is_numeric(ety) && !ty::type_is_unsafe_ptr(ety) {
+        ExprCast(ref from, _) => {
+            let toty = ty::expr_ty(v.tcx, e);
+            let fromty = ty::expr_ty(v.tcx, &**from);
+            if !ty::type_is_numeric(toty) && !ty::type_is_unsafe_ptr(toty) {
                 span_err!(v.tcx.sess, e.span, E0012,
                           "can not cast to `{}` in a constant expression",
-                          ppaux::ty_to_string(v.tcx, ety));
+                          ppaux::ty_to_string(v.tcx, toty));
+            }
+            if ty::type_is_unsafe_ptr(fromty) && ty::type_is_numeric(toty) {
+                span_err!(v.tcx.sess, e.span, E0018,
+                          "can not cast a pointer to an integer in a constant \
+                           expression");
             }
         }
         ExprPath(ref pth) => {
index 315266dbc84060484da3386c122d58a96b3fb33e..fe38669ea6c29a89c5c19036def93c242238af88 100644 (file)
@@ -421,7 +421,7 @@ fn construct_witness(cx: &MatchCheckCtxt, ctor: &Constructor,
                         node: FieldPat {
                             ident: Ident::new(field.name),
                             pat: pat,
-                            is_shorthand: true,
+                            is_shorthand: false,
                         }
                     }).collect();
                 let has_more_fields = field_pats.len() < pats_len;
index 1f76d9dba263553e6d56a89caba63c793cece5fd..1c83bf199192039cf68e8f0aabce35441d177f7f 100644 (file)
@@ -99,7 +99,17 @@ fn visit_expr(&mut self, e: &ast::Expr) {
                     Some(&DefStatic(def_id, _)) |
                     Some(&DefConst(def_id)) if
                             ast_util::is_local(def_id) => {
-                        self.visit_item(&*self.ast_map.expect_item(def_id.node));
+                        match self.ast_map.get(def_id.node) {
+                          ast_map::NodeItem(item) =>
+                            self.visit_item(item),
+                          ast_map::NodeForeignItem(_) => {},
+                          _ => {
+                            self.sess.span_err(e.span,
+                              format!("expected item, found {}",
+                                      self.ast_map.node_to_string(def_id.node)).as_slice());
+                            return;
+                          },
+                        }
                     }
                     _ => ()
                 }
index 9e2f78edb77f0dca7c3d16d50ab8518432d276f4..3d6b319ac0d62077de387023795afbba87750727 100644 (file)
@@ -341,7 +341,7 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr) -> P<Pat> {
                 node: FieldPat {
                     ident: field.ident.node,
                     pat: const_expr_to_pat(tcx, &*field.expr),
-                    is_shorthand: true,
+                    is_shorthand: false,
                 },
             }).collect();
             PatStruct(path.clone(), field_pats, false)
index d5557dfeeff1a37463ab675f9e504a53dcc3f6b2..612c9a00bbef40ee0a4efe6b8e1c5aaee5d84743 100644 (file)
@@ -88,7 +88,7 @@ struct PropagationContext<'a, 'b: 'a, 'tcx: 'b, O: 'a> {
 fn to_cfgidx_or_die(id: ast::NodeId, index: &NodeMap<CFGIndex>) -> CFGIndex {
     let opt_cfgindex = index.find(&id).map(|&i|i);
     opt_cfgindex.unwrap_or_else(|| {
-        fail!("nodeid_to_index does not have entry for NodeId {}", id);
+        panic!("nodeid_to_index does not have entry for NodeId {}", id);
     })
 }
 
index 3facf0b0c0a49220e4db51565b6a13ef9b67cbda..f88269ccac947fedc3583f299966cb6582837f11 100644 (file)
@@ -74,7 +74,7 @@ pub fn def_id(&self) -> ast::DefId {
                 local_def(id)
             }
 
-            DefPrimTy(_) => fail!()
+            DefPrimTy(_) => panic!()
         }
     }
 
index ee9dc05c0e7612a5efb68e314344234ac2da567b..e8a85b89b58474d5d1373dd65cd761b858cd1f30 100644 (file)
@@ -396,13 +396,9 @@ pub fn walk_expr(&mut self, expr: &ast::Expr) {
                 // make sure that the thing we are pointing out stays valid
                 // for the lifetime `scope_r` of the resulting ptr:
                 let expr_ty = ty::expr_ty(self.tcx(), expr);
-                if !ty::type_is_bot(expr_ty) {
-                    let r = ty::ty_region(self.tcx(), expr.span, expr_ty);
-                    let bk = ty::BorrowKind::from_mutbl(m);
-                    self.borrow_expr(&**base, r, bk, AddrOf);
-                } else {
-                    self.walk_expr(&**base);
-                }
+                let r = ty::ty_region(self.tcx(), expr.span, expr_ty);
+                let bk = ty::BorrowKind::from_mutbl(m);
+                self.borrow_expr(&**base, r, bk, AddrOf);
             }
 
             ast::ExprInlineAsm(ref ia) => {
index d7707be58bb58b5aa93388f48a4d247f64f0608b..1dd823539b4c6216cf0b179085eb0ec3dd818398 100644 (file)
@@ -126,9 +126,10 @@ fn visit_expr(&mut self, expr: &ast::Expr) {
                         match ty::get(typ).sty {
                             ty_bare_fn(ref bare_fn_ty)
                                     if bare_fn_ty.abi == RustIntrinsic => {
-                                let from = bare_fn_ty.sig.inputs[0];
-                                let to = bare_fn_ty.sig.output;
-                                self.check_transmute(expr.span, from, to, expr.id);
+                                if let ty::FnConverging(to) = bare_fn_ty.sig.output {
+                                    let from = bare_fn_ty.sig.inputs[0];
+                                    self.check_transmute(expr.span, from, to, expr.id);
+                                }
                             }
                             _ => {
                                 self.tcx
index f2d1a5e1d927243d17a099a802286afc97ee7b21..08202897558fb69f13146d4e9cdbe1350cd248ec 100644 (file)
@@ -264,18 +264,18 @@ pub fn collect_language_items(krate: &ast::Crate,
 
     StrEqFnLangItem,                 "str_eq",                  str_eq_fn;
 
-    // A number of failure-related lang items. The `fail` item corresponds to
-    // divide-by-zero and various failure cases with `match`. The
-    // `fail_bounds_check` item is for indexing arrays.
+    // A number of panic-related lang items. The `panic` item corresponds to
+    // divide-by-zero and various panic cases with `match`. The
+    // `panic_bounds_check` item is for indexing arrays.
     //
     // The `begin_unwind` lang item has a predefined symbol name and is sort of
     // a "weak lang item" in the sense that a crate is not required to have it
     // defined to use it, but a final product is required to define it
     // somewhere. Additionally, there are restrictions on crates that use a weak
     // lang item, but do not have it defined.
-    FailFnLangItem,                  "fail",                    fail_fn;
-    FailBoundsCheckFnLangItem,       "fail_bounds_check",       fail_bounds_check_fn;
-    FailFmtLangItem,                 "fail_fmt",                fail_fmt;
+    PanicFnLangItem,                 "panic",                   panic_fn;
+    PanicBoundsCheckFnLangItem,      "panic_bounds_check",      panic_bounds_check_fn;
+    PanicFmtLangItem,                "panic_fmt",               panic_fmt;
 
     ExchangeMallocFnLangItem,        "exchange_malloc",         exchange_malloc_fn;
     ExchangeFreeFnLangItem,          "exchange_free",           exchange_free_fn;
index 63e9a80adc61aa3aad273224ad662c84a01e8a65..f9810120d211b6bbb6bd9d342f68454e890381da 100644 (file)
  * These are described in the `specials` struct:
  *
  * - `exit_ln`: a live node that is generated to represent every 'exit' from
- *   the function, whether it be by explicit return, fail, or other means.
+ *   the function, whether it be by explicit return, panic, or other means.
  *
  * - `fallthrough_ln`: a live node that represents a fallthrough
  *
  * - `no_ret_var`: a synthetic variable that is only 'read' from, the
  *   fallthrough node.  This allows us to detect functions where we fail
  *   to return explicitly.
+ * - `clean_exit_var`: a synthetic variable that is only 'read' from the
+ *   fallthrough node.  It is only live if the function could converge
+ *   via means other than an explicit `return` expression. That is, it is
+ *   only dead if the end of the function's block can never be reached.
+ *   It is the responsibility of typeck to ensure that there are no
+ *   `return` expressions in a function declared as diverging.
  */
 
 use middle::def::*;
 use middle::mem_categorization::Typer;
 use middle::pat_util;
+use middle::typeck;
 use middle::ty;
 use lint;
 use util::nodemap::NodeMap;
@@ -250,7 +257,8 @@ struct LocalInfo {
 enum VarKind {
     Arg(NodeId, Ident),
     Local(LocalInfo),
-    ImplicitRet
+    ImplicitRet,
+    CleanExit
 }
 
 struct IrMaps<'a, 'tcx: 'a> {
@@ -306,7 +314,7 @@ fn add_variable(&mut self, vk: VarKind) -> Variable {
             Local(LocalInfo { id: node_id, .. }) | Arg(node_id, _) => {
                 self.variable_map.insert(node_id, v);
             },
-            ImplicitRet => {}
+            ImplicitRet | CleanExit => {}
         }
 
         debug!("{} is {}", v.to_string(), vk);
@@ -331,7 +339,8 @@ fn variable_name(&self, var: Variable) -> String {
             Local(LocalInfo { ident: nm, .. }) | Arg(_, nm) => {
                 token::get_ident(nm).get().to_string()
             },
-            ImplicitRet => "<implicit-ret>".to_string()
+            ImplicitRet => "<implicit-ret>".to_string(),
+            CleanExit => "<clean-exit>".to_string()
         }
     }
 
@@ -391,13 +400,14 @@ fn visit_fn(ir: &mut IrMaps,
     visit::walk_fn(&mut fn_maps, fk, decl, body, sp);
 
     // Special nodes and variables:
-    // - exit_ln represents the end of the fn, either by return or fail
+    // - exit_ln represents the end of the fn, either by return or panic
     // - implicit_ret_var is a pseudo-variable that represents
     //   an implicit return
     let specials = Specials {
         exit_ln: fn_maps.add_live_node(ExitNode),
         fallthrough_ln: fn_maps.add_live_node(ExitNode),
-        no_ret_var: fn_maps.add_variable(ImplicitRet)
+        no_ret_var: fn_maps.add_variable(ImplicitRet),
+        clean_exit_var: fn_maps.add_variable(CleanExit)
     };
 
     // compute liveness
@@ -546,7 +556,8 @@ fn invalid_users() -> Users {
 struct Specials {
     exit_ln: LiveNode,
     fallthrough_ln: LiveNode,
-    no_ret_var: Variable
+    no_ret_var: Variable,
+    clean_exit_var: Variable
 }
 
 static ACC_READ: uint = 1u;
@@ -873,6 +884,7 @@ fn propagate_through_fn_block(&mut self, _: &FnDecl, blk: &Block)
         if blk.expr.is_none() {
             self.acc(s.fallthrough_ln, s.no_ret_var, ACC_READ)
         }
+        self.acc(s.fallthrough_ln, s.clean_exit_var, ACC_READ);
 
         self.propagate_through_block(blk, s.fallthrough_ln)
     }
@@ -943,9 +955,7 @@ fn propagate_through_opt_expr(&mut self,
                                   opt_expr: Option<&Expr>,
                                   succ: LiveNode)
                                   -> LiveNode {
-        opt_expr.iter().fold(succ, |succ, expr| {
-            self.propagate_through_expr(&**expr, succ)
-        })
+        opt_expr.map_or(succ, |expr| self.propagate_through_expr(expr, succ))
     }
 
     fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
@@ -1146,13 +1156,11 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
           }
 
           ExprCall(ref f, ref args) => {
-            // calling a fn with bot return type means that the fn
-            // will fail, and hence the successors can be ignored
-            let is_bot = !self.ir.tcx.is_method_call(expr.id) && {
+            let diverges = !self.ir.tcx.is_method_call(expr.id) && {
                 let t_ret = ty::ty_fn_ret(ty::expr_ty(self.ir.tcx, &**f));
-                ty::type_is_bot(t_ret)
+                t_ret == ty::FnDiverging
             };
-            let succ = if is_bot {
+            let succ = if diverges {
                 self.s.exit_ln
             } else {
                 succ
@@ -1162,11 +1170,14 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
           }
 
           ExprMethodCall(_, _, ref args) => {
-            // calling a method with bot return type means that the method
-            // will fail, and hence the successors can be ignored
-            let t_ret = ty::node_id_to_type(self.ir.tcx, expr.id);
-            let succ = if ty::type_is_bot(t_ret) {self.s.exit_ln}
-                       else {succ};
+            let method_call = typeck::MethodCall::expr(expr.id);
+            let method_ty = self.ir.tcx.method_map.borrow().find(&method_call).unwrap().ty;
+            let diverges = ty::ty_fn_ret(method_ty) == ty::FnDiverging;
+            let succ = if diverges {
+                self.s.exit_ln
+            } else {
+                succ
+            };
             self.propagate_through_exprs(args.as_slice(), succ)
           }
 
@@ -1507,50 +1518,68 @@ fn check_fn(_v: &Liveness,
 }
 
 impl<'a, 'tcx> Liveness<'a, 'tcx> {
+    fn fn_ret(&self, id: NodeId) -> ty::FnOutput {
+        let fn_ty = ty::node_id_to_type(self.ir.tcx, id);
+        match ty::get(fn_ty).sty {
+            ty::ty_unboxed_closure(closure_def_id, _, _) =>
+                self.ir.tcx.unboxed_closures()
+                    .borrow()
+                    .find(&closure_def_id)
+                    .unwrap()
+                    .closure_type
+                    .sig
+                    .output,
+            _ => ty::ty_fn_ret(fn_ty)
+        }
+    }
+
     fn check_ret(&self,
                  id: NodeId,
                  sp: Span,
                  _fk: FnKind,
                  entry_ln: LiveNode,
                  body: &Block) {
-        if self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() {
-            // if no_ret_var is live, then we fall off the end of the
-            // function without any kind of return expression:
-
-            let t_ret = ty::ty_fn_ret(ty::node_id_to_type(self.ir.tcx, id));
-            if ty::type_is_nil(t_ret) {
-                // for nil return types, it is ok to not return a value expl.
-            } else if ty::type_is_bot(t_ret) {
-                // for bot return types, not ok.  Function should fail.
-                self.ir.tcx.sess.span_err(
-                    sp, "some control paths may return");
-            } else {
-                let ends_with_stmt = match body.expr {
-                    None if body.stmts.len() > 0 =>
-                        match body.stmts.last().unwrap().node {
-                            StmtSemi(ref e, _) => {
-                                let t_stmt = ty::expr_ty(self.ir.tcx, &**e);
-                                ty::get(t_stmt).sty == ty::get(t_ret).sty
+        match self.fn_ret(id) {
+            ty::FnConverging(t_ret)
+                if self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() => {
+
+                if ty::type_is_nil(t_ret) {
+                    // for nil return types, it is ok to not return a value expl.
+                } else {
+                    let ends_with_stmt = match body.expr {
+                        None if body.stmts.len() > 0 =>
+                            match body.stmts.last().unwrap().node {
+                                StmtSemi(ref e, _) => {
+                                    let t_stmt = ty::expr_ty(self.ir.tcx, &**e);
+                                    ty::get(t_stmt).sty == ty::get(t_ret).sty
+                                },
+                                _ => false
                             },
-                            _ => false
-                        },
-                    _ => false
-                };
-                self.ir.tcx.sess.span_err(
-                    sp, "not all control paths return a value");
-                if ends_with_stmt {
-                    let last_stmt = body.stmts.last().unwrap();
-                    let original_span = original_sp(self.ir.tcx.sess.codemap(),
-                                                    last_stmt.span, sp);
-                    let span_semicolon = Span {
-                        lo: original_span.hi - BytePos(1),
-                        hi: original_span.hi,
-                        expn_id: original_span.expn_id
+                        _ => false
                     };
-                    self.ir.tcx.sess.span_note(
-                        span_semicolon, "consider removing this semicolon:");
+                    self.ir.tcx.sess.span_err(
+                        sp, "not all control paths return a value");
+                    if ends_with_stmt {
+                        let last_stmt = body.stmts.last().unwrap();
+                        let original_span = original_sp(self.ir.tcx.sess.codemap(),
+                                                        last_stmt.span, sp);
+                        let span_semicolon = Span {
+                            lo: original_span.hi - BytePos(1),
+                            hi: original_span.hi,
+                            expn_id: original_span.expn_id
+                        };
+                        self.ir.tcx.sess.span_note(
+                            span_semicolon, "consider removing this semicolon:");
+                    }
                 }
-           }
+            }
+            ty::FnDiverging
+                if self.live_on_entry(entry_ln, self.s.clean_exit_var).is_some() => {
+                    self.ir.tcx.sess.span_err(sp,
+                        "computation may converge in a function marked as diverging");
+                }
+
+            _ => {}
         }
     }
 
index 0cac3fcdba1a8e1e02f00f6f43bae2f769a18d3d..c0188cac259ced92a9509683844e371c9103305a 100644 (file)
@@ -485,7 +485,7 @@ pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> McResult<cmt> {
                 Some(method_ty) => {
                     // If this is an index implemented by a method call, then it will
                     // include an implicit deref of the result.
-                    let ret_ty = ty::ty_fn_ret(method_ty);
+                    let ret_ty = ty::ty_fn_ret(method_ty).unwrap();
                     Ok(self.cat_deref(expr,
                                       self.cat_rvalue_node(expr.id(),
                                                            expr.span(),
@@ -594,7 +594,7 @@ pub fn cat_def(&self,
                       };
                       self.cat_upvar(id, span, var_id, fn_node_id, kind, mode, false)
                   }
-                  ty::ty_unboxed_closure(closure_id, _) => {
+                  ty::ty_unboxed_closure(closure_id, _, _) => {
                       let unboxed_closures = self.typer.unboxed_closures().borrow();
                       let kind = (*unboxed_closures)[closure_id].kind;
                       let mode = self.typer.capture_mode(fn_node_id);
@@ -655,51 +655,54 @@ fn cat_upvar(&self,
         // FnOnce         | copied               | upvar -> &'up bk
         // old stack      | N/A                  | upvar -> &'env mut -> &'up bk
         // old proc/once  | copied               | N/A
+        let var_ty = if_ok!(self.node_ty(var_id));
+
         let upvar_id = ty::UpvarId { var_id: var_id,
                                      closure_expr_id: fn_node_id };
 
-        // Do we need to deref through an env reference?
-        let has_env_deref = kind != ty::FnOnceUnboxedClosureKind;
-
         // Mutability of original variable itself
         let var_mutbl = MutabilityCategory::from_local(self.tcx(), var_id);
 
-        // Mutability of environment dereference
-        let env_mutbl = match kind {
-            ty::FnOnceUnboxedClosureKind => var_mutbl,
-            ty::FnMutUnboxedClosureKind => McInherited,
-            ty::FnUnboxedClosureKind => McImmutable
+        // Construct information about env pointer dereference, if any
+        let mutbl = match kind {
+            ty::FnOnceUnboxedClosureKind => None, // None, env is by-value
+            ty::FnMutUnboxedClosureKind => match mode { // Depends on capture type
+                ast::CaptureByValue => Some(var_mutbl), // Mutable if the original var is
+                ast::CaptureByRef => Some(McDeclared) // Mutable regardless
+            },
+            ty::FnUnboxedClosureKind => Some(McImmutable) // Never mutable
         };
+        let env_info = mutbl.map(|env_mutbl| {
+            // Look up the node ID of the closure body so we can construct
+            // a free region within it
+            let fn_body_id = {
+                let fn_expr = match self.tcx().map.find(fn_node_id) {
+                    Some(ast_map::NodeExpr(e)) => e,
+                    _ => unreachable!()
+                };
 
-        // Look up the node ID of the closure body so we can construct
-        // a free region within it
-        let fn_body_id = {
-            let fn_expr = match self.tcx().map.find(fn_node_id) {
-                Some(ast_map::NodeExpr(e)) => e,
-                _ => unreachable!()
+                match fn_expr.node {
+                    ast::ExprFnBlock(_, _, ref body) |
+                    ast::ExprProc(_, ref body) |
+                    ast::ExprUnboxedFn(_, _, _, ref body) => body.id,
+                    _ => unreachable!()
+                }
             };
 
-            match fn_expr.node {
-                ast::ExprFnBlock(_, _, ref body) |
-                ast::ExprProc(_, ref body) |
-                ast::ExprUnboxedFn(_, _, _, ref body) => body.id,
-                _ => unreachable!()
-            }
-        };
+            // Region of environment pointer
+            let env_region = ty::ReFree(ty::FreeRegion {
+                scope_id: fn_body_id,
+                bound_region: ty::BrEnv
+            });
 
-        // Region of environment pointer
-        let env_region = ty::ReFree(ty::FreeRegion {
-            scope_id: fn_body_id,
-            bound_region: ty::BrEnv
-        });
-
-        let env_ptr = BorrowedPtr(if env_mutbl.is_mutable() {
-            ty::MutBorrow
-        } else {
-            ty::ImmBorrow
-        }, env_region);
+            let env_ptr = BorrowedPtr(if env_mutbl.is_mutable() {
+                ty::MutBorrow
+            } else {
+                ty::ImmBorrow
+            }, env_region);
 
-        let var_ty = if_ok!(self.node_ty(var_id));
+            (env_mutbl, env_ptr)
+        });
 
         // First, switch by capture mode
         Ok(match mode {
@@ -717,25 +720,27 @@ fn cat_upvar(&self,
                     note: NoteNone
                 };
 
-                if has_env_deref {
-                    // We need to add the env deref.  This means that
-                    // the above is actually immutable and has a ref
-                    // type.  However, nothing should actually look at
-                    // the type, so we can get away with stuffing a
-                    // `ty_err` in there instead of bothering to
-                    // construct a proper one.
-                    base.mutbl = McImmutable;
-                    base.ty = ty::mk_err();
-                    Rc::new(cmt_ {
-                        id: id,
-                        span: span,
-                        cat: cat_deref(Rc::new(base), 0, env_ptr),
-                        mutbl: env_mutbl,
-                        ty: var_ty,
-                        note: NoteClosureEnv(upvar_id)
-                    })
-                } else {
-                    Rc::new(base)
+                match env_info {
+                    Some((env_mutbl, env_ptr)) => {
+                        // We need to add the env deref.  This means
+                        // that the above is actually immutable and
+                        // has a ref type.  However, nothing should
+                        // actually look at the type, so we can get
+                        // away with stuffing a `ty_err` in there
+                        // instead of bothering to construct a proper
+                        // one.
+                        base.mutbl = McImmutable;
+                        base.ty = ty::mk_err();
+                        Rc::new(cmt_ {
+                            id: id,
+                            span: span,
+                            cat: cat_deref(Rc::new(base), 0, env_ptr),
+                            mutbl: env_mutbl,
+                            ty: var_ty,
+                            note: NoteClosureEnv(upvar_id)
+                        })
+                    }
+                    None => Rc::new(base)
                 }
             },
             ast::CaptureByRef => {
@@ -755,16 +760,18 @@ fn cat_upvar(&self,
                     note: NoteNone
                 };
 
-                // As in the by-value case, add env deref if needed
-                if has_env_deref {
-                    base = cmt_ {
-                        id: id,
-                        span: span,
-                        cat: cat_deref(Rc::new(base), 0, env_ptr),
-                        mutbl: env_mutbl,
-                        ty: ty::mk_err(),
-                        note: NoteClosureEnv(upvar_id)
-                    };
+                match env_info {
+                    Some((env_mutbl, env_ptr)) => {
+                        base = cmt_ {
+                            id: id,
+                            span: span,
+                            cat: cat_deref(Rc::new(base), 0, env_ptr),
+                            mutbl: env_mutbl,
+                            ty: ty::mk_err(),
+                            note: NoteClosureEnv(upvar_id)
+                        };
+                    }
+                    None => {}
                 }
 
                 // Look up upvar borrow so we can get its region
@@ -871,7 +878,7 @@ fn cat_deref<N:ast_node>(&self,
 
         let base_cmt = match method_ty {
             Some(method_ty) => {
-                let ref_ty = ty::ty_fn_ret(method_ty);
+                let ref_ty = ty::ty_fn_ret(method_ty).unwrap();
                 self.cat_rvalue_node(node.id(), node.span(), ref_ty)
             }
             None => base_cmt
@@ -950,7 +957,7 @@ pub fn cat_index<N:ast_node>(&self,
 
         let element_ty = match method_ty {
             Some(method_ty) => {
-                let ref_ty = ty::ty_fn_ret(method_ty);
+                let ref_ty = ty::ty_fn_ret(method_ty).unwrap();
                 base_cmt = self.cat_rvalue_node(elt.id(), elt.span(), ref_ty);
                 ty::ty_fn_args(method_ty)[0]
             }
index ad297309c088003885756fe16760c5b9fc0ddf34..32e373f5851c069cc678129e8ef297a4b307ab74 100644 (file)
@@ -157,7 +157,7 @@ pub fn encl_scope(&self, id: ast::NodeId) -> ast::NodeId {
         //! Returns the narrowest scope that encloses `id`, if any.
         match self.scope_map.borrow().find(&id) {
             Some(&r) => r,
-            None => { fail!("no enclosing scope for id {}", id); }
+            None => { panic!("no enclosing scope for id {}", id); }
         }
     }
 
@@ -167,7 +167,7 @@ pub fn var_scope(&self, var_id: ast::NodeId) -> ast::NodeId {
          */
         match self.var_map.borrow().find(&var_id) {
             Some(&r) => r,
-            None => { fail!("no enclosing scope for id {}", var_id); }
+            None => { panic!("no enclosing scope for id {}", var_id); }
         }
     }
 
index fad4ef4f15f6b2983d4aea9c1cc302855f39958e..7af4739d409156b3b6b1d6ec58f315758aee369e 100644 (file)
@@ -728,7 +728,7 @@ fn get_module_if_available(&self) -> Option<Rc<Module>> {
     fn get_module(&self) -> Rc<Module> {
         match self.get_module_if_available() {
             None => {
-                fail!("get_module called on a node with no module \
+                panic!("get_module called on a node with no module \
                        definition!")
             }
             Some(module_def) => module_def
@@ -1910,7 +1910,7 @@ fn handle_external_def(&mut self,
           DefLocal(..) | DefPrimTy(..) | DefTyParam(..) |
           DefUse(..) | DefUpvar(..) | DefRegion(..) |
           DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
-            fail!("didn't expect `{}`", def);
+            panic!("didn't expect `{}`", def);
           }
         }
     }
@@ -2618,7 +2618,7 @@ fn get_binding(this: &mut Resolver,
             }
             UnboundResult => { /* Continue. */ }
             UnknownResult => {
-                fail!("value result should be known at this point");
+                panic!("value result should be known at this point");
             }
         }
         match type_result {
@@ -2641,7 +2641,7 @@ fn get_binding(this: &mut Resolver,
             }
             UnboundResult => { /* Continue. */ }
             UnknownResult => {
-                fail!("type result should be known at this point");
+                panic!("type result should be known at this point");
             }
         }
 
@@ -5161,7 +5161,7 @@ fn resolve_bare_identifier_pattern(&mut self, name: Name, span: Span)
                         target.bindings.value_def.borrow());
                 match *target.bindings.value_def.borrow() {
                     None => {
-                        fail!("resolved name in the value namespace to a \
+                        panic!("resolved name in the value namespace to a \
                               set of name bindings with no def?!");
                     }
                     Some(def) => {
@@ -5191,7 +5191,7 @@ fn resolve_bare_identifier_pattern(&mut self, name: Name, span: Span)
             }
 
             Indeterminate => {
-                fail!("unexpected indeterminate result");
+                panic!("unexpected indeterminate result");
             }
             Failed(err) => {
                 match err {
@@ -5389,7 +5389,7 @@ fn resolve_module_relative_path(&mut self,
                                                  msg.as_slice()));
                 return None;
             }
-            Indeterminate => fail!("indeterminate unexpected"),
+            Indeterminate => panic!("indeterminate unexpected"),
             Success((resulting_module, resulting_last_private)) => {
                 containing_module = resulting_module;
                 last_private = resulting_last_private;
@@ -5451,7 +5451,7 @@ fn resolve_crate_relative_path(&mut self,
             }
 
             Indeterminate => {
-                fail!("indeterminate unexpected");
+                panic!("indeterminate unexpected");
             }
 
             Success((resulting_module, resulting_last_private)) => {
@@ -5537,7 +5537,7 @@ fn resolve_item_by_name_in_lexical_scope(&mut self,
                 }
             }
             Indeterminate => {
-                fail!("unexpected indeterminate result");
+                panic!("unexpected indeterminate result");
             }
             Failed(err) => {
                 match err {
@@ -6155,7 +6155,7 @@ fn finalize_import(&mut self, id: NodeId, span: Span) {
                 type_used: _
             }) => (v, t),
             Some(_) => {
-                fail!("we should only have LastImport for `use` directives")
+                panic!("we should only have LastImport for `use` directives")
             }
             _ => return,
         };
index 47c596f3474958a6e42293cee8cafece9e5e0b91..4748de01240cfb210a4b307009df6a01243bdea4 100644 (file)
@@ -428,7 +428,7 @@ fn process_struct_field_def(&mut self,
                 let qualname = format!("{}::{}", qualname, name);
                 let typ = ppaux::ty_to_string(&self.analysis.ty_cx,
                     (*self.analysis.ty_cx.node_types.borrow())[field.node.id as uint]);
-                match self.span.sub_span_before_token(field.span, token::COLON) {
+                match self.span.sub_span_before_token(field.span, token::Colon) {
                     Some(sub_span) => self.fmt.field_str(field.span,
                                                          Some(sub_span),
                                                          field.node.id,
@@ -1175,7 +1175,7 @@ fn visit_view_item(&mut self, i: &ast::ViewItem) {
                         // 'use' always introduces an alias, if there is not an explicit
                         // one, there is an implicit one.
                         let sub_span =
-                            match self.span.sub_span_before_token(path.span, token::EQ) {
+                            match self.span.sub_span_before_token(path.span, token::Eq) {
                                 Some(sub_span) => Some(sub_span),
                                 None => sub_span,
                             };
index 10832572ae255f33949b5105acd19805be1e5910..511d8aa5bace67bc0db2c35e342d0a7c84672451 100644 (file)
@@ -19,7 +19,7 @@
 use syntax::parse::lexer;
 use syntax::parse::lexer::{Reader,StringReader};
 use syntax::parse::token;
-use syntax::parse::token::{is_keyword,keywords,is_ident,Token};
+use syntax::parse::token::{keywords, Token};
 
 pub struct SpanUtils<'a> {
     pub sess: &'a Session,
@@ -93,18 +93,18 @@ pub fn span_for_last_ident(&self, span: Span) -> Option<Span> {
         let mut bracket_count = 0u;
         loop {
             let ts = toks.next_token();
-            if ts.tok == token::EOF {
+            if ts.tok == token::Eof {
                 return self.make_sub_span(span, result)
             }
             if bracket_count == 0 &&
-               (is_ident(&ts.tok) || is_keyword(keywords::Self, &ts.tok)) {
+               (ts.tok.is_ident() || ts.tok.is_keyword(keywords::Self)) {
                 result = Some(ts.sp);
             }
 
             bracket_count += match ts.tok {
-                token::LT => 1,
-                token::GT => -1,
-                token::BINOP(token::SHR) => -2,
+                token::Lt => 1,
+                token::Gt => -1,
+                token::BinOp(token::Shr) => -2,
                 _ => 0
             }
         }
@@ -116,18 +116,18 @@ pub fn span_for_first_ident(&self, span: Span) -> Option<Span> {
         let mut bracket_count = 0u;
         loop {
             let ts = toks.next_token();
-            if ts.tok == token::EOF {
+            if ts.tok == token::Eof {
                 return None;
             }
             if bracket_count == 0 &&
-               (is_ident(&ts.tok) || is_keyword(keywords::Self, &ts.tok)) {
+               (ts.tok.is_ident() || ts.tok.is_keyword(keywords::Self)) {
                 return self.make_sub_span(span, Some(ts.sp));
             }
 
             bracket_count += match ts.tok {
-                token::LT => 1,
-                token::GT => -1,
-                token::BINOP(token::SHR) => -2,
+                token::Lt => 1,
+                token::Gt => -1,
+                token::BinOp(token::Shr) => -2,
                 _ => 0
             }
         }
@@ -141,36 +141,36 @@ pub fn sub_span_for_meth_name(&self, span: Span) -> Option<Span> {
         let mut result = None;
         let mut bracket_count = 0u;
         let mut last_span = None;
-        while prev.tok != token::EOF {
+        while prev.tok != token::Eof {
             last_span = None;
             let mut next = toks.next_token();
 
-            if (next.tok == token::LPAREN ||
-                next.tok == token::LT) &&
+            if (next.tok == token::LParen ||
+                next.tok == token::Lt) &&
                bracket_count == 0 &&
-               is_ident(&prev.tok) {
+               prev.tok.is_ident() {
                 result = Some(prev.sp);
             }
 
             if bracket_count == 0 &&
-                next.tok == token::MOD_SEP {
+                next.tok == token::ModSep {
                 let old = prev;
                 prev = next;
                 next = toks.next_token();
-                if next.tok == token::LT &&
-                   is_ident(&old.tok) {
+                if next.tok == token::Lt &&
+                   old.tok.is_ident() {
                     result = Some(old.sp);
                 }
             }
 
             bracket_count += match prev.tok {
-                token::LPAREN | token::LT => 1,
-                token::RPAREN | token::GT => -1,
-                token::BINOP(token::SHR) => -2,
+                token::LParen | token::Lt => 1,
+                token::RParen | token::Gt => -1,
+                token::BinOp(token::Shr) => -2,
                 _ => 0
             };
 
-            if is_ident(&prev.tok) && bracket_count == 0 {
+            if prev.tok.is_ident() && bracket_count == 0 {
                 last_span = Some(prev.sp);
             }
             prev = next;
@@ -191,21 +191,21 @@ pub fn sub_span_for_type_name(&self, span: Span) -> Option<Span> {
         loop {
             let next = toks.next_token();
 
-            if (next.tok == token::LT ||
-                next.tok == token::COLON) &&
+            if (next.tok == token::Lt ||
+                next.tok == token::Colon) &&
                bracket_count == 0 &&
-               is_ident(&prev.tok) {
+               prev.tok.is_ident() {
                 result = Some(prev.sp);
             }
 
             bracket_count += match prev.tok {
-                token::LT => 1,
-                token::GT => -1,
-                token::BINOP(token::SHR) => -2,
+                token::Lt => 1,
+                token::Gt => -1,
+                token::BinOp(token::Shr) => -2,
                 _ => 0
             };
 
-            if next.tok == token::EOF {
+            if next.tok == token::Eof {
                 break;
             }
             prev = next;
@@ -216,7 +216,7 @@ pub fn sub_span_for_type_name(&self, span: Span) -> Option<Span> {
                 format!("Mis-counted brackets when breaking path? Parsing '{}' in {}, line {}",
                         self.snippet(span), loc.file.name, loc.line).as_slice());
         }
-        if result.is_none() && is_ident(&prev.tok) && bracket_count == 0 {
+        if result.is_none() && prev.tok.is_ident() && bracket_count == 0 {
             return self.make_sub_span(span, Some(prev.sp));
         }
         self.make_sub_span(span, result)
@@ -235,7 +235,7 @@ pub fn spans_with_brackets(&self, span: Span, nesting: int, limit: int) -> Vec<S
         let mut bracket_count = 0i;
         loop {
             let ts = toks.next_token();
-            if ts.tok == token::EOF {
+            if ts.tok == token::Eof {
                 if bracket_count != 0 {
                     let loc = self.sess.codemap().lookup_char_pos(span.lo);
                     self.sess.span_bug(span, format!(
@@ -248,13 +248,13 @@ pub fn spans_with_brackets(&self, span: Span, nesting: int, limit: int) -> Vec<S
                 return result;
             }
             bracket_count += match ts.tok {
-                token::LT => 1,
-                token::GT => -1,
-                token::BINOP(token::SHL) => 2,
-                token::BINOP(token::SHR) => -2,
+                token::Lt => 1,
+                token::Gt => -1,
+                token::BinOp(token::Shl) => 2,
+                token::BinOp(token::Shr) => -2,
                 _ => 0
             };
-            if is_ident(&ts.tok) &&
+            if ts.tok.is_ident() &&
                bracket_count == nesting {
                 result.push(self.make_sub_span(span, Some(ts.sp)).unwrap());
             }
@@ -265,7 +265,7 @@ pub fn sub_span_before_token(&self, span: Span, tok: Token) -> Option<Span> {
         let mut toks = self.retokenise_span(span);
         let mut prev = toks.next_token();
         loop {
-            if prev.tok == token::EOF {
+            if prev.tok == token::Eof {
                 return None;
             }
             let next = toks.next_token();
@@ -282,12 +282,12 @@ pub fn sub_span_after_keyword(&self,
         let mut toks = self.retokenise_span(span);
         loop {
             let ts = toks.next_token();
-            if ts.tok == token::EOF {
+            if ts.tok == token::Eof {
                 return None;
             }
-            if is_keyword(keyword, &ts.tok) {
+            if ts.tok.is_keyword(keyword) {
                 let ts = toks.next_token();
-                if ts.tok == token::EOF {
+                if ts.tok == token::Eof {
                     return None
                 } else {
                     return self.make_sub_span(span, Some(ts.sp));
index 237f4e950ceee42a301bb9735a407138e652172c..b986d4dd591f382c80198502dc3b925c90a382e2 100644 (file)
@@ -177,7 +177,7 @@ pub fn regions<'a>(&'a self) -> &'a VecPerParamSpace<ty::Region> {
          */
 
         match self.regions {
-            ErasedRegions => fail!("Erased regions only expected in trans"),
+            ErasedRegions => panic!("Erased regions only expected in trans"),
             NonerasedRegions(ref r) => r
         }
     }
@@ -190,7 +190,7 @@ pub fn mut_regions<'a>(&'a mut self) -> &'a mut VecPerParamSpace<ty::Region> {
          */
 
         match self.regions {
-            ErasedRegions => fail!("Erased regions only expected in trans"),
+            ErasedRegions => panic!("Erased regions only expected in trans"),
             NonerasedRegions(ref mut r) => r
         }
     }
@@ -249,7 +249,7 @@ pub fn from_uint(u: uint) -> ParamSpace {
             0 => TypeSpace,
             1 => SelfSpace,
             2 => FnSpace,
-            _ => fail!("Invalid ParamSpace: {}", u)
+            _ => panic!("Invalid ParamSpace: {}", u)
         }
     }
 }
index e045b9fd4f4a3a58ca523fb0f5780f974b3eb7af..8b2ddca3131971acb997194d5911956947e05ced 100644 (file)
@@ -80,7 +80,6 @@ pub fn ty_is_local(tcx: &ty::ctxt,
 
     match ty::get(ty).sty {
         ty::ty_nil |
-        ty::ty_bot |
         ty::ty_bool |
         ty::ty_char |
         ty::ty_int(..) |
index f24121d9a3a5f8b5521aac54c71adb64349757f6..c014bc0c164f206dce9b7c1180382c215b0d846f 100644 (file)
@@ -279,4 +279,132 @@ impl Bar<uint> for int { ... }
 type of the receiver and various other complications. The procedure is
 described in `select.rs` in the "METHOD MATCHING" section.
 
+# Caching and subtle considerations therewith
+
+In general we attempt to cache the results of trait selection.  This
+is a somewhat complex process. Part of the reason for this is that we
+want to be able to cache results even when all the types in the trait
+reference are not fully known. In that case, it may happen that the
+trait selection process is also influencing type variables, so we have
+to be able to not only cache the *result* of the selection process,
+but *replay* its effects on the type variables.
+
+## An example
+
+The high-level idea of how the cache works is that we first replace
+all unbound inference variables with skolemized versions. Therefore,
+if we had a trait reference `uint : Foo<$1>`, where `$n` is an unbound
+inference variable, we might replace it with `uint : Foo<%0>`, where
+`%n` is a skolemized type. We would then look this up in the cache.
+If we found a hit, the hit would tell us the immediate next step to
+take in the selection process: i.e., apply impl #22, or apply where
+clause `X : Foo<Y>`. Let's say in this case there is no hit.
+Therefore, we search through impls and where clauses and so forth, and
+we come to the conclusion that the only possible impl is this one,
+with def-id 22:
+
+    impl Foo<int> for uint { ... } // Impl #22
+
+We would then record in the cache `uint : Foo<%0> ==>
+ImplCandidate(22)`. Next we would confirm `ImplCandidate(22)`, which
+would (as a side-effect) unify `$1` with `int`.
+
+Now, at some later time, we might come along and see a `uint :
+Foo<$3>`.  When skolemized, this would yield `uint : Foo<%0>`, just as
+before, and hence the cache lookup would succeed, yielding
+`ImplCandidate(22)`. We would confirm `ImplCandidate(22)` which would
+(as a side-effect) unify `$3` with `int`.
+
+## Where clauses and the local vs global cache
+
+One subtle interaction is that the results of trait lookup will vary
+depending on what where clauses are in scope. Therefore, we actually
+have *two* caches, a local and a global cache. The local cache is
+attached to the `ParameterEnvironment` and the global cache attached
+to the `tcx`. We use the local cache whenever the result might depend
+on the where clauses that are in scope. The determination of which
+cache to use is done by the method `pick_candidate_cache` in
+`select.rs`.
+
+There are two cases where we currently use the local cache. The
+current rules are probably more conservative than necessary.
+
+### Trait references that involve parameter types
+
+The most obvious case where you need the local environment is
+when the trait reference includes parameter types. For example,
+consider the following function:
+
+    impl<T> Vec<T> {
+        fn foo(x: T)
+            where T : Foo
+        { ... }
+
+        fn bar(x: T)
+        { ... }
+    }
+
+If there is an obligation `T : Foo`, or `int : Bar<T>`, or whatever,
+clearly the results from `foo` and `bar` are potentially different,
+since the set of where clauses in scope are different.
+
+### Trait references with unbound variables when where clauses are in scope
+
+There is another less obvious interaction which involves unbound variables
+where *only* where clauses are in scope (no impls). This manifested as
+issue #18209 (`run-pass/trait-cache-issue-18209.rs`). Consider
+this snippet:
+
+```
+pub trait Foo {
+    fn load_from() -> Box<Self>;
+    fn load() -> Box<Self> {
+        Foo::load_from()
+    }
+}
+```
+
+The default method will incur an obligation `$0 : Foo` from the call
+to `load_from`. If there are no impls, this can be eagerly resolved to
+`VtableParam(Self : Foo)` and cached. Because the trait reference
+doesn't involve any parameters types (only the resolution does), this
+result was stored in the global cache, causing later calls to
+`Foo::load_from()` to get nonsense.
+
+To fix this, we always use the local cache if there are unbound
+variables and where clauses in scope. This is more conservative than
+necessary as far as I can tell. However, it still seems to be a simple
+rule and I observe ~99% hit rate on rustc, so it doesn't seem to hurt
+us in particular.
+
+Here is an example of the kind of subtle case that I would be worried
+about with a more complex rule (although this particular case works
+out ok). Imagine the trait reference doesn't directly reference a
+where clause, but the where clause plays a role in the winnowing
+phase. Something like this:
+
+```
+pub trait Foo<T> { ... }
+pub trait Bar { ... }
+impl<U,T:Bar> Foo<U> for T { ... } // Impl A
+impl Foo<char> for uint { ... }    // Impl B
+```
+
+Now, in some function, we have no where clauses in scope, and we have
+an obligation `$1 : Foo<$0>`. We might then conclude that `$0=char`
+and `$1=uint`: this is because for impl A to apply, `uint:Bar` would
+have to hold, and we know it does not or else the coherence check
+would have failed.  So we might enter into our global cache: `$1 :
+Foo<$0> => Impl B`.  Then we come along in a different scope, where a
+generic type `A` is around with the bound `A:Bar`. Now suddenly the
+impl is viable.
+
+The flaw in this imaginary DOOMSDAY SCENARIO is that we would not
+currently conclude that `$1 : Foo<$0>` implies that `$0 == uint` and
+`$1 == char`, even though it is true that (absent type parameters)
+there is no other type the user could enter. However, it is not
+*completely* implausible that we *could* draw this conclusion in the
+future; we wouldn't have to guess types, in particular, we could be
+led by the impls.
+
 */
index c0caa1d7c79fb638968938fefa552091cb8613a7..6baf4e6c048903f9b517b4933e9f37a936f3588b 100644 (file)
@@ -35,12 +35,18 @@ pub struct FulfillmentContext {
     // A list of all obligations that have been registered with this
     // fulfillment context.
     trait_obligations: Vec<Obligation>,
+
+    // Remembers the count of trait obligations that we have already
+    // attempted to select. This is used to avoid repeating work
+    // when `select_new_obligations` is called.
+    attempted_mark: uint,
 }
 
 impl FulfillmentContext {
     pub fn new() -> FulfillmentContext {
         FulfillmentContext {
             trait_obligations: Vec::new(),
+            attempted_mark: 0,
         }
     }
 
@@ -74,18 +80,49 @@ pub fn select_all_or_error<'a,'tcx>(&mut self,
         }
     }
 
+    pub fn select_new_obligations<'a,'tcx>(&mut self,
+                                           infcx: &InferCtxt<'a,'tcx>,
+                                           param_env: &ty::ParameterEnvironment,
+                                           typer: &Typer<'tcx>)
+                                           -> Result<(),Vec<FulfillmentError>>
+    {
+        /*!
+         * Attempts to select obligations that were registered since
+         * the call to a selection routine. This is used by the type checker
+         * to eagerly attempt to resolve obligations in hopes of gaining
+         * type information. It'd be equally valid to use `select_where_possible`
+         * but it results in `O(n^2)` performance (#18208).
+         */
+
+        let mut selcx = SelectionContext::new(infcx, param_env, typer);
+        self.select(&mut selcx, true)
+    }
+
     pub fn select_where_possible<'a,'tcx>(&mut self,
                                           infcx: &InferCtxt<'a,'tcx>,
                                           param_env: &ty::ParameterEnvironment,
                                           typer: &Typer<'tcx>)
                                           -> Result<(),Vec<FulfillmentError>>
     {
-        let tcx = infcx.tcx;
         let mut selcx = SelectionContext::new(infcx, param_env, typer);
+        self.select(&mut selcx, false)
+    }
 
-        debug!("select_where_possible({} obligations) start",
-               self.trait_obligations.len());
+    fn select(&mut self,
+              selcx: &mut SelectionContext,
+              only_new_obligations: bool)
+              -> Result<(),Vec<FulfillmentError>>
+    {
+        /*!
+         * Attempts to select obligations using `selcx`. If
+         * `only_new_obligations` is true, then it only attempts to
+         * select obligations that haven't been seen before.
+         */
+        debug!("select({} obligations, only_new_obligations={}) start",
+               self.trait_obligations.len(),
+               only_new_obligations);
 
+        let tcx = selcx.tcx();
         let mut errors = Vec::new();
 
         loop {
@@ -96,30 +133,47 @@ pub fn select_where_possible<'a,'tcx>(&mut self,
 
             let mut selections = Vec::new();
 
+            // If we are only attempting obligations we haven't seen yet,
+            // then set `skip` to the number of obligations we've already
+            // seen.
+            let mut skip = if only_new_obligations {
+                self.attempted_mark
+            } else {
+                0
+            };
+
             // First pass: walk each obligation, retaining
             // only those that we cannot yet process.
             self.trait_obligations.retain(|obligation| {
-                match selcx.select(obligation) {
-                    Ok(None) => {
-                        true
-                    }
-                    Ok(Some(s)) => {
-                        selections.push(s);
-                        false
-                    }
-                    Err(selection_err) => {
-                        debug!("obligation: {} error: {}",
-                               obligation.repr(tcx),
-                               selection_err.repr(tcx));
-
-                        errors.push(FulfillmentError::new(
-                            (*obligation).clone(),
-                            CodeSelectionError(selection_err)));
-                        false
+                // Hack: Retain does not pass in the index, but we want
+                // to avoid processing the first `start_count` entries.
+                if skip > 0 {
+                    skip -= 1;
+                    true
+                } else {
+                    match selcx.select(obligation) {
+                        Ok(None) => {
+                            true
+                        }
+                        Ok(Some(s)) => {
+                            selections.push(s);
+                            false
+                        }
+                        Err(selection_err) => {
+                            debug!("obligation: {} error: {}",
+                                   obligation.repr(tcx),
+                                   selection_err.repr(tcx));
+                            errors.push(FulfillmentError::new(
+                                (*obligation).clone(),
+                                CodeSelectionError(selection_err)));
+                            false
+                        }
                     }
                 }
             });
 
+            self.attempted_mark = self.trait_obligations.len();
+
             if self.trait_obligations.len() == count {
                 // Nothing changed.
                 break;
@@ -133,7 +187,7 @@ pub fn select_where_possible<'a,'tcx>(&mut self,
             }
         }
 
-        debug!("select_where_possible({} obligations, {} errors) done",
+        debug!("select({} obligations, {} errors) done",
                self.trait_obligations.len(),
                errors.len());
 
index 23257912b8264f457970d5af15db82b7b06508ac..f8c1c37452b38c4e93b6ac35a75ee3cbc720b382 100644 (file)
@@ -110,7 +110,7 @@ enum Candidate {
     BuiltinCandidate(ty::BuiltinBound),
     ParamCandidate(VtableParamData),
     ImplCandidate(ast::DefId),
-    UnboxedClosureCandidate(/* closure */ ast::DefId),
+    UnboxedClosureCandidate(/* closure */ ast::DefId, Substs),
     ErrorCandidate,
 }
 
@@ -211,7 +211,7 @@ pub fn select_inherent_impl(&mut self,
     // can be applied to particular types. It skips the "confirmation"
     // step and hence completely ignores output type parameters.
     //
-    // The result is "true" if the obliation *may* hold and "false" if
+    // The result is "true" if the obligation *may* hold and "false" if
     // we can be sure it does not.
 
     pub fn evaluate_obligation_intercrate(&mut self,
@@ -844,19 +844,36 @@ fn pick_candidate_cache(&self,
                             cache_skol_trait_ref: &Rc<ty::TraitRef>)
                             -> &SelectionCache
     {
+        // High-level idea: we have to decide whether to consult the
+        // cache that is specific to this scope, or to consult the
+        // global cache. We want the cache that is specific to this
+        // scope whenever where clauses might affect the result.
+
         // If the trait refers to any parameters in scope, then use
-        // the cache of the param-environment. This is because the
-        // result will depend on the where clauses that are in
-        // scope. Otherwise, use the generic tcx cache, since the
-        // result holds across all environments.
+        // the cache of the param-environment.
         if
             cache_skol_trait_ref.input_types().iter().any(
                 |&t| ty::type_has_self(t) || ty::type_has_params(t))
         {
-            &self.param_env.selection_cache
-        } else {
-            &self.tcx().selection_cache
+            return &self.param_env.selection_cache;
+        }
+
+        // If the trait refers to unbound type variables, and there
+        // are where clauses in scope, then use the local environment.
+        // If there are no where clauses in scope, which is a very
+        // common case, then we can use the global environment.
+        // See the discussion in doc.rs for more details.
+        if
+            !self.param_env.caller_obligations.is_empty()
+            &&
+            cache_skol_trait_ref.input_types().iter().any(
+                |&t| ty::type_has_ty_infer(t))
+        {
+            return &self.param_env.selection_cache;
         }
+
+        // Otherwise, we can use the global cache.
+        &self.tcx().selection_cache
     }
 
     fn check_candidate_cache(&mut self,
@@ -978,8 +995,8 @@ fn assemble_unboxed_candidates(&mut self,
         };
 
         let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
-        let closure_def_id = match ty::get(self_ty).sty {
-            ty::ty_unboxed_closure(id, _) => id,
+        let (closure_def_id, substs) = match ty::get(self_ty).sty {
+            ty::ty_unboxed_closure(id, _, ref substs) => (id, substs.clone()),
             ty::ty_infer(ty::TyVar(_)) => {
                 candidates.ambiguous = true;
                 return Ok(());
@@ -1002,7 +1019,7 @@ fn assemble_unboxed_candidates(&mut self,
         };
 
         if closure_kind == kind {
-            candidates.vec.push(UnboxedClosureCandidate(closure_def_id));
+            candidates.vec.push(UnboxedClosureCandidate(closure_def_id, substs.clone()));
         }
 
         Ok(())
@@ -1176,7 +1193,6 @@ fn builtin_bound(&mut self,
             ty::ty_uint(_) |
             ty::ty_int(_) |
             ty::ty_nil |
-            ty::ty_bot |
             ty::ty_bool |
             ty::ty_float(_) |
             ty::ty_bare_fn(_) |
@@ -1366,7 +1382,7 @@ fn builtin_bound(&mut self,
                 Ok(If(tys.clone()))
             }
 
-            ty::ty_unboxed_closure(def_id, _) => {
+            ty::ty_unboxed_closure(def_id, _, ref substs) => {
                 // FIXME -- This case is tricky. In the case of by-ref
                 // closures particularly, we need the results of
                 // inference to decide how to reflect the type of each
@@ -1390,7 +1406,7 @@ fn builtin_bound(&mut self,
                             .map(|freevar| {
                                 let freevar_def_id = freevar.def.def_id();
                                 self.typer.node_ty(freevar_def_id.node)
-                                    .unwrap_or(ty::mk_err())
+                                    .unwrap_or(ty::mk_err()).subst(self.tcx(), substs)
                             })
                             .collect();
                         Ok(If(tys))
@@ -1531,8 +1547,8 @@ fn confirm_candidate(&mut self,
                 Ok(VtableImpl(vtable_impl))
             }
 
-            UnboxedClosureCandidate(closure_def_id) => {
-                try!(self.confirm_unboxed_closure_candidate(obligation, closure_def_id));
+            UnboxedClosureCandidate(closure_def_id, ref substs) => {
+                try!(self.confirm_unboxed_closure_candidate(obligation, closure_def_id, substs));
                 Ok(VtableUnboxedClosure(closure_def_id))
             }
         }
@@ -1629,12 +1645,14 @@ fn vtable_impl(&mut self,
 
     fn confirm_unboxed_closure_candidate(&mut self,
                                          obligation: &Obligation,
-                                         closure_def_id: ast::DefId)
+                                         closure_def_id: ast::DefId,
+                                         substs: &Substs)
                                          -> Result<(),SelectionError>
     {
-        debug!("confirm_unboxed_closure_candidate({},{})",
+        debug!("confirm_unboxed_closure_candidate({},{},{})",
                obligation.repr(self.tcx()),
-               closure_def_id.repr(self.tcx()));
+               closure_def_id.repr(self.tcx()),
+               substs.repr(self.tcx()));
 
         let closure_type = match self.typer.unboxed_closures().borrow().find(&closure_def_id) {
             Some(closure) => closure.closure_type.clone(),
@@ -1661,7 +1679,8 @@ fn confirm_unboxed_closure_candidate(&mut self,
         let trait_ref = Rc::new(ty::TraitRef {
             def_id: obligation.trait_ref.def_id,
             substs: Substs::new_trait(
-                vec![arguments_tuple, new_signature.output],
+                vec![arguments_tuple.subst(self.tcx(), substs),
+                     new_signature.output.unwrap().subst(self.tcx(), substs)],
                 vec![],
                 obligation.self_ty())
         });
@@ -1935,26 +1954,6 @@ fn impl_obligations(&self,
         util::obligations_for_generics(self.tcx(), cause, recursion_depth,
                                        &impl_generics, impl_substs)
     }
-
-    fn contains_skolemized_types(&self,
-                                 ty: ty::t)
-                                 -> bool
-    {
-        /*!
-         * True if the type contains skolemized variables.
-         */
-
-        let mut found_skol = false;
-
-        ty::walk_ty(ty, |t| {
-            match ty::get(t).sty {
-                ty::ty_infer(ty::SkolemizedTy(_)) => { found_skol = true; }
-                _ => { }
-            }
-        });
-
-        found_skol
-    }
 }
 
 impl Repr for Candidate {
@@ -1962,7 +1961,9 @@ fn repr(&self, tcx: &ty::ctxt) -> String {
         match *self {
             ErrorCandidate => format!("ErrorCandidate"),
             BuiltinCandidate(b) => format!("BuiltinCandidate({})", b),
-            UnboxedClosureCandidate(c) => format!("MatchedUnboxedClosureCandidate({})", c),
+            UnboxedClosureCandidate(c, ref s) => {
+                format!("MatchedUnboxedClosureCandidate({},{})", c, s.repr(tcx))
+            }
             ParamCandidate(ref a) => format!("ParamCandidate({})", a.repr(tcx)),
             ImplCandidate(a) => format!("ImplCandidate({})", a.repr(tcx)),
         }
index e4f34d8ab47be48ad1bdd53fabff54351aba337b..f53b5331eddeb7a2624abc37ff50571272f9745f 100644 (file)
@@ -235,7 +235,7 @@ fn eq(self, other: ConstantExpr<'a>, tcx: &ty::ctxt) -> bool {
         let ConstantExpr(other_expr) = other;
         match const_eval::compare_lit_exprs(tcx, expr, other_expr) {
             Some(val1) => val1 == 0,
-            None => fail!("compare_list_exprs: type mismatch"),
+            None => panic!("compare_list_exprs: type mismatch"),
         }
     }
 }
@@ -734,7 +734,7 @@ fn is_infallible(&self) -> bool {
     fn handle_fail(&self, bcx: Block) {
         match *self {
             Infallible =>
-                fail!("attempted to fail in an infallible failure handler!"),
+                panic!("attempted to panic in a non-panicking panic handler!"),
             JumpToBasicBlock(basic_block) =>
                 Br(bcx, basic_block),
             Unreachable =>
@@ -1462,15 +1462,11 @@ fn create_dummy_locals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             // General path.
             let init_datum =
                 unpack_datum!(bcx, expr::trans_to_lvalue(bcx, &**init_expr, "let"));
-            if ty::type_is_bot(expr_ty(bcx, &**init_expr)) {
-                create_dummy_locals(bcx, pat)
-            } else {
-                if bcx.sess().asm_comments() {
-                    add_comment(bcx, "creating zeroable ref llval");
-                }
-                let var_scope = cleanup::var_scope(tcx, local.id);
-                bind_irrefutable_pat(bcx, pat, init_datum.val, var_scope)
+            if bcx.sess().asm_comments() {
+                add_comment(bcx, "creating zeroable ref llval");
             }
+            let var_scope = cleanup::var_scope(tcx, local.id);
+            bind_irrefutable_pat(bcx, pat, init_datum.val, var_scope)
         }
         None => {
             create_dummy_locals(bcx, pat)
index 438bb337e3f4e1095a783831ec1a3d521b887351..1f737cae86f9241e679b8369fcb09fc0c191f84f 100644 (file)
@@ -176,8 +176,8 @@ fn represent_type_uncached(cx: &CrateContext, t: ty::t) -> Repr {
 
             return Univariant(mk_struct(cx, ftys.as_slice(), packed, t), dtor)
         }
-        ty::ty_unboxed_closure(def_id, _) => {
-            let upvars = ty::unboxed_closure_upvars(cx.tcx(), def_id);
+        ty::ty_unboxed_closure(def_id, _, ref substs) => {
+            let upvars = ty::unboxed_closure_upvars(cx.tcx(), def_id, substs);
             let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
             return Univariant(mk_struct(cx, upvar_types.as_slice(), false, t),
                               false)
@@ -586,7 +586,7 @@ fn generic_type_of(cx: &CrateContext,
                                  Type::array(&Type::i64(cx), align_units),
                 a if a.count_ones() == 1 => Type::array(&Type::vector(&Type::i32(cx), a / 4),
                                                               align_units),
-                _ => fail!("unsupported enum alignment: {}", align)
+                _ => panic!("unsupported enum alignment: {}", align)
             };
             assert_eq!(machine::llalign_of_min(cx, pad_ty), align);
             assert_eq!(align_s % discr_size, 0);
index b92b9e84a9562c13cc1d7c3e64e64dc770590a56..ae8f944cab100d9dbc07d44e6a65b0c8f6e4d3cf 100644 (file)
@@ -180,7 +180,7 @@ fn drop(&mut self) {
 
 // only use this for foreign function ABIs and glue, use `decl_rust_fn` for Rust functions
 pub fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv,
-           ty: Type, output: ty::t) -> ValueRef {
+           ty: Type, output: ty::FnOutput) -> ValueRef {
 
     let llfn: ValueRef = name.with_c_str(|buf| {
         unsafe {
@@ -188,12 +188,9 @@ pub fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv,
         }
     });
 
-    match ty::get(output).sty {
-        // functions returning bottom may unwind, but can never return normally
-        ty::ty_bot => {
-            llvm::SetFunctionAttribute(llfn, llvm::NoReturnAttribute)
-        }
-        _ => {}
+    // diverging functions may unwind, but can never return normally
+    if output == ty::FnDiverging {
+        llvm::SetFunctionAttribute(llfn, llvm::NoReturnAttribute);
     }
 
     if ccx.tcx().sess.opts.cg.no_redzone {
@@ -216,7 +213,7 @@ pub fn decl_cdecl_fn(ccx: &CrateContext,
                      name: &str,
                      ty: Type,
                      output: ty::t) -> ValueRef {
-    decl_fn(ccx, name, llvm::CCallConv, ty, output)
+    decl_fn(ccx, name, llvm::CCallConv, ty, ty::FnConverging(output))
 }
 
 // only use this for foreign function ABIs and glue, use `get_extern_rust_fn` for Rust functions
@@ -231,7 +228,7 @@ pub fn get_extern_fn(ccx: &CrateContext,
         Some(n) => return *n,
         None => {}
     }
-    let f = decl_fn(ccx, name, cc, ty, output);
+    let f = decl_fn(ccx, name, cc, ty, ty::FnConverging(output));
     externs.insert(name.to_string(), f);
     f
 }
@@ -253,21 +250,19 @@ fn get_extern_rust_fn(ccx: &CrateContext, fn_ty: ty::t, name: &str, did: ast::De
 }
 
 pub fn self_type_for_unboxed_closure(ccx: &CrateContext,
-                                     closure_id: ast::DefId)
+                                     closure_id: ast::DefId,
+                                     fn_ty: ty::t)
                                      -> ty::t {
-    let unboxed_closure_type = ty::mk_unboxed_closure(ccx.tcx(),
-                                                      closure_id,
-                                                      ty::ReStatic);
     let unboxed_closures = ccx.tcx().unboxed_closures.borrow();
     let unboxed_closure = &(*unboxed_closures)[closure_id];
     match unboxed_closure.kind {
         ty::FnUnboxedClosureKind => {
-            ty::mk_imm_rptr(ccx.tcx(), ty::ReStatic, unboxed_closure_type)
+            ty::mk_imm_rptr(ccx.tcx(), ty::ReStatic, fn_ty)
         }
         ty::FnMutUnboxedClosureKind => {
-            ty::mk_mut_rptr(ccx.tcx(), ty::ReStatic, unboxed_closure_type)
+            ty::mk_mut_rptr(ccx.tcx(), ty::ReStatic, fn_ty)
         }
-        ty::FnOnceUnboxedClosureKind => unboxed_closure_type,
+        ty::FnOnceUnboxedClosureKind => fn_ty
     }
 }
 
@@ -285,18 +280,18 @@ pub fn decl_rust_fn(ccx: &CrateContext, fn_ty: ty::t, name: &str) -> ValueRef {
         ty::ty_closure(ref f) => {
             (f.sig.inputs.clone(), f.sig.output, f.abi, Some(Type::i8p(ccx)))
         }
-        ty::ty_unboxed_closure(closure_did, _) => {
+        ty::ty_unboxed_closure(closure_did, _, ref substs) => {
             let unboxed_closures = ccx.tcx().unboxed_closures.borrow();
             let unboxed_closure = &(*unboxed_closures)[closure_did];
             let function_type = unboxed_closure.closure_type.clone();
-            let self_type = self_type_for_unboxed_closure(ccx, closure_did);
+            let self_type = self_type_for_unboxed_closure(ccx, closure_did, fn_ty);
             let llenvironment_type = type_of_explicit_arg(ccx, self_type);
-            (function_type.sig.inputs.clone(),
-             function_type.sig.output,
+            (function_type.sig.inputs.iter().map(|t| t.subst(ccx.tcx(), substs)).collect(),
+             function_type.sig.output.subst(ccx.tcx(), substs),
              RustCall,
              Some(llenvironment_type))
         }
-        _ => fail!("expected closure or fn")
+        _ => panic!("expected closure or fn")
     };
 
     let llfty = type_of_rust_fn(ccx, env, inputs.as_slice(), output, abi);
@@ -738,9 +733,9 @@ fn iter_variant<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>,
               }
           })
       }
-      ty::ty_unboxed_closure(def_id, _) => {
+      ty::ty_unboxed_closure(def_id, _, ref substs) => {
           let repr = adt::represent_type(cx.ccx(), t);
-          let upvars = ty::unboxed_closure_upvars(cx.tcx(), def_id);
+          let upvars = ty::unboxed_closure_upvars(cx.tcx(), def_id, substs);
           for (i, upvar) in upvars.iter().enumerate() {
               let llupvar = adt::trans_field_ptr(cx, &*repr, data_ptr, 0, i);
               cx = f(cx, llupvar, upvar.ty);
@@ -1419,7 +1414,7 @@ pub fn new_fn_ctxt<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
                              llfndecl: ValueRef,
                              id: ast::NodeId,
                              has_env: bool,
-                             output_type: ty::t,
+                             output_type: ty::FnOutput,
                              param_substs: &'a param_substs,
                              sp: Option<Span>,
                              block_arena: &'a TypedArena<common::BlockS<'a, 'tcx>>)
@@ -1434,8 +1429,13 @@ pub fn new_fn_ctxt<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
            },
            id, param_substs.repr(ccx.tcx()));
 
-    let substd_output_type = output_type.substp(ccx.tcx(), param_substs);
-    let uses_outptr = type_of::return_uses_outptr(ccx, substd_output_type);
+    let uses_outptr = match output_type {
+        ty::FnConverging(output_type) => {
+            let substd_output_type = output_type.substp(ccx.tcx(), param_substs);
+            type_of::return_uses_outptr(ccx, substd_output_type)
+        }
+        ty::FnDiverging => false
+    };
     let debug_context = debuginfo::create_function_debug_context(ccx, id, param_substs, llfndecl);
     let nested_returns = has_nested_returns(ccx.tcx(), id);
 
@@ -1470,7 +1470,7 @@ pub fn new_fn_ctxt<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
 /// and allocating space for the return pointer.
 pub fn init_function<'a, 'tcx>(fcx: &'a FunctionContext<'a, 'tcx>,
                                skip_retptr: bool,
-                               output_type: ty::t) -> Block<'a, 'tcx> {
+                               output: ty::FnOutput) -> Block<'a, 'tcx> {
     let entry_bcx = fcx.new_temp_block("entry-block");
 
     // Use a dummy instruction as the insertion point for all allocas.
@@ -1480,18 +1480,19 @@ pub fn init_function<'a, 'tcx>(fcx: &'a FunctionContext<'a, 'tcx>,
         llvm::LLVMGetFirstInstruction(entry_bcx.llbb)
     }));
 
-    // This shouldn't need to recompute the return type,
-    // as new_fn_ctxt did it already.
-    let substd_output_type = output_type.substp(fcx.ccx.tcx(), fcx.param_substs);
-
-    if !return_type_is_void(fcx.ccx, substd_output_type) {
-        // If the function returns nil/bot, there is no real return
-        // value, so do not set `llretslotptr`.
-        if !skip_retptr || fcx.caller_expects_out_pointer {
-            // Otherwise, we normally allocate the llretslotptr, unless we
-            // have been instructed to skip it for immediate return
-            // values.
-            fcx.llretslotptr.set(Some(make_return_slot_pointer(fcx, substd_output_type)));
+    if let ty::FnConverging(output_type) = output {
+        // This shouldn't need to recompute the return type,
+        // as new_fn_ctxt did it already.
+        let substd_output_type = output_type.substp(fcx.ccx.tcx(), fcx.param_substs);
+        if !return_type_is_void(fcx.ccx, substd_output_type) {
+            // If the function returns nil/bot, there is no real return
+            // value, so do not set `llretslotptr`.
+            if !skip_retptr || fcx.caller_expects_out_pointer {
+                // Otherwise, we normally allocate the llretslotptr, unless we
+                // have been instructed to skip it for immediate return
+                // values.
+                fcx.llretslotptr.set(Some(make_return_slot_pointer(fcx, substd_output_type)));
+            }
         }
     }
 
@@ -1695,13 +1696,9 @@ fn copy_unboxed_closure_args_to_allocas<'blk, 'tcx>(
 // and builds the return block.
 pub fn finish_fn<'blk, 'tcx>(fcx: &'blk FunctionContext<'blk, 'tcx>,
                              last_bcx: Block<'blk, 'tcx>,
-                             retty: ty::t) {
+                             retty: ty::FnOutput) {
     let _icx = push_ctxt("finish_fn");
 
-    // This shouldn't need to recompute the return type,
-    // as new_fn_ctxt did it already.
-    let substd_retty = retty.substp(fcx.ccx.tcx(), fcx.param_substs);
-
     let ret_cx = match fcx.llreturn.get() {
         Some(llreturn) => {
             if !last_bcx.terminated.get() {
@@ -1711,13 +1708,18 @@ pub fn finish_fn<'blk, 'tcx>(fcx: &'blk FunctionContext<'blk, 'tcx>,
         }
         None => last_bcx
     };
+
+    // This shouldn't need to recompute the return type,
+    // as new_fn_ctxt did it already.
+    let substd_retty = retty.substp(fcx.ccx.tcx(), fcx.param_substs);
     build_return_block(fcx, ret_cx, substd_retty);
+
     debuginfo::clear_source_location(fcx);
     fcx.cleanup();
 }
 
 // Builds the return block for a function.
-pub fn build_return_block(fcx: &FunctionContext, ret_cx: Block, retty: ty::t) {
+pub fn build_return_block(fcx: &FunctionContext, ret_cx: Block, retty: ty::FnOutput) {
     if fcx.llretslotptr.get().is_none() ||
        (!fcx.needs_ret_allocas && fcx.caller_expects_out_pointer) {
         return RetVoid(ret_cx);
@@ -1740,26 +1742,37 @@ pub fn build_return_block(fcx: &FunctionContext, ret_cx: Block, retty: ty::t) {
                 retptr.erase_from_parent();
             }
 
-            let retval = if ty::type_is_bool(retty) {
+            let retval = if retty == ty::FnConverging(ty::mk_bool()) {
                 Trunc(ret_cx, retval, Type::i1(fcx.ccx))
             } else {
                 retval
             };
 
             if fcx.caller_expects_out_pointer {
-                store_ty(ret_cx, retval, get_param(fcx.llfn, 0), retty);
-                return RetVoid(ret_cx);
+                if let ty::FnConverging(retty) = retty {
+                    store_ty(ret_cx, retval, get_param(fcx.llfn, 0), retty);
+                }
+                RetVoid(ret_cx)
             } else {
-                return Ret(ret_cx, retval);
+                Ret(ret_cx, retval)
             }
         }
         // Otherwise, copy the return value to the ret slot
-        None => {
-            if fcx.caller_expects_out_pointer {
-                memcpy_ty(ret_cx, get_param(fcx.llfn, 0), retslot, retty);
-                return RetVoid(ret_cx);
-            } else {
-                return Ret(ret_cx, load_ty(ret_cx, retslot, retty));
+        None => match retty {
+            ty::FnConverging(retty) => {
+                if fcx.caller_expects_out_pointer {
+                    memcpy_ty(ret_cx, get_param(fcx.llfn, 0), retslot, retty);
+                    RetVoid(ret_cx)
+                } else {
+                    Ret(ret_cx, load_ty(ret_cx, retslot, retty))
+                }
+            }
+            ty::FnDiverging => {
+                if fcx.caller_expects_out_pointer {
+                    RetVoid(ret_cx)
+                } else {
+                    Ret(ret_cx, C_undef(Type::nil(fcx.ccx)))
+                }
             }
         }
     }
@@ -1782,7 +1795,7 @@ pub fn trans_closure(ccx: &CrateContext,
                      fn_ast_id: ast::NodeId,
                      _attributes: &[ast::Attribute],
                      arg_types: Vec<ty::t>,
-                     output_type: ty::t,
+                     output_type: ty::FnOutput,
                      abi: Abi,
                      has_env: bool,
                      is_unboxed_closure: IsUnboxedClosureFlag,
@@ -1862,7 +1875,7 @@ pub fn trans_closure(ccx: &CrateContext,
     debuginfo::start_emitting_source_locations(&fcx);
 
     let dest = match fcx.llretslotptr.get() {
-        Some(_) => expr::SaveIn(fcx.get_ret_slot(bcx, block_ty, "iret_slot")),
+        Some(_) => expr::SaveIn(fcx.get_ret_slot(bcx, ty::FnConverging(block_ty), "iret_slot")),
         None => {
             assert!(type_is_zero_size(bcx.ccx(), block_ty));
             expr::Ignore
@@ -1967,7 +1980,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     let tcx = ccx.tcx();
 
     let result_ty = match ty::get(ctor_ty).sty {
-        ty::ty_bare_fn(ref bft) => bft.sig.output,
+        ty::ty_bare_fn(ref bft) => bft.sig.output.unwrap(),
         _ => ccx.sess().bug(
             format!("trans_enum_variant_constructor: \
                      unexpected ctor return type {}",
@@ -2057,9 +2070,9 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext,
 
     let arg_datums = create_datums_for_fn_args(&fcx, arg_tys.as_slice());
 
-    if !type_is_zero_size(fcx.ccx, result_ty) {
+    if !type_is_zero_size(fcx.ccx, result_ty.unwrap()) {
         let dest = fcx.get_ret_slot(bcx, result_ty, "eret_slot");
-        let repr = adt::represent_type(ccx, result_ty);
+        let repr = adt::represent_type(ccx, result_ty.unwrap());
         for (i, arg_datum) in arg_datums.into_iter().enumerate() {
             let lldestptr = adt::trans_field_ptr(bcx,
                                                  &*repr,
@@ -2336,7 +2349,7 @@ fn register_fn(ccx: &CrateContext,
         ty::ty_bare_fn(ref f) => {
             assert!(f.abi == Rust || f.abi == RustCall);
         }
-        _ => fail!("expected bare rust fn")
+        _ => panic!("expected bare rust fn")
     };
 
     let llfn = decl_rust_fn(ccx, node_type, sym.as_slice());
@@ -2351,12 +2364,12 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t)
     let (fn_sig, abi, has_env) = match ty::get(fn_ty).sty {
         ty::ty_closure(ref f) => (f.sig.clone(), f.abi, true),
         ty::ty_bare_fn(ref f) => (f.sig.clone(), f.abi, false),
-        ty::ty_unboxed_closure(closure_did, _) => {
+        ty::ty_unboxed_closure(closure_did, _, ref substs) => {
             let unboxed_closures = ccx.tcx().unboxed_closures.borrow();
             let ref function_type = (*unboxed_closures)[closure_did]
                                                     .closure_type;
 
-            (function_type.sig.clone(), RustCall, true)
+            (function_type.sig.subst(ccx.tcx(), substs), RustCall, true)
         }
         _ => ccx.sess().bug("expected closure or function.")
     };
@@ -2371,7 +2384,7 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t)
     // These have an odd calling convention, so we need to manually
     // unpack the input ty's
     let input_tys = match ty::get(fn_ty).sty {
-        ty::ty_unboxed_closure(_, _) => {
+        ty::ty_unboxed_closure(_, _, _) => {
             assert!(abi == RustCall);
 
             match ty::get(fn_sig.inputs[0]).sty {
@@ -2395,53 +2408,55 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t)
         _ => fn_sig.inputs.clone()
     };
 
-    // A function pointer is called without the declaration
-    // available, so we have to apply any attributes with ABI
-    // implications directly to the call instruction. Right now,
-    // the only attribute we need to worry about is `sret`.
-    if type_of::return_uses_outptr(ccx, ret_ty) {
-        let llret_sz = llsize_of_real(ccx, type_of::type_of(ccx, ret_ty));
-
-        // The outptr can be noalias and nocapture because it's entirely
-        // invisible to the program. We also know it's nonnull as well
-        // as how many bytes we can dereference
-        attrs.arg(1, llvm::StructRetAttribute)
-             .arg(1, llvm::NoAliasAttribute)
-             .arg(1, llvm::NoCaptureAttribute)
-             .arg(1, llvm::DereferenceableAttribute(llret_sz));
-
-        // Add one more since there's an outptr
-        first_arg_offset += 1;
-    } else {
-        // The `noalias` attribute on the return value is useful to a
-        // function ptr caller.
-        match ty::get(ret_ty).sty {
-            // `~` pointer return values never alias because ownership
-            // is transferred
-            ty::ty_uniq(it) if !ty::type_is_sized(ccx.tcx(), it) => {}
-            ty::ty_uniq(_) => {
-                attrs.ret(llvm::NoAliasAttribute);
+    if let ty::FnConverging(ret_ty) = ret_ty {
+        // A function pointer is called without the declaration
+        // available, so we have to apply any attributes with ABI
+        // implications directly to the call instruction. Right now,
+        // the only attribute we need to worry about is `sret`.
+        if type_of::return_uses_outptr(ccx, ret_ty) {
+            let llret_sz = llsize_of_real(ccx, type_of::type_of(ccx, ret_ty));
+
+            // The outptr can be noalias and nocapture because it's entirely
+            // invisible to the program. We also know it's nonnull as well
+            // as how many bytes we can dereference
+            attrs.arg(1, llvm::StructRetAttribute)
+                 .arg(1, llvm::NoAliasAttribute)
+                 .arg(1, llvm::NoCaptureAttribute)
+                 .arg(1, llvm::DereferenceableAttribute(llret_sz));
+
+            // Add one more since there's an outptr
+            first_arg_offset += 1;
+        } else {
+            // The `noalias` attribute on the return value is useful to a
+            // function ptr caller.
+            match ty::get(ret_ty).sty {
+                // `~` pointer return values never alias because ownership
+                // is transferred
+                ty::ty_uniq(it) if !ty::type_is_sized(ccx.tcx(), it) => {}
+                ty::ty_uniq(_) => {
+                    attrs.ret(llvm::NoAliasAttribute);
+                }
+                _ => {}
             }
-            _ => {}
-        }
 
-        // We can also mark the return value as `dereferenceable` in certain cases
-        match ty::get(ret_ty).sty {
-            // These are not really pointers but pairs, (pointer, len)
-            ty::ty_uniq(it) |
-            ty::ty_rptr(_, ty::mt { ty: it, .. }) if !ty::type_is_sized(ccx.tcx(), it) => {}
-            ty::ty_uniq(inner) | ty::ty_rptr(_, ty::mt { ty: inner, .. }) => {
-                let llret_sz = llsize_of_real(ccx, type_of::type_of(ccx, inner));
-                attrs.ret(llvm::DereferenceableAttribute(llret_sz));
+            // We can also mark the return value as `dereferenceable` in certain cases
+            match ty::get(ret_ty).sty {
+                // These are not really pointers but pairs, (pointer, len)
+                ty::ty_uniq(it) |
+                ty::ty_rptr(_, ty::mt { ty: it, .. }) if !ty::type_is_sized(ccx.tcx(), it) => {}
+                ty::ty_uniq(inner) | ty::ty_rptr(_, ty::mt { ty: inner, .. }) => {
+                    let llret_sz = llsize_of_real(ccx, type_of::type_of(ccx, inner));
+                    attrs.ret(llvm::DereferenceableAttribute(llret_sz));
+                }
+                _ => {}
             }
-            _ => {}
-        }
 
-        match ty::get(ret_ty).sty {
-            ty::ty_bool => {
-                attrs.ret(llvm::ZExtAttribute);
+            match ty::get(ret_ty).sty {
+                ty::ty_bool => {
+                    attrs.ret(llvm::ZExtAttribute);
+                }
+                _ => {}
             }
-            _ => {}
         }
     }
 
@@ -2525,7 +2540,7 @@ pub fn register_fn_llvmty(ccx: &CrateContext,
                           llfty: Type) -> ValueRef {
     debug!("register_fn_llvmty id={} sym={}", node_id, sym);
 
-    let llfn = decl_fn(ccx, sym.as_slice(), cc, llfty, ty::mk_nil());
+    let llfn = decl_fn(ccx, sym.as_slice(), cc, llfty, ty::FnConverging(ty::mk_nil()));
     finish_register_fn(ccx, sp, sym, node_id, llfn);
     llfn
 }
@@ -2729,7 +2744,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
                     llfn
                 }
 
-                _ => fail!("get_item_val: weird result in table")
+                _ => panic!("get_item_val: weird result in table")
             };
 
             match attr::first_attr_value_str_by_name(i.attrs.as_slice(),
@@ -2796,7 +2811,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
             let args = match v.node.kind {
                 ast::TupleVariantKind(ref args) => args,
                 ast::StructVariantKind(_) => {
-                    fail!("struct variant kind unexpected in get_item_val")
+                    panic!("struct variant kind unexpected in get_item_val")
                 }
             };
             assert!(args.len() != 0u);
@@ -2812,7 +2827,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
                 ast::ItemEnum(_, _) => {
                     register_fn(ccx, (*v).span, sym, id, ty)
                 }
-                _ => fail!("NodeVariant, shouldn't happen")
+                _ => panic!("NodeVariant, shouldn't happen")
             };
             set_inline_hint(llfn);
             llfn
index 025b5f368ecae3bdbd0c5cc3b67cd74a5cf62032..895f03ec2c79de7ccb4f9625c739d44d8e497a5b 100644 (file)
@@ -30,7 +30,7 @@ pub fn terminate(cx: Block, _: &str) {
 
 pub fn check_not_terminated(cx: Block) {
     if cx.terminated.get() {
-        fail!("already terminated!");
+        panic!("already terminated!");
     }
 }
 
@@ -45,7 +45,7 @@ pub fn B<'blk, 'tcx>(cx: Block<'blk, 'tcx>) -> Builder<'blk, 'tcx> {
 // terminated, we're saying that trying to add any further statements in the
 // block is an error. On the other hand, if something is unreachable, that
 // means that the block was terminated in some way that we don't want to check
-// for (fail/break/return statements, call to diverging functions, etc), and
+// for (panic/break/return statements, call to diverging functions, etc), and
 // further instructions to the block should simply be ignored.
 
 pub fn RetVoid(cx: Block) {
index ccfc79ac0c5002bec9ce1074297c366250d6df6f..d8cf8dbb7959f3331a19d55601b7238f479819c1 100644 (file)
@@ -50,7 +50,7 @@ fn ty_align(ty: Type) -> uint {
             let elt = ty.element_type();
             ty_align(elt)
         }
-        _ => fail!("ty_align: unhandled type")
+        _ => panic!("ty_align: unhandled type")
     }
 }
 
@@ -80,7 +80,7 @@ fn ty_size(ty: Type) -> uint {
             let eltsz = ty_size(elt);
             len * eltsz
         }
-        _ => fail!("ty_size: unhandled type")
+        _ => panic!("ty_size: unhandled type")
     }
 }
 
index 90bd1521705f029bc0e5e7ad967a395e3fbb367d..9f51e153a0fc9baa54ceda10187f611d641bbe80 100644 (file)
@@ -50,7 +50,7 @@ fn ty_align(ty: Type) -> uint {
             let elt = ty.element_type();
             ty_align(elt)
         }
-        _ => fail!("ty_size: unhandled type")
+        _ => panic!("ty_size: unhandled type")
     }
 }
 
@@ -80,7 +80,7 @@ fn ty_size(ty: Type) -> uint {
             let eltsz = ty_size(elt);
             len * eltsz
         }
-        _ => fail!("ty_size: unhandled type")
+        _ => panic!("ty_size: unhandled type")
     }
 }
 
index 1b8a354259ad785977df301be29db8335658ca6b..54fd20ff995b5b04ff3eb1c92eb80f0f738ca7f9 100644 (file)
@@ -111,7 +111,7 @@ fn ty_align(ty: Type) -> uint {
                 let elt = ty.element_type();
                 ty_align(elt)
             }
-            _ => fail!("ty_size: unhandled type")
+            _ => panic!("ty_size: unhandled type")
         }
     }
 
@@ -140,7 +140,7 @@ fn ty_size(ty: Type) -> uint {
                 let eltsz = ty_size(elt);
                 len * eltsz
             }
-            _ => fail!("ty_size: unhandled type")
+            _ => panic!("ty_size: unhandled type")
         }
     }
 
@@ -235,7 +235,7 @@ fn classify(ty: Type,
                     i += 1u;
                 }
             }
-            _ => fail!("classify: unhandled type")
+            _ => panic!("classify: unhandled type")
         }
     }
 
@@ -328,7 +328,7 @@ fn llvec_len(cls: &[RegClass]) -> uint {
             SSEDs => {
                 tys.push(Type::f64(ccx));
             }
-            _ => fail!("llregtype: unhandled class")
+            _ => panic!("llregtype: unhandled class")
         }
         i += 1u;
     }
index 22fd943b68c7426fee14b6c4f14720052880d53e..1f4a0dadc0209e20f2c19729b419997482b28c17 100644 (file)
@@ -375,10 +375,9 @@ pub fn trans_unboxing_shim(bcx: Block,
         llshimmedargs.push(get_param(fcx.llfn, fcx.arg_pos(i) as u32));
     }
     assert!(!fcx.needs_ret_allocas);
-    let dest = match fcx.llretslotptr.get() {
-        Some(_) => Some(expr::SaveIn(fcx.get_ret_slot(bcx, return_type, "ret_slot"))),
-        None => None
-    };
+    let dest = fcx.llretslotptr.get().map(|_|
+        expr::SaveIn(fcx.get_ret_slot(bcx, return_type, "ret_slot"))
+    );
     bcx = trans_call_inner(bcx,
                            None,
                            function_type,
@@ -491,7 +490,7 @@ pub fn trans_fn_ref_with_substs(
     };
 
     // If this is an unboxed closure, redirect to it.
-    match closure::get_or_create_declaration_if_unboxed_closure(ccx, def_id) {
+    match closure::get_or_create_declaration_if_unboxed_closure(bcx, def_id) {
         None => {}
         Some(llfn) => return llfn,
     }
@@ -690,9 +689,9 @@ pub fn trans_call_inner<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     // Introduce a temporary cleanup scope that will contain cleanups
     // for the arguments while they are being evaluated. The purpose
-    // this cleanup is to ensure that, should a failure occur while
+    // this cleanup is to ensure that, should a panic occur while
     // evaluating argument N, the values for arguments 0...N-1 are all
-    // cleaned up. If no failure occurs, the values are handed off to
+    // cleaned up. If no panic occurs, the values are handed off to
     // the callee, and hence none of the cleanups in this temporary
     // scope will ever execute.
     let fcx = bcx.fcx;
@@ -705,7 +704,7 @@ pub fn trans_call_inner<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let (abi, ret_ty) = match ty::get(callee_ty).sty {
         ty::ty_bare_fn(ref f) => (f.abi, f.sig.output),
         ty::ty_closure(ref f) => (f.abi, f.sig.output),
-        _ => fail!("expected bare rust fn or closure in trans_call_inner")
+        _ => panic!("expected bare rust fn or closure in trans_call_inner")
     };
 
     let (llfn, llenv, llself) = match callee.data {
@@ -757,24 +756,29 @@ pub fn trans_call_inner<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     // Generate a location to store the result. If the user does
     // not care about the result, just make a stack slot.
-    let opt_llretslot = match dest {
-        None => {
-            assert!(!type_of::return_uses_outptr(ccx, ret_ty));
-            None
-        }
-        Some(expr::SaveIn(dst)) => Some(dst),
-        Some(expr::Ignore) if !is_rust_fn ||
-                type_of::return_uses_outptr(ccx, ret_ty) ||
-                ty::type_needs_drop(bcx.tcx(), ret_ty) => {
-            if !type_is_zero_size(ccx, ret_ty) {
-                Some(alloc_ty(bcx, ret_ty, "__llret"))
+    let opt_llretslot = dest.and_then(|dest| match dest {
+        expr::SaveIn(dst) => Some(dst),
+        expr::Ignore => {
+            let ret_ty = match ret_ty {
+                ty::FnConverging(ret_ty) => ret_ty,
+                ty::FnDiverging => ty::mk_nil()
+            };
+            if !is_rust_fn ||
+              type_of::return_uses_outptr(ccx, ret_ty) ||
+              ty::type_needs_drop(bcx.tcx(), ret_ty) {
+                // Push the out-pointer if we use an out-pointer for this
+                // return type, otherwise push "undef".
+                if type_is_zero_size(ccx, ret_ty) {
+                    let llty = type_of::type_of(ccx, ret_ty);
+                    Some(C_undef(llty.ptr_to()))
+                } else {
+                    Some(alloc_ty(bcx, ret_ty, "__llret"))
+                }
             } else {
-                let llty = type_of::type_of(ccx, ret_ty);
-                Some(C_undef(llty.ptr_to()))
+                None
             }
         }
-        Some(expr::Ignore) => None
-    };
+    });
 
     let mut llresult = unsafe {
         llvm::LLVMGetUndef(Type::nil(ccx).ptr_to().to_ref())
@@ -789,17 +793,15 @@ pub fn trans_call_inner<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     if is_rust_fn {
         let mut llargs = Vec::new();
 
-        // Push the out-pointer if we use an out-pointer for this
-        // return type, otherwise push "undef".
-        if type_of::return_uses_outptr(ccx, ret_ty) {
-            llargs.push(opt_llretslot.unwrap());
+        if let (ty::FnConverging(ret_ty), Some(llretslot)) = (ret_ty, opt_llretslot) {
+            if type_of::return_uses_outptr(ccx, ret_ty) {
+                llargs.push(llretslot);
+            }
         }
 
         // Push the environment (or a trait object's self).
         match (llenv, llself) {
-            (Some(llenv), None) => {
-                llargs.push(llenv)
-            },
+            (Some(llenv), None) => llargs.push(llenv),
             (None, Some(llself)) => llargs.push(llself),
             _ => {}
         }
@@ -827,15 +829,15 @@ pub fn trans_call_inner<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
         // If the Rust convention for this type is return via
         // the return value, copy it into llretslot.
-        match opt_llretslot {
-            Some(llretslot) => {
+        match (opt_llretslot, ret_ty) {
+            (Some(llretslot), ty::FnConverging(ret_ty)) => {
                 if !type_of::return_uses_outptr(bcx.ccx(), ret_ty) &&
                     !type_is_zero_size(bcx.ccx(), ret_ty)
                 {
                     store_ty(bcx, llret, llretslot, ret_ty)
                 }
             }
-            None => {}
+            (_, _) => {}
         }
     } else {
         // Lang items are the only case where dest is None, and
@@ -845,7 +847,7 @@ pub fn trans_call_inner<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         let mut llargs = Vec::new();
         let arg_tys = match args {
             ArgExprs(a) => a.iter().map(|x| expr_ty(bcx, &**x)).collect(),
-            _ => fail!("expected arg exprs.")
+            _ => panic!("expected arg exprs.")
         };
         bcx = trans_args(bcx,
                          args,
@@ -865,8 +867,8 @@ pub fn trans_call_inner<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     // If the caller doesn't care about the result of this fn call,
     // drop the temporary slot we made.
-    match (dest, opt_llretslot) {
-        (Some(expr::Ignore), Some(llretslot)) => {
+    match (dest, opt_llretslot, ret_ty) {
+        (Some(expr::Ignore), Some(llretslot), ty::FnConverging(ret_ty)) => {
             // drop the value if it is not being saved.
             bcx = glue::drop_ty(bcx, llretslot, ret_ty, call_info);
             call_lifetime_end(bcx, llretslot);
@@ -874,7 +876,7 @@ pub fn trans_call_inner<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         _ => {}
     }
 
-    if ty::type_is_bot(ret_ty) {
+    if ret_ty == ty::FnDiverging {
         Unreachable(bcx);
     }
 
@@ -1118,52 +1120,41 @@ pub fn trans_arg_datum<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     debug!("   arg datum: {}", arg_datum.to_string(bcx.ccx()));
 
     let mut val;
-    if ty::type_is_bot(arg_datum_ty) {
-        // For values of type _|_, we generate an
-        // "undef" value, as such a value should never
-        // be inspected. It's important for the value
-        // to have type lldestty (the callee's expected type).
-        let llformal_arg_ty = type_of::type_of_explicit_arg(ccx, formal_arg_ty);
-        unsafe {
-            val = llvm::LLVMGetUndef(llformal_arg_ty.to_ref());
+    // FIXME(#3548) use the adjustments table
+    match autoref_arg {
+        DoAutorefArg(arg_id) => {
+            // We will pass argument by reference
+            // We want an lvalue, so that we can pass by reference and
+            let arg_datum = unpack_datum!(
+                bcx, arg_datum.to_lvalue_datum(bcx, "arg", arg_id));
+            val = arg_datum.val;
         }
-    } else {
-        // FIXME(#3548) use the adjustments table
-        match autoref_arg {
-            DoAutorefArg(arg_id) => {
-                // We will pass argument by reference
-                // We want an lvalue, so that we can pass by reference and
-                let arg_datum = unpack_datum!(
-                    bcx, arg_datum.to_lvalue_datum(bcx, "arg", arg_id));
-                val = arg_datum.val;
-            }
-            DontAutorefArg => {
-                // Make this an rvalue, since we are going to be
-                // passing ownership.
-                let arg_datum = unpack_datum!(
-                    bcx, arg_datum.to_rvalue_datum(bcx, "arg"));
-
-                // Now that arg_datum is owned, get it into the appropriate
-                // mode (ref vs value).
-                let arg_datum = unpack_datum!(
-                    bcx, arg_datum.to_appropriate_datum(bcx));
-
-                // Technically, ownership of val passes to the callee.
-                // However, we must cleanup should we fail before the
-                // callee is actually invoked.
-                val = arg_datum.add_clean(bcx.fcx, arg_cleanup_scope);
-            }
+        DontAutorefArg => {
+            // Make this an rvalue, since we are going to be
+            // passing ownership.
+            let arg_datum = unpack_datum!(
+                bcx, arg_datum.to_rvalue_datum(bcx, "arg"));
+
+            // Now that arg_datum is owned, get it into the appropriate
+            // mode (ref vs value).
+            let arg_datum = unpack_datum!(
+                bcx, arg_datum.to_appropriate_datum(bcx));
+
+            // Technically, ownership of val passes to the callee.
+            // However, we must cleanup should we panic before the
+            // callee is actually invoked.
+            val = arg_datum.add_clean(bcx.fcx, arg_cleanup_scope);
         }
+    }
 
-        if formal_arg_ty != arg_datum_ty {
-            // this could happen due to e.g. subtyping
-            let llformal_arg_ty = type_of::type_of_explicit_arg(ccx, formal_arg_ty);
-            debug!("casting actual type ({}) to match formal ({})",
-                   bcx.val_to_string(val), bcx.llty_str(llformal_arg_ty));
-            debug!("Rust types: {}; {}", ty_to_string(bcx.tcx(), arg_datum_ty),
-                                         ty_to_string(bcx.tcx(), formal_arg_ty));
-            val = PointerCast(bcx, val, llformal_arg_ty);
-        }
+    if formal_arg_ty != arg_datum_ty {
+        // this could happen due to e.g. subtyping
+        let llformal_arg_ty = type_of::type_of_explicit_arg(ccx, formal_arg_ty);
+        debug!("casting actual type ({}) to match formal ({})",
+               bcx.val_to_string(val), bcx.llty_str(llformal_arg_ty));
+        debug!("Rust types: {}; {}", ty_to_string(bcx.tcx(), arg_datum_ty),
+                                     ty_to_string(bcx.tcx(), formal_arg_ty));
+        val = PointerCast(bcx, val, llformal_arg_ty);
     }
 
     debug!("--- trans_arg_datum passing {}", bcx.val_to_string(val));
index 827df48071af9221da0309ad38bed8b90d62e80d..e5825d7a38f1538988cdda83f51eaa2adfd7982f 100644 (file)
@@ -477,7 +477,7 @@ fn schedule_clean_in_custom_scope(&self,
     fn needs_invoke(&self) -> bool {
         /*!
          * Returns true if there are pending cleanups that should
-         * execute on failure.
+         * execute on panic.
          */
 
         self.scopes.borrow().iter().rev().any(|s| s.needs_invoke())
@@ -485,8 +485,8 @@ fn needs_invoke(&self) -> bool {
 
     fn get_landing_pad(&'blk self) -> BasicBlockRef {
         /*!
-         * Returns a basic block to branch to in the event of a failure.
-         * This block will run the failure cleanups and eventually
+         * Returns a basic block to branch to in the event of a panic.
+         * This block will run the panic cleanups and eventually
          * invoke the LLVM `Resume` instruction.
          */
 
@@ -497,7 +497,7 @@ fn get_landing_pad(&'blk self) -> BasicBlockRef {
         let orig_scopes_len = self.scopes_len();
         assert!(orig_scopes_len > 0);
 
-        // Remove any scopes that do not have cleanups on failure:
+        // Remove any scopes that do not have cleanups on panic:
         let mut popped_scopes = vec!();
         while !self.top_scope(|s| s.needs_invoke()) {
             debug!("top scope does not need invoke");
index 94df7fa57db2310d29170703525a28802ea65435..b6f45b2ccda774754abf154943a6acb36e089c5b 100644 (file)
@@ -23,6 +23,7 @@
 use middle::trans::datum::{Datum, DatumBlock, Expr, Lvalue, rvalue_scratch_datum};
 use middle::trans::debuginfo;
 use middle::trans::expr;
+use middle::trans::monomorphize::MonoId;
 use middle::trans::type_of::*;
 use middle::trans::type_::Type;
 use middle::ty;
@@ -312,7 +313,8 @@ fn load_unboxed_closure_environment<'blk, 'tcx>(
     }
 
     // Special case for small by-value selfs.
-    let self_type = self_type_for_unboxed_closure(bcx.ccx(), closure_id);
+    let self_type = self_type_for_unboxed_closure(bcx.ccx(), closure_id,
+                                                  node_id_type(bcx, closure_id.node));
     let kind = kind_for_unboxed_closure(bcx.ccx(), closure_id);
     let llenv = if kind == ty::FnOnceUnboxedClosureKind &&
             !arg_is_indirect(bcx.ccx(), self_type) {
@@ -418,15 +420,26 @@ pub fn trans_expr_fn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
 /// Returns the LLVM function declaration for an unboxed closure, creating it
 /// if necessary. If the ID does not correspond to a closure ID, returns None.
-pub fn get_or_create_declaration_if_unboxed_closure(ccx: &CrateContext,
-                                                    closure_id: ast::DefId)
-                                                    -> Option<ValueRef> {
+pub fn get_or_create_declaration_if_unboxed_closure<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
+                                                                closure_id: ast::DefId)
+                                                                -> Option<ValueRef> {
+    let ccx = bcx.ccx();
     if !ccx.tcx().unboxed_closures.borrow().contains_key(&closure_id) {
         // Not an unboxed closure.
         return None
     }
 
-    match ccx.unboxed_closure_vals().borrow().find(&closure_id) {
+    let function_type = node_id_type(bcx, closure_id.node);
+    let params = match ty::get(function_type).sty {
+        ty::ty_unboxed_closure(_, _, ref substs) => substs.types.clone(),
+        _ => unreachable!()
+    };
+    let mono_id = MonoId {
+        def: closure_id,
+        params: params
+    };
+
+    match ccx.unboxed_closure_vals().borrow().find(&mono_id) {
         Some(llfn) => {
             debug!("get_or_create_declaration_if_unboxed_closure(): found \
                     closure");
@@ -435,9 +448,7 @@ pub fn get_or_create_declaration_if_unboxed_closure(ccx: &CrateContext,
         None => {}
     }
 
-    let function_type = ty::mk_unboxed_closure(ccx.tcx(),
-                                               closure_id,
-                                               ty::ReStatic);
+    let function_type = node_id_type(bcx, closure_id.node);
     let symbol = ccx.tcx().map.with_path(closure_id.node, |path| {
         mangle_internal_name_by_path_and_seq(path, "unboxed_closure")
     });
@@ -449,9 +460,9 @@ pub fn get_or_create_declaration_if_unboxed_closure(ccx: &CrateContext,
 
     debug!("get_or_create_declaration_if_unboxed_closure(): inserting new \
             closure {} (type {})",
-           closure_id,
+           mono_id,
            ccx.tn().type_to_string(val_ty(llfn)));
-    ccx.unboxed_closure_vals().borrow_mut().insert(closure_id, llfn);
+    ccx.unboxed_closure_vals().borrow_mut().insert(mono_id, llfn);
 
     Some(llfn)
 }
@@ -469,7 +480,7 @@ pub fn trans_unboxed_closure<'blk, 'tcx>(
 
     let closure_id = ast_util::local_def(id);
     let llfn = get_or_create_declaration_if_unboxed_closure(
-        bcx.ccx(),
+        bcx,
         closure_id).unwrap();
 
     let unboxed_closures = bcx.tcx().unboxed_closures.borrow();
@@ -612,10 +623,17 @@ pub fn get_wrapper_for_bare_fn(ccx: &CrateContext,
     llargs.extend(args.iter().map(|arg| arg.val));
 
     let retval = Call(bcx, fn_ptr, llargs.as_slice(), None);
-    if type_is_zero_size(ccx, f.sig.output) || fcx.llretslotptr.get().is_some() {
-        RetVoid(bcx);
-    } else {
-        Ret(bcx, retval);
+    match f.sig.output {
+        ty::FnConverging(output_type) => {
+            if type_is_zero_size(ccx, output_type) || fcx.llretslotptr.get().is_some() {
+                RetVoid(bcx);
+            } else {
+                Ret(bcx, retval);
+            }
+        }
+        ty::FnDiverging => {
+            RetVoid(bcx);
+        }
     }
 
     // HACK(eddyb) finish_fn cannot be used here, we returned directly.
index 496838c9e84f23ecbd1a253fd9173356fc3afa36..60b107c049f412c9cefa031ca3882de4eb623b81 100644 (file)
@@ -74,7 +74,7 @@ pub fn type_is_immediate(ccx: &CrateContext, ty: ty::t) -> bool {
     let tcx = ccx.tcx();
     let simple = ty::type_is_scalar(ty) ||
         ty::type_is_unique(ty) || ty::type_is_region_ptr(ty) ||
-        type_is_newtype_immediate(ccx, ty) || ty::type_is_bot(ty) ||
+        type_is_newtype_immediate(ccx, ty) ||
         ty::type_is_simd(tcx, ty);
     if simple && !ty::type_is_fat_ptr(tcx, ty) {
         return true;
@@ -83,7 +83,6 @@ pub fn type_is_immediate(ccx: &CrateContext, ty: ty::t) -> bool {
         return false;
     }
     match ty::get(ty).sty {
-        ty::ty_bot => true,
         ty::ty_struct(..) | ty::ty_enum(..) | ty::ty_tup(..) |
         ty::ty_unboxed_closure(..) => {
             let llty = sizing_type_of(ccx, ty);
@@ -113,7 +112,7 @@ pub fn return_type_is_void(ccx: &CrateContext, ty: ty::t) -> bool {
      * return type (in order to aid with C ABI compatibility).
      */
 
-    ty::type_is_nil(ty) || ty::type_is_bot(ty) || ty::type_is_empty(ccx.tcx(), ty)
+    ty::type_is_nil(ty) || ty::type_is_empty(ccx.tcx(), ty)
 }
 
 /// Generates a unique symbol based off the name given. This is used to create
@@ -217,7 +216,7 @@ fn substp(&self, tcx: &ty::ctxt, param_substs: &param_substs)
               -> Self;
 }
 
-impl<T:Subst+Clone> SubstP for T {
+impl<T: Subst + Clone> SubstP for T {
     fn substp(&self, tcx: &ty::ctxt, substs: &param_substs) -> T {
         self.subst(tcx, &substs.substs)
     }
@@ -343,9 +342,12 @@ pub fn get_llreturn(&self) -> BasicBlockRef {
         self.llreturn.get().unwrap()
     }
 
-    pub fn get_ret_slot(&self, bcx: Block, ty: ty::t, name: &str) -> ValueRef {
+    pub fn get_ret_slot(&self, bcx: Block, output: ty::FnOutput, name: &str) -> ValueRef {
         if self.needs_ret_allocas {
-            base::alloca_no_lifetime(bcx, type_of::type_of(bcx.ccx(), ty), name)
+            base::alloca_no_lifetime(bcx, match output {
+                ty::FnConverging(output_type) => type_of::type_of(bcx.ccx(), output_type),
+                ty::FnDiverging => Type::void(bcx.ccx())
+            }, name)
         } else {
             self.llretslotptr.get().unwrap()
         }
@@ -601,7 +603,7 @@ pub fn C_int<I: AsI64>(ccx: &CrateContext, i: I) -> ValueRef {
     match machine::llbitsize_of_real(ccx, ccx.int_type()) {
         32 => assert!(v < (1<<31) && v >= -(1<<31)),
         64 => {},
-        n => fail!("unsupported target size: {}", n)
+        n => panic!("unsupported target size: {}", n)
     }
 
     C_integral(ccx.int_type(), v as u64, true)
@@ -613,7 +615,7 @@ pub fn C_uint<I: AsU64>(ccx: &CrateContext, i: I) -> ValueRef {
     match machine::llbitsize_of_real(ccx, ccx.int_type()) {
         32 => assert!(v < (1<<32)),
         64 => {},
-        n => fail!("unsupported target size: {}", n)
+        n => panic!("unsupported target size: {}", n)
     }
 
     C_integral(ccx.int_type(), v, false)
index 90159389688a6a0e3e7dd8cd3f57eec42f44ad9b..955fcbfab842f93655bb3e3b748b4ee04f4c3d9b 100644 (file)
@@ -138,7 +138,7 @@ pub struct LocalCrateContext {
     builder: BuilderRef_res,
 
     /// Holds the LLVM values for closure IDs.
-    unboxed_closure_vals: RefCell<DefIdMap<ValueRef>>,
+    unboxed_closure_vals: RefCell<HashMap<MonoId, ValueRef>>,
 
     dbg_cx: Option<debuginfo::CrateDebugContext>,
 
@@ -419,7 +419,7 @@ fn new(shared: &SharedCrateContext,
                 int_type: Type::from_ref(ptr::null_mut()),
                 opaque_vec_type: Type::from_ref(ptr::null_mut()),
                 builder: BuilderRef_res(llvm::LLVMCreateBuilderInContext(llcx)),
-                unboxed_closure_vals: RefCell::new(DefIdMap::new()),
+                unboxed_closure_vals: RefCell::new(HashMap::new()),
                 dbg_cx: dbg_cx,
                 eh_personality: RefCell::new(None),
                 intrinsics: RefCell::new(HashMap::new()),
@@ -453,7 +453,7 @@ fn new(shared: &SharedCrateContext,
     /// Create a dummy `CrateContext` from `self` and  the provided
     /// `SharedCrateContext`.  This is somewhat dangerous because `self` may
     /// not actually be an element of `shared.local_ccxs`, which can cause some
-    /// operations to `fail` unexpectedly.
+    /// operations to panic unexpectedly.
     ///
     /// This is used in the `LocalCrateContext` constructor to allow calling
     /// functions that expect a complete `CrateContext`, even before the local
@@ -527,7 +527,7 @@ pub fn get_intrinsic(&self, key: & &'static str) -> ValueRef {
         }
         match declare_intrinsic(self, key) {
             Some(v) => return v,
-            None => fail!()
+            None => panic!()
         }
     }
 
@@ -689,7 +689,7 @@ pub fn opaque_vec_type(&self) -> Type {
         self.local.opaque_vec_type
     }
 
-    pub fn unboxed_closure_vals<'a>(&'a self) -> &'a RefCell<DefIdMap<ValueRef>> {
+    pub fn unboxed_closure_vals<'a>(&'a self) -> &'a RefCell<HashMap<MonoId,ValueRef>> {
         &self.local.unboxed_closure_vals
     }
 
index 995943c301731fe27f1e7b5404d0df2f4283a03e..911ae42e142d87e867c5a572471a05817a29cfa5 100644 (file)
@@ -11,7 +11,7 @@
 use llvm::*;
 use driver::config::FullDebugInfo;
 use middle::def;
-use middle::lang_items::{FailFnLangItem, FailBoundsCheckFnLangItem};
+use middle::lang_items::{PanicFnLangItem, PanicBoundsCheckFnLangItem};
 use middle::trans::_match;
 use middle::trans::adt;
 use middle::trans::base::*;
@@ -296,7 +296,7 @@ pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                                      .borrow())[method_call]
                                      .ty;
     let method_type = monomorphize_type(loopback_bcx_in, method_type);
-    let method_result_type = ty::ty_fn_ret(method_type);
+    let method_result_type = ty::ty_fn_ret(method_type).unwrap();
     let option_cleanup_scope = body_bcx_in.fcx.push_custom_cleanup_scope();
     let option_cleanup_scope_id = cleanup::CustomScope(option_cleanup_scope);
 
@@ -402,10 +402,6 @@ pub fn trans_loop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     fcx.pop_loop_cleanup_scope(loop_id);
 
-    if ty::type_is_bot(node_id_type(bcx, loop_id)) {
-        Unreachable(next_bcx_in);
-    }
-
     return next_bcx_in;
 }
 
@@ -465,7 +461,7 @@ pub fn trans_ret<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let dest = match (fcx.llretslotptr.get(), e) {
         (Some(_), Some(e)) => {
             let ret_ty = expr_ty(bcx, &*e);
-            expr::SaveIn(fcx.get_ret_slot(bcx, ret_ty, "ret_slot"))
+            expr::SaveIn(fcx.get_ret_slot(bcx, ty::FnConverging(ret_ty), "ret_slot"))
         }
         _ => expr::Ignore,
     };
@@ -502,7 +498,7 @@ pub fn trans_fail<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let expr_file_line_const = C_struct(ccx, &[v_str, filename, line], false);
     let expr_file_line = consts::const_addr_of(ccx, expr_file_line_const, ast::MutImmutable);
     let args = vec!(expr_file_line);
-    let did = langcall(bcx, Some(sp), "", FailFnLangItem);
+    let did = langcall(bcx, Some(sp), "", PanicFnLangItem);
     let bcx = callee::trans_lang_call(bcx,
                                       did,
                                       args.as_slice(),
@@ -529,7 +525,7 @@ pub fn trans_fail_bounds_check<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let file_line_const = C_struct(ccx, &[filename, line], false);
     let file_line = consts::const_addr_of(ccx, file_line_const, ast::MutImmutable);
     let args = vec!(file_line, index, len);
-    let did = langcall(bcx, Some(sp), "", FailBoundsCheckFnLangItem);
+    let did = langcall(bcx, Some(sp), "", PanicBoundsCheckFnLangItem);
     let bcx = callee::trans_lang_call(bcx,
                                       did,
                                       args.as_slice(),
index ea6d9e1dd8c48a61a93ae7618934948e66aa5cd9..8ee258e77fa5d3493f0ee7d290c0eb1ac6b942c1 100644 (file)
@@ -650,7 +650,7 @@ pub fn to_llscalarish(self, bcx: Block) -> ValueRef {
     }
 
     pub fn to_llbool(self, bcx: Block) -> ValueRef {
-        assert!(ty::type_is_bool(self.ty) || ty::type_is_bot(self.ty))
+        assert!(ty::type_is_bool(self.ty))
         self.to_llscalarish(bcx)
     }
 }
index 3e07eaf9586de6658a8800fd3e60647178ace6f1..5e039a3c098c70ee7e1f4e4e9c8a60eef6ae1068 100644 (file)
@@ -190,7 +190,7 @@ struct List {
 use llvm::{ModuleRef, ContextRef, ValueRef};
 use llvm::debuginfo::*;
 use metadata::csearch;
-use middle::subst;
+use middle::subst::{mod, Subst};
 use middle::trans::adt;
 use middle::trans::common::*;
 use middle::trans::machine;
@@ -352,7 +352,6 @@ fn get_unique_type_id_of_type(&mut self, cx: &CrateContext, type_: ty::t) -> Uni
 
         match ty::get(type_).sty {
             ty::ty_nil      |
-            ty::ty_bot      |
             ty::ty_bool     |
             ty::ty_char     |
             ty::ty_str      |
@@ -451,18 +450,25 @@ fn get_unique_type_id_of_type(&mut self, cx: &CrateContext, type_: ty::t) -> Uni
                 }
 
                 unique_type_id.push_str(")->");
-                let return_type_id = self.get_unique_type_id_of_type(cx, sig.output);
-                let return_type_id = self.get_unique_type_id_as_string(return_type_id);
-                unique_type_id.push_str(return_type_id.as_slice());
+                match sig.output {
+                    ty::FnConverging(ret_ty) => {
+                        let return_type_id = self.get_unique_type_id_of_type(cx, ret_ty);
+                        let return_type_id = self.get_unique_type_id_as_string(return_type_id);
+                        unique_type_id.push_str(return_type_id.as_slice());
+                    }
+                    ty::FnDiverging => {
+                        unique_type_id.push_str("!");
+                    }
+                }
             },
             ty::ty_closure(box ref closure_ty) => {
                 self.get_unique_type_id_of_closure_type(cx,
                                                         closure_ty.clone(),
                                                         &mut unique_type_id);
             },
-            ty::ty_unboxed_closure(ref def_id, _) => {
+            ty::ty_unboxed_closure(ref def_id, _, ref substs) => {
                 let closure_ty = cx.tcx().unboxed_closures.borrow()
-                                   .find(def_id).unwrap().closure_type.clone();
+                                   .find(def_id).unwrap().closure_type.subst(cx.tcx(), substs);
                 self.get_unique_type_id_of_closure_type(cx,
                                                         closure_ty,
                                                         &mut unique_type_id);
@@ -578,9 +584,16 @@ fn get_unique_type_id_of_closure_type(&mut self,
 
         unique_type_id.push_str("|->");
 
-        let return_type_id = self.get_unique_type_id_of_type(cx, sig.output);
-        let return_type_id = self.get_unique_type_id_as_string(return_type_id);
-        unique_type_id.push_str(return_type_id.as_slice());
+        match sig.output {
+            ty::FnConverging(ret_ty) => {
+                let return_type_id = self.get_unique_type_id_of_type(cx, ret_ty);
+                let return_type_id = self.get_unique_type_id_as_string(return_type_id);
+                unique_type_id.push_str(return_type_id.as_slice());
+            }
+            ty::FnDiverging => {
+                unique_type_id.push_str("!");
+            }
+        }
 
         unique_type_id.push(':');
 
@@ -1707,13 +1720,25 @@ fn scope_metadata(fcx: &FunctionContext,
     }
 }
 
+fn diverging_type_metadata(cx: &CrateContext) -> DIType {
+    "!".with_c_str(|name| {
+        unsafe {
+            llvm::LLVMDIBuilderCreateBasicType(
+                DIB(cx),
+                name,
+                bytes_to_bits(0),
+                bytes_to_bits(0),
+                DW_ATE_unsigned)
+        }
+    })
+}
+
 fn basic_type_metadata(cx: &CrateContext, t: ty::t) -> DIType {
 
     debug!("basic_type_metadata: {}", ty::get(t));
 
     let (name, encoding) = match ty::get(t).sty {
         ty::ty_nil => ("()".to_string(), DW_ATE_unsigned),
-        ty::ty_bot => ("!".to_string(), DW_ATE_unsigned),
         ty::ty_bool => ("bool".to_string(), DW_ATE_boolean),
         ty::ty_char => ("char".to_string(), DW_ATE_unsigned_char),
         ty::ty_int(int_ty) => match int_ty {
@@ -2748,9 +2773,12 @@ fn subroutine_type_metadata(cx: &CrateContext,
     let mut signature_metadata: Vec<DIType> = Vec::with_capacity(signature.inputs.len() + 1);
 
     // return type
-    signature_metadata.push(match ty::get(signature.output).sty {
-        ty::ty_nil => ptr::null_mut(),
-        _ => type_metadata(cx, signature.output, span)
+    signature_metadata.push(match signature.output {
+        ty::FnConverging(ret_ty) => match ty::get(ret_ty).sty {
+            ty::ty_nil => ptr::null_mut(),
+            _ => type_metadata(cx, ret_ty, span)
+        },
+        ty::FnDiverging => diverging_type_metadata(cx)
     });
 
     // regular arguments
@@ -2855,7 +2883,6 @@ fn type_metadata(cx: &CrateContext,
     let sty = &ty::get(t).sty;
     let MetadataCreationResult { metadata, already_stored_in_typemap } = match *sty {
         ty::ty_nil      |
-        ty::ty_bot      |
         ty::ty_bool     |
         ty::ty_char     |
         ty::ty_int(_)   |
@@ -2911,9 +2938,9 @@ fn type_metadata(cx: &CrateContext,
         ty::ty_closure(ref closurety) => {
             subroutine_type_metadata(cx, unique_type_id, &closurety.sig, usage_site_span)
         }
-        ty::ty_unboxed_closure(ref def_id, _) => {
+        ty::ty_unboxed_closure(ref def_id, _, ref substs) => {
             let sig = cx.tcx().unboxed_closures.borrow()
-                        .find(def_id).unwrap().closure_type.sig.clone();
+                        .find(def_id).unwrap().closure_type.sig.subst(cx.tcx(), substs);
             subroutine_type_metadata(cx, unique_type_id, &sig, usage_site_span)
         }
         ty::ty_struct(def_id, ref substs) => {
@@ -3647,7 +3674,6 @@ fn push_debuginfo_type_name(cx: &CrateContext,
                             output:&mut String) {
     match ty::get(t).sty {
         ty::ty_nil               => output.push_str("()"),
-        ty::ty_bot               => output.push_str("!"),
         ty::ty_bool              => output.push_str("bool"),
         ty::ty_char              => output.push_str("char"),
         ty::ty_str               => output.push_str("str"),
@@ -3749,9 +3775,15 @@ fn push_debuginfo_type_name(cx: &CrateContext,
 
             output.push(')');
 
-            if !ty::type_is_nil(sig.output) {
-                output.push_str(" -> ");
-                push_debuginfo_type_name(cx, sig.output, true, output);
+            match sig.output {
+                ty::FnConverging(result_type) if ty::type_is_nil(result_type) => {}
+                ty::FnConverging(result_type) => {
+                    output.push_str(" -> ");
+                    push_debuginfo_type_name(cx, result_type, true, output);
+                }
+                ty::FnDiverging => {
+                    output.push_str(" -> !");
+                }
             }
         },
         ty::ty_closure(box ty::ClosureTy { fn_style,
@@ -3803,9 +3835,15 @@ fn push_debuginfo_type_name(cx: &CrateContext,
 
             output.push(param_list_closing_char);
 
-            if !ty::type_is_nil(sig.output) {
-                output.push_str(" -> ");
-                push_debuginfo_type_name(cx, sig.output, true, output);
+            match sig.output {
+                ty::FnConverging(result_type) if ty::type_is_nil(result_type) => {}
+                ty::FnConverging(result_type) => {
+                    output.push_str(" -> ");
+                    push_debuginfo_type_name(cx, result_type, true, output);
+                }
+                ty::FnDiverging => {
+                    output.push_str(" -> !");
+                }
             }
         },
         ty::ty_unboxed_closure(..) => {
index d6df0d88a769ffde6ea60bfef002905f3bcf2920..013483d0003c31e5ca4c43a5181afeffd286e819 100644 (file)
@@ -132,7 +132,7 @@ fn foo() -> Box<int> { ... }
 ## The Cleanup module
 
 The cleanup module tracks what values need to be cleaned up as scopes
-are exited, either via failure or just normal control flow. The basic
+are exited, either via panic or just normal control flow. The basic
 idea is that the function context maintains a stack of cleanup scopes
 that are pushed/popped as we traverse the AST tree. There is typically
 at least one cleanup scope per AST node; some AST nodes may introduce
@@ -142,9 +142,9 @@ fn foo() -> Box<int> { ... }
 Typically, when a scope is popped, we will also generate the code for
 each of its cleanups at that time. This corresponds to a normal exit
 from a block (for example, an expression completing evaluation
-successfully without failure). However, it is also possible to pop a
+successfully without panic). However, it is also possible to pop a
 block *without* executing its cleanups; this is typically used to
-guard intermediate values that must be cleaned up on failure, but not
+guard intermediate values that must be cleaned up on panic, but not
 if everything goes right. See the section on custom scopes below for
 more details.
 
@@ -170,7 +170,7 @@ fn foo() -> Box<int> { ... }
 byproducts that need to be freed, then you should use temporary custom
 scopes to ensure that those byproducts will get freed on unwind.  For
 example, an expression like `box foo()` will first allocate a box in the
-heap and then call `foo()` -- if `foo()` should fail, this box needs
+heap and then call `foo()` -- if `foo()` should panic, this box needs
 to be *shallowly* freed.
 
 ### Long-distance jumps
@@ -178,13 +178,13 @@ fn foo() -> Box<int> { ... }
 In addition to popping a scope, which corresponds to normal control
 flow exiting the scope, we may also *jump out* of a scope into some
 earlier scope on the stack. This can occur in response to a `return`,
-`break`, or `continue` statement, but also in response to failure. In
+`break`, or `continue` statement, but also in response to panic. In
 any of these cases, we will generate a series of cleanup blocks for
 each of the scopes that is exited. So, if the stack contains scopes A
 ... Z, and we break out of a loop whose corresponding cleanup scope is
 X, we would generate cleanup blocks for the cleanups in X, Y, and Z.
 After cleanup is done we would branch to the exit point for scope X.
-But if failure should occur, we would generate cleanups for all the
+But if panic should occur, we would generate cleanups for all the
 scopes from A to Z and then resume the unwind process afterwards.
 
 To avoid generating tons of code, we cache the cleanup blocks that we
@@ -211,7 +211,7 @@ fn foo() -> Box<int> { ... }
 
 Custom cleanup scopes are used for a variety of purposes. The most
 common though is to handle temporary byproducts, where cleanup only
-needs to occur on failure. The general strategy is to push a custom
+needs to occur on panic. The general strategy is to push a custom
 cleanup scope, schedule *shallow* cleanups into the custom scope, and
 then pop the custom scope (without transing the cleanups) when
 execution succeeds normally. This way the cleanups are only trans'd on
@@ -229,7 +229,7 @@ fn foo() -> Box<int> { ... }
 5. Pop the scope C.
 6. Return the box as an rvalue.
 
-This way, if a failure occurs while transing `expr`, the custom
+This way, if a panic occurs while transing `expr`, the custom
 cleanup scope C is pushed and hence the box will be freed. The trans
 code for `expr` itself is responsible for freeing any other byproducts
 that may be in play.
index 834441d4430b0d4ddf9a118be82c95f9e22b90a0..4d004c85f6e5f1ce47b3c93e23bef00d0a8426cd 100644 (file)
@@ -609,7 +609,7 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             start.as_ref().map(|e| args.push((unpack_datum!(bcx, trans(bcx, &**e)), e.id)));
             end.as_ref().map(|e| args.push((unpack_datum!(bcx, trans(bcx, &**e)), e.id)));
 
-            let result_ty = ty::ty_fn_ret(monomorphize_type(bcx, method_ty.unwrap()));
+            let result_ty = ty::ty_fn_ret(monomorphize_type(bcx, method_ty.unwrap())).unwrap();
             let scratch = rvalue_scratch_datum(bcx, result_ty, "trans_slice");
 
             unpack_result!(bcx,
@@ -757,7 +757,7 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                                    base_datum,
                                                    vec![(ix_datum, idx.id)],
                                                    None));
-            let ref_ty = ty::ty_fn_ret(monomorphize_type(bcx, method_ty));
+            let ref_ty = ty::ty_fn_ret(monomorphize_type(bcx, method_ty)).unwrap();
             let elt_ty = match ty::deref(ref_ty, true) {
                 None => {
                     bcx.tcx().sess.span_bug(index_expr.span,
@@ -940,6 +940,7 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             controlflow::trans_loop(bcx, expr.id, &**body)
         }
         ast::ExprAssign(ref dst, ref src) => {
+            let src_datum = unpack_datum!(bcx, trans(bcx, &**src));
             let dst_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, &**dst, "assign"));
 
             if ty::type_needs_drop(bcx.tcx(), dst_datum.ty) {
@@ -960,7 +961,6 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 // We could avoid this intermediary with some analysis
                 // to determine whether `dst` may possibly own `src`.
                 debuginfo::set_source_location(bcx.fcx, expr.id, expr.span);
-                let src_datum = unpack_datum!(bcx, trans(bcx, &**src));
                 let src_datum = unpack_datum!(
                     bcx, src_datum.to_rvalue_datum(bcx, "ExprAssign"));
                 bcx = glue::drop_ty(bcx,
@@ -969,7 +969,7 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                     Some(NodeInfo { id: expr.id, span: expr.span }));
                 src_datum.store_to(bcx, dst_datum.val)
             } else {
-                trans_into(bcx, &**src, SaveIn(dst_datum.to_llref()))
+                src_datum.store_to(bcx, dst_datum.val)
             }
         }
         ast::ExprAssignOp(op, ref dst, ref src) => {
@@ -1263,7 +1263,7 @@ pub fn with_field_tys<R>(tcx: &ty::ctxt,
      * Helper for enumerating the field types of structs, enums, or records.
      * The optional node ID here is the node ID of the path identifying the enum
      * variant in use. If none, this cannot possibly an enum variant (so, if it
-     * is and `node_id_opt` is none, this function fails).
+     * is and `node_id_opt` is none, this function panics).
      */
 
     match ty::get(ty).sty {
@@ -1421,7 +1421,7 @@ pub fn trans_adt<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     };
 
     // This scope holds intermediates that must be cleaned should
-    // failure occur before the ADT as a whole is ready.
+    // panic occur before the ADT as a whole is ready.
     let custom_cleanup_scope = fcx.push_custom_cleanup_scope();
 
     // First we trans the base, if we have one, to the dest
@@ -1614,8 +1614,7 @@ fn trans_eager_binop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let tcx = bcx.tcx();
     let is_simd = ty::type_is_simd(tcx, lhs_t);
     let intype = {
-        if ty::type_is_bot(lhs_t) { rhs_t }
-        else if is_simd { ty::simd_type(tcx, lhs_t) }
+        if is_simd { ty::simd_type(tcx, lhs_t) }
         else { lhs_t }
     };
     let is_float = ty::type_is_fp(intype);
@@ -1675,9 +1674,7 @@ fn trans_eager_binop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         } else { LShr(bcx, lhs, rhs) }
       }
       ast::BiEq | ast::BiNe | ast::BiLt | ast::BiGe | ast::BiLe | ast::BiGt => {
-        if ty::type_is_bot(rhs_t) {
-            C_bool(bcx.ccx(), false)
-        } else if ty::type_is_scalar(rhs_t) {
+        if ty::type_is_scalar(rhs_t) {
             unpack_result!(bcx, base::compare_scalar_types(bcx, lhs, rhs, rhs_t, op))
         } else if is_simd {
             base::compare_simd_types(bcx, lhs, rhs, intype, ty::simd_size(tcx, lhs_t), op)
@@ -2098,7 +2095,7 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 _ => datum
             };
 
-            let ref_ty = ty::ty_fn_ret(monomorphize_type(bcx, method_ty));
+            let ref_ty = ty::ty_fn_ret(monomorphize_type(bcx, method_ty)).unwrap();
             let scratch = rvalue_scratch_datum(bcx, ref_ty, "overloaded_deref");
 
             unpack_result!(bcx, trans_overloaded_op(bcx, expr, method_call,
@@ -2117,7 +2114,7 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 deref_owned_pointer(bcx, expr, datum, content_ty)
             } else {
                 // A fat pointer and an opened DST value have the same
-                // represenation just different types. Since there is no
+                // representation just different types. Since there is no
                 // temporary for `*e` here (because it is unsized), we cannot
                 // emulate the sized object code path for running drop glue and
                 // free. Instead, we schedule cleanup for `e`, turning it into
@@ -2142,7 +2139,7 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 // owner (or, in the case of *T, by the user).
                 DatumBlock::new(bcx, Datum::new(ptr, content_ty, LvalueExpr))
             } else {
-                // A fat pointer and an opened DST value have the same represenation
+                // A fat pointer and an opened DST value have the same representation
                 // just different types.
                 DatumBlock::new(bcx, Datum::new(datum.val,
                                                 ty::mk_open(bcx.tcx(), content_ty),
index 406ccc56a62389c017d62b609db73812d299940a..d979024c1607666be5405e8c52e19bb063402913 100644 (file)
@@ -49,9 +49,6 @@ struct ForeignTypes {
 
     /// LLVM types that will appear on the foreign function
     llsig: LlvmSignature,
-
-    /// True if there is a return value (not bottom, not unit)
-    ret_def: bool,
 }
 
 struct LlvmSignature {
@@ -63,6 +60,9 @@ struct LlvmSignature {
     // function, because the foreign function may opt to return via an
     // out pointer.
     llret_ty: Type,
+
+    /// True if there is a return value (not bottom, not unit)
+    ret_def: bool,
 }
 
 
@@ -286,11 +286,10 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         _ => ccx.sess().bug("trans_native_call called on non-function type")
     };
     let llsig = foreign_signature(ccx, &fn_sig, passed_arg_tys.as_slice());
-    let ret_def = !return_type_is_void(bcx.ccx(), fn_sig.output);
     let fn_type = cabi::compute_abi_info(ccx,
                                          llsig.llarg_tys.as_slice(),
                                          llsig.llret_ty,
-                                         ret_def);
+                                         llsig.ret_def);
 
     let arg_tys: &[cabi::ArgType] = fn_type.arg_tys.as_slice();
 
@@ -437,7 +436,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     // type to match because some ABIs will use a different type than
     // the Rust type. e.g., a {u32,u32} struct could be returned as
     // u64.
-    if ret_def && !fn_type.ret_ty.is_indirect() {
+    if llsig.ret_def && !fn_type.ret_ty.is_indirect() {
         let llrust_ret_ty = llsig.llret_ty;
         let llforeign_ret_ty = match fn_type.ret_ty.cast {
             Some(ty) => ty,
@@ -450,7 +449,12 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         debug!("llforeign_ret_ty={}", ccx.tn().type_to_string(llforeign_ret_ty));
 
         if llrust_ret_ty == llforeign_ret_ty {
-            base::store_ty(bcx, llforeign_retval, llretptr, fn_sig.output)
+            match fn_sig.output {
+                ty::FnConverging(result_ty) => {
+                    base::store_ty(bcx, llforeign_retval, llretptr, result_ty)
+                }
+                ty::FnDiverging => {}
+            }
         } else {
             // The actual return type is a struct, but the ABI
             // adaptation code has cast it into some scalar type.  The
@@ -547,9 +551,9 @@ pub fn decl_rust_fn_with_foreign_abi(ccx: &CrateContext,
             let c = llvm_calling_convention(ccx, fn_ty.abi);
             c.unwrap_or(llvm::CCallConv)
         }
-        _ => fail!("expected bare fn in decl_rust_fn_with_foreign_abi")
+        _ => panic!("expected bare fn in decl_rust_fn_with_foreign_abi")
     };
-    let llfn = base::decl_fn(ccx, name, cconv, llfn_ty, ty::mk_nil());
+    let llfn = base::decl_fn(ccx, name, cconv, llfn_ty, ty::FnConverging(ty::mk_nil()));
     add_argument_attributes(&tys, llfn);
     debug!("decl_rust_fn_with_foreign_abi(llfn_ty={}, llfn={})",
            ccx.tn().type_to_string(llfn_ty), ccx.tn().val_to_string(llfn));
@@ -571,7 +575,7 @@ pub fn register_rust_fn_with_foreign_abi(ccx: &CrateContext,
             let c = llvm_calling_convention(ccx, fn_ty.abi);
             c.unwrap_or(llvm::CCallConv)
         }
-        _ => fail!("expected bare fn in register_rust_fn_with_foreign_abi")
+        _ => panic!("expected bare fn in register_rust_fn_with_foreign_abi")
     };
     let llfn = base::register_fn_llvmty(ccx, sp, sym, node_id, cconv, llfn_ty);
     add_argument_attributes(&tys, llfn);
@@ -698,8 +702,10 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
         };
 
         // Push Rust return pointer, using null if it will be unused.
-        let rust_uses_outptr =
-            type_of::return_uses_outptr(ccx, tys.fn_sig.output);
+        let rust_uses_outptr = match tys.fn_sig.output {
+            ty::FnConverging(ret_ty) => type_of::return_uses_outptr(ccx, ret_ty),
+            ty::FnDiverging => false
+        };
         let return_alloca: Option<ValueRef>;
         let llrust_ret_ty = tys.llsig.llret_ty;
         let llrust_retptr_ty = llrust_ret_ty.ptr_to();
@@ -714,7 +720,7 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
                     debug!("out pointer, foreign={}",
                            ccx.tn().val_to_string(llforeign_outptr));
                     let llrust_retptr =
-                        builder.bitcast(llforeign_outptr, llrust_ret_ty.ptr_to());
+                        builder.bitcast(llforeign_outptr, llrust_retptr_ty);
                     debug!("out pointer, foreign={} (casted)",
                            ccx.tn().val_to_string(llrust_retptr));
                     llrust_args.push(llrust_retptr);
@@ -817,7 +823,7 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
             None => tys.fn_ty.ret_ty.ty
         };
         match foreign_outptr {
-            None if !tys.ret_def => {
+            None if !tys.llsig.ret_def => {
                 // Function returns `()` or `bot`, which in Rust is the LLVM
                 // type "{}" but in foreign ABIs is "Void".
                 builder.ret_void();
@@ -896,10 +902,16 @@ fn foreign_signature(ccx: &CrateContext, fn_sig: &ty::FnSig, arg_tys: &[ty::t])
      */
 
     let llarg_tys = arg_tys.iter().map(|&arg| arg_type_of(ccx, arg)).collect();
-    let llret_ty = type_of::arg_type_of(ccx, fn_sig.output);
+    let (llret_ty, ret_def) = match fn_sig.output {
+        ty::FnConverging(ret_ty) =>
+            (type_of::arg_type_of(ccx, ret_ty), !return_type_is_void(ccx, ret_ty)),
+        ty::FnDiverging =>
+            (Type::nil(ccx), false)
+    };
     LlvmSignature {
         llarg_tys: llarg_tys,
-        llret_ty: llret_ty
+        llret_ty: llret_ty,
+        ret_def: ret_def
     }
 }
 
@@ -915,11 +927,10 @@ fn foreign_types_for_fn_ty(ccx: &CrateContext,
         _ => ccx.sess().bug("foreign_types_for_fn_ty called on non-function type")
     };
     let llsig = foreign_signature(ccx, &fn_sig, fn_sig.inputs.as_slice());
-    let ret_def = !return_type_is_void(ccx, fn_sig.output);
     let fn_ty = cabi::compute_abi_info(ccx,
                                        llsig.llarg_tys.as_slice(),
                                        llsig.llret_ty,
-                                       ret_def);
+                                       llsig.ret_def);
     debug!("foreign_types_for_fn_ty(\
            ty={}, \
            llsig={} -> {}, \
@@ -930,12 +941,11 @@ fn foreign_types_for_fn_ty(ccx: &CrateContext,
            ccx.tn().type_to_string(llsig.llret_ty),
            ccx.tn().types_to_str(fn_ty.arg_tys.iter().map(|t| t.ty).collect::<Vec<_>>().as_slice()),
            ccx.tn().type_to_string(fn_ty.ret_ty.ty),
-           ret_def);
+           llsig.ret_def);
 
     ForeignTypes {
         fn_sig: fn_sig,
         llsig: llsig,
-        ret_def: ret_def,
         fn_ty: fn_ty
     }
 }
index 8fc3426e372996d48105a81a171dd9a650ef2f02..fb85e6198666726d1bad7c346059f782b86e8ba0 100644 (file)
@@ -244,7 +244,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     adt::fold_variants(bcx, &*repr, struct_data, |variant_cx, st, value| {
         // Be sure to put all of the fields into a scope so we can use an invoke
         // instruction to call the user destructor but still call the field
-        // destructors if the user destructor fails.
+        // destructors if the user destructor panics.
         let field_scope = variant_cx.fcx.push_custom_cleanup_scope();
 
         // Class dtors have no explicit args, so the params should
@@ -538,10 +538,10 @@ fn make_generic_glue(ccx: &CrateContext,
 
     let arena = TypedArena::new();
     let empty_param_substs = param_substs::empty();
-    let fcx = new_fn_ctxt(ccx, llfn, ast::DUMMY_NODE_ID, false, ty::mk_nil(),
+    let fcx = new_fn_ctxt(ccx, llfn, ast::DUMMY_NODE_ID, false, ty::FnConverging(ty::mk_nil()),
                           &empty_param_substs, None, &arena);
 
-    let bcx = init_function(&fcx, false, ty::mk_nil());
+    let bcx = init_function(&fcx, false, ty::FnConverging(ty::mk_nil()));
 
     update_linkage(ccx, llfn, None, OriginalTranslation);
 
@@ -556,7 +556,7 @@ fn make_generic_glue(ccx: &CrateContext,
 
     let llrawptr0 = get_param(llfn, fcx.arg_pos(0) as c_uint);
     let bcx = helper(bcx, llrawptr0, t);
-    finish_fn(&fcx, bcx, ty::mk_nil());
+    finish_fn(&fcx, bcx, ty::FnConverging(ty::mk_nil()));
 
     llfn
 }
index 3e75b0772fb10d9616072cb52795c73e10e9bec6..2455970b6a64d37616734e4056192ca85ca66100 100644 (file)
@@ -147,14 +147,14 @@ pub fn trans_intrinsic_call<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, node: ast::N
 
     let ret_ty = match ty::get(callee_ty).sty {
         ty::ty_bare_fn(ref f) => f.sig.output,
-        _ => fail!("expected bare_fn in trans_intrinsic_call")
+        _ => panic!("expected bare_fn in trans_intrinsic_call")
     };
-    let llret_ty = type_of::type_of(ccx, ret_ty);
     let foreign_item = tcx.map.expect_foreign_item(node);
     let name = token::get_ident(foreign_item.ident);
 
     // For `transmute` we can just trans the input expr directly into dest
     if name.get() == "transmute" {
+        let llret_ty = type_of::type_of(ccx, ret_ty.unwrap());
         match args {
             callee::ArgExprs(arg_exprs) => {
                 assert_eq!(arg_exprs.len(), 1);
@@ -192,6 +192,36 @@ pub fn trans_intrinsic_call<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, node: ast::N
         }
     }
 
+    // Push the arguments.
+    let mut llargs = Vec::new();
+    bcx = callee::trans_args(bcx,
+                             args,
+                             callee_ty,
+                             &mut llargs,
+                             cleanup::CustomScope(cleanup_scope),
+                             false,
+                             RustIntrinsic);
+
+    fcx.pop_custom_cleanup_scope(cleanup_scope);
+
+    // These are the only intrinsic functions that diverge.
+    if name.get() == "abort" {
+        let llfn = ccx.get_intrinsic(&("llvm.trap"));
+        Call(bcx, llfn, [], None);
+        Unreachable(bcx);
+        return Result::new(bcx, C_undef(Type::nil(ccx).ptr_to()));
+    } else if name.get() == "unreachable" {
+        Unreachable(bcx);
+        return Result::new(bcx, C_nil(ccx));
+    }
+
+    let ret_ty = match ret_ty {
+        ty::FnConverging(ret_ty) => ret_ty,
+        ty::FnDiverging => unreachable!()
+    };
+
+    let llret_ty = type_of::type_of(ccx, ret_ty);
+
     // Get location to store the result. If the user does
     // not care about the result, just make a stack slot
     let llresult = match dest {
@@ -205,34 +235,11 @@ pub fn trans_intrinsic_call<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, node: ast::N
         }
     };
 
-    // Push the arguments.
-    let mut llargs = Vec::new();
-    bcx = callee::trans_args(bcx,
-                             args,
-                             callee_ty,
-                             &mut llargs,
-                             cleanup::CustomScope(cleanup_scope),
-                             false,
-                             RustIntrinsic);
-
-    fcx.pop_custom_cleanup_scope(cleanup_scope);
-
     let simple = get_simple_intrinsic(ccx, &*foreign_item);
-
     let llval = match (simple, name.get()) {
         (Some(llfn), _) => {
             Call(bcx, llfn, llargs.as_slice(), None)
         }
-        (_, "abort") => {
-            let llfn = ccx.get_intrinsic(&("llvm.trap"));
-            let v = Call(bcx, llfn, [], None);
-            Unreachable(bcx);
-            v
-        }
-        (_, "unreachable") => {
-            Unreachable(bcx);
-            C_nil(ccx)
-        }
         (_, "breakpoint") => {
             let llfn = ccx.get_intrinsic(&("llvm.debugtrap"));
             Call(bcx, llfn, [], None)
index 24b41fe144a230b99ebfbfbef8fe975dc82cfdad..db433167298cea8db4b8a8a13174c861122c0c1f 100644 (file)
@@ -193,7 +193,7 @@ pub fn trans_static_method_callee(bcx: Block,
                 };
                 ident.name
             }
-            _ => fail!("callee is not a trait method")
+            _ => panic!("callee is not a trait method")
         }
     } else {
         csearch::get_item_path(bcx.tcx(), method_id).last().unwrap().name()
@@ -344,13 +344,10 @@ fn trans_monomorphized_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             Callee { bcx: bcx, data: Fn(llfn) }
         }
         traits::VtableUnboxedClosure(closure_def_id) => {
-          // The static region and type parameters are lies, but we're in
-          // trans so it doesn't matter.
-          //
-          // FIXME(pcwalton): Is this true in the case of type parameters?
-          let callee_substs = get_callee_substitutions_for_unboxed_closure(
+            let self_ty = node_id_type(bcx, closure_def_id.node);
+            let callee_substs = get_callee_substitutions_for_unboxed_closure(
                 bcx,
-                closure_def_id);
+                self_ty);
 
             let llfn = trans_fn_ref_with_substs(bcx,
                                                 closure_def_id,
@@ -504,24 +501,22 @@ pub fn trans_trait_callee_from_llval<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     };
 }
 
-/// Creates the self type and (fake) callee substitutions for an unboxed
-/// closure with the given def ID. The static region and type parameters are
-/// lies, but we're in trans so it doesn't matter.
+/// Looks up the substitutions for an unboxed closure and adds the
+/// self type
 fn get_callee_substitutions_for_unboxed_closure(bcx: Block,
-                                                def_id: ast::DefId)
+                                                self_ty: ty::t)
                                                 -> subst::Substs {
-    let self_ty = ty::mk_unboxed_closure(bcx.tcx(), def_id, ty::ReStatic);
-    subst::Substs::erased(
-        VecPerParamSpace::new(Vec::new(),
-                              vec![
-                                  ty::mk_rptr(bcx.tcx(),
-                                              ty::ReStatic,
-                                              ty::mt {
+    match ty::get(self_ty).sty {
+        ty::ty_unboxed_closure(_, _, ref substs) => {
+            substs.with_self_ty(ty::mk_rptr(bcx.tcx(),
+                                            ty::ReStatic,
+                                            ty::mt {
                                                 ty: self_ty,
                                                 mutbl: ast::MutMutable,
-                                              })
-                              ],
-                              Vec::new()))
+                                            }))
+        },
+        _ => unreachable!()
+    }
 }
 
 /// Creates a returns a dynamic vtable for the given type and vtable origin.
@@ -569,10 +564,12 @@ pub fn get_vtable(bcx: Block,
                 emit_vtable_methods(bcx, id, substs).into_iter()
             }
             traits::VtableUnboxedClosure(closure_def_id) => {
+                let self_ty = node_id_type(bcx, closure_def_id.node);
+
                 let callee_substs =
                     get_callee_substitutions_for_unboxed_closure(
                         bcx,
-                        closure_def_id);
+                        self_ty.clone());
 
                 let mut llfn = trans_fn_ref_with_substs(
                     bcx,
@@ -590,25 +587,28 @@ pub fn get_vtable(bcx: Block,
                                                  unboxed closure");
                     if closure_info.kind == ty::FnOnceUnboxedClosureKind {
                         // Untuple the arguments and create an unboxing shim.
-                        let mut new_inputs = vec![
-                            ty::mk_unboxed_closure(bcx.tcx(),
-                                                   closure_def_id,
-                                                   ty::ReStatic)
-                        ];
-                        match ty::get(closure_info.closure_type
-                                                  .sig
-                                                  .inputs[0]).sty {
-                            ty::ty_tup(ref elements) => {
-                                for element in elements.iter() {
-                                    new_inputs.push(*element)
+                        let (new_inputs, new_output) = match ty::get(self_ty).sty {
+                            ty::ty_unboxed_closure(_, _, ref substs) => {
+                                let mut new_inputs = vec![self_ty.clone()];
+                                match ty::get(closure_info.closure_type
+                                              .sig
+                                              .inputs[0]).sty {
+                                    ty::ty_tup(ref elements) => {
+                                        for element in elements.iter() {
+                                            new_inputs.push(element.subst(bcx.tcx(), substs));
+                                        }
+                                    }
+                                    ty::ty_nil => {}
+                                    _ => {
+                                        bcx.tcx().sess.bug("get_vtable(): closure \
+                                                            type wasn't a tuple")
+                                    }
                                 }
-                            }
-                            ty::ty_nil => {}
-                            _ => {
-                                bcx.tcx().sess.bug("get_vtable(): closure \
-                                                    type wasn't a tuple")
-                            }
-                        }
+                                (new_inputs,
+                                 closure_info.closure_type.sig.output.subst(bcx.tcx(), substs))
+                            },
+                            _ => bcx.tcx().sess.bug("get_vtable(): def wasn't an unboxed closure")
+                        };
 
                         let closure_type = ty::BareFnTy {
                             fn_style: closure_info.closure_type.fn_style,
@@ -618,7 +618,7 @@ pub fn get_vtable(bcx: Block,
                                                        .sig
                                                        .binder_id,
                                 inputs: new_inputs,
-                                output: closure_info.closure_type.sig.output,
+                                output: new_output,
                                 variadic: false,
                             },
                         };
index 0dcc69a6686567ed96ae6a3033e8c5a8294f11bb..5c8287c0030d43b804c9ce75e4e1940055f1bade 100644 (file)
@@ -315,7 +315,7 @@ pub fn write_content<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                         return bcx;
                     }
 
-                    // Some cleanup would be required in the case in which failure happens
+                    // Some cleanup would be required in the case in which panic happens
                     // during a copy. But given that copy constructors are not overridable,
                     // this can only happen as a result of OOM. So we just skip out on the
                     // cleanup since things would *probably* be broken at that point anyways.
index 6acbde3b2adc95ad7088d9a10cae731a62b484e9..f08fd20314a6635fc99d326bb541f6da57c04445 100644 (file)
@@ -308,7 +308,7 @@ pub fn float_width(&self) -> uint {
             Double => 64,
             X86_FP80 => 80,
             FP128 | PPC_FP128 => 128,
-            _ => fail!("llvm_float_width called on a non-float type")
+            _ => panic!("llvm_float_width called on a non-float type")
         }
     }
 }
index 989ac63cd5c264984319b2654d95e925f52b44b9..649dbbacc698447789e7e9de9fd8d9b31ec8e480 100644 (file)
@@ -97,7 +97,7 @@ pub fn untuple_arguments_if_necessary(ccx: &CrateContext,
 pub fn type_of_rust_fn(cx: &CrateContext,
                        llenvironment_type: Option<Type>,
                        inputs: &[ty::t],
-                       output: ty::t,
+                       output: ty::FnOutput,
                        abi: abi::Abi)
                        -> Type {
     let mut atys: Vec<Type> = Vec::new();
@@ -107,11 +107,22 @@ pub fn type_of_rust_fn(cx: &CrateContext,
 
     // Arg 0: Output pointer.
     // (if the output type is non-immediate)
-    let use_out_pointer = return_uses_outptr(cx, output);
-    let lloutputtype = arg_type_of(cx, output);
-    if use_out_pointer {
-        atys.push(lloutputtype.ptr_to());
-    }
+    let lloutputtype = match output {
+        ty::FnConverging(output) => {
+            let use_out_pointer = return_uses_outptr(cx, output);
+            let lloutputtype = arg_type_of(cx, output);
+            // Use the output as the actual return value if it's immediate.
+            if use_out_pointer {
+                atys.push(lloutputtype.ptr_to());
+                Type::void(cx)
+            } else if return_type_is_void(cx, output) {
+                Type::void(cx)
+            } else {
+                lloutputtype
+            }
+        }
+        ty::FnDiverging => Type::void(cx)
+    };
 
     // Arg 1: Environment
     match llenvironment_type {
@@ -123,12 +134,7 @@ pub fn type_of_rust_fn(cx: &CrateContext,
     let input_tys = inputs.iter().map(|&arg_ty| type_of_explicit_arg(cx, arg_ty));
     atys.extend(input_tys);
 
-    // Use the output as the actual return value if it's immediate.
-    if use_out_pointer || return_type_is_void(cx, output) {
-        Type::func(atys.as_slice(), &Type::void(cx))
-    } else {
-        Type::func(atys.as_slice(), &lloutputtype)
-    }
+    Type::func(atys.as_slice(), &lloutputtype)
 }
 
 // Given a function type and a count of ty params, construct an llvm type
@@ -181,7 +187,7 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
                                   ppaux::ty_to_string(cx.tcx(), t)).as_slice())
         }
 
-        ty::ty_nil | ty::ty_bot => Type::nil(cx),
+        ty::ty_nil => Type::nil(cx),
         ty::ty_bool => Type::bool(cx),
         ty::ty_char => Type::char(cx),
         ty::ty_int(t) => Type::int_from_ty(cx, t),
@@ -231,7 +237,7 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
             cx.sess().bug(format!("fictitious type {} in sizing_type_of()",
                                   ppaux::ty_to_string(cx.tcx(), t)).as_slice())
         }
-        ty::ty_vec(_, None) | ty::ty_trait(..) | ty::ty_str => fail!("unreachable")
+        ty::ty_vec(_, None) | ty::ty_trait(..) | ty::ty_str => panic!("unreachable")
     };
 
     cx.llsizingtypes().borrow_mut().insert(t, llsizingty);
@@ -260,7 +266,7 @@ fn type_of_unsize_info(cx: &CrateContext, t: ty::t) -> Type {
         match ty::get(ty::unsized_part_of_type(cx.tcx(), t)).sty {
             ty::ty_str | ty::ty_vec(..) => Type::uint_from_ty(cx, ast::TyU),
             ty::ty_trait(_) => Type::vtable_ptr(cx),
-            _ => fail!("Unexpected type returned from unsized_part_of_type : {}",
+            _ => panic!("Unexpected type returned from unsized_part_of_type : {}",
                        t.repr(cx.tcx()))
         }
     }
@@ -293,7 +299,7 @@ fn type_of_unsize_info(cx: &CrateContext, t: ty::t) -> Type {
     }
 
     let mut llty = match ty::get(t).sty {
-      ty::ty_nil | ty::ty_bot => Type::nil(cx),
+      ty::ty_nil => Type::nil(cx),
       ty::ty_bool => Type::bool(cx),
       ty::ty_char => Type::char(cx),
       ty::ty_int(t) => Type::int_from_ty(cx, t),
@@ -309,11 +315,15 @@ fn type_of_unsize_info(cx: &CrateContext, t: ty::t) -> Type {
           let name = llvm_type_name(cx, an_enum, did, tps);
           adt::incomplete_type_of(cx, &*repr, name.as_slice())
       }
-      ty::ty_unboxed_closure(did, _) => {
+      ty::ty_unboxed_closure(did, _, ref substs) => {
           // Only create the named struct, but don't fill it in. We
           // fill it in *after* placing it into the type cache.
           let repr = adt::represent_type(cx, t);
-          let name = llvm_type_name(cx, an_unboxed_closure, did, []);
+          // Unboxed closures can have substitutions in all spaces
+          // inherited from their environment, so we use entire
+          // contents of the VecPerParamSpace to to construct the llvm
+          // name
+          let name = llvm_type_name(cx, an_unboxed_closure, did, substs.types.as_slice());
           adt::incomplete_type_of(cx, &*repr, name.as_slice())
       }
 
index 8c602548f33f6ceaccde3763e148368d75a20803..edb67f7fddf8b3f971dd7538964dbf0f11b27204 100644 (file)
@@ -585,17 +585,21 @@ pub struct ctxt<'tcx> {
     pub repr_hint_cache: RefCell<DefIdMap<Rc<Vec<attr::ReprAttr>>>>,
 }
 
-pub enum tbox_flag {
-    has_params = 1,
-    has_self = 2,
-    needs_infer = 4,
-    has_regions = 8,
-    has_ty_err = 16,
-    has_ty_bot = 32,
-
-    // a meta-pub flag: subst may be required if the type has parameters, a self
-    // type, or references bound regions
-    needs_subst = 1 | 2 | 8
+// Flags that we track on types. These flags are propagated upwards
+// through the type during type construction, so that we can quickly
+// check whether the type has various kinds of types in it without
+// recursing over the type itself.
+bitflags! {
+    flags TypeFlags: u32 {
+        const NO_TYPE_FLAGS = 0b0,
+        const HAS_PARAMS    = 0b1,
+        const HAS_SELF      = 0b10,
+        const HAS_TY_INFER  = 0b100,
+        const HAS_RE_INFER  = 0b1000,
+        const HAS_REGIONS   = 0b10000,
+        const HAS_TY_ERR    = 0b100000,
+        const NEEDS_SUBST   = HAS_PARAMS.bits | HAS_SELF.bits | HAS_REGIONS.bits,
+    }
 }
 
 pub type t_box = &'static t_box_;
@@ -604,7 +608,13 @@ pub enum tbox_flag {
 pub struct t_box_ {
     pub sty: sty,
     pub id: uint,
-    pub flags: uint,
+    pub flags: TypeFlags,
+}
+
+impl fmt::Show for TypeFlags {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}", self.bits)
+    }
 }
 
 // To reduce refcounting cost, we're representing types as unsafe pointers
@@ -631,15 +641,16 @@ pub fn get(t: t) -> t_box {
     }
 }
 
-pub fn tbox_has_flag(tb: t_box, flag: tbox_flag) -> bool {
-    (tb.flags & (flag as uint)) != 0u
+fn tbox_has_flag(tb: t_box, flag: TypeFlags) -> bool {
+    tb.flags.intersects(flag)
 }
 pub fn type_has_params(t: t) -> bool {
-    tbox_has_flag(get(t), has_params)
+    tbox_has_flag(get(t), HAS_PARAMS)
 }
-pub fn type_has_self(t: t) -> bool { tbox_has_flag(get(t), has_self) }
+pub fn type_has_self(t: t) -> bool { tbox_has_flag(get(t), HAS_SELF) }
+pub fn type_has_ty_infer(t: t) -> bool { tbox_has_flag(get(t), HAS_TY_INFER) }
 pub fn type_needs_infer(t: t) -> bool {
-    tbox_has_flag(get(t), needs_infer)
+    tbox_has_flag(get(t), HAS_TY_INFER | HAS_RE_INFER)
 }
 pub fn type_id(t: t) -> uint { get(t).id }
 
@@ -660,6 +671,21 @@ pub struct ClosureTy {
     pub abi: abi::Abi,
 }
 
+#[deriving(Clone, PartialEq, Eq, Hash)]
+pub enum FnOutput {
+    FnConverging(ty::t),
+    FnDiverging
+}
+
+impl FnOutput {
+    pub fn unwrap(&self) -> ty::t {
+        match *self {
+            ty::FnConverging(ref t) => *t,
+            ty::FnDiverging => unreachable!()
+        }
+    }
+}
+
 /**
  * Signature of a function type, which I have arbitrarily
  * decided to use to refer to the input/output types.
@@ -676,7 +702,7 @@ pub struct ClosureTy {
 pub struct FnSig {
     pub binder_id: ast::NodeId,
     pub inputs: Vec<t>,
-    pub output: t,
+    pub output: FnOutput,
     pub variadic: bool
 }
 
@@ -886,7 +912,7 @@ macro_rules! def_prim_ty(
             pub static $name: t_box_ = t_box_ {
                 sty: $sty,
                 id: $id,
-                flags: 0,
+                flags: super::NO_TYPE_FLAGS,
             };
         )
     )
@@ -907,16 +933,10 @@ macro_rules! def_prim_ty(
     def_prim_ty!(TY_F32,    super::ty_float(ast::TyF32),    14)
     def_prim_ty!(TY_F64,    super::ty_float(ast::TyF64),    15)
 
-    pub static TY_BOT: t_box_ = t_box_ {
-        sty: super::ty_bot,
-        id: 16,
-        flags: super::has_ty_bot as uint,
-    };
-
     pub static TY_ERR: t_box_ = t_box_ {
         sty: super::ty_err,
         id: 17,
-        flags: super::has_ty_err as uint,
+        flags: super::HAS_TY_ERR,
     };
 
     pub const LAST_PRIMITIVE_ID: uint = 18;
@@ -927,7 +947,6 @@ macro_rules! def_prim_ty(
 #[deriving(Clone, PartialEq, Eq, Hash, Show)]
 pub enum sty {
     ty_nil,
-    ty_bot,
     ty_bool,
     ty_char,
     ty_int(ast::IntTy),
@@ -950,7 +969,7 @@ pub enum sty {
     ty_closure(Box<ClosureTy>),
     ty_trait(Box<TyTrait>),
     ty_struct(DefId, Substs),
-    ty_unboxed_closure(DefId, Region),
+    ty_unboxed_closure(DefId, Region, Substs),
     ty_tup(Vec<t>),
 
     ty_param(ParamTy), // type parameter
@@ -1032,6 +1051,7 @@ pub enum type_err {
     terr_builtin_bounds(expected_found<BuiltinBounds>),
     terr_variadic_mismatch(expected_found<bool>),
     terr_cyclic_ty,
+    terr_convergence_mismatch(expected_found<bool>)
 }
 
 /// Bounds suitable for a named type parameter like `A` in `fn foo<A>`
@@ -1566,7 +1586,6 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t {
         ty_uint(u) => return mk_mach_uint(u),
         ty_float(f) => return mk_mach_float(f),
         ty_char => return mk_char(),
-        ty_bot => return mk_bot(),
         _ => {}
     };
 
@@ -1577,32 +1596,32 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t {
         _ => ()
     }
 
-    let mut flags = 0u;
-    fn rflags(r: Region) -> uint {
-        (has_regions as uint) | {
+    let mut flags = NO_TYPE_FLAGS;
+    fn rflags(r: Region) -> TypeFlags {
+        HAS_REGIONS | {
             match r {
-              ty::ReInfer(_) => needs_infer as uint,
-              _ => 0u
+              ty::ReInfer(_) => HAS_RE_INFER,
+              _ => NO_TYPE_FLAGS,
             }
         }
     }
-    fn sflags(substs: &Substs) -> uint {
-        let mut f = 0u;
+    fn sflags(substs: &Substs) -> TypeFlags {
+        let mut f = NO_TYPE_FLAGS;
         let mut i = substs.types.iter();
         for tt in i {
-            f |= get(*tt).flags;
+            f = f | get(*tt).flags;
         }
         match substs.regions {
             subst::ErasedRegions => {}
             subst::NonerasedRegions(ref regions) => {
                 for r in regions.iter() {
-                    f |= rflags(*r)
+                    f = f | rflags(*r)
                 }
             }
         }
         return f;
     }
-    fn flags_for_bounds(bounds: &ExistentialBounds) -> uint {
+    fn flags_for_bounds(bounds: &ExistentialBounds) -> TypeFlags {
         rflags(bounds.region_bound)
     }
     match &st {
@@ -1610,58 +1629,60 @@ fn flags_for_bounds(bounds: &ExistentialBounds) -> uint {
       &ty_str => {}
       // You might think that we could just return ty_err for
       // any type containing ty_err as a component, and get
-      // rid of the has_ty_err flag -- likewise for ty_bot (with
+      // rid of the HAS_TY_ERR flag -- likewise for ty_bot (with
       // the exception of function types that return bot).
       // But doing so caused sporadic memory corruption, and
       // neither I (tjc) nor nmatsakis could figure out why,
       // so we're doing it this way.
-      &ty_bot => flags |= has_ty_bot as uint,
-      &ty_err => flags |= has_ty_err as uint,
+      &ty_err => flags = flags | HAS_TY_ERR,
       &ty_param(ref p) => {
           if p.space == subst::SelfSpace {
-              flags |= has_self as uint;
+              flags = flags | HAS_SELF;
           } else {
-              flags |= has_params as uint;
+              flags = flags | HAS_PARAMS;
           }
       }
-      &ty_unboxed_closure(_, ref region) => flags |= rflags(*region),
-      &ty_infer(_) => flags |= needs_infer as uint,
+      &ty_unboxed_closure(_, ref region, ref substs) => {
+          flags = flags | rflags(*region);
+          flags = flags | sflags(substs);
+      }
+      &ty_infer(_) => flags = flags | HAS_TY_INFER,
       &ty_enum(_, ref substs) | &ty_struct(_, ref substs) => {
-          flags |= sflags(substs);
+          flags = flags | sflags(substs);
       }
       &ty_trait(box TyTrait { ref substs, ref bounds, .. }) => {
-          flags |= sflags(substs);
-          flags |= flags_for_bounds(bounds);
+          flags = flags | sflags(substs);
+          flags = flags | flags_for_bounds(bounds);
       }
       &ty_uniq(tt) | &ty_vec(tt, _) | &ty_open(tt) => {
-        flags |= get(tt).flags
+        flags = flags | get(tt).flags
       }
       &ty_ptr(ref m) => {
-        flags |= get(m.ty).flags;
+        flags = flags | get(m.ty).flags;
       }
       &ty_rptr(r, ref m) => {
-        flags |= rflags(r);
-        flags |= get(m.ty).flags;
+        flags = flags | rflags(r);
+        flags = flags | get(m.ty).flags;
       }
-      &ty_tup(ref ts) => for tt in ts.iter() { flags |= get(*tt).flags; },
+      &ty_tup(ref ts) => for tt in ts.iter() { flags = flags | get(*tt).flags; },
       &ty_bare_fn(ref f) => {
-        for a in f.sig.inputs.iter() { flags |= get(*a).flags; }
-        flags |= get(f.sig.output).flags;
-        // T -> _|_ is *not* _|_ !
-        flags &= !(has_ty_bot as uint);
+        for a in f.sig.inputs.iter() { flags = flags | get(*a).flags; }
+        if let ty::FnConverging(output) = f.sig.output {
+            flags = flags | get(output).flags;
+        }
       }
       &ty_closure(ref f) => {
         match f.store {
             RegionTraitStore(r, _) => {
-                flags |= rflags(r);
+                flags = flags | rflags(r);
             }
             _ => {}
         }
-        for a in f.sig.inputs.iter() { flags |= get(*a).flags; }
-        flags |= get(f.sig.output).flags;
-        // T -> _|_ is *not* _|_ !
-        flags &= !(has_ty_bot as uint);
-        flags |= flags_for_bounds(&f.bounds);
+        for a in f.sig.inputs.iter() { flags = flags | get(*a).flags; }
+        if let ty::FnConverging(output) = f.sig.output {
+            flags = flags | get(output).flags;
+        }
+        flags = flags | flags_for_bounds(&f.bounds);
       }
     }
 
@@ -1699,9 +1720,6 @@ pub fn mk_nil() -> t { mk_prim_t(&primitives::TY_NIL) }
 #[inline]
 pub fn mk_err() -> t { mk_prim_t(&primitives::TY_ERR) }
 
-#[inline]
-pub fn mk_bot() -> t { mk_prim_t(&primitives::TY_BOT) }
-
 #[inline]
 pub fn mk_bool() -> t { mk_prim_t(&primitives::TY_BOOL) }
 
@@ -1847,7 +1865,7 @@ pub fn mk_ctor_fn(cx: &ctxt,
                    sig: FnSig {
                     binder_id: binder_id,
                     inputs: input_args,
-                    output: output,
+                    output: ty::FnConverging(output),
                     variadic: false
                    }
                 })
@@ -1873,9 +1891,9 @@ pub fn mk_struct(cx: &ctxt, struct_id: ast::DefId, substs: Substs) -> t {
     mk_t(cx, ty_struct(struct_id, substs))
 }
 
-pub fn mk_unboxed_closure(cx: &ctxt, closure_id: ast::DefId, region: Region)
+pub fn mk_unboxed_closure(cx: &ctxt, closure_id: ast::DefId, region: Region, substs: Substs)
                           -> t {
-    mk_t(cx, ty_unboxed_closure(closure_id, region))
+    mk_t(cx, ty_unboxed_closure(closure_id, region, substs))
 }
 
 pub fn mk_var(cx: &ctxt, v: TyVid) -> t { mk_infer(cx, TyVar(v)) }
@@ -1909,13 +1927,13 @@ pub fn maybe_walk_ty(ty: t, f: |t| -> bool) {
         return;
     }
     match get(ty).sty {
-        ty_nil | ty_bot | ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) |
-        ty_str | ty_infer(_) | ty_param(_) | ty_unboxed_closure(_, _) | ty_err => {}
+        ty_nil | ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) |
+        ty_str | ty_infer(_) | ty_param(_) | ty_err => {}
         ty_uniq(ty) | ty_vec(ty, _) | ty_open(ty) => maybe_walk_ty(ty, f),
         ty_ptr(ref tm) | ty_rptr(_, ref tm) => {
             maybe_walk_ty(tm.ty, f);
         }
-        ty_enum(_, ref substs) | ty_struct(_, ref substs) |
+        ty_enum(_, ref substs) | ty_struct(_, ref substs) | ty_unboxed_closure(_, _, ref substs) |
         ty_trait(box TyTrait { ref substs, .. }) => {
             for subty in (*substs).types.iter() {
                 maybe_walk_ty(*subty, |x| f(x));
@@ -1924,11 +1942,15 @@ pub fn maybe_walk_ty(ty: t, f: |t| -> bool) {
         ty_tup(ref ts) => { for tt in ts.iter() { maybe_walk_ty(*tt, |x| f(x)); } }
         ty_bare_fn(ref ft) => {
             for a in ft.sig.inputs.iter() { maybe_walk_ty(*a, |x| f(x)); }
-            maybe_walk_ty(ft.sig.output, f);
+            if let ty::FnConverging(output) = ft.sig.output {
+                maybe_walk_ty(output, f);
+            }
         }
         ty_closure(ref ft) => {
             for a in ft.sig.inputs.iter() { maybe_walk_ty(*a, |x| f(x)); }
-            maybe_walk_ty(ft.sig.output, f);
+            if let ty::FnConverging(output) = ft.sig.output {
+                maybe_walk_ty(output, f);
+            }
         }
     }
 }
@@ -1976,18 +1998,16 @@ pub fn is_noop(&self) -> bool {
 
 // Type utilities
 
-pub fn type_is_nil(ty: t) -> bool { get(ty).sty == ty_nil }
-
-pub fn type_is_bot(ty: t) -> bool {
-    (get(ty).flags & (has_ty_bot as uint)) != 0
+pub fn type_is_nil(ty: t) -> bool {
+    get(ty).sty == ty_nil
 }
 
 pub fn type_is_error(ty: t) -> bool {
-    (get(ty).flags & (has_ty_err as uint)) != 0
+    get(ty).flags.intersects(HAS_TY_ERR)
 }
 
 pub fn type_needs_subst(ty: t) -> bool {
-    tbox_has_flag(get(ty), needs_subst)
+    tbox_has_flag(get(ty), NEEDS_SUBST)
 }
 
 pub fn trait_ref_contains_error(tref: &ty::TraitRef) -> bool {
@@ -1996,8 +2016,8 @@ pub fn trait_ref_contains_error(tref: &ty::TraitRef) -> bool {
 
 pub fn type_is_ty_var(ty: t) -> bool {
     match get(ty).sty {
-      ty_infer(TyVar(_)) => true,
-      _ => false
+        ty_infer(TyVar(_)) => true,
+        _ => false
     }
 }
 
@@ -2063,7 +2083,7 @@ pub fn simd_type(cx: &ctxt, ty: t) -> t {
             let fields = lookup_struct_fields(cx, did);
             lookup_field_type(cx, did, fields[0].id, substs)
         }
-        _ => fail!("simd_type called on invalid type")
+        _ => panic!("simd_type called on invalid type")
     }
 }
 
@@ -2073,7 +2093,7 @@ pub fn simd_size(cx: &ctxt, ty: t) -> uint {
             let fields = lookup_struct_fields(cx, did);
             fields.len()
         }
-        _ => fail!("simd_size called on invalid type")
+        _ => panic!("simd_size called on invalid type")
     }
 }
 
@@ -2153,7 +2173,7 @@ fn type_needs_unwind_cleanup_(cx: &ctxt, ty: t, tycache: &mut HashSet<t>) -> boo
         let mut needs_unwind_cleanup = false;
         maybe_walk_ty(ty, |ty| {
             needs_unwind_cleanup |= match get(ty).sty {
-                ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) |
+                ty_nil | ty_bool | ty_int(_) | ty_uint(_) |
                 ty_float(_) | ty_tup(_) | ty_ptr(_) => false,
 
                 ty_enum(did, ref substs) =>
@@ -2413,7 +2433,7 @@ fn tc_ty(cx: &ctxt,
 
             // Scalar and unique types are sendable, and durable
             ty_infer(ty::SkolemizedIntTy(_)) |
-            ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
+            ty_nil | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
             ty_bare_fn(_) | ty::ty_char => {
                 TC::None
             }
@@ -2470,10 +2490,10 @@ fn tc_ty(cx: &ctxt,
                 apply_lang_items(cx, did, res)
             }
 
-            ty_unboxed_closure(did, r) => {
+            ty_unboxed_closure(did, r, ref substs) => {
                 // FIXME(#14449): `borrowed_contents` below assumes `&mut`
                 // unboxed closure.
-                let upvars = unboxed_closure_upvars(cx, did);
+                let upvars = unboxed_closure_upvars(cx, did, substs);
                 TypeContents::union(upvars.as_slice(),
                                     |f| tc_ty(cx, f.ty, cache)) |
                     borrowed_contents(r, MutMutable)
@@ -2543,8 +2563,8 @@ fn tc_ty(cx: &ctxt,
                 // We only ever ask for the kind of types that are defined in
                 // the current crate; therefore, the only type parameters that
                 // could be in scope are those defined in the current crate.
-                // If this assertion failures, it is likely because of a
-                // failure in the cross-crate inlining code to translate a
+                // If this assertion fails, it is likely because of a
+                // failure of the cross-crate inlining code to translate a
                 // def-id.
                 assert_eq!(p.def_id.krate, ast::LOCAL_CRATE);
 
@@ -2725,7 +2745,6 @@ fn subtypes_require(cx: &ctxt, seen: &mut Vec<DefId>,
             ty_vec(ty, Some(_)) => type_requires(cx, seen, r_ty, ty),
 
             ty_nil |
-            ty_bot |
             ty_bool |
             ty_char |
             ty_int(_) |
@@ -2767,8 +2786,8 @@ fn subtypes_require(cx: &ctxt, seen: &mut Vec<DefId>,
                 r
             }
 
-            ty_unboxed_closure(did, _) => {
-                let upvars = unboxed_closure_upvars(cx, did);
+            ty_unboxed_closure(did, _, ref substs) => {
+                let upvars = unboxed_closure_upvars(cx, did, substs);
                 upvars.iter().any(|f| type_requires(cx, seen, r_ty, f.ty))
             }
 
@@ -2855,8 +2874,8 @@ fn are_inner_types_recursive(cx: &ctxt, sp: Span,
 
                 find_nonrepresentable(cx, sp, seen, iter)
             }
-            ty_unboxed_closure(did, _) => {
-                let upvars = unboxed_closure_upvars(cx, did);
+            ty_unboxed_closure(did, _, ref substs) => {
+                let upvars = unboxed_closure_upvars(cx, did, substs);
                 find_nonrepresentable(cx, sp, seen, upvars.iter().map(|f| f.ty))
             }
             _ => Representable,
@@ -3078,7 +3097,7 @@ pub fn unsized_part_of_type(cx: &ctxt, ty: t) -> t {
         _ => {
             assert!(type_is_sized(cx, ty),
                     "unsized_part_of_type failed even though ty is unsized");
-            fail!("called unsized_part_of_type with sized ty");
+            panic!("called unsized_part_of_type with sized ty");
         }
     }
 }
@@ -3210,7 +3229,7 @@ pub fn fn_is_variadic(fty: t) -> bool {
         ty_bare_fn(ref f) => f.sig.variadic,
         ty_closure(ref f) => f.sig.variadic,
         ref s => {
-            fail!("fn_is_variadic() called on non-fn type: {}", s)
+            panic!("fn_is_variadic() called on non-fn type: {}", s)
         }
     }
 }
@@ -3220,7 +3239,7 @@ pub fn ty_fn_sig(fty: t) -> FnSig {
         ty_bare_fn(ref f) => f.sig.clone(),
         ty_closure(ref f) => f.sig.clone(),
         ref s => {
-            fail!("ty_fn_sig() called on non-fn type: {}", s)
+            panic!("ty_fn_sig() called on non-fn type: {}", s)
         }
     }
 }
@@ -3230,7 +3249,7 @@ pub fn ty_fn_abi(fty: t) -> abi::Abi {
     match get(fty).sty {
         ty_bare_fn(ref f) => f.abi,
         ty_closure(ref f) => f.abi,
-        _ => fail!("ty_fn_abi() called on non-fn type"),
+        _ => panic!("ty_fn_abi() called on non-fn type"),
     }
 }
 
@@ -3240,7 +3259,7 @@ pub fn ty_fn_args(fty: t) -> Vec<t> {
         ty_bare_fn(ref f) => f.sig.inputs.clone(),
         ty_closure(ref f) => f.sig.inputs.clone(),
         ref s => {
-            fail!("ty_fn_args() called on non-fn type: {}", s)
+            panic!("ty_fn_args() called on non-fn type: {}", s)
         }
     }
 }
@@ -3254,17 +3273,17 @@ pub fn ty_closure_store(fty: t) -> TraitStore {
             UniqTraitStore
         }
         ref s => {
-            fail!("ty_closure_store() called on non-closure type: {}", s)
+            panic!("ty_closure_store() called on non-closure type: {}", s)
         }
     }
 }
 
-pub fn ty_fn_ret(fty: t) -> t {
+pub fn ty_fn_ret(fty: t) -> FnOutput {
     match get(fty).sty {
         ty_bare_fn(ref f) => f.sig.output,
         ty_closure(ref f) => f.sig.output,
         ref s => {
-            fail!("ty_fn_ret() called on non-fn type: {}", s)
+            panic!("ty_fn_ret() called on non-fn type: {}", s)
         }
     }
 }
@@ -3434,7 +3453,9 @@ pub fn adjust_ty(cx: &ctxt,
                             let method_call = typeck::MethodCall::autoderef(expr_id, i);
                             match method_type(method_call) {
                                 Some(method_ty) => {
-                                    adjusted_ty = ty_fn_ret(method_ty);
+                                    if let ty::FnConverging(result_type) = ty_fn_ret(method_ty) {
+                                        adjusted_ty = result_type;
+                                    }
                                 }
                                 None => {}
                             }
@@ -3605,7 +3626,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
 
                 // Special case: A unit like struct's constructor must be called without () at the
                 // end (like `UnitStruct`) which means this is an ExprPath to a DefFn. But in case
-                // of unit structs this is should not be interpretet as function pointer but as
+                // of unit structs this is should not be interpreted as function pointer but as
                 // call to the constructor.
                 def::DefFn(_, _, true) => RvalueDpsExpr,
 
@@ -3714,7 +3735,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
             // Special case `Box<T>` for now:
             let definition = match tcx.def_map.borrow().find(&place.id) {
                 Some(&def) => def,
-                None => fail!("no def for place"),
+                None => panic!("no def for place"),
             };
             let def_id = definition.def_id();
             if tcx.lang_items.exchange_heap() == Some(def_id) {
@@ -3739,7 +3760,7 @@ pub fn stmt_node_id(s: &ast::Stmt) -> ast::NodeId {
       ast::StmtDecl(_, id) | StmtExpr(_, id) | StmtSemi(_, id) => {
         return id;
       }
-      ast::StmtMac(..) => fail!("unexpanded macro in trans")
+      ast::StmtMac(..) => panic!("unexpanded macro in trans")
     }
 }
 
@@ -3762,7 +3783,7 @@ pub fn impl_or_trait_item_idx(id: ast::Name, trait_items: &[ImplOrTraitItem])
 
 pub fn ty_sort_string(cx: &ctxt, t: t) -> String {
     match get(t).sty {
-        ty_nil | ty_bot | ty_bool | ty_char | ty_int(_) |
+        ty_nil | ty_bool | ty_char | ty_int(_) |
         ty_uint(_) | ty_float(_) | ty_str => {
             ::util::ppaux::ty_to_string(cx, t)
         }
@@ -3942,6 +3963,11 @@ fn tstore_to_closure(s: &TraitStore) -> String {
                     if values.expected { "variadic" } else { "non-variadic" },
                     if values.found { "variadic" } else { "non-variadic" })
         }
+        terr_convergence_mismatch(ref values) => {
+            format!("expected {} fn, found {} function",
+                    if values.expected { "converging" } else { "diverging" },
+                    if values.found { "converging" } else { "diverging" })
+        }
     }
 }
 
@@ -4042,7 +4068,7 @@ fn lookup_locally_or_in_crate_store<V:Clone>(
     }
 
     if def_id.krate == ast::LOCAL_CRATE {
-        fail!("No def'n found for {} in tcx.{}", def_id, descr);
+        panic!("No def'n found for {} in tcx.{}", def_id, descr);
     }
     let v = load_external();
     map.insert(def_id, v.clone());
@@ -4211,7 +4237,7 @@ pub fn ty_to_def_id(ty: t) -> Option<ast::DefId> {
         ty_trait(box TyTrait { def_id: id, .. }) |
         ty_struct(id, _) |
         ty_enum(id, _) |
-        ty_unboxed_closure(id, _) => Some(id),
+        ty_unboxed_closure(id, _, _) => Some(id),
         _ => None
     }
 }
@@ -4609,7 +4635,7 @@ pub struct UnboxedClosureUpvar {
 }
 
 // Returns a list of `UnboxedClosureUpvar`s for each upvar.
-pub fn unboxed_closure_upvars(tcx: &ctxt, closure_id: ast::DefId)
+pub fn unboxed_closure_upvars(tcx: &ctxt, closure_id: ast::DefId, substs: &Substs)
                               -> Vec<UnboxedClosureUpvar> {
     if closure_id.krate == ast::LOCAL_CRATE {
         let capture_mode = tcx.capture_modes.borrow().get_copy(&closure_id.node);
@@ -4618,7 +4644,8 @@ pub fn unboxed_closure_upvars(tcx: &ctxt, closure_id: ast::DefId)
             Some(ref freevars) => {
                 freevars.iter().map(|freevar| {
                     let freevar_def_id = freevar.def.def_id();
-                    let mut freevar_ty = node_id_to_type(tcx, freevar_def_id.node);
+                    let freevar_ty = node_id_to_type(tcx, freevar_def_id.node);
+                    let mut freevar_ty = freevar_ty.subst(tcx, substs);
                     if capture_mode == ast::CaptureByRef {
                         let borrow = tcx.upvar_borrow_map.borrow().get_copy(&ty::UpvarId {
                             var_id: freevar_def_id.node,
@@ -4649,7 +4676,6 @@ pub fn is_binopable(cx: &ctxt, ty: t, op: ast::BinOp) -> bool {
     static tycat_char: int = 2;
     static tycat_int: int = 3;
     static tycat_float: int = 4;
-    static tycat_bot: int = 5;
     static tycat_raw_ptr: int = 6;
 
     static opcat_add: int = 0;
@@ -4694,7 +4720,6 @@ fn tycat(cx: &ctxt, ty: t) -> int {
           ty_bool => tycat_bool,
           ty_int(_) | ty_uint(_) | ty_infer(IntVar(_)) => tycat_int,
           ty_float(_) | ty_infer(FloatVar(_)) => tycat_float,
-          ty_bot => tycat_bot,
           ty_ptr(_) => tycat_raw_ptr,
           _ => tycat_other
         }
@@ -5131,7 +5156,6 @@ pub fn hash_crate_independent(tcx: &ctxt, t: t, svh: &Svh) -> u64 {
     ty::walk_ty(t, |t| {
         match ty::get(t).sty {
             ty_nil => byte!(0),
-            ty_bot => byte!(1),
             ty_bool => byte!(2),
             ty_char => byte!(3),
             ty_int(i) => {
@@ -5212,7 +5236,7 @@ pub fn hash_crate_independent(tcx: &ctxt, t: t, svh: &Svh) -> u64 {
             ty_open(_) => byte!(22),
             ty_infer(_) => unreachable!(),
             ty_err => byte!(23),
-            ty_unboxed_closure(d, r) => {
+            ty_unboxed_closure(d, r, _) => {
                 byte!(24);
                 did(&mut state, d);
                 region(&mut state, r);
@@ -5409,7 +5433,7 @@ pub fn to_mutbl_lossy(self) -> ast::Mutability {
             MutBorrow => ast::MutMutable,
             ImmBorrow => ast::MutImmutable,
 
-            // We have no type correponding to a unique imm borrow, so
+            // We have no type corresponding to a unique imm borrow, so
             // use `&mut`. It gives all the capabilities of an `&uniq`
             // and hence is a safe "over approximation".
             UniqueImmBorrow => ast::MutMutable,
@@ -5489,14 +5513,7 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
                 ..
             }) |
             ty_struct(_, ref substs) => {
-                match substs.regions {
-                    subst::ErasedRegions => {}
-                    subst::NonerasedRegions(ref regions) => {
-                        for region in regions.iter() {
-                            accumulator.push(*region)
-                        }
-                    }
-                }
+                accum_substs(accumulator, substs);
             }
             ty_closure(ref closure_ty) => {
                 match closure_ty.store {
@@ -5504,9 +5521,11 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
                     UniqTraitStore => {}
                 }
             }
-            ty_unboxed_closure(_, ref region) => accumulator.push(*region),
+            ty_unboxed_closure(_, ref region, ref substs) => {
+                accumulator.push(*region);
+                accum_substs(accumulator, substs);
+            }
             ty_nil |
-            ty_bot |
             ty_bool |
             ty_char |
             ty_int(_) |
@@ -5523,7 +5542,18 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
             ty_open(_) |
             ty_err => {}
         }
-    })
+    });
+
+    fn accum_substs(accumulator: &mut Vec<Region>, substs: &Substs) {
+        match substs.regions {
+            subst::ErasedRegions => {}
+            subst::NonerasedRegions(ref regions) => {
+                for region in regions.iter() {
+                    accumulator.push(*region)
+                }
+            }
+        }
+    }
 }
 
 /// A free variable referred to in a function.
index fa0c29d888335ddece84da490830bc887ed3d0b0..a96e81ce20bb418a47393dbce3be4f5e99b534fa 100644 (file)
@@ -91,6 +91,12 @@ fn fold_sig(&mut self,
         super_fold_sig(self, sig)
     }
 
+    fn fold_output(&mut self,
+                      output: &ty::FnOutput)
+                      -> ty::FnOutput {
+        super_fold_output(self, output)
+    }
+
     fn fold_bare_fn_ty(&mut self,
                        fty: &ty::BareFnTy)
                        -> ty::BareFnTy
@@ -207,6 +213,12 @@ fn fold_with<'tcx, F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::mt {
     }
 }
 
+impl TypeFoldable for ty::FnOutput {
+    fn fold_with<'tcx, F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::FnOutput {
+        folder.fold_output(self)
+    }
+}
+
 impl TypeFoldable for ty::FnSig {
     fn fold_with<'tcx, F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::FnSig {
         folder.fold_sig(self)
@@ -453,6 +465,15 @@ pub fn super_fold_sig<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
                 variadic: sig.variadic }
 }
 
+pub fn super_fold_output<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
+                                                    output: &ty::FnOutput)
+                                                    -> ty::FnOutput {
+    match *output {
+        ty::FnConverging(ref ty) => ty::FnConverging(ty.fold_with(this)),
+        ty::FnDiverging => ty::FnDiverging
+    }
+}
+
 pub fn super_fold_bare_fn_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
                                                         fty: &ty::BareFnTy)
                                                         -> ty::BareFnTy
@@ -534,10 +555,10 @@ pub fn super_fold_sty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
         ty::ty_struct(did, ref substs) => {
             ty::ty_struct(did, substs.fold_with(this))
         }
-        ty::ty_unboxed_closure(did, ref region) => {
-            ty::ty_unboxed_closure(did, region.fold_with(this))
+        ty::ty_unboxed_closure(did, ref region, ref substs) => {
+            ty::ty_unboxed_closure(did, region.fold_with(this), substs.fold_with(this))
         }
-        ty::ty_nil | ty::ty_bot | ty::ty_bool | ty::ty_char | ty::ty_str |
+        ty::ty_nil | ty::ty_bool | ty::ty_char | ty::ty_str |
         ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) |
         ty::ty_err | ty::ty_infer(_) |
         ty::ty_param(..) => {
index 15e3ee4c8fad3b754b6141f2822577217ba7f2f2..66d4f73eacc876615e5fa83e735907c81d0643a1 100644 (file)
@@ -674,7 +674,7 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
                             return constr(ty::mk_str(tcx));
                         }
                         RPtr(r) => {
-                            return ty::mk_str_slice(tcx, r, ast::MutImmutable);
+                            return ty::mk_str_slice(tcx, r, a_seq_mutbl);
                         }
                     }
                 }
@@ -793,7 +793,7 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
     let typ = ast_ty_to_builtin_ty(this, rscope, ast_ty).unwrap_or_else(|| {
         match ast_ty.node {
             ast::TyNil => ty::mk_nil(),
-            ast::TyBot => ty::mk_bot(),
+            ast::TyBot => unreachable!(),
             ast::TyUniq(ref ty) => {
                 mk_pointer(this, rscope, ast::MutImmutable, &**ty, Uniq,
                            |ty| ty::mk_uniq(tcx, ty))
@@ -937,7 +937,7 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
                                     tcx.map.node_to_string(id.node)).as_slice());
                     }
                     def::DefPrimTy(_) => {
-                        fail!("DefPrimTy arm missed in previous ast_ty_to_prim_ty call");
+                        panic!("DefPrimTy arm missed in previous ast_ty_to_prim_ty call");
                     }
                     def::DefAssociatedTy(trait_type_id) => {
                         let path_str = tcx.map.path_to_string(
@@ -1171,22 +1171,21 @@ fn ty_of_method_or_bare_fn<'tcx, AC: AstConv<'tcx>>(
                                                                    .collect();
 
     let output_ty = match decl.output.node {
-        ast::TyInfer => this.ty_infer(decl.output.span),
-        _ => {
-            match implied_output_region {
-                Some(implied_output_region) => {
-                    let rb = SpecificRscope::new(implied_output_region);
-                    ast_ty_to_ty(this, &rb, &*decl.output)
-                }
-                None => {
-                    // All regions must be explicitly specified in the output
-                    // if the lifetime elision rules do not apply. This saves
-                    // the user from potentially-confusing errors.
-                    let rb = UnelidableRscope::new(param_lifetimes);
-                    ast_ty_to_ty(this, &rb, &*decl.output)
-                }
+        ast::TyBot => ty::FnDiverging,
+        ast::TyInfer => ty::FnConverging(this.ty_infer(decl.output.span)),
+        _ => ty::FnConverging(match implied_output_region {
+            Some(implied_output_region) => {
+                let rb = SpecificRscope::new(implied_output_region);
+                ast_ty_to_ty(this, &rb, &*decl.output)
             }
-        }
+            None => {
+                // All regions must be explicitly specified in the output
+                // if the lifetime elision rules do not apply. This saves
+                // the user from potentially-confusing errors.
+                let rb = UnelidableRscope::new(param_lifetimes);
+                ast_ty_to_ty(this, &rb, &*decl.output)
+            }
+        })
     };
 
     (ty::BareFnTy {
@@ -1308,10 +1307,12 @@ pub fn ty_of_closure<'tcx, AC: AstConv<'tcx>>(
     }).collect();
 
     let expected_ret_ty = expected_sig.map(|e| e.output);
+
     let output_ty = match decl.output.node {
+        ast::TyBot => ty::FnDiverging,
         ast::TyInfer if expected_ret_ty.is_some() => expected_ret_ty.unwrap(),
-        ast::TyInfer => this.ty_infer(decl.output.span),
-        _ => ast_ty_to_ty(this, &rb, &*decl.output)
+        ast::TyInfer => ty::FnConverging(this.ty_infer(decl.output.span)),
+        _ => ty::FnConverging(ast_ty_to_ty(this, &rb, &*decl.output))
     };
 
     ty::ClosureTy {
index 14725c581c8a8165328a4d15d92b30014427be35..97c6cf24f0e1900a31efa8ab15699897dbae3b0c 100644 (file)
@@ -74,7 +74,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
             let const_did = tcx.def_map.borrow().get_copy(&pat.id).def_id();
             let const_pty = ty::lookup_item_type(tcx, const_did);
             fcx.write_ty(pat.id, const_pty.ty);
-            demand::eqtype(fcx, pat.span, expected, const_pty.ty);
+            demand::suptype(fcx, pat.span, expected, const_pty.ty);
         }
         ast::PatIdent(bm, ref path, ref sub) if pat_is_binding(&tcx.def_map, pat) => {
             let typ = fcx.local_ty(pat.span, pat.id);
@@ -259,9 +259,9 @@ pub fn check_match(fcx: &FnCtxt,
     // bottom the type lattice, and we'll be moving up the lattice as
     // we process each arm. (Note that any match with 0 arms is matching
     // on any empty type and is therefore unreachable; should the flow
-    // of execution reach it, we will fail, so bottom is an appropriate
+    // of execution reach it, we will panic, so bottom is an appropriate
     // type in that case)
-    let result_ty = arms.iter().fold(ty::mk_bot(), |result_ty, arm| {
+    let result_ty = arms.iter().fold(fcx.infcx().next_diverging_ty_var(), |result_ty, arm| {
         check_expr(fcx, &*arm.body);
         let bty = fcx.node_ty(arm.body.id);
 
@@ -347,7 +347,10 @@ pub fn check_pat_enum(pcx: &pat_ctxt, pat: &ast::Pat,
 
     let ctor_pty = ty::lookup_item_type(tcx, enum_def);
     let path_ty = if ty::is_fn_ty(ctor_pty.ty) {
-        ty::Polytype { ty: ty::ty_fn_ret(ctor_pty.ty), ..ctor_pty }
+        ty::Polytype {
+            ty: ty::ty_fn_ret(ctor_pty.ty).unwrap(),
+            ..ctor_pty
+        }
     } else {
         ctor_pty
     };
index cb2f1e010ac6e6ed719557f56569a850b311a34f..cd3cc43b8539d4e17ab2bdbb0bb8fe043fae7ecb 100644 (file)
@@ -88,7 +88,7 @@ trait `ToString` imported, and I call `to_string()` on a value of type `T`,
 use middle::typeck::astconv::AstConv;
 use middle::typeck::check::{FnCtxt, NoPreference, PreferMutLvalue};
 use middle::typeck::check::{impl_self_ty};
-use middle::typeck::check::vtable2::select_fcx_obligations_where_possible;
+use middle::typeck::check::vtable::select_new_fcx_obligations;
 use middle::typeck::check;
 use middle::typeck::infer;
 use middle::typeck::{MethodCall, MethodCallee};
@@ -223,17 +223,37 @@ pub fn report_error(fcx: &FnCtxt,
 {
     match error {
         NoMatch(static_sources) => {
+            let cx = fcx.tcx();
+            let method_ustring = method_name.user_string(cx);
+
+            // True if the type is a struct and contains a field with
+            // the same name as the not-found method
+            let is_field = match ty::get(rcvr_ty).sty {
+                ty_struct(did, _) =>
+                    ty::lookup_struct_fields(cx, did)
+                        .iter()
+                        .any(|f| f.name.user_string(cx) == method_ustring),
+                _ => false
+            };
+
             fcx.type_error_message(
                 span,
                 |actual| {
                     format!("type `{}` does not implement any \
                              method in scope named `{}`",
                             actual,
-                            method_name.user_string(fcx.tcx()))
+                            method_ustring)
                 },
                 rcvr_ty,
                 None);
 
+            // If the method has the name of a field, give a help note
+            if is_field {
+                cx.sess.span_note(span,
+                    format!("use `(s.{0})(...)` if you meant to call the \
+                            function stored in the `{0}` field", method_ustring).as_slice());
+            }
+
             if static_sources.len() > 0 {
                 fcx.tcx().sess.fileline_note(
                     span,
@@ -485,7 +505,7 @@ fn push_inherent_candidates(&mut self, self_ty: ty::t) {
                 }
                 ty_enum(did, _) |
                 ty_struct(did, _) |
-                ty_unboxed_closure(did, _) => {
+                ty_unboxed_closure(did, _, _) => {
                     if self.check_traits == CheckTraitsAndInherentMethods {
                         self.push_inherent_impl_candidates_for_type(did);
                     }
@@ -599,14 +619,12 @@ fn push_inherent_candidates_from_object(&mut self,
 
         let tcx = self.tcx();
 
-        // It is illegal to invoke a method on a trait instance that
-        // refers to the `Self` type. An error will be reported by
-        // `enforce_object_limitations()` if the method refers to the
-        // `Self` type anywhere other than the receiver. Here, we use
-        // a substitution that replaces `Self` with the object type
-        // itself. Hence, a `&self` method will wind up with an
-        // argument type like `&Trait`.
+        // It is illegal to invoke a method on a trait instance that refers to
+        // the `Self` type.  Here, we use a substitution that replaces `Self`
+        // with the object type itself. Hence, a `&self` method will wind up
+        // with an argument type like `&Trait`.
         let rcvr_substs = substs.with_self_ty(self_ty);
+
         let trait_ref = Rc::new(TraitRef {
             def_id: did,
             substs: rcvr_substs.clone()
@@ -896,7 +914,7 @@ fn default_method_hack(self_mt: ty::mt) -> bool {
             // FIXME(#6129). Default methods can't deal with autoref.
             //
             // I am a horrible monster and I pray for death. Currently
-            // the default method code fails when you try to reborrow
+            // the default method code panics when you try to reborrow
             // because it is not handling types correctly. In lieu of
             // fixing that, I am introducing this horrible hack. - ndm
             self_mt.mutbl == MutImmutable && ty::type_is_self(self_mt.ty)
@@ -1014,7 +1032,7 @@ fn auto_slice_trait(&self, ty: ty::t, autoderefs: uint) -> Option<MethodResult>
                         ty::mk_rptr(tcx, r, ty::mt{ ty: tr, mutbl: m })
                     })
             }
-            _ => fail!("Expected ty_trait in auto_slice_trait")
+            _ => panic!("Expected ty_trait in auto_slice_trait")
         }
     }
 
@@ -1062,7 +1080,7 @@ fn search_for_autoptrd_method(&self, self_ty: ty::t, autoderefs: uint)
             ty_bare_fn(..) | ty_uniq(..) | ty_rptr(..) |
             ty_infer(IntVar(_)) |
             ty_infer(FloatVar(_)) |
-            ty_param(..) | ty_nil | ty_bot | ty_bool |
+            ty_param(..) | ty_nil | ty_bool |
             ty_char | ty_int(..) | ty_uint(..) |
             ty_float(..) | ty_enum(..) | ty_ptr(..) | ty_struct(..) |
             ty_unboxed_closure(..) | ty_tup(..) | ty_open(..) |
@@ -1282,7 +1300,7 @@ fn consider_extension_candidates(&self, rcvr_ty: ty::t)
         // the `Self` trait).
         let callee = self.confirm_candidate(rcvr_ty, &candidate);
 
-        select_fcx_obligations_where_possible(self.fcx);
+        select_new_fcx_obligations(self.fcx);
 
         Some(Ok(callee))
     }
@@ -1316,16 +1334,7 @@ fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
                self.ty_to_string(rcvr_ty),
                candidate.repr(self.tcx()));
 
-        let mut rcvr_substs = candidate.rcvr_substs.clone();
-
-        if !self.enforce_object_limitations(candidate) {
-            // Here we change `Self` from `Trait` to `err` in the case that
-            // this is an illegal object method. This is necessary to prevent
-            // the user from getting strange, derivative errors when the method
-            // takes an argument/return-type of type `Self` etc.
-            rcvr_substs.types.get_mut_slice(SelfSpace)[0] = ty::mk_err();
-        }
-
+        let rcvr_substs = candidate.rcvr_substs.clone();
         self.enforce_drop_trait_limitations(candidate);
 
         // Determine the values for the generic parameters of the method.
@@ -1534,69 +1543,6 @@ fn fixup_derefs_on_method_receiver_if_necessary(
         }
     }
 
-    fn enforce_object_limitations(&self, candidate: &Candidate) -> bool {
-        /*!
-         * There are some limitations to calling functions through an
-         * object, because (a) the self type is not known
-         * (that's the whole point of a trait instance, after all, to
-         * obscure the self type) and (b) the call must go through a
-         * vtable and hence cannot be monomorphized.
-         */
-
-        match candidate.origin {
-            MethodStatic(..) |
-            MethodTypeParam(..) |
-            MethodStaticUnboxedClosure(..) => {
-                return true; // not a call to a trait instance
-            }
-            MethodTraitObject(..) => {}
-        }
-
-        match candidate.method_ty.explicit_self {
-            ty::StaticExplicitSelfCategory => { // reason (a) above
-                self.tcx().sess.span_err(
-                    self.span,
-                    "cannot call a method without a receiver \
-                     through an object");
-                return false;
-            }
-
-            ty::ByValueExplicitSelfCategory |
-            ty::ByReferenceExplicitSelfCategory(..) |
-            ty::ByBoxExplicitSelfCategory => {}
-        }
-
-        // reason (a) above
-        let check_for_self_ty = |ty| -> bool {
-            if ty::type_has_self(ty) {
-                span_err!(self.tcx().sess, self.span, E0038,
-                    "cannot call a method whose type contains a \
-                     self-type through an object");
-                false
-            } else {
-                true
-            }
-        };
-        let ref sig = candidate.method_ty.fty.sig;
-        for &input_ty in sig.inputs[1..].iter() {
-            if !check_for_self_ty(input_ty) {
-                return false;
-            }
-        }
-        if !check_for_self_ty(sig.output) {
-            return false;
-        }
-
-        if candidate.method_ty.generics.has_type_params(subst::FnSpace) {
-            // reason (b) above
-            span_err!(self.tcx().sess, self.span, E0039,
-                "cannot call a generic method through an object");
-            return false;
-        }
-
-        true
-    }
-
     fn enforce_drop_trait_limitations(&self, candidate: &Candidate) {
         // No code can call the finalize method explicitly.
         let bad = match candidate.origin {
@@ -1745,7 +1691,7 @@ fn to_source(&self) -> CandidateSource {
                 ImplSource(def_id)
             }
             MethodStaticUnboxedClosure(..) => {
-                fail!("MethodStaticUnboxedClosure only used in trans")
+                panic!("MethodStaticUnboxedClosure only used in trans")
             }
             MethodTypeParam(ref param) => {
                 TraitSource(param.trait_ref.def_id)
index 5ad68544570d168646c5d6b7dbb66544028d718b..94c4d7c25e0a615fca13381c962a4a72401bef8a 100644 (file)
 use middle::typeck::check::method::{CheckTraitsAndInherentMethods};
 use middle::typeck::check::regionmanip::replace_late_bound_regions;
 use middle::typeck::CrateCtxt;
-use middle::typeck::infer::{resolve_type, force_tvar};
 use middle::typeck::infer;
 use middle::typeck::rscope::RegionScope;
 use middle::typeck::{lookup_def_ccx};
 use syntax;
 
 pub mod _match;
-pub mod vtable2; // New trait code
+pub mod vtable;
 pub mod writeback;
 pub mod regionmanip;
 pub mod regionck;
@@ -281,7 +280,7 @@ pub struct FnCtxt<'a, 'tcx: 'a> {
     // expects the types within the function to be consistent.
     err_count_on_creation: uint,
 
-    ret_ty: ty::t,
+    ret_ty: ty::FnOutput,
 
     ps: RefCell<FnStyleState>,
 
@@ -347,7 +346,7 @@ fn new(tcx: &'a ty::ctxt<'tcx>,
 // Used by check_const and check_enum_variants
 pub fn blank_fn_ctxt<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
                                inh: &'a Inherited<'a, 'tcx>,
-                               rty: ty::t,
+                               rty: ty::FnOutput,
                                body_id: ast::NodeId)
                                -> FnCtxt<'a, 'tcx> {
     FnCtxt {
@@ -409,8 +408,9 @@ fn check_bare_fn(ccx: &CrateCtxt,
             let fcx = check_fn(ccx, fn_ty.fn_style, id, &fn_ty.sig,
                                decl, id, body, &inh);
 
-            vtable2::select_all_fcx_obligations_or_error(&fcx);
+            vtable::select_all_fcx_obligations_or_error(&fcx);
             regionck::regionck_fn(&fcx, id, body);
+            fcx.default_diverging_type_variables_to_nil();
             writeback::resolve_type_vars_in_fn(&fcx, decl, body);
         }
         _ => ccx.tcx.sess.impossible_case(body.span,
@@ -427,8 +427,7 @@ fn assign(&mut self, _span: Span, nid: ast::NodeId, ty_opt: Option<ty::t>) -> ty
         match ty_opt {
             None => {
                 // infer the variable's type
-                let var_id = self.fcx.infcx().next_ty_var_id();
-                let var_ty = ty::mk_var(self.fcx.tcx(), var_id);
+                let var_ty = self.fcx.infcx().next_ty_var();
                 self.fcx.inh.locals.borrow_mut().insert(nid, var_ty);
                 var_ty
             }
@@ -552,8 +551,16 @@ fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
     };
 
     // Remember return type so that regionck can access it later.
-    let fn_sig_tys: Vec<ty::t> =
-        arg_tys.iter().chain([ret_ty].iter()).map(|&ty| ty).collect();
+    let mut fn_sig_tys: Vec<ty::t> =
+        arg_tys.iter()
+        .map(|&ty| ty)
+        .collect();
+
+    if let ty::FnConverging(ret_ty) = ret_ty {
+        fcx.require_type_is_sized(ret_ty, decl.output.span, traits::ReturnType);
+        fn_sig_tys.push(ret_ty);
+    }
+
     debug!("fn-sig-map: fn_id={} fn_sig_tys={}",
            fn_id,
            fn_sig_tys.repr(tcx));
@@ -585,9 +592,11 @@ fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
 
         visit.visit_block(body);
     }
-    fcx.require_type_is_sized(ret_ty, decl.output.span, traits::ReturnType);
 
-    check_block_with_expected(&fcx, body, ExpectHasType(ret_ty));
+    check_block_with_expected(&fcx, body, match ret_ty {
+        ty::FnConverging(result_type) => ExpectHasType(result_type),
+        ty::FnDiverging => NoExpectation
+    });
 
     for (input, arg) in decl.inputs.iter().zip(arg_tys.iter()) {
         fcx.write_ty(input.id, *arg);
@@ -1334,11 +1343,6 @@ fn check_cast(fcx: &FnCtxt,
         return
     }
 
-    if ty::type_is_bot(t_e) {
-        fcx.write_bot(id);
-        return
-    }
-
     if !ty::type_is_sized(fcx.tcx(), t_1) {
         let tstr = fcx.infcx().ty_to_string(t_1);
         fcx.type_error_message(span, |actual| {
@@ -1372,7 +1376,7 @@ fn check_cast(fcx: &FnCtxt,
 
     if ty::type_is_trait(t_1) {
         // This will be looked up later on.
-        vtable2::check_object_cast(fcx, cast_expr, e, t_1);
+        vtable::check_object_cast(fcx, cast_expr, e, t_1);
         fcx.write_ty(id, t_1);
         return
     }
@@ -1412,7 +1416,7 @@ fn check_cast(fcx: &FnCtxt,
         }
         // casts from C-like enums are allowed
     } else if t_1_is_char {
-        let t_e = fcx.infcx().resolve_type_vars_if_possible(t_e);
+        let t_e = fcx.infcx().shallow_resolve(t_e);
         if ty::get(t_e).sty != ty::ty_uint(ast::TyU8) {
             fcx.type_error_message(span, |actual| {
                 format!("only `u8` can be cast as \
@@ -1563,6 +1567,14 @@ pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> ty::t {
         }
     }
 
+    pub fn default_diverging_type_variables_to_nil(&self) {
+        for (_, &ref ty) in self.inh.node_types.borrow_mut().iter_mut() {
+            if self.infcx().type_var_diverges(self.infcx().resolve_type_vars_if_possible(*ty)) {
+                demand::eqtype(self, codemap::DUMMY_SP, *ty, ty::mk_nil());
+            }
+        }
+    }
+
     #[inline]
     pub fn write_ty(&self, node_id: ast::NodeId, ty: ty::t) {
         debug!("write_ty({}, {}) in fcx {}",
@@ -1675,9 +1687,10 @@ fn register_unsize_obligations(&self,
                 self.register_unsize_obligations(span, &**u)
             }
             ty::UnsizeVtable(ref ty_trait, self_ty) => {
+                vtable::check_object_safety(self.tcx(), ty_trait, span);
                 // If the type is `Foo+'a`, ensures that the type
                 // being cast to `Foo+'a` implements `Foo`:
-                vtable2::register_object_cast_obligations(self,
+                vtable::register_object_cast_obligations(self,
                                                           span,
                                                           ty_trait,
                                                           self_ty);
@@ -1727,9 +1740,6 @@ pub fn instantiate_item_type(&self,
     pub fn write_nil(&self, node_id: ast::NodeId) {
         self.write_ty(node_id, ty::mk_nil());
     }
-    pub fn write_bot(&self, node_id: ast::NodeId) {
-        self.write_ty(node_id, ty::mk_bot());
-    }
     pub fn write_error(&self, node_id: ast::NodeId) {
         self.write_ty(node_id, ty::mk_err());
     }
@@ -2052,10 +2062,6 @@ pub fn autoderef<T>(fcx: &FnCtxt, sp: Span, base_ty: ty::t,
     for autoderefs in range(0, fcx.tcx().sess.recursion_limit.get()) {
         let resolved_t = structurally_resolved_type(fcx, sp, t);
 
-        if ty::type_is_bot(resolved_t) {
-            return (resolved_t, autoderefs, None);
-        }
-
         match should_stop(resolved_t, autoderefs) {
             Some(x) => return (resolved_t, autoderefs, Some(x)),
             None => {}
@@ -2198,7 +2204,12 @@ fn make_return_type(fcx: &FnCtxt,
                 }
                 None => {}
             }
-            ty::deref(ref_ty, true)
+            match ref_ty {
+                ty::FnConverging(ref_ty) =>
+                    ty::deref(ref_ty, true),
+                ty::FnDiverging =>
+                    None
+            }
         }
         None => None,
     }
@@ -2286,7 +2297,12 @@ fn try_overloaded_slice(fcx: &FnCtxt,
                 }
                 None => {}
             }
-            Some(ty::mt { ty: result_ty, mutbl: ast::MutImmutable })
+            match result_ty {
+                ty::FnConverging(result_ty) =>
+                    Some(ty::mt { ty: result_ty, mutbl: ast::MutImmutable }),
+                ty::FnDiverging =>
+                    None
+            }
         }
         None => None,
     }
@@ -2401,9 +2417,11 @@ fn lookup_method_for_for_loop(fcx: &FnCtxt,
 
             // We expect the return type to be `Option` or something like it.
             // Grab the first parameter of its type substitution.
-            let return_type = structurally_resolved_type(fcx,
-                                                         iterator_expr.span,
-                                                         return_type);
+            let return_type = match return_type {
+                ty::FnConverging(return_type) =>
+                    structurally_resolved_type(fcx, iterator_expr.span, return_type),
+                ty::FnDiverging => ty::mk_err()
+            };
             match ty::get(return_type).sty {
                 ty::ty_enum(_, ref substs)
                         if !substs.types.is_empty_in(subst::TypeSpace) => {
@@ -2428,7 +2446,7 @@ fn check_method_argument_types<'a>(fcx: &FnCtxt,
                                    args_no_rcvr: &[&'a P<ast::Expr>],
                                    deref_args: DerefArgs,
                                    tuple_arguments: TupleArgumentsFlag)
-                                   -> ty::t {
+                                   -> ty::FnOutput {
     if ty::type_is_error(method_fn_ty) {
        let err_inputs = err_args(args_no_rcvr.len());
         check_argument_types(fcx,
@@ -2439,7 +2457,7 @@ fn check_method_argument_types<'a>(fcx: &FnCtxt,
                              deref_args,
                              false,
                              tuple_arguments);
-        method_fn_ty
+        ty::FnConverging(method_fn_ty)
     } else {
         match ty::get(method_fn_ty).sty {
             ty::ty_bare_fn(ref fty) => {
@@ -2564,7 +2582,7 @@ fn check_argument_types<'a>(fcx: &FnCtxt,
         // an "opportunistic" vtable resolution of any trait
         // bounds on the call.
         if check_blocks {
-            vtable2::select_fcx_obligations_where_possible(fcx);
+            vtable::select_new_fcx_obligations(fcx);
         }
 
         // For variadic functions, we don't have a declared type for all of
@@ -2655,8 +2673,11 @@ fn err_args(len: uint) -> Vec<ty::t> {
     Vec::from_fn(len, |_| ty::mk_err())
 }
 
-fn write_call(fcx: &FnCtxt, call_expr: &ast::Expr, output: ty::t) {
-    fcx.write_ty(call_expr.id, output);
+fn write_call(fcx: &FnCtxt, call_expr: &ast::Expr, output: ty::FnOutput) {
+    fcx.write_ty(call_expr.id, match output {
+        ty::FnConverging(output_ty) => output_ty,
+        ty::FnDiverging => fcx.infcx().next_diverging_ty_var()
+    });
 }
 
 // AST fragment checking
@@ -2846,8 +2867,8 @@ enum TupleArgumentsFlag {
 /// strict, _|_ can appear in the type of an expression that does not,
 /// itself, diverge: for example, fn() -> _|_.)
 /// Note that inspecting a type's structure *directly* may expose the fact
-/// that there are actually multiple representations for both `ty_err` and
-/// `ty_bot`, so avoid that when err and bot need to be handled differently.
+/// that there are actually multiple representations for `ty_err`, so avoid
+/// that when err needs to be handled differently.
 fn check_expr_with_unifier(fcx: &FnCtxt,
                            expr: &ast::Expr,
                            expected: Expectation,
@@ -2874,7 +2895,7 @@ fn check_call<'a>(fcx: &FnCtxt,
         let error_fn_sig = FnSig {
             binder_id: ast::CRATE_NODE_ID,
             inputs: err_args(args.len()),
-            output: ty::mk_err(),
+            output: ty::FnConverging(ty::mk_err()),
             variadic: false
         };
 
@@ -2988,9 +3009,11 @@ fn check_then_else(fcx: &FnCtxt,
         // 'else' branch.
         let expected = match expected.only_has_type() {
             ExpectHasType(ety) => {
-                match infer::resolve_type(fcx.infcx(), Some(sp), ety, force_tvar) {
-                    Ok(rty) if !ty::type_is_ty_var(rty) => ExpectHasType(rty),
-                    _ => NoExpectation
+                let ety = fcx.infcx().shallow_resolve(ety);
+                if !ty::type_is_ty_var(ety) {
+                    ExpectHasType(ety)
+                } else {
+                    NoExpectation
                 }
             }
             _ => NoExpectation
@@ -3020,8 +3043,6 @@ fn check_then_else(fcx: &FnCtxt,
         let cond_ty = fcx.expr_ty(cond_expr);
         let if_ty = if ty::type_is_error(cond_ty) {
             ty::mk_err()
-        } else if ty::type_is_bot(cond_ty) {
-            ty::mk_bot()
         } else {
             branches_ty
         };
@@ -3054,13 +3075,16 @@ fn lookup_op_method<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>,
                 // HACK(eddyb) Fully qualified path to work around a resolve bug.
                 let method_call = ::middle::typeck::MethodCall::expr(op_ex.id);
                 fcx.inh.method_map.borrow_mut().insert(method_call, method);
-                check_method_argument_types(fcx,
+                match check_method_argument_types(fcx,
                                             op_ex.span,
                                             method_ty,
                                             op_ex,
                                             args.as_slice(),
                                             DoDerefArgs,
-                                            DontTupleArguments)
+                                            DontTupleArguments) {
+                    ty::FnConverging(result_type) => result_type,
+                    ty::FnDiverging => ty::mk_err()
+                }
             }
             None => {
                 unbound_method();
@@ -3270,7 +3294,8 @@ fn check_unboxed_closure(fcx: &FnCtxt,
         };
         let closure_type = ty::mk_unboxed_closure(fcx.ccx.tcx,
                                                   local_def(expr.id),
-                                                  region);
+                                                  region,
+                                                  fcx.inh.param_env.free_substs.clone());
         fcx.write_ty(expr.id, closure_type);
 
         check_fn(fcx.ccx,
@@ -3661,9 +3686,6 @@ fn check_struct_constructor(fcx: &FnCtxt,
             None => {}
             Some(base_expr) => {
                 check_expr_has_type(fcx, &*base_expr, struct_type);
-                if ty::type_is_bot(fcx.node_ty(base_expr.id)) {
-                    struct_type = ty::mk_bot();
-                }
             }
         }
 
@@ -3761,10 +3783,6 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
             ty::type_is_error(rhs_ty) {
             fcx.write_error(id);
         }
-        else if ty::type_is_bot(lhs_ty) ||
-          (ty::type_is_bot(rhs_ty) && !ast_util::lazy_binop(op)) {
-            fcx.write_bot(id);
-        }
       }
       ast::ExprAssignOp(op, ref lhs, ref rhs) => {
         check_binop(fcx, expr, op, &**lhs, rhs, BinopAssignment);
@@ -3783,8 +3801,7 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
         // Overwrite result of check_binop...this preserves existing behavior
         // but seems quite dubious with regard to user-defined methods
         // and so forth. - Niko
-        if !ty::type_is_error(result_t)
-            && !ty::type_is_bot(result_t) {
+        if !ty::type_is_error(result_t) {
             fcx.write_nil(expr.id);
         }
       }
@@ -3818,9 +3835,7 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
         if !ty::type_is_error(oprnd_t) {
             match unop {
                 ast::UnUniq => {
-                    if !ty::type_is_bot(oprnd_t) {
-                        oprnd_t = ty::mk_uniq(tcx, oprnd_t);
-                    }
+                    oprnd_t = ty::mk_uniq(tcx, oprnd_t);
                 }
                 ast::UnDeref => {
                     oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
@@ -3857,27 +3872,23 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
                     };
                 }
                 ast::UnNot => {
-                    if !ty::type_is_bot(oprnd_t) {
-                        oprnd_t = structurally_resolved_type(fcx, oprnd.span,
-                                                             oprnd_t);
-                        if !(ty::type_is_integral(oprnd_t) ||
-                             ty::get(oprnd_t).sty == ty::ty_bool) {
-                            oprnd_t = check_user_unop(fcx, "!", "not",
-                                                      tcx.lang_items.not_trait(),
-                                                      expr, &**oprnd, oprnd_t);
-                        }
+                    oprnd_t = structurally_resolved_type(fcx, oprnd.span,
+                                                         oprnd_t);
+                    if !(ty::type_is_integral(oprnd_t) ||
+                         ty::get(oprnd_t).sty == ty::ty_bool) {
+                        oprnd_t = check_user_unop(fcx, "!", "not",
+                                                  tcx.lang_items.not_trait(),
+                                                  expr, &**oprnd, oprnd_t);
                     }
                 }
                 ast::UnNeg => {
-                    if !ty::type_is_bot(oprnd_t) {
-                        oprnd_t = structurally_resolved_type(fcx, oprnd.span,
-                                                             oprnd_t);
-                        if !(ty::type_is_integral(oprnd_t) ||
-                             ty::type_is_fp(oprnd_t)) {
-                            oprnd_t = check_user_unop(fcx, "-", "neg",
-                                                      tcx.lang_items.neg_trait(),
-                                                      expr, &**oprnd, oprnd_t);
-                        }
+                    oprnd_t = structurally_resolved_type(fcx, oprnd.span,
+                                                         oprnd_t);
+                    if !(ty::type_is_integral(oprnd_t) ||
+                         ty::type_is_fp(oprnd_t)) {
+                        oprnd_t = check_user_unop(fcx, "-", "neg",
+                                                  tcx.lang_items.neg_trait(),
+                                                  expr, &**oprnd, oprnd_t);
                     }
                 }
             }
@@ -3902,10 +3913,7 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
         let tm = ty::mt { ty: fcx.expr_ty(&**oprnd), mutbl: mutbl };
         let oprnd_t = if ty::type_is_error(tm.ty) {
             ty::mk_err()
-        } else if ty::type_is_bot(tm.ty) {
-            ty::mk_bot()
-        }
-        else {
+        } else {
             // Note: at this point, we cannot say what the best lifetime
             // is to use for resulting pointer.  We want to use the
             // shortest lifetime possible so as to avoid spurious borrowck
@@ -3959,24 +3967,32 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
           fcx.write_nil(id);
       }
       ast::ExprMac(_) => tcx.sess.bug("unexpanded macro"),
-      ast::ExprBreak(_) => { fcx.write_bot(id); }
-      ast::ExprAgain(_) => { fcx.write_bot(id); }
+      ast::ExprBreak(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
+      ast::ExprAgain(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
       ast::ExprRet(ref expr_opt) => {
-        let ret_ty = fcx.ret_ty;
-        match *expr_opt {
-          None => match fcx.mk_eqty(false, infer::Misc(expr.span),
-                                    ret_ty, ty::mk_nil()) {
-            Ok(_) => { /* fall through */ }
-            Err(_) => {
-                span_err!(tcx.sess, expr.span, E0069,
-                    "`return;` in function returning non-nil");
+        match fcx.ret_ty {
+            ty::FnConverging(result_type) => {
+                match *expr_opt {
+                    None =>
+                        if let Err(_) = fcx.mk_eqty(false, infer::Misc(expr.span),
+                                                    result_type, ty::mk_nil()) {
+                            span_err!(tcx.sess, expr.span, E0069,
+                                "`return;` in function returning non-nil");
+                        },
+                    Some(ref e) => {
+                        check_expr_coercable_to_type(fcx, &**e, result_type);
+                    }
+                }
+            }
+            ty::FnDiverging => {
+                if let Some(ref e) = *expr_opt {
+                    check_expr(fcx, &**e);
+                }
+                span_err!(tcx.sess, expr.span, E0166,
+                    "`return` in a function declared as diverging");
             }
-          },
-          Some(ref e) => {
-              check_expr_coercable_to_type(fcx, &**e, ret_ty);
-          }
         }
-        fcx.write_bot(id);
+        fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
       }
       ast::ExprParen(ref a) => {
         check_expr_with_expectation_and_lvalue_pref(fcx,
@@ -4002,8 +4018,6 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
 
         if ty::type_is_error(lhs_ty) || ty::type_is_error(rhs_ty) {
             fcx.write_error(id);
-        } else if ty::type_is_bot(lhs_ty) || ty::type_is_bot(rhs_ty) {
-            fcx.write_bot(id);
         } else {
             fcx.write_nil(id);
         }
@@ -4023,9 +4037,6 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
         if ty::type_is_error(cond_ty) || ty::type_is_error(body_ty) {
             fcx.write_error(id);
         }
-        else if ty::type_is_bot(cond_ty) {
-            fcx.write_bot(id);
-        }
         else {
             fcx.write_nil(id);
         }
@@ -4036,7 +4047,7 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
       ast::ExprForLoop(ref pat, ref head, ref block, _) => {
         check_expr(fcx, &**head);
         let typ = lookup_method_for_for_loop(fcx, &**head, expr.id);
-        vtable2::select_fcx_obligations_where_possible(fcx);
+        vtable::select_new_fcx_obligations(fcx);
 
         let pcx = pat_ctxt {
             fcx: fcx,
@@ -4050,7 +4061,7 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
       ast::ExprLoop(ref body, _) => {
         check_block_no_value(fcx, &**body);
         if !may_break(tcx, expr.id, &**body) {
-            fcx.write_bot(id);
+            fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
         } else {
             fcx.write_nil(id);
         }
@@ -4098,31 +4109,24 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
           let args: Vec<_> = args.iter().map(|x| x).collect();
           if !try_overloaded_call(fcx, expr, &**f, f_ty, args.as_slice()) {
               check_call(fcx, expr, &**f, args.as_slice());
-              let (args_bot, args_err) = args.iter().fold((false, false),
-                 |(rest_bot, rest_err), a| {
+              let args_err = args.iter().fold(false,
+                 |rest_err, a| {
                      // is this not working?
                      let a_ty = fcx.expr_ty(&***a);
-                     (rest_bot || ty::type_is_bot(a_ty),
-                      rest_err || ty::type_is_error(a_ty))});
+                     rest_err || ty::type_is_error(a_ty)});
               if ty::type_is_error(f_ty) || args_err {
                   fcx.write_error(id);
               }
-              else if ty::type_is_bot(f_ty) || args_bot {
-                  fcx.write_bot(id);
-              }
           }
       }
       ast::ExprMethodCall(ident, ref tps, ref args) => {
         check_method_call(fcx, expr, ident, args.as_slice(), tps.as_slice(), lvalue_pref);
         let mut arg_tys = args.iter().map(|a| fcx.expr_ty(&**a));
-        let (args_bot, args_err) = arg_tys.fold((false, false),
-             |(rest_bot, rest_err), a| {
-              (rest_bot || ty::type_is_bot(a),
-               rest_err || ty::type_is_error(a))});
+        let  args_err = arg_tys.fold(false,
+             |rest_err, a| {
+              rest_err || ty::type_is_error(a)});
         if args_err {
             fcx.write_error(id);
-        } else if args_bot {
-            fcx.write_bot(id);
         }
       }
       ast::ExprCast(ref e, ref t) => {
@@ -4201,8 +4205,6 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
 
         if ty::type_is_error(element_ty) {
             fcx.write_error(id);
-        } else if ty::type_is_bot(element_ty) {
-            fcx.write_bot(id);
         } else {
             let t = ty::mk_vec(tcx, t, Some(count));
             fcx.write_ty(id, t);
@@ -4216,7 +4218,6 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
                 _ => None
             }
         });
-        let mut bot_field = false;
         let mut err_field = false;
 
         let elt_ts = elts.iter().enumerate().map(|(i, e)| {
@@ -4232,12 +4233,9 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
                 }
             };
             err_field = err_field || ty::type_is_error(t);
-            bot_field = bot_field || ty::type_is_bot(t);
             t
         }).collect();
-        if bot_field {
-            fcx.write_bot(id);
-        } else if err_field {
+        if err_field {
             fcx.write_error(id);
         } else {
             let typ = ty::mk_tup(tcx, elt_ts);
@@ -4350,7 +4348,7 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
                 autoderef(fcx, expr.span, raw_base_t, Some(base.id),
                           lvalue_pref, |base_t, _| ty::index(base_t));
               match field_ty {
-                  Some(ty) if !ty::type_is_bot(ty) => {
+                  Some(ty) => {
                       check_expr_has_type(fcx, &**idx, ty::mk_uint());
                       fcx.write_ty(id, ty);
                       fcx.write_autoderef_adjustment(base.id, base.span, autoderefs);
@@ -4392,7 +4390,7 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
           let raw_base_t = fcx.expr_ty(&**base);
 
           let mut some_err = false;
-          if ty::type_is_error(raw_base_t) || ty::type_is_bot(raw_base_t) {
+          if ty::type_is_error(raw_base_t) {
               fcx.write_ty(id, raw_base_t);
               some_err = true;
           }
@@ -4401,7 +4399,7 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
               let check_slice_idx = |e: &ast::Expr| {
                   check_expr(fcx, e);
                   let e_t = fcx.expr_ty(e);
-                  if ty::type_is_error(e_t) || ty::type_is_bot(e_t) {
+                  if ty::type_is_error(e_t) {
                     fcx.write_ty(id, e_t);
                     some_err = true;
                   }
@@ -4541,7 +4539,7 @@ pub fn check_decl_local(fcx: &FnCtxt, local: &ast::Local)  {
         Some(ref init) => {
             check_decl_initializer(fcx, local.id, &**init);
             let init_ty = fcx.expr_ty(&**init);
-            if ty::type_is_error(init_ty) || ty::type_is_bot(init_ty) {
+            if ty::type_is_error(init_ty) {
                 fcx.write_ty(local.id, init_ty);
             }
         }
@@ -4554,7 +4552,7 @@ pub fn check_decl_local(fcx: &FnCtxt, local: &ast::Local)  {
     };
     _match::check_pat(&pcx, &*local.pat, t);
     let pat_ty = fcx.node_ty(local.pat.id);
-    if ty::type_is_error(pat_ty) || ty::type_is_bot(pat_ty) {
+    if ty::type_is_error(pat_ty) {
         fcx.write_ty(local.id, pat_ty);
     }
 }
@@ -4570,7 +4568,7 @@ pub fn check_stmt(fcx: &FnCtxt, stmt: &ast::Stmt)  {
           ast::DeclLocal(ref l) => {
               check_decl_local(fcx, &**l);
               let l_t = fcx.node_ty(l.id);
-              saw_bot = saw_bot || ty::type_is_bot(l_t);
+              saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
               saw_err = saw_err || ty::type_is_error(l_t);
           }
           ast::DeclItem(_) => {/* ignore for now */ }
@@ -4581,20 +4579,20 @@ pub fn check_stmt(fcx: &FnCtxt, stmt: &ast::Stmt)  {
         // Check with expected type of ()
         check_expr_has_type(fcx, &**expr, ty::mk_nil());
         let expr_ty = fcx.expr_ty(&**expr);
-        saw_bot = saw_bot || ty::type_is_bot(expr_ty);
+        saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
         saw_err = saw_err || ty::type_is_error(expr_ty);
       }
       ast::StmtSemi(ref expr, id) => {
         node_id = id;
         check_expr(fcx, &**expr);
         let expr_ty = fcx.expr_ty(&**expr);
-        saw_bot |= ty::type_is_bot(expr_ty);
+        saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
         saw_err |= ty::type_is_error(expr_ty);
       }
       ast::StmtMac(..) => fcx.ccx.tcx.sess.bug("unexpanded macro")
     }
     if saw_bot {
-        fcx.write_bot(node_id);
+        fcx.write_ty(node_id, fcx.infcx().next_diverging_ty_var());
     }
     else if saw_err {
         fcx.write_error(node_id);
@@ -4609,11 +4607,7 @@ pub fn check_block_no_value(fcx: &FnCtxt, blk: &ast::Block)  {
     let blkty = fcx.node_ty(blk.id);
     if ty::type_is_error(blkty) {
         fcx.write_error(blk.id);
-    }
-    else if ty::type_is_bot(blkty) {
-        fcx.write_bot(blk.id);
-    }
-    else {
+    } else {
         let nilty = ty::mk_nil();
         demand::suptype(fcx, blk.span, nilty, blkty);
     }
@@ -4629,14 +4623,13 @@ fn check_block_with_expected(fcx: &FnCtxt,
     };
 
     let mut warned = false;
-    let mut last_was_bot = false;
-    let mut any_bot = false;
+    let mut any_diverges = false;
     let mut any_err = false;
     for s in blk.stmts.iter() {
         check_stmt(fcx, &**s);
         let s_id = ast_util::stmt_id(&**s);
         let s_ty = fcx.node_ty(s_id);
-        if last_was_bot && !warned && match s.node {
+        if any_diverges && !warned && match s.node {
             ast::StmtDecl(ref decl, _) => {
                 match decl.node {
                     ast::DeclLocal(_) => true,
@@ -4655,22 +4648,19 @@ fn check_block_with_expected(fcx: &FnCtxt,
                           "unreachable statement".to_string());
             warned = true;
         }
-        if ty::type_is_bot(s_ty) {
-            last_was_bot = true;
-        }
-        any_bot = any_bot || ty::type_is_bot(s_ty);
+        any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
         any_err = any_err || ty::type_is_error(s_ty);
     }
     match blk.expr {
         None => if any_err {
             fcx.write_error(blk.id);
-        } else if any_bot {
-            fcx.write_bot(blk.id);
+        } else if any_diverges {
+            fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
         } else {
             fcx.write_nil(blk.id);
         },
         Some(ref e) => {
-            if any_bot && !warned {
+            if any_diverges && !warned {
                 fcx.ccx
                     .tcx
                     .sess
@@ -4690,11 +4680,12 @@ fn check_block_with_expected(fcx: &FnCtxt,
                 }
             };
 
-            fcx.write_ty(blk.id, ety);
             if any_err {
                 fcx.write_error(blk.id);
-            } else if any_bot {
-                fcx.write_bot(blk.id);
+            } else if any_diverges {
+                fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
+            } else {
+                fcx.write_ty(blk.id, ety);
             }
         }
     };
@@ -4716,7 +4707,7 @@ pub fn check_const_in_type(tcx: &ty::ctxt,
         tcx: tcx,
     };
     let inh = static_inherited_fields(&ccx);
-    let fcx = blank_fn_ctxt(&ccx, &inh, expected_type, expr.id);
+    let fcx = blank_fn_ctxt(&ccx, &inh, ty::FnConverging(expected_type), expr.id);
     check_const_with_ty(&fcx, expr.span, expr, expected_type);
 }
 
@@ -4726,7 +4717,7 @@ pub fn check_const(ccx: &CrateCtxt,
                    id: ast::NodeId) {
     let inh = static_inherited_fields(ccx);
     let rty = ty::node_id_to_type(ccx.tcx, id);
-    let fcx = blank_fn_ctxt(ccx, &inh, rty, e.id);
+    let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
     let declty = (*fcx.ccx.tcx.tcache.borrow())[local_def(id)].ty;
     check_const_with_ty(&fcx, sp, e, declty);
 }
@@ -4743,7 +4734,7 @@ pub fn check_const_with_ty(fcx: &FnCtxt,
 
     check_expr_with_hint(fcx, e, declty);
     demand::coerce(fcx, e.span, declty, e);
-    vtable2::select_all_fcx_obligations_or_error(fcx);
+    vtable::select_all_fcx_obligations_or_error(fcx);
     regionck::regionck_expr(fcx, e);
     writeback::resolve_type_vars_in_expr(fcx, e);
 }
@@ -4890,7 +4881,7 @@ fn do_check(ccx: &CrateCtxt,
                     debug!("disr expr, checking {}", pprust::expr_to_string(&**e));
 
                     let inh = static_inherited_fields(ccx);
-                    let fcx = blank_fn_ctxt(ccx, &inh, rty, e.id);
+                    let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
                     let declty = match hint {
                         attr::ReprAny | attr::ReprPacked | attr::ReprExtern => ty::mk_int(),
                         attr::ReprInt(_, attr::SignedInt(ity)) => {
@@ -5392,18 +5383,32 @@ fn adjust_region_parameters(
 
 // Resolves `typ` by a single level if `typ` is a type variable.  If no
 // resolution is possible, then an error is reported.
-pub fn structurally_resolved_type(fcx: &FnCtxt, sp: Span, tp: ty::t) -> ty::t {
-    match infer::resolve_type(fcx.infcx(), Some(sp), tp, force_tvar) {
-        Ok(t_s) if !ty::type_is_ty_var(t_s) => t_s,
-        _ => {
-            fcx.type_error_message(sp, |_actual| {
-                "the type of this value must be known in this \
-                 context".to_string()
-            }, tp, None);
-            demand::suptype(fcx, sp, ty::mk_err(), tp);
-            tp
-        }
-    }
+pub fn structurally_resolved_type(fcx: &FnCtxt, sp: Span, mut ty: ty::t) -> ty::t {
+    // If `ty` is a type variable, see whether we already know what it is.
+    ty = fcx.infcx().shallow_resolve(ty);
+
+    // If not, try resolve pending fcx obligations. Those can shed light.
+    //
+    // FIXME(#18391) -- This current strategy can lead to bad performance in
+    // extreme cases.  We probably ought to smarter in general about
+    // only resolving when we need help and only resolving obligations
+    // will actually help.
+    if ty::type_is_ty_var(ty) {
+        vtable::select_fcx_obligations_where_possible(fcx);
+        ty = fcx.infcx().shallow_resolve(ty);
+    }
+
+    // If not, error.
+    if ty::type_is_ty_var(ty) {
+        fcx.type_error_message(sp, |_actual| {
+            "the type of this value must be known in this \
+             context".to_string()
+        }, ty, None);
+        demand::suptype(fcx, sp, ty::mk_err(), ty);
+        ty = ty::mk_err();
+    }
+
+    ty
 }
 
 // Returns the one-level-deep structure of the given type.
@@ -5478,7 +5483,7 @@ fn param(ccx: &CrateCtxt, n: uint) -> ty::t {
         assert!(split.len() >= 2, "Atomic intrinsic not correct format");
 
         //We only care about the operation here
-        match split[1] {
+        let (n_tps, inputs, output) = match split[1] {
             "cxchg" => (1, vec!(ty::mk_mut_ptr(tcx, param(ccx, 0)),
                                 param(ccx, 0),
                                 param(ccx, 0)),
@@ -5501,12 +5506,12 @@ fn param(ccx: &CrateCtxt, n: uint) -> ty::t {
                     "unrecognized atomic operation function: `{}`", op);
                 return;
             }
-        }
-
+        };
+        (n_tps, inputs, ty::FnConverging(output))
+    } else if name.get() == "abort" || name.get() == "unreachable" {
+        (0, Vec::new(), ty::FnDiverging)
     } else {
-        match name.get() {
-            "abort" => (0, Vec::new(), ty::mk_bot()),
-            "unreachable" => (0, Vec::new(), ty::mk_bot()),
+        let (n_tps, inputs, output) = match name.get() {
             "breakpoint" => (0, Vec::new(), ty::mk_nil()),
             "size_of" |
             "pref_align_of" | "min_align_of" => (1u, Vec::new(), ty::mk_uint()),
@@ -5714,7 +5719,8 @@ fn param(ccx: &CrateCtxt, n: uint) -> ty::t {
                     "unrecognized intrinsic function: `{}`", *other);
                 return;
             }
-        }
+        };
+        (n_tps, inputs, ty::FnConverging(output))
     };
     let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
         fn_style: ast::UnsafeFn,
index 6d135c0c90e30a5ea7612d48cd97113865ff8102..bcade1e74ca65d8b910b1c6cfce1ab21d28e76f8 100644 (file)
@@ -126,7 +126,7 @@ fn get_i(x: &'a Bar) -> &'a int {
 use middle::typeck::astconv::AstConv;
 use middle::typeck::check::FnCtxt;
 use middle::typeck::check::regionmanip;
-use middle::typeck::check::vtable2;
+use middle::typeck::check::vtable;
 use middle::typeck::infer::resolve_and_force_all_but_regions;
 use middle::typeck::infer::resolve_type;
 use middle::typeck::infer;
@@ -172,7 +172,7 @@ pub fn regionck_fn(fcx: &FnCtxt, id: ast::NodeId, blk: &ast::Block) {
 
     // Region checking a fn can introduce new trait obligations,
     // particularly around closure bounds.
-    vtable2::select_all_fcx_obligations_or_error(fcx);
+    vtable::select_all_fcx_obligations_or_error(fcx);
 
     fcx.infcx().resolve_regions_and_report_errors();
 }
@@ -334,7 +334,7 @@ fn resolve_method_type(&self, method_call: MethodCall) -> Option<ty::t> {
     /// Try to resolve the type for the given node.
     pub fn resolve_expr_type_adjusted(&mut self, expr: &ast::Expr) -> ty::t {
         let ty_unadjusted = self.resolve_node_type(expr.id);
-        if ty::type_is_error(ty_unadjusted) || ty::type_is_bot(ty_unadjusted) {
+        if ty::type_is_error(ty_unadjusted) {
             ty_unadjusted
         } else {
             let tcx = self.fcx.tcx();
@@ -690,7 +690,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
                 Some(method) => {
                     constrain_call(rcx, expr, Some(&**base),
                                    None::<ast::Expr>.iter(), true);
-                    ty::ty_fn_ret(method.ty)
+                    ty::ty_fn_ret(method.ty).unwrap()
                 }
                 None => rcx.resolve_node_type(base.id)
             };
@@ -867,7 +867,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
                 }
             });
         }
-        ty::ty_unboxed_closure(_, region) => {
+        ty::ty_unboxed_closure(_, region, _) => {
             if tcx.capture_modes.borrow().get_copy(&expr.id) == ast::CaptureByRef {
                 ty::with_freevars(tcx, expr.id, |freevars| {
                     if !freevars.is_empty() {
@@ -908,7 +908,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
                 ensure_free_variable_types_outlive_closure_bound(rcx, bounds, expr, freevars);
             })
         }
-        ty::ty_unboxed_closure(_, region) => {
+        ty::ty_unboxed_closure(_, region, _) => {
             ty::with_freevars(tcx, expr.id, |freevars| {
                 let bounds = ty::region_existential_bound(region);
                 ensure_free_variable_types_outlive_closure_bound(rcx, bounds, expr, freevars);
@@ -1217,9 +1217,14 @@ fn constrain_autoderefs(rcx: &mut Rcx,
                 // Specialized version of constrain_call.
                 type_must_outlive(rcx, infer::CallRcvr(deref_expr.span),
                                   self_ty, r_deref_expr);
-                type_must_outlive(rcx, infer::CallReturn(deref_expr.span),
-                                  fn_sig.output, r_deref_expr);
-                fn_sig.output
+                match fn_sig.output {
+                    ty::FnConverging(return_type) => {
+                        type_must_outlive(rcx, infer::CallReturn(deref_expr.span),
+                                          return_type, r_deref_expr);
+                        return_type
+                    }
+                    ty::FnDiverging => unreachable!()
+                }
             }
             None => derefd_ty
         };
@@ -1445,7 +1450,7 @@ fn link_region_from_node_type(rcx: &Rcx,
      */
 
     let rptr_ty = rcx.resolve_node_type(id);
-    if !ty::type_is_bot(rptr_ty) && !ty::type_is_error(rptr_ty) {
+    if !ty::type_is_error(rptr_ty) {
         let tcx = rcx.fcx.ccx.tcx;
         debug!("rptr_ty={}", ty_to_string(tcx, rptr_ty));
         let r = ty::ty_region(tcx, span, rptr_ty);
@@ -1674,7 +1679,7 @@ fn link_reborrowed_region(rcx: &Rcx,
             //
             // If mutability was inferred from an upvar, we may be
             // forced to revisit this decision later if processing
-            // another borrow or nested closure ends up coverting the
+            // another borrow or nested closure ends up converting the
             // upvar borrow kind to mutable/unique.  Record the
             // information needed to perform the recursive link in the
             // maybe link map.
index a448a93c5178fdfc58cbff8b4baaddd94583bd91..225a3162af90470c62d7d5d617961817e4b55389 100644 (file)
@@ -92,7 +92,6 @@ fn accumulate_from_ty(&mut self, ty: ty::t) {
 
         match ty::get(ty).sty {
             ty::ty_nil |
-            ty::ty_bot |
             ty::ty_bool |
             ty::ty_char |
             ty::ty_int(..) |
@@ -108,7 +107,7 @@ fn accumulate_from_ty(&mut self, ty: ty::t) {
                 self.accumulate_from_closure_ty(ty, c);
             }
 
-            ty::ty_unboxed_closure(_, region) => {
+            ty::ty_unboxed_closure(_, region, _) => {
                 // An "unboxed closure type" is basically
                 // modeled here as equivalent to a struct like
                 //
@@ -118,6 +117,18 @@ fn accumulate_from_ty(&mut self, ty: ty::t) {
                 //
                 // where the `'b` is the lifetime bound of the
                 // contents (i.e., all contents must outlive 'b).
+                //
+                // Even though unboxed closures are glorified structs
+                // of upvars, we do not need to consider them as they
+                // can't generate any new constraints.  The
+                // substitutions on the closure are equal to the free
+                // substitutions of the enclosing parameter
+                // environment.  An upvar captured by value has the
+                // same type as the original local variable which is
+                // already checked for consistency.  If the upvar is
+                // captured by reference it must also outlive the
+                // region bound on the closure, but this is explicitly
+                // handled by logic in regionck.
                 self.push_region_constraint_from_top(region);
             }
 
diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs
new file mode 100644 (file)
index 0000000..b719573
--- /dev/null
@@ -0,0 +1,532 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use middle::subst::{SelfSpace, FnSpace};
+use middle::traits;
+use middle::traits::{SelectionError, OutputTypeParameterMismatch, Overflow, Unimplemented};
+use middle::traits::{Obligation, obligation_for_builtin_bound};
+use middle::traits::{FulfillmentError, CodeSelectionError, CodeAmbiguity};
+use middle::traits::{ObligationCause};
+use middle::ty;
+use middle::typeck::check::{FnCtxt,
+                            structurally_resolved_type};
+use middle::typeck::infer;
+use std::rc::Rc;
+use syntax::ast;
+use syntax::codemap::Span;
+use util::ppaux::{UserString, Repr, ty_to_string};
+
+pub fn check_object_cast(fcx: &FnCtxt,
+                         cast_expr: &ast::Expr,
+                         source_expr: &ast::Expr,
+                         target_object_ty: ty::t)
+{
+    debug!("check_object_cast(cast_expr={}, target_object_ty={})",
+           cast_expr.repr(fcx.tcx()),
+           target_object_ty.repr(fcx.tcx()));
+
+    // Look up vtables for the type we're casting to,
+    // passing in the source and target type.  The source
+    // must be a pointer type suitable to the object sigil,
+    // e.g.: `&x as &Trait` or `box x as Box<Trait>`
+    let source_ty = fcx.expr_ty(source_expr);
+    let source_ty = structurally_resolved_type(fcx, source_expr.span, source_ty);
+    debug!("source_ty={}", source_ty.repr(fcx.tcx()));
+    match (&ty::get(source_ty).sty, &ty::get(target_object_ty).sty) {
+        (&ty::ty_uniq(referent_ty), &ty::ty_uniq(object_trait_ty)) => {
+            let object_trait = object_trait(&object_trait_ty);
+
+            // Ensure that if ~T is cast to ~Trait, then T : Trait
+            push_cast_obligation(fcx, cast_expr, object_trait, referent_ty);
+            check_object_safety(fcx.tcx(), object_trait, source_expr.span);
+        }
+
+        (&ty::ty_rptr(referent_region, ty::mt { ty: referent_ty,
+                                                mutbl: referent_mutbl }),
+         &ty::ty_rptr(target_region, ty::mt { ty: object_trait_ty,
+                                              mutbl: target_mutbl })) =>
+        {
+            let object_trait = object_trait(&object_trait_ty);
+            if !mutability_allowed(referent_mutbl, target_mutbl) {
+                fcx.tcx().sess.span_err(source_expr.span,
+                                        "types differ in mutability");
+            } else {
+                // Ensure that if &'a T is cast to &'b Trait, then T : Trait
+                push_cast_obligation(fcx, cast_expr,
+                                     object_trait,
+                                     referent_ty);
+
+                // Ensure that if &'a T is cast to &'b Trait, then 'b <= 'a
+                infer::mk_subr(fcx.infcx(),
+                               infer::RelateObjectBound(source_expr.span),
+                               target_region,
+                               referent_region);
+
+                check_object_safety(fcx.tcx(), object_trait, source_expr.span);
+            }
+        }
+
+        (_, &ty::ty_uniq(..)) => {
+            fcx.ccx.tcx.sess.span_err(
+                source_expr.span,
+                format!("can only cast an boxed pointer \
+                         to a boxed object, not a {}",
+                        ty::ty_sort_string(fcx.tcx(), source_ty)).as_slice());
+        }
+
+        (_, &ty::ty_rptr(..)) => {
+            fcx.ccx.tcx.sess.span_err(
+                source_expr.span,
+                format!("can only cast a &-pointer \
+                         to an &-object, not a {}",
+                        ty::ty_sort_string(fcx.tcx(), source_ty)).as_slice());
+        }
+
+        _ => {
+            fcx.tcx().sess.span_bug(
+                source_expr.span,
+                "expected object type");
+        }
+    }
+
+    // Because we currently give unsound lifetimes to the "t_box", I
+    // could have written &'static ty::TyTrait here, but it seems
+    // gratuitously unsafe.
+    fn object_trait<'a>(t: &'a ty::t) -> &'a ty::TyTrait {
+        match ty::get(*t).sty {
+            ty::ty_trait(ref ty_trait) => &**ty_trait,
+            _ => panic!("expected ty_trait")
+        }
+    }
+
+    fn mutability_allowed(a_mutbl: ast::Mutability,
+                          b_mutbl: ast::Mutability)
+                          -> bool {
+        a_mutbl == b_mutbl ||
+            (a_mutbl == ast::MutMutable && b_mutbl == ast::MutImmutable)
+    }
+
+    fn push_cast_obligation(fcx: &FnCtxt,
+                            cast_expr: &ast::Expr,
+                            object_trait: &ty::TyTrait,
+                            referent_ty: ty::t) {
+        let object_trait_ref =
+            register_object_cast_obligations(fcx,
+                                             cast_expr.span,
+                                             object_trait,
+                                             referent_ty);
+
+        // Finally record the object_trait_ref for use during trans
+        // (it would prob be better not to do this, but it's just kind
+        // of a pain to have to reconstruct it).
+        fcx.write_object_cast(cast_expr.id, object_trait_ref);
+    }
+}
+
+// Check that a trait is 'object-safe'. This should be checked whenever a trait object
+// is created (by casting or coercion, etc.). A trait is object-safe if all its
+// methods are object-safe. A trait method is object-safe if it does not take
+// self by value, has no type parameters and does not use the `Self` type, except
+// in self position.
+pub fn check_object_safety(tcx: &ty::ctxt, object_trait: &ty::TyTrait, span: Span) {
+    // Skip the fn_once lang item trait since only the compiler should call
+    // `call_once` which is the method which takes self by value. What could go
+    // wrong?
+    match tcx.lang_items.fn_once_trait() {
+        Some(def_id) if def_id == object_trait.def_id => return,
+        _ => {}
+    }
+
+    let trait_items = ty::trait_items(tcx, object_trait.def_id);
+
+    let mut errors = Vec::new();
+    for item in trait_items.iter() {
+        match *item {
+            ty::MethodTraitItem(ref m) => {
+                errors.push(check_object_safety_of_method(tcx, &**m))
+            }
+            ty::TypeTraitItem(_) => {}
+        }
+    }
+
+    let mut errors = errors.iter().flat_map(|x| x.iter()).peekable();
+    if errors.peek().is_some() {
+        let trait_name = ty::item_path_str(tcx, object_trait.def_id);
+        span_err!(tcx.sess, span, E0038,
+            "cannot convert to a trait object because trait `{}` is not object-safe",
+            trait_name);
+
+        for msg in errors {
+            tcx.sess.note(msg.as_slice());
+        }
+    }
+
+    // Returns a vec of error messages. If hte vec is empty - no errors!
+    fn check_object_safety_of_method(tcx: &ty::ctxt, method: &ty::Method) -> Vec<String> {
+        /*!
+         * There are some limitations to calling functions through an
+         * object, because (a) the self type is not known
+         * (that's the whole point of a trait instance, after all, to
+         * obscure the self type) and (b) the call must go through a
+         * vtable and hence cannot be monomorphized.
+         */
+        let mut msgs = Vec::new();
+
+        let method_name = method.name.repr(tcx);
+
+        match method.explicit_self {
+            ty::ByValueExplicitSelfCategory => { // reason (a) above
+                msgs.push(format!("cannot call a method (`{}`) with a by-value \
+                                   receiver through a trait object", method_name))
+            }
+
+            ty::StaticExplicitSelfCategory |
+            ty::ByReferenceExplicitSelfCategory(..) |
+            ty::ByBoxExplicitSelfCategory => {}
+        }
+
+        // reason (a) above
+        let check_for_self_ty = |ty| {
+            if ty::type_has_self(ty) {
+                Some(format!(
+                    "cannot call a method (`{}`) whose type contains \
+                     a self-type (`{}`) through a trait object",
+                    method_name, ty_to_string(tcx, ty)))
+            } else {
+                None
+            }
+        };
+        let ref sig = method.fty.sig;
+        for &input_ty in sig.inputs[1..].iter() {
+            match check_for_self_ty(input_ty) {
+                Some(msg) => msgs.push(msg),
+                _ => {}
+            }
+        }
+        if let ty::FnConverging(result_type) = sig.output {
+            match check_for_self_ty(result_type) {
+                Some(msg) => msgs.push(msg),
+                _ => {}
+            }
+        }
+
+        if method.generics.has_type_params(FnSpace) {
+            // reason (b) above
+            msgs.push(format!("cannot call a generic method (`{}`) through a trait object",
+                              method_name));
+        }
+
+        msgs
+    }
+}
+
+pub fn register_object_cast_obligations(fcx: &FnCtxt,
+                                        span: Span,
+                                        object_trait: &ty::TyTrait,
+                                        referent_ty: ty::t)
+                                        -> Rc<ty::TraitRef>
+{
+    // This is just for better error reporting. Kinda goofy. The object type stuff
+    // needs some refactoring so there is a more convenient type to pass around.
+    let object_trait_ty =
+        ty::mk_trait(fcx.tcx(),
+                     object_trait.def_id,
+                     object_trait.substs.clone(),
+                     object_trait.bounds);
+
+    debug!("register_object_cast_obligations: referent_ty={} object_trait_ty={}",
+           referent_ty.repr(fcx.tcx()),
+           object_trait_ty.repr(fcx.tcx()));
+
+    // Take the type parameters from the object type, but set
+    // the Self type (which is unknown, for the object type)
+    // to be the type we are casting from.
+    let mut object_substs = object_trait.substs.clone();
+    assert!(object_substs.self_ty().is_none());
+    object_substs.types.push(SelfSpace, referent_ty);
+
+    // Create the obligation for casting from T to Trait.
+    let object_trait_ref =
+        Rc::new(ty::TraitRef { def_id: object_trait.def_id,
+                               substs: object_substs });
+    let object_obligation =
+        Obligation::new(
+            ObligationCause::new(span,
+                                 traits::ObjectCastObligation(object_trait_ty)),
+            object_trait_ref.clone());
+    fcx.register_obligation(object_obligation);
+
+    // Create additional obligations for all the various builtin
+    // bounds attached to the object cast. (In other words, if the
+    // object type is Foo+Send, this would create an obligation
+    // for the Send check.)
+    for builtin_bound in object_trait.bounds.builtin_bounds.iter() {
+            let obligation = obligation_for_builtin_bound(
+                fcx.tcx(),
+                ObligationCause::new(span,
+                                     traits::ObjectCastObligation(object_trait_ty)),
+                referent_ty,
+                builtin_bound);
+            match obligation {
+                Ok(obligation) => fcx.register_obligation(obligation),
+                _ => {}
+            }
+    }
+
+    object_trait_ref
+}
+
+pub fn select_all_fcx_obligations_or_error(fcx: &FnCtxt) {
+    debug!("select_all_fcx_obligations_or_error");
+
+    let mut fulfillment_cx = fcx.inh.fulfillment_cx.borrow_mut();
+    let r = fulfillment_cx.select_all_or_error(fcx.infcx(),
+                                               &fcx.inh.param_env,
+                                               fcx);
+    match r {
+        Ok(()) => { }
+        Err(errors) => { report_fulfillment_errors(fcx, &errors); }
+    }
+}
+
+fn resolve_trait_ref(fcx: &FnCtxt, obligation: &Obligation)
+                     -> (ty::TraitRef, ty::t)
+{
+    let trait_ref =
+        fcx.infcx().resolve_type_vars_in_trait_ref_if_possible(
+            &*obligation.trait_ref);
+    let self_ty =
+        trait_ref.substs.self_ty().unwrap();
+    (trait_ref, self_ty)
+}
+
+pub fn report_fulfillment_errors(fcx: &FnCtxt,
+                                 errors: &Vec<FulfillmentError>) {
+    for error in errors.iter() {
+        report_fulfillment_error(fcx, error);
+    }
+}
+
+pub fn report_fulfillment_error(fcx: &FnCtxt,
+                                error: &FulfillmentError) {
+    match error.code {
+        CodeSelectionError(ref e) => {
+            report_selection_error(fcx, &error.obligation, e);
+        }
+        CodeAmbiguity => {
+            maybe_report_ambiguity(fcx, &error.obligation);
+        }
+    }
+}
+
+pub fn report_selection_error(fcx: &FnCtxt,
+                              obligation: &Obligation,
+                              error: &SelectionError)
+{
+    match *error {
+        Overflow => {
+            let (trait_ref, self_ty) = resolve_trait_ref(fcx, obligation);
+            fcx.tcx().sess.span_err(
+                obligation.cause.span,
+                format!(
+                    "overflow evaluating the trait `{}` for the type `{}`",
+                    trait_ref.user_string(fcx.tcx()),
+                    self_ty.user_string(fcx.tcx())).as_slice());
+            note_obligation_cause(fcx, obligation);
+        }
+        Unimplemented => {
+            let (trait_ref, self_ty) = resolve_trait_ref(fcx, obligation);
+            if !ty::type_is_error(self_ty) {
+                fcx.tcx().sess.span_err(
+                    obligation.cause.span,
+                    format!(
+                        "the trait `{}` is not implemented for the type `{}`",
+                        trait_ref.user_string(fcx.tcx()),
+                        self_ty.user_string(fcx.tcx())).as_slice());
+                note_obligation_cause(fcx, obligation);
+            }
+        }
+        OutputTypeParameterMismatch(ref expected_trait_ref, ref e) => {
+            let expected_trait_ref =
+                fcx.infcx().resolve_type_vars_in_trait_ref_if_possible(
+                    &**expected_trait_ref);
+            let (trait_ref, self_ty) = resolve_trait_ref(fcx, obligation);
+            if !ty::type_is_error(self_ty) {
+                fcx.tcx().sess.span_err(
+                    obligation.cause.span,
+                    format!(
+                        "type mismatch: the type `{}` implements the trait `{}`, \
+                         but the trait `{}` is required ({})",
+                        self_ty.user_string(fcx.tcx()),
+                        expected_trait_ref.user_string(fcx.tcx()),
+                        trait_ref.user_string(fcx.tcx()),
+                        ty::type_err_to_str(fcx.tcx(), e)).as_slice());
+                note_obligation_cause(fcx, obligation);
+            }
+        }
+    }
+}
+
+pub fn maybe_report_ambiguity(fcx: &FnCtxt, obligation: &Obligation) {
+    // Unable to successfully determine, probably means
+    // insufficient type information, but could mean
+    // ambiguous impls. The latter *ought* to be a
+    // coherence violation, so we don't report it here.
+    let (trait_ref, self_ty) = resolve_trait_ref(fcx, obligation);
+    debug!("maybe_report_ambiguity(trait_ref={}, self_ty={}, obligation={})",
+           trait_ref.repr(fcx.tcx()),
+           self_ty.repr(fcx.tcx()),
+           obligation.repr(fcx.tcx()));
+    let all_types = &trait_ref.substs.types;
+    if all_types.iter().any(|&t| ty::type_is_error(t)) {
+    } else if all_types.iter().any(|&t| ty::type_needs_infer(t)) {
+        // This is kind of a hack: it frequently happens that some earlier
+        // error prevents types from being fully inferred, and then we get
+        // a bunch of uninteresting errors saying something like "<generic
+        // #0> doesn't implement Sized".  It may even be true that we
+        // could just skip over all checks where the self-ty is an
+        // inference variable, but I was afraid that there might be an
+        // inference variable created, registered as an obligation, and
+        // then never forced by writeback, and hence by skipping here we'd
+        // be ignoring the fact that we don't KNOW the type works
+        // out. Though even that would probably be harmless, given that
+        // we're only talking about builtin traits, which are known to be
+        // inhabited. But in any case I just threw in this check for
+        // has_errors() to be sure that compilation isn't happening
+        // anyway. In that case, why inundate the user.
+        if !fcx.tcx().sess.has_errors() {
+            fcx.tcx().sess.span_err(
+                obligation.cause.span,
+                format!(
+                    "unable to infer enough type information to \
+                     locate the impl of the trait `{}` for \
+                     the type `{}`; type annotations required",
+                    trait_ref.user_string(fcx.tcx()),
+                    self_ty.user_string(fcx.tcx())).as_slice());
+            note_obligation_cause(fcx, obligation);
+        }
+    } else if !fcx.tcx().sess.has_errors() {
+         // Ambiguity. Coherence should have reported an error.
+        fcx.tcx().sess.span_bug(
+            obligation.cause.span,
+            format!(
+                "coherence failed to report ambiguity: \
+                 cannot locate the impl of the trait `{}` for \
+                 the type `{}`",
+                trait_ref.user_string(fcx.tcx()),
+                self_ty.user_string(fcx.tcx())).as_slice());
+    }
+}
+
+pub fn select_fcx_obligations_where_possible(fcx: &FnCtxt) {
+    /*! Select as many obligations as we can at present. */
+
+    match
+        fcx.inh.fulfillment_cx
+        .borrow_mut()
+        .select_where_possible(fcx.infcx(), &fcx.inh.param_env, fcx)
+    {
+        Ok(()) => { }
+        Err(errors) => { report_fulfillment_errors(fcx, &errors); }
+    }
+}
+
+pub fn select_new_fcx_obligations(fcx: &FnCtxt) {
+    /*!
+     * Try to select any fcx obligation that we haven't tried yet,
+     * in an effort to improve inference. You could just call
+     * `select_fcx_obligations_where_possible` except that it leads
+     * to repeated work.
+     */
+
+    match
+        fcx.inh.fulfillment_cx
+        .borrow_mut()
+        .select_new_obligations(fcx.infcx(), &fcx.inh.param_env, fcx)
+    {
+        Ok(()) => { }
+        Err(errors) => { report_fulfillment_errors(fcx, &errors); }
+    }
+}
+
+fn note_obligation_cause(fcx: &FnCtxt,
+                         obligation: &Obligation) {
+    let tcx = fcx.tcx();
+    let trait_name = ty::item_path_str(tcx, obligation.trait_ref.def_id);
+    match obligation.cause.code {
+        traits::MiscObligation => { }
+        traits::ItemObligation(item_def_id) => {
+            let item_name = ty::item_path_str(tcx, item_def_id);
+            tcx.sess.span_note(
+                obligation.cause.span,
+                format!(
+                    "the trait `{}` must be implemented because it is required by `{}`",
+                    trait_name,
+                    item_name).as_slice());
+        }
+        traits::ObjectCastObligation(object_ty) => {
+            tcx.sess.span_note(
+                obligation.cause.span,
+                format!(
+                    "the trait `{}` must be implemented for the cast \
+                     to the object type `{}`",
+                    trait_name,
+                    fcx.infcx().ty_to_string(object_ty)).as_slice());
+        }
+        traits::RepeatVec => {
+            tcx.sess.span_note(
+                obligation.cause.span,
+                "the `Copy` trait is required because the \
+                 repeated element will be copied");
+        }
+        traits::VariableType(_) => {
+            tcx.sess.span_note(
+                obligation.cause.span,
+                "all local variables must have a statically known size");
+        }
+        traits::ReturnType => {
+            tcx.sess.span_note(
+                obligation.cause.span,
+                "the return type of a function must have a \
+                 statically known size");
+        }
+        traits::AssignmentLhsSized => {
+            tcx.sess.span_note(
+                obligation.cause.span,
+                "the left-hand-side of an assignment must have a statically known size");
+        }
+        traits::StructInitializerSized => {
+            tcx.sess.span_note(
+                obligation.cause.span,
+                "structs must have a statically known size to be initialized");
+        }
+        traits::DropTrait => {
+            span_note!(tcx.sess, obligation.cause.span,
+                      "cannot implement a destructor on a \
+                      structure or enumeration that does not satisfy Send");
+            span_note!(tcx.sess, obligation.cause.span,
+                       "use \"#[unsafe_destructor]\" on the implementation \
+                       to force the compiler to allow this");
+        }
+        traits::ClosureCapture(var_id, closure_span) => {
+            let name = ty::local_var_name_str(tcx, var_id);
+            span_note!(tcx.sess, closure_span,
+                       "the closure that captures `{}` requires that all captured variables \"
+                       implement the trait `{}`",
+                       name,
+                       trait_name);
+        }
+        traits::FieldSized => {
+            span_note!(tcx.sess, obligation.cause.span,
+                       "only the last field of a struct or enum variant \
+                       may have a dynamically sized type")
+        }
+    }
+}
diff --git a/src/librustc/middle/typeck/check/vtable2.rs b/src/librustc/middle/typeck/check/vtable2.rs
deleted file mode 100644 (file)
index d557a2b..0000000
+++ /dev/null
@@ -1,415 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use middle::subst::{SelfSpace};
-use middle::traits;
-use middle::traits::{SelectionError, OutputTypeParameterMismatch, Overflow, Unimplemented};
-use middle::traits::{Obligation, obligation_for_builtin_bound};
-use middle::traits::{FulfillmentError, CodeSelectionError, CodeAmbiguity};
-use middle::traits::{ObligationCause};
-use middle::ty;
-use middle::typeck::check::{FnCtxt,
-                            structurally_resolved_type};
-use middle::typeck::infer;
-use std::rc::Rc;
-use syntax::ast;
-use syntax::codemap::Span;
-use util::ppaux::UserString;
-use util::ppaux::Repr;
-
-pub fn check_object_cast(fcx: &FnCtxt,
-                         cast_expr: &ast::Expr,
-                         source_expr: &ast::Expr,
-                         target_object_ty: ty::t)
-{
-    debug!("check_object_cast(cast_expr={}, target_object_ty={})",
-           cast_expr.repr(fcx.tcx()),
-           target_object_ty.repr(fcx.tcx()));
-
-    // Look up vtables for the type we're casting to,
-    // passing in the source and target type.  The source
-    // must be a pointer type suitable to the object sigil,
-    // e.g.: `&x as &Trait` or `box x as Box<Trait>`
-    let source_ty = fcx.expr_ty(source_expr);
-    let source_ty = structurally_resolved_type(fcx, source_expr.span, source_ty);
-    debug!("source_ty={}", source_ty.repr(fcx.tcx()));
-    match (&ty::get(source_ty).sty, &ty::get(target_object_ty).sty) {
-        (&ty::ty_uniq(referent_ty), &ty::ty_uniq(object_trait_ty)) => {
-            let object_trait = object_trait(&object_trait_ty);
-
-            // Ensure that if ~T is cast to ~Trait, then T : Trait
-            push_cast_obligation(fcx, cast_expr, object_trait, referent_ty);
-        }
-
-        (&ty::ty_rptr(referent_region, ty::mt { ty: referent_ty,
-                                                mutbl: referent_mutbl }),
-         &ty::ty_rptr(target_region, ty::mt { ty: object_trait_ty,
-                                              mutbl: target_mutbl })) =>
-        {
-            let object_trait = object_trait(&object_trait_ty);
-            if !mutability_allowed(referent_mutbl, target_mutbl) {
-                fcx.tcx().sess.span_err(source_expr.span,
-                                        "types differ in mutability");
-            } else {
-                // Ensure that if &'a T is cast to &'b Trait, then T : Trait
-                push_cast_obligation(fcx, cast_expr,
-                                     object_trait,
-                                     referent_ty);
-
-                // Ensure that if &'a T is cast to &'b Trait, then 'b <= 'a
-                infer::mk_subr(fcx.infcx(),
-                               infer::RelateObjectBound(source_expr.span),
-                               target_region,
-                               referent_region);
-            }
-        }
-
-        (_, &ty::ty_uniq(..)) => {
-            fcx.ccx.tcx.sess.span_err(
-                source_expr.span,
-                format!("can only cast an boxed pointer \
-                         to a boxed object, not a {}",
-                        ty::ty_sort_string(fcx.tcx(), source_ty)).as_slice());
-        }
-
-        (_, &ty::ty_rptr(..)) => {
-            fcx.ccx.tcx.sess.span_err(
-                source_expr.span,
-                format!("can only cast a &-pointer \
-                         to an &-object, not a {}",
-                        ty::ty_sort_string(fcx.tcx(), source_ty)).as_slice());
-        }
-
-        _ => {
-            fcx.tcx().sess.span_bug(
-                source_expr.span,
-                "expected object type");
-        }
-    }
-
-    // Because we currently give unsound lifetimes to the "t_box", I
-    // could have written &'static ty::TyTrait here, but it seems
-    // gratuitously unsafe.
-    fn object_trait<'a>(t: &'a ty::t) -> &'a ty::TyTrait {
-        match ty::get(*t).sty {
-            ty::ty_trait(ref ty_trait) => &**ty_trait,
-            _ => fail!("expected ty_trait")
-        }
-    }
-
-    fn mutability_allowed(a_mutbl: ast::Mutability,
-                          b_mutbl: ast::Mutability)
-                          -> bool {
-        a_mutbl == b_mutbl ||
-            (a_mutbl == ast::MutMutable && b_mutbl == ast::MutImmutable)
-    }
-
-    fn push_cast_obligation(fcx: &FnCtxt,
-                            cast_expr: &ast::Expr,
-                            object_trait: &ty::TyTrait,
-                            referent_ty: ty::t) {
-        let object_trait_ref =
-            register_object_cast_obligations(fcx,
-                                             cast_expr.span,
-                                             object_trait,
-                                             referent_ty);
-
-        // Finally record the object_trait_ref for use during trans
-        // (it would prob be better not to do this, but it's just kind
-        // of a pain to have to reconstruct it).
-        fcx.write_object_cast(cast_expr.id, object_trait_ref);
-    }
-}
-
-pub fn register_object_cast_obligations(fcx: &FnCtxt,
-                                        span: Span,
-                                        object_trait: &ty::TyTrait,
-                                        referent_ty: ty::t)
-                                        -> Rc<ty::TraitRef>
-{
-    // This is just for better error reporting. Kinda goofy. The object type stuff
-    // needs some refactoring so there is a more convenient type to pass around.
-    let object_trait_ty =
-        ty::mk_trait(fcx.tcx(),
-                     object_trait.def_id,
-                     object_trait.substs.clone(),
-                     object_trait.bounds);
-
-    debug!("register_object_cast_obligations: referent_ty={} object_trait_ty={}",
-           referent_ty.repr(fcx.tcx()),
-           object_trait_ty.repr(fcx.tcx()));
-
-    // Take the type parameters from the object type, but set
-    // the Self type (which is unknown, for the object type)
-    // to be the type we are casting from.
-    let mut object_substs = object_trait.substs.clone();
-    assert!(object_substs.self_ty().is_none());
-    object_substs.types.push(SelfSpace, referent_ty);
-
-    // Create the obligation for casting from T to Trait.
-    let object_trait_ref =
-        Rc::new(ty::TraitRef { def_id: object_trait.def_id,
-                               substs: object_substs });
-    let object_obligation =
-        Obligation::new(
-            ObligationCause::new(span,
-                                 traits::ObjectCastObligation(object_trait_ty)),
-            object_trait_ref.clone());
-    fcx.register_obligation(object_obligation);
-
-    // Create additional obligations for all the various builtin
-    // bounds attached to the object cast. (In other words, if the
-    // object type is Foo+Send, this would create an obligation
-    // for the Send check.)
-    for builtin_bound in object_trait.bounds.builtin_bounds.iter() {
-            let obligation = obligation_for_builtin_bound(
-                fcx.tcx(),
-                ObligationCause::new(span,
-                                     traits::ObjectCastObligation(object_trait_ty)),
-                referent_ty,
-                builtin_bound);
-            match obligation {
-                Ok(obligation) => fcx.register_obligation(obligation),
-                _ => {}
-            }
-    }
-
-    object_trait_ref
-}
-
-pub fn select_all_fcx_obligations_or_error(fcx: &FnCtxt) {
-    debug!("select_all_fcx_obligations_or_error");
-
-    let mut fulfillment_cx = fcx.inh.fulfillment_cx.borrow_mut();
-    let r = fulfillment_cx.select_all_or_error(fcx.infcx(),
-                                               &fcx.inh.param_env,
-                                               fcx);
-    match r {
-        Ok(()) => { }
-        Err(errors) => { report_fulfillment_errors(fcx, &errors); }
-    }
-}
-
-fn resolve_trait_ref(fcx: &FnCtxt, obligation: &Obligation)
-                     -> (ty::TraitRef, ty::t)
-{
-    let trait_ref =
-        fcx.infcx().resolve_type_vars_in_trait_ref_if_possible(
-            &*obligation.trait_ref);
-    let self_ty =
-        trait_ref.substs.self_ty().unwrap();
-    (trait_ref, self_ty)
-}
-
-pub fn report_fulfillment_errors(fcx: &FnCtxt,
-                                 errors: &Vec<FulfillmentError>) {
-    for error in errors.iter() {
-        report_fulfillment_error(fcx, error);
-    }
-}
-
-pub fn report_fulfillment_error(fcx: &FnCtxt,
-                                error: &FulfillmentError) {
-    match error.code {
-        CodeSelectionError(ref e) => {
-            report_selection_error(fcx, &error.obligation, e);
-        }
-        CodeAmbiguity => {
-            maybe_report_ambiguity(fcx, &error.obligation);
-        }
-    }
-}
-
-pub fn report_selection_error(fcx: &FnCtxt,
-                              obligation: &Obligation,
-                              error: &SelectionError)
-{
-    match *error {
-        Overflow => {
-            let (trait_ref, self_ty) = resolve_trait_ref(fcx, obligation);
-            fcx.tcx().sess.span_err(
-                obligation.cause.span,
-                format!(
-                    "overflow evaluating the trait `{}` for the type `{}`",
-                    trait_ref.user_string(fcx.tcx()),
-                    self_ty.user_string(fcx.tcx())).as_slice());
-            note_obligation_cause(fcx, obligation);
-        }
-        Unimplemented => {
-            let (trait_ref, self_ty) = resolve_trait_ref(fcx, obligation);
-            if !ty::type_is_error(self_ty) {
-                fcx.tcx().sess.span_err(
-                    obligation.cause.span,
-                    format!(
-                        "the trait `{}` is not implemented for the type `{}`",
-                        trait_ref.user_string(fcx.tcx()),
-                        self_ty.user_string(fcx.tcx())).as_slice());
-                note_obligation_cause(fcx, obligation);
-            }
-        }
-        OutputTypeParameterMismatch(ref expected_trait_ref, ref e) => {
-            let expected_trait_ref =
-                fcx.infcx().resolve_type_vars_in_trait_ref_if_possible(
-                    &**expected_trait_ref);
-            let (trait_ref, self_ty) = resolve_trait_ref(fcx, obligation);
-            if !ty::type_is_error(self_ty) {
-                fcx.tcx().sess.span_err(
-                    obligation.cause.span,
-                    format!(
-                        "type mismatch: the type `{}` implements the trait `{}`, \
-                         but the trait `{}` is required ({})",
-                        self_ty.user_string(fcx.tcx()),
-                        expected_trait_ref.user_string(fcx.tcx()),
-                        trait_ref.user_string(fcx.tcx()),
-                        ty::type_err_to_str(fcx.tcx(), e)).as_slice());
-                note_obligation_cause(fcx, obligation);
-            }
-        }
-    }
-}
-
-pub fn maybe_report_ambiguity(fcx: &FnCtxt, obligation: &Obligation) {
-    // Unable to successfully determine, probably means
-    // insufficient type information, but could mean
-    // ambiguous impls. The latter *ought* to be a
-    // coherence violation, so we don't report it here.
-    let (trait_ref, self_ty) = resolve_trait_ref(fcx, obligation);
-    debug!("maybe_report_ambiguity(trait_ref={}, self_ty={}, obligation={})",
-           trait_ref.repr(fcx.tcx()),
-           self_ty.repr(fcx.tcx()),
-           obligation.repr(fcx.tcx()));
-    let all_types = &trait_ref.substs.types;
-    if all_types.iter().any(|&t| ty::type_is_error(t)) {
-    } else if all_types.iter().any(|&t| ty::type_needs_infer(t)) {
-        // This is kind of a hack: it frequently happens that some earlier
-        // error prevents types from being fully inferred, and then we get
-        // a bunch of uninteresting errors saying something like "<generic
-        // #0> doesn't implement Sized".  It may even be true that we
-        // could just skip over all checks where the self-ty is an
-        // inference variable, but I was afraid that there might be an
-        // inference variable created, registered as an obligation, and
-        // then never forced by writeback, and hence by skipping here we'd
-        // be ignoring the fact that we don't KNOW the type works
-        // out. Though even that would probably be harmless, given that
-        // we're only talking about builtin traits, which are known to be
-        // inhabited. But in any case I just threw in this check for
-        // has_errors() to be sure that compilation isn't happening
-        // anyway. In that case, why inundate the user.
-        if !fcx.tcx().sess.has_errors() {
-            fcx.tcx().sess.span_err(
-                obligation.cause.span,
-                format!(
-                    "unable to infer enough type information to \
-                     locate the impl of the trait `{}` for \
-                     the type `{}`; type annotations required",
-                    trait_ref.user_string(fcx.tcx()),
-                    self_ty.user_string(fcx.tcx())).as_slice());
-            note_obligation_cause(fcx, obligation);
-        }
-    } else if !fcx.tcx().sess.has_errors() {
-         // Ambiguity. Coherence should have reported an error.
-        fcx.tcx().sess.span_bug(
-            obligation.cause.span,
-            format!(
-                "coherence failed to report ambiguity: \
-                 cannot locate the impl of the trait `{}` for \
-                 the type `{}`",
-                trait_ref.user_string(fcx.tcx()),
-                self_ty.user_string(fcx.tcx())).as_slice());
-    }
-}
-
-pub fn select_fcx_obligations_where_possible(fcx: &FnCtxt) {
-    /*! Select as many obligations as we can at present. */
-
-    match
-        fcx.inh.fulfillment_cx
-        .borrow_mut()
-        .select_where_possible(fcx.infcx(), &fcx.inh.param_env, fcx)
-    {
-        Ok(()) => { }
-        Err(errors) => { report_fulfillment_errors(fcx, &errors); }
-    }
-}
-
-fn note_obligation_cause(fcx: &FnCtxt,
-                         obligation: &Obligation) {
-    let tcx = fcx.tcx();
-    let trait_name = ty::item_path_str(tcx, obligation.trait_ref.def_id);
-    match obligation.cause.code {
-        traits::MiscObligation => { }
-        traits::ItemObligation(item_def_id) => {
-            let item_name = ty::item_path_str(tcx, item_def_id);
-            tcx.sess.span_note(
-                obligation.cause.span,
-                format!(
-                    "the trait `{}` must be implemented because it is required by `{}`",
-                    trait_name,
-                    item_name).as_slice());
-        }
-        traits::ObjectCastObligation(object_ty) => {
-            tcx.sess.span_note(
-                obligation.cause.span,
-                format!(
-                    "the trait `{}` must be implemented for the cast \
-                     to the object type `{}`",
-                    trait_name,
-                    fcx.infcx().ty_to_string(object_ty)).as_slice());
-        }
-        traits::RepeatVec => {
-            tcx.sess.span_note(
-                obligation.cause.span,
-                "the `Copy` trait is required because the \
-                 repeated element will be copied");
-        }
-        traits::VariableType(_) => {
-            tcx.sess.span_note(
-                obligation.cause.span,
-                "all local variables must have a statically known size");
-        }
-        traits::ReturnType => {
-            tcx.sess.span_note(
-                obligation.cause.span,
-                "the return type of a function must have a \
-                 statically known size");
-        }
-        traits::AssignmentLhsSized => {
-            tcx.sess.span_note(
-                obligation.cause.span,
-                "the left-hand-side of an assignment must have a statically known size");
-        }
-        traits::StructInitializerSized => {
-            tcx.sess.span_note(
-                obligation.cause.span,
-                "structs must have a statically known size to be initialized");
-        }
-        traits::DropTrait => {
-            span_note!(tcx.sess, obligation.cause.span,
-                      "cannot implement a destructor on a \
-                      structure or enumeration that does not satisfy Send");
-            span_note!(tcx.sess, obligation.cause.span,
-                       "use \"#[unsafe_destructor]\" on the implementation \
-                       to force the compiler to allow this");
-        }
-        traits::ClosureCapture(var_id, closure_span) => {
-            let name = ty::local_var_name_str(tcx, var_id);
-            span_note!(tcx.sess, closure_span,
-                       "the closure that captures `{}` requires that all captured variables \"
-                       implement the trait `{}`",
-                       name,
-                       trait_name);
-        }
-        traits::FieldSized => {
-            span_note!(tcx.sess, obligation.cause.span,
-                       "only the last field of a struct or enum variant \
-                       may have a dynamically sized type")
-        }
-    }
-}
index dc79fd4aa328c151fdf75d200069f08f96ae2630..b3449d658f6d6e556da15cb8914a003960f97e7f 100644 (file)
@@ -14,7 +14,7 @@
 use middle::ty;
 use middle::ty_fold::{TypeFolder, TypeFoldable};
 use middle::typeck::astconv::AstConv;
-use middle::typeck::check::{FnCtxt, Inherited, blank_fn_ctxt, vtable2, regionck};
+use middle::typeck::check::{FnCtxt, Inherited, blank_fn_ctxt, vtable, regionck};
 use middle::typeck::check::regionmanip::replace_late_bound_regions;
 use middle::typeck::CrateCtxt;
 use util::ppaux::Repr;
@@ -98,9 +98,9 @@ fn with_fcx(&mut self,
                                                 &polytype.generics,
                                                 item.id);
         let inh = Inherited::new(ccx.tcx, param_env);
-        let fcx = blank_fn_ctxt(ccx, &inh, polytype.ty, item.id);
+        let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(polytype.ty), item.id);
         f(self, &fcx);
-        vtable2::select_all_fcx_obligations_or_error(&fcx);
+        vtable::select_all_fcx_obligations_or_error(&fcx);
         regionck::regionck_item(&fcx, item);
     }
 
index cb4e878c22cc30b0e5ae4067cef53cd509c4d376..a569053507cf88ff96d8ef7ef565e70e066177a2 100644 (file)
@@ -23,7 +23,7 @@
 use middle::ty::get;
 use middle::ty::{ImplContainer, ImplOrTraitItemId, MethodTraitItemId};
 use middle::ty::{TypeTraitItemId, lookup_item_type};
-use middle::ty::{t, ty_bool, ty_char, ty_bot, ty_enum, ty_err};
+use middle::ty::{t, ty_bool, ty_char, ty_enum, ty_err};
 use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_nil, ty_open};
 use middle::ty::{ty_param, Polytype, ty_ptr};
 use middle::ty::{ty_rptr, ty_struct, ty_trait, ty_tup};
@@ -82,7 +82,7 @@ fn get_base_type(inference_context: &InferCtxt,
             Some(resolved_type)
         }
 
-        ty_nil | ty_bot | ty_bool | ty_char | ty_int(..) | ty_uint(..) | ty_float(..) |
+        ty_nil | ty_bool | ty_char | ty_int(..) | ty_uint(..) | ty_float(..) |
         ty_str(..) | ty_vec(..) | ty_bare_fn(..) | ty_closure(..) | ty_tup(..) |
         ty_infer(..) | ty_param(..) | ty_err | ty_open(..) | ty_uniq(_) |
         ty_ptr(_) | ty_rptr(_, _) => {
@@ -90,7 +90,7 @@ fn get_base_type(inference_context: &InferCtxt,
                    get(original_type).sty);
             None
         }
-        ty_trait(..) => fail!("should have been caught")
+        ty_trait(..) => panic!("should have been caught")
     }
 }
 
@@ -105,7 +105,7 @@ fn get_base_type_def_id(inference_context: &InferCtxt,
             match get(base_type).sty {
                 ty_enum(def_id, _) |
                 ty_struct(def_id, _) |
-                ty_unboxed_closure(def_id, _) => {
+                ty_unboxed_closure(def_id, _, _) => {
                     Some(def_id)
                 }
                 ty_ptr(ty::mt {ty, ..}) |
@@ -116,7 +116,7 @@ fn get_base_type_def_id(inference_context: &InferCtxt,
                             Some(def_id)
                         }
                         _ => {
-                            fail!("get_base_type() returned a type that wasn't an \
+                            panic!("get_base_type() returned a type that wasn't an \
                                    enum, struct, or trait");
                         }
                     }
@@ -125,7 +125,7 @@ fn get_base_type_def_id(inference_context: &InferCtxt,
                     Some(def_id)
                 }
                 _ => {
-                    fail!("get_base_type() returned a type that wasn't an \
+                    panic!("get_base_type() returned a type that wasn't an \
                            enum, struct, or trait");
                 }
             }
@@ -445,7 +445,7 @@ fn populate_destructor_table(&self) {
             match ty::get(self_type.ty).sty {
                 ty::ty_enum(type_def_id, _) |
                 ty::ty_struct(type_def_id, _) |
-                ty::ty_unboxed_closure(type_def_id, _) => {
+                ty::ty_unboxed_closure(type_def_id, _, _) => {
                     tcx.destructor_for_type
                        .borrow_mut()
                        .insert(type_def_id, method_def_id.def_id());
index 1f4b80b360bd266a2f6fa4634d1807e37172d764..847d8e88bde88b25c8a5fed7e14e631e15777dfc 100644 (file)
@@ -1593,7 +1593,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::Item)
             return pty;
         }
         ast::ItemImpl(..) | ast::ItemMod(_) |
-        ast::ItemForeignMod(_) | ast::ItemMac(_) => fail!(),
+        ast::ItemForeignMod(_) | ast::ItemMac(_) => panic!(),
     }
 }
 
@@ -2236,7 +2236,10 @@ pub fn ty_of_foreign_fn_decl(ccx: &CrateCtxt,
                         .map(|a| ty_of_arg(ccx, &rb, a, None))
                         .collect();
 
-    let output_ty = ast_ty_to_ty(ccx, &rb, &*decl.output);
+    let output = match decl.output.node {
+        ast::TyBot => ty::FnDiverging,
+        _ => ty::FnConverging(ast_ty_to_ty(ccx, &rb, &*decl.output))
+    };
 
     let t_fn = ty::mk_bare_fn(
         ccx.tcx,
@@ -2245,7 +2248,7 @@ pub fn ty_of_foreign_fn_decl(ccx: &CrateCtxt,
             fn_style: ast::UnsafeFn,
             sig: ty::FnSig {binder_id: def_id.node,
                             inputs: input_tys,
-                            output: output_ty,
+                            output: output,
                             variadic: decl.variadic}
         });
     let pty = Polytype {
index d2e062a20d2ec8f1b928ce642f6632c10e6ecbe9..de9379a3aa763e79442d94105340877a9d1f7495 100644 (file)
@@ -105,6 +105,15 @@ fn substs(&self,
         } else {
             None
         };
+        self.substs_variances(variances.as_ref().map(|v| &**v), a_subst, b_subst)
+    }
+
+    fn substs_variances(&self,
+                        variances: Option<&ty::ItemVariances>,
+                        a_subst: &subst::Substs,
+                        b_subst: &subst::Substs)
+                        -> cres<subst::Substs>
+    {
         let mut substs = subst::Substs::empty();
 
         for &space in subst::ParamSpace::all().iter() {
@@ -126,7 +135,7 @@ fn substs(&self,
 
                     let mut invariance = Vec::new();
                     let r_variances = match variances {
-                        Some(ref variances) => {
+                        Some(variances) => {
                             variances.regions.get_slice(space)
                         }
                         None => {
@@ -138,7 +147,6 @@ fn substs(&self,
                     };
 
                     let regions = try!(relate_region_params(self,
-                                                            item_def_id,
                                                             r_variances,
                                                             a_regions,
                                                             b_regions));
@@ -150,7 +158,6 @@ fn substs(&self,
         return Ok(substs);
 
         fn relate_region_params<'tcx, C: Combine<'tcx>>(this: &C,
-                                                        item_def_id: ast::DefId,
                                                         variances: &[ty::Variance],
                                                         a_rs: &[ty::Region],
                                                         b_rs: &[ty::Region])
@@ -159,11 +166,9 @@ fn relate_region_params<'tcx, C: Combine<'tcx>>(this: &C,
             let num_region_params = variances.len();
 
             debug!("relate_region_params(\
-                   item_def_id={}, \
                    a_rs={}, \
                    b_rs={},
                    variances={})",
-                   item_def_id.repr(tcx),
                    a_rs.repr(tcx),
                    b_rs.repr(tcx),
                    variances.repr(tcx));
@@ -354,7 +359,18 @@ fn argvecs<'tcx, C: Combine<'tcx>>(this: &C,
     let inputs = try!(argvecs(this,
                                 a.inputs.as_slice(),
                                 b.inputs.as_slice()));
-    let output = try!(this.tys(a.output, b.output));
+
+    let output = try!(match (a.output, b.output) {
+        (ty::FnConverging(a_ty), ty::FnConverging(b_ty)) =>
+            Ok(ty::FnConverging(try!(this.tys(a_ty, b_ty)))),
+        (ty::FnDiverging, ty::FnDiverging) =>
+            Ok(ty::FnDiverging),
+        (a, b) =>
+            Err(ty::terr_convergence_mismatch(
+                expected_found(this, a != ty::FnDiverging, b != ty::FnDiverging)
+            )),
+    });
+
     Ok(FnSig {binder_id: a.binder_id,
               inputs: inputs,
               output: output,
@@ -368,9 +384,7 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C, a: ty::t, b: ty::t) -> cres<t
     let b_sty = &ty::get(b).sty;
     debug!("super_tys: a_sty={} b_sty={}", a_sty, b_sty);
     return match (a_sty, b_sty) {
-      // The "subtype" ought to be handling cases involving bot or var:
-      (&ty::ty_bot, _) |
-      (_, &ty::ty_bot) |
+      // The "subtype" ought to be handling cases involving var:
       (&ty::ty_infer(TyVar(_)), _) |
       (_, &ty::ty_infer(TyVar(_))) => {
         tcx.sess.bug(
@@ -464,14 +478,15 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C, a: ty::t, b: ty::t) -> cres<t
             Ok(ty::mk_struct(tcx, a_id, substs))
       }
 
-      (&ty::ty_unboxed_closure(a_id, a_region),
-       &ty::ty_unboxed_closure(b_id, b_region))
+      (&ty::ty_unboxed_closure(a_id, a_region, ref a_substs),
+       &ty::ty_unboxed_closure(b_id, b_region, ref b_substs))
       if a_id == b_id => {
           // All ty_unboxed_closure types with the same id represent
           // the (anonymous) type of the same closure expression. So
           // all of their regions should be equated.
           let region = try!(this.equate().regions(a_region, b_region));
-          Ok(ty::mk_unboxed_closure(tcx, a_id, region))
+          let substs = try!(this.substs_variances(None, a_substs, b_substs));
+          Ok(ty::mk_unboxed_closure(tcx, a_id, region, substs))
       }
 
       (&ty::ty_uniq(a_inner), &ty::ty_uniq(b_inner)) => {
index fd4a5927362188d066f61e5626e03f0225409695..97453dc86efd442ed6fe769fedf33fd721212d07 100644 (file)
@@ -112,15 +112,6 @@ fn tys(&self, a: ty::t, b: ty::t) -> cres<ty::t> {
         let a = infcx.type_variables.borrow().replace_if_possible(a);
         let b = infcx.type_variables.borrow().replace_if_possible(b);
         match (&ty::get(a).sty, &ty::get(b).sty) {
-            (&ty::ty_bot, &ty::ty_bot) => {
-                Ok(a)
-            }
-
-            (&ty::ty_bot, _) |
-            (_, &ty::ty_bot) => {
-                Err(ty::terr_sorts(expected_found(self, a, b)))
-            }
-
             (&ty::ty_infer(TyVar(a_id)), &ty::ty_infer(TyVar(b_id))) => {
                 infcx.type_variables.borrow_mut().relate_vars(a_id, EqTo, b_id);
                 Ok(a)
index 83ca67f33bc31a7a7e5a47a4af97138619b622f9..fbf2918c2921af615a48b22314310b3b45e54290 100644 (file)
@@ -210,7 +210,7 @@ fn generalize_region(this: &Glb,
 
             // NB---I do not believe this algorithm computes
             // (necessarily) the GLB.  As written it can
-            // spuriously fail.  In particular, if there is a case
+            // spuriously fail. In particular, if there is a case
             // like: |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
index 24642d5213892ddb1a563f383d7278d1bf9fc18d..4fb7bebc58f6d7e29c695f5af6afb7d14694566c 100644 (file)
 use std::collections::HashMap;
 
 pub trait LatticeDir {
-    // Relates the bottom type to `t` and returns LUB(t, _|_) or
-    // GLB(t, _|_) as appropriate.
-    fn ty_bot(&self, t: ty::t) -> cres<ty::t>;
-
     // Relates the type `v` to `a` and `b` such that `v` represents
     // the LUB/GLB of `a` and `b` as appropriate.
     fn relate_bound<'a>(&'a self, v: ty::t, a: ty::t, b: ty::t) -> cres<()>;
 }
 
 impl<'a, 'tcx> LatticeDir for Lub<'a, 'tcx> {
-    fn ty_bot(&self, t: ty::t) -> cres<ty::t> {
-        Ok(t)
-    }
-
     fn relate_bound<'a>(&'a self, v: ty::t, a: ty::t, b: ty::t) -> cres<()> {
         let sub = self.sub();
         try!(sub.tys(a, v));
@@ -65,10 +57,6 @@ fn relate_bound<'a>(&'a self, v: ty::t, a: ty::t, b: ty::t) -> cres<()> {
 }
 
 impl<'a, 'tcx> LatticeDir for Glb<'a, 'tcx> {
-    fn ty_bot(&self, _: ty::t) -> cres<ty::t> {
-        Ok(ty::mk_bot())
-    }
-
     fn relate_bound<'a>(&'a self, v: ty::t, a: ty::t, b: ty::t) -> cres<()> {
         let sub = self.sub();
         try!(sub.tys(v, a));
@@ -95,8 +83,12 @@ pub fn super_lattice_tys<'tcx, L:LatticeDir+Combine<'tcx>>(this: &L,
     let a = infcx.type_variables.borrow().replace_if_possible(a);
     let b = infcx.type_variables.borrow().replace_if_possible(b);
     match (&ty::get(a).sty, &ty::get(b).sty) {
-        (&ty::ty_bot, _) => { this.ty_bot(b) }
-        (_, &ty::ty_bot) => { this.ty_bot(a) }
+        (&ty::ty_infer(TyVar(..)), &ty::ty_infer(TyVar(..)))
+            if infcx.type_var_diverges(a) && infcx.type_var_diverges(b) => {
+            let v = infcx.next_diverging_ty_var();
+            try!(this.relate_bound(v, a, b));
+            Ok(v)
+        }
 
         (&ty::ty_infer(TyVar(..)), _) |
         (_, &ty::ty_infer(TyVar(..))) => {
index a466581ef394a0ea570a589e326f7dd654b7223b..d2a77f906b5356954a205746c63f69599369e59d 100644 (file)
@@ -510,6 +510,13 @@ pub fn skolemize<T:TypeFoldable>(&self, t: T) -> T {
         t.fold_with(&mut self.skolemizer())
     }
 
+    pub fn type_var_diverges(&'a self, ty: ty::t) -> bool {
+        match ty::get(ty).sty {
+            ty::ty_infer(ty::TyVar(vid)) => self.type_variables.borrow().var_diverges(vid),
+            _ => false
+        }
+    }
+
     pub fn skolemizer<'a>(&'a self) -> TypeSkolemizer<'a, 'tcx> {
         skolemize::TypeSkolemizer::new(self)
     }
@@ -596,7 +603,7 @@ pub fn commit_if_ok<T,E>(&self, f: || -> Result<T,E>) -> Result<T,E> {
         self.commit_unconditionally(|| self.try(|| f()))
     }
 
-    /// Execute `f`, unroll bindings on failure
+    /// Execute `f`, unroll bindings on panic
     pub fn try<T,E>(&self, f: || -> Result<T,E>) -> Result<T,E> {
         debug!("try()");
         let snapshot = self.start_snapshot();
@@ -684,14 +691,18 @@ pub fn sub_trait_refs(&self,
 }
 
 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
-    pub fn next_ty_var_id(&self) -> TyVid {
+    pub fn next_ty_var_id(&self, diverging: bool) -> TyVid {
         self.type_variables
             .borrow_mut()
-            .new_var()
+            .new_var(diverging)
     }
 
     pub fn next_ty_var(&self) -> ty::t {
-        ty::mk_var(self.tcx, self.next_ty_var_id())
+        ty::mk_var(self.tcx, self.next_ty_var_id(false))
+    }
+
+    pub fn next_diverging_ty_var(&self) -> ty::t {
+        ty::mk_var(self.tcx, self.next_ty_var_id(true))
     }
 
     pub fn next_ty_vars(&self, n: uint) -> Vec<ty::t> {
index b4704b2a27c97f5d959d16a6173b4e92399fd5e9..80213d43ec4378a43e7eee7058e6e97c009ae875 100644 (file)
@@ -273,7 +273,7 @@ pub fn rollback_to(&self, snapshot: RegionSnapshot) {
         while undo_log.len() > snapshot.length + 1 {
             match undo_log.pop().unwrap() {
                 OpenSnapshot => {
-                    fail!("Failure to observe stack discipline");
+                    panic!("Failure to observe stack discipline");
                 }
                 Mark | CommitedSnapshot => { }
                 AddVar(vid) => {
@@ -916,7 +916,7 @@ fn intersect_scopes(&self,
         // We want to generate the intersection of two
         // scopes or two free regions.  So, if one of
         // these scopes is a subscope of the other, return
-        // it.  Otherwise fail.
+        // it. Otherwise fail.
         debug!("intersect_scopes(scope_a={}, scope_b={}, region_a={}, region_b={})",
                scope_a, scope_b, region_a, region_b);
         match self.tcx.region_maps.nearest_common_ancestor(scope_a, scope_b) {
index 87f3fd987871cdea8336a33a84896dcd4b364941..db26376fc69db2144f60271a286639c842ed1ee6 100644 (file)
@@ -205,7 +205,8 @@ pub fn resolve_region_var(&mut self, rid: RegionVid) -> ty::Region {
 
     pub fn resolve_ty_var(&mut self, vid: TyVid) -> ty::t {
         let tcx = self.infcx.tcx;
-        let t1 = match self.infcx.type_variables.borrow().probe(vid) {
+        let tv = self.infcx.type_variables.borrow();
+        match tv.probe(vid) {
             Some(t) => {
                 self.resolve_type(t)
             }
@@ -215,8 +216,7 @@ pub fn resolve_ty_var(&mut self, vid: TyVid) -> ty::t {
                 }
                 ty::mk_var(tcx, vid)
             }
-        };
-        return t1;
+        }
     }
 
     pub fn resolve_int_var(&mut self, vid: IntVid) -> ty::t {
index 1b3290c8b5af8f5c3172cfdfe4e63aee4256d6cd..0fe1e2b565befa4a12ce0588ba00778b9613de5e 100644 (file)
@@ -149,7 +149,6 @@ fn fold_ty(&mut self, t: ty::t) -> ty::t {
             }
 
             ty::ty_nil |
-            ty::ty_bot |
             ty::ty_bool |
             ty::ty_char |
             ty::ty_int(..) |
index 4c04bcc5236f4af88ab9949cbe0f0e5a2a817007..f44fa1ac1c69689272482f0e9b8472428a071823 100644 (file)
@@ -129,10 +129,6 @@ fn tys(&self, a: ty::t, b: ty::t) -> cres<ty::t> {
         let a = infcx.type_variables.borrow().replace_if_possible(a);
         let b = infcx.type_variables.borrow().replace_if_possible(b);
         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))) => {
                 infcx.type_variables
                     .borrow_mut()
@@ -154,10 +150,6 @@ fn tys(&self, a: ty::t, b: ty::t) -> cres<ty::t> {
                 Ok(ty::mk_err())
             }
 
-            (_, &ty::ty_bot) => {
-                Err(ty::terr_sorts(expected_found(self, a, b)))
-            }
-
             _ => {
                 super_tys(self, a, b)
             }
index cad648a8ddbb9a53c934e57d4d85b336856fa7f9..5b1ee7c64b4a37c7ffe8ca8160b8ea896b4380f8 100644 (file)
@@ -67,7 +67,7 @@ fn remove_message(e: &mut ExpectErrorEmitter, msg: &str, lvl: Level) {
             e.messages.remove(i);
         }
         None => {
-            fail!("Unexpected error: {} Expected: {}",
+            panic!("Unexpected error: {} Expected: {}",
                   msg, e.messages);
         }
     }
@@ -169,7 +169,7 @@ pub fn lookup_item(&self, names: &[String]) -> ast::NodeId {
         return match search_mod(self, &self.infcx.tcx.map.krate().module, 0, names) {
             Some(id) => id,
             None => {
-                fail!("no item found: `{}`", names.connect("::"));
+                panic!("no item found: `{}`", names.connect("::"));
             }
         };
 
@@ -218,7 +218,7 @@ fn search(this: &Env,
     pub fn make_subtype(&self, a: ty::t, b: ty::t) -> bool {
         match infer::mk_subty(self.infcx, true, infer::Misc(DUMMY_SP), a, b) {
             Ok(_) => true,
-            Err(ref e) => fail!("Encountered error: {}",
+            Err(ref e) => panic!("Encountered error: {}",
                                 ty::type_err_to_str(self.infcx.tcx, e))
         }
     }
@@ -232,7 +232,7 @@ pub fn is_subtype(&self, a: ty::t, b: ty::t) -> bool {
 
     pub fn assert_subtype(&self, a: ty::t, b: ty::t) {
         if !self.is_subtype(a, b) {
-            fail!("{} is not a subtype of {}, but it should be",
+            panic!("{} is not a subtype of {}, but it should be",
                   self.ty_to_string(a),
                   self.ty_to_string(b));
         }
@@ -240,7 +240,7 @@ pub fn assert_subtype(&self, a: ty::t, b: ty::t) {
 
     pub fn assert_not_subtype(&self, a: ty::t, b: ty::t) {
         if self.is_subtype(a, b) {
-            fail!("{} is a subtype of {}, but it shouldn't be",
+            panic!("{} is a subtype of {}, but it shouldn't be",
                   self.ty_to_string(a),
                   self.ty_to_string(b));
         }
@@ -315,7 +315,7 @@ pub fn resolve_regions(&self) {
     pub fn make_lub_ty(&self, t1: ty::t, t2: ty::t) -> ty::t {
         match self.lub().tys(t1, t2) {
             Ok(t) => t,
-            Err(ref e) => fail!("unexpected error computing LUB: {}",
+            Err(ref e) => panic!("unexpected error computing LUB: {}",
                                 ty::type_err_to_str(self.infcx.tcx, e))
         }
     }
@@ -327,7 +327,7 @@ pub fn check_lub(&self, t1: ty::t, t2: ty::t, t_lub: ty::t) {
                 self.assert_eq(t, t_lub);
             }
             Err(ref e) => {
-                fail!("unexpected error in LUB: {}",
+                panic!("unexpected error in LUB: {}",
                       ty::type_err_to_str(self.infcx.tcx, e))
             }
         }
@@ -341,7 +341,7 @@ pub fn check_glb(&self, t1: ty::t, t2: ty::t, t_glb: ty::t) {
                self.ty_to_string(t_glb));
         match self.glb().tys(t1, t2) {
             Err(e) => {
-                fail!("unexpected error computing LUB: {}", e)
+                panic!("unexpected error computing LUB: {}", e)
             }
             Ok(t) => {
                 self.assert_eq(t, t_glb);
@@ -358,7 +358,7 @@ pub fn check_no_lub(&self, t1: ty::t, t2: ty::t) {
         match self.lub().tys(t1, t2) {
             Err(_) => {}
             Ok(t) => {
-                fail!("unexpected success computing LUB: {}", self.ty_to_string(t))
+                panic!("unexpected success computing LUB: {}", self.ty_to_string(t))
             }
         }
     }
@@ -368,7 +368,7 @@ pub fn check_no_glb(&self, t1: ty::t, t2: ty::t) {
         match self.glb().tys(t1, t2) {
             Err(_) => {}
             Ok(t) => {
-                fail!("unexpected success computing GLB: {}", self.ty_to_string(t))
+                panic!("unexpected success computing GLB: {}", self.ty_to_string(t))
             }
         }
     }
index 5f67f8a048aa4e48148975db250b758319ab6304..63094ceaabdf962e701ad0e08f5cbfbf3a0301aa 100644 (file)
@@ -17,7 +17,8 @@ pub struct TypeVariableTable {
 }
 
 struct TypeVariableData {
-    value: TypeVariableValue
+    value: TypeVariableValue,
+    diverging: bool
 }
 
 enum TypeVariableValue {
@@ -63,6 +64,10 @@ fn relations<'a>(&'a mut self, a: ty::TyVid) -> &'a mut Vec<Relation> {
         relations(self.values.get_mut(a.index))
     }
 
+    pub fn var_diverges<'a>(&'a self, vid: ty::TyVid) -> bool {
+        self.values.get(vid.index).diverging
+    }
+
     pub fn relate_vars(&mut self, a: ty::TyVid, dir: RelationDir, b: ty::TyVid) {
         /*!
          * Records that `a <: b`, `a :> b`, or `a == b`, depending on `dir`.
@@ -97,7 +102,7 @@ pub fn instantiate_and_push(
 
         let relations = match old_value {
             Bounded(b) => b,
-            Known(_) => fail!("Asked to instantiate variable that is \
+            Known(_) => panic!("Asked to instantiate variable that is \
                                already instantiated")
         };
 
@@ -108,10 +113,11 @@ pub fn instantiate_and_push(
         self.values.record(SpecifyVar(vid, relations));
     }
 
-    pub fn new_var(&mut self) -> ty::TyVid {
-        let index =
-            self.values.push(
-                TypeVariableData { value: Bounded(Vec::new()) });
+    pub fn new_var(&mut self, diverging: bool) -> ty::TyVid {
+        let index = self.values.push(TypeVariableData {
+            value: Bounded(vec![]),
+            diverging: diverging
+        });
         ty::TyVid { index: index }
     }
 
@@ -166,7 +172,7 @@ fn reverse(&mut self,
 
 fn relations<'a>(v: &'a mut TypeVariableData) -> &'a mut Vec<Relation> {
     match v.value {
-        Known(_) => fail!("var_sub_var: variable is known"),
+        Known(_) => panic!("var_sub_var: variable is known"),
         Bounded(ref mut relations) => relations
     }
 }
index 301582d55d6eb0bbfc6fca57126e468bbe6bf485..d93e985190cffccacc7a5afa3eaa3b962cda4571 100644 (file)
@@ -245,7 +245,7 @@ pub fn unify(&mut self,
 
 impl<K,V> sv::SnapshotVecDelegate<VarValue<K,V>,()> for Delegate {
     fn reverse(&mut self, _: &mut Vec<VarValue<K,V>>, _: ()) {
-        fail!("Nothing to reverse");
+        panic!("Nothing to reverse");
     }
 }
 
index 5a23d54c9720b60766dbe0e6d00c4bec7b258097..22898221d9b53468a5839592dbafd2e7e9b6b748 100644 (file)
@@ -381,7 +381,7 @@ fn check_main_fn_ty(ccx: &CrateCtxt,
                 sig: ty::FnSig {
                     binder_id: main_id,
                     inputs: Vec::new(),
-                    output: ty::mk_nil(),
+                    output: ty::FnConverging(ty::mk_nil()),
                     variadic: false
                 }
             });
@@ -433,7 +433,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
                         ty::mk_int(),
                         ty::mk_imm_ptr(tcx, ty::mk_imm_ptr(tcx, ty::mk_u8()))
                     ),
-                    output: ty::mk_int(),
+                    output: ty::FnConverging(ty::mk_int()),
                     variadic: false
                 }
             });
index 1b64d90427bd08be618b90ac6bbb9e63bd3f9dd9..b8c47cff48c6b1fe9f92dcbd667d0ae1114169d4 100644 (file)
@@ -572,7 +572,7 @@ fn find_binding_for_lifetime(&self, param_id: ast::NodeId) -> ast::NodeId {
         match tcx.named_region_map.find(&param_id) {
             Some(&rl::DefEarlyBoundRegion(_, _, lifetime_decl_id))
                 => lifetime_decl_id,
-            Some(_) => fail!("should not encounter non early-bound cases"),
+            Some(_) => panic!("should not encounter non early-bound cases"),
 
             // The lookup should only fail when `param_id` is
             // itself a lifetime binding: use it as the decl_id.
@@ -597,11 +597,11 @@ fn is_to_be_inferred(&self, param_id: ast::NodeId) -> bool {
             assert!(is_lifetime(&tcx.map, param_id));
             let parent_id = tcx.map.get_parent(decl_id);
             let parent = tcx.map.find(parent_id).unwrap_or_else(
-                || fail!("tcx.map missing entry for id: {}", parent_id));
+                || panic!("tcx.map missing entry for id: {}", parent_id));
 
             let is_inferred;
             macro_rules! cannot_happen { () => { {
-                fail!("invalid parent: {:s} for {:s}",
+                panic!("invalid parent: {:s} for {:s}",
                       tcx.map.node_to_string(parent_id),
                       tcx.map.node_to_string(param_id));
             } } }
@@ -728,15 +728,14 @@ fn add_constraints_from_ty(&mut self,
         debug!("add_constraints_from_ty(ty={})", ty.repr(self.tcx()));
 
         match ty::get(ty).sty {
-            ty::ty_nil | ty::ty_bot | ty::ty_bool |
+            ty::ty_nil | ty::ty_bool |
             ty::ty_char | ty::ty_int(_) | ty::ty_uint(_) |
             ty::ty_float(_) | ty::ty_str => {
                 /* leaf type -- noop */
             }
 
-            ty::ty_unboxed_closure(_, region) => {
-                let contra = self.contravariant(variance);
-                self.add_constraints_from_region(region, contra);
+            ty::ty_unboxed_closure(..) => {
+                self.tcx().sess.bug("Unexpected unboxed closure type in variance computation");
             }
 
             ty::ty_rptr(region, ref mt) => {
@@ -883,7 +882,9 @@ fn add_constraints_from_sig(&mut self,
         for &input in sig.inputs.iter() {
             self.add_constraints_from_ty(input, contra);
         }
-        self.add_constraints_from_ty(sig.output, variance);
+        if let ty::FnConverging(result_type) = sig.output {
+            self.add_constraints_from_ty(result_type, variance);
+        }
     }
 
     /// Adds constraints appropriate for a region appearing in a
index 79faf3aa147ed1b6a466bbdb5d85a0177be59937..e107ac73d79953abada2ca9709972f0e667582de 100644 (file)
@@ -118,7 +118,7 @@ fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
 ) )
 
 weak_lang_items!(
-    fail_fmt,           FailFmtLangItem,            rust_begin_unwind;
+    panic_fmt,          PanicFmtLangItem,            rust_begin_unwind;
     stack_exhausted,    StackExhaustedLangItem,     rust_stack_exhausted;
     eh_personality,     EhPersonalityLangItem,      rust_eh_personality;
 )
index 88e6f0ad186c6cd2bed5752bf11e248c8f9a1df0..99e870a901e0893240a9acb87a6ccf4559d041f4 100644 (file)
@@ -64,7 +64,7 @@ pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxEx
             Decorator(ext) => Decorator(ext),
             Modifier(ext) => Modifier(ext),
             // there's probably a nicer way to signal this:
-            LetSyntaxTT(_, _) => fail!("can't register a new LetSyntax!"),
+            LetSyntaxTT(_, _) => panic!("can't register a new LetSyntax!"),
         }));
     }
 
index 81deae86faa4849c32f8e2594e7861665d539bc8..296158dd4a868e74b104d2f92abd6ce1c4691a23 100644 (file)
@@ -17,7 +17,7 @@
 use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region, ReEmpty};
 use middle::ty::{ReSkolemized, ReVar, BrEnv};
 use middle::ty::{mt, t, ParamTy};
-use middle::ty::{ty_bool, ty_char, ty_bot, ty_struct, ty_enum};
+use middle::ty::{ty_bool, ty_char, ty_struct, ty_enum};
 use middle::ty::{ty_err, ty_str, ty_vec, ty_float, ty_bare_fn, ty_closure};
 use middle::ty::{ty_nil, ty_param, ty_ptr, ty_rptr, ty_tup, ty_open};
 use middle::ty::{ty_unboxed_closure};
@@ -352,12 +352,15 @@ fn push_sig_to_string(cx: &ctxt,
             s.push_str(bounds);
         }
 
-        if ty::get(sig.output).sty != ty_nil {
-            s.push_str(" -> ");
-            if ty::type_is_bot(sig.output) {
-                s.push('!');
-            } else {
-                s.push_str(ty_to_string(cx, sig.output).as_slice());
+        match sig.output {
+            ty::FnConverging(t) => {
+                if !ty::type_is_nil(t) {
+                    s.push_str(" -> ");
+                   s.push_str(ty_to_string(cx, t).as_slice());
+                }
+            }
+            ty::FnDiverging => {
+                s.push_str(" -> !");
             }
         }
     }
@@ -371,7 +374,6 @@ fn push_sig_to_string(cx: &ctxt,
     // pretty print the structural type representation:
     return match ty::get(typ).sty {
       ty_nil => "()".to_string(),
-      ty_bot => "!".to_string(),
       ty_bool => "bool".to_string(),
       ty_char => "char".to_string(),
       ty_int(t) => ast_util::int_ty_to_string(t, None).to_string(),
@@ -425,7 +427,12 @@ fn push_sig_to_string(cx: &ctxt,
                   bound_str)
       }
       ty_str => "str".to_string(),
-      ty_unboxed_closure(..) => "closure".to_string(),
+      ty_unboxed_closure(ref did, _, ref substs) => {
+          let unboxed_closures = cx.unboxed_closures.borrow();
+          unboxed_closures.find(did).map(|cl| {
+              closure_to_string(cx, &cl.closure_type.subst(cx, substs))
+          }).unwrap_or_else(|| "closure".to_string())
+      }
       ty_vec(t, sz) => {
           match sz {
               Some(n) => {
@@ -947,6 +954,17 @@ fn repr(&self, tcx: &ctxt) -> String {
     }
 }
 
+impl Repr for ty::FnOutput {
+    fn repr(&self, tcx: &ctxt) -> String {
+        match *self {
+            ty::FnConverging(ty) =>
+                format!("FnConverging({0})", ty.repr(tcx)),
+            ty::FnDiverging =>
+                "FnDiverging".to_string()
+        }
+    }
+}
+
 impl Repr for typeck::MethodCallee {
     fn repr(&self, tcx: &ctxt) -> String {
         format!("MethodCallee {{origin: {}, ty: {}, {}}}",
index 7a7c8f8d94f72da590b5e53f2b9a19253e42c90f..8885d86d4da3637602e8d9372dd77ed342039fe4 100644 (file)
@@ -148,7 +148,7 @@ pub fn rollback_to(&mut self, snapshot: Snapshot) {
             match self.undo_log.pop().unwrap() {
                 OpenSnapshot => {
                     // This indicates a failure to obey the stack discipline.
-                    fail!("Cannot rollback an uncommitted snapshot");
+                    panic!("Cannot rollback an uncommitted snapshot");
                 }
 
                 CommittedSnapshot => {
index 060dda5934f8e3f7d0f454815fe04eb5ec6b5bc4..2e58a8dab3b3905289a3ee4b96f50e292f2b6f99 100644 (file)
@@ -91,7 +91,7 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>,
             handler.err(format!("could not exec `{}`: {}", ar.as_slice(),
                              e).as_slice());
             handler.abort_if_errors();
-            fail!("rustc::back::archive::run_ar() should not reach this point");
+            panic!("rustc::back::archive::run_ar() should not reach this point");
         }
     }
 }
index a7a234dc18ac51f8739708612a872dce88371dbb..4c62ba54ac427c00e1ac3ee7ef060ded5ec8dda6 100644 (file)
@@ -206,7 +206,7 @@ fn test_rpath_relative() {
             os: abi::OsLinux,
             used_crates: Vec::new(),
             out_filename: Path::new("bin/rustc"),
-            get_install_prefix_lib_path: || fail!(),
+            get_install_prefix_lib_path: || panic!(),
             realpath: |p| Ok(p.clone())
         };
         let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
@@ -220,7 +220,7 @@ fn test_rpath_relative() {
             os: abi::OsFreebsd,
             used_crates: Vec::new(),
             out_filename: Path::new("bin/rustc"),
-            get_install_prefix_lib_path: || fail!(),
+            get_install_prefix_lib_path: || panic!(),
             realpath: |p| Ok(p.clone())
         };
         let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
@@ -234,7 +234,7 @@ fn test_rpath_relative() {
             os: abi::OsDragonfly,
             used_crates: Vec::new(),
             out_filename: Path::new("bin/rustc"),
-            get_install_prefix_lib_path: || fail!(),
+            get_install_prefix_lib_path: || panic!(),
             realpath: |p| Ok(p.clone())
         };
         let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
@@ -248,7 +248,7 @@ fn test_rpath_relative() {
             os: abi::OsMacos,
             used_crates: Vec::new(),
             out_filename: Path::new("bin/rustc"),
-            get_install_prefix_lib_path: || fail!(),
+            get_install_prefix_lib_path: || panic!(),
             realpath: |p| Ok(p.clone())
         };
         let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
index bf8d993964ff9b3ccd08f3533973347e8edbf2fa..96a15213c5ed6ffcedc40da07d28827f8cc7b4a0 100644 (file)
@@ -59,18 +59,18 @@ fn to_bits(self) -> (u64, u64) {
     }
 }
 
-/// Adds the specified number of bytes to the bit count. fail!() if this would cause numeric
+/// Adds the specified number of bytes to the bit count. panic!() if this would cause numeric
 /// overflow.
 fn add_bytes_to_bits<T: Int + CheckedAdd + ToBits>(bits: T, bytes: T) -> T {
     let (new_high_bits, new_low_bits) = bytes.to_bits();
 
     if new_high_bits > Zero::zero() {
-        fail!("numeric overflow occurred.")
+        panic!("numeric overflow occurred.")
     }
 
     match bits.checked_add(&new_low_bits) {
         Some(x) => return x,
-        None => fail!("numeric overflow occurred.")
+        None => panic!("numeric overflow occurred.")
     }
 }
 
index 3c28cac6c6f7c1e9186ae56796016f018e979c2a..01a5767aeb2560b5fa5b3f60d6825b5c4c5252d1 100644 (file)
@@ -347,7 +347,7 @@ fn visit_mac(&mut self, macro: &Mac) {
             } else {
                 // It is not possible to observe any kind of macro
                 // invocation at this stage except `macro_rules!`.
-                fail!("reached macro somehow: {}",
+                panic!("reached macro somehow: {}",
                       pprust::to_string(|pp_state| pp_state.print_mac(macro)));
             }
 
index 4ef72361701f2bf4e2ab5294bc382fbbb671554d..967e1fbb70021eb885abf9887f12127d609b4318 100644 (file)
@@ -174,7 +174,7 @@ fn build_external_function(cx: &DocContext, tcx: &ty::ctxt,
     clean::Function {
         decl: match ty::get(t.ty).sty {
             ty::ty_bare_fn(ref f) => (did, &f.sig).clean(cx),
-            _ => fail!("bad function"),
+            _ => panic!("bad function"),
         },
         generics: (&t.generics, subst::FnSpace).clean(cx),
         fn_style: style,
@@ -308,7 +308,7 @@ fn build_impl(cx: &DocContext, tcx: &ty::ctxt,
                             generics: generics,
                         })
                     }
-                    _ => fail!("not a tymethod"),
+                    _ => panic!("not a tymethod"),
                 };
                 Some(item)
             }
@@ -382,7 +382,7 @@ fn fill_in(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId,
                 decoder::DlDef(..) => {}
                 // All impls were inlined above
                 decoder::DlImpl(..) => {}
-                decoder::DlField => fail!("unimplemented field"),
+                decoder::DlField => panic!("unimplemented field"),
             }
         });
     }
index bdafe192705ce3a8c51119f2274ca06e6c51715f..7c8f4ba8f65c7bb5f345142e4b0947cba142835a 100644 (file)
@@ -880,6 +880,15 @@ fn clean(&self, cx: &DocContext) -> FnDecl {
     }
 }
 
+impl<'a> Clean<Type> for ty::FnOutput {
+    fn clean(&self, cx: &DocContext) -> Type {
+        match *self {
+            ty::FnConverging(ty) => ty.clean(cx),
+            ty::FnDiverging => Bottom
+        }
+    }
+}
+
 impl<'a> Clean<FnDecl> for (ast::DefId, &'a ty::FnSig) {
     fn clean(&self, cx: &DocContext) -> FnDecl {
         let (did, sig) = *self;
@@ -1250,7 +1259,7 @@ fn clean(&self, cx: &DocContext) -> Type {
             TyBareFn(ref barefn) => BareFunction(box barefn.clean(cx)),
             TyParen(ref ty) => ty.clean(cx),
             TyBot => Bottom,
-            ref x => fail!("Unimplemented type {}", x),
+            ref x => panic!("Unimplemented type {}", x),
         }
     }
 }
@@ -1258,7 +1267,6 @@ fn clean(&self, cx: &DocContext) -> Type {
 impl Clean<Type> for ty::t {
     fn clean(&self, cx: &DocContext) -> Type {
         match ty::get(*self).sty {
-            ty::ty_bot => Bottom,
             ty::ty_nil => Primitive(Unit),
             ty::ty_bool => Primitive(Bool),
             ty::ty_char => Primitive(Char),
@@ -1346,9 +1354,9 @@ fn clean(&self, cx: &DocContext) -> Type {
 
             ty::ty_unboxed_closure(..) => Primitive(Unit), // FIXME(pcwalton)
 
-            ty::ty_infer(..) => fail!("ty_infer"),
-            ty::ty_open(..) => fail!("ty_open"),
-            ty::ty_err => fail!("ty_err"),
+            ty::ty_infer(..) => panic!("ty_infer"),
+            ty::ty_open(..) => panic!("ty_open"),
+            ty::ty_err => panic!("ty_err"),
         }
     }
 }
@@ -2060,9 +2068,9 @@ fn name_from_pat(p: &ast::Pat) -> String {
                   which is silly in function arguments");
             "()".to_string()
         },
-        PatRange(..) => fail!("tried to get argument name from PatRange, \
+        PatRange(..) => panic!("tried to get argument name from PatRange, \
                               which is not allowed in function arguments"),
-        PatVec(..) => fail!("tried to get argument name from pat_vec, \
+        PatVec(..) => panic!("tried to get argument name from pat_vec, \
                              which is not allowed in function arguments"),
         PatMac(..) => {
             warn!("can't document the name of a function argument \
@@ -2084,7 +2092,7 @@ fn resolve_type(cx: &DocContext, path: Path,
     debug!("searching for {} in defmap", id);
     let def = match tcx.def_map.borrow().find(&id) {
         Some(&k) => k,
-        None => fail!("unresolved id not in defmap")
+        None => panic!("unresolved id not in defmap")
     };
 
     match def {
index ef921a84cfb8eea5f7a240ddc3b63b36ef989f62..a89b20c949b4040b2a14c4f674a06e5b1a3a9d57 100644 (file)
@@ -128,7 +128,7 @@ pub fn new(p: &Path) -> Lock {
             };
             if ret == -1 {
                 unsafe { libc::close(fd); }
-                fail!("could not lock `{}`", p.display())
+                panic!("could not lock `{}`", p.display())
             }
             Lock { fd: fd }
         }
@@ -197,7 +197,7 @@ pub fn new(p: &Path) -> Lock {
                                   ptr::null_mut())
             };
             if handle == libc::INVALID_HANDLE_VALUE {
-                fail!("create file error: {}", os::last_os_error());
+                panic!("create file error: {}", os::last_os_error());
             }
             let mut overlapped: libc::OVERLAPPED = unsafe { mem::zeroed() };
             let ret = unsafe {
@@ -206,7 +206,7 @@ pub fn new(p: &Path) -> Lock {
             };
             if ret == 0 {
                 unsafe { libc::CloseHandle(handle); }
-                fail!("could not lock `{}`: {}", p.display(),
+                panic!("could not lock `{}`: {}", p.display(),
                       os::last_os_error())
             }
             Lock { handle: handle }
index ca8a6cd0c401073993e21f3f6ceed63269feea42..f9177c8d61578797a79a5af5f234f287edcb591c 100644 (file)
@@ -499,7 +499,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                 }
             }
             clean::Unique(..) => {
-                fail!("should have been cleaned")
+                panic!("should have been cleaned")
             }
         }
     }
index 85455b9df9ed1c6f03a1897c9599657b26c1af87..0441e6b791f57aa018001ebf7e0082a6fecc6c34 100644 (file)
@@ -17,7 +17,7 @@
 
 use std::io;
 use syntax::parse::lexer;
-use syntax::parse::token as t;
+use syntax::parse::token;
 use syntax::parse;
 
 /// Highlights some source code, returning the HTML output.
@@ -63,19 +63,19 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
 
         let snip = |sp| sess.span_diagnostic.cm.span_to_snippet(sp).unwrap();
 
-        if next.tok == t::EOF { break }
+        if next.tok == token::Eof { break }
 
         let klass = match next.tok {
-            t::WS => {
+            token::Whitespace => {
                 try!(write!(out, "{}", Escape(snip(next.sp).as_slice())));
                 continue
             },
-            t::COMMENT => {
+            token::Comment => {
                 try!(write!(out, "<span class='comment'>{}</span>",
                             Escape(snip(next.sp).as_slice())));
                 continue
             },
-            t::SHEBANG(s) => {
+            token::Shebang(s) => {
                 try!(write!(out, "{}", Escape(s.as_str())));
                 continue
             },
@@ -83,24 +83,25 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
             // that it's the address-of operator instead of the and-operator.
             // This allows us to give all pointers their own class (`Box` and
             // `@` are below).
-            t::BINOP(t::AND) if lexer.peek().sp.lo == next.sp.hi => "kw-2",
-            t::AT | t::TILDE => "kw-2",
+            token::BinOp(token::And) if lexer.peek().sp.lo == next.sp.hi => "kw-2",
+            token::At | token::Tilde => "kw-2",
 
             // consider this as part of a macro invocation if there was a
             // leading identifier
-            t::NOT if is_macro => { is_macro = false; "macro" }
+            token::Not if is_macro => { is_macro = false; "macro" }
 
             // operators
-            t::EQ | t::LT | t::LE | t::EQEQ | t::NE | t::GE | t::GT |
-                t::ANDAND | t::OROR | t::NOT | t::BINOP(..) | t::RARROW |
-                t::BINOPEQ(..) | t::FAT_ARROW => "op",
+            token::Eq | token::Lt | token::Le | token::EqEq | token::Ne | token::Ge | token::Gt |
+                token::AndAnd | token::OrOr | token::Not | token::BinOp(..) | token::RArrow |
+                token::BinOpEq(..) | token::FatArrow => "op",
 
             // miscellaneous, no highlighting
-            t::DOT | t::DOTDOT | t::DOTDOTDOT | t::COMMA | t::SEMI |
-                t::COLON | t::MOD_SEP | t::LARROW | t::LPAREN |
-                t::RPAREN | t::LBRACKET | t::LBRACE | t::RBRACE | t::QUESTION => "",
-            t::DOLLAR => {
-                if t::is_ident(&lexer.peek().tok) {
+            token::Dot | token::DotDot | token::DotDotDot | token::Comma | token::Semi |
+                token::Colon | token::ModSep | token::LArrow | token::LParen |
+                token::RParen | token::LBracket | token::LBrace | token::RBrace |
+                token::Question => "",
+            token::Dollar => {
+                if lexer.peek().tok.is_ident() {
                     is_macro_nonterminal = true;
                     "macro-nonterminal"
                 } else {
@@ -112,12 +113,12 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
             // continue highlighting it as an attribute until the ending ']' is
             // seen, so skip out early. Down below we terminate the attribute
             // span when we see the ']'.
-            t::POUND => {
+            token::Pound => {
                 is_attribute = true;
                 try!(write!(out, r"<span class='attribute'>#"));
                 continue
             }
-            t::RBRACKET => {
+            token::RBracket => {
                 if is_attribute {
                     is_attribute = false;
                     try!(write!(out, "]</span>"));
@@ -128,15 +129,15 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
             }
 
             // text literals
-            t::LIT_BYTE(..) | t::LIT_BINARY(..) | t::LIT_BINARY_RAW(..) |
-                t::LIT_CHAR(..) | t::LIT_STR(..) | t::LIT_STR_RAW(..) => "string",
+            token::LitByte(..) | token::LitBinary(..) | token::LitBinaryRaw(..) |
+                token::LitChar(..) | token::LitStr(..) | token::LitStrRaw(..) => "string",
 
             // number literals
-            t::LIT_INTEGER(..) | t::LIT_FLOAT(..) => "number",
+            token::LitInteger(..) | token::LitFloat(..) => "number",
 
             // keywords are also included in the identifier set
-            t::IDENT(ident, _is_mod_sep) => {
-                match t::get_ident(ident).get() {
+            token::Ident(ident, _is_mod_sep) => {
+                match token::get_ident(ident).get() {
                     "ref" | "mut" => "kw-2",
 
                     "self" => "self",
@@ -145,12 +146,12 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
                     "Option" | "Result" => "prelude-ty",
                     "Some" | "None" | "Ok" | "Err" => "prelude-val",
 
-                    _ if t::is_any_keyword(&next.tok) => "kw",
+                    _ if next.tok.is_any_keyword() => "kw",
                     _ => {
                         if is_macro_nonterminal {
                             is_macro_nonterminal = false;
                             "macro-nonterminal"
-                        } else if lexer.peek().tok == t::NOT {
+                        } else if lexer.peek().tok == token::Not {
                             is_macro = true;
                             "macro"
                         } else {
@@ -160,9 +161,9 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
                 }
             }
 
-            t::LIFETIME(..) => "lifetime",
-            t::DOC_COMMENT(..) => "doccomment",
-            t::UNDERSCORE | t::EOF | t::INTERPOLATED(..) => "",
+            token::Lifetime(..) => "lifetime",
+            token::DocComment(..) => "doccomment",
+            token::Underscore | token::Eof | token::Interpolated(..) => "",
         };
 
         // as mentioned above, use the original source code instead of
index 6e515f611986e70ad8a9ac59b37bc95a0a64eb35..b7dfd811574a3c1e955b22fe2654143c80775c66 100644 (file)
@@ -1042,7 +1042,7 @@ impl Context {
     /// sure it always points to the top (relatively)
     fn recurse<T>(&mut self, s: String, f: |&mut Context| -> T) -> T {
         if s.len() == 0 {
-            fail!("Unexpected empty destination: {}", self.current);
+            panic!("Unexpected empty destination: {}", self.current);
         }
         let prev = self.dst.clone();
         self.dst.push(s.as_slice());
index ad79faebd45c5635d33ba3a7f4b4385ee90e203c..5f404238beb30dda938e463612fc9eea68aa0989 100644 (file)
@@ -243,13 +243,13 @@ pub fn main_args(args: &[String]) -> int {
         Some("html") | None => {
             match html::render::run(krate, &external_html, output.unwrap_or(Path::new("doc"))) {
                 Ok(()) => {}
-                Err(e) => fail!("failed to generate documentation: {}", e),
+                Err(e) => panic!("failed to generate documentation: {}", e),
             }
         }
         Some("json") => {
             match json_output(krate, res, output.unwrap_or(Path::new("doc.json"))) {
                 Ok(()) => {}
-                Err(e) => fail!("failed to write json: {}", e),
+                Err(e) => panic!("failed to write json: {}", e),
             }
         }
         Some(s) => {
@@ -480,7 +480,7 @@ fn json_output(krate: clean::Crate, res: Vec<plugins::PluginJson> ,
     };
     let crate_json = match json::from_str(crate_json_str.as_slice()) {
         Ok(j) => j,
-        Err(e) => fail!("Rust generated JSON is invalid: {}", e)
+        Err(e) => panic!("Rust generated JSON is invalid: {}", e)
     };
 
     json.insert("crate".to_string(), crate_json);
index 685d76bb5200b82f0252a5b29bddc15a6639e5ab..642abf924ae71ddde749533891b1bbab8a0572b1 100644 (file)
@@ -192,15 +192,15 @@ fn runtest(test: &str, cratename: &str, libs: Vec<Path>, externs: core::Externs,
     cmd.env(DynamicLibrary::envvar(), newpath.as_slice());
 
     match cmd.output() {
-        Err(e) => fail!("couldn't run the test: {}{}", e,
+        Err(e) => panic!("couldn't run the test: {}{}", e,
                         if e.kind == io::PermissionDenied {
                             " - maybe your tempdir is mounted with noexec?"
                         } else { "" }),
         Ok(out) => {
             if should_fail && out.status.success() {
-                fail!("test executable succeeded when it should have failed");
+                panic!("test executable succeeded when it should have failed");
             } else if !should_fail && !out.status.success() {
-                fail!("test executable failed:\n{}",
+                panic!("test executable failed:\n{}",
                       str::from_utf8(out.error.as_slice()));
             }
         }
index 8e377037a9713e42db97f5aab17e0bff32456ca4..1cafc38f826c96542552ad22bea00f7131c75807 100644 (file)
@@ -249,7 +249,7 @@ fn resolve_id(&mut self, id: ast::NodeId, renamed: Option<ast::Ident>,
                                 self.visit_item(&**i, None, om);
                             }
                         }
-                        _ => { fail!("glob not mapped to a module"); }
+                        _ => { panic!("glob not mapped to a module"); }
                     }
                 } else {
                     self.visit_item(it, renamed, om);
@@ -353,7 +353,7 @@ pub fn visit_item(&mut self, item: &ast::Item,
                 om.foreigns.push(fm.clone());
             }
             ast::ItemMac(_) => {
-                fail!("rustdoc: macros should be gone, after expansion");
+                panic!("rustdoc: macros should be gone, after expansion");
             }
         }
     }
index 3138c9be99247ab5fb88e1ccd75f5ddd394ead9d..20a63f655b8ff9d2166ac7e7a6c862b0d869e1be 100644 (file)
@@ -160,14 +160,14 @@ pub fn cleanup() {
     }
 
     pub fn take() -> Option<Vec<Vec<u8>>> {
-        fail!()
+        panic!()
     }
 
     pub fn put(_args: Vec<Vec<u8>>) {
-        fail!()
+        panic!()
     }
 
     pub fn clone() -> Option<Vec<Vec<u8>>> {
-        fail!()
+        panic!()
     }
 }
index 6a33777a413c5d5fa8394c47e18271095b913856..ddb4df4fdc5386479c34954e84dd63c4620fc33a 100644 (file)
@@ -101,7 +101,7 @@ impl Clone for CString {
     fn clone(&self) -> CString {
         let len = self.len() + 1;
         let buf = unsafe { libc::malloc(len as libc::size_t) } as *mut libc::c_char;
-        if buf.is_null() { fail!("out of memory") }
+        if buf.is_null() { panic!("out of memory") }
         unsafe { ptr::copy_nonoverlapping_memory(buf, self.buf, len); }
         CString { buf: buf as *const libc::c_char, owns_buffer_: true }
     }
@@ -394,7 +394,7 @@ fn to_c_str(&self) -> CString {
     unsafe fn to_c_str_unchecked(&self) -> CString {
         let self_len = self.len();
         let buf = libc::malloc(self_len as libc::size_t + 1) as *mut u8;
-        if buf.is_null() { fail!("out of memory") }
+        if buf.is_null() { panic!("out of memory") }
 
         ptr::copy_memory(buf, self.as_ptr(), self_len);
         *buf.offset(self_len as int) = 0;
index 972497f98188309f3aa0ec481e9c053f683966ff..9a8bd3cdfc81cc6e35b555fff82adceb554fdc44 100644 (file)
@@ -101,7 +101,7 @@ fn spawn_sibling(self: Box<Self>,
     fn wrap(self: Box<Self>) -> Box<Any+'static>;
 }
 
-/// The default error code of the rust runtime if the main task fails instead
+/// The default error code of the rust runtime if the main task panics instead
 /// of exiting cleanly.
 pub const DEFAULT_ERROR_CODE: int = 101;
 
index 8d5c49d767f1584f41e735acb65219397b19d9e5..5d9e20b07de9aaa6610c6c016f58f626dc453160 100644 (file)
@@ -134,7 +134,7 @@ unsafe fn get_local_map<'a>() -> Option<&'a mut Map> {
             *slot = Some(TreeMap::new());
             match *slot {
                 Some(ref mut map_ptr) => { return Some(map_ptr) }
-                None => fail!("unreachable code"),
+                None => panic!("unreachable code"),
             }
         }
     }
@@ -161,12 +161,12 @@ impl<T: 'static> KeyValue<T> {
     /// If this key is already present in TLD, then the previous value is
     /// replaced with the provided data, and then returned.
     ///
-    /// # Failure
+    /// # Panics
     ///
-    /// This function will fail if the key is present in TLD and currently on
+    /// This function will panic if the key is present in TLD and currently on
     /// loan with the `get` method.
     ///
-    /// It will also fail if there is no local task (because the current thread
+    /// It will also panic if there is no local task (because the current thread
     /// is not owned by the runtime).
     ///
     /// # Example
@@ -181,7 +181,7 @@ impl<T: 'static> KeyValue<T> {
     pub fn replace(&'static self, data: Option<T>) -> Option<T> {
         let map = match unsafe { get_local_map() } {
             Some(map) => map,
-            None => fail!("must have a local task to insert into TLD"),
+            None => panic!("must have a local task to insert into TLD"),
         };
         let keyval = key_to_key_value(self);
 
@@ -233,7 +233,7 @@ pub fn replace(&'static self, data: Option<T>) -> Option<T> {
                     }
                     _ => {
                         // Refcount is 2+, which means we have a live borrow.
-                        fail!("TLD value cannot be replaced because it is already borrowed");
+                        panic!("TLD value cannot be replaced because it is already borrowed");
                     }
                 }
             }
@@ -369,7 +369,7 @@ fn new<T>(value: T) -> TLDValue {
         unsafe fn d<T>(p: *mut ()) {
             let value_box = p as *mut TLDValueBox<T>;
             debug_assert!(*(*value_box).refcount.get() < 2, "TLDValue destructed while borrowed");
-            // use a RAII type here to ensure we always deallocate even if we fail while
+            // use a RAII type here to ensure we always deallocate even if we panic while
             // running the destructor for the value.
             struct Guard<T> {
                 p: *mut TLDValueBox<T>
@@ -495,7 +495,7 @@ fn test_tls_overwrite_multiple_types() {
 
     #[test]
     #[should_fail]
-    fn test_tls_cleanup_on_failure() {
+    fn test_tls_cleanup_on_panic() {
         static STR_KEY: Key<String> = &KeyValueKey;
         static BOX_KEY: Key<Box<int>> = &KeyValueKey;
         static INT_KEY: Key<int> = &KeyValueKey;
@@ -505,11 +505,11 @@ fn test_tls_cleanup_on_failure() {
             STR_KEY.replace(Some("string data".to_string()));
             BOX_KEY.replace(Some(box 2));
             INT_KEY.replace(Some(42));
-            fail!();
+            panic!();
         });
         // Not quite nondeterministic.
         INT_KEY.replace(Some(31337));
-        fail!();
+        panic!();
     }
 
     #[test]
index 838dfd6b7abe6b5807dfc0e6e5df06b5ebae1743..6a6e2e40ec8888e3f07dd04e1626e117665b844d 100644 (file)
@@ -81,7 +81,7 @@ pub struct NativeMutex {
 /// destruction.
 ///
 /// Using this makes lock-based code resilient to unwinding/task
-/// failure, because the lock will be automatically unlocked even
+/// panic, because the lock will be automatically unlocked even
 /// then.
 #[must_use]
 pub struct LockGuard<'a> {
index aaaeb8846ccafd3a699bbb25aa401e726d6d57c6..d01b4a3a4b34c87f44c0ef5c3104f8f8de6edf8f 100644 (file)
@@ -116,7 +116,7 @@ pub unsafe fn init() {
         PAGE_SIZE = info.dwPageSize as uint;
 
         if AddVectoredExceptionHandler(0, vectored_handler) == ptr::null_mut() {
-            fail!("failed to install exception handler");
+            panic!("failed to install exception handler");
         }
 
         mem::forget(make_handler());
@@ -127,7 +127,7 @@ pub unsafe fn cleanup() {
 
     pub unsafe fn make_handler() -> Handler {
         if SetThreadStackGuarantee(&mut 0x5000) == 0 {
-            fail!("failed to reserve stack space for exception handling");
+            panic!("failed to reserve stack space for exception handling");
         }
 
         super::Handler { _data: 0i as *mut libc::c_void }
@@ -232,7 +232,7 @@ unsafe fn term(signum: libc::c_int) -> ! {
     pub unsafe fn init() {
         let psize = libc::sysconf(libc::consts::os::sysconf::_SC_PAGESIZE);
         if psize == -1 {
-            fail!("failed to get page size");
+            panic!("failed to get page size");
         }
 
         PAGE_SIZE = psize as uint;
@@ -260,7 +260,7 @@ pub unsafe fn make_handler() -> Handler {
                              -1,
                              0);
         if alt_stack == MAP_FAILED {
-            fail!("failed to allocate an alternative stack");
+            panic!("failed to allocate an alternative stack");
         }
 
         let mut stack: sigaltstack = mem::zeroed();
index 5eb28412abdab2dccf6d85c90f775f05426dec8f..ad3b1dc7e1695e8e0b2f513ae4cb96312907da5d 100644 (file)
@@ -53,7 +53,7 @@
 ///
 /// * `run` - This function will execute a closure inside the context of a task.
 ///           Failure is caught and handled via the task's on_exit callback. If
-///           this fails, the task is still returned, but it can no longer be
+///           this panics, the task is still returned, but it can no longer be
 ///           used, it is poisoned.
 ///
 /// * `destroy` - This is a required function to call to destroy a task. If a
 /// // Create a task using a native runtime
 /// let task = native::task::new((0, uint::MAX), 0);
 ///
-/// // Run some code, catching any possible failures
+/// // Run some code, catching any possible panic
 /// let task = task.run(|| {
 ///     // Run some code inside this task
 ///     println!("Hello with a native runtime!");
 /// });
 ///
-/// // Run some code again, catching the failure
+/// // Run some code again, catching the panic
 /// let task = task.run(|| {
-///     fail!("oh no, what to do!");
+///     panic!("oh no, what to do!");
 /// });
 ///
-/// // Now that the task is failed, it can never be used again
+/// // Now that the task has panicked, it can never be used again
 /// assert!(task.is_destroyed());
 ///
 /// // Deallocate the resources associated with this task
@@ -114,7 +114,7 @@ enum TaskState {
 pub struct TaskOpts {
     /// Invoke this procedure with the result of the task when it finishes.
     pub on_exit: Option<proc(Result): Send>,
-    /// A name for the task-to-be, for identification in failure messages
+    /// A name for the task-to-be, for identification in panic messages
     pub name: Option<SendStr>,
     /// The size of the stack for the spawned task
     pub stack_size: Option<uint>,
@@ -122,7 +122,7 @@ pub struct TaskOpts {
 
 /// Indicates the manner in which a task exited.
 ///
-/// A task that completes without failing is considered to exit successfully.
+/// A task that completes without panicking is considered to exit successfully.
 ///
 /// If you wish for this result's delivery to block until all
 /// children tasks complete, recommend using a result future.
@@ -138,7 +138,7 @@ pub enum BlockedTask {
     Shared(Arc<AtomicUint>),
 }
 
-/// Per-task state related to task death, killing, failure, etc.
+/// Per-task state related to task death, killing, panic, etc.
 pub struct Death {
     pub on_exit: Option<proc(Result):Send>,
     marker: marker::NoCopy,
@@ -175,15 +175,15 @@ pub fn new() -> Task {
     /// try/catch). Invoking this function is quite cheap.
     ///
     /// If the closure `f` succeeds, then the returned task can be used again
-    /// for another invocation of `run`. If the closure `f` fails then `self`
+    /// for another invocation of `run`. If the closure `f` panics then `self`
     /// will be internally destroyed along with all of the other associated
     /// resources of this task. The `on_exit` callback is invoked with the
-    /// cause of failure (not returned here). This can be discovered by querying
+    /// cause of panic (not returned here). This can be discovered by querying
     /// `is_destroyed()`.
     ///
     /// Note that it is possible to view partial execution of the closure `f`
     /// because it is not guaranteed to run to completion, but this function is
-    /// guaranteed to return if it fails. Care should be taken to ensure that
+    /// guaranteed to return if it panicks. Care should be taken to ensure that
     /// stack references made by `f` are handled appropriately.
     ///
     /// It is invalid to call this function with a task that has been previously
@@ -212,7 +212,7 @@ pub fn run(mut self: Box<Task>, f: ||) -> Box<Task> {
         // recursive invocations of run(). If there's no one else, then
         // relinquish ownership of ourselves back into TLS.
         if Local::exists(None::<Task>) {
-            fail!("cannot run a task recursively inside another");
+            panic!("cannot run a task recursively inside another");
         }
         self.state = Armed;
         Local::put(self);
@@ -226,7 +226,7 @@ pub fn run(mut self: Box<Task>, f: ||) -> Box<Task> {
         let result = unsafe { unwind::try(f) };
 
         // After running the closure given return the task back out if it ran
-        // successfully, or clean up the task if it failed.
+        // successfully, or clean up the task if it panicked.
         let task: Box<Task> = Local::take();
         match result {
             Ok(()) => task,
@@ -275,7 +275,7 @@ fn cleanup(self: Box<Task>, result: Result) -> Box<Task> {
         //    There is a test for this at fail-during-tld-destroy.rs.
         //
         // 2. One failure in destruction is tolerable, so long as the task
-        //    didn't originally fail while it was running.
+        //    didn't originally panic while it was running.
         //
         // And with all that in mind, we attempt to clean things up!
         let mut task = self.run(|| {
@@ -290,7 +290,7 @@ fn cleanup(self: Box<Task>, result: Result) -> Box<Task> {
             drop(tld);
         });
 
-        // If the above `run` block failed, then it must be the case that the
+        // If the above `run` block panicked, then it must be the case that the
         // task had previously succeeded. This also means that the code below
         // was recursively run via the `run` method invoking this method. In
         // this case, we just make sure the world is as we thought, and return.
@@ -306,7 +306,7 @@ fn cleanup(self: Box<Task>, result: Result) -> Box<Task> {
 
         // FIXME: this is running in a seriously constrained context. If this
         //        allocates TLD then it will likely abort the runtime. Similarly,
-        //        if this fails, this will also likely abort the runtime.
+        //        if this panics, this will also likely abort the runtime.
         //
         //        This closure is currently limited to a channel send via the
         //        standard library's task interface, but this needs
@@ -490,7 +490,7 @@ pub fn reawaken(self) {
     }
 
     // This assertion has two flavours because the wake involves an atomic op.
-    // In the faster version, destructors will fail dramatically instead.
+    // In the faster version, destructors will panic dramatically instead.
     #[cfg(not(test))] pub fn trash(self) { }
     #[cfg(test)]      pub fn trash(self) { assert!(self.wake().is_none()); }
 
@@ -570,7 +570,7 @@ fn unwind() {
         let result = task::try(proc()());
         rtdebug!("trying first assert");
         assert!(result.is_ok());
-        let result = task::try::<()>(proc() fail!());
+        let result = task::try::<()>(proc() panic!());
         rtdebug!("trying second assert");
         assert!(result.is_err());
     }
index 50b570091ada146246270bb266165966bb440db5..9f3f45ba0981c47b1c0f40507cbd7137547d8af5 100644 (file)
@@ -235,7 +235,7 @@ pub unsafe fn create(stack: uint, p: Box<proc():Send>) -> rust_thread {
         if ret as uint == 0 {
             // be sure to not leak the closure
             let _p: Box<proc():Send> = mem::transmute(arg);
-            fail!("failed to spawn native thread: {}", ret);
+            panic!("failed to spawn native thread: {}", ret);
         }
         return ret;
     }
@@ -327,15 +327,15 @@ unsafe fn get_stack_start() -> *mut libc::c_void {
         unsafe fn get_stack_start() -> *mut libc::c_void {
             let mut attr: libc::pthread_attr_t = mem::zeroed();
             if pthread_getattr_np(pthread_self(), &mut attr) != 0 {
-                fail!("failed to get thread attributes");
+                panic!("failed to get thread attributes");
             }
             let mut stackaddr = ptr::null_mut();
             let mut stacksize = 0;
             if pthread_attr_getstack(&attr, &mut stackaddr, &mut stacksize) != 0 {
-                fail!("failed to get stack information");
+                panic!("failed to get stack information");
             }
             if pthread_attr_destroy(&mut attr) != 0 {
-                fail!("failed to destroy thread attributes");
+                panic!("failed to destroy thread attributes");
             }
             stackaddr
         }
@@ -343,7 +343,7 @@ unsafe fn get_stack_start() -> *mut libc::c_void {
         pub unsafe fn init() {
             let psize = libc::sysconf(libc::consts::os::sysconf::_SC_PAGESIZE);
             if psize == -1 {
-                fail!("failed to get page size");
+                panic!("failed to get page size");
             }
 
             PAGE_SIZE = psize as uint;
@@ -361,7 +361,7 @@ pub unsafe fn init() {
                               0);
 
             if result != stackaddr || result == MAP_FAILED {
-                fail!("failed to allocate a guard page");
+                panic!("failed to allocate a guard page");
             }
 
             let offset = if cfg!(target_os = "linux") {
@@ -387,22 +387,22 @@ pub unsafe fn current() -> uint {
         pub unsafe fn current() -> uint {
             let mut attr: libc::pthread_attr_t = mem::zeroed();
             if pthread_getattr_np(pthread_self(), &mut attr) != 0 {
-                fail!("failed to get thread attributes");
+                panic!("failed to get thread attributes");
             }
             let mut guardsize = 0;
             if pthread_attr_getguardsize(&attr, &mut guardsize) != 0 {
-                fail!("failed to get stack guard page");
+                panic!("failed to get stack guard page");
             }
             if guardsize == 0 {
-                fail!("there is no guard page");
+                panic!("there is no guard page");
             }
             let mut stackaddr = ptr::null_mut();
             let mut stacksize = 0;
             if pthread_attr_getstack(&attr, &mut stackaddr, &mut stacksize) != 0 {
-                fail!("failed to get stack information");
+                panic!("failed to get stack information");
             }
             if pthread_attr_destroy(&mut attr) != 0 {
-                fail!("failed to destroy thread attributes");
+                panic!("failed to destroy thread attributes");
             }
 
             stackaddr as uint + guardsize as uint
@@ -433,7 +433,7 @@ pub unsafe fn create(stack: uint, p: Box<proc():Send>) -> rust_thread {
             },
             errno => {
                 // This cannot really happen.
-                fail!("pthread_attr_setstacksize() error: {}", errno);
+                panic!("pthread_attr_setstacksize() error: {}", errno);
             },
         };
 
@@ -444,7 +444,7 @@ pub unsafe fn create(stack: uint, p: Box<proc():Send>) -> rust_thread {
         if ret != 0 {
             // be sure to not leak the closure
             let _p: Box<proc():Send> = mem::transmute(arg);
-            fail!("failed to spawn native thread: {}", ret);
+            panic!("failed to spawn native thread: {}", ret);
         }
         native
     }
index 9483beca1c39d781878413f1da5d92ffba88d776..8279b7d9654e4bbc24016d96225b605ffff891a7 100644 (file)
@@ -115,11 +115,11 @@ pub fn unwinding(&self) -> bool {
     }
 }
 
-/// Invoke a closure, capturing the cause of failure if one occurs.
+/// Invoke a closure, capturing the cause of panic if one occurs.
 ///
-/// This function will return `None` if the closure did not fail, and will
-/// return `Some(cause)` if the closure fails. The `cause` returned is the
-/// object with which failure was originally invoked.
+/// This function will return `None` if the closure did not panic, and will
+/// return `Some(cause)` if the closure panics. The `cause` returned is the
+/// object with which panic was originally invoked.
 ///
 /// This function also is unsafe for a variety of reasons:
 ///
@@ -489,18 +489,26 @@ extern "C" fn inner(
     }
 }
 
-// Entry point of failure from the libcore crate
+// Entry point of panic from the libcore crate
 #[cfg(not(test))]
-#[lang = "fail_fmt"]
+#[lang = "panic_fmt"]
 pub extern fn rust_begin_unwind(msg: &fmt::Arguments,
                                 file: &'static str, line: uint) -> ! {
     begin_unwind_fmt(msg, &(file, line))
 }
 
+// NOTE(stage0): remove after a snapshot
+#[cfg(not(test))]
+#[lang = "fail_fmt"]
+pub extern fn rust_fail_begin_unwind(msg: &fmt::Arguments,
+                                file: &'static str, line: uint) -> ! {
+    rust_begin_unwind(msg, file, line)
+}
+
 /// The entry point for unwinding with a formatted message.
 ///
 /// This is designed to reduce the amount of code required at the call
-/// site as much as possible (so that `fail!()` has as low an impact
+/// site as much as possible (so that `panic!()` has as low an impact
 /// on (e.g.) the inlining of other functions as possible), by moving
 /// the actual formatting into this shared place.
 #[inline(never)] #[cold]
@@ -509,7 +517,7 @@ pub fn begin_unwind_fmt(msg: &fmt::Arguments, file_line: &(&'static str, uint))
 
     // We do two allocations here, unfortunately. But (a) they're
     // required with the current scheme, and (b) we don't handle
-    // failure + OOM properly anyway (see comment in begin_unwind
+    // panic + OOM properly anyway (see comment in begin_unwind
     // below).
 
     struct VecWriter<'a> { v: &'a mut Vec<u8> }
@@ -528,15 +536,15 @@ fn write(&mut self, buf: &[u8]) -> fmt::Result {
     begin_unwind_inner(msg, file_line)
 }
 
-/// This is the entry point of unwinding for fail!() and assert!().
+/// This is the entry point of unwinding for panic!() and assert!().
 #[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
 pub fn begin_unwind<M: Any + Send>(msg: M, file_line: &(&'static str, uint)) -> ! {
     // Note that this should be the only allocation performed in this code path.
-    // Currently this means that fail!() on OOM will invoke this code path,
-    // but then again we're not really ready for failing on OOM anyway. If
+    // Currently this means that panic!() on OOM will invoke this code path,
+    // but then again we're not really ready for panic on OOM anyway. If
     // we do start doing this, then we should propagate this allocation to
     // be performed in the parent of this task instead of the task that's
-    // failing.
+    // panicking.
 
     // see below for why we do the `Any` coercion here.
     begin_unwind_inner(box msg, file_line)
@@ -549,11 +557,11 @@ pub fn begin_unwind<M: Any + Send>(msg: M, file_line: &(&'static str, uint)) ->
 /// we need the `Any` object anyway, we're not just creating it to
 /// avoid being generic.)
 ///
-/// Do this split took the LLVM IR line counts of `fn main() { fail!()
+/// Do this split took the LLVM IR line counts of `fn main() { panic!()
 /// }` from ~1900/3700 (-O/no opts) to 180/590.
 #[inline(never)] #[cold] // this is the slow path, please never inline this
 fn begin_unwind_inner(msg: Box<Any + Send>, file_line: &(&'static str, uint)) -> ! {
-    // First, invoke call the user-defined callbacks triggered on task failure.
+    // First, invoke call the user-defined callbacks triggered on task panic.
     //
     // By the time that we see a callback has been registered (by reading
     // MAX_CALLBACKS), the actual callback itself may have not been stored yet,
@@ -584,7 +592,7 @@ fn begin_unwind_inner(msg: Box<Any + Send>, file_line: &(&'static str, uint)) ->
     };
 
     if task.unwinder.unwinding {
-        // If a task fails while it's already unwinding then we
+        // If a task panics while it's already unwinding then we
         // have limited options. Currently our preference is to
         // just abort. In the future we may consider resuming
         // unwinding or otherwise exiting the task cleanly.
@@ -603,7 +611,7 @@ fn begin_unwind_inner(msg: Box<Any + Send>, file_line: &(&'static str, uint)) ->
 /// Register a callback to be invoked when a task unwinds.
 ///
 /// This is an unsafe and experimental API which allows for an arbitrary
-/// callback to be invoked when a task fails. This callback is invoked on both
+/// callback to be invoked when a task panics. This callback is invoked on both
 /// the initial unwinding and a double unwinding if one occurs. Additionally,
 /// the local `Task` will be in place for the duration of the callback, and
 /// the callback must ensure that it remains in place once the callback returns.
index 19dcc3c132cd7328a26db09a303ef35ce92b757b..c999157b89a8ffb5d334d343994a230274c059de 100644 (file)
@@ -144,7 +144,7 @@ fn to_base64(&self, config: Config) -> String {
                     v.push(b'=');
                 }
             }
-            _ => fail!("Algebra is broken, please alert the math police")
+            _ => panic!("Algebra is broken, please alert the math police")
         }
 
         unsafe {
index 73b4773fb3ff948f129da4229e9ef840b75f2c8e..99c60dde0ac59c44e70c982364e9b3beae37dca1 100644 (file)
@@ -1229,7 +1229,7 @@ fn bump_index(&mut self) {
         let len = self.stack.len();
         let idx = match *self.stack.last().unwrap() {
             InternalIndex(i) => { i + 1 }
-            _ => { fail!(); }
+            _ => { panic!(); }
         };
         *self.stack.get_mut(len - 1) = InternalIndex(idx);
     }
@@ -1814,7 +1814,7 @@ pub fn build(&mut self) -> Result<Json, BuilderError> {
         match self.token {
             None => {}
             Some(Error(e)) => { return Err(e); }
-            ref tok => { fail!("unexpected token {}", tok.clone()); }
+            ref tok => { panic!("unexpected token {}", tok.clone()); }
         }
         result
     }
@@ -1874,7 +1874,7 @@ fn build_object(&mut self) -> Result<Json, BuilderError> {
             }
             let key = match self.parser.stack().top() {
                 Some(Key(k)) => { k.to_string() }
-                _ => { fail!("invalid state"); }
+                _ => { panic!("invalid state"); }
             };
             match self.build_value() {
                 Ok(value) => { values.insert(key, value); }
@@ -3015,9 +3015,9 @@ fn check_err<T: Decodable<Decoder, DecoderError>>(to_parse: &'static str,
             Ok(json) => Decodable::decode(&mut Decoder::new(json))
         };
         match res {
-            Ok(_) => fail!("`{}` parsed & decoded ok, expecting error `{}`",
+            Ok(_) => panic!("`{}` parsed & decoded ok, expecting error `{}`",
                               to_parse, expected),
-            Err(ParseError(e)) => fail!("`{}` is not valid json: {}",
+            Err(ParseError(e)) => panic!("`{}` is not valid json: {}",
                                            to_parse, e),
             Err(e) => {
                 assert_eq!(e, expected);
@@ -3226,7 +3226,7 @@ fn test_encode_hashmap_with_numeric_key() {
         let bytes = mem_buf.unwrap();
         let json_str = from_utf8(bytes.as_slice()).unwrap();
         match from_str(json_str) {
-            Err(_) => fail!("Unable to parse json_str: {}", json_str),
+            Err(_) => panic!("Unable to parse json_str: {}", json_str),
             _ => {} // it parsed and we are good to go
         }
     }
@@ -3247,7 +3247,7 @@ fn test_prettyencode_hashmap_with_numeric_key() {
         let bytes = mem_buf.unwrap();
         let json_str = from_utf8(bytes.as_slice()).unwrap();
         match from_str(json_str) {
-            Err(_) => fail!("Unable to parse json_str: {}", json_str),
+            Err(_) => panic!("Unable to parse json_str: {}", json_str),
             _ => {} // it parsed and we are good to go
         }
     }
@@ -3315,7 +3315,7 @@ fn test_hashmap_with_numeric_key_can_handle_double_quote_delimited_key() {
         use Decodable;
         let json_str = "{\"1\":true}";
         let json_obj = match from_str(json_str) {
-            Err(_) => fail!("Unable to parse json_str: {}", json_str),
+            Err(_) => panic!("Unable to parse json_str: {}", json_str),
             Ok(o) => o
         };
         let mut decoder = Decoder::new(json_obj);
@@ -3328,7 +3328,7 @@ fn test_hashmap_with_numeric_key_will_error_with_string_keys() {
         use Decodable;
         let json_str = "{\"a\":true}";
         let json_obj = match from_str(json_str) {
-            Err(_) => fail!("Unable to parse json_str: {}", json_str),
+            Err(_) => panic!("Unable to parse json_str: {}", json_str),
             Ok(o) => o
         };
         let mut decoder = Decoder::new(json_obj);
@@ -3347,7 +3347,7 @@ fn assert_stream_equal(src: &str,
             };
             let (ref expected_evt, ref expected_stack) = expected[i];
             if !parser.stack().is_equal_to(expected_stack.as_slice()) {
-                fail!("Parser stack is not equal to {}", expected_stack);
+                panic!("Parser stack is not equal to {}", expected_stack);
             }
             assert_eq!(&evt, expected_evt);
             i+=1;
index 3bed4e4040b3a1267c6a5ba57a6951b8bb3ee9f8..1cd1738e36972c75a6809a7f1d6e8bab344945a1 100644 (file)
@@ -17,6 +17,7 @@
 use std::path;
 use std::rc::Rc;
 use std::cell::{Cell, RefCell};
+use std::sync::Arc;
 
 pub trait Encoder<E> {
     // Primitive types:
@@ -556,6 +557,18 @@ fn decode(d: &mut D) -> Result<RefCell<T>, E> {
     }
 }
 
+impl<E, S:Encoder<E>, T:Encodable<S, E>> Encodable<S, E> for Arc<T> {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
+        (**self).encode(s)
+    }
+}
+
+impl<E, D:Decoder<E>,T:Decodable<D, E>+Send+Sync> Decodable<D, E> for Arc<T> {
+    fn decode(d: &mut D) -> Result<Arc<T>, E> {
+        Ok(Arc::new(try!(Decodable::decode(d))))
+    }
+}
+
 // ___________________________________________________________________________
 // Helper routines
 
index 07be15486fdbc0355f5c945b7897be9e0298cfc5..31f37a8a1bbda38e7eca9f3247a584b3b0d44b45 100644 (file)
@@ -15,6 +15,7 @@
 #![experimental]
 
 use collections::Collection;
+use core::kinds::Sized;
 use fmt;
 use iter::Iterator;
 use mem;
@@ -137,7 +138,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 /// Trait for converting into an ascii type.
 pub trait AsciiCast<T> {
-    /// Convert to an ascii type, fail on non-ASCII input.
+    /// Convert to an ascii type, panic on non-ASCII input.
     #[inline]
     fn to_ascii(&self) -> T {
         assert!(self.is_ascii());
@@ -247,8 +248,7 @@ fn is_ascii(&self) -> bool {
 
     #[inline]
     unsafe fn into_ascii_nocheck(self) -> Vec<Ascii> {
-        let v: Vec<u8> = mem::transmute(self);
-        v.into_ascii_nocheck()
+        self.into_bytes().into_ascii_nocheck()
     }
 }
 
@@ -260,13 +260,20 @@ fn is_ascii(&self) -> bool {
 
     #[inline]
     unsafe fn into_ascii_nocheck(self) -> Vec<Ascii> {
-        mem::transmute(self)
+        let v = Vec::from_raw_parts(self.as_ptr() as *mut Ascii,
+                                    self.len(),
+                                    self.capacity());
+
+        // We forget `self` to avoid freeing it at the end of the scope
+        // Otherwise, the returned `Vec` would point to freed memory
+        mem::forget(self);
+        v
     }
 }
 
 /// Trait for converting an ascii type to a string. Needed to convert
 /// `&[Ascii]` to `&str`.
-pub trait AsciiStr {
+pub trait AsciiStr for Sized? {
     /// Convert to a string.
     fn as_str_ascii<'a>(&'a self) -> &'a str;
 
@@ -285,13 +292,13 @@ pub trait AsciiStr {
     fn to_uppercase(&self) -> Vec<Ascii>;
 
     /// Compares two Ascii strings ignoring case.
-    fn eq_ignore_case(self, other: &[Ascii]) -> bool;
+    fn eq_ignore_case(&self, other: &[Ascii]) -> bool;
 }
 
-impl<'a> AsciiStr for &'a [Ascii] {
+impl AsciiStr for [Ascii] {
     #[inline]
     fn as_str_ascii<'a>(&'a self) -> &'a str {
-        unsafe { mem::transmute(*self) }
+        unsafe { mem::transmute(self) }
     }
 
     #[inline]
@@ -315,7 +322,7 @@ fn to_uppercase(&self) -> Vec<Ascii> {
     }
 
     #[inline]
-    fn eq_ignore_case(self, other: &[Ascii]) -> bool {
+    fn eq_ignore_case(&self, other: &[Ascii]) -> bool {
         self.iter().zip(other.iter()).all(|(&a, &b)| a.eq_ignore_case(b))
     }
 }
@@ -324,8 +331,7 @@ impl IntoStr for Vec<Ascii> {
     #[inline]
     fn into_string(self) -> String {
         unsafe {
-            let s: &str = mem::transmute(self.as_slice());
-            String::from_str(s)
+            string::raw::from_utf8(self.into_bytes())
         }
     }
 }
@@ -338,7 +344,16 @@ pub trait IntoBytes {
 
 impl IntoBytes for Vec<Ascii> {
     fn into_bytes(self) -> Vec<u8> {
-        unsafe { mem::transmute(self) }
+        unsafe {
+            let v = Vec::from_raw_parts(self.as_ptr() as *mut u8,
+                                        self.len(),
+                                        self.capacity());
+
+            // We forget `self` to avoid freeing it at the end of the scope
+            // Otherwise, the returned `Vec` would point to freed memory
+            mem::forget(self);
+            v
+        }
     }
 }
 
@@ -357,7 +372,7 @@ pub trait OwnedAsciiExt {
 }
 
 /// Extension methods for ASCII-subset only operations on string slices
-pub trait AsciiExt<T> {
+pub trait AsciiExt<T> for Sized? {
     /// Makes a copy of the string in ASCII upper case:
     /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
     /// but non-ASCII letters are unchanged.
@@ -371,10 +386,10 @@ pub trait AsciiExt<T> {
     /// Check that two strings are an ASCII case-insensitive match.
     /// Same as `to_ascii_lower(a) == to_ascii_lower(b)`,
     /// but without allocating and copying temporary strings.
-    fn eq_ignore_ascii_case(&self, other: Self) -> bool;
+    fn eq_ignore_ascii_case(&self, other: &Self) -> bool;
 }
 
-impl<'a> AsciiExt<String> for &'a str {
+impl AsciiExt<String> for str {
     #[inline]
     fn to_ascii_upper(&self) -> String {
         // Vec<u8>::to_ascii_upper() preserves the UTF-8 invariant.
@@ -407,7 +422,7 @@ fn into_ascii_lower(self) -> String {
     }
 }
 
-impl<'a> AsciiExt<Vec<u8>> for &'a [u8] {
+impl AsciiExt<Vec<u8>> for [u8] {
     #[inline]
     fn to_ascii_upper(&self) -> Vec<u8> {
         self.iter().map(|&byte| ASCII_UPPER_MAP[byte as uint]).collect()
@@ -633,16 +648,16 @@ fn test_ascii_to_bytes() {
     }
 
     #[test] #[should_fail]
-    fn test_ascii_vec_fail_u8_slice()  { (&[127u8, 128u8, 255u8]).to_ascii(); }
+    fn test_ascii_vec_panic_u8_slice()  { (&[127u8, 128u8, 255u8]).to_ascii(); }
 
     #[test] #[should_fail]
-    fn test_ascii_vec_fail_str_slice() { "zoä华".to_ascii(); }
+    fn test_ascii_vec_panic_str_slice() { "zoä华".to_ascii(); }
 
     #[test] #[should_fail]
-    fn test_ascii_fail_u8_slice() { 255u8.to_ascii(); }
+    fn test_ascii_panic_u8_slice() { 255u8.to_ascii(); }
 
     #[test] #[should_fail]
-    fn test_ascii_fail_char_slice() { 'λ'.to_ascii(); }
+    fn test_ascii_panic_char_slice() { 'λ'.to_ascii(); }
 
     #[test]
     fn test_opt() {
index 7ec25acb17308af454bb12f65c99d1ec08bc667d..bb7de168898f0b820a5f42064521bf950c2e1778 100644 (file)
@@ -169,7 +169,7 @@ mod tests {
     fn malloc(n: uint) -> CVec<u8> {
         unsafe {
             let mem = libc::malloc(n as libc::size_t);
-            if mem.is_null() { fail!("out of memory") }
+            if mem.is_null() { panic!("out of memory") }
 
             CVec::new_with_dtor(mem as *mut u8, n,
                 proc() { libc::free(mem as *mut libc::c_void); })
@@ -189,7 +189,7 @@ fn test_basic() {
 
     #[test]
     #[should_fail]
-    fn test_fail_at_null() {
+    fn test_panic_at_null() {
         unsafe {
             CVec::new(ptr::null_mut::<u8>(), 9);
         }
@@ -213,7 +213,7 @@ fn test_overrun_set() {
     fn test_unwrap() {
         unsafe {
             let cv = CVec::new_with_dtor(1 as *mut int, 0,
-                proc() { fail!("Don't run this destructor!") });
+                proc() { panic!("Don't run this destructor!") });
             let p = cv.unwrap();
             assert_eq!(p, 1 as *mut int);
         }
index ac0d117e02a114d732ebd7633dab0136b315ac4f..6562a644988e6f32d4be9c72e532629eba97b431 100644 (file)
@@ -120,8 +120,7 @@ fn reserve(&mut self, new_capacity: uint) {
 // is also memory and cache pressure that this would entail that would be very
 // difficult to properly see in a microbenchmark.
 //
-// Future Improvements (FIXME!)
-// ============================
+// ## Future Improvements (FIXME!)
 //
 // Allow the load factor to be changed dynamically and/or at initialization.
 //
@@ -129,8 +128,7 @@ fn reserve(&mut self, new_capacity: uint) {
 // underlying table? This is exactly the use case for 'realloc', and may
 // be worth exploring.
 //
-// Future Optimizations (FIXME!)
-// =============================
+// ## Future Optimizations (FIXME!)
 //
 // Another possible design choice that I made without any real reason is
 // parameterizing the raw table over keys and values. Technically, all we need
@@ -473,7 +471,7 @@ fn insert_hashed_ordered(&mut self, hash: SafeHash, k: K, v: V) {
             };
             buckets.next();
         }
-        fail!("Internal HashMap error: Out of space.");
+        panic!("Internal HashMap error: Out of space.");
     }
 }
 
@@ -829,7 +827,8 @@ fn insert_or_replace_with<'a>(&'a mut self,
     }
 
     /// Retrieves a mutable value for the given key.
-    /// See [`find_mut`](../trait.MutableMap.html#tymethod.find_mut) for a non-failing alternative.
+    /// See [`find_mut`](../trait.MutableMap.html#tymethod.find_mut) for a non-panicking
+    /// alternative.
     ///
     /// # Failure
     ///
@@ -856,7 +855,7 @@ fn insert_or_replace_with<'a>(&'a mut self,
     pub fn get_mut<'a>(&'a mut self, k: &K) -> &'a mut V {
         match self.find_mut(k) {
             Some(v) => v,
-            None => fail!("no entry found for key")
+            None => panic!("no entry found for key")
         }
     }
 
@@ -1625,7 +1624,7 @@ fn test_find_mut() {
         assert!(m.insert(5i, 14i));
         let new = 100;
         match m.find_mut(&5) {
-            None => fail!(), Some(x) => *x = new
+            None => panic!(), Some(x) => *x = new
         }
         assert_eq!(m.find(&5), Some(&new));
     }
@@ -1746,7 +1745,7 @@ fn test_find() {
         assert!(m.find(&1i).is_none());
         m.insert(1i, 2i);
         match m.find(&1) {
-            None => fail!(),
+            None => panic!(),
             Some(v) => assert_eq!(*v, 2)
         }
     }
@@ -1759,12 +1758,12 @@ fn test_find_copy() {
         for i in range(1i, 10000) {
             m.insert(i, i + 7);
             match m.find_copy(&i) {
-                None => fail!(),
+                None => panic!(),
                 Some(v) => assert_eq!(v, i + 7)
             }
             for j in range(1i, i/100) {
                 match m.find_copy(&j) {
-                    None => fail!(),
+                    None => panic!(),
                     Some(v) => assert_eq!(v, j + 7)
                 }
             }
index dde1f27c9a322dd54665d584c81224d6e63be61b..ca954679c1c9d7db7851c03df088a8bf33524f32 100644 (file)
@@ -186,7 +186,7 @@ pub fn reserve(&mut self, n: uint) {
     /// # Example
     ///
     /// This is a slightly silly example where we define the number's
-    /// parity as the equivilance class. It is important that the
+    /// parity as the equivalance class. It is important that the
     /// values hash the same, which is why we implement `Hash`.
     ///
     /// ```
index ee64a7931c06242d887e9f222da7e5443606e3c3..ca20c3ddb74f02f1b36cad22c2f3ec2b8add85c7 100644 (file)
@@ -470,7 +470,7 @@ impl<K, V, M> BucketState<K, V, M> {
     pub fn expect_full(self) -> FullBucket<K, V, M> {
         match self {
             Full(full) => full,
-            Empty(..) => fail!("Expected full bucket")
+            Empty(..) => panic!("Expected full bucket")
         }
     }
 }
index ed8ff821f5cad67ffb9fe8cf8d4676de555b1019..c2f27caad1d9c6758690b4a3b7b3abe75d5862b4 100644 (file)
@@ -44,7 +44,7 @@ fn drop(&mut self) {
             }
         }) {
             Ok(()) => {},
-            Err(str) => fail!("{}", str)
+            Err(str) => panic!("{}", str)
         }
     }
 }
@@ -168,13 +168,13 @@ fn test_loading_cosine() {
         // statically linked in
         let none: Option<Path> = None; // appease the typechecker
         let libm = match DynamicLibrary::open(none) {
-            Err(error) => fail!("Could not load self as module: {}", error),
+            Err(error) => panic!("Could not load self as module: {}", error),
             Ok(libm) => libm
         };
 
         let cosine: extern fn(libc::c_double) -> libc::c_double = unsafe {
             match libm.symbol("cos") {
-                Err(error) => fail!("Could not load function cos: {}", error),
+                Err(error) => panic!("Could not load function cos: {}", error),
                 Ok(cosine) => mem::transmute::<*mut u8, _>(cosine)
             }
         };
@@ -183,7 +183,7 @@ fn test_loading_cosine() {
         let expected_result = 1.0;
         let result = cosine(argument);
         if result != expected_result {
-            fail!("cos({}) != {} but equaled {} instead", argument,
+            panic!("cos({}) != {} but equaled {} instead", argument,
                    expected_result, result)
         }
     }
@@ -199,7 +199,7 @@ fn test_errors_do_not_crash() {
         let path = Path::new("/dev/null");
         match DynamicLibrary::open(Some(&path)) {
             Err(_) => {}
-            Ok(_) => fail!("Successfully opened the empty library.")
+            Ok(_) => panic!("Successfully opened the empty library.")
         }
     }
 }
index a7de84184ff5db719651ce22e92fb55a5d61c1f5..077599743564151b5b72ec5cd43184d26d71044c 100644 (file)
@@ -51,11 +51,11 @@ pub fn on_fail(obj: &Any + Send, file: &'static str, line: uint) {
     // all times. This means that this `exists` will return true almost all of
     // the time. There are border cases, however, when the runtime has
     // *almost* set up the local task, but hasn't quite gotten there yet. In
-    // order to get some better diagnostics, we print on failure and
+    // order to get some better diagnostics, we print on panic and
     // immediately abort the whole process if there is no local task
     // available.
     if !Local::exists(None::<Task>) {
-        let _ = writeln!(&mut err, "failed at '{}', {}:{}", msg, file, line);
+        let _ = writeln!(&mut err, "panicked at '{}', {}:{}", msg, file, line);
         if backtrace::log_enabled() {
             let _ = backtrace::write(&mut err);
         } else {
@@ -76,9 +76,9 @@ pub fn on_fail(obj: &Any + Send, file: &'static str, line: uint) {
 
         match local_stderr.replace(None) {
             Some(mut stderr) => {
-                // FIXME: what to do when the task printing fails?
+                // FIXME: what to do when the task printing panics?
                 let _ = writeln!(stderr,
-                                 "task '{}' failed at '{}', {}:{}\n",
+                                 "task '{}' panicked at '{}', {}:{}\n",
                                  n, msg, file, line);
                 if backtrace::log_enabled() {
                     let _ = backtrace::write(&mut *stderr);
@@ -86,7 +86,7 @@ pub fn on_fail(obj: &Any + Send, file: &'static str, line: uint) {
                 local_stderr.replace(Some(stderr));
             }
             None => {
-                let _ = writeln!(&mut err, "task '{}' failed at '{}', {}:{}",
+                let _ = writeln!(&mut err, "task '{}' panicked at '{}', {}:{}",
                                  n, msg, file, line);
                 if backtrace::log_enabled() {
                     let _ = backtrace::write(&mut err);
@@ -94,8 +94,8 @@ pub fn on_fail(obj: &Any + Send, file: &'static str, line: uint) {
             }
         }
 
-        // If this is a double failure, make sure that we printed a backtrace
-        // for this failure.
+        // If this is a double panic, make sure that we printed a backtrace
+        // for this panic.
         if unwinding && !backtrace::log_enabled() {
             let _ = backtrace::write(&mut err);
         }
index 95c44e6a3fc89c94712e0611a12f3d42b534a521..a01787c286bb92311ca802cd0f83addaa31fa338 100644 (file)
@@ -130,14 +130,13 @@ fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
 /// # Example
 ///
 /// ```rust
-/// # #![allow(unused_must_use)]
 /// use std::io::{BufferedWriter, File};
 ///
-/// let file = File::open(&Path::new("message.txt"));
+/// let file = File::create(&Path::new("message.txt")).unwrap();
 /// let mut writer = BufferedWriter::new(file);
 ///
-/// writer.write_str("hello, world");
-/// writer.flush();
+/// writer.write_str("hello, world").unwrap();
+/// writer.flush().unwrap();
 /// ```
 pub struct BufferedWriter<W> {
     inner: Option<W>,
@@ -183,7 +182,7 @@ pub fn get_ref<'a>(&'a self) -> &'a W { self.inner.as_ref().unwrap() }
     ///
     /// The buffer is flushed before returning the writer.
     pub fn unwrap(mut self) -> W {
-        // FIXME(#12628): is failing the right thing to do if flushing fails?
+        // FIXME(#12628): is panicking the right thing to do if flushing panicks?
         self.flush_buf().unwrap();
         self.inner.take().unwrap()
     }
@@ -214,7 +213,7 @@ fn flush(&mut self) -> IoResult<()> {
 impl<W: Writer> Drop for BufferedWriter<W> {
     fn drop(&mut self) {
         if self.inner.is_some() {
-            // dtors should not fail, so we ignore a failed flush
+            // dtors should not panic, so we ignore a panicked flush
             let _ = self.flush_buf();
         }
     }
@@ -612,7 +611,7 @@ fn test_chars() {
 
     #[test]
     #[should_fail]
-    fn dont_fail_in_drop_on_failed_flush() {
+    fn dont_panic_in_drop_on_panicked_flush() {
         struct FailFlushWriter;
 
         impl Writer for FailFlushWriter {
@@ -623,9 +622,8 @@ fn flush(&mut self) -> IoResult<()> { Err(io::standard_error(EndOfFile)) }
         let writer = FailFlushWriter;
         let _writer = BufferedWriter::new(writer);
 
-        // Trigger failure. If writer fails *again* due to the flush
-        // error then the process will abort.
-        fail!();
+        // If writer panics *again* due to the flush error then the process will abort.
+        panic!();
     }
 
     #[bench]
index bd9577c8cfc8cf3dcf8a1d70e8a46c7800ce34c7..07f4ebda2d41aa4f4d60ba53bcd696dcb62e0f96 100644 (file)
@@ -188,14 +188,14 @@ fn test_rx_reader() {
         assert_eq!(a, buf.as_slice());
 
         match reader.read(buf.as_mut_slice()) {
-            Ok(..) => fail!(),
+            Ok(..) => panic!(),
             Err(e) => assert_eq!(e.kind, io::EndOfFile),
         }
         assert_eq!(a, buf.as_slice());
 
-        // Ensure it continues to fail in the same way.
+        // Ensure it continues to panic in the same way.
         match reader.read(buf.as_mut_slice()) {
-            Ok(..) => fail!(),
+            Ok(..) => panic!(),
             Err(e) => assert_eq!(e.kind, io::EndOfFile),
         }
         assert_eq!(a, buf.as_slice());
@@ -218,7 +218,7 @@ fn test_rx_buffer() {
         assert_eq!(Ok("hello world\n".to_string()), reader.read_line());
         assert_eq!(Ok("how are you?".to_string()), reader.read_line());
         match reader.read_line() {
-            Ok(..) => fail!(),
+            Ok(..) => panic!(),
             Err(e) => assert_eq!(e.kind, io::EndOfFile),
         }
     }
@@ -232,12 +232,12 @@ fn test_chan_writer() {
         let wanted = vec![0u8, 0u8, 0u8, 42u8];
         let got = match task::try(proc() { rx.recv() }) {
             Ok(got) => got,
-            Err(_) => fail!(),
+            Err(_) => panic!(),
         };
         assert_eq!(wanted, got);
 
         match writer.write_u8(1) {
-            Ok(..) => fail!(),
+            Ok(..) => panic!(),
             Err(e) => assert_eq!(e.kind, io::BrokenPipe),
         }
     }
index 57741db5ae2182bd4b27574cc798910bf9e694b7..078a9a014c9c8d97c38d29c2e9e527edcc63b918 100644 (file)
@@ -70,7 +70,7 @@ fn next(&mut self) -> Option<IoResult<u8>> {
 ///
 /// * `n`: The value to convert.
 /// * `size`: The size of the value, in bytes. This must be 8 or less, or task
-///           failure occurs. If this is less than 8, then a value of that
+///           panic occurs. If this is less than 8, then a value of that
 ///           many bytes is produced. For example, if `size` is 4, then a
 ///           32-bit byte representation is produced.
 /// * `f`: A callback that receives the value.
@@ -109,7 +109,7 @@ pub fn u64_to_le_bytes<T>(n: u64, size: uint, f: |v: &[u8]| -> T) -> T {
 ///
 /// * `n`: The value to convert.
 /// * `size`: The size of the value, in bytes. This must be 8 or less, or task
-///           failure occurs. If this is less than 8, then a value of that
+///           panic occurs. If this is less than 8, then a value of that
 ///           many bytes is produced. For example, if `size` is 4, then a
 ///           32-bit byte representation is produced.
 /// * `f`: A callback that receives the value.
@@ -146,7 +146,7 @@ pub fn u64_to_be_bytes<T>(n: u64, size: uint, f: |v: &[u8]| -> T) -> T {
 /// * `data`: The buffer in which to extract the value.
 /// * `start`: The offset at which to extract the value.
 /// * `size`: The size of the value in bytes to extract. This must be 8 or
-///           less, or task failure occurs. If this is less than 8, then only
+///           less, or task panic occurs. If this is less than 8, then only
 ///           that many bytes are parsed. For example, if `size` is 4, then a
 ///           32-bit value is parsed.
 pub fn u64_from_be_bytes(data: &[u8], start: uint, size: uint) -> u64 {
@@ -156,7 +156,7 @@ pub fn u64_from_be_bytes(data: &[u8], start: uint, size: uint) -> u64 {
     assert!(size <= 8u);
 
     if data.len() - start < size {
-        fail!("index out of bounds");
+        panic!("index out of bounds");
     }
 
     let mut buf = [0u8, ..8];
@@ -172,7 +172,7 @@ pub fn u64_from_be_bytes(data: &[u8], start: uint, size: uint) -> u64 {
 mod test {
     use prelude::*;
     use io;
-    use io::{MemReader, MemWriter};
+    use io::{MemReader, MemWriter, BytesReader};
 
     struct InitialZeroByteReader {
         count: int,
index 8632fc63e52f87d79865dfe8c01cee79a51d691c..f749d6c823ea3b399055b0b1fda3105b879cead7 100644 (file)
@@ -105,7 +105,7 @@ impl File {
     ///
     /// let file = match File::open_mode(&p, Open, ReadWrite) {
     ///     Ok(f) => f,
-    ///     Err(e) => fail!("file error: {}", e),
+    ///     Err(e) => panic!("file error: {}", e),
     /// };
     /// // do some stuff with that file
     ///
@@ -957,13 +957,13 @@ mod test {
     macro_rules! check( ($e:expr) => (
         match $e {
             Ok(t) => t,
-            Err(e) => fail!("{} failed with: {}", stringify!($e), e),
+            Err(e) => panic!("{} failed with: {}", stringify!($e), e),
         }
     ) )
 
     macro_rules! error( ($e:expr, $s:expr) => (
         match $e {
-            Ok(val) => fail!("Unexpected success. Should've been: {}", $s),
+            Ok(val) => panic!("Unexpected success. Should've been: {}", $s),
             Err(ref err) => assert!(err.to_string().as_slice().contains($s.as_slice()),
                                     format!("`{}` did not contain `{}`", err, $s))
         }
@@ -1013,7 +1013,7 @@ fn file_test_io_smoke_test() {
             let mut read_stream = File::open_mode(filename, Open, Read);
             let mut read_buf = [0, .. 1028];
             let read_str = match check!(read_stream.read(read_buf)) {
-                -1|0 => fail!("shouldn't happen"),
+                -1|0 => panic!("shouldn't happen"),
                 n => str::from_utf8(read_buf[..n]).unwrap().to_string()
             };
             assert_eq!(read_str.as_slice(), message);
@@ -1241,7 +1241,7 @@ fn file_test_directoryinfo_readdir() {
                 check!(File::open(f).read(mem));
                 let read_str = str::from_utf8(mem).unwrap();
                 let expected = match n {
-                    None|Some("") => fail!("really shouldn't happen.."),
+                    None|Some("") => panic!("really shouldn't happen.."),
                     Some(n) => format!("{}{}", prefix, n),
                 };
                 assert_eq!(expected.as_slice(), read_str);
@@ -1371,7 +1371,7 @@ fn copy_file_does_not_exist() {
                     from.display(), to.display()));
 
         match copy(&from, &to) {
-            Ok(..) => fail!(),
+            Ok(..) => panic!(),
             Err(..) => {
                 assert!(!from.exists());
                 assert!(!to.exists());
@@ -1400,7 +1400,7 @@ fn copy_file_dst_dir() {
 
         check!(File::create(&out));
         match copy(&out, tmpdir.path()) {
-            Ok(..) => fail!(), Err(..) => {}
+            Ok(..) => panic!(), Err(..) => {}
         }
     }
 
@@ -1424,7 +1424,7 @@ fn copy_file_src_dir() {
         let out = tmpdir.join("out");
 
         match copy(tmpdir.path(), &out) {
-            Ok(..) => fail!(), Err(..) => {}
+            Ok(..) => panic!(), Err(..) => {}
         }
         assert!(!out.exists());
     }
@@ -1475,7 +1475,7 @@ fn symlink_noexist() {
     fn readlink_not_symlink() {
         let tmpdir = tmpdir();
         match readlink(tmpdir.path()) {
-            Ok(..) => fail!("wanted a failure"),
+            Ok(..) => panic!("wanted a failure"),
             Err(..) => {}
         }
     }
@@ -1501,12 +1501,12 @@ fn links_work() {
 
         // can't link to yourself
         match link(&input, &input) {
-            Ok(..) => fail!("wanted a failure"),
+            Ok(..) => panic!("wanted a failure"),
             Err(..) => {}
         }
         // can't link to something that doesn't exist
         match link(&tmpdir.join("foo"), &tmpdir.join("bar")) {
-            Ok(..) => fail!("wanted a failure"),
+            Ok(..) => panic!("wanted a failure"),
             Err(..) => {}
         }
     }
@@ -1522,7 +1522,7 @@ fn chmod_works() {
         assert!(!check!(stat(&file)).perm.contains(io::USER_WRITE));
 
         match chmod(&tmpdir.join("foo"), io::USER_RWX) {
-            Ok(..) => fail!("wanted a failure"),
+            Ok(..) => panic!("wanted a panic"),
             Err(..) => {}
         }
 
@@ -1580,7 +1580,7 @@ fn open_flavors() {
         let tmpdir = tmpdir();
 
         match File::open_mode(&tmpdir.join("a"), io::Open, io::Read) {
-            Ok(..) => fail!(), Err(..) => {}
+            Ok(..) => panic!(), Err(..) => {}
         }
 
         // Perform each one twice to make sure that it succeeds the second time
@@ -1615,7 +1615,7 @@ fn open_flavors() {
             let mut f = check!(File::open_mode(&tmpdir.join("h"), io::Open,
                                                io::Read));
             match f.write("wut".as_bytes()) {
-                Ok(..) => fail!(), Err(..) => {}
+                Ok(..) => panic!(), Err(..) => {}
             }
         }
         assert!(check!(stat(&tmpdir.join("h"))).size == 3,
@@ -1653,7 +1653,7 @@ fn utime_noexist() {
         let tmpdir = tmpdir();
 
         match change_file_times(&tmpdir.join("a"), 100, 200) {
-            Ok(..) => fail!(),
+            Ok(..) => panic!(),
             Err(..) => {}
         }
     }
index f86ae05d623ca462c2a70e87c9e899b19326d996..2f6dd7e47955fd703b5e0dc76f7861c125c573e4 100644 (file)
@@ -22,7 +22,7 @@
 use slice::AsSlice;
 use vec::Vec;
 
-static BUF_CAPACITY: uint = 128;
+const BUF_CAPACITY: uint = 128;
 
 fn combine(seek: SeekStyle, cur: uint, end: uint, offset: i64) -> IoResult<u64> {
     // compute offset as signed and clamp to prevent overflow
@@ -71,7 +71,12 @@ pub fn new() -> MemWriter {
     /// the internal buffer.
     #[inline]
     pub fn with_capacity(n: uint) -> MemWriter {
-        MemWriter { buf: Vec::with_capacity(n) }
+        MemWriter::from_vec(Vec::with_capacity(n))
+    }
+    /// Create a new `MemWriter` that will append to an existing `Vec`.
+    #[inline]
+    pub fn from_vec(buf: Vec<u8>) -> MemWriter {
+        MemWriter { buf: buf }
     }
 
     /// Acquires an immutable reference to the underlying buffer of this
@@ -404,7 +409,7 @@ fn test_buf_writer_error() {
         writer.write([0]).unwrap();
 
         match writer.write([0, 0]) {
-            Ok(..) => fail!(),
+            Ok(..) => panic!(),
             Err(e) => assert_eq!(e.kind, io::OtherIoError),
         }
     }
@@ -505,7 +510,7 @@ fn test_read_whole_string_bad() {
         let buf = [0xff];
         let mut r = BufReader::new(buf);
         match r.read_to_string() {
-            Ok(..) => fail!(),
+            Ok(..) => panic!(),
             Err(..) => {}
         }
     }
index 8592d48974a25f8c143a202cb01b2dbf4fddbc58..d22650107a334e697f3a8ec149cf9f835a930405 100644 (file)
@@ -712,17 +712,6 @@ fn read_to_string(&mut self) -> IoResult<String> {
         })
     }
 
-    /// Create an iterator that reads a single byte on
-    /// each iteration, until EOF.
-    ///
-    /// # Error
-    ///
-    /// Any error other than `EndOfFile` that is produced by the underlying Reader
-    /// is returned by the iterator and should be handled by the caller.
-    fn bytes<'r>(&'r mut self) -> extensions::Bytes<'r, Self> {
-        extensions::Bytes::new(self)
-    }
-
     // Byte conversion helpers
 
     /// Reads `n` little-endian unsigned integer bytes.
@@ -932,16 +921,41 @@ fn read_u8(&mut self) -> IoResult<u8> {
     fn read_i8(&mut self) -> IoResult<i8> {
         self.read_byte().map(|i| i as i8)
     }
+}
 
+/// A reader which can be converted to a RefReader.
+pub trait AsRefReader {
     /// Creates a wrapper around a mutable reference to the reader.
     ///
     /// This is useful to allow applying adaptors while still
     /// retaining ownership of the original value.
-    fn by_ref<'a>(&'a mut self) -> RefReader<'a, Self> {
+    fn by_ref<'a>(&'a mut self) -> RefReader<'a, Self>;
+}
+
+impl<T: Reader> AsRefReader for T {
+    fn by_ref<'a>(&'a mut self) -> RefReader<'a, T> {
         RefReader { inner: self }
     }
 }
 
+/// A reader which can be converted to bytes.
+pub trait BytesReader {
+    /// Create an iterator that reads a single byte on
+    /// each iteration, until EOF.
+    ///
+    /// # Error
+    ///
+    /// Any error other than `EndOfFile` that is produced by the underlying Reader
+    /// is returned by the iterator and should be handled by the caller.
+    fn bytes<'r>(&'r mut self) -> extensions::Bytes<'r, Self>;
+}
+
+impl<T: Reader> BytesReader for T {
+    fn bytes<'r>(&'r mut self) -> extensions::Bytes<'r, T> {
+        extensions::Bytes::new(self)
+    }
+}
+
 impl<'a> Reader for Box<Reader+'a> {
     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
         let reader: &mut Reader = &mut **self;
@@ -986,6 +1000,7 @@ unsafe fn slice_vec_capacity<'a, T>(v: &'a mut Vec<T>, start: uint, end: uint) -
 /// # fn process_input<R: Reader>(r: R) {}
 /// # fn foo() {
 /// use std::io;
+/// use std::io::AsRefReader;
 /// use std::io::util::LimitReader;
 ///
 /// let mut stream = io::stdin();
@@ -1268,13 +1283,20 @@ fn write_u8(&mut self, n: u8) -> IoResult<()> {
     fn write_i8(&mut self, n: i8) -> IoResult<()> {
         self.write([n as u8])
     }
+}
 
+/// A writer which can be converted to a RefWriter.
+pub trait AsRefWriter {
     /// Creates a wrapper around a mutable reference to the writer.
     ///
     /// This is useful to allow applying wrappers while still
     /// retaining ownership of the original value.
     #[inline]
-    fn by_ref<'a>(&'a mut self) -> RefWriter<'a, Self> {
+    fn by_ref<'a>(&'a mut self) -> RefWriter<'a, Self>;
+}
+
+impl<T: Writer> AsRefWriter for T {
+    fn by_ref<'a>(&'a mut self) -> RefWriter<'a, T> {
         RefWriter { inner: self }
     }
 }
@@ -1309,7 +1331,7 @@ fn flush(&mut self) -> IoResult<()> { (**self).flush() }
 /// # fn process_input<R: Reader>(r: R) {}
 /// # fn foo () {
 /// use std::io::util::TeeReader;
-/// use std::io::{stdin, MemWriter};
+/// use std::io::{stdin, MemWriter, AsRefWriter};
 ///
 /// let mut output = MemWriter::new();
 ///
@@ -1730,7 +1752,7 @@ pub enum FileType {
 /// # fn foo() {
 /// let info = match Path::new("foo.txt").stat() {
 ///     Ok(stat) => stat,
-///     Err(e) => fail!("couldn't read foo.txt: {}", e),
+///     Err(e) => panic!("couldn't read foo.txt: {}", e),
 /// };
 ///
 /// println!("byte size: {}", info.size);
index e0cf761fdbd7e7bde3bd436796b1e77a7b47346c..112094d1d39b366477ee2754f9ec99327872a8fb 100644 (file)
@@ -269,13 +269,13 @@ pub fn smalltest(server: proc(UnixStream):Send, client: proc(UnixStream):Send) {
         spawn(proc() {
             match UnixStream::connect(&path2) {
                 Ok(c) => client(c),
-                Err(e) => fail!("failed connect: {}", e),
+                Err(e) => panic!("failed connect: {}", e),
             }
         });
 
         match acceptor.accept() {
             Ok(c) => server(c),
-            Err(e) => fail!("failed accept: {}", e),
+            Err(e) => panic!("failed accept: {}", e),
         }
     }
 
@@ -283,7 +283,7 @@ pub fn smalltest(server: proc(UnixStream):Send, client: proc(UnixStream):Send) {
     fn bind_error() {
         let path = "path/to/nowhere";
         match UnixListener::bind(&path) {
-            Ok(..) => fail!(),
+            Ok(..) => panic!(),
             Err(e) => {
                 assert!(e.kind == PermissionDenied || e.kind == FileNotFound ||
                         e.kind == InvalidInput);
@@ -299,7 +299,7 @@ fn connect_error() {
             "path/to/nowhere"
         };
         match UnixStream::connect(&path) {
-            Ok(..) => fail!(),
+            Ok(..) => panic!(),
             Err(e) => {
                 assert!(e.kind == FileNotFound || e.kind == OtherIoError);
             }
@@ -358,7 +358,7 @@ fn accept_lots() {
 
         let mut acceptor = match UnixListener::bind(&path1).listen() {
             Ok(a) => a,
-            Err(e) => fail!("failed listen: {}", e),
+            Err(e) => panic!("failed listen: {}", e),
         };
 
         spawn(proc() {
@@ -366,7 +366,7 @@ fn accept_lots() {
                 let mut stream = UnixStream::connect(&path2);
                 match stream.write([100]) {
                     Ok(..) => {}
-                    Err(e) => fail!("failed write: {}", e)
+                    Err(e) => panic!("failed write: {}", e)
                 }
             }
         });
@@ -376,7 +376,7 @@ fn accept_lots() {
             let mut buf = [0];
             match client.read(buf) {
                 Ok(..) => {}
-                Err(e) => fail!("failed read/accept: {}", e),
+                Err(e) => panic!("failed read/accept: {}", e),
             }
             assert_eq!(buf[0], 100);
         }
@@ -531,10 +531,10 @@ fn accept_timeout() {
             match a.accept() {
                 Ok(..) => break,
                 Err(ref e) if e.kind == TimedOut => {}
-                Err(e) => fail!("error: {}", e),
+                Err(e) => panic!("error: {}", e),
             }
             ::task::deschedule();
-            if i == 1000 { fail!("should have a pending connection") }
+            if i == 1000 { panic!("should have a pending connection") }
         }
         drop(l);
 
@@ -659,9 +659,9 @@ fn readwrite_timeouts() {
             match s.write([0, .. 128 * 1024]) {
                 Ok(()) | Err(IoError { kind: ShortWrite(..), .. }) => {},
                 Err(IoError { kind: TimedOut, .. }) => break,
-                Err(e) => fail!("{}", e),
+                Err(e) => panic!("{}", e),
            }
-           if i == 1000 { fail!("should have filled up?!"); }
+           if i == 1000 { panic!("should have filled up?!"); }
         }
 
         // I'm not sure as to why, but apparently the write on windows always
@@ -687,7 +687,7 @@ fn read_timeouts() {
             while amt < 100 * 128 * 1024 {
                 match s.read([0, ..128 * 1024]) {
                     Ok(n) => { amt += n; }
-                    Err(e) => fail!("{}", e),
+                    Err(e) => panic!("{}", e),
                 }
             }
             let _ = rx.recv_opt();
@@ -722,9 +722,9 @@ fn write_timeouts() {
             match s.write([0, .. 128 * 1024]) {
                 Ok(()) | Err(IoError { kind: ShortWrite(..), .. }) => {},
                 Err(IoError { kind: TimedOut, .. }) => break,
-                Err(e) => fail!("{}", e),
+                Err(e) => panic!("{}", e),
            }
-           if i == 1000 { fail!("should have filled up?!"); }
+           if i == 1000 { panic!("should have filled up?!"); }
         }
 
         tx.send(());
index d6528ce977e9821e8c9c7412b40c24fca6052894..09804ef57031384425c3669532410afd2e3612ee 100644 (file)
@@ -471,7 +471,7 @@ impl TcpAcceptor {
     ///         match socket {
     ///             Ok(s) => { /* handle s */ }
     ///             Err(ref e) if e.kind == EndOfFile => break, // closed
-    ///             Err(e) => fail!("unexpected error: {}", e),
+    ///             Err(e) => panic!("unexpected error: {}", e),
     ///         }
     ///     }
     /// });
@@ -532,7 +532,7 @@ mod test {
     #[test]
     fn bind_error() {
         match TcpListener::bind("0.0.0.0", 1) {
-            Ok(..) => fail!(),
+            Ok(..) => panic!(),
             Err(e) => assert_eq!(e.kind, PermissionDenied),
         }
     }
@@ -540,7 +540,7 @@ fn bind_error() {
     #[test]
     fn connect_error() {
         match TcpStream::connect("0.0.0.0", 1) {
-            Ok(..) => fail!(),
+            Ok(..) => panic!(),
             Err(e) => assert_eq!(e.kind, ConnectionRefused),
         }
     }
@@ -708,7 +708,7 @@ fn read_eof_twice_ip4() {
         assert!(nread.is_err());
 
         match stream.read(buf) {
-            Ok(..) => fail!(),
+            Ok(..) => panic!(),
             Err(ref e) => {
                 assert!(e.kind == NotConnected || e.kind == EndOfFile,
                         "unknown kind: {}", e.kind);
@@ -734,7 +734,7 @@ fn read_eof_twice_ip6() {
         assert!(nread.is_err());
 
         match stream.read(buf) {
-            Ok(..) => fail!(),
+            Ok(..) => panic!(),
             Err(ref e) => {
                 assert!(e.kind == NotConnected || e.kind == EndOfFile,
                         "unknown kind: {}", e.kind);
@@ -1082,7 +1082,7 @@ fn double_bind() {
         let listener = TcpListener::bind(ip_str.as_slice(), port).unwrap().listen();
         assert!(listener.is_ok());
         match TcpListener::bind(ip_str.as_slice(), port).listen() {
-            Ok(..) => fail!(),
+            Ok(..) => panic!(),
             Err(e) => {
                 assert!(e.kind == ConnectionRefused || e.kind == OtherIoError,
                         "unknown error: {} {}", e, e.kind);
@@ -1266,10 +1266,10 @@ fn accept_timeout() {
                 match a.accept() {
                     Ok(..) => break,
                     Err(ref e) if e.kind == TimedOut => {}
-                    Err(e) => fail!("error: {}", e),
+                    Err(e) => panic!("error: {}", e),
                 }
                 ::task::deschedule();
-                if i == 1000 { fail!("should have a pending connection") }
+                if i == 1000 { panic!("should have a pending connection") }
             }
         }
 
@@ -1373,9 +1373,9 @@ fn readwrite_timeouts() {
             match s.write([0, .. 128 * 1024]) {
                 Ok(()) | Err(IoError { kind: ShortWrite(..), .. }) => {},
                 Err(IoError { kind: TimedOut, .. }) => break,
-                Err(e) => fail!("{}", e),
+                Err(e) => panic!("{}", e),
            }
-           if i == 1000 { fail!("should have filled up?!"); }
+           if i == 1000 { panic!("should have filled up?!"); }
         }
         assert_eq!(s.write([0]).err().unwrap().kind, TimedOut);
 
@@ -1398,7 +1398,7 @@ fn read_timeouts() {
             while amt < 100 * 128 * 1024 {
                 match s.read([0, ..128 * 1024]) {
                     Ok(n) => { amt += n; }
-                    Err(e) => fail!("{}", e),
+                    Err(e) => panic!("{}", e),
                 }
             }
             let _ = rx.recv_opt();
@@ -1435,9 +1435,9 @@ fn write_timeouts() {
             match s.write([0, .. 128 * 1024]) {
                 Ok(()) | Err(IoError { kind: ShortWrite(..), .. }) => {},
                 Err(IoError { kind: TimedOut, .. }) => break,
-                Err(e) => fail!("{}", e),
+                Err(e) => panic!("{}", e),
            }
-           if i == 1000 { fail!("should have filled up?!"); }
+           if i == 1000 { panic!("should have filled up?!"); }
         }
         assert_eq!(s.write([0]).err().unwrap().kind, TimedOut);
 
index 7d9eea3a73279bf535fdeb6cc8cb230fe6bf6718..ad9ed090a5ba667cbed3d866b36c452e53532c84 100644 (file)
@@ -43,7 +43,7 @@
 ///     let addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 34254 };
 ///     let mut socket = match UdpSocket::bind(addr) {
 ///         Ok(s) => s,
-///         Err(e) => fail!("couldn't bind socket: {}", e),
+///         Err(e) => panic!("couldn't bind socket: {}", e),
 ///     };
 ///
 ///     let mut buf = [0, ..10];
@@ -271,7 +271,7 @@ mod test {
     fn bind_error() {
         let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
         match UdpSocket::bind(addr) {
-            Ok(..) => fail!(),
+            Ok(..) => panic!(),
             Err(e) => assert_eq!(e.kind, PermissionDenied),
         }
     }
@@ -289,7 +289,7 @@ fn socket_smoke_test_ip4() {
                     rx1.recv();
                     client.send_to([99], server_ip).unwrap()
                 }
-                Err(..) => fail!()
+                Err(..) => panic!()
             }
             tx2.send(());
         });
@@ -304,10 +304,10 @@ fn socket_smoke_test_ip4() {
                         assert_eq!(buf[0], 99);
                         assert_eq!(src, client_ip);
                     }
-                    Err(..) => fail!()
+                    Err(..) => panic!()
                 }
             }
-            Err(..) => fail!()
+            Err(..) => panic!()
         }
         rx2.recv();
     }
@@ -324,7 +324,7 @@ fn socket_smoke_test_ip6() {
                     rx.recv();
                     client.send_to([99], server_ip).unwrap()
                 }
-                Err(..) => fail!()
+                Err(..) => panic!()
             }
         });
 
@@ -338,10 +338,10 @@ fn socket_smoke_test_ip6() {
                         assert_eq!(buf[0], 99);
                         assert_eq!(src, client_ip);
                     }
-                    Err(..) => fail!()
+                    Err(..) => panic!()
                 }
             }
-            Err(..) => fail!()
+            Err(..) => panic!()
         }
     }
 
@@ -362,7 +362,7 @@ fn stream_smoke_test_ip4() {
                         let mut stream = client.connect(server_ip);
                         stream.write(val).unwrap();
                     }
-                    Err(..) => fail!()
+                    Err(..) => panic!()
                 }
             };
             rx1.recv();
@@ -382,10 +382,10 @@ fn stream_smoke_test_ip4() {
                         assert_eq!(nread, 1);
                         assert_eq!(buf[0], 99);
                     }
-                    Err(..) => fail!(),
+                    Err(..) => panic!(),
                 }
             }
-            Err(..) => fail!()
+            Err(..) => panic!()
         }
         rx2.recv();
     }
@@ -406,7 +406,7 @@ fn stream_smoke_test_ip6() {
                     rx1.recv();
                     stream.write([99]).unwrap();
                 }
-                Err(..) => fail!()
+                Err(..) => panic!()
             }
             tx2.send(());
         });
@@ -422,10 +422,10 @@ fn stream_smoke_test_ip6() {
                         assert_eq!(nread, 1);
                         assert_eq!(buf[0], 99);
                     }
-                    Err(..) => fail!()
+                    Err(..) => panic!()
                 }
             }
-            Err(..) => fail!()
+            Err(..) => panic!()
         }
         rx2.recv();
     }
@@ -535,7 +535,7 @@ fn udp_clone_two_write() {
             rx.recv();
             match sock2.recv_from(buf) {
                 Ok(..) => {}
-                Err(e) => fail!("failed receive: {}", e),
+                Err(e) => panic!("failed receive: {}", e),
             }
             serv_tx.send(());
         });
@@ -612,7 +612,7 @@ fn send_to_timeout() {
             match a.send_to([0, ..4*1024], addr2) {
                 Ok(()) | Err(IoError { kind: ShortWrite(..), .. }) => {},
                 Err(IoError { kind: TimedOut, .. }) => break,
-                Err(e) => fail!("other error: {}", e),
+                Err(e) => panic!("other error: {}", e),
             }
         }
     }
index 88f8434b9576e12dcfe9fd8380bc482e40991871..36d235907046d3537072b5866de4f11e6819c93c 100644 (file)
@@ -56,7 +56,7 @@
 ///
 /// let mut child = match Command::new("/bin/cat").arg("file.txt").spawn() {
 ///     Ok(child) => child,
-///     Err(e) => fail!("failed to execute child: {}", e),
+///     Err(e) => panic!("failed to execute child: {}", e),
 /// };
 ///
 /// let contents = child.stdout.as_mut().unwrap().read_to_end();
@@ -145,7 +145,7 @@ fn eq(&self, other: &EnvKey) -> bool {
 ///
 /// let mut process = match Command::new("sh").arg("-c").arg("echo hello").spawn() {
 ///   Ok(p) => p,
-///   Err(e) => fail!("failed to execute process: {}", e),
+///   Err(e) => panic!("failed to execute process: {}", e),
 /// };
 ///
 /// let output = process.stdout.as_mut().unwrap().read_to_end();
@@ -372,7 +372,7 @@ fn to_rtio(p: StdioContainer) -> rtio::StdioContainer {
     ///
     /// let output = match Command::new("cat").arg("foot.txt").output() {
     ///     Ok(output) => output,
-    ///     Err(e) => fail!("failed to execute process: {}", e),
+    ///     Err(e) => panic!("failed to execute process: {}", e),
     /// };
     ///
     /// println!("status: {}", output.status);
@@ -393,7 +393,7 @@ pub fn output(&self) -> IoResult<ProcessOutput> {
     ///
     /// let status = match Command::new("ls").status() {
     ///     Ok(status) => status,
-    ///     Err(e) => fail!("failed to execute process: {}", e),
+    ///     Err(e) => panic!("failed to execute process: {}", e),
     /// };
     ///
     /// println!("process exited with: {}", status);
@@ -691,7 +691,7 @@ fn smoke() {
     #[test]
     fn smoke_failure() {
         match Command::new("if-this-is-a-binary-then-the-world-has-ended").spawn() {
-            Ok(..) => fail!(),
+            Ok(..) => panic!(),
             Err(..) => {}
         }
     }
@@ -714,7 +714,7 @@ fn signal_reported_right() {
         let mut p = p.unwrap();
         match p.wait().unwrap() {
             process::ExitSignal(1) => {},
-            result => fail!("not terminated by signal 1 (instead, {})", result),
+            result => panic!("not terminated by signal 1 (instead, {})", result),
         }
     }
 
@@ -815,7 +815,7 @@ fn test_process_status() {
     fn test_process_output_fail_to_start() {
         match Command::new("/no-binary-by-this-name-should-exist").output() {
             Err(e) => assert_eq!(e.kind, FileNotFound),
-            Ok(..) => fail!()
+            Ok(..) => panic!()
         }
     }
 
@@ -1063,7 +1063,7 @@ fn test_zero() {
             }
             timer::sleep(Duration::milliseconds(100));
         }
-        fail!("never saw the child go away");
+        panic!("never saw the child go away");
     }
 
     #[test]
@@ -1121,7 +1121,7 @@ fn dont_close_fd_on_command_spawn() {
 
         let mut fdes = match file::open(&path.to_c_str(), Truncate, Write) {
             Ok(f) => f,
-            Err(_) => fail!("failed to open file descriptor"),
+            Err(_) => panic!("failed to open file descriptor"),
         };
 
         let mut cmd = pwd_cmd();
index 03637079241d6cb542d4626f02ee821dd8ca76a7..40793d98ee3b893eac11d6eb10cbf81f96b4b255 100644 (file)
@@ -96,11 +96,11 @@ fn test_option_writer_error() {
             Err(io::standard_error(io::EndOfFile));
 
         match writer.write([0, 0, 0]) {
-            Ok(..) => fail!(),
+            Ok(..) => panic!(),
             Err(e) => assert_eq!(e.kind, io::EndOfFile),
         }
         match writer.flush() {
-            Ok(..) => fail!(),
+            Ok(..) => panic!(),
             Err(e) => assert_eq!(e.kind, io::EndOfFile),
         }
     }
@@ -122,7 +122,7 @@ fn test_option_reader_error() {
         let mut buf = [];
 
         match reader.read(buf) {
-            Ok(..) => fail!(),
+            Ok(..) => panic!(),
             Err(e) => assert_eq!(e.kind, io::EndOfFile),
         }
     }
index 93037f765d635c2d582e7ce2a4be1f0b2066caee..5fd4faff6d2500f75486043e230ca5703bc0560d 100644 (file)
@@ -176,8 +176,8 @@ pub fn set_stdout(stdout: Box<Writer + Send>) -> Option<Box<Writer + Send>> {
 /// Resets the task-local stderr handle to the specified writer
 ///
 /// This will replace the current task's stderr handle, returning the old
-/// handle. Currently, the stderr handle is used for printing failure messages
-/// during task failure.
+/// handle. Currently, the stderr handle is used for printing panic messages
+/// during task panic.
 ///
 /// Note that this does not need to be called for all new tasks; the default
 /// output handle is to the process's stderr stream.
@@ -212,7 +212,7 @@ fn with_task_stdout(f: |&mut Writer| -> IoResult<()>) {
     };
     match result {
         Ok(()) => {}
-        Err(e) => fail!("failed printing to stdout: {}", e),
+        Err(e) => panic!("failed printing to stdout: {}", e),
     }
 }
 
@@ -415,7 +415,7 @@ fn capture_stderr() {
         let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
         spawn(proc() {
             ::realstd::io::stdio::set_stderr(box w);
-            fail!("my special message");
+            panic!("my special message");
         });
         let s = r.read_to_string().unwrap();
         assert!(s.as_slice().contains("my special message"));
index 9b4333a6d8298753892921cb5cedc9d33971dc90..6571dc41585bb76ff55825399841dfbe090b9665 100644 (file)
@@ -139,14 +139,14 @@ pub unsafe fn raise_fd_limit() {
         if sysctl(&mut mib[0], 2, &mut maxfiles as *mut libc::c_int as *mut libc::c_void, &mut size,
                   null_mut(), 0) != 0 {
             let err = last_os_error();
-            fail!("raise_fd_limit: error calling sysctl: {}", err);
+            panic!("raise_fd_limit: error calling sysctl: {}", err);
         }
 
         // Fetch the current resource limits
         let mut rlim = rlimit{rlim_cur: 0, rlim_max: 0};
         if getrlimit(RLIMIT_NOFILE, &mut rlim) != 0 {
             let err = last_os_error();
-            fail!("raise_fd_limit: error calling getrlimit: {}", err);
+            panic!("raise_fd_limit: error calling getrlimit: {}", err);
         }
 
         // Bump the soft limit to the smaller of kern.maxfilesperproc and the hard limit
@@ -155,7 +155,7 @@ pub unsafe fn raise_fd_limit() {
         // Set our newly-increased resource limit
         if setrlimit(RLIMIT_NOFILE, &rlim) != 0 {
             let err = last_os_error();
-            fail!("raise_fd_limit: error calling setrlimit: {}", err);
+            panic!("raise_fd_limit: error calling setrlimit: {}", err);
         }
     }
 }
index a657989fe1244486b225b7f669be6d44e8ef748d..d16199da77fcdf3de982dfbe84a3aba07c9b2065 100644 (file)
@@ -340,7 +340,7 @@ fn sleep() {
     fn oneshot_fail() {
         let mut timer = Timer::new().unwrap();
         let _rx = timer.oneshot(Duration::milliseconds(1));
-        fail!();
+        panic!();
     }
 
     #[test]
@@ -348,14 +348,14 @@ fn oneshot_fail() {
     fn period_fail() {
         let mut timer = Timer::new().unwrap();
         let _rx = timer.periodic(Duration::milliseconds(1));
-        fail!();
+        panic!();
     }
 
     #[test]
     #[should_fail]
     fn normal_fail() {
         let _timer = Timer::new().unwrap();
-        fail!();
+        panic!();
     }
 
     #[test]
index 820ae931f320484a3ef7fa8caf5b60c4618d67fd..5694565b4ea6a98e7a6ab5be9bb0226bbf6b09d6 100644 (file)
@@ -265,7 +265,7 @@ fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
 
 #[cfg(test)]
 mod test {
-    use io::{MemReader, MemWriter, BufReader};
+    use io::{MemReader, MemWriter, BufReader, AsRefReader};
     use io;
     use boxed::Box;
     use super::*;
index c47cd02599485ff5b40ba14c6def549fa4a518af..5451d07ab468536355f9af84f5e17e9f5e7b78de 100644 (file)
@@ -91,7 +91,7 @@
 //! Finally, the [`prelude`](prelude/index.html) defines a
 //! common set of traits, types, and functions that are made available
 //! to all code by default. [`macros`](macros/index.html) contains
-//! all the standard macros, such as `assert!`, `fail!`, `println!`,
+//! all the standard macros, such as `assert!`, `panic!`, `println!`,
 //! and `format!`, also available to all Rust code.
 
 #![crate_name = "std"]
@@ -261,7 +261,7 @@ mod std {
     pub use io; // used for println!()
     pub use local_data; // used for local_data_key!()
     pub use option; // used for bitflags!{}
-    pub use rt; // used for fail!()
+    pub use rt; // used for panic!()
     pub use vec; // used for vec![]
 
     // The test runner calls ::std::os::args() but really wants realstd
index 1ad3d6eed942068bdb1758434ec19a37e2144749..9e0530a76f2577e197f0d72cae54264ff51dfdd6 100644 (file)
 #![experimental]
 #![macro_escape]
 
-/// The entry point for failure of rust tasks.
+/// The entry point for panic of Rust tasks.
 ///
-/// This macro is used to inject failure into a rust task, causing the task to
-/// unwind and fail entirely. Each task's failure can be reaped as the
-/// `Box<Any>` type, and the single-argument form of the `fail!` macro will be
+/// This macro is used to inject panic into a Rust task, causing the task to
+/// unwind and panic entirely. Each task's panic can be reaped as the
+/// `Box<Any>` type, and the single-argument form of the `panic!` macro will be
 /// the value which is transmitted.
 ///
-/// The multi-argument form of this macro fails with a string and has the
+/// The multi-argument form of this macro panics with a string and has the
 /// `format!` syntax for building a string.
 ///
 /// # Example
 ///
 /// ```should_fail
 /// # #![allow(unreachable_code)]
-/// fail!();
-/// fail!("this is a terrible mistake!");
-/// fail!(4i); // fail with the value of 4 to be collected elsewhere
-/// fail!("this is a {} {message}", "fancy", message = "message");
+/// panic!();
+/// panic!("this is a terrible mistake!");
+/// panic!(4i); // panic with the value of 4 to be collected elsewhere
+/// panic!("this is a {} {message}", "fancy", message = "message");
 /// ```
 #[macro_export]
-macro_rules! fail(
+macro_rules! panic(
     () => ({
-        fail!("explicit failure")
+        panic!("explicit panic")
     });
     ($msg:expr) => ({
         // static requires less code at runtime, more constant data
@@ -57,7 +57,7 @@ macro_rules! fail(
         // as returning !. We really do want this to be inlined, however,
         // because it's just a tiny wrapper. Small wins (156K to 149K in size)
         // were seen when forcing this to be inlined, and that number just goes
-        // up with the number of calls to fail!()
+        // up with the number of calls to panic!()
         //
         // The leading _'s are to avoid dead code warnings if this is
         // used inside a dead function. Just `#[allow(dead_code)]` is
@@ -74,13 +74,13 @@ fn _run_fmt(fmt: &::std::fmt::Arguments) -> ! {
 
 /// Ensure that a boolean expression is `true` at runtime.
 ///
-/// This will invoke the `fail!` macro if the provided expression cannot be
+/// This will invoke the `panic!` macro if the provided expression cannot be
 /// evaluated to `true` at runtime.
 ///
 /// # Example
 ///
 /// ```
-/// // the failure message for these assertions is the stringified value of the
+/// // the panic message for these assertions is the stringified value of the
 /// // expression given.
 /// assert!(true);
 /// # fn some_computation() -> bool { true }
@@ -96,12 +96,12 @@ fn _run_fmt(fmt: &::std::fmt::Arguments) -> ! {
 macro_rules! assert(
     ($cond:expr) => (
         if !$cond {
-            fail!(concat!("assertion failed: ", stringify!($cond)))
+            panic!(concat!("assertion failed: ", stringify!($cond)))
         }
     );
     ($cond:expr, $($arg:expr),+) => (
         if !$cond {
-            fail!($($arg),+)
+            panic!($($arg),+)
         }
     );
 )
@@ -109,7 +109,7 @@ macro_rules! assert(
 /// Asserts that two expressions are equal to each other, testing equality in
 /// both directions.
 ///
-/// On failure, this macro will print the values of the expressions.
+/// On panic, this macro will print the values of the expressions.
 ///
 /// # Example
 ///
@@ -126,7 +126,7 @@ macro_rules! assert_eq(
                 // check both directions of equality....
                 if !((*given_val == *expected_val) &&
                      (*expected_val == *given_val)) {
-                    fail!("assertion failed: `(left == right) && (right == left)` \
+                    panic!("assertion failed: `(left == right) && (right == left)` \
                            (left: `{}`, right: `{}`)", *given_val, *expected_val)
                 }
             }
@@ -136,7 +136,7 @@ macro_rules! assert_eq(
 
 /// Ensure that a boolean expression is `true` at runtime.
 ///
-/// This will invoke the `fail!` macro if the provided expression cannot be
+/// This will invoke the `panic!` macro if the provided expression cannot be
 /// evaluated to `true` at runtime.
 ///
 /// Unlike `assert!`, `debug_assert!` statements can be disabled by passing
@@ -147,7 +147,7 @@ macro_rules! assert_eq(
 /// # Example
 ///
 /// ```
-/// // the failure message for these assertions is the stringified value of the
+/// // the panic message for these assertions is the stringified value of the
 /// // expression given.
 /// debug_assert!(true);
 /// # fn some_expensive_computation() -> bool { true }
@@ -167,7 +167,7 @@ macro_rules! debug_assert(
 /// Asserts that two expressions are equal to each other, testing equality in
 /// both directions.
 ///
-/// On failure, this macro will print the values of the expressions.
+/// On panic, this macro will print the values of the expressions.
 ///
 /// Unlike `assert_eq!`, `debug_assert_eq!` statements can be disabled by
 /// passing `--cfg ndebug` to the compiler. This makes `debug_assert_eq!`
@@ -186,7 +186,7 @@ macro_rules! debug_assert_eq(
     ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert_eq!($($arg)*); })
 )
 
-/// A utility macro for indicating unreachable code. It will fail if
+/// A utility macro for indicating unreachable code. It will panic if
 /// executed. This is occasionally useful to put after loops that never
 /// terminate normally, but instead directly return from a function.
 ///
@@ -211,14 +211,14 @@ macro_rules! debug_assert_eq(
 /// ```
 #[macro_export]
 macro_rules! unreachable(
-    () => (fail!("internal error: entered unreachable code"))
+    () => (panic!("internal error: entered unreachable code"))
 )
 
-/// A standardised placeholder for marking unfinished code. It fails with the
+/// A standardised placeholder for marking unfinished code. It panics with the
 /// message `"not yet implemented"` when executed.
 #[macro_export]
 macro_rules! unimplemented(
-    () => (fail!("not yet implemented"))
+    () => (panic!("not yet implemented"))
 )
 
 /// Use the syntax described in `std::fmt` to create a value of type `String`.
index af66e6ca9349003891635ece3de9f761ec614592..6e0d81a63c951da37baf427828407f05a05a5567 100644 (file)
@@ -264,10 +264,10 @@ pub fn float_to_str_bytes_common<T:NumCast+Zero+One+PartialEq+PartialOrd+Float+
     assert!(2 <= radix && radix <= 36);
     match exp_format {
         ExpDec if radix >= DIGIT_E_RADIX       // decimal exponent 'e'
-          => fail!("float_to_str_bytes_common: radix {} incompatible with \
+          => panic!("float_to_str_bytes_common: radix {} incompatible with \
                     use of 'e' as decimal exponent", radix),
         ExpBin if radix >= DIGIT_P_RADIX       // binary exponent 'p'
-          => fail!("float_to_str_bytes_common: radix {} incompatible with \
+          => panic!("float_to_str_bytes_common: radix {} incompatible with \
                     use of 'p' as binary exponent", radix),
         _ => ()
     }
@@ -553,19 +553,19 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+PartialEq+PartialOrd+Div<T,T>+
         ) -> Option<T> {
     match exponent {
         ExpDec if radix >= DIGIT_E_RADIX       // decimal exponent 'e'
-          => fail!("from_str_bytes_common: radix {} incompatible with \
+          => panic!("from_str_bytes_common: radix {} incompatible with \
                     use of 'e' as decimal exponent", radix),
         ExpBin if radix >= DIGIT_P_RADIX       // binary exponent 'p'
-          => fail!("from_str_bytes_common: radix {} incompatible with \
+          => panic!("from_str_bytes_common: radix {} incompatible with \
                     use of 'p' as binary exponent", radix),
         _ if special && radix >= DIGIT_I_RADIX // first digit of 'inf'
-          => fail!("from_str_bytes_common: radix {} incompatible with \
+          => panic!("from_str_bytes_common: radix {} incompatible with \
                     special values 'inf' and 'NaN'", radix),
         _ if (radix as int) < 2
-          => fail!("from_str_bytes_common: radix {} to low, \
+          => panic!("from_str_bytes_common: radix {} to low, \
                     must lie in the range [2, 36]", radix),
         _ if (radix as int) > 36
-          => fail!("from_str_bytes_common: radix {} to high, \
+          => panic!("from_str_bytes_common: radix {} to high, \
                     must lie in the range [2, 36]", radix),
         _ => ()
     }
index e758dec6bff9485a2aadf63d2b3449247d166619..c7994ae84e8482f2cbf3597f1d5f54992ddbe0d0 100644 (file)
@@ -96,7 +96,7 @@ pub fn getcwd() -> Path {
     let mut buf = [0 as c_char, ..BUF_BYTES];
     unsafe {
         if libc::getcwd(buf.as_mut_ptr(), buf.len() as libc::size_t).is_null() {
-            fail!()
+            panic!()
         }
         Path::new(CString::new(buf.as_ptr(), false))
     }
@@ -130,7 +130,7 @@ pub fn getcwd() -> Path {
     let mut buf = [0 as u16, ..BUF_BYTES];
     unsafe {
         if libc::GetCurrentDirectoryW(buf.len() as DWORD, buf.as_mut_ptr()) == 0 as DWORD {
-            fail!();
+            panic!();
         }
     }
     Path::new(String::from_utf16(::str::truncate_utf16_at_nul(buf))
@@ -238,7 +238,7 @@ unsafe fn get_env_pairs() -> Vec<Vec<u8>> {
             };
             let ch = GetEnvironmentStringsW();
             if ch as uint == 0 {
-                fail!("os::env() failure getting env string from OS: {}",
+                panic!("os::env() failure getting env string from OS: {}",
                        os::last_os_error());
             }
             // Here, we lossily decode the string as UTF16.
@@ -280,7 +280,7 @@ unsafe fn get_env_pairs() -> Vec<Vec<u8>> {
             }
             let mut environ = rust_env_pairs();
             if environ as uint == 0 {
-                fail!("os::env() failure getting env string from OS: {}",
+                panic!("os::env() failure getting env string from OS: {}",
                        os::last_os_error());
             }
             let mut result = Vec::new();
@@ -1009,7 +1009,7 @@ fn __xpg_strerror_r(errnum: c_int,
         let p = buf.as_mut_ptr();
         unsafe {
             if strerror_r(errnum as c_int, p, buf.len() as libc::size_t) < 0 {
-                fail!("strerror_r failure");
+                panic!("strerror_r failure");
             }
 
             ::string::raw::from_buf(p as *const u8)
@@ -1079,9 +1079,9 @@ pub fn last_os_error() -> String {
  * Sets the process exit code
  *
  * Sets the exit code returned by the process if all supervised tasks
- * terminate successfully (without failing). If the current root task fails
+ * terminate successfully (without panicking). If the current root task panics
  * and is supervised by the scheduler then any user-specified exit status is
- * ignored and the process exits with the default failure status.
+ * ignored and the process exits with the default panic status.
  *
  * Note that this is not synchronized against modifications of other threads.
  */
@@ -1185,7 +1185,7 @@ fn real_args_as_bytes() -> Vec<Vec<u8>> {
 
     match rt::args::clone() {
         Some(args) => args,
-        None => fail!("process arguments not initialized")
+        None => panic!("process arguments not initialized")
     }
 }
 
@@ -1511,12 +1511,12 @@ pub fn granularity() -> uint {
 
 #[cfg(unix)]
 impl Drop for MemoryMap {
-    /// Unmap the mapping. Fails the task if `munmap` fails.
+    /// Unmap the mapping. Panics the task if `munmap` panics.
     fn drop(&mut self) {
         if self.len == 0 { /* workaround for dummy_stack */ return; }
 
         unsafe {
-            // `munmap` only fails due to logic errors
+            // `munmap` only panics due to logic errors
             libc::munmap(self.data as *mut c_void, self.len as libc::size_t);
         }
     }
@@ -2098,7 +2098,7 @@ fn memory_map_rw() {
             os::MapWritable
         ]) {
             Ok(chunk) => chunk,
-            Err(msg) => fail!("{}", msg)
+            Err(msg) => panic!("{}", msg)
         };
         assert!(chunk.len >= 16);
 
@@ -2147,7 +2147,7 @@ fn lseek_(fd: c_int, size: uint) {
             MapOffset(size / 2)
         ]) {
             Ok(chunk) => chunk,
-            Err(msg) => fail!("{}", msg)
+            Err(msg) => panic!("{}", msg)
         };
         assert!(chunk.len > 0);
 
index 69b6dd76676168a3bf4a3b1787b1e4b658190fbb..f27a1c1fedad417584b37b00986b461914560b48 100644 (file)
@@ -367,7 +367,7 @@ pub fn new_opt<T: BytesContainer>(path: T) -> Option<Path> {
 
     /// Returns a normalized byte vector representation of a path, by removing all empty
     /// components, and unnecessary . and .. components.
-    fn normalize<V: AsSlice<u8>+CloneableVector<u8>>(v: V) -> Vec<u8> {
+    fn normalize<V: AsSlice<u8>>(v: V) -> Vec<u8> {
         // borrowck is being very picky
         let val = {
             let is_abs = !v.as_slice().is_empty() && v.as_slice()[0] == SEP_BYTE;
index 4456cf96094285dd89297676e0b2638f856e7e23..1897c8638cc69e3c4a68e4b174ebefbf0e450df8 100644 (file)
@@ -1343,7 +1343,7 @@ fn test_null_byte() {
 
     #[test]
     #[should_fail]
-    fn test_not_utf8_fail() {
+    fn test_not_utf8_panics() {
         Path::new(b"hello\x80.txt");
     }
 
index db9f3114cda14b255dabaf4638fa51b1dd46fc44..48be404b0d02a88ffdbf049b0d79ed54a97555fc 100644 (file)
@@ -76,7 +76,7 @@
 #[doc(no_inline)] pub use num::{FloatMath, ToPrimitive, FromPrimitive};
 #[doc(no_inline)] pub use boxed::Box;
 #[doc(no_inline)] pub use path::{GenericPath, Path, PosixPath, WindowsPath};
-#[doc(no_inline)] pub use ptr::RawPtr;
+#[doc(no_inline)] pub use ptr::{RawPtr, RawMutPtr};
 #[doc(no_inline)] pub use io::{Buffer, Writer, Reader, Seek};
 #[doc(no_inline)] pub use str::{Str, StrVector, StrSlice};
 #[doc(no_inline)] pub use str::{IntoMaybeOwned, StrAllocating, UnicodeStrSlice};
index 29eae0ced5412d0663ab53407edd89839748b011..d1c655cb4d0bb1186cea212a2856b182fee5a7e9 100644 (file)
@@ -297,7 +297,7 @@ fn from_seed(seed: &'a [uint]) -> StdRng {
 pub fn weak_rng() -> XorShiftRng {
     match OsRng::new() {
         Ok(mut r) => r.gen(),
-        Err(e) => fail!("weak_rng: failed to create seeded RNG: {}", e)
+        Err(e) => panic!("weak_rng: failed to create seeded RNG: {}", e)
     }
 }
 
@@ -308,7 +308,7 @@ impl reseeding::Reseeder<StdRng> for TaskRngReseeder {
     fn reseed(&mut self, rng: &mut StdRng) {
         *rng = match StdRng::new() {
             Ok(r) => r,
-            Err(e) => fail!("could not reseed task_rng: {}", e)
+            Err(e) => panic!("could not reseed task_rng: {}", e)
         }
     }
 }
@@ -339,7 +339,7 @@ pub fn task_rng() -> TaskRng {
         None => {
             let r = match StdRng::new() {
                 Ok(r) => r,
-                Err(e) => fail!("could not initialize task_rng: {}", e)
+                Err(e) => panic!("could not initialize task_rng: {}", e)
             };
             let rng = reseeding::ReseedingRng::new(r,
                                                    TASK_RNG_RESEED_THRESHOLD,
@@ -445,7 +445,7 @@ fn test_fill_bytes_default() {
             // use this to get nicer error messages.
             for (i, &byte) in v.iter().enumerate() {
                 if byte == 0 {
-                    fail!("byte {} of {} is zero", i, n)
+                    panic!("byte {} of {} is zero", i, n)
                 }
             }
         }
@@ -472,14 +472,14 @@ fn test_gen_range() {
 
     #[test]
     #[should_fail]
-    fn test_gen_range_fail_int() {
+    fn test_gen_range_panic_int() {
         let mut r = task_rng();
         r.gen_range(5i, -2);
     }
 
     #[test]
     #[should_fail]
-    fn test_gen_range_fail_uint() {
+    fn test_gen_range_panic_uint() {
         let mut r = task_rng();
         r.gen_range(5u, 2u);
     }
index 91308be21edbd6905ca61676e5f531a8734714f0..424fd039fd4c45f8f0dbc8b0d39f23d34c972fba 100644 (file)
@@ -120,7 +120,7 @@ fn fill_bytes(&mut self, v: &mut [u8]) {
                 SecRandomCopyBytes(kSecRandomDefault, v.len() as size_t, v.as_mut_ptr())
             };
             if ret == -1 {
-                fail!("couldn't generate random bytes: {}", os::last_os_error());
+                panic!("couldn't generate random bytes: {}", os::last_os_error());
             }
         }
     }
@@ -208,7 +208,7 @@ fn fill_bytes(&mut self, v: &mut [u8]) {
                                v.as_mut_ptr())
             };
             if ret == 0 {
-                fail!("couldn't generate random bytes: {}", os::last_os_error());
+                panic!("couldn't generate random bytes: {}", os::last_os_error());
             }
         }
     }
@@ -219,7 +219,7 @@ fn drop(&mut self) {
                 CryptReleaseContext(self.hcryptprov, 0)
             };
             if ret == 0 {
-                fail!("couldn't release context: {}", os::last_os_error());
+                panic!("couldn't release context: {}", os::last_os_error());
             }
         }
     }
index 8ca1cec3e0ae9675a16ef8aaa02dba8308d969bd..4f2205312373c20b0d9141520b9f52af743dda44 100644 (file)
@@ -18,7 +18,9 @@
 /// An RNG that reads random bytes straight from a `Reader`. This will
 /// work best with an infinite reader, but this is not required.
 ///
-/// It will fail if it there is insufficient data to fulfill a request.
+/// # Panics
+///
+/// It will panic if it there is insufficient data to fulfill a request.
 ///
 /// # Example
 ///
@@ -65,7 +67,7 @@ fn fill_bytes(&mut self, v: &mut [u8]) {
         if v.len() == 0 { return }
         match self.reader.read_at_least(v.len(), v) {
             Ok(_) => {}
-            Err(e) => fail!("ReaderRng.fill_bytes error: {}", e)
+            Err(e) => panic!("ReaderRng.fill_bytes error: {}", e)
         }
     }
 }
index e05e533be56c572aaa5931fe36049b07c9471a97..5bd3927727574ff3b56eb39fa70bf6a436559824 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Simple backtrace functionality (to print on failure)
+//! Simple backtrace functionality (to print on panic)
 
 #![allow(non_camel_case_types)]
 
@@ -265,7 +265,7 @@ fn backtrace(buf: *mut *mut libc::c_void,
 
         // while it doesn't requires lock for work as everything is
         // local, it still displays much nicer backtraces when a
-        // couple of tasks fail simultaneously
+        // couple of tasks panic simultaneously
         static LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
         let _g = unsafe { LOCK.lock() };
 
@@ -327,7 +327,7 @@ struct Context<'a> {
             // FindEnclosingFunction on non-osx platforms. In doing so, we get a
             // slightly more accurate stack trace in the process.
             //
-            // This is often because failure involves the last instruction of a
+            // This is often because panic involves the last instruction of a
             // function being "call std::rt::begin_unwind", with no ret
             // instructions after it. This means that the return instruction
             // pointer points *outside* of the calling function, and by
index a91c6c572e686c0f8ff073b342846f8c3a9b08ce..e36d4ce8d4b7414b140c85bdf53bfa9922e985dd 100644 (file)
@@ -67,7 +67,7 @@
 pub use rustrt::{Stdio, Stdout, Stderr, begin_unwind, begin_unwind_fmt};
 pub use rustrt::{bookkeeping, at_exit, unwind, DEFAULT_ERROR_CODE, Runtime};
 
-// Simple backtrace functionality (to print on failure)
+// Simple backtrace functionality (to print on panic)
 pub mod backtrace;
 
 // Just stuff
index ec301369804ed78f30d4286e548440a489470521..56f2dbf667a7c30680aab7af33acd92be95240a6 100644 (file)
@@ -62,7 +62,7 @@ pub fn default_sched_threads() -> uint {
             let opt_n: Option<uint> = FromStr::from_str(nstr.as_slice());
             match opt_n {
                 Some(n) if n > 0 => n,
-                _ => fail!("`RUST_THREADS` is `{}`, should be a positive integer", nstr)
+                _ => panic!("`RUST_THREADS` is `{}`, should be a positive integer", nstr)
             }
         }
         None => {
index 621c08fe7bcc0bc68da5838ff632bfe9cbef10c8..3607050943270db02c37deacaa19ef294d30d815 100644 (file)
@@ -58,7 +58,7 @@ pub fn unwrap(mut self) -> A {
         let state = replace(&mut self.state, Evaluating);
         match state {
             Forced(v) => v,
-            _ => fail!( "Logic error." ),
+            _ => panic!( "Logic error." ),
         }
     }
 
@@ -70,10 +70,10 @@ pub fn get_ref<'a>(&'a mut self) -> &'a A {
         */
         match self.state {
             Forced(ref v) => return v,
-            Evaluating => fail!("Recursive forcing of future!"),
+            Evaluating => panic!("Recursive forcing of future!"),
             Pending(_) => {
                 match replace(&mut self.state, Evaluating) {
-                    Forced(_) | Evaluating => fail!("Logic error."),
+                    Forced(_) | Evaluating => panic!("Logic error."),
                     Pending(f) => {
                         self.state = Forced(f());
                         self.get_ref()
@@ -132,7 +132,7 @@ pub fn spawn(blk: proc():Send -> A) -> Future<A> {
         let (tx, rx) = channel();
 
         spawn(proc() {
-            // Don't fail if the other end has hung up
+            // Don't panic if the other end has hung up
             let _ = tx.send_opt(blk());
         });
 
@@ -193,8 +193,8 @@ fn test_spawn() {
 
     #[test]
     #[should_fail]
-    fn test_futurefail() {
-        let mut f = Future::spawn(proc() fail!());
+    fn test_future_panic() {
+        let mut f = Future::spawn(proc() panic!());
         let _x: String = f.get();
     }
 
@@ -211,7 +211,7 @@ fn test_sendable_future() {
     }
 
     #[test]
-    fn test_dropped_future_doesnt_fail() {
+    fn test_dropped_future_doesnt_panic() {
         struct Bomb(Sender<bool>);
 
         local_data_key!(LOCAL: Bomb)
@@ -224,13 +224,13 @@ fn drop(&mut self) {
         }
 
         // Spawn a future, but drop it immediately. When we receive the result
-        // later on, we should never view the task as having failed.
+        // later on, we should never view the task as having panicked.
         let (tx, rx) = channel();
         drop(Future::spawn(proc() {
             LOCAL.replace(Some(Bomb(tx)));
         }));
 
-        // Make sure the future didn't fail the task.
+        // Make sure the future didn't panic the task.
         assert!(!rx.recv());
     }
 }
index a00eeb1f938389afb640722cf94cf25abbec8ba4..d4a60fb584457e90088b73fa9739837af669d3ef 100644 (file)
@@ -42,9 +42,9 @@ impl<T> TaskPool<T> {
     /// `init_fn_factory` returns a function which, given the index of the
     /// task, should return local data to be kept around in that task.
     ///
-    /// # Failure
+    /// # Panics
     ///
-    /// This function will fail if `n_tasks` is less than 1.
+    /// This function will panic if `n_tasks` is less than 1.
     pub fn new(n_tasks: uint,
                init_fn_factory: || -> proc(uint):Send -> T)
                -> TaskPool<T> {
@@ -96,7 +96,7 @@ fn test_task_pool() {
 
 #[test]
 #[should_fail]
-fn test_zero_tasks_failure() {
+fn test_zero_tasks_panic() {
     let f: || -> proc(uint):Send -> uint = || { proc(i) i };
     TaskPool::new(0, f);
 }
index 1d1e6ae4febfdc8f8ffb514c41a8ca83b8d8bc62..c79b8715c06c2757ade5974950b6c4a773499fb7 100644 (file)
 //! using the atomically-reference-counted container,
 //! [`Arc`](../../std/sync/struct.Arc.html).
 //!
-//! Fatal logic errors in Rust cause *task failure*, during which
+//! Fatal logic errors in Rust cause *task panic*, during which
 //! a task will unwind the stack, running destructors and freeing
-//! owned resources. Task failure is unrecoverable from within
-//! the failing task (i.e. there is no 'try/catch' in Rust), but
-//! failure may optionally be detected from a different task. If
-//! the main task fails the application will exit with a non-zero
+//! owned resources. Task panic is unrecoverable from within
+//! the panicking task (i.e. there is no 'try/catch' in Rust), but
+//! panic may optionally be detected from a different task. If
+//! the main task panics the application will exit with a non-zero
 //! exit code.
 //!
 //! # Basic task scheduling
@@ -123,7 +123,7 @@ fn spawn(self, opts: task::TaskOpts, f: proc():Send) {
         let tb: Option<Box<Task>> = Local::try_take();
         match tb {
             Some(t) => t.spawn_sibling(opts, f),
-            None => fail!("need a local task to spawn a sibling task"),
+            None => panic!("need a local task to spawn a sibling task"),
         };
     }
 }
@@ -140,7 +140,7 @@ fn spawn(self, opts: task::TaskOpts, f: proc():Send) {
 // sidestep that whole issue by making builders uncopyable and making
 // the run function move them in.
 pub struct TaskBuilder<S = SiblingSpawner> {
-    // A name for the task-to-be, for identification in failure messages
+    // A name for the task-to-be, for identification in panic messages
     name: Option<SendStr>,
     // The size of the stack for the spawned task
     stack_size: Option<uint>,
@@ -173,7 +173,7 @@ pub fn new() -> TaskBuilder<SiblingSpawner> {
 
 impl<S: Spawner> TaskBuilder<S> {
     /// Name the task-to-be. Currently the name is used for identification
-    /// only in failure messages.
+    /// only in panic messages.
     #[unstable = "IntoMaybeOwned will probably change."]
     pub fn named<T: IntoMaybeOwned<'static>>(mut self, name: T) -> TaskBuilder<S> {
         self.name = Some(name.into_maybe_owned());
@@ -269,10 +269,10 @@ pub fn spawn(self, f: proc():Send) {
     ///
     /// # Return value
     ///
-    /// If the child task executes successfully (without failing) then the
+    /// If the child task executes successfully (without panicking) then the
     /// future returns `result::Ok` containing the value returned by the
-    /// function. If the child task fails then the future returns `result::Err`
-    /// containing the argument to `fail!(...)` as an `Any` trait object.
+    /// function. If the child task panics then the future returns `result::Err`
+    /// containing the argument to `panic!(...)` as an `Any` trait object.
     #[experimental = "Futures are experimental."]
     pub fn try_future<T:Send>(self, f: proc():Send -> T)
                               -> Future<Result<T, Box<Any + Send>>> {
@@ -293,7 +293,7 @@ pub fn try_future<T:Send>(self, f: proc():Send -> T)
     }
 
     /// Execute a function in a newly-spawnedtask and block until the task
-    /// completes or fails. Equivalent to `.try_future(f).unwrap()`.
+    /// completes or panics. Equivalent to `.try_future(f).unwrap()`.
     #[unstable = "Error type may change."]
     pub fn try<T:Send>(self, f: proc():Send -> T) -> Result<T, Box<Any + Send>> {
         self.try_future(f).unwrap()
@@ -313,7 +313,7 @@ pub fn spawn(f: proc(): Send) {
 }
 
 /// Execute a function in a newly-spawned task and return either the return
-/// value of the function or an error if the task failed.
+/// value of the function or an error if the task panicked.
 ///
 /// This is equivalent to `TaskBuilder::new().try`.
 #[unstable = "Error type may change."]
@@ -355,8 +355,8 @@ pub fn deschedule() {
     task.yield_now();
 }
 
-/// True if the running task is currently failing (e.g. will return `true` inside a
-/// destructor that is run while unwinding the stack after a call to `fail!()`).
+/// True if the running task is currently panicking (e.g. will return `true` inside a
+/// destructor that is run while unwinding the stack after a call to `panic!()`).
 #[unstable = "May move to a different module."]
 pub fn failing() -> bool {
     use rt::task::Task;
@@ -420,7 +420,7 @@ fn test_try_future() {
         assert!(result.unwrap().is_ok());
 
         let result = TaskBuilder::new().try_future(proc() -> () {
-            fail!();
+            panic!();
         });
         assert!(result.unwrap().is_err());
     }
@@ -431,17 +431,17 @@ fn test_try_success() {
             "Success!".to_string()
         }).as_ref().map(|s| s.as_slice()) {
             result::Ok("Success!") => (),
-            _ => fail!()
+            _ => panic!()
         }
     }
 
     #[test]
-    fn test_try_fail() {
+    fn test_try_panic() {
         match try(proc() {
-            fail!()
+            panic!()
         }) {
             result::Err(_) => (),
-            result::Ok(()) => fail!()
+            result::Ok(()) => panic!()
         }
     }
 
@@ -541,37 +541,37 @@ fn test_simple_newsched_spawn() {
     }
 
     #[test]
-    fn test_try_fail_message_static_str() {
+    fn test_try_panic_message_static_str() {
         match try(proc() {
-            fail!("static string");
+            panic!("static string");
         }) {
             Err(e) => {
                 type T = &'static str;
                 assert!(e.is::<T>());
                 assert_eq!(*e.downcast::<T>().unwrap(), "static string");
             }
-            Ok(()) => fail!()
+            Ok(()) => panic!()
         }
     }
 
     #[test]
-    fn test_try_fail_message_owned_str() {
+    fn test_try_panic_message_owned_str() {
         match try(proc() {
-            fail!("owned string".to_string());
+            panic!("owned string".to_string());
         }) {
             Err(e) => {
                 type T = String;
                 assert!(e.is::<T>());
                 assert_eq!(*e.downcast::<T>().unwrap(), "owned string".to_string());
             }
-            Ok(()) => fail!()
+            Ok(()) => panic!()
         }
     }
 
     #[test]
-    fn test_try_fail_message_any() {
+    fn test_try_panic_message_any() {
         match try(proc() {
-            fail!(box 413u16 as Box<Any + Send>);
+            panic!(box 413u16 as Box<Any + Send>);
         }) {
             Err(e) => {
                 type T = Box<Any + Send>;
@@ -580,19 +580,19 @@ fn test_try_fail_message_any() {
                 assert!(any.is::<u16>());
                 assert_eq!(*any.downcast::<u16>().unwrap(), 413u16);
             }
-            Ok(()) => fail!()
+            Ok(()) => panic!()
         }
     }
 
     #[test]
-    fn test_try_fail_message_unit_struct() {
+    fn test_try_panic_message_unit_struct() {
         struct Juju;
 
         match try(proc() {
-            fail!(Juju)
+            panic!(Juju)
         }) {
             Err(ref e) if e.is::<Juju>() => {}
-            Err(_) | Ok(()) => fail!()
+            Err(_) | Ok(()) => panic!()
         }
     }
 
index 751eb00bfaeccf65add80c63bd92f7de3bebba80..102f002855762b6b1e7b3ae717309ff884dfe5be 100644 (file)
@@ -107,7 +107,7 @@ pub fn minutes(minutes: i64) -> Duration {
     pub fn seconds(seconds: i64) -> Duration {
         let d = Duration { secs: seconds, nanos: 0 };
         if d < MIN || d > MAX {
-            fail!("Duration::seconds out of bounds");
+            panic!("Duration::seconds out of bounds");
         }
         d
     }
@@ -317,26 +317,29 @@ fn div(&self, rhs: &i32) -> Duration {
 
 impl fmt::Show for Duration {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        let days = self.num_days();
-        let secs = self.secs - days * SECS_PER_DAY;
+        // technically speaking, negative duration is not valid ISO 8601,
+        // but we need to print it anyway.
+        let (abs, sign) = if self.secs < 0 { (-self, "-") } else { (*self, "") };
+
+        let days = abs.secs / SECS_PER_DAY;
+        let secs = abs.secs - days * SECS_PER_DAY;
         let hasdate = days != 0;
-        let hastime = (secs != 0 || self.nanos != 0) || !hasdate;
+        let hastime = (secs != 0 || abs.nanos != 0) || !hasdate;
+
+        try!(write!(f, "{}P", sign));
 
-        try!(write!(f, "P"));
         if hasdate {
-            // technically speaking the negative part is not the valid ISO 8601,
-            // but we need to print it anyway.
             try!(write!(f, "{}D", days));
         }
         if hastime {
-            if self.nanos == 0 {
+            if abs.nanos == 0 {
                 try!(write!(f, "T{}S", secs));
-            } else if self.nanos % NANOS_PER_MILLI == 0 {
-                try!(write!(f, "T{}.{:03}S", secs, self.nanos / NANOS_PER_MILLI));
-            } else if self.nanos % NANOS_PER_MICRO == 0 {
-                try!(write!(f, "T{}.{:06}S", secs, self.nanos / NANOS_PER_MICRO));
+            } else if abs.nanos % NANOS_PER_MILLI == 0 {
+                try!(write!(f, "T{}.{:03}S", secs, abs.nanos / NANOS_PER_MILLI));
+            } else if abs.nanos % NANOS_PER_MICRO == 0 {
+                try!(write!(f, "T{}.{:06}S", secs, abs.nanos / NANOS_PER_MICRO));
             } else {
-                try!(write!(f, "T{}.{:09}S", secs, self.nanos));
+                try!(write!(f, "T{}.{:09}S", secs, abs.nanos));
             }
         }
         Ok(())
@@ -540,13 +543,15 @@ fn test_duration_fmt() {
         let d: Duration = Zero::zero();
         assert_eq!(d.to_string(), "PT0S".to_string());
         assert_eq!(Duration::days(42).to_string(), "P42D".to_string());
-        assert_eq!(Duration::days(-42).to_string(), "P-42D".to_string());
+        assert_eq!(Duration::days(-42).to_string(), "-P42D".to_string());
         assert_eq!(Duration::seconds(42).to_string(), "PT42S".to_string());
         assert_eq!(Duration::milliseconds(42).to_string(), "PT0.042S".to_string());
         assert_eq!(Duration::microseconds(42).to_string(), "PT0.000042S".to_string());
         assert_eq!(Duration::nanoseconds(42).to_string(), "PT0.000000042S".to_string());
         assert_eq!((Duration::days(7) + Duration::milliseconds(6543)).to_string(),
                    "P7DT6.543S".to_string());
+        assert_eq!(Duration::seconds(-86401).to_string(), "-P1DT1S".to_string());
+        assert_eq!(Duration::nanoseconds(-1).to_string(), "-PT0.000000001S".to_string());
 
         // the format specifier should have no effect on `Duration`
         assert_eq!(format!("{:30}", Duration::days(1) + Duration::milliseconds(2345)),
index ddfd1088a41a844e8537b8074f8811796dc8c9e7..247f50d666e1402000ba4a3bcec7f49262f96576 100644 (file)
 //! ## Failure Propagation
 //!
 //! In addition to being a core primitive for communicating in rust, channels
-//! are the points at which failure is propagated among tasks.  Whenever the one
+//! are the points at which panics are propagated among tasks.  Whenever the one
 //! half of channel is closed, the other half will have its next operation
-//! `fail!`. The purpose of this is to allow propagation of failure among tasks
+//! `panic!`. The purpose of this is to allow propagation of panics among tasks
 //! that are linked to one another via channels.
 //!
 //! There are methods on both of senders and receivers to perform their
-//! respective operations without failing, however.
+//! respective operations without panicking, however.
 //!
 //! ## Runtime Requirements
 //!
 //! }
 //! ```
 //!
-//! Propagating failure:
+//! Propagating panics:
 //!
 //! ```should_fail
-//! // The call to recv() will fail!() because the channel has already hung
+//! // The call to recv() will panic!() because the channel has already hung
 //! // up (or been deallocated)
 //! let (tx, rx) = channel::<int>();
 //! drop(tx);
@@ -506,7 +506,7 @@ pub fn channel<T: Send>() -> (Sender<T>, Receiver<T>) {
 /// becomes  "rendezvous channel" where each send will not return until a recv
 /// is paired with it.
 ///
-/// As with asynchronous channels, all senders will fail in `send` if the
+/// As with asynchronous channels, all senders will panic in `send` if the
 /// `Receiver` has been destroyed.
 ///
 /// # Example
@@ -550,25 +550,25 @@ fn new(inner: Flavor<T>) -> Sender<T> {
     ///
     /// Rust channels are infinitely buffered so this method will never block.
     ///
-    /// # Failure
+    /// # Panics
     ///
-    /// This function will fail if the other end of the channel has hung up.
+    /// This function will panic if the other end of the channel has hung up.
     /// This means that if the corresponding receiver has fallen out of scope,
-    /// this function will trigger a fail message saying that a message is
+    /// this function will trigger a panic message saying that a message is
     /// being sent on a closed channel.
     ///
-    /// Note that if this function does *not* fail, it does not mean that the
+    /// Note that if this function does *not* panic, it does not mean that the
     /// data will be successfully received. All sends are placed into a queue,
     /// so it is possible for a send to succeed (the other end is alive), but
     /// then the other end could immediately disconnect.
     ///
-    /// The purpose of this functionality is to propagate failure among tasks.
-    /// If failure is not desired, then consider using the `send_opt` method
+    /// The purpose of this functionality is to propagate panicks among tasks.
+    /// If a panic is not desired, then consider using the `send_opt` method
     #[experimental = "this function is being considered candidate for removal \
                       to adhere to the general guidelines of rust"]
     pub fn send(&self, t: T) {
         if self.send_opt(t).is_err() {
-            fail!("sending on a closed channel");
+            panic!("sending on a closed channel");
         }
     }
 
@@ -585,9 +585,9 @@ pub fn send(&self, t: T) {
     ///
     /// Like `send`, this method will never block.
     ///
-    /// # Failure
+    /// # Panics
     ///
-    /// This method will never fail, it will return the message back to the
+    /// This method will never panic, it will return the message back to the
     /// caller if the other end is disconnected
     ///
     /// # Example
@@ -634,7 +634,7 @@ pub fn send_opt(&self, t: T) -> Result<(), T> {
                             }
                             oneshot::UpDisconnected => (a, Err(t)),
                             oneshot::UpWoke(task) => {
-                                // This send cannot fail because the task is
+                                // This send cannot panic because the task is
                                 // asleep (we're looking at it), so the receiver
                                 // can't go away.
                                 (*a.get()).send(t).ok().unwrap();
@@ -731,20 +731,20 @@ fn new(inner: Arc<UnsafeCell<sync::Packet<T>>>) -> SyncSender<T> {
     /// time. If the buffer size is 0, however, it can be guaranteed that the
     /// receiver has indeed received the data if this function returns success.
     ///
-    /// # Failure
+    /// # Panics
     ///
-    /// Similarly to `Sender::send`, this function will fail if the
+    /// Similarly to `Sender::send`, this function will panic if the
     /// corresponding `Receiver` for this channel has disconnected. This
-    /// behavior is used to propagate failure among tasks.
+    /// behavior is used to propagate panics among tasks.
     ///
-    /// If failure is not desired, you can achieve the same semantics with the
-    /// `SyncSender::send_opt` method which will not fail if the receiver
+    /// If a panic is not desired, you can achieve the same semantics with the
+    /// `SyncSender::send_opt` method which will not panic if the receiver
     /// disconnects.
     #[experimental = "this function is being considered candidate for removal \
                       to adhere to the general guidelines of rust"]
     pub fn send(&self, t: T) {
         if self.send_opt(t).is_err() {
-            fail!("sending on a closed channel");
+            panic!("sending on a closed channel");
         }
     }
 
@@ -756,9 +756,9 @@ pub fn send(&self, t: T) {
     /// is returned back to the callee. This function is similar to `try_send`,
     /// except that it will block if the channel is currently full.
     ///
-    /// # Failure
+    /// # Panics
     ///
-    /// This function cannot fail.
+    /// This function cannot panic.
     #[unstable = "this function may be renamed to send() in the future"]
     pub fn send_opt(&self, t: T) -> Result<(), T> {
         unsafe { (*self.inner.get()).send(t) }
@@ -774,9 +774,9 @@ pub fn send_opt(&self, t: T) -> Result<(), T> {
     /// See `SyncSender::send` for notes about guarantees of whether the
     /// receiver has received the data or not if this function is successful.
     ///
-    /// # Failure
+    /// # Panics
     ///
-    /// This function cannot fail
+    /// This function cannot panic
     #[unstable = "the return type of this function is candidate for \
                   modification"]
     pub fn try_send(&self, t: T) -> Result<(), TrySendError<T>> {
@@ -814,13 +814,13 @@ fn new(inner: Flavor<T>) -> Receiver<T> {
     /// on the channel from its paired `Sender` structure. This receiver will
     /// be woken up when data is ready, and the data will be returned.
     ///
-    /// # Failure
+    /// # Panics
     ///
-    /// Similar to channels, this method will trigger a task failure if the
+    /// Similar to channels, this method will trigger a task panic if the
     /// other end of the channel has hung up (been deallocated). The purpose of
-    /// this is to propagate failure among tasks.
+    /// this is to propagate panicks among tasks.
     ///
-    /// If failure is not desired, then there are two options:
+    /// If a panic is not desired, then there are two options:
     ///
     /// * If blocking is still desired, the `recv_opt` method will return `None`
     ///   when the other end hangs up
@@ -832,7 +832,7 @@ fn new(inner: Flavor<T>) -> Receiver<T> {
     pub fn recv(&self) -> T {
         match self.recv_opt() {
             Ok(t) => t,
-            Err(()) => fail!("receiving on a closed channel"),
+            Err(()) => panic!("receiving on a closed channel"),
         }
     }
 
@@ -845,7 +845,9 @@ pub fn recv(&self) -> T {
     /// This is useful for a flavor of "optimistic check" before deciding to
     /// block on a receiver.
     ///
-    /// This function cannot fail.
+    /// # Panics
+    ///
+    /// This function cannot panic.
     #[unstable = "the return type of this function may be altered"]
     pub fn try_recv(&self) -> Result<T, TryRecvError> {
         // If a thread is spinning in try_recv, we should take the opportunity
@@ -899,15 +901,15 @@ pub fn try_recv(&self) -> Result<T, TryRecvError> {
         }
     }
 
-    /// Attempt to wait for a value on this receiver, but does not fail if the
+    /// Attempt to wait for a value on this receiver, but does not panic if the
     /// corresponding channel has hung up.
     ///
     /// This implementation of iterators for ports will always block if there is
-    /// not data available on the receiver, but it will not fail in the case
+    /// not data available on the receiver, but it will not panic in the case
     /// that the channel has been deallocated.
     ///
     /// In other words, this function has the same semantics as the `recv`
-    /// method except for the failure aspect.
+    /// method except for the panic aspect.
     ///
     /// If the channel has hung up, then `Err` is returned. Otherwise `Ok` of
     /// the value found on the receiver is returned.
@@ -947,7 +949,7 @@ pub fn recv_opt(&self) -> Result<T, ()> {
     }
 
     /// Returns an iterator which will block waiting for messages, but never
-    /// `fail!`. It will return `None` when the channel has hung up.
+    /// `panic!`. It will return `None` when the channel has hung up.
     #[unstable]
     pub fn iter<'a>(&'a self) -> Messages<'a, T> {
         Messages { rx: self }
@@ -1191,7 +1193,7 @@ pub fn stress_factor() -> uint {
                 assert_eq!(rx.recv(), 1);
             }
             match rx.try_recv() {
-                Ok(..) => fail!(),
+                Ok(..) => panic!(),
                 _ => {}
             }
             dtx.send(());
@@ -1287,7 +1289,7 @@ fn no_runtime() {
     } #[should_fail])
 
     test!(fn oneshot_single_thread_recv_chan_close() {
-        // Receiving on a closed chan will fail
+        // Receiving on a closed chan will panic
         let res = task::try(proc() {
             let (tx, rx) = channel::<int>();
             drop(tx);
@@ -1711,7 +1713,7 @@ pub fn stress_factor() -> uint {
                 assert_eq!(rx.recv(), 1);
             }
             match rx.try_recv() {
-                Ok(..) => fail!(),
+                Ok(..) => panic!(),
                 _ => {}
             }
             dtx.send(());
@@ -1747,7 +1749,7 @@ pub fn stress_factor() -> uint {
     } #[should_fail])
 
     test!(fn oneshot_single_thread_recv_chan_close() {
-        // Receiving on a closed chan will fail
+        // Receiving on a closed chan will panic
         let res = task::try(proc() {
             let (tx, rx) = sync_channel::<int>(0);
             drop(tx);
index 053b5dc4c8a7478454cefee3514d9543857597fa..447585fb2e08760cf905a8fb5505cdcb20abbe8e 100644 (file)
@@ -94,7 +94,7 @@ pub fn send(&mut self, t: T) -> Result<(), T> {
         // Sanity check
         match self.upgrade {
             NothingSent => {}
-            _ => fail!("sending on a oneshot that's already sent on "),
+            _ => panic!("sending on a oneshot that's already sent on "),
         }
         assert!(self.data.is_none());
         self.data = Some(t);
@@ -203,7 +203,7 @@ pub fn upgrade(&mut self, up: Receiver<T>) -> UpgradeResult {
         let prev = match self.upgrade {
             NothingSent => NothingSent,
             SendUsed => SendUsed,
-            _ => fail!("upgrading again"),
+            _ => panic!("upgrading again"),
         };
         self.upgrade = GoUp(up);
 
index 669c1c958b8842461f410a1337b9e2d13e9c888a..f826664308429128fca793331e6e656bd90c5931 100644 (file)
@@ -102,7 +102,7 @@ pub trait Packet {
 
 impl Select {
     /// Creates a new selection structure. This set is initially empty and
-    /// `wait` will fail!() if called.
+    /// `wait` will panic!() if called.
     ///
     /// Usage of this struct directly can sometimes be burdensome, and usage is
     /// rather much easier through the `select!` macro.
@@ -353,17 +353,17 @@ macro_rules! select {
         tx1.send(1);
         select! (
             foo = rx1.recv() => { assert_eq!(foo, 1); },
-            _bar = rx2.recv() => { fail!() }
+            _bar = rx2.recv() => { panic!() }
         )
         tx2.send(2);
         select! (
-            _foo = rx1.recv() => { fail!() },
+            _foo = rx1.recv() => { panic!() },
             bar = rx2.recv() => { assert_eq!(bar, 2) }
         )
         drop(tx1);
         select! (
             foo = rx1.recv_opt() => { assert_eq!(foo, Err(())); },
-            _bar = rx2.recv() => { fail!() }
+            _bar = rx2.recv() => { panic!() }
         )
         drop(tx2);
         select! (
@@ -379,10 +379,10 @@ macro_rules! select {
         let (tx5, rx5) = channel::<int>();
         tx5.send(4);
         select! (
-            _foo = rx1.recv() => { fail!("1") },
-            _foo = rx2.recv() => { fail!("2") },
-            _foo = rx3.recv() => { fail!("3") },
-            _foo = rx4.recv() => { fail!("4") },
+            _foo = rx1.recv() => { panic!("1") },
+            _foo = rx2.recv() => { panic!("2") },
+            _foo = rx3.recv() => { panic!("3") },
+            _foo = rx4.recv() => { panic!("4") },
             foo = rx5.recv() => { assert_eq!(foo, 4); }
         )
     })
@@ -393,7 +393,7 @@ macro_rules! select {
         drop(tx2);
 
         select! (
-            _a1 = rx1.recv_opt() => { fail!() },
+            _a1 = rx1.recv_opt() => { panic!() },
             a2 = rx2.recv_opt() => { assert_eq!(a2, Err(())); }
         )
     })
@@ -412,12 +412,12 @@ macro_rules! select {
 
         select! (
             a = rx1.recv() => { assert_eq!(a, 1); },
-            _b = rx2.recv() => { fail!() }
+            _b = rx2.recv() => { panic!() }
         )
         tx3.send(1);
         select! (
             a = rx1.recv_opt() => { assert_eq!(a, Err(())); },
-            _b = rx2.recv() => { fail!() }
+            _b = rx2.recv() => { panic!() }
         )
     })
 
@@ -488,7 +488,7 @@ macro_rules! select {
         tx3.send(());
         select!(
             _i1 = rx1.recv() => {},
-            _i2 = rx2.recv() => fail!()
+            _i2 = rx2.recv() => panic!()
         )
         tx3.send(());
     })
@@ -509,7 +509,7 @@ macro_rules! select {
         tx3.send(());
         select!(
             _i1 = rx1.recv() => {},
-            _i2 = rx2.recv() => fail!()
+            _i2 = rx2.recv() => panic!()
         )
         tx3.send(());
     })
index cfd045d08821af814a61728f27d90c529a94fb4b..a82efe76289bfb7d6b7aceec23ffa67a094d622e 100644 (file)
@@ -299,7 +299,7 @@ pub fn try_recv(&mut self) -> Result<T, Failure> {
                     Thread::yield_now();
                     match self.queue.pop() {
                         mpsc::Data(t) => { data = t; break }
-                        mpsc::Empty => fail!("inconsistent => empty"),
+                        mpsc::Empty => panic!("inconsistent => empty"),
                         mpsc::Inconsistent => {}
                     }
                 }
@@ -358,7 +358,7 @@ pub fn drop_chan(&mut self) {
         match self.channels.fetch_sub(1, atomic::SeqCst) {
             1 => {}
             n if n > 1 => return,
-            n => fail!("bad number of channels left {}", n),
+            n => panic!("bad number of channels left {}", n),
         }
 
         match self.cnt.swap(DISCONNECTED, atomic::SeqCst) {
index 528a15cf6d7658a10bb26332d814e10794eee340..bbb4813f5f90f965c2268d772de1cbbeb64fb9c6 100644 (file)
@@ -19,7 +19,7 @@
 /// which means that every successful send is paired with a successful recv.
 ///
 /// This flavor of channels defines a new `send_opt` method for channels which
-/// is the method by which a message is sent but the task does not fail if it
+/// is the method by which a message is sent but the task does not panic if it
 /// cannot be delivered.
 ///
 /// Another major difference is that send() will *always* return back the data
@@ -193,7 +193,7 @@ pub fn send(&self, t: T) -> Result<(), T> {
             // success, someone's about to receive our buffered data.
             BlockedReceiver(task) => { wakeup(task, guard); Ok(()) }
 
-            BlockedSender(..) => fail!("lolwut"),
+            BlockedSender(..) => panic!("lolwut"),
         }
     }
 
index 09fa8920a07d7daff55f56213b3417af62bfcae5..31889a36dd7abdb87e5d649ed63246dac70e278b 100644 (file)
@@ -467,7 +467,7 @@ fn stealpush_large() {
             while left > 0 {
                 match s.steal() {
                     Data((1, 10)) => { left -= 1; }
-                    Data(..) => fail!(),
+                    Data(..) => panic!(),
                     Abort | Empty => {}
                 }
             }
@@ -497,7 +497,7 @@ fn stampede(w: Worker<Box<int>>, s: Stealer<Box<int>>,
                             Data(box 20) => {
                                 (*unsafe_remaining).fetch_sub(1, SeqCst);
                             }
-                            Data(..) => fail!(),
+                            Data(..) => panic!(),
                             Abort | Empty => {}
                         }
                     }
@@ -508,7 +508,7 @@ fn stampede(w: Worker<Box<int>>, s: Stealer<Box<int>>,
         while remaining.load(SeqCst) > 0 {
             match w.pop() {
                 Some(box 20) => { remaining.fetch_sub(1, SeqCst); }
-                Some(..) => fail!(),
+                Some(..) => panic!(),
                 None => {}
             }
         }
@@ -556,7 +556,7 @@ fn stress() {
                 loop {
                     match s.steal() {
                         Data(2) => { HITS.fetch_add(1, SeqCst); }
-                        Data(..) => fail!(),
+                        Data(..) => panic!(),
                         _ if DONE.load(SeqCst) => break,
                         _ => {}
                     }
@@ -571,7 +571,7 @@ fn stress() {
                 match w.pop() {
                     None => {}
                     Some(2) => { HITS.fetch_add(1, SeqCst); },
-                    Some(_) => fail!(),
+                    Some(_) => panic!(),
                 }
             } else {
                 expected += 1;
@@ -583,7 +583,7 @@ fn stress() {
             match w.pop() {
                 None => {}
                 Some(2) => { HITS.fetch_add(1, SeqCst); },
-                Some(_) => fail!(),
+                Some(_) => panic!(),
             }
         }
         DONE.store(true, SeqCst);
@@ -618,7 +618,7 @@ fn no_starvation() {
                             Data((1, 2)) => {
                                 (*thread_box).fetch_add(1, SeqCst);
                             }
-                            Data(..) => fail!(),
+                            Data(..) => panic!(),
                             _ if DONE.load(SeqCst) => break,
                             _ => {}
                         }
@@ -635,7 +635,7 @@ fn no_starvation() {
                     match w.pop() {
                         None => {}
                         Some((1, 2)) => myhit = true,
-                        Some(_) => fail!(),
+                        Some(_) => panic!(),
                     }
                 } else {
                     w.push((1, 2));
index 78a7d128be5f3ac504639f72d4e1fe41dda91864..a9b0b7c48034f31cee3ddf084a358b2c11dcb928 100644 (file)
 //!
 //! The wrappers in this module build on the primitives from `sync::raw` to
 //! provide safe interfaces around using the primitive locks. These primitives
-//! implement a technique called "poisoning" where when a task failed with a
-//! held lock, all future attempts to use the lock will fail.
+//! implement a technique called "poisoning" where when a task panicked with a
+//! held lock, all future attempts to use the lock will panic.
 //!
-//! For example, if two tasks are contending on a mutex and one of them fails
-//! after grabbing the lock, the second task will immediately fail because the
+//! For example, if two tasks are contending on a mutex and one of them panics
+//! after grabbing the lock, the second task will immediately panic because the
 //! lock is now poisoned.
 
 use core::prelude::*;
@@ -43,7 +43,7 @@ fn failing() -> bool {
 impl<'a> PoisonOnFail<'a> {
     fn check(flag: bool, name: &str) {
         if flag {
-            fail!("Poisoned {} - another task failed inside!", name);
+            panic!("Poisoned {} - another task failed inside!", name);
         }
     }
 
@@ -99,10 +99,10 @@ impl<'a> Condvar<'a> {
     ///
     /// wait() is equivalent to wait_on(0).
     ///
-    /// # Failure
+    /// # Panics
     ///
     /// A task which is killed while waiting on a condition variable will wake
-    /// up, fail, and unlock the associated lock as it unwinds.
+    /// up, panic, and unlock the associated lock as it unwinds.
     #[inline]
     pub fn wait(&self) { self.wait_on(0) }
 
@@ -213,12 +213,12 @@ pub fn new_with_condvars(user_data: T, num_condvars: uint) -> Mutex<T> {
     /// when dropped. All concurrent tasks attempting to lock the mutex will
     /// block while the returned value is still alive.
     ///
-    /// # Failure
+    /// # Panics
     ///
-    /// Failing while inside the Mutex will unlock the Mutex while unwinding, so
+    /// Panicking while inside the Mutex will unlock the Mutex while unwinding, so
     /// that other tasks won't block forever. It will also poison the Mutex:
     /// any tasks that subsequently try to access it (including those already
-    /// blocked on the mutex) will also fail immediately.
+    /// blocked on the mutex) will also panic immediately.
     #[inline]
     pub fn lock<'a>(&'a self) -> MutexGuard<'a, T> {
         let guard = self.lock.lock();
@@ -317,11 +317,11 @@ pub fn new_with_condvars(user_data: T, num_condvars: uint) -> RWLock<T> {
     /// Access the underlying data mutably. Locks the rwlock in write mode;
     /// other readers and writers will block.
     ///
-    /// # Failure
+    /// # Panics
     ///
-    /// Failing while inside the lock will unlock the lock while unwinding, so
+    /// Panicking while inside the lock will unlock the lock while unwinding, so
     /// that other tasks won't block forever. As Mutex.lock, it will also poison
-    /// the lock, so subsequent readers and writers will both also fail.
+    /// the lock, so subsequent readers and writers will both also panic.
     #[inline]
     pub fn write<'a>(&'a self) -> RWLockWriteGuard<'a, T> {
         let guard = self.lock.write();
@@ -496,7 +496,7 @@ fn test_arc_condvar_poison() {
             let lock = arc2.lock();
             lock.cond.signal();
             // Parent should fail when it wakes up.
-            fail!();
+            panic!();
         });
 
         let lock = arc.lock();
@@ -546,7 +546,7 @@ fn drop(&mut self) {
                 }
             }
             let _u = Unwinder { i: arc2 };
-            fail!();
+            panic!();
         });
         let lock = arc.lock();
         assert_eq!(*lock, 2);
@@ -661,7 +661,7 @@ fn drop(&mut self) {
                 }
             }
             let _u = Unwinder { i: arc2 };
-            fail!();
+            panic!();
         });
         let lock = arc.read();
         assert_eq!(*lock, 2);
index ac2acf3d7d4d2f0770f749e7814347e4ddda5291..69dc2fe8e607e359113aded9253306e76709dc01 100644 (file)
@@ -177,7 +177,7 @@ fn test() {
         let q = Queue::new();
         match q.pop() {
             Empty => {}
-            Inconsistent | Data(..) => fail!()
+            Inconsistent | Data(..) => panic!()
         }
         let (tx, rx) = channel();
         let q = Arc::new(q);
index 81ae8dbb98f1ae19e0ec452fafea19722b33c66d..4fd62ac3a1da04d6cfc9a391248011ac36305174 100644 (file)
@@ -216,10 +216,10 @@ pub struct Condvar<'a> {
 impl<'a> Condvar<'a> {
     /// Atomically drop the associated lock, and block until a signal is sent.
     ///
-    /// # Failure
+    /// # Panics
     ///
     /// A task which is killed while waiting on a condition variable will wake
-    /// up, fail, and unlock the associated lock as it unwinds.
+    /// up, panic, and unlock the associated lock as it unwinds.
     pub fn wait(&self) { self.wait_on(0) }
 
     /// As wait(), but can specify which of multiple condition variables to
@@ -228,7 +228,7 @@ pub fn wait(&self) { self.wait_on(0) }
     ///
     /// The associated lock must have been initialised with an appropriate
     /// number of condvars. The condvar_id must be between 0 and num_condvars-1
-    /// or else this call will fail.
+    /// or else this call will panic.
     ///
     /// wait() is equivalent to wait_on(0).
     pub fn wait_on(&self, condvar_id: uint) {
@@ -324,7 +324,7 @@ pub fn broadcast_on(&self, condvar_id: uint) -> uint {
     }
 }
 
-// Checks whether a condvar ID was out of bounds, and fails if so, or does
+// Checks whether a condvar ID was out of bounds, and panics if so, or does
 // something else next on success.
 #[inline]
 fn check_cvar_bounds<U>(
@@ -335,9 +335,9 @@ fn check_cvar_bounds<U>(
                      -> U {
     match out_of_bounds {
         Some(0) =>
-            fail!("{} with illegal ID {} - this lock has no condvars!", act, id),
+            panic!("{} with illegal ID {} - this lock has no condvars!", act, id),
         Some(length) =>
-            fail!("{} with illegal ID {} - ID must be less than {}", act, id, length),
+            panic!("{} with illegal ID {} - ID must be less than {}", act, id, length),
         None => blk()
     }
 }
@@ -367,9 +367,9 @@ pub struct SemaphoreGuard<'a> {
 impl Semaphore {
     /// Create a new semaphore with the specified count.
     ///
-    /// # Failure
+    /// # Panics
     ///
-    /// This function will fail if `count` is negative.
+    /// This function will panic if `count` is negative.
     pub fn new(count: int) -> Semaphore {
         Semaphore { sem: Sem::new(count, ()) }
     }
@@ -396,8 +396,9 @@ pub fn access<'a>(&'a self) -> SemaphoreGuard<'a> {
 /// A blocking, bounded-waiting, mutual exclusion lock with an associated
 /// FIFO condition variable.
 ///
-/// # Failure
-/// A task which fails while holding a mutex will unlock the mutex as it
+/// # Panics
+///
+/// A task which panicks while holding a mutex will unlock the mutex as it
 /// unwinds.
 pub struct Mutex {
     sem: Sem<Vec<WaitQueue>>,
@@ -421,7 +422,7 @@ pub fn new() -> Mutex { Mutex::new_with_condvars(1) }
     /// Create a new mutex, with a specified number of associated condvars. This
     /// will allow calling wait_on/signal_on/broadcast_on with condvar IDs
     /// between 0 and num_condvars-1. (If num_condvars is 0, lock_cond will be
-    /// allowed but any operations on the condvar will fail.)
+    /// allowed but any operations on the condvar will panic.)
     pub fn new_with_condvars(num_condvars: uint) -> Mutex {
         Mutex { sem: Sem::new_and_signal(1, num_condvars) }
     }
@@ -443,9 +444,9 @@ pub fn lock<'a>(&'a self) -> MutexGuard<'a> {
 
 /// A blocking, no-starvation, reader-writer lock with an associated condvar.
 ///
-/// # Failure
+/// # Panics
 ///
-/// A task which fails while holding an rwlock will unlock the rwlock as it
+/// A task which panics while holding an rwlock will unlock the rwlock as it
 /// unwinds.
 pub struct RWLock {
     order_lock:  Semaphore,
@@ -835,13 +836,13 @@ fn test_mutex_cond_no_waiter() {
     fn test_mutex_killed_simple() {
         use std::any::Any;
 
-        // Mutex must get automatically unlocked if failed/killed within.
+        // Mutex must get automatically unlocked if panicked/killed within.
         let m = Arc::new(Mutex::new());
         let m2 = m.clone();
 
         let result: result::Result<(), Box<Any + Send>> = task::try(proc() {
             let _lock = m2.lock();
-            fail!();
+            panic!();
         });
         assert!(result.is_err());
         // child task must have finished by the time try returns
@@ -1075,13 +1076,13 @@ fn test_rwlock_cond_broadcast() {
     fn rwlock_kill_helper(mode1: RWLockMode, mode2: RWLockMode) {
         use std::any::Any;
 
-        // Mutex must get automatically unlocked if failed/killed within.
+        // Mutex must get automatically unlocked if panicked/killed within.
         let x = Arc::new(RWLock::new());
         let x2 = x.clone();
 
         let result: result::Result<(), Box<Any + Send>> = task::try(proc() {
             lock_rwlock_in_mode(&x2, mode1, || {
-                fail!();
+                panic!();
             })
         });
         assert!(result.is_err());
index 9cd64d46bad85e5175ffa37a17dd0ab3d59150f9..ef0ceb141458b23b5203adea2a4ab626e698f625 100644 (file)
@@ -369,7 +369,7 @@ fn stress_bound(bound: uint) {
                     loop {
                         match consumer.pop() {
                             Some(1i) => break,
-                            Some(_) => fail!(),
+                            Some(_) => panic!(),
                             None => {}
                         }
                     }
index 8eaee7282d1971f4527f37cb4287626add9f0ca3..3bd25d245e175d814fe27db28e19ed0540239e3e 100644 (file)
@@ -24,6 +24,9 @@
 use std::rc::Rc;
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 
+#[cfg(stage0)]
+pub use self::TtToken as TTTok;
+
 // FIXME #6993: in librustc, uses of "ident" should be replaced
 // by just "Name".
 
@@ -79,9 +82,9 @@ fn eq(&self, other: &Ident) -> bool {
             //
             // On the other hand, if the comparison does need to be hygienic,
             // one example and its non-hygienic counterpart would be:
-            //      syntax::parse::token::mtwt_token_eq
+            //      syntax::parse::token::Token::mtwt_eq
             //      syntax::ext::tt::macro_parser::token_name_eq
-            fail!("not allowed to compare these idents: {}, {}. \
+            panic!("not allowed to compare these idents: {}, {}. \
                    Probably related to issue \\#6993", self, other);
         }
     }
@@ -436,7 +439,7 @@ pub enum Stmt_ {
     /// Expr with trailing semi-colon (may have any type):
     StmtSemi(P<Expr>, NodeId),
 
-    /// bool: is there a trailing sem-colon?
+    /// bool: is there a trailing semi-colon?
     StmtMac(Mac, bool),
 }
 
@@ -592,6 +595,28 @@ pub enum CaptureClause {
     CaptureByRef,
 }
 
+/// A token that delimits a sequence of token trees
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
+pub struct Delimiter {
+    pub span: Span,
+    pub token: ::parse::token::Token,
+}
+
+impl Delimiter {
+    /// Convert the delimiter to a `TtToken`
+    pub fn to_tt(&self) -> TokenTree {
+        TtToken(self.span, self.token.clone())
+    }
+}
+
+/// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star)
+/// for token sequences.
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
+pub enum KleeneOp {
+    ZeroOrMore,
+    OneOrMore,
+}
+
 /// When the main rust parser encounters a syntax-extension invocation, it
 /// parses the arguments to the invocation as a token-tree. This is a very
 /// loose structure, such that all sorts of different AST-fragments can
@@ -600,9 +625,9 @@ pub enum CaptureClause {
 /// If the syntax extension is an MBE macro, it will attempt to match its
 /// LHS "matchers" against the provided token tree, and if it finds a
 /// match, will transcribe the RHS token tree, splicing in any captured
-/// macro_parser::matched_nonterminals into the TTNonterminals it finds.
+/// `macro_parser::matched_nonterminals` into the `TtNonterminal`s it finds.
 ///
-/// The RHS of an MBE macro is the only place a TTNonterminal or TTSeq
+/// The RHS of an MBE macro is the only place a `TtNonterminal` or `TtSequence`
 /// makes any real sense. You could write them elsewhere but nothing
 /// else knows what to do with them, so you'll probably get a syntax
 /// error.
@@ -610,22 +635,29 @@ pub enum CaptureClause {
 #[doc="For macro invocations; parsing is delegated to the macro"]
 pub enum TokenTree {
     /// A single token
-    TTTok(Span, ::parse::token::Token),
-    /// A delimited sequence (the delimiters appear as the first
-    /// and last elements of the vector)
-    // FIXME(eddyb) #6308 Use Rc<[TokenTree]> after DST.
-    TTDelim(Rc<Vec<TokenTree>>),
+    TtToken(Span, ::parse::token::Token),
+    /// A delimited sequence of token trees
+    TtDelimited(Span, Rc<(Delimiter, Vec<TokenTree>, Delimiter)>),
 
     // These only make sense for right-hand-sides of MBE macros:
 
-    /// A kleene-style repetition sequence with a span, a TTForest,
-    /// an optional separator, and a boolean where true indicates
-    /// zero or more (..), and false indicates one or more (+).
+    /// A Kleene-style repetition sequence with an optional separator.
     // FIXME(eddyb) #6308 Use Rc<[TokenTree]> after DST.
-    TTSeq(Span, Rc<Vec<TokenTree>>, Option<::parse::token::Token>, bool),
-
+    TtSequence(Span, Rc<Vec<TokenTree>>, Option<::parse::token::Token>, KleeneOp),
     /// A syntactic variable that will be filled in by macro expansion.
-    TTNonterminal(Span, Ident)
+    TtNonterminal(Span, Ident)
+}
+
+impl TokenTree {
+    /// Returns the `Span` corresponding to this token tree.
+    pub fn get_span(&self) -> Span {
+        match *self {
+            TtToken(span, _)           => span,
+            TtDelimited(span, _)       => span,
+            TtSequence(span, _, _, _)  => span,
+            TtNonterminal(span, _)     => span,
+        }
+    }
 }
 
 // Matchers are nodes defined-by and recognized-by the main rust parser and
@@ -684,9 +716,9 @@ pub enum TokenTree {
 pub enum Matcher_ {
     /// Match one token
     MatchTok(::parse::token::Token),
-    /// Match repetitions of a sequence: body, separator, zero ok?,
+    /// Match repetitions of a sequence: body, separator, Kleene operator,
     /// lo, hi position-in-match-array used:
-    MatchSeq(Vec<Matcher> , Option<::parse::token::Token>, bool, uint, uint),
+    MatchSeq(Vec<Matcher> , Option<::parse::token::Token>, KleeneOp, uint, uint),
     /// Parse a Rust NT: name to bind, name of NT, position in match array:
     MatchNonterminal(Ident, Ident, uint)
 }
index 8280f34615fc2406051478c3a8e4c578e641381d..187d94d1fa7809b58cc5226f31178265df624cec 100644 (file)
@@ -198,17 +198,17 @@ fn handle<A>(self,
                         ident: i.ident, decl: &**decl, style: style, body: &**block,
                         generics: generics, abi: abi, id: i.id, span: i.span
                     }),
-                _ => fail!("item FnLikeNode that is not fn-like"),
+                _ => panic!("item FnLikeNode that is not fn-like"),
             },
             ast_map::NodeTraitItem(t) => match *t {
                 ast::ProvidedMethod(ref m) => method(&**m),
-                _ => fail!("trait method FnLikeNode that is not fn-like"),
+                _ => panic!("trait method FnLikeNode that is not fn-like"),
             },
             ast_map::NodeImplItem(ii) => {
                 match *ii {
                     ast::MethodImplItem(ref m) => method(&**m),
                     ast::TypeImplItem(_) => {
-                        fail!("impl method FnLikeNode that is not fn-like")
+                        panic!("impl method FnLikeNode that is not fn-like")
                     }
                 }
             }
@@ -217,9 +217,9 @@ fn handle<A>(self,
                     closure(ClosureParts::new(&**decl, &**block, e.id, e.span)),
                 ast::ExprProc(ref decl, ref block) =>
                     closure(ClosureParts::new(&**decl, &**block, e.id, e.span)),
-                _ => fail!("expr FnLikeNode that is not fn-like"),
+                _ => panic!("expr FnLikeNode that is not fn-like"),
             },
-            _ => fail!("other FnLikeNode that is not fn-like"),
+            _ => panic!("other FnLikeNode that is not fn-like"),
         }
     }
 }
index b82a4a0b9971852dd8bc181d420b7d98ef2aacb3..915c2d1b3188cbcba6cf6e8b140331b73ec7fc2b 100644 (file)
@@ -263,12 +263,12 @@ pub fn krate(&self) -> &'ast Crate {
         &self.forest.krate
     }
 
-    /// Retrieve the Node corresponding to `id`, failing if it cannot
+    /// Retrieve the Node corresponding to `id`, panicking if it cannot
     /// be found.
     pub fn get(&self, id: NodeId) -> Node<'ast> {
         match self.find(id) {
             Some(node) => node,
-            None => fail!("couldn't find node id {} in the AST map", id)
+            None => panic!("couldn't find node id {} in the AST map", id)
         }
     }
 
@@ -308,7 +308,7 @@ pub fn get_foreign_abi(&self, id: NodeId) -> abi::Abi {
         };
         match abi {
             Some(abi) => abi,
-            None => fail!("expected foreign mod or inlined parent, found {}",
+            None => panic!("expected foreign mod or inlined parent, found {}",
                           self.node_to_string(parent))
         }
     }
@@ -324,7 +324,7 @@ pub fn get_foreign_vis(&self, id: NodeId) -> Visibility {
     pub fn expect_item(&self, id: NodeId) -> &'ast Item {
         match self.find(id) {
             Some(NodeItem(item)) => item,
-            _ => fail!("expected item, found {}", self.node_to_string(id))
+            _ => panic!("expected item, found {}", self.node_to_string(id))
         }
     }
 
@@ -333,37 +333,37 @@ pub fn expect_struct(&self, id: NodeId) -> &'ast StructDef {
             Some(NodeItem(i)) => {
                 match i.node {
                     ItemStruct(ref struct_def, _) => &**struct_def,
-                    _ => fail!("struct ID bound to non-struct")
+                    _ => panic!("struct ID bound to non-struct")
                 }
             }
             Some(NodeVariant(variant)) => {
                 match variant.node.kind {
                     StructVariantKind(ref struct_def) => &**struct_def,
-                    _ => fail!("struct ID bound to enum variant that isn't struct-like"),
+                    _ => panic!("struct ID bound to enum variant that isn't struct-like"),
                 }
             }
-            _ => fail!(format!("expected struct, found {}", self.node_to_string(id))),
+            _ => panic!(format!("expected struct, found {}", self.node_to_string(id))),
         }
     }
 
     pub fn expect_variant(&self, id: NodeId) -> &'ast Variant {
         match self.find(id) {
             Some(NodeVariant(variant)) => variant,
-            _ => fail!(format!("expected variant, found {}", self.node_to_string(id))),
+            _ => panic!(format!("expected variant, found {}", self.node_to_string(id))),
         }
     }
 
     pub fn expect_foreign_item(&self, id: NodeId) -> &'ast ForeignItem {
         match self.find(id) {
             Some(NodeForeignItem(item)) => item,
-            _ => fail!("expected foreign item, found {}", self.node_to_string(id))
+            _ => panic!("expected foreign item, found {}", self.node_to_string(id))
         }
     }
 
     pub fn expect_expr(&self, id: NodeId) -> &'ast Expr {
         match self.find(id) {
             Some(NodeExpr(expr)) => expr,
-            _ => fail!("expected expr, found {}", self.node_to_string(id))
+            _ => panic!("expected expr, found {}", self.node_to_string(id))
         }
     }
 
@@ -388,7 +388,7 @@ pub fn get_path_elem(&self, id: NodeId) -> PathElem {
                                 PathName(ident.name)
                             }
                             MethMac(_) => {
-                                fail!("no path elem for {}", node)
+                                panic!("no path elem for {}", node)
                             }
                         }
                     }
@@ -402,13 +402,13 @@ pub fn get_path_elem(&self, id: NodeId) -> PathElem {
                         MethDecl(ident, _, _, _, _, _, _, _) => {
                             PathName(ident.name)
                         }
-                        MethMac(_) => fail!("no path elem for {}", node),
+                        MethMac(_) => panic!("no path elem for {}", node),
                     }
                 }
                 TypeTraitItem(ref m) => PathName(m.ident.name),
             },
             NodeVariant(v) => PathName(v.node.name.name),
-            _ => fail!("no path elem for {}", node)
+            _ => panic!("no path elem for {}", node)
         }
     }
 
@@ -533,7 +533,7 @@ pub fn opt_span(&self, id: NodeId) -> Option<Span> {
 
     pub fn span(&self, id: NodeId) -> Span {
         self.opt_span(id)
-            .unwrap_or_else(|| fail!("AstMap.span: could not find span for id {}", id))
+            .unwrap_or_else(|| panic!("AstMap.span: could not find span for id {}", id))
     }
 
     pub fn def_id_span(&self, def_id: DefId, fallback: Span) -> Span {
@@ -666,7 +666,7 @@ impl Named for Method {
     fn name(&self) -> Name {
         match self.node {
             MethDecl(i, _, _, _, _, _, _, _) => i.name,
-            MethMac(_) => fail!("encountered unexpanded method macro."),
+            MethMac(_) => panic!("encountered unexpanded method macro."),
         }
     }
 }
@@ -1018,9 +1018,9 @@ fn print_node(&mut self, node: &Node) -> IoResult<()> {
             // these cases do not carry enough information in the
             // ast_map to reconstruct their full structure for pretty
             // printing.
-            NodeLocal(_)       => fail!("cannot print isolated Local"),
-            NodeArg(_)         => fail!("cannot print isolated Arg"),
-            NodeStructCtor(_)  => fail!("cannot print isolated StructCtor"),
+            NodeLocal(_)       => panic!("cannot print isolated Local"),
+            NodeArg(_)         => panic!("cannot print isolated Arg"),
+            NodeStructCtor(_)  => panic!("cannot print isolated StructCtor"),
         }
     }
 }
index d5a460dc9dba1812f61a5be4043f8e2adbf805ed..7e1716e6b18171a3de9df2fb3ebf9713f504d10c 100644 (file)
@@ -43,7 +43,7 @@ pub fn stmt_id(s: &Stmt) -> NodeId {
       StmtDecl(_, id) => id,
       StmtExpr(_, id) => id,
       StmtSemi(_, id) => id,
-      StmtMac(..) => fail!("attempted to analyze unexpanded stmt")
+      StmtMac(..) => panic!("attempted to analyze unexpanded stmt")
     }
 }
 
@@ -233,7 +233,7 @@ pub fn trait_method_to_ty_method(method: &Method) -> TypeMethod {
                 abi: abi,
             }
         },
-        MethMac(_) => fail!("expected non-macro method declaration")
+        MethMac(_) => panic!("expected non-macro method declaration")
     }
 }
 
@@ -246,7 +246,7 @@ pub fn trait_item_to_ty_method(method: &TraitItem) -> TypeMethod {
         RequiredMethod(ref m) => (*m).clone(),
         ProvidedMethod(ref m) => trait_method_to_ty_method(&**m),
         TypeTraitItem(_) => {
-            fail!("trait_method_to_ty_method(): expected method but found \
+            panic!("trait_method_to_ty_method(): expected method but found \
                    typedef")
         }
     }
@@ -615,7 +615,7 @@ pub fn walk_pat(pat: &Pat, it: |&Pat| -> bool) -> bool {
             slice.iter().all(|p| walk_pat(&**p, |p| it(p))) &&
             after.iter().all(|p| walk_pat(&**p, |p| it(p)))
         }
-        PatMac(_) => fail!("attempted to analyze unexpanded pattern"),
+        PatMac(_) => panic!("attempted to analyze unexpanded pattern"),
         PatWild(_) | PatLit(_) | PatRange(_, _) | PatIdent(_, _, _) |
         PatEnum(_, _) => {
             true
@@ -725,7 +725,7 @@ fn $meth_name<'a>(&'a self) -> $field_ty {
             match self.node {
                 $field_pat => $result,
                 MethMac(_) => {
-                    fail!("expected an AST without macro invocations");
+                    panic!("expected an AST without macro invocations");
                 }
             }
         }
index 4df334a3f2c70cbee997387aba9f67c6f053466e..7d303644020a47fdbb34da6bf192804b843f7d5c 100644 (file)
@@ -425,7 +425,7 @@ pub fn span_to_snippet(&self, sp: Span) -> Option<String> {
 
         // FIXME #8256: this used to be an assert but whatever precondition
         // it's testing isn't true for all spans in the AST, so to allow the
-        // caller to not have to fail (and it can't catch it since the CodeMap
+        // caller to not have to panic (and it can't catch it since the CodeMap
         // isn't sendable), return None
         if begin.fm.start_pos != end.fm.start_pos {
             None
@@ -441,7 +441,7 @@ pub fn get_filemap(&self, filename: &str) -> Rc<FileMap> {
                 return fm.clone();
             }
         }
-        fail!("asking for {} which we don't know about", filename);
+        panic!("asking for {} which we don't know about", filename);
     }
 
     pub fn lookup_byte_offset(&self, bpos: BytePos) -> FileMapAndBytePos {
@@ -503,13 +503,13 @@ fn lookup_filemap_idx(&self, pos: BytePos) -> uint {
                 break;
             }
             if a == 0 {
-                fail!("position {} does not resolve to a source location",
+                panic!("position {} does not resolve to a source location",
                       pos.to_uint());
             }
             a -= 1;
         }
         if a >= len {
-            fail!("position {} does not resolve to a source location",
+            panic!("position {} does not resolve to a source location",
                   pos.to_uint())
         }
 
index 8824a937038a8143e1b0c4733d7579b5f1609f63..72c62a173fc30b88bf18992e5f86448cc7bd397d 100644 (file)
@@ -250,30 +250,18 @@ fn impl_item_in_cfg(cx: &mut Context, impl_item: &ast::ImplItem) -> bool {
 // Determine if an item should be translated in the current crate
 // configuration based on the item's attributes
 fn in_cfg(diagnostic: &SpanHandler, cfg: &[P<ast::MetaItem>], attrs: &[ast::Attribute]) -> bool {
-    let mut in_cfg = false;
-    let mut seen_cfg = false;
-    for attr in attrs.iter() {
+    attrs.iter().all(|attr| {
         let mis = match attr.node.value.node {
             ast::MetaList(_, ref mis) if attr.check_name("cfg") => mis,
-            _ => continue
+            _ => return true
         };
 
         if mis.len() != 1 {
             diagnostic.span_err(attr.span, "expected 1 cfg-pattern");
-            return false;
+            return true;
         }
 
-        if seen_cfg {
-            diagnostic.span_err(attr.span, "The semantics of multiple `#[cfg(..)]` attributes on \
-                                            same item are changing from the union of the cfgs to \
-                                            the intersection of the cfgs. Change `#[cfg(a)] \
-                                            #[cfg(b)]` to `#[cfg(any(a, b))]`.");
-            return false;
-        }
-
-        seen_cfg = true;
-        in_cfg |= attr::cfg_matches(diagnostic, cfg, &*mis[0]);
-    }
-    in_cfg | !seen_cfg
+        attr::cfg_matches(diagnostic, cfg, &*mis[0])
+    })
 }
 
index 3da1b1f3175f273bda78c6c4d6ec84246ace6d70..e24aa0f0b95870cda55c2218312247cd08a962c3 100644 (file)
@@ -63,7 +63,7 @@ fn custom_emit(&mut self, cm: &codemap::CodeMap,
                    sp: RenderSpan, msg: &str, lvl: Level);
 }
 
-/// This structure is used to signify that a task has failed with a fatal error
+/// This structure is used to signify that a task has panicked with a fatal error
 /// from the diagnostics. You can use this with the `Any` trait to figure out
 /// how a rustc task died (if so desired).
 pub struct FatalError;
@@ -83,7 +83,7 @@ pub struct SpanHandler {
 impl SpanHandler {
     pub fn span_fatal(&self, sp: Span, msg: &str) -> ! {
         self.handler.emit(Some((&self.cm, sp)), msg, Fatal);
-        fail!(FatalError);
+        panic!(FatalError);
     }
     pub fn span_err(&self, sp: Span, msg: &str) {
         self.handler.emit(Some((&self.cm, sp)), msg, Error);
@@ -113,7 +113,7 @@ pub fn fileline_note(&self, sp: Span, msg: &str) {
     }
     pub fn span_bug(&self, sp: Span, msg: &str) -> ! {
         self.handler.emit(Some((&self.cm, sp)), msg, Bug);
-        fail!(ExplicitBug);
+        panic!(ExplicitBug);
     }
     pub fn span_unimpl(&self, sp: Span, msg: &str) -> ! {
         self.span_bug(sp, format!("unimplemented {}", msg).as_slice());
@@ -134,7 +134,7 @@ pub struct Handler {
 impl Handler {
     pub fn fatal(&self, msg: &str) -> ! {
         self.emit.borrow_mut().emit(None, msg, None, Fatal);
-        fail!(FatalError);
+        panic!(FatalError);
     }
     pub fn err(&self, msg: &str) {
         self.emit.borrow_mut().emit(None, msg, None, Error);
@@ -172,7 +172,7 @@ pub fn help(&self, msg: &str) {
     }
     pub fn bug(&self, msg: &str) -> ! {
         self.emit.borrow_mut().emit(None, msg, None, Bug);
-        fail!(ExplicitBug);
+        panic!(ExplicitBug);
     }
     pub fn unimpl(&self, msg: &str) -> ! {
         self.bug(format!("unimplemented {}", msg).as_slice());
@@ -367,7 +367,7 @@ fn emit(&mut self,
 
         match error {
             Ok(()) => {}
-            Err(e) => fail!("failed to print diagnostics: {}", e),
+            Err(e) => panic!("failed to print diagnostics: {}", e),
         }
     }
 
@@ -375,7 +375,7 @@ fn custom_emit(&mut self, cm: &codemap::CodeMap,
                    sp: RenderSpan, msg: &str, lvl: Level) {
         match emit(self, cm, sp, msg, None, lvl, true) {
             Ok(()) => {}
-            Err(e) => fail!("failed to print diagnostics: {}", e),
+            Err(e) => panic!("failed to print diagnostics: {}", e),
         }
     }
 }
index d3c39284f55822f5d701d39d1df7176a4cebf859..d9d549f6841252da37ef21ac3ec76e2565f0bfe1 100644 (file)
@@ -50,7 +50,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt,
                                    token_tree: &[TokenTree])
                                    -> Box<MacResult+'cx> {
     let code = match token_tree {
-        [ast::TTTok(_, token::IDENT(code, _))] => code,
+        [ast::TtToken(_, token::Ident(code, _))] => code,
         _ => unreachable!()
     };
     with_registered_diagnostics(|diagnostics| {
@@ -82,12 +82,12 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
                                        token_tree: &[TokenTree])
                                        -> Box<MacResult+'cx> {
     let (code, description) = match token_tree {
-        [ast::TTTok(_, token::IDENT(ref code, _))] => {
+        [ast::TtToken(_, token::Ident(ref code, _))] => {
             (code, None)
         },
-        [ast::TTTok(_, token::IDENT(ref code, _)),
-         ast::TTTok(_, token::COMMA),
-         ast::TTTok(_, token::LIT_STR_RAW(description, _))] => {
+        [ast::TtToken(_, token::Ident(ref code, _)),
+         ast::TtToken(_, token::Comma),
+         ast::TtToken(_, token::LitStrRaw(description, _))] => {
             (code, Some(description))
         }
         _ => unreachable!()
@@ -110,7 +110,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
                                           token_tree: &[TokenTree])
                                           -> Box<MacResult+'cx> {
     let name = match token_tree {
-        [ast::TTTok(_, token::IDENT(ref name, _))] => name,
+        [ast::TtToken(_, token::Ident(ref name, _))] => name,
         _ => unreachable!()
     };
 
index 702be0c0eeede090cb501a24a57de7d2983c99d4..2b52b7feaccd0c5487b9148d15f818c569946042 100644 (file)
@@ -72,21 +72,21 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                 asm_str_style = Some(style);
             }
             Outputs => {
-                while p.token != token::EOF &&
-                      p.token != token::COLON &&
-                      p.token != token::MOD_SEP {
+                while p.token != token::Eof &&
+                      p.token != token::Colon &&
+                      p.token != token::ModSep {
 
                     if outputs.len() != 0 {
-                        p.eat(&token::COMMA);
+                        p.eat(&token::Comma);
                     }
 
                     let (constraint, _str_style) = p.parse_str();
 
                     let span = p.last_span;
 
-                    p.expect(&token::LPAREN);
+                    p.expect(&token::LParen);
                     let out = p.parse_expr();
-                    p.expect(&token::RPAREN);
+                    p.expect(&token::RParen);
 
                     // Expands a read+write operand into two operands.
                     //
@@ -113,12 +113,12 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                 }
             }
             Inputs => {
-                while p.token != token::EOF &&
-                      p.token != token::COLON &&
-                      p.token != token::MOD_SEP {
+                while p.token != token::Eof &&
+                      p.token != token::Colon &&
+                      p.token != token::ModSep {
 
                     if inputs.len() != 0 {
-                        p.eat(&token::COMMA);
+                        p.eat(&token::Comma);
                     }
 
                     let (constraint, _str_style) = p.parse_str();
@@ -129,21 +129,21 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                         cx.span_err(p.last_span, "input operand constraint contains '+'");
                     }
 
-                    p.expect(&token::LPAREN);
+                    p.expect(&token::LParen);
                     let input = p.parse_expr();
-                    p.expect(&token::RPAREN);
+                    p.expect(&token::RParen);
 
                     inputs.push((constraint, input));
                 }
             }
             Clobbers => {
                 let mut clobs = Vec::new();
-                while p.token != token::EOF &&
-                      p.token != token::COLON &&
-                      p.token != token::MOD_SEP {
+                while p.token != token::Eof &&
+                      p.token != token::Colon &&
+                      p.token != token::ModSep {
 
                     if clobs.len() != 0 {
-                        p.eat(&token::COMMA);
+                        p.eat(&token::Comma);
                     }
 
                     let (s, _str_style) = p.parse_str();
@@ -172,8 +172,8 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                     cx.span_warn(p.last_span, "unrecognized option");
                 }
 
-                if p.token == token::COMMA {
-                    p.eat(&token::COMMA);
+                if p.token == token::Comma {
+                    p.eat(&token::Comma);
                 }
             }
             StateNone => ()
@@ -183,17 +183,17 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
             // MOD_SEP is a double colon '::' without space in between.
             // When encountered, the state must be advanced twice.
             match (&p.token, state.next(), state.next().next()) {
-                (&token::COLON, StateNone, _)   |
-                (&token::MOD_SEP, _, StateNone) => {
+                (&token::Colon, StateNone, _)   |
+                (&token::ModSep, _, StateNone) => {
                     p.bump();
                     break 'statement;
                 }
-                (&token::COLON, st, _)   |
-                (&token::MOD_SEP, _, st) => {
+                (&token::Colon, st, _)   |
+                (&token::ModSep, _, st) => {
                     p.bump();
                     state = st;
                 }
-                (&token::EOF, _, _) => break 'statement,
+                (&token::Eof, _, _) => break 'statement,
                 _ => break
             }
         }
index 5cc2fe03618c46b25df24d5b333d26340f2771fe..a8326e79ef368eac5506a72684c0c7eb98e5c171 100644 (file)
@@ -684,8 +684,8 @@ pub fn get_single_str_from_tts(cx: &ExtCtxt,
         cx.span_err(sp, format!("{} takes 1 argument.", name).as_slice());
     } else {
         match tts[0] {
-            ast::TTTok(_, token::LIT_STR(ident)) => return Some(parse::str_lit(ident.as_str())),
-            ast::TTTok(_, token::LIT_STR_RAW(ident, _)) => {
+            ast::TtToken(_, token::LitStr(ident)) => return Some(parse::str_lit(ident.as_str())),
+            ast::TtToken(_, token::LitStrRaw(ident, _)) => {
                 return Some(parse::raw_str_lit(ident.as_str()))
             }
             _ => {
@@ -704,12 +704,12 @@ pub fn get_exprs_from_tts(cx: &mut ExtCtxt,
                           tts: &[ast::TokenTree]) -> Option<Vec<P<ast::Expr>>> {
     let mut p = cx.new_parser_from_tts(tts);
     let mut es = Vec::new();
-    while p.token != token::EOF {
+    while p.token != token::Eof {
         es.push(cx.expander().fold_expr(p.parse_expr()));
-        if p.eat(&token::COMMA) {
+        if p.eat(&token::Comma) {
             continue;
         }
-        if p.token != token::EOF {
+        if p.token != token::Eof {
             cx.span_err(sp, "expected token: `,`");
             return None;
         }
index f697acb417de7f393cc701d0a3852a442b46814b..72da60ffe0941f827a97fb6723de25ddf27fc1b3 100644 (file)
@@ -29,7 +29,7 @@ pub fn expand_cfg<'cx>(cx: &mut ExtCtxt,
     let mut p = cx.new_parser_from_tts(tts);
     let cfg = p.parse_meta_item();
 
-    if !p.eat(&token::EOF) {
+    if !p.eat(&token::Eof) {
         cx.span_err(sp, "expected 1 cfg-pattern");
         return DummyResult::expr(sp);
     }
index 145412caa0bfe44bbac17fa10e7ac0a512181cd4..e5e93a7d8b3bb3c761e2e7ddf643fb9aaf266859 100644 (file)
@@ -23,21 +23,21 @@ pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]
     for (i, e) in tts.iter().enumerate() {
         if i & 1 == 1 {
             match *e {
-                ast::TTTok(_, token::COMMA) => (),
+                ast::TtToken(_, token::Comma) => {},
                 _ => {
                     cx.span_err(sp, "concat_idents! expecting comma.");
                     return DummyResult::expr(sp);
-                }
+                },
             }
         } else {
             match *e {
-                ast::TTTok(_, token::IDENT(ident,_)) => {
+                ast::TtToken(_, token::Ident(ident, _)) => {
                     res_str.push_str(token::get_ident(ident).get())
-                }
+                },
                 _ => {
                     cx.span_err(sp, "concat_idents! requires ident args.");
                     return DummyResult::expr(sp);
-                }
+                },
             }
         }
     }
index 533a28998bd1d2f45e6b2a7155d86ea9d76e6239..7c32b84550893a5813916a555a97539d00409ab2 100644 (file)
@@ -1250,7 +1250,7 @@ fn create_struct_pattern(&self,
                 // id is guaranteed to be Some
                 codemap::Spanned {
                     span: pat.span,
-                    node: ast::FieldPat { ident: id.unwrap(), pat: pat, is_shorthand: true },
+                    node: ast::FieldPat { ident: id.unwrap(), pat: pat, is_shorthand: false },
                 }
             }).collect();
             cx.pat_struct(self.span, matching_path, field_pats)
index 39b710e0d5725779a8ce1348d5bc1769b730e7c7..87406081aae97123dce8c23eaecb69404cac1007 100644 (file)
@@ -741,7 +741,7 @@ fn expand_arm(arm: ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
     // expand pats... they might contain macro uses:
     let expanded_pats = arm.pats.move_map(|pat| fld.fold_pat(pat));
     if expanded_pats.len() == 0 {
-        fail!("encountered match arm with 0 patterns");
+        panic!("encountered match arm with 0 patterns");
     }
     // all of the pats must have the same set of bindings, so use the
     // first one to extract them and generate new names:
@@ -1621,7 +1621,7 @@ fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
                     // good lord, you can't make a path with 0 segments, can you?
                     let final_varref_ident = match varref.segments.last() {
                         Some(pathsegment) => pathsegment.identifier,
-                        None => fail!("varref with 0 path segments?")
+                        None => panic!("varref with 0 path segments?")
                     };
                     let varref_name = mtwt::resolve(final_varref_ident);
                     let varref_idents : Vec<ast::Ident>
@@ -1688,7 +1688,7 @@ fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
         let cxbinds: &[&ast::Ident] = cxbinds.as_slice();
         let cxbind = match cxbinds {
             [b] => b,
-            _ => fail!("expected just one binding for ext_cx")
+            _ => panic!("expected just one binding for ext_cx")
         };
         let resolved_binding = mtwt::resolve(*cxbind);
         let varrefs = crate_varrefs(&cr);
index 87cd61c9b223718a9b9c418a1456ea4aeb1c75db..1b12ae67ee5cb11fdadaaca1d13d088ccf2eac79 100644 (file)
@@ -91,7 +91,7 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool,
     // Parse the leading function expression (maybe a block, maybe a path)
     let invocation = if allow_method {
         let e = p.parse_expr();
-        if !p.eat(&token::COMMA) {
+        if !p.eat(&token::Comma) {
             ecx.span_err(sp, "expected token: `,`");
             return (Call(e), None);
         }
@@ -99,28 +99,27 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool,
     } else {
         Call(p.parse_expr())
     };
-    if !p.eat(&token::COMMA) {
+    if !p.eat(&token::Comma) {
         ecx.span_err(sp, "expected token: `,`");
         return (invocation, None);
     }
 
-    if p.token == token::EOF {
+    if p.token == token::Eof {
         ecx.span_err(sp, "requires at least a format string argument");
         return (invocation, None);
     }
     let fmtstr = p.parse_expr();
     let mut named = false;
-    while p.token != token::EOF {
-        if !p.eat(&token::COMMA) {
+    while p.token != token::Eof {
+        if !p.eat(&token::Comma) {
             ecx.span_err(sp, "expected token: `,`");
             return (invocation, None);
         }
-        if p.token == token::EOF { break } // accept trailing commas
-        if named || (token::is_ident(&p.token) &&
-                     p.look_ahead(1, |t| *t == token::EQ)) {
+        if p.token == token::Eof { break } // accept trailing commas
+        if named || (p.token.is_ident() && p.look_ahead(1, |t| *t == token::Eq)) {
             named = true;
             let ident = match p.token {
-                token::IDENT(i, _) => {
+                token::Ident(i, _) => {
                     p.bump();
                     i
                 }
@@ -139,7 +138,7 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool,
             };
             let interned_name = token::get_ident(ident);
             let name = interned_name.get();
-            p.expect(&token::EQ);
+            p.expect(&token::Eq);
             let e = p.parse_expr();
             match names.find_equiv(&name) {
                 None => {}
index 8df5746e412d49aab017be628cb2b8c5768f0c89..30301e3b8cc92414a940ebc6fb374d958a267479 100644 (file)
 use ext::base;
 use print;
 
-use std::rc::Rc;
-
 pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt,
                               sp: codemap::Span,
-                              tt: &[ast::TokenTree])
+                              tts: &[ast::TokenTree])
                               -> Box<base::MacResult+'cx> {
 
     cx.print_backtrace();
-    println!("{}", print::pprust::tt_to_string(&ast::TTDelim(
-                Rc::new(tt.iter().map(|x| (*x).clone()).collect()))));
+
+    println!("{}", print::pprust::tts_to_string(tts));
 
     // any so that `log_syntax` can be invoked as an expression and item.
     base::DummyResult::any(sp)
index b4f8b9f82284980335fca8de2552bb61e951eac0..840468176ab0310c0c75e5591084e847edcac0a6 100644 (file)
@@ -211,7 +211,7 @@ fn resolve_internal(id: Ident,
                     resolvedthis
                 }
             }
-            IllegalCtxt => fail!("expected resolvable context, got IllegalCtxt")
+            IllegalCtxt => panic!("expected resolvable context, got IllegalCtxt")
         }
     };
     resolve_table.insert(key, resolved);
@@ -250,7 +250,7 @@ fn marksof_internal(ctxt: SyntaxContext,
                     loopvar = tl;
                 }
             }
-            IllegalCtxt => fail!("expected resolvable context, got IllegalCtxt")
+            IllegalCtxt => panic!("expected resolvable context, got IllegalCtxt")
         }
     }
 }
@@ -261,7 +261,7 @@ pub fn outer_mark(ctxt: SyntaxContext) -> Mrk {
     with_sctable(|sctable| {
         match (*sctable.table.borrow())[ctxt as uint] {
             Mark(mrk, _) => mrk,
-            _ => fail!("can't retrieve outer mark when outside is not a mark")
+            _ => panic!("can't retrieve outer mark when outside is not a mark")
         }
     })
 }
@@ -342,7 +342,7 @@ fn refold_test_sc(mut sc: SyntaxContext, table : &SCTable) -> Vec<TestSC> {
                     sc = tail;
                     continue;
                 }
-                IllegalCtxt => fail!("expected resolvable context, got IllegalCtxt")
+                IllegalCtxt => panic!("expected resolvable context, got IllegalCtxt")
             }
         }
     }
index 84775c12d641f7570ea422534afa7d76930a6f68..a95a737720a96bb3097414b741fc02899c9bd267 100644 (file)
@@ -23,7 +23,7 @@
 *
 * This is registered as a set of expression syntax extension called quote!
 * that lifts its argument token-tree to an AST representing the
-* construction of the same token tree, with ast::TTNonterminal nodes
+* construction of the same token tree, with ast::TtNonterminal nodes
 * interpreted as antiquotes (splices).
 *
 */
@@ -366,7 +366,7 @@ fn parse_item(&self, s: String) -> P<ast::Item> {
                 Some(ast) => ast,
                 None => {
                     error!("parse error");
-                    fail!()
+                    panic!()
                 }
             }
         }
@@ -515,134 +515,138 @@ fn mk_token_path(cx: &ExtCtxt, sp: Span, name: &str) -> P<ast::Expr> {
     cx.expr_path(cx.path_global(sp, idents))
 }
 
-fn mk_binop(cx: &ExtCtxt, sp: Span, bop: token::BinOp) -> P<ast::Expr> {
+fn mk_binop(cx: &ExtCtxt, sp: Span, bop: token::BinOpToken) -> P<ast::Expr> {
     let name = match bop {
-        PLUS => "PLUS",
-        MINUS => "MINUS",
-        STAR => "STAR",
-        SLASH => "SLASH",
-        PERCENT => "PERCENT",
-        CARET => "CARET",
-        AND => "AND",
-        OR => "OR",
-        SHL => "SHL",
-        SHR => "SHR"
+        token::Plus     => "Plus",
+        token::Minus    => "Minus",
+        token::Star     => "Star",
+        token::Slash    => "Slash",
+        token::Percent  => "Percent",
+        token::Caret    => "Caret",
+        token::And      => "And",
+        token::Or       => "Or",
+        token::Shl      => "Shl",
+        token::Shr      => "Shr"
     };
     mk_token_path(cx, sp, name)
 }
 
+#[allow(non_uppercase_statics)] // NOTE(stage0): remove this attribute after the next snapshot
 fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> {
-
     match *tok {
-        BINOP(binop) => {
-            return cx.expr_call(sp, mk_token_path(cx, sp, "BINOP"), vec!(mk_binop(cx, sp, binop)));
+        token::BinOp(binop) => {
+            return cx.expr_call(sp, mk_token_path(cx, sp, "BinOp"), vec!(mk_binop(cx, sp, binop)));
         }
-        BINOPEQ(binop) => {
-            return cx.expr_call(sp, mk_token_path(cx, sp, "BINOPEQ"),
+        token::BinOpEq(binop) => {
+            return cx.expr_call(sp, mk_token_path(cx, sp, "BinOpEq"),
                                 vec!(mk_binop(cx, sp, binop)));
         }
 
-        LIT_BYTE(i) => {
+        token::LitByte(i) => {
             let e_byte = mk_name(cx, sp, i.ident());
 
-            return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_BYTE"), vec!(e_byte));
+            return cx.expr_call(sp, mk_token_path(cx, sp, "LitByte"), vec!(e_byte));
         }
 
-        LIT_CHAR(i) => {
+        token::LitChar(i) => {
             let e_char = mk_name(cx, sp, i.ident());
 
-            return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_CHAR"), vec!(e_char));
+            return cx.expr_call(sp, mk_token_path(cx, sp, "LitChar"), vec!(e_char));
         }
 
-        LIT_INTEGER(i) => {
+        token::LitInteger(i) => {
             let e_int = mk_name(cx, sp, i.ident());
-            return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_INTEGER"), vec!(e_int));
+            return cx.expr_call(sp, mk_token_path(cx, sp, "LitInteger"), vec!(e_int));
         }
 
-        LIT_FLOAT(fident) => {
+        token::LitFloat(fident) => {
             let e_fident = mk_name(cx, sp, fident.ident());
-            return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_FLOAT"), vec!(e_fident));
+            return cx.expr_call(sp, mk_token_path(cx, sp, "LitFloat"), vec!(e_fident));
         }
 
-        LIT_STR(ident) => {
+        token::LitStr(ident) => {
             return cx.expr_call(sp,
-                                mk_token_path(cx, sp, "LIT_STR"),
+                                mk_token_path(cx, sp, "LitStr"),
                                 vec!(mk_name(cx, sp, ident.ident())));
         }
 
-        LIT_STR_RAW(ident, n) => {
+        token::LitStrRaw(ident, n) => {
             return cx.expr_call(sp,
-                                mk_token_path(cx, sp, "LIT_STR_RAW"),
+                                mk_token_path(cx, sp, "LitStrRaw"),
                                 vec!(mk_name(cx, sp, ident.ident()), cx.expr_uint(sp, n)));
         }
 
-        IDENT(ident, b) => {
+        token::Ident(ident, style) => {
             return cx.expr_call(sp,
-                                mk_token_path(cx, sp, "IDENT"),
-                                vec!(mk_ident(cx, sp, ident), cx.expr_bool(sp, b)));
+                                mk_token_path(cx, sp, "Ident"),
+                                vec![mk_ident(cx, sp, ident),
+                                     match style {
+                                        ModName => mk_token_path(cx, sp, "ModName"),
+                                        Plain   => mk_token_path(cx, sp, "Plain"),
+                                     }]);
         }
 
-        LIFETIME(ident) => {
+        token::Lifetime(ident) => {
             return cx.expr_call(sp,
-                                mk_token_path(cx, sp, "LIFETIME"),
+                                mk_token_path(cx, sp, "Lifetime"),
                                 vec!(mk_ident(cx, sp, ident)));
         }
 
-        DOC_COMMENT(ident) => {
+        token::DocComment(ident) => {
             return cx.expr_call(sp,
-                                mk_token_path(cx, sp, "DOC_COMMENT"),
+                                mk_token_path(cx, sp, "DocComment"),
                                 vec!(mk_name(cx, sp, ident.ident())));
         }
 
-        INTERPOLATED(_) => fail!("quote! with interpolated token"),
+        token::Interpolated(_) => panic!("quote! with interpolated token"),
 
         _ => ()
     }
 
     let name = match *tok {
-        EQ => "EQ",
-        LT => "LT",
-        LE => "LE",
-        EQEQ => "EQEQ",
-        NE => "NE",
-        GE => "GE",
-        GT => "GT",
-        ANDAND => "ANDAND",
-        OROR => "OROR",
-        NOT => "NOT",
-        TILDE => "TILDE",
-        AT => "AT",
-        DOT => "DOT",
-        DOTDOT => "DOTDOT",
-        COMMA => "COMMA",
-        SEMI => "SEMI",
-        COLON => "COLON",
-        MOD_SEP => "MOD_SEP",
-        RARROW => "RARROW",
-        LARROW => "LARROW",
-        FAT_ARROW => "FAT_ARROW",
-        LPAREN => "LPAREN",
-        RPAREN => "RPAREN",
-        LBRACKET => "LBRACKET",
-        RBRACKET => "RBRACKET",
-        LBRACE => "LBRACE",
-        RBRACE => "RBRACE",
-        POUND => "POUND",
-        DOLLAR => "DOLLAR",
-        UNDERSCORE => "UNDERSCORE",
-        EOF => "EOF",
-        _ => fail!()
+        token::Eq           => "Eq",
+        token::Lt           => "Lt",
+        token::Le           => "Le",
+        token::EqEq         => "EqEq",
+        token::Ne           => "Ne",
+        token::Ge           => "Ge",
+        token::Gt           => "Gt",
+        token::AndAnd       => "AndAnd",
+        token::OrOr         => "OrOr",
+        token::Not          => "Not",
+        token::Tilde        => "Tilde",
+        token::At           => "At",
+        token::Dot          => "Dot",
+        token::DotDot       => "DotDot",
+        token::Comma        => "Comma",
+        token::Semi         => "Semi",
+        token::Colon        => "Colon",
+        token::ModSep       => "ModSep",
+        token::RArrow       => "RArrow",
+        token::LArrow       => "LArrow",
+        token::FatArrow     => "FatArrow",
+        token::LParen       => "LParen",
+        token::RParen       => "RParen",
+        token::LBracket     => "LBracket",
+        token::RBracket     => "RBracket",
+        token::LBrace       => "LBrace",
+        token::RBrace       => "RBrace",
+        token::Pound        => "Pound",
+        token::Dollar       => "Dollar",
+        token::Underscore   => "Underscore",
+        token::Eof          => "Eof",
+        _                   => panic!(),
     };
     mk_token_path(cx, sp, name)
 }
 
 
-fn mk_tt(cx: &ExtCtxt, sp: Span, tt: &ast::TokenTree) -> Vec<P<ast::Stmt>> {
+fn mk_tt(cx: &ExtCtxt, _: Span, tt: &ast::TokenTree) -> Vec<P<ast::Stmt>> {
     match *tt {
-        ast::TTTok(sp, ref tok) => {
+        ast::TtToken(sp, ref tok) => {
             let e_sp = cx.expr_ident(sp, id_ext("_sp"));
             let e_tok = cx.expr_call(sp,
-                                     mk_ast_path(cx, sp, "TTTok"),
+                                     mk_ast_path(cx, sp, "TtToken"),
                                      vec!(e_sp, mk_token(cx, sp, tok)));
             let e_push =
                 cx.expr_method_call(sp,
@@ -650,13 +654,16 @@ fn mk_tt(cx: &ExtCtxt, sp: Span, tt: &ast::TokenTree) -> Vec<P<ast::Stmt>> {
                                     id_ext("push"),
                                     vec!(e_tok));
             vec!(cx.stmt_expr(e_push))
-        }
-
-        ast::TTDelim(ref tts) => mk_tts(cx, sp, tts.as_slice()),
-        ast::TTSeq(..) => fail!("TTSeq in quote!"),
-
-        ast::TTNonterminal(sp, ident) => {
-
+        },
+        ast::TtDelimited(sp, ref delimed) => {
+            let (ref open, ref tts, ref close) = **delimed;
+            mk_tt(cx, sp, &open.to_tt()).into_iter()
+                .chain(tts.iter().flat_map(|tt| mk_tt(cx, sp, tt).into_iter()))
+                .chain(mk_tt(cx, sp, &close.to_tt()).into_iter())
+                .collect()
+        },
+        ast::TtSequence(..) => panic!("TtSequence in quote!"),
+        ast::TtNonterminal(sp, ident) => {
             // tt.extend($ident.to_tokens(ext_cx).into_iter())
 
             let e_to_toks =
@@ -674,7 +681,7 @@ fn mk_tt(cx: &ExtCtxt, sp: Span, tt: &ast::TokenTree) -> Vec<P<ast::Stmt>> {
                                     vec!(e_to_toks));
 
             vec!(cx.stmt_expr(e_push))
-        }
+        },
     }
 }
 
@@ -690,7 +697,7 @@ fn mk_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
 fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
               -> (P<ast::Expr>, P<ast::Expr>) {
     // NB: It appears that the main parser loses its mind if we consider
-    // $foo as a TTNonterminal during the main parse, so we have to re-parse
+    // $foo as a TtNonterminal during the main parse, so we have to re-parse
     // under quote_depth > 0. This is silly and should go away; the _guess_ is
     // it has to do with transition away from supporting old-style macros, so
     // try removing it when enough of them are gone.
@@ -699,7 +706,7 @@ fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     p.quote_depth += 1u;
 
     let cx_expr = p.parse_expr();
-    if !p.eat(&token::COMMA) {
+    if !p.eat(&token::Comma) {
         p.fatal("expected token `,`");
     }
 
index 1f50eb933bb4e80a1c7b731b9a9b0db2aba178a0..76f7b7b0d7b3b18c95f0dbb37fbc479436060da9 100644 (file)
@@ -12,7 +12,7 @@
 use codemap::Span;
 use ext::base::ExtCtxt;
 use ext::base;
-use parse::token::{keywords, is_keyword};
+use parse::token::keywords;
 
 
 pub fn expand_trace_macros(cx: &mut ExtCtxt,
@@ -20,10 +20,10 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt,
                            tt: &[ast::TokenTree])
                            -> Box<base::MacResult+'static> {
     match tt {
-        [ast::TTTok(_, ref tok)] if is_keyword(keywords::True, tok) => {
+        [ast::TtToken(_, ref tok)] if tok.is_keyword(keywords::True) => {
             cx.set_trace_macros(true);
         }
-        [ast::TTTok(_, ref tok)] if is_keyword(keywords::False, tok) => {
+        [ast::TtToken(_, ref tok)] if tok.is_keyword(keywords::False) => {
             cx.set_trace_macros(false);
         }
         _ => cx.span_err(sp, "trace_macros! accepts only `true` or `false`"),
index f2081674fb7c847097768cab5fad31925b42c1f3..9260a45adb954075e849229176d808c4eb222830 100644 (file)
@@ -85,8 +85,9 @@
 use parse::ParseSess;
 use parse::attr::ParserAttr;
 use parse::parser::{LifetimeAndTypesWithoutColons, Parser};
-use parse::token::{Token, EOF, Nonterminal};
+use parse::token::{Token, Nonterminal};
 use parse::token;
+use print::pprust;
 use ptr::P;
 
 use std::rc::Rc;
@@ -226,8 +227,8 @@ pub fn parse_or_else(sess: &ParseSess,
 /// unhygienic comparison)
 pub fn token_name_eq(t1 : &Token, t2 : &Token) -> bool {
     match (t1,t2) {
-        (&token::IDENT(id1,_),&token::IDENT(id2,_))
-        | (&token::LIFETIME(id1),&token::LIFETIME(id2)) =>
+        (&token::Ident(id1,_),&token::Ident(id2,_))
+        | (&token::Lifetime(id1),&token::Lifetime(id2)) =>
             id1.name == id2.name,
         _ => *t1 == *t2
     }
@@ -323,9 +324,9 @@ pub fn parse(sess: &ParseSess,
             } else {
                 match ei.elts[idx].node.clone() {
                   /* need to descend into sequence */
-                  MatchSeq(ref matchers, ref sep, zero_ok,
+                  MatchSeq(ref matchers, ref sep, kleene_op,
                            match_idx_lo, match_idx_hi) => {
-                    if zero_ok {
+                    if kleene_op == ast::ZeroOrMore {
                         let mut new_ei = ei.clone();
                         new_ei.idx += 1u;
                         //we specifically matched zero repeats.
@@ -354,9 +355,9 @@ pub fn parse(sess: &ParseSess,
                     // Built-in nonterminals never start with these tokens,
                     // so we can eliminate them from consideration.
                     match tok {
-                        token::RPAREN |
-                        token::RBRACE |
-                        token::RBRACKET => {},
+                        token::RParen |
+                        token::RBrace |
+                        token::RBracket => {},
                         _ => bb_eis.push(ei)
                     }
                   }
@@ -372,7 +373,7 @@ pub fn parse(sess: &ParseSess,
         }
 
         /* error messages here could be improved with links to orig. rules */
-        if token_name_eq(&tok, &EOF) {
+        if token_name_eq(&tok, &token::Eof) {
             if eof_eis.len() == 1u {
                 let mut v = Vec::new();
                 for dv in eof_eis.get_mut(0).matches.iter_mut() {
@@ -394,7 +395,7 @@ pub fn parse(sess: &ParseSess,
                                 token::get_ident(name),
                                 token::get_ident(bind))).to_string()
                       }
-                      _ => fail!()
+                      _ => panic!()
                     } }).collect::<Vec<String>>().connect(" or ");
                 return Error(sp, format!(
                     "local ambiguity: multiple parsing options: \
@@ -402,7 +403,7 @@ pub fn parse(sess: &ParseSess,
                     nts, next_eis.len()).to_string());
             } else if bb_eis.len() == 0u && next_eis.len() == 0u {
                 return Failure(sp, format!("no rules expected the token `{}`",
-                            token::to_string(&tok)).to_string());
+                            pprust::token_to_string(&tok)).to_string());
             } else if next_eis.len() > 0u {
                 /* Now process the next token */
                 while next_eis.len() > 0u {
@@ -420,7 +421,7 @@ pub fn parse(sess: &ParseSess,
                         parse_nt(&mut rust_parser, name_string.get()))));
                     ei.idx += 1u;
                   }
-                  _ => fail!()
+                  _ => panic!()
                 }
                 cur_eis.push(ei);
 
@@ -447,9 +448,9 @@ pub fn parse_nt(p: &mut Parser, name: &str) -> Nonterminal {
       "ty" => token::NtTy(p.parse_ty(false /* no need to disambiguate*/)),
       // this could be handled like a token, since it is one
       "ident" => match p.token {
-        token::IDENT(sn,b) => { p.bump(); token::NtIdent(box sn,b) }
+        token::Ident(sn,b) => { p.bump(); token::NtIdent(box sn,b) }
         _ => {
-            let token_str = token::to_string(&p.token);
+            let token_str = pprust::token_to_string(&p.token);
             p.fatal((format!("expected ident, found {}",
                              token_str.as_slice())).as_slice())
         }
index 91db3a9d8df50a6b6200a16fb49b894fbb812a6b..85bd5cde3044f1e61c22811ef3e16a89beb5b14c 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use ast::{Ident, Matcher_, Matcher, MatchTok, MatchNonterminal, MatchSeq, TTDelim};
+use ast::{Ident, Matcher_, Matcher, MatchTok, MatchNonterminal, MatchSeq, TtDelimited};
 use ast;
 use codemap::{Span, Spanned, DUMMY_SP};
 use ext::base::{ExtCtxt, MacResult, MacroDef};
@@ -20,7 +20,7 @@
 use parse::parser::Parser;
 use parse::attr::ParserAttr;
 use parse::token::{special_idents, gensym_ident};
-use parse::token::{FAT_ARROW, SEMI, NtMatchers, NtTT, EOF};
+use parse::token::{NtMatchers, NtTT};
 use parse::token;
 use print;
 use ptr::P;
@@ -39,14 +39,14 @@ impl<'a> ParserAnyMacro<'a> {
     /// silently drop anything. `allow_semi` is so that "optional"
     /// semicolons at the end of normal expressions aren't complained
     /// about e.g. the semicolon in `macro_rules! kapow( () => {
-    /// fail!(); } )` doesn't get picked up by .parse_expr(), but it's
+    /// panic!(); } )` doesn't get picked up by .parse_expr(), but it's
     /// allowed to be there.
     fn ensure_complete_parse(&self, allow_semi: bool) {
         let mut parser = self.parser.borrow_mut();
-        if allow_semi && parser.token == SEMI {
+        if allow_semi && parser.token == token::Semi {
             parser.bump()
         }
-        if parser.token != EOF {
+        if parser.token != token::Eof {
             let token_str = parser.this_token_to_string();
             let msg = format!("macro expansion ignores token `{}` and any \
                                following",
@@ -89,7 +89,7 @@ fn make_methods(self: Box<ParserAnyMacro<'a>>) -> Option<SmallVector<P<ast::Meth
         loop {
             let mut parser = self.parser.borrow_mut();
             match parser.token {
-                EOF => break,
+                token::Eof => break,
                 _ => {
                     let attrs = parser.parse_outer_attributes();
                     ret.push(parser.parse_method(attrs, ast::Inherited))
@@ -147,13 +147,9 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
                           rhses: &[Rc<NamedMatch>])
                           -> Box<MacResult+'cx> {
     if cx.trace_macros() {
-        println!("{}! {} {} {}",
+        println!("{}! {{ {} }}",
                  token::get_ident(name),
-                 "{",
-                 print::pprust::tt_to_string(&TTDelim(Rc::new(arg.iter()
-                                                              .map(|x| (*x).clone())
-                                                              .collect()))),
-                 "}");
+                 print::pprust::tts_to_string(arg));
     }
 
     // Which arm's failure should we report? (the one furthest along)
@@ -175,15 +171,12 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
                     // okay, what's your transcriber?
                     MatchedNonterminal(NtTT(ref tt)) => {
                         match **tt {
-                            // cut off delimiters; don't parse 'em
-                            TTDelim(ref tts) => {
-                                (*tts).slice(1u,(*tts).len()-1u)
-                                      .iter()
-                                      .map(|x| (*x).clone())
-                                      .collect()
-                            }
-                            _ => cx.span_fatal(
-                                sp, "macro rhs must be delimited")
+                            // ignore delimiters
+                            TtDelimited(_, ref delimed) => {
+                                let (_, ref tts, _) = **delimed;
+                                tts.clone()
+                            },
+                            _ => cx.span_fatal(sp, "macro rhs must be delimited"),
                         }
                     },
                     _ => cx.span_bug(sp, "bad thing in rhs")
@@ -238,11 +231,13 @@ fn ms(m: Matcher_) -> Matcher {
     let argument_gram = vec!(
         ms(MatchSeq(vec!(
             ms(MatchNonterminal(lhs_nm, special_idents::matchers, 0u)),
-            ms(MatchTok(FAT_ARROW)),
-            ms(MatchNonterminal(rhs_nm, special_idents::tt, 1u))), Some(SEMI), false, 0u, 2u)),
+            ms(MatchTok(token::FatArrow)),
+            ms(MatchNonterminal(rhs_nm, special_idents::tt, 1u))),
+                                Some(token::Semi), ast::OneOrMore, 0u, 2u)),
         //to phase into semicolon-termination instead of
         //semicolon-separation
-        ms(MatchSeq(vec!(ms(MatchTok(SEMI))), None, true, 2u, 2u)));
+        ms(MatchSeq(vec!(ms(MatchTok(token::Semi))), None,
+                            ast::ZeroOrMore, 2u, 2u)));
 
 
     // Parse the macro_rules! invocation (`none` is for no interpolations):
index 35ec37d842af1c6e56aeb703a249bdd96c505590..2c7b583d46021c1f1967d95600562539c0286b6b 100644 (file)
@@ -9,15 +9,16 @@
 // except according to those terms.
 
 use ast;
-use ast::{TokenTree, TTDelim, TTTok, TTSeq, TTNonterminal, Ident};
+use ast::{TokenTree, TtDelimited, TtToken, TtSequence, TtNonterminal, Ident};
 use codemap::{Span, DUMMY_SP};
 use diagnostic::SpanHandler;
 use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
-use parse::token::{EOF, INTERPOLATED, IDENT, Token, NtIdent};
+use parse::token::{Token, NtIdent};
 use parse::token;
 use parse::lexer::TokenAndSpan;
 
 use std::rc::Rc;
+use std::ops::Add;
 use std::collections::HashMap;
 
 ///an unzipping of `TokenTree`s
@@ -44,7 +45,7 @@ pub struct TtReader<'a> {
 }
 
 /// This can do Macro-By-Example transcription. On the other hand, if
-/// `src` contains no `TTSeq`s and `TTNonterminal`s, `interp` can (and
+/// `src` contains no `TtSequence`s and `TtNonterminal`s, `interp` can (and
 /// should) be none.
 pub fn new_tt_reader<'a>(sp_diag: &'a SpanHandler,
                          interp: Option<HashMap<Ident, Rc<NamedMatch>>>,
@@ -65,7 +66,7 @@ pub fn new_tt_reader<'a>(sp_diag: &'a SpanHandler,
         repeat_idx: Vec::new(),
         repeat_len: Vec::new(),
         /* dummy values, never read: */
-        cur_tok: EOF,
+        cur_tok: token::Eof,
         cur_span: DUMMY_SP,
     };
     tt_next_token(&mut r); /* get cur_tok and cur_span set up */
@@ -104,37 +105,45 @@ enum LockstepIterSize {
     LisContradiction(String),
 }
 
-fn lis_merge(lhs: LockstepIterSize, rhs: LockstepIterSize) -> LockstepIterSize {
-    match lhs {
-        LisUnconstrained => rhs.clone(),
-        LisContradiction(_) => lhs.clone(),
-        LisConstraint(l_len, l_id) => match rhs {
-            LisUnconstrained => lhs.clone(),
-            LisContradiction(_) => rhs.clone(),
-            LisConstraint(r_len, _) if l_len == r_len => lhs.clone(),
-            LisConstraint(r_len, r_id) => {
-                let l_n = token::get_ident(l_id);
-                let r_n = token::get_ident(r_id);
-                LisContradiction(format!("inconsistent lockstep iteration: \
-                                          '{}' has {} items, but '{}' has {}",
-                                          l_n, l_len, r_n, r_len).to_string())
-            }
+impl Add<LockstepIterSize, LockstepIterSize> for LockstepIterSize {
+    fn add(&self, other: &LockstepIterSize) -> LockstepIterSize {
+        match *self {
+            LisUnconstrained => other.clone(),
+            LisContradiction(_) => self.clone(),
+            LisConstraint(l_len, l_id) => match *other {
+                LisUnconstrained => self.clone(),
+                LisContradiction(_) => other.clone(),
+                LisConstraint(r_len, _) if l_len == r_len => self.clone(),
+                LisConstraint(r_len, r_id) => {
+                    let l_n = token::get_ident(l_id);
+                    let r_n = token::get_ident(r_id);
+                    LisContradiction(format!("inconsistent lockstep iteration: \
+                                              '{}' has {} items, but '{}' has {}",
+                                              l_n, l_len, r_n, r_len).to_string())
+                }
+            },
         }
     }
 }
 
 fn lockstep_iter_size(t: &TokenTree, r: &TtReader) -> LockstepIterSize {
     match *t {
-        TTDelim(ref tts) | TTSeq(_, ref tts, _, _) => {
-            tts.iter().fold(LisUnconstrained, |lis, tt| {
-                lis_merge(lis, lockstep_iter_size(tt, r))
+        TtDelimited(_, ref delimed) => {
+            let (_, ref tts, _) = **delimed;
+            tts.iter().fold(LisUnconstrained, |size, tt| {
+                size + lockstep_iter_size(tt, r)
             })
-        }
-        TTTok(..) => LisUnconstrained,
-        TTNonterminal(_, name) => match *lookup_cur_matched(r, name) {
+        },
+        TtSequence(_, ref tts, _, _) => {
+            tts.iter().fold(LisUnconstrained, |size, tt| {
+                size + lockstep_iter_size(tt, r)
+            })
+        },
+        TtToken(..) => LisUnconstrained,
+        TtNonterminal(_, name) => match *lookup_cur_matched(r, name) {
             MatchedNonterminal(_) => LisUnconstrained,
             MatchedSeq(ref ads, _) => LisConstraint(ads.len(), name)
-        }
+        },
     }
 }
 
@@ -149,7 +158,7 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
     loop {
         let should_pop = match r.stack.last() {
             None => {
-                assert_eq!(ret_val.tok, EOF);
+                assert_eq!(ret_val.tok, token::Eof);
                 return ret_val;
             }
             Some(frame) => {
@@ -166,7 +175,7 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
             let prev = r.stack.pop().unwrap();
             match r.stack.last_mut() {
                 None => {
-                    r.cur_tok = EOF;
+                    r.cur_tok = token::Eof;
                     return ret_val;
                 }
                 Some(frame) => {
@@ -189,32 +198,38 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
             }
         }
     }
-    loop { /* because it's easiest, this handles `TTDelim` not starting
-              with a `TTTok`, even though it won't happen */
+    loop { /* because it's easiest, this handles `TtDelimited` not starting
+              with a `TtToken`, even though it won't happen */
         let t = {
             let frame = r.stack.last().unwrap();
             // FIXME(pcwalton): Bad copy.
             (*frame.forest)[frame.idx].clone()
         };
         match t {
-            TTDelim(tts) => {
+            TtDelimited(_, ref delimed) => {
+                let (ref open, ref tts, ref close) = **delimed;
+                let mut forest = Vec::with_capacity(1 + tts.len() + 1);
+                forest.push(open.to_tt());
+                forest.extend(tts.iter().map(|x| (*x).clone()));
+                forest.push(close.to_tt());
+
                 r.stack.push(TtFrame {
-                    forest: tts,
+                    forest: Rc::new(forest),
                     idx: 0,
                     dotdotdoted: false,
                     sep: None
                 });
                 // if this could be 0-length, we'd need to potentially recur here
             }
-            TTTok(sp, tok) => {
+            TtToken(sp, tok) => {
                 r.cur_span = sp;
                 r.cur_tok = tok;
                 r.stack.last_mut().unwrap().idx += 1;
                 return ret_val;
             }
-            TTSeq(sp, tts, sep, zerok) => {
+            TtSequence(sp, tts, sep, kleene_op) => {
                 // FIXME(pcwalton): Bad copy.
-                match lockstep_iter_size(&TTSeq(sp, tts.clone(), sep.clone(), zerok), r) {
+                match lockstep_iter_size(&TtSequence(sp, tts.clone(), sep.clone(), kleene_op), r) {
                     LisUnconstrained => {
                         r.sp_diag.span_fatal(
                             sp.clone(), /* blame macro writer */
@@ -228,7 +243,7 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
                         }
                     LisConstraint(len, _) => {
                         if len == 0 {
-                            if !zerok {
+                            if kleene_op == ast::OneOrMore {
                                 // FIXME #2887 blame invoker
                                 r.sp_diag.span_fatal(sp.clone(),
                                                      "this must repeat at least once");
@@ -249,7 +264,7 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
                 }
             }
             // FIXME #2887: think about span stuff here
-            TTNonterminal(sp, ident) => {
+            TtNonterminal(sp, ident) => {
                 r.stack.last_mut().unwrap().idx += 1;
                 match *lookup_cur_matched(r, ident) {
                     /* sidestep the interpolation tricks for ident because
@@ -257,13 +272,13 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
                        (b) we actually can, since it's a token. */
                     MatchedNonterminal(NtIdent(box sn, b)) => {
                         r.cur_span = sp;
-                        r.cur_tok = IDENT(sn,b);
+                        r.cur_tok = token::Ident(sn,b);
                         return ret_val;
                     }
                     MatchedNonterminal(ref other_whole_nt) => {
                         // FIXME(pcwalton): Bad copy.
                         r.cur_span = sp;
-                        r.cur_tok = INTERPOLATED((*other_whole_nt).clone());
+                        r.cur_tok = token::Interpolated((*other_whole_nt).clone());
                         return ret_val;
                     }
                     MatchedSeq(..) => {
index ceef190f5d4535731614987efddfb2ed1a7b91d3..47ca66b0b4923cd868aa40966878dae5075b85b0 100644 (file)
@@ -171,7 +171,7 @@ fn fold_local(&mut self, l: P<Local>) -> P<Local> {
     }
 
     fn fold_mac(&mut self, _macro: Mac) -> Mac {
-        fail!("fold_mac disabled by default");
+        panic!("fold_mac disabled by default");
         // NB: see note about macros above.
         // if you really want a folder that
         // works on macros, use this
@@ -569,16 +569,29 @@ pub fn noop_fold_arg<T: Folder>(Arg {id, pat, ty}: Arg, fld: &mut T) -> Arg {
 
 pub fn noop_fold_tt<T: Folder>(tt: &TokenTree, fld: &mut T) -> TokenTree {
     match *tt {
-        TTTok(span, ref tok) =>
-            TTTok(span, fld.fold_token(tok.clone())),
-        TTDelim(ref tts) => TTDelim(Rc::new(fld.fold_tts(tts.as_slice()))),
-        TTSeq(span, ref pattern, ref sep, is_optional) =>
-            TTSeq(span,
-                  Rc::new(fld.fold_tts(pattern.as_slice())),
-                  sep.clone().map(|tok| fld.fold_token(tok)),
-                  is_optional),
-        TTNonterminal(sp,ref ident) =>
-            TTNonterminal(sp,fld.fold_ident(*ident))
+        TtToken(span, ref tok) =>
+            TtToken(span, fld.fold_token(tok.clone())),
+        TtDelimited(span, ref delimed) => {
+            let (ref open, ref tts, ref close) = **delimed;
+            TtDelimited(span, Rc::new((
+                            Delimiter {
+                                span: open.span,
+                                token: fld.fold_token(open.token.clone())
+                            },
+                            fld.fold_tts(tts.as_slice()),
+                            Delimiter {
+                                span: close.span,
+                                token: fld.fold_token(close.token.clone())
+                            },
+                        )))
+        },
+        TtSequence(span, ref pattern, ref sep, is_optional) =>
+            TtSequence(span,
+                       Rc::new(fld.fold_tts(pattern.as_slice())),
+                       sep.clone().map(|tok| fld.fold_token(tok)),
+                       is_optional),
+        TtNonterminal(sp,ref ident) =>
+            TtNonterminal(sp,fld.fold_ident(*ident))
     }
 }
 
@@ -589,11 +602,11 @@ pub fn noop_fold_tts<T: Folder>(tts: &[TokenTree], fld: &mut T) -> Vec<TokenTree
 // apply ident folder if it's an ident, apply other folds to interpolated nodes
 pub fn noop_fold_token<T: Folder>(t: token::Token, fld: &mut T) -> token::Token {
     match t {
-        token::IDENT(id, followed_by_colons) => {
-            token::IDENT(fld.fold_ident(id), followed_by_colons)
+        token::Ident(id, followed_by_colons) => {
+            token::Ident(fld.fold_ident(id), followed_by_colons)
         }
-        token::LIFETIME(id) => token::LIFETIME(fld.fold_ident(id)),
-        token::INTERPOLATED(nt) => token::INTERPOLATED(fld.fold_interpolated(nt)),
+        token::Lifetime(id) => token::Lifetime(fld.fold_ident(id)),
+        token::Interpolated(nt) => token::Interpolated(fld.fold_interpolated(nt)),
         _ => t
     }
 }
@@ -1391,7 +1404,7 @@ macro_rules! assert_pred (
                 let a_val = $a;
                 let b_val = $b;
                 if !(pred_val(a_val.as_slice(),b_val.as_slice())) {
-                    fail!("expected args satisfying {}, got {} and {}",
+                    panic!("expected args satisfying {}, got {} and {}",
                           $predname, a_val, b_val);
                 }
             }
index e5c37e5041abf43a984c2716fdc56d8c5bcdfe25..4f09b34557c74e93ab2938474406992381a77e14 100644 (file)
@@ -74,7 +74,7 @@ pub fn from_vec(mut v: Vec<T>) -> OwnedSlice<T> {
     pub fn into_vec(self) -> Vec<T> {
         // null is ok, because len == 0 in that case, as required by Vec.
         unsafe {
-            let ret = Vec::from_raw_parts(self.len, self.len, self.data);
+            let ret = Vec::from_raw_parts(self.data, self.len, self.len);
             // the vector owns the allocation now
             mem::forget(self);
             ret
index 17dd546ad59d1d46d1f067b56ff78d4f17834767..458a5042a7e234df1828f29caa799ca3c6adbbca 100644 (file)
@@ -14,7 +14,6 @@
 use parse::common::*; //resolve bug?
 use parse::token;
 use parse::parser::Parser;
-use parse::token::INTERPOLATED;
 use ptr::P;
 
 /// A parser that can parse attributes.
@@ -36,10 +35,10 @@ fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute> {
             debug!("parse_outer_attributes: self.token={}",
                    self.token);
             match self.token {
-              token::POUND => {
+              token::Pound => {
                 attrs.push(self.parse_attribute(false));
               }
-              token::DOC_COMMENT(s) => {
+              token::DocComment(s) => {
                 let attr = ::attr::mk_sugared_doc_attr(
                     attr::mk_attr_id(),
                     self.id_to_interned_str(s.ident()),
@@ -66,11 +65,11 @@ fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute {
         debug!("parse_attributes: permit_inner={} self.token={}",
                permit_inner, self.token);
         let (span, value, mut style) = match self.token {
-            token::POUND => {
+            token::Pound => {
                 let lo = self.span.lo;
                 self.bump();
 
-                let style = if self.eat(&token::NOT) {
+                let style = if self.eat(&token::Not) {
                     if !permit_inner {
                         let span = self.span;
                         self.span_err(span,
@@ -82,10 +81,10 @@ fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute {
                     ast::AttrOuter
                 };
 
-                self.expect(&token::LBRACKET);
+                self.expect(&token::LBracket);
                 let meta_item = self.parse_meta_item();
                 let hi = self.span.hi;
-                self.expect(&token::RBRACKET);
+                self.expect(&token::RBracket);
 
                 (mk_sp(lo, hi), meta_item, style)
             }
@@ -96,7 +95,7 @@ fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute {
             }
         };
 
-        if permit_inner && self.eat(&token::SEMI) {
+        if permit_inner && self.eat(&token::Semi) {
             self.span_warn(span, "this inner attribute syntax is deprecated. \
                            The new syntax is `#![foo]`, with a bang and no semicolon.");
             style = ast::AttrInner;
@@ -130,10 +129,10 @@ fn parse_inner_attrs_and_next(&mut self)
         let mut next_outer_attrs: Vec<ast::Attribute> = Vec::new();
         loop {
             let attr = match self.token {
-                token::POUND => {
+                token::Pound => {
                     self.parse_attribute(true)
                 }
-                token::DOC_COMMENT(s) => {
+                token::DocComment(s) => {
                     // we need to get the position of this token before we bump.
                     let Span { lo, hi, .. } = self.span;
                     self.bump();
@@ -161,7 +160,7 @@ fn parse_inner_attrs_and_next(&mut self)
     /// | IDENT meta_seq
     fn parse_meta_item(&mut self) -> P<ast::MetaItem> {
         let nt_meta = match self.token {
-            token::INTERPOLATED(token::NtMeta(ref e)) => {
+            token::Interpolated(token::NtMeta(ref e)) => {
                 Some(e.clone())
             }
             _ => None
@@ -179,7 +178,7 @@ fn parse_meta_item(&mut self) -> P<ast::MetaItem> {
         let ident = self.parse_ident();
         let name = self.id_to_interned_str(ident);
         match self.token {
-            token::EQ => {
+            token::Eq => {
                 self.bump();
                 let lit = self.parse_lit();
                 // FIXME #623 Non-string meta items are not serialized correctly;
@@ -195,7 +194,7 @@ fn parse_meta_item(&mut self) -> P<ast::MetaItem> {
                 let hi = self.span.hi;
                 P(spanned(lo, hi, ast::MetaNameValue(name, lit)))
             }
-            token::LPAREN => {
+            token::LParen => {
                 let inner_items = self.parse_meta_seq();
                 let hi = self.span.hi;
                 P(spanned(lo, hi, ast::MetaList(name, inner_items)))
@@ -209,15 +208,15 @@ fn parse_meta_item(&mut self) -> P<ast::MetaItem> {
 
     /// matches meta_seq = ( COMMASEP(meta_item) )
     fn parse_meta_seq(&mut self) -> Vec<P<ast::MetaItem>> {
-        self.parse_seq(&token::LPAREN,
-                       &token::RPAREN,
-                       seq_sep_trailing_disallowed(token::COMMA),
+        self.parse_seq(&token::LParen,
+                       &token::RParen,
+                       seq_sep_trailing_disallowed(token::Comma),
                        |p| p.parse_meta_item()).node
     }
 
     fn parse_optional_meta(&mut self) -> Vec<P<ast::MetaItem>> {
         match self.token {
-            token::LPAREN => self.parse_meta_seq(),
+            token::LParen => self.parse_meta_seq(),
             _ => Vec::new()
         }
     }
index 3298eae125a638c85a2349502ae0583deb98bab8..5a7679570bf8d7b7011650566291ab357e7d649e 100644 (file)
@@ -15,7 +15,7 @@
 use parse::lexer::{StringReader, TokenAndSpan};
 use parse::lexer::is_block_doc_comment;
 use parse::lexer;
-use parse::token;
+use print::pprust;
 
 use std::io;
 use std::str;
@@ -142,7 +142,7 @@ fn horizontal_trim(lines: Vec<String> ) -> Vec<String> {
         return lines.connect("\n");
     }
 
-    fail!("not a doc-comment: {}", comment);
+    panic!("not a doc-comment: {}", comment);
 }
 
 fn push_blank_line_comment(rdr: &StringReader, comments: &mut Vec<Comment>) {
@@ -322,7 +322,7 @@ fn consume_comment(rdr: &mut StringReader,
         read_block_comment(rdr, code_to_the_left, comments);
     } else if rdr.curr_is('#') && rdr.nextch_is('!') {
         read_shebang_comment(rdr, code_to_the_left, comments);
-    } else { fail!(); }
+    } else { panic!(); }
     debug!("<<< consume comment");
 }
 
@@ -367,13 +367,13 @@ pub fn gather_comments_and_literals(span_diagnostic: &diagnostic::SpanHandler,
         rdr.next_token();
         //discard, and look ahead; we're working with internal state
         let TokenAndSpan { tok, sp } = rdr.peek();
-        if token::is_lit(&tok) {
+        if tok.is_lit() {
             rdr.with_str_from(bstart, |s| {
                 debug!("tok lit: {}", s);
                 literals.push(Literal {lit: s.to_string(), pos: sp.lo});
             })
         } else {
-            debug!("tok: {}", token::to_string(&tok));
+            debug!("tok: {}", pprust::token_to_string(&tok));
         }
         first_read = false;
     }
index 55d071b8d6005151707bf60e461ca0ea64763cef..3a6cf610b4f8b058b0d026b21c7dd9e9bb3609f5 100644 (file)
@@ -69,7 +69,7 @@ fn is_eof(&self) -> bool { self.curr.is_none() }
     /// Return the next token. EFFECT: advances the string_reader.
     fn next_token(&mut self) -> TokenAndSpan {
         let ret_val = TokenAndSpan {
-            tok: replace(&mut self.peek_tok, token::UNDERSCORE),
+            tok: replace(&mut self.peek_tok, token::Underscore),
             sp: self.peek_span,
         };
         self.advance_token();
@@ -92,7 +92,7 @@ fn peek(&self) -> TokenAndSpan {
 
 impl<'a> Reader for TtReader<'a> {
     fn is_eof(&self) -> bool {
-        self.cur_tok == token::EOF
+        self.cur_tok == token::Eof
     }
     fn next_token(&mut self) -> TokenAndSpan {
         let r = tt_next_token(self);
@@ -136,7 +136,7 @@ pub fn new_raw<'b>(span_diagnostic: &'b SpanHandler,
             curr: Some('\n'),
             filemap: filemap,
             /* dummy values; not read */
-            peek_tok: token::EOF,
+            peek_tok: token::Eof,
             peek_span: codemap::DUMMY_SP,
             read_embedded_ident: false,
         };
@@ -213,7 +213,7 @@ fn advance_token(&mut self) {
             },
             None => {
                 if self.is_eof() {
-                    self.peek_tok = token::EOF;
+                    self.peek_tok = token::Eof;
                 } else {
                     let start_bytepos = self.last_pos;
                     self.peek_tok = self.next_token_inner();
@@ -396,9 +396,9 @@ fn scan_comment(&mut self) -> Option<TokenAndSpan> {
                         return self.with_str_from(start_bpos, |string| {
                             // but comments with only more "/"s are not
                             let tok = if is_doc_comment(string) {
-                                token::DOC_COMMENT(token::intern(string))
+                                token::DocComment(token::intern(string))
                             } else {
-                                token::COMMENT
+                                token::Comment
                             };
 
                             return Some(TokenAndSpan{
@@ -410,7 +410,7 @@ fn scan_comment(&mut self) -> Option<TokenAndSpan> {
                         let start_bpos = self.last_pos - BytePos(2);
                         while !self.curr_is('\n') && !self.is_eof() { self.bump(); }
                         return Some(TokenAndSpan {
-                            tok: token::COMMENT,
+                            tok: token::Comment,
                             sp: codemap::mk_sp(start_bpos, self.last_pos)
                         });
                     }
@@ -440,7 +440,7 @@ fn scan_comment(&mut self) -> Option<TokenAndSpan> {
                     let start = self.last_pos;
                     while !self.curr_is('\n') && !self.is_eof() { self.bump(); }
                     return Some(TokenAndSpan {
-                        tok: token::SHEBANG(self.name_from(start)),
+                        tok: token::Shebang(self.name_from(start)),
                         sp: codemap::mk_sp(start, self.last_pos)
                     });
                 }
@@ -466,7 +466,7 @@ fn scan_whitespace_or_comment(&mut self) -> Option<TokenAndSpan> {
                 let start_bpos = self.last_pos;
                 while is_whitespace(self.curr) { self.bump(); }
                 let c = Some(TokenAndSpan {
-                    tok: token::WS,
+                    tok: token::Whitespace,
                     sp: codemap::mk_sp(start_bpos, self.last_pos)
                 });
                 debug!("scanning whitespace: {}", c);
@@ -519,9 +519,9 @@ fn scan_block_comment(&mut self) -> Option<TokenAndSpan> {
                     self.translate_crlf(start_bpos, string,
                                         "bare CR not allowed in block doc-comment")
                 } else { string.into_maybe_owned() };
-                token::DOC_COMMENT(token::intern(string.as_slice()))
+                token::DocComment(token::intern(string.as_slice()))
             } else {
-                token::COMMENT
+                token::Comment
             };
 
             Some(TokenAndSpan{
@@ -555,8 +555,8 @@ fn bump_expecting_char<'a,D:fmt::Show>(r: &mut StringReader<'a>,
                                                whence: &str) {
             match r.curr {
                 Some(r_c) if r_c == c => r.bump(),
-                Some(r_c) => fail!("expected {}, hit {}, {}", described_c, r_c, whence),
-                None      => fail!("expected {}, hit EOF, {}", described_c, whence),
+                Some(r_c) => panic!("expected {}, hit {}, {}", described_c, r_c, whence),
+                None      => panic!("expected {}, hit EOF, {}", described_c, whence),
             }
         }
 
@@ -577,7 +577,7 @@ fn bump_expecting_char<'a,D:fmt::Show>(r: &mut StringReader<'a>,
         self.scan_digits(base);
         let encoded_name : u32 = self.with_str_from(start_bpos, |s| {
             num::from_str_radix(s, 10).unwrap_or_else(|| {
-                fail!("expected digits representing a name, got `{}`, {}, range [{},{}]",
+                panic!("expected digits representing a name, got `{}`, {}, range [{},{}]",
                       s, whence, start_bpos, self.last_pos);
             })
         });
@@ -595,7 +595,7 @@ fn bump_expecting_char<'a,D:fmt::Show>(r: &mut StringReader<'a>,
         self.scan_digits(base);
         let encoded_ctxt : ast::SyntaxContext = self.with_str_from(start_bpos, |s| {
             num::from_str_radix(s, 10).unwrap_or_else(|| {
-                fail!("expected digits representing a ctxt, got `{}`, {}", s, whence);
+                panic!("expected digits representing a ctxt, got `{}`, {}", s, whence);
             })
         });
 
@@ -642,17 +642,17 @@ fn scan_number(&mut self, c: char) -> token::Token {
                 }
                 'u' | 'i' => {
                     self.scan_int_suffix();
-                    return token::LIT_INTEGER(self.name_from(start_bpos));
+                    return token::LitInteger(self.name_from(start_bpos));
                 },
                 'f' => {
                     let last_pos = self.last_pos;
                     self.scan_float_suffix();
                     self.check_float_base(start_bpos, last_pos, base);
-                    return token::LIT_FLOAT(self.name_from(start_bpos));
+                    return token::LitFloat(self.name_from(start_bpos));
                 }
                 _ => {
                     // just a 0
-                    return token::LIT_INTEGER(self.name_from(start_bpos));
+                    return token::LitInteger(self.name_from(start_bpos));
                 }
             }
         } else if c.is_digit_radix(10) {
@@ -665,7 +665,7 @@ fn scan_number(&mut self, c: char) -> token::Token {
             self.err_span_(start_bpos, self.last_pos, "no valid digits found for number");
             // eat any suffix
             self.scan_int_suffix();
-            return token::LIT_INTEGER(token::intern("0"));
+            return token::LitInteger(token::intern("0"));
         }
 
         // might be a float, but don't be greedy if this is actually an
@@ -683,13 +683,13 @@ fn scan_number(&mut self, c: char) -> token::Token {
             }
             let last_pos = self.last_pos;
             self.check_float_base(start_bpos, last_pos, base);
-            return token::LIT_FLOAT(self.name_from(start_bpos));
+            return token::LitFloat(self.name_from(start_bpos));
         } else if self.curr_is('f') {
             // or it might be an integer literal suffixed as a float
             self.scan_float_suffix();
             let last_pos = self.last_pos;
             self.check_float_base(start_bpos, last_pos, base);
-            return token::LIT_FLOAT(self.name_from(start_bpos));
+            return token::LitFloat(self.name_from(start_bpos));
         } else {
             // it might be a float if it has an exponent
             if self.curr_is('e') || self.curr_is('E') {
@@ -697,11 +697,11 @@ fn scan_number(&mut self, c: char) -> token::Token {
                 self.scan_float_suffix();
                 let last_pos = self.last_pos;
                 self.check_float_base(start_bpos, last_pos, base);
-                return token::LIT_FLOAT(self.name_from(start_bpos));
+                return token::LitFloat(self.name_from(start_bpos));
             }
             // but we certainly have an integer!
             self.scan_int_suffix();
-            return token::LIT_INTEGER(self.name_from(start_bpos));
+            return token::LitInteger(self.name_from(start_bpos));
         }
     }
 
@@ -889,13 +889,13 @@ fn check_float_base(&mut self, start_bpos: BytePos, last_bpos: BytePos, base: ui
         }
     }
 
-    fn binop(&mut self, op: token::BinOp) -> token::Token {
+    fn binop(&mut self, op: token::BinOpToken) -> token::Token {
         self.bump();
         if self.curr_is('=') {
             self.bump();
-            return token::BINOPEQ(op);
+            return token::BinOpEq(op);
         } else {
-            return token::BINOP(op);
+            return token::BinOp(op);
         }
     }
 
@@ -919,14 +919,16 @@ fn next_token_inner(&mut self) -> token::Token {
 
             return self.with_str_from(start, |string| {
                 if string == "_" {
-                    token::UNDERSCORE
+                    token::Underscore
                 } else {
-                    let is_mod_name = self.curr_is(':') && self.nextch_is(':');
-
                     // FIXME: perform NFKC normalization here. (Issue #2253)
-                    token::IDENT(str_to_ident(string), is_mod_name)
+                    if self.curr_is(':') && self.nextch_is(':') {
+                        token::Ident(str_to_ident(string), token::ModName)
+                    } else {
+                        token::Ident(str_to_ident(string), token::Plain)
+                    }
                 }
-            })
+            });
         }
 
         if is_dec_digit(c) {
@@ -937,8 +939,11 @@ fn next_token_inner(&mut self) -> token::Token {
             match (c.unwrap(), self.nextch(), self.nextnextch()) {
                 ('\x00', Some('n'), Some('a')) => {
                     let ast_ident = self.scan_embedded_hygienic_ident();
-                    let is_mod_name = self.curr_is(':') && self.nextch_is(':');
-                    return token::IDENT(ast_ident, is_mod_name);
+                    return if self.curr_is(':') && self.nextch_is(':') {
+                        token::Ident(ast_ident, token::ModName)
+                    } else {
+                        token::Ident(ast_ident, token::Plain)
+                    };
                 }
                 _ => {}
             }
@@ -946,84 +951,84 @@ fn next_token_inner(&mut self) -> token::Token {
 
         match c.expect("next_token_inner called at EOF") {
           // One-byte tokens.
-          ';' => { self.bump(); return token::SEMI; }
-          ',' => { self.bump(); return token::COMMA; }
+          ';' => { self.bump(); return token::Semi; }
+          ',' => { self.bump(); return token::Comma; }
           '.' => {
               self.bump();
               return if self.curr_is('.') {
                   self.bump();
                   if self.curr_is('.') {
                       self.bump();
-                      token::DOTDOTDOT
+                      token::DotDotDot
                   } else {
-                      token::DOTDOT
+                      token::DotDot
                   }
               } else {
-                  token::DOT
+                  token::Dot
               };
           }
-          '(' => { self.bump(); return token::LPAREN; }
-          ')' => { self.bump(); return token::RPAREN; }
-          '{' => { self.bump(); return token::LBRACE; }
-          '}' => { self.bump(); return token::RBRACE; }
-          '[' => { self.bump(); return token::LBRACKET; }
-          ']' => { self.bump(); return token::RBRACKET; }
-          '@' => { self.bump(); return token::AT; }
-          '#' => { self.bump(); return token::POUND; }
-          '~' => { self.bump(); return token::TILDE; }
-          '?' => { self.bump(); return token::QUESTION; }
+          '(' => { self.bump(); return token::LParen; }
+          ')' => { self.bump(); return token::RParen; }
+          '{' => { self.bump(); return token::LBrace; }
+          '}' => { self.bump(); return token::RBrace; }
+          '[' => { self.bump(); return token::LBracket; }
+          ']' => { self.bump(); return token::RBracket; }
+          '@' => { self.bump(); return token::At; }
+          '#' => { self.bump(); return token::Pound; }
+          '~' => { self.bump(); return token::Tilde; }
+          '?' => { self.bump(); return token::Question; }
           ':' => {
             self.bump();
             if self.curr_is(':') {
                 self.bump();
-                return token::MOD_SEP;
+                return token::ModSep;
             } else {
-                return token::COLON;
+                return token::Colon;
             }
           }
 
-          '$' => { self.bump(); return token::DOLLAR; }
+          '$' => { self.bump(); return token::Dollar; }
 
           // Multi-byte tokens.
           '=' => {
             self.bump();
             if self.curr_is('=') {
                 self.bump();
-                return token::EQEQ;
+                return token::EqEq;
             } else if self.curr_is('>') {
                 self.bump();
-                return token::FAT_ARROW;
+                return token::FatArrow;
             } else {
-                return token::EQ;
+                return token::Eq;
             }
           }
           '!' => {
             self.bump();
             if self.curr_is('=') {
                 self.bump();
-                return token::NE;
-            } else { return token::NOT; }
+                return token::Ne;
+            } else { return token::Not; }
           }
           '<' => {
             self.bump();
             match self.curr.unwrap_or('\x00') {
-              '=' => { self.bump(); return token::LE; }
-              '<' => { return self.binop(token::SHL); }
+              '=' => { self.bump(); return token::Le; }
+              '<' => { return self.binop(token::Shl); }
               '-' => {
                 self.bump();
                 match self.curr.unwrap_or('\x00') {
-                  _ => { return token::LARROW; }
+                  _ => { return token::LArrow; }
                 }
               }
-              _ => { return token::LT; }
+              _ => { return token::Lt; }
             }
           }
           '>' => {
             self.bump();
             match self.curr.unwrap_or('\x00') {
-              '=' => { self.bump(); return token::GE; }
-              '>' => { return self.binop(token::SHR); }
-              _ => { return token::GT; }
+              '=' => { self.bump(); return token::Ge; }
+              '>' => { return self.binop(token::Shr); }
+              _ => { return token::Gt; }
             }
           }
           '\'' => {
@@ -1056,22 +1061,21 @@ fn next_token_inner(&mut self) -> token::Token {
                         str_to_ident(lifetime_name)
                     });
                 let keyword_checking_token =
-                    &token::IDENT(keyword_checking_ident, false);
+                    &token::Ident(keyword_checking_ident, token::Plain);
                 let last_bpos = self.last_pos;
-                if token::is_keyword(token::keywords::Self,
-                                     keyword_checking_token) {
+                if keyword_checking_token.is_keyword(token::keywords::Self) {
                     self.err_span_(start,
                                    last_bpos,
                                    "invalid lifetime name: 'self \
                                     is no longer a special lifetime");
-                } else if token::is_any_keyword(keyword_checking_token) &&
-                    !token::is_keyword(token::keywords::Static,
-                                       keyword_checking_token) {
+                } else if keyword_checking_token.is_any_keyword() &&
+                    !keyword_checking_token.is_keyword(token::keywords::Static)
+                {
                     self.err_span_(start,
                                    last_bpos,
                                    "invalid lifetime name");
                 }
-                return token::LIFETIME(ident);
+                return token::Lifetime(ident);
             }
 
             // Otherwise it is a character constant:
@@ -1087,7 +1091,7 @@ fn next_token_inner(&mut self) -> token::Token {
             }
             let id = if valid { self.name_from(start) } else { token::intern("0") };
             self.bump(); // advance curr past token
-            return token::LIT_CHAR(id);
+            return token::LitChar(id);
           }
           'b' => {
             self.bump();
@@ -1095,7 +1099,7 @@ fn next_token_inner(&mut self) -> token::Token {
                 Some('\'') => self.scan_byte(),
                 Some('"') => self.scan_byte_string(),
                 Some('r') => self.scan_raw_byte_string(),
-                _ => unreachable!()  // Should have been a token::IDENT above.
+                _ => unreachable!()  // Should have been a token::Ident above.
             };
 
           }
@@ -1118,7 +1122,7 @@ fn next_token_inner(&mut self) -> token::Token {
             let id = if valid { self.name_from(start_bpos + BytePos(1)) }
                      else { token::intern("??") };
             self.bump();
-            return token::LIT_STR(id);
+            return token::LitStr(id);
           }
           'r' => {
             let start_bpos = self.last_pos;
@@ -1185,33 +1189,33 @@ fn next_token_inner(&mut self) -> token::Token {
             } else {
                 token::intern("??")
             };
-            return token::LIT_STR_RAW(id, hash_count);
+            return token::LitStrRaw(id, hash_count);
           }
           '-' => {
             if self.nextch_is('>') {
                 self.bump();
                 self.bump();
-                return token::RARROW;
-            } else { return self.binop(token::MINUS); }
+                return token::RArrow;
+            } else { return self.binop(token::Minus); }
           }
           '&' => {
             if self.nextch_is('&') {
                 self.bump();
                 self.bump();
-                return token::ANDAND;
-            } else { return self.binop(token::AND); }
+                return token::AndAnd;
+            } else { return self.binop(token::And); }
           }
           '|' => {
             match self.nextch() {
-              Some('|') => { self.bump(); self.bump(); return token::OROR; }
-              _ => { return self.binop(token::OR); }
+              Some('|') => { self.bump(); self.bump(); return token::OrOr; }
+              _ => { return self.binop(token::Or); }
             }
           }
-          '+' => { return self.binop(token::PLUS); }
-          '*' => { return self.binop(token::STAR); }
-          '/' => { return self.binop(token::SLASH); }
-          '^' => { return self.binop(token::CARET); }
-          '%' => { return self.binop(token::PERCENT); }
+          '+' => { return self.binop(token::Plus); }
+          '*' => { return self.binop(token::Star); }
+          '/' => { return self.binop(token::Slash); }
+          '^' => { return self.binop(token::Caret); }
+          '%' => { return self.binop(token::Percent); }
           c => {
               let last_bpos = self.last_pos;
               let bpos = self.pos;
@@ -1275,7 +1279,7 @@ fn scan_byte(&mut self) -> token::Token {
 
         let id = if valid { self.name_from(start) } else { token::intern("??") };
         self.bump(); // advance curr past token
-        return token::LIT_BYTE(id);
+        return token::LitByte(id);
     }
 
     fn scan_byte_string(&mut self) -> token::Token {
@@ -1297,7 +1301,7 @@ fn scan_byte_string(&mut self) -> token::Token {
         }
         let id = if valid { self.name_from(start) } else { token::intern("??") };
         self.bump();
-        return token::LIT_BINARY(id);
+        return token::LitBinary(id);
     }
 
     fn scan_raw_byte_string(&mut self) -> token::Token {
@@ -1348,7 +1352,7 @@ fn scan_raw_byte_string(&mut self) -> token::Token {
             self.bump();
         }
         self.bump();
-        return token::LIT_BINARY_RAW(self.name_from_to(content_start_bpos, content_end_bpos),
+        return token::LitBinaryRaw(self.name_from_to(content_start_bpos, content_end_bpos),
                                      hash_count);
     }
 }
@@ -1431,20 +1435,20 @@ fn setup<'a>(span_handler: &'a diagnostic::SpanHandler,
             "/* my source file */ \
              fn main() { println!(\"zebra\"); }\n".to_string());
         let id = str_to_ident("fn");
-        assert_eq!(string_reader.next_token().tok, token::COMMENT);
-        assert_eq!(string_reader.next_token().tok, token::WS);
+        assert_eq!(string_reader.next_token().tok, token::Comment);
+        assert_eq!(string_reader.next_token().tok, token::Whitespace);
         let tok1 = string_reader.next_token();
         let tok2 = TokenAndSpan{
-            tok:token::IDENT(id, false),
+            tok:token::Ident(id, token::Plain),
             sp:Span {lo:BytePos(21),hi:BytePos(23),expn_id: NO_EXPANSION}};
         assert_eq!(tok1,tok2);
-        assert_eq!(string_reader.next_token().tok, token::WS);
+        assert_eq!(string_reader.next_token().tok, token::Whitespace);
         // the 'main' id is already read:
         assert_eq!(string_reader.last_pos.clone(), BytePos(28));
         // read another token:
         let tok3 = string_reader.next_token();
         let tok4 = TokenAndSpan{
-            tok:token::IDENT(str_to_ident("main"), false),
+            tok:token::Ident(str_to_ident("main"), token::Plain),
             sp:Span {lo:BytePos(24),hi:BytePos(28),expn_id: NO_EXPANSION}};
         assert_eq!(tok3,tok4);
         // the lparen is already read:
@@ -1459,66 +1463,72 @@ fn check_tokenization (mut string_reader: StringReader, expected: Vec<token::Tok
         }
     }
 
-    // make the identifier by looking up the string in the interner
+    #[cfg(stage0)]
     fn mk_ident (id: &str, is_mod_name: bool) -> token::Token {
-        token::IDENT (str_to_ident(id),is_mod_name)
+        token::Ident(str_to_ident(id), is_mod_name)
+    }
+
+    // make the identifier by looking up the string in the interner
+    #[cfg(not(stage0))]
+    fn mk_ident(id: &str, style: token::IdentStyle) -> token::Token {
+        token::Ident(str_to_ident(id), style)
     }
 
     #[test] fn doublecolonparsing () {
         check_tokenization(setup(&mk_sh(), "a b".to_string()),
-                           vec!(mk_ident("a",false),
-                            token::WS,
-                             mk_ident("b",false)));
+                           vec![mk_ident("a", token::Plain),
+                                token::Whitespace,
+                                mk_ident("b", token::Plain)]);
     }
 
     #[test] fn dcparsing_2 () {
         check_tokenization(setup(&mk_sh(), "a::b".to_string()),
-                           vec!(mk_ident("a",true),
-                             token::MOD_SEP,
-                             mk_ident("b",false)));
+                           vec![mk_ident("a",token::ModName),
+                                token::ModSep,
+                                mk_ident("b", token::Plain)]);
     }
 
     #[test] fn dcparsing_3 () {
         check_tokenization(setup(&mk_sh(), "a ::b".to_string()),
-                           vec!(mk_ident("a",false),
-                             token::WS,
-                             token::MOD_SEP,
-                             mk_ident("b",false)));
+                           vec![mk_ident("a", token::Plain),
+                                token::Whitespace,
+                                token::ModSep,
+                                mk_ident("b", token::Plain)]);
     }
 
     #[test] fn dcparsing_4 () {
         check_tokenization(setup(&mk_sh(), "a:: b".to_string()),
-                           vec!(mk_ident("a",true),
-                             token::MOD_SEP,
-                             token::WS,
-                             mk_ident("b",false)));
+                           vec![mk_ident("a",token::ModName),
+                                token::ModSep,
+                                token::Whitespace,
+                                mk_ident("b", token::Plain)]);
     }
 
     #[test] fn character_a() {
         assert_eq!(setup(&mk_sh(), "'a'".to_string()).next_token().tok,
-                   token::LIT_CHAR(token::intern("a")));
+                   token::LitChar(token::intern("a")));
     }
 
     #[test] fn character_space() {
         assert_eq!(setup(&mk_sh(), "' '".to_string()).next_token().tok,
-                   token::LIT_CHAR(token::intern(" ")));
+                   token::LitChar(token::intern(" ")));
     }
 
     #[test] fn character_escaped() {
         assert_eq!(setup(&mk_sh(), "'\\n'".to_string()).next_token().tok,
-                   token::LIT_CHAR(token::intern("\\n")));
+                   token::LitChar(token::intern("\\n")));
     }
 
     #[test] fn lifetime_name() {
         assert_eq!(setup(&mk_sh(), "'abc".to_string()).next_token().tok,
-                   token::LIFETIME(token::str_to_ident("'abc")));
+                   token::Lifetime(token::str_to_ident("'abc")));
     }
 
     #[test] fn raw_string() {
         assert_eq!(setup(&mk_sh(),
                          "r###\"\"#a\\b\x00c\"\"###".to_string()).next_token()
                                                                  .tok,
-                   token::LIT_STR_RAW(token::intern("\"#a\\b\x00c\""), 3));
+                   token::LitStrRaw(token::intern("\"#a\\b\x00c\""), 3));
     }
 
     #[test] fn line_doc_comments() {
@@ -1531,10 +1541,10 @@ fn mk_ident (id: &str, is_mod_name: bool) -> token::Token {
         let sh = mk_sh();
         let mut lexer = setup(&sh, "/* /* */ */'a'".to_string());
         match lexer.next_token().tok {
-            token::COMMENT => { },
-            _ => fail!("expected a comment!")
+            token::Comment => { },
+            _ => panic!("expected a comment!")
         }
-        assert_eq!(lexer.next_token().tok, token::LIT_CHAR(token::intern("a")));
+        assert_eq!(lexer.next_token().tok, token::LitChar(token::intern("a")));
     }
 
 }
index 2d7d32cd9eaccdcdf189b1f82cc5d699575fa1af..c731f3965a0c907eb7d6d1b8dc9fede35de9802d 100644 (file)
@@ -65,7 +65,7 @@ pub fn reserve_node_ids(&self, count: ast::NodeId) -> ast::NodeId {
 
         match v.checked_add(&count) {
             Some(next) => { self.node_id.set(next); }
-            None => fail!("Input too large, ran out of node ids!")
+            None => panic!("Input too large, ran out of node ids!")
         }
 
         v
@@ -381,7 +381,7 @@ pub fn char_lit(lit: &str) -> (char, int) {
             '0' => Some('\0'),
             _ => { None }
         },
-        _ => fail!("lexer accepted invalid char escape `{}`", lit)
+        _ => panic!("lexer accepted invalid char escape `{}`", lit)
     };
 
     match c {
@@ -434,7 +434,7 @@ fn eat<'a>(it: &mut iter::Peekable<(uint, char), str::CharOffsets<'a>>) {
                 match c {
                     '\\' => {
                         let ch = chars.peek().unwrap_or_else(|| {
-                            fail!("{}", error(i).as_slice())
+                            panic!("{}", error(i).as_slice())
                         }).val1();
 
                         if ch == '\n' {
@@ -442,11 +442,11 @@ fn eat<'a>(it: &mut iter::Peekable<(uint, char), str::CharOffsets<'a>>) {
                         } else if ch == '\r' {
                             chars.next();
                             let ch = chars.peek().unwrap_or_else(|| {
-                                fail!("{}", error(i).as_slice())
+                                panic!("{}", error(i).as_slice())
                             }).val1();
 
                             if ch != '\n' {
-                                fail!("lexer accepted bare CR");
+                                panic!("lexer accepted bare CR");
                             }
                             eat(&mut chars);
                         } else {
@@ -460,11 +460,11 @@ fn eat<'a>(it: &mut iter::Peekable<(uint, char), str::CharOffsets<'a>>) {
                     },
                     '\r' => {
                         let ch = chars.peek().unwrap_or_else(|| {
-                            fail!("{}", error(i).as_slice())
+                            panic!("{}", error(i).as_slice())
                         }).val1();
 
                         if ch != '\n' {
-                            fail!("lexer accepted bare CR");
+                            panic!("lexer accepted bare CR");
                         }
                         chars.next();
                         res.push('\n');
@@ -494,7 +494,7 @@ pub fn raw_str_lit(lit: &str) -> String {
             Some(c) => {
                 if c == '\r' {
                     if *chars.peek().unwrap() != '\n' {
-                        fail!("lexer accepted bare CR");
+                        panic!("lexer accepted bare CR");
                     }
                     chars.next();
                     res.push('\n');
@@ -553,11 +553,11 @@ pub fn byte_lit(lit: &str) -> (u8, uint) {
                 match ::std::num::from_str_radix::<u64>(lit.slice(2, 4), 16) {
                     Some(c) =>
                         if c > 0xFF {
-                            fail!(err(2))
+                            panic!(err(2))
                         } else {
                             return (c as u8, 4)
                         },
-                    None => fail!(err(3))
+                    None => panic!(err(3))
                 }
             }
         };
@@ -594,7 +594,7 @@ fn eat<'a, I: Iterator<(uint, u8)>>(it: &mut iter::Peekable<(uint, u8), I>) {
                     b'\r' => {
                         chars.next();
                         if chars.peek().expect(em.as_slice()).val1() != b'\n' {
-                            fail!("lexer accepted bare CR");
+                            panic!("lexer accepted bare CR");
                         }
                         eat(&mut chars);
                     }
@@ -612,7 +612,7 @@ fn eat<'a, I: Iterator<(uint, u8)>>(it: &mut iter::Peekable<(uint, u8), I>) {
             Some((i, b'\r')) => {
                 let em = error(i);
                 if chars.peek().expect(em.as_slice()).val1() != b'\n' {
-                    fail!("lexer accepted bare CR");
+                    panic!("lexer accepted bare CR");
                 }
                 chars.next();
                 res.push(b'\n');
@@ -788,180 +788,166 @@ fn sp(a: u32, b: u32) -> Span {
     }
 
     // check the token-tree-ization of macros
-    #[test] fn string_to_tts_macro () {
+    #[test]
+    fn string_to_tts_macro () {
         let tts = string_to_tts("macro_rules! zip (($a)=>($a))".to_string());
         let tts: &[ast::TokenTree] = tts.as_slice();
         match tts {
-            [ast::TTTok(_,_),
-             ast::TTTok(_,token::NOT),
-             ast::TTTok(_,_),
-             ast::TTDelim(ref delim_elts)] => {
-                let delim_elts: &[ast::TokenTree] = delim_elts.as_slice();
-                match delim_elts {
-                    [ast::TTTok(_,token::LPAREN),
-                     ast::TTDelim(ref first_set),
-                     ast::TTTok(_,token::FAT_ARROW),
-                     ast::TTDelim(ref second_set),
-                     ast::TTTok(_,token::RPAREN)] => {
-                        let first_set: &[ast::TokenTree] =
-                            first_set.as_slice();
-                        match first_set {
-                            [ast::TTTok(_,token::LPAREN),
-                             ast::TTTok(_,token::DOLLAR),
-                             ast::TTTok(_,_),
-                             ast::TTTok(_,token::RPAREN)] => {
-                                let second_set: &[ast::TokenTree] =
-                                    second_set.as_slice();
-                                match second_set {
-                                    [ast::TTTok(_,token::LPAREN),
-                                     ast::TTTok(_,token::DOLLAR),
-                                     ast::TTTok(_,_),
-                                     ast::TTTok(_,token::RPAREN)] => {
-                                        assert_eq!("correct","correct")
-                                    }
-                                    _ => assert_eq!("wrong 4","correct")
-                                }
-                            },
-                            _ => {
-                                error!("failing value 3: {}",first_set);
-                                assert_eq!("wrong 3","correct")
-                            }
+            [ast::TtToken(_, token::Ident(name_macro_rules, token::Plain)),
+             ast::TtToken(_, token::Not),
+             ast::TtToken(_, token::Ident(name_zip, token::Plain)),
+             ast::TtDelimited(_, ref macro_delimed)]
+            if name_macro_rules.as_str() == "macro_rules"
+            && name_zip.as_str() == "zip" => {
+                let (ref macro_open, ref macro_tts, ref macro_close) = **macro_delimed;
+                match (macro_open, macro_tts.as_slice(), macro_close) {
+                    (&ast::Delimiter { token: token::LParen, .. },
+                     [ast::TtDelimited(_, ref first_delimed),
+                      ast::TtToken(_, token::FatArrow),
+                      ast::TtDelimited(_, ref second_delimed)],
+                     &ast::Delimiter { token: token::RParen, .. }) => {
+                        let (ref first_open, ref first_tts, ref first_close) = **first_delimed;
+                        match (first_open, first_tts.as_slice(), first_close) {
+                            (&ast::Delimiter { token: token::LParen, .. },
+                             [ast::TtToken(_, token::Dollar),
+                              ast::TtToken(_, token::Ident(name, token::Plain))],
+                             &ast::Delimiter { token: token::RParen, .. })
+                            if name.as_str() == "a" => {},
+                            _ => panic!("value 3: {}", **first_delimed),
+                        }
+                        let (ref second_open, ref second_tts, ref second_close) = **second_delimed;
+                        match (second_open, second_tts.as_slice(), second_close) {
+                            (&ast::Delimiter { token: token::LParen, .. },
+                             [ast::TtToken(_, token::Dollar),
+                              ast::TtToken(_, token::Ident(name, token::Plain))],
+                             &ast::Delimiter { token: token::RParen, .. })
+                            if name.as_str() == "a" => {},
+                            _ => panic!("value 4: {}", **second_delimed),
                         }
                     },
-                    _ => {
-                        error!("failing value 2: {}",delim_elts);
-                        assert_eq!("wrong","correct");
-                    }
+                    _ => panic!("value 2: {}", **macro_delimed),
                 }
             },
-            _ => {
-                error!("failing value: {}",tts);
-                assert_eq!("wrong 1","correct");
-            }
+            _ => panic!("value: {}",tts),
         }
     }
 
-    #[test] fn string_to_tts_1 () {
+    #[test]
+    fn string_to_tts_1 () {
         let tts = string_to_tts("fn a (b : int) { b; }".to_string());
         assert_eq!(json::encode(&tts),
         "[\
     {\
-        \"variant\":\"TTTok\",\
+        \"variant\":\"TtToken\",\
         \"fields\":[\
             null,\
             {\
-                \"variant\":\"IDENT\",\
+                \"variant\":\"Ident\",\
                 \"fields\":[\
                     \"fn\",\
-                    false\
+                    \"Plain\"\
                 ]\
             }\
         ]\
     },\
     {\
-        \"variant\":\"TTTok\",\
+        \"variant\":\"TtToken\",\
         \"fields\":[\
             null,\
             {\
-                \"variant\":\"IDENT\",\
+                \"variant\":\"Ident\",\
                 \"fields\":[\
                     \"a\",\
-                    false\
+                    \"Plain\"\
                 ]\
             }\
         ]\
     },\
     {\
-        \"variant\":\"TTDelim\",\
+        \"variant\":\"TtDelimited\",\
         \"fields\":[\
+            null,\
             [\
                 {\
-                    \"variant\":\"TTTok\",\
-                    \"fields\":[\
-                        null,\
-                        \"LPAREN\"\
-                    ]\
-                },\
-                {\
-                    \"variant\":\"TTTok\",\
-                    \"fields\":[\
-                        null,\
-                        {\
-                            \"variant\":\"IDENT\",\
-                            \"fields\":[\
-                                \"b\",\
-                                false\
-                            ]\
-                        }\
-                    ]\
+                    \"span\":null,\
+                    \"token\":\"LParen\"\
                 },\
+                [\
+                    {\
+                        \"variant\":\"TtToken\",\
+                        \"fields\":[\
+                            null,\
+                            {\
+                                \"variant\":\"Ident\",\
+                                \"fields\":[\
+                                    \"b\",\
+                                    \"Plain\"\
+                                ]\
+                            }\
+                        ]\
+                    },\
+                    {\
+                        \"variant\":\"TtToken\",\
+                        \"fields\":[\
+                            null,\
+                            \"Colon\"\
+                        ]\
+                    },\
+                    {\
+                        \"variant\":\"TtToken\",\
+                        \"fields\":[\
+                            null,\
+                            {\
+                                \"variant\":\"Ident\",\
+                                \"fields\":[\
+                                    \"int\",\
+                                    \"Plain\"\
+                                ]\
+                            }\
+                        ]\
+                    }\
+                ],\
                 {\
-                    \"variant\":\"TTTok\",\
-                    \"fields\":[\
-                        null,\
-                        \"COLON\"\
-                    ]\
-                },\
-                {\
-                    \"variant\":\"TTTok\",\
-                    \"fields\":[\
-                        null,\
-                        {\
-                            \"variant\":\"IDENT\",\
-                            \"fields\":[\
-                                \"int\",\
-                                false\
-                            ]\
-                        }\
-                    ]\
-                },\
-                {\
-                    \"variant\":\"TTTok\",\
-                    \"fields\":[\
-                        null,\
-                        \"RPAREN\"\
-                    ]\
+                    \"span\":null,\
+                    \"token\":\"RParen\"\
                 }\
             ]\
         ]\
     },\
     {\
-        \"variant\":\"TTDelim\",\
+        \"variant\":\"TtDelimited\",\
         \"fields\":[\
+            null,\
             [\
                 {\
-                    \"variant\":\"TTTok\",\
-                    \"fields\":[\
-                        null,\
-                        \"LBRACE\"\
-                    ]\
-                },\
-                {\
-                    \"variant\":\"TTTok\",\
-                    \"fields\":[\
-                        null,\
-                        {\
-                            \"variant\":\"IDENT\",\
-                            \"fields\":[\
-                                \"b\",\
-                                false\
-                            ]\
-                        }\
-                    ]\
-                },\
-                {\
-                    \"variant\":\"TTTok\",\
-                    \"fields\":[\
-                        null,\
-                        \"SEMI\"\
-                    ]\
+                    \"span\":null,\
+                    \"token\":\"LBrace\"\
                 },\
+                [\
+                    {\
+                        \"variant\":\"TtToken\",\
+                        \"fields\":[\
+                            null,\
+                            {\
+                                \"variant\":\"Ident\",\
+                                \"fields\":[\
+                                    \"b\",\
+                                    \"Plain\"\
+                                ]\
+                            }\
+                        ]\
+                    },\
+                    {\
+                        \"variant\":\"TtToken\",\
+                        \"fields\":[\
+                            null,\
+                            \"Semi\"\
+                        ]\
+                    }\
+                ],\
                 {\
-                    \"variant\":\"TTTok\",\
-                    \"fields\":[\
-                        null,\
-                        \"RBRACE\"\
-                    ]\
+                    \"span\":null,\
+                    \"token\":\"RBrace\"\
                 }\
             ]\
         ]\
@@ -1016,7 +1002,7 @@ fn sp(a: u32, b: u32) -> Span {
     }
 
     fn parser_done(p: Parser){
-        assert_eq!(p.token.clone(), token::EOF);
+        assert_eq!(p.token.clone(), token::Eof);
     }
 
     #[test] fn parse_ident_pat () {
index 1a6fb9b85dd255f7fcba5bd1e728d24f33f8933f..73787763c8b58a7e9f8a1e153c60dbccf25de7e7 100644 (file)
@@ -118,7 +118,7 @@ fn report(&mut self,
 
     fn is_obsolete_ident(&mut self, ident: &str) -> bool {
         match self.token {
-            token::IDENT(sid, _) => {
+            token::Ident(sid, _) => {
                 token::get_ident(sid).equiv(&ident)
             }
             _ => false
index 5abf79836f5b2b4d5a45d8c4852f779ebcc18e49..8ef3a559bf41abda8fbac7a372d4ed1e8eb6f6bc 100644 (file)
@@ -48,8 +48,8 @@
 use ast::{StructVariantKind, BiSub};
 use ast::StrStyle;
 use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue};
-use ast::{TokenTree, TraitItem, TraitRef, TTDelim, TTSeq, TTTok};
-use ast::{TTNonterminal, TupleVariantKind, Ty, Ty_, TyBot};
+use ast::{Delimiter, TokenTree, TraitItem, TraitRef, TtDelimited, TtSequence, TtToken};
+use ast::{TtNonterminal, TupleVariantKind, Ty, Ty_, TyBot};
 use ast::{TypeField, TyFixedLengthVec, TyClosure, TyProc, TyBareFn};
 use ast::{TyTypeof, TyInfer, TypeMethod};
 use ast::{TyNil, TyParam, TyParamBound, TyParen, TyPath, TyPtr, TyQPath};
 use parse::lexer::Reader;
 use parse::lexer::TokenAndSpan;
 use parse::obsolete::*;
-use parse::token::{INTERPOLATED, InternedString, can_begin_expr};
-use parse::token::{is_ident, is_ident_or_path, is_plain_ident};
-use parse::token::{keywords, special_idents, token_to_binop};
+use parse::token::InternedString;
+use parse::token::{keywords, special_idents};
 use parse::token;
 use parse::{new_sub_parser_from_file, ParseSess};
+use print::pprust;
 use ptr::P;
 use owned_slice::OwnedSlice;
 
@@ -134,34 +134,33 @@ enum ItemOrViewItem {
 }
 
 
-/// Possibly accept an `INTERPOLATED` expression (a pre-parsed expression
-/// dropped into the token stream, which happens while parsing the
-/// result of macro expansion)
-/// Placement of these is not as complex as I feared it would be.
-/// The important thing is to make sure that lookahead doesn't balk
-/// at INTERPOLATED tokens
+/// Possibly accept an `token::Interpolated` expression (a pre-parsed expression
+/// dropped into the token stream, which happens while parsing the result of
+/// macro expansion). Placement of these is not as complex as I feared it would
+/// be. The important thing is to make sure that lookahead doesn't balk at
+/// `token::Interpolated` tokens.
 macro_rules! maybe_whole_expr (
     ($p:expr) => (
         {
             let found = match $p.token {
-                INTERPOLATED(token::NtExpr(ref e)) => {
+                token::Interpolated(token::NtExpr(ref e)) => {
                     Some((*e).clone())
                 }
-                INTERPOLATED(token::NtPath(_)) => {
+                token::Interpolated(token::NtPath(_)) => {
                     // FIXME: The following avoids an issue with lexical borrowck scopes,
                     // but the clone is unfortunate.
                     let pt = match $p.token {
-                        INTERPOLATED(token::NtPath(ref pt)) => (**pt).clone(),
+                        token::Interpolated(token::NtPath(ref pt)) => (**pt).clone(),
                         _ => unreachable!()
                     };
                     let span = $p.span;
                     Some($p.mk_expr(span.lo, span.hi, ExprPath(pt)))
                 }
-                INTERPOLATED(token::NtBlock(_)) => {
+                token::Interpolated(token::NtBlock(_)) => {
                     // FIXME: The following avoids an issue with lexical borrowck scopes,
                     // but the clone is unfortunate.
                     let b = match $p.token {
-                        INTERPOLATED(token::NtBlock(ref b)) => (*b).clone(),
+                        token::Interpolated(token::NtBlock(ref b)) => (*b).clone(),
                         _ => unreachable!()
                     };
                     let span = $p.span;
@@ -185,13 +184,13 @@ macro_rules! maybe_whole (
     ($p:expr, $constructor:ident) => (
         {
             let found = match ($p).token {
-                INTERPOLATED(token::$constructor(_)) => {
+                token::Interpolated(token::$constructor(_)) => {
                     Some(($p).bump_and_get())
                 }
                 _ => None
             };
             match found {
-                Some(INTERPOLATED(token::$constructor(x))) => {
+                Some(token::Interpolated(token::$constructor(x))) => {
                     return x.clone()
                 }
                 _ => {}
@@ -201,13 +200,13 @@ macro_rules! maybe_whole (
     (no_clone $p:expr, $constructor:ident) => (
         {
             let found = match ($p).token {
-                INTERPOLATED(token::$constructor(_)) => {
+                token::Interpolated(token::$constructor(_)) => {
                     Some(($p).bump_and_get())
                 }
                 _ => None
             };
             match found {
-                Some(INTERPOLATED(token::$constructor(x))) => {
+                Some(token::Interpolated(token::$constructor(x))) => {
                     return x
                 }
                 _ => {}
@@ -217,13 +216,13 @@ macro_rules! maybe_whole (
     (deref $p:expr, $constructor:ident) => (
         {
             let found = match ($p).token {
-                INTERPOLATED(token::$constructor(_)) => {
+                token::Interpolated(token::$constructor(_)) => {
                     Some(($p).bump_and_get())
                 }
                 _ => None
             };
             match found {
-                Some(INTERPOLATED(token::$constructor(x))) => {
+                Some(token::Interpolated(token::$constructor(x))) => {
                     return (*x).clone()
                 }
                 _ => {}
@@ -233,13 +232,13 @@ macro_rules! maybe_whole (
     (Some $p:expr, $constructor:ident) => (
         {
             let found = match ($p).token {
-                INTERPOLATED(token::$constructor(_)) => {
+                token::Interpolated(token::$constructor(_)) => {
                     Some(($p).bump_and_get())
                 }
                 _ => None
             };
             match found {
-                Some(INTERPOLATED(token::$constructor(x))) => {
+                Some(token::Interpolated(token::$constructor(x))) => {
                     return Some(x.clone()),
                 }
                 _ => {}
@@ -249,13 +248,13 @@ macro_rules! maybe_whole (
     (iovi $p:expr, $constructor:ident) => (
         {
             let found = match ($p).token {
-                INTERPOLATED(token::$constructor(_)) => {
+                token::Interpolated(token::$constructor(_)) => {
                     Some(($p).bump_and_get())
                 }
                 _ => None
             };
             match found {
-                Some(INTERPOLATED(token::$constructor(x))) => {
+                Some(token::Interpolated(token::$constructor(x))) => {
                     return IoviItem(x.clone())
                 }
                 _ => {}
@@ -265,13 +264,13 @@ macro_rules! maybe_whole (
     (pair_empty $p:expr, $constructor:ident) => (
         {
             let found = match ($p).token {
-                INTERPOLATED(token::$constructor(_)) => {
+                token::Interpolated(token::$constructor(_)) => {
                     Some(($p).bump_and_get())
                 }
                 _ => None
             };
             match found {
-                Some(INTERPOLATED(token::$constructor(x))) => {
+                Some(token::Interpolated(token::$constructor(x))) => {
                     return (Vec::new(), x)
                 }
                 _ => {}
@@ -336,7 +335,7 @@ pub struct Parser<'a> {
 }
 
 fn is_plain_ident_or_underscore(t: &token::Token) -> bool {
-    is_plain_ident(t) || *t == token::UNDERSCORE
+    t.is_plain_ident() || *t == token::Underscore
 }
 
 /// Get a token the parser cares about
@@ -344,7 +343,7 @@ fn real_token(rdr: &mut Reader) -> TokenAndSpan {
     let mut t = rdr.next_token();
     loop {
         match t.tok {
-            token::WS | token::COMMENT | token::SHEBANG(_) => {
+            token::Whitespace | token::Comment | token::Shebang(_) => {
                 t = rdr.next_token();
             },
             _ => break
@@ -362,7 +361,7 @@ pub fn new(sess: &'a ParseSess,
         let tok0 = real_token(&mut *rdr);
         let span = tok0.sp;
         let placeholder = TokenAndSpan {
-            tok: token::UNDERSCORE,
+            tok: token::Underscore,
             sp: span,
         };
 
@@ -396,7 +395,7 @@ pub fn new(sess: &'a ParseSess,
 
     /// Convert a token to a string using self's reader
     pub fn token_to_string(token: &token::Token) -> String {
-        token::to_string(token)
+        pprust::token_to_string(token)
     }
 
     /// Convert the current token to a string using self's reader
@@ -475,15 +474,15 @@ fn tokens_to_string(tokens: &[token::Token]) -> String {
     /// recover (without consuming any expected input token).  Returns
     /// true if and only if input was consumed for recovery.
     pub fn check_for_erroneous_unit_struct_expecting(&mut self, expected: &[token::Token]) -> bool {
-        if self.token == token::LBRACE
-            && expected.iter().all(|t| *t != token::LBRACE)
-            && self.look_ahead(1, |t| *t == token::RBRACE) {
+        if self.token == token::LBrace
+            && expected.iter().all(|t| *t != token::LBrace)
+            && self.look_ahead(1, |t| *t == token::RBrace) {
             // matched; signal non-fatal error and recover.
             let span = self.span;
             self.span_err(span,
                           "unit-like struct construction is written with no trailing `{ }`");
-            self.eat(&token::LBRACE);
-            self.eat(&token::RBRACE);
+            self.eat(&token::LBrace);
+            self.eat(&token::RBrace);
             true
         } else {
             false
@@ -518,7 +517,7 @@ pub fn commit_expr_expecting(&mut self, e: &Expr, edible: token::Token) {
     pub fn commit_stmt(&mut self, edible: &[token::Token], inedible: &[token::Token]) {
         if self.last_token
                .as_ref()
-               .map_or(false, |t| is_ident_or_path(&**t)) {
+               .map_or(false, |t| t.is_ident() || t.is_path()) {
             let mut expected = edible.iter().map(|x| x.clone()).collect::<Vec<_>>();
             expected.push_all(inedible.as_slice());
             self.check_for_erroneous_unit_struct_expecting(
@@ -535,11 +534,11 @@ pub fn parse_ident(&mut self) -> ast::Ident {
         self.check_strict_keywords();
         self.check_reserved_keywords();
         match self.token {
-            token::IDENT(i, _) => {
+            token::Ident(i, _) => {
                 self.bump();
                 i
             }
-            token::INTERPOLATED(token::NtIdent(..)) => {
+            token::Interpolated(token::NtIdent(..)) => {
                 self.bug("ident interpolation not converted to real token");
             }
             _ => {
@@ -570,14 +569,10 @@ pub fn eat(&mut self, tok: &token::Token) -> bool {
         is_present
     }
 
-    pub fn is_keyword(&mut self, kw: keywords::Keyword) -> bool {
-        token::is_keyword(kw, &self.token)
-    }
-
     /// If the next token is the given keyword, eat it and return
     /// true. Otherwise, return false.
     pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> bool {
-        if self.is_keyword(kw) {
+        if self.token.is_keyword(kw) {
             self.bump();
             true
         } else {
@@ -599,7 +594,7 @@ pub fn expect_keyword(&mut self, kw: keywords::Keyword) {
 
     /// Signal an error if the given string is a strict keyword
     pub fn check_strict_keywords(&mut self) {
-        if token::is_strict_keyword(&self.token) {
+        if self.token.is_strict_keyword() {
             let token_str = self.this_token_to_string();
             let span = self.span;
             self.span_err(span,
@@ -610,7 +605,7 @@ pub fn check_strict_keywords(&mut self) {
 
     /// Signal an error if the current token is a reserved keyword
     pub fn check_reserved_keywords(&mut self) {
-        if token::is_reserved_keyword(&self.token) {
+        if self.token.is_reserved_keyword() {
             let token_str = self.this_token_to_string();
             self.fatal(format!("`{}` is a reserved keyword",
                                token_str).as_slice())
@@ -621,16 +616,16 @@ pub fn check_reserved_keywords(&mut self) {
     /// `&` and continue. If an `&` is not seen, signal an error.
     fn expect_and(&mut self) {
         match self.token {
-            token::BINOP(token::AND) => self.bump(),
-            token::ANDAND => {
+            token::BinOp(token::And) => self.bump(),
+            token::AndAnd => {
                 let span = self.span;
                 let lo = span.lo + BytePos(1);
-                self.replace_token(token::BINOP(token::AND), lo, span.hi)
+                self.replace_token(token::BinOp(token::And), lo, span.hi)
             }
             _ => {
                 let token_str = self.this_token_to_string();
                 let found_token =
-                    Parser::token_to_string(&token::BINOP(token::AND));
+                    Parser::token_to_string(&token::BinOp(token::And));
                 self.fatal(format!("expected `{}`, found `{}`",
                                    found_token,
                                    token_str).as_slice())
@@ -642,16 +637,16 @@ fn expect_and(&mut self) {
     /// `|` and continue. If a `|` is not seen, signal an error.
     fn expect_or(&mut self) {
         match self.token {
-            token::BINOP(token::OR) => self.bump(),
-            token::OROR => {
+            token::BinOp(token::Or) => self.bump(),
+            token::OrOr => {
                 let span = self.span;
                 let lo = span.lo + BytePos(1);
-                self.replace_token(token::BINOP(token::OR), lo, span.hi)
+                self.replace_token(token::BinOp(token::Or), lo, span.hi)
             }
             _ => {
                 let found_token = self.this_token_to_string();
                 let token_str =
-                    Parser::token_to_string(&token::BINOP(token::OR));
+                    Parser::token_to_string(&token::BinOp(token::Or));
                 self.fatal(format!("expected `{}`, found `{}`",
                                    token_str,
                                    found_token).as_slice())
@@ -681,16 +676,16 @@ fn expect_or(&mut self) {
     ///      impl Foo<<'a> ||>() { ... }
     fn eat_lt(&mut self, force: bool) -> bool {
         match self.token {
-            token::LT => { self.bump(); true }
-            token::BINOP(token::SHL) => {
+            token::Lt => { self.bump(); true }
+            token::BinOp(token::Shl) => {
                 let next_lifetime = self.look_ahead(1, |t| match *t {
-                    token::LIFETIME(..) => true,
+                    token::Lifetime(..) => true,
                     _ => false,
                 });
                 if force || next_lifetime {
                     let span = self.span;
                     let lo = span.lo + BytePos(1);
-                    self.replace_token(token::LT, lo, span.hi);
+                    self.replace_token(token::Lt, lo, span.hi);
                     true
                 } else {
                     false
@@ -703,7 +698,7 @@ fn eat_lt(&mut self, force: bool) -> bool {
     fn expect_lt(&mut self) {
         if !self.eat_lt(true) {
             let found_token = self.this_token_to_string();
-            let token_str = Parser::token_to_string(&token::LT);
+            let token_str = Parser::token_to_string(&token::Lt);
             self.fatal(format!("expected `{}`, found `{}`",
                                token_str,
                                found_token).as_slice())
@@ -718,8 +713,8 @@ fn parse_seq_to_before_or<T>(
                               -> Vec<T> {
         let mut first = true;
         let mut vector = Vec::new();
-        while self.token != token::BINOP(token::OR) &&
-                self.token != token::OROR {
+        while self.token != token::BinOp(token::Or) &&
+                self.token != token::OrOr {
             if first {
                 first = false
             } else {
@@ -736,24 +731,24 @@ fn parse_seq_to_before_or<T>(
     /// signal an error.
     pub fn expect_gt(&mut self) {
         match self.token {
-            token::GT => self.bump(),
-            token::BINOP(token::SHR) => {
+            token::Gt => self.bump(),
+            token::BinOp(token::Shr) => {
                 let span = self.span;
                 let lo = span.lo + BytePos(1);
-                self.replace_token(token::GT, lo, span.hi)
+                self.replace_token(token::Gt, lo, span.hi)
             }
-            token::BINOPEQ(token::SHR) => {
+            token::BinOpEq(token::Shr) => {
                 let span = self.span;
                 let lo = span.lo + BytePos(1);
-                self.replace_token(token::GE, lo, span.hi)
+                self.replace_token(token::Ge, lo, span.hi)
             }
-            token::GE => {
+            token::Ge => {
                 let span = self.span;
                 let lo = span.lo + BytePos(1);
-                self.replace_token(token::EQ, lo, span.hi)
+                self.replace_token(token::Eq, lo, span.hi)
             }
             _ => {
-                let gt_str = Parser::token_to_string(&token::GT);
+                let gt_str = Parser::token_to_string(&token::Gt);
                 let this_token_str = self.this_token_to_string();
                 self.fatal(format!("expected `{}`, found `{}`",
                                    gt_str,
@@ -777,10 +772,10 @@ pub fn parse_seq_to_before_gt<T>(
         // commas in generic parameters, because it can stop either after
         // parsing a type or after parsing a comma.
         for i in iter::count(0u, 1) {
-            if self.token == token::GT
-                || self.token == token::BINOP(token::SHR)
-                || self.token == token::GE
-                || self.token == token::BINOPEQ(token::SHR) {
+            if self.token == token::Gt
+                || self.token == token::BinOp(token::Shr)
+                || self.token == token::Ge
+                || self.token == token::BinOpEq(token::Shr) {
                 break;
             }
 
@@ -897,7 +892,7 @@ pub fn parse_seq<T>(
     pub fn bump(&mut self) {
         self.last_span = self.span;
         // Stash token for error recovery (sometimes; clone is not necessarily cheap).
-        self.last_token = if is_ident_or_path(&self.token) {
+        self.last_token = if self.token.is_ident() || self.token.is_path() {
             Some(box self.token.clone())
         } else {
             None
@@ -911,7 +906,7 @@ pub fn bump(&mut self) {
             self.buffer_start = next_index as int;
 
             let placeholder = TokenAndSpan {
-                tok: token::UNDERSCORE,
+                tok: token::Underscore,
                 sp: self.span,
             };
             replace(&mut self.buffer[buffer_start], placeholder)
@@ -923,7 +918,7 @@ pub fn bump(&mut self) {
 
     /// Advance the parser by one token and return the bumped token.
     pub fn bump_and_get(&mut self) -> token::Token {
-        let old_token = replace(&mut self.token, token::UNDERSCORE);
+        let old_token = replace(&mut self.token, token::Underscore);
         self.bump();
         old_token
     }
@@ -987,13 +982,13 @@ pub fn id_to_interned_str(&mut self, id: Ident) -> InternedString {
     /// Is the current token one of the keywords that signals a bare function
     /// type?
     pub fn token_is_bare_fn_keyword(&mut self) -> bool {
-        if token::is_keyword(keywords::Fn, &self.token) {
+        if self.token.is_keyword(keywords::Fn) {
             return true
         }
 
-        if token::is_keyword(keywords::Unsafe, &self.token) ||
-            token::is_keyword(keywords::Once, &self.token) {
-            return self.look_ahead(1, |t| token::is_keyword(keywords::Fn, t))
+        if self.token.is_keyword(keywords::Unsafe) ||
+            self.token.is_keyword(keywords::Once) {
+            return self.look_ahead(1, |t| t.is_keyword(keywords::Fn))
         }
 
         false
@@ -1001,28 +996,21 @@ pub fn token_is_bare_fn_keyword(&mut self) -> bool {
 
     /// Is the current token one of the keywords that signals a closure type?
     pub fn token_is_closure_keyword(&mut self) -> bool {
-        token::is_keyword(keywords::Unsafe, &self.token) ||
-            token::is_keyword(keywords::Once, &self.token)
+        self.token.is_keyword(keywords::Unsafe) ||
+            self.token.is_keyword(keywords::Once)
     }
 
     /// Is the current token one of the keywords that signals an old-style
     /// closure type (with explicit sigil)?
     pub fn token_is_old_style_closure_keyword(&mut self) -> bool {
-        token::is_keyword(keywords::Unsafe, &self.token) ||
-            token::is_keyword(keywords::Once, &self.token) ||
-            token::is_keyword(keywords::Fn, &self.token)
-    }
-
-    pub fn token_is_lifetime(tok: &token::Token) -> bool {
-        match *tok {
-            token::LIFETIME(..) => true,
-            _ => false,
-        }
+        self.token.is_keyword(keywords::Unsafe) ||
+            self.token.is_keyword(keywords::Once) ||
+            self.token.is_keyword(keywords::Fn)
     }
 
     pub fn get_lifetime(&mut self) -> ast::Ident {
         match self.token {
-            token::LIFETIME(ref ident) => *ident,
+            token::Lifetime(ref ident) => *ident,
             _ => self.bug("not a lifetime"),
         }
     }
@@ -1074,7 +1062,7 @@ pub fn parse_proc_type(&mut self) -> Ty_ {
 
         */
 
-        let lifetime_defs = if self.eat(&token::LT) {
+        let lifetime_defs = if self.eat(&token::Lt) {
             let lifetime_defs = self.parse_lifetime_defs();
             self.expect_gt();
             lifetime_defs
@@ -1103,25 +1091,23 @@ pub fn parse_proc_type(&mut self) -> Ty_ {
     /// Parses an optional unboxed closure kind (`&:`, `&mut:`, or `:`).
     pub fn parse_optional_unboxed_closure_kind(&mut self)
                                                -> Option<UnboxedClosureKind> {
-        if self.token == token::BINOP(token::AND) &&
-                    self.look_ahead(1, |t| {
-                        token::is_keyword(keywords::Mut, t)
-                    }) &&
-                    self.look_ahead(2, |t| *t == token::COLON) {
+        if self.token == token::BinOp(token::And) &&
+                self.look_ahead(1, |t| t.is_keyword(keywords::Mut)) &&
+                self.look_ahead(2, |t| *t == token::Colon) {
             self.bump();
             self.bump();
             self.bump();
             return Some(FnMutUnboxedClosureKind)
         }
 
-        if self.token == token::BINOP(token::AND) &&
-                    self.look_ahead(1, |t| *t == token::COLON) {
+        if self.token == token::BinOp(token::And) &&
+                    self.look_ahead(1, |t| *t == token::Colon) {
             self.bump();
             self.bump();
             return Some(FnUnboxedClosureKind)
         }
 
-        if self.eat(&token::COLON) {
+        if self.eat(&token::Colon) {
             return Some(FnOnceUnboxedClosureKind)
         }
 
@@ -1147,7 +1133,7 @@ pub fn parse_ty_closure(&mut self) -> Ty_ {
         let fn_style = self.parse_unsafety();
         let onceness = if self.eat_keyword(keywords::Once) {Once} else {Many};
 
-        let lifetime_defs = if self.eat(&token::LT) {
+        let lifetime_defs = if self.eat(&token::Lt) {
             let lifetime_defs = self.parse_lifetime_defs();
             self.expect_gt();
 
@@ -1156,7 +1142,7 @@ pub fn parse_ty_closure(&mut self) -> Ty_ {
             Vec::new()
         };
 
-        let (optional_unboxed_closure_kind, inputs) = if self.eat(&token::OROR) {
+        let (optional_unboxed_closure_kind, inputs) = if self.eat(&token::OrOr) {
             (None, Vec::new())
         } else {
             self.expect_or();
@@ -1165,7 +1151,7 @@ pub fn parse_ty_closure(&mut self) -> Ty_ {
                 self.parse_optional_unboxed_closure_kind();
 
             let inputs = self.parse_seq_to_before_or(
-                &token::COMMA,
+                &token::Comma,
                 |p| p.parse_arg_general(false));
             self.expect_or();
             (optional_unboxed_closure_kind, inputs)
@@ -1221,7 +1207,7 @@ pub fn parse_ty_fn_decl(&mut self, allow_variadic: bool)
            Lifetime_defs
 
         */
-        let lifetime_defs = if self.eat(&token::LT) {
+        let lifetime_defs = if self.eat(&token::Lt) {
             let lifetime_defs = self.parse_lifetime_defs();
             self.expect_gt();
             lifetime_defs
@@ -1247,7 +1233,7 @@ fn parse_associated_type(&mut self, attrs: Vec<Attribute>)
         let lo = self.span.lo;
         let ident = self.parse_ident();
         let hi = self.span.hi;
-        self.expect(&token::SEMI);
+        self.expect(&token::Semi);
         AssociatedType {
             id: ast::DUMMY_NODE_ID,
             span: mk_sp(lo, hi),
@@ -1262,10 +1248,10 @@ fn parse_typedef(&mut self, attrs: Vec<Attribute>, vis: Visibility)
                      -> Typedef {
         let lo = self.span.lo;
         let ident = self.parse_ident();
-        self.expect(&token::EQ);
+        self.expect(&token::Eq);
         let typ = self.parse_ty(true);
         let hi = self.span.hi;
-        self.expect(&token::SEMI);
+        self.expect(&token::Semi);
         Typedef {
             id: ast::DUMMY_NODE_ID,
             span: mk_sp(lo, hi),
@@ -1279,8 +1265,8 @@ fn parse_typedef(&mut self, attrs: Vec<Attribute>, vis: Visibility)
     /// Parse the items in a trait declaration
     pub fn parse_trait_items(&mut self) -> Vec<TraitItem> {
         self.parse_unspanned_seq(
-            &token::LBRACE,
-            &token::RBRACE,
+            &token::LBrace,
+            &token::RBrace,
             seq_sep_none(),
             |p| {
             let attrs = p.parse_outer_attributes();
@@ -1317,7 +1303,7 @@ pub fn parse_trait_items(&mut self) -> Vec<TraitItem> {
 
                 let hi = p.last_span.hi;
                 match p.token {
-                  token::SEMI => {
+                  token::Semi => {
                     p.bump();
                     debug!("parse_trait_methods(): parsing required method");
                     RequiredMethod(TypeMethod {
@@ -1333,7 +1319,7 @@ pub fn parse_trait_items(&mut self) -> Vec<TraitItem> {
                         vis: vis,
                     })
                   }
-                  token::LBRACE => {
+                  token::LBrace => {
                     debug!("parse_trait_methods(): parsing provided method");
                     let (inner_attrs, body) =
                         p.parse_inner_attrs_and_block();
@@ -1377,7 +1363,7 @@ pub fn parse_ty_field(&mut self) -> TypeField {
         let lo = self.span.lo;
         let mutbl = self.parse_mutability();
         let id = self.parse_ident();
-        self.expect(&token::COLON);
+        self.expect(&token::Colon);
         let ty = self.parse_ty(true);
         let hi = ty.span.hi;
         ast::TypeField {
@@ -1389,9 +1375,9 @@ pub fn parse_ty_field(&mut self) -> TypeField {
 
     /// Parse optional return type [ -> TY ] in function decl
     pub fn parse_ret_ty(&mut self) -> (RetStyle, P<Ty>) {
-        return if self.eat(&token::RARROW) {
+        return if self.eat(&token::RArrow) {
             let lo = self.span.lo;
-            if self.eat(&token::NOT) {
+            if self.eat(&token::Not) {
                 (
                     NoReturn,
                     P(Ty {
@@ -1425,9 +1411,9 @@ pub fn parse_ty(&mut self, plus_allowed: bool) -> P<Ty> {
 
         let lo = self.span.lo;
 
-        let t = if self.token == token::LPAREN {
+        let t = if self.token == token::LParen {
             self.bump();
-            if self.token == token::RPAREN {
+            if self.token == token::RParen {
                 self.bump();
                 TyNil
             } else {
@@ -1436,9 +1422,9 @@ pub fn parse_ty(&mut self, plus_allowed: bool) -> P<Ty> {
                 // of type t
                 let mut ts = vec!(self.parse_ty(true));
                 let mut one_tuple = false;
-                while self.token == token::COMMA {
+                while self.token == token::Comma {
                     self.bump();
-                    if self.token != token::RPAREN {
+                    if self.token != token::RParen {
                         ts.push(self.parse_ty(true));
                     }
                     else {
@@ -1447,30 +1433,30 @@ pub fn parse_ty(&mut self, plus_allowed: bool) -> P<Ty> {
                 }
 
                 if ts.len() == 1 && !one_tuple {
-                    self.expect(&token::RPAREN);
+                    self.expect(&token::RParen);
                     TyParen(ts.into_iter().nth(0).unwrap())
                 } else {
                     let t = TyTup(ts);
-                    self.expect(&token::RPAREN);
+                    self.expect(&token::RParen);
                     t
                 }
             }
-        } else if self.token == token::TILDE {
+        } else if self.token == token::Tilde {
             // OWNED POINTER
             self.bump();
             let last_span = self.last_span;
             match self.token {
-                token::LBRACKET => self.obsolete(last_span, ObsoleteOwnedVector),
+                token::LBracket => self.obsolete(last_span, ObsoleteOwnedVector),
                 _ => self.obsolete(last_span, ObsoleteOwnedType)
             }
             TyUniq(self.parse_ty(false))
-        } else if self.token == token::BINOP(token::STAR) {
+        } else if self.token == token::BinOp(token::Star) {
             // STAR POINTER (bare pointer?)
             self.bump();
             TyPtr(self.parse_ptr())
-        } else if self.token == token::LBRACKET {
+        } else if self.token == token::LBracket {
             // VECTOR
-            self.expect(&token::LBRACKET);
+            self.expect(&token::LBracket);
             let t = self.parse_ty(true);
 
             // Parse the `, ..e` in `[ int, ..e ]`
@@ -1479,24 +1465,24 @@ pub fn parse_ty(&mut self, plus_allowed: bool) -> P<Ty> {
                 None => TyVec(t),
                 Some(suffix) => TyFixedLengthVec(t, suffix)
             };
-            self.expect(&token::RBRACKET);
+            self.expect(&token::RBracket);
             t
-        } else if self.token == token::BINOP(token::AND) ||
-                self.token == token::ANDAND {
+        } else if self.token == token::BinOp(token::And) ||
+                self.token == token::AndAnd {
             // BORROWED POINTER
             self.expect_and();
             self.parse_borrowed_pointee()
-        } else if self.is_keyword(keywords::Extern) ||
-                  self.is_keyword(keywords::Unsafe) ||
+        } else if self.token.is_keyword(keywords::Extern) ||
+                  self.token.is_keyword(keywords::Unsafe) ||
                 self.token_is_bare_fn_keyword() {
             // BARE FUNCTION
             self.parse_ty_bare_fn()
         } else if self.token_is_closure_keyword() ||
-                self.token == token::BINOP(token::OR) ||
-                self.token == token::OROR ||
-                (self.token == token::LT &&
+                self.token == token::BinOp(token::Or) ||
+                self.token == token::OrOr ||
+                (self.token == token::Lt &&
                  self.look_ahead(1, |t| {
-                     *t == token::GT || Parser::token_is_lifetime(t)
+                     *t == token::Gt || t.is_lifetime()
                  })) {
             // CLOSURE
 
@@ -1504,28 +1490,29 @@ pub fn parse_ty(&mut self, plus_allowed: bool) -> P<Ty> {
         } else if self.eat_keyword(keywords::Typeof) {
             // TYPEOF
             // In order to not be ambiguous, the type must be surrounded by parens.
-            self.expect(&token::LPAREN);
+            self.expect(&token::LParen);
             let e = self.parse_expr();
-            self.expect(&token::RPAREN);
+            self.expect(&token::RParen);
             TyTypeof(e)
         } else if self.eat_keyword(keywords::Proc) {
             self.parse_proc_type()
-        } else if self.token == token::LT {
+        } else if self.token == token::Lt {
             // QUALIFIED PATH
             self.bump();
             let for_type = self.parse_ty(true);
             self.expect_keyword(keywords::As);
             let trait_name = self.parse_path(LifetimeAndTypesWithoutColons);
-            self.expect(&token::GT);
-            self.expect(&token::MOD_SEP);
+            self.expect(&token::Gt);
+            self.expect(&token::ModSep);
             let item_name = self.parse_ident();
             TyQPath(P(QPath {
                 for_type: for_type,
                 trait_name: trait_name.path,
                 item_name: item_name,
             }))
-        } else if self.token == token::MOD_SEP
-            || is_ident_or_path(&self.token) {
+        } else if self.token == token::ModSep
+            || self.token.is_ident()
+            || self.token.is_path() {
             // NAMED TYPE
             let mode = if plus_allowed {
                 LifetimeAndTypesAndBounds
@@ -1537,7 +1524,7 @@ pub fn parse_ty(&mut self, plus_allowed: bool) -> P<Ty> {
                 bounds
             } = self.parse_path(mode);
             TyPath(path, bounds, ast::DUMMY_NODE_ID)
-        } else if self.eat(&token::UNDERSCORE) {
+        } else if self.eat(&token::Underscore) {
             // TYPE TO BE INFERRED
             TyInfer
         } else {
@@ -1576,9 +1563,9 @@ pub fn parse_ptr(&mut self) -> MutTy {
 
     pub fn is_named_argument(&mut self) -> bool {
         let offset = match self.token {
-            token::BINOP(token::AND) => 1,
-            token::ANDAND => 1,
-            _ if token::is_keyword(keywords::Mut, &self.token) => 1,
+            token::BinOp(token::And) => 1,
+            token::AndAnd => 1,
+            _ if self.token.is_keyword(keywords::Mut) => 1,
             _ => 0
         };
 
@@ -1586,10 +1573,10 @@ pub fn is_named_argument(&mut self) -> bool {
 
         if offset == 0 {
             is_plain_ident_or_underscore(&self.token)
-                && self.look_ahead(1, |t| *t == token::COLON)
+                && self.look_ahead(1, |t| *t == token::Colon)
         } else {
             self.look_ahead(offset, |t| is_plain_ident_or_underscore(t))
-                && self.look_ahead(offset + 1, |t| *t == token::COLON)
+                && self.look_ahead(offset + 1, |t| *t == token::Colon)
         }
     }
 
@@ -1601,7 +1588,7 @@ pub fn parse_arg_general(&mut self, require_name: bool) -> Arg {
                    require_name);
             let pat = self.parse_pat();
 
-            self.expect(&token::COLON);
+            self.expect(&token::Colon);
             pat
         } else {
             debug!("parse_arg_general ident_to_pat");
@@ -1627,7 +1614,7 @@ pub fn parse_arg(&mut self) -> Arg {
     /// Parse an argument in a lambda header e.g. |arg, arg|
     pub fn parse_fn_block_arg(&mut self) -> Arg {
         let pat = self.parse_pat();
-        let t = if self.eat(&token::COLON) {
+        let t = if self.eat(&token::Colon) {
             self.parse_ty(true)
         } else {
             P(Ty {
@@ -1644,8 +1631,8 @@ pub fn parse_fn_block_arg(&mut self) -> Arg {
     }
 
     pub fn maybe_parse_fixed_vstore(&mut self) -> Option<P<ast::Expr>> {
-        if self.token == token::COMMA &&
-                self.look_ahead(1, |t| *t == token::DOTDOT) {
+        if self.token == token::Comma &&
+                self.look_ahead(1, |t| *t == token::DotDot) {
             self.bump();
             self.bump();
             Some(self.parse_expr())
@@ -1657,24 +1644,24 @@ pub fn maybe_parse_fixed_vstore(&mut self) -> Option<P<ast::Expr>> {
     /// Matches token_lit = LIT_INTEGER | ...
     pub fn lit_from_token(&mut self, tok: &token::Token) -> Lit_ {
         match *tok {
-            token::LIT_BYTE(i) => LitByte(parse::byte_lit(i.as_str()).val0()),
-            token::LIT_CHAR(i) => LitChar(parse::char_lit(i.as_str()).val0()),
-            token::LIT_INTEGER(s) => parse::integer_lit(s.as_str(),
+            token::LitByte(i) => LitByte(parse::byte_lit(i.as_str()).val0()),
+            token::LitChar(i) => LitChar(parse::char_lit(i.as_str()).val0()),
+            token::LitInteger(s) => parse::integer_lit(s.as_str(),
                                                         &self.sess.span_diagnostic, self.span),
-            token::LIT_FLOAT(s) => parse::float_lit(s.as_str()),
-            token::LIT_STR(s) => {
+            token::LitFloat(s) => parse::float_lit(s.as_str()),
+            token::LitStr(s) => {
                 LitStr(token::intern_and_get_ident(parse::str_lit(s.as_str()).as_slice()),
                        ast::CookedStr)
             }
-            token::LIT_STR_RAW(s, n) => {
+            token::LitStrRaw(s, n) => {
                 LitStr(token::intern_and_get_ident(parse::raw_str_lit(s.as_str()).as_slice()),
                        ast::RawStr(n))
             }
-            token::LIT_BINARY(i) =>
+            token::LitBinary(i) =>
                 LitBinary(parse::binary_lit(i.as_str())),
-            token::LIT_BINARY_RAW(i, _) =>
+            token::LitBinaryRaw(i, _) =>
                 LitBinary(Rc::new(i.as_str().as_bytes().iter().map(|&x| x).collect())),
-            token::LPAREN => { self.expect(&token::RPAREN); LitNil },
+            token::LParen => { self.expect(&token::RParen); LitNil },
             _ => { self.unexpected_last(tok); }
         }
     }
@@ -1697,7 +1684,7 @@ pub fn parse_lit(&mut self) -> Lit {
     /// matches '-' lit | lit
     pub fn parse_literal_maybe_minus(&mut self) -> P<Expr> {
         let minus_lo = self.span.lo;
-        let minus_present = self.eat(&token::BINOP(token::MINUS));
+        let minus_present = self.eat(&token::BinOp(token::Minus));
 
         let lo = self.span.lo;
         let literal = P(self.parse_lit());
@@ -1720,11 +1707,11 @@ pub fn parse_literal_maybe_minus(&mut self) -> P<Expr> {
     pub fn parse_path(&mut self, mode: PathParsingMode) -> PathAndBounds {
         // Check for a whole path...
         let found = match self.token {
-            INTERPOLATED(token::NtPath(_)) => Some(self.bump_and_get()),
+            token::Interpolated(token::NtPath(_)) => Some(self.bump_and_get()),
             _ => None,
         };
         match found {
-            Some(INTERPOLATED(token::NtPath(box path))) => {
+            Some(token::Interpolated(token::NtPath(box path))) => {
                 return PathAndBounds {
                     path: path,
                     bounds: None
@@ -1734,7 +1721,7 @@ pub fn parse_path(&mut self, mode: PathParsingMode) -> PathAndBounds {
         }
 
         let lo = self.span.lo;
-        let is_global = self.eat(&token::MOD_SEP);
+        let is_global = self.eat(&token::ModSep);
 
         // Parse any number of segments and bound sets. A segment is an
         // identifier followed by an optional lifetime and a set of types.
@@ -1747,7 +1734,7 @@ pub fn parse_path(&mut self, mode: PathParsingMode) -> PathAndBounds {
             // Parse the '::' before type parameters if it's required. If
             // it is required and wasn't present, then we're done.
             if mode == LifetimeAndTypesWithColons &&
-                    !self.eat(&token::MOD_SEP) {
+                    !self.eat(&token::ModSep) {
                 segments.push(ast::PathSegment {
                     identifier: identifier,
                     lifetimes: Vec::new(),
@@ -1778,7 +1765,7 @@ pub fn parse_path(&mut self, mode: PathParsingMode) -> PathAndBounds {
             // a double colon to get here in the first place.
             if !(mode == LifetimeAndTypesWithColons &&
                     !any_lifetime_or_types) {
-                if !self.eat(&token::MOD_SEP) {
+                if !self.eat(&token::ModSep) {
                     break
                 }
             }
@@ -1790,7 +1777,7 @@ pub fn parse_path(&mut self, mode: PathParsingMode) -> PathAndBounds {
         // error.
         let opt_bounds = {
             if mode == LifetimeAndTypesAndBounds &&
-                self.eat(&token::BINOP(token::PLUS))
+                self.eat(&token::BinOp(token::Plus))
             {
                 let bounds = self.parse_ty_param_bounds();
 
@@ -1828,7 +1815,7 @@ pub fn parse_path(&mut self, mode: PathParsingMode) -> PathAndBounds {
     /// parses 0 or 1 lifetime
     pub fn parse_opt_lifetime(&mut self) -> Option<ast::Lifetime> {
         match self.token {
-            token::LIFETIME(..) => {
+            token::Lifetime(..) => {
                 Some(self.parse_lifetime())
             }
             _ => {
@@ -1841,7 +1828,7 @@ pub fn parse_opt_lifetime(&mut self) -> Option<ast::Lifetime> {
     /// Matches lifetime = LIFETIME
     pub fn parse_lifetime(&mut self) -> ast::Lifetime {
         match self.token {
-            token::LIFETIME(i) => {
+            token::Lifetime(i) => {
                 let span = self.span;
                 self.bump();
                 return ast::Lifetime {
@@ -1865,11 +1852,11 @@ pub fn parse_lifetime_defs(&mut self) -> Vec<ast::LifetimeDef> {
         let mut res = Vec::new();
         loop {
             match self.token {
-                token::LIFETIME(_) => {
+                token::Lifetime(_) => {
                     let lifetime = self.parse_lifetime();
                     let bounds =
-                        if self.eat(&token::COLON) {
-                            self.parse_lifetimes(token::BINOP(token::PLUS))
+                        if self.eat(&token::Colon) {
+                            self.parse_lifetimes(token::BinOp(token::Plus))
                         } else {
                             Vec::new()
                         };
@@ -1883,9 +1870,9 @@ pub fn parse_lifetime_defs(&mut self) -> Vec<ast::LifetimeDef> {
             }
 
             match self.token {
-                token::COMMA => { self.bump(); }
-                token::GT => { return res; }
-                token::BINOP(token::SHR) => { return res; }
+                token::Comma => { self.bump(); }
+                token::Gt => { return res; }
+                token::BinOp(token::Shr) => { return res; }
                 _ => {
                     let msg = format!("expected `,` or `>` after lifetime \
                                       name, got: {}",
@@ -1910,7 +1897,7 @@ pub fn parse_lifetimes(&mut self, sep: token::Token) -> Vec<ast::Lifetime> {
         let mut res = Vec::new();
         loop {
             match self.token {
-                token::LIFETIME(_) => {
+                token::Lifetime(_) => {
                     res.push(self.parse_lifetime());
                 }
                 _ => {
@@ -1926,11 +1913,6 @@ pub fn parse_lifetimes(&mut self, sep: token::Token) -> Vec<ast::Lifetime> {
         }
     }
 
-    pub fn token_is_mutability(tok: &token::Token) -> bool {
-        token::is_keyword(keywords::Mut, tok) ||
-        token::is_keyword(keywords::Const, tok)
-    }
-
     /// Parse mutability declaration (mut/const/imm)
     pub fn parse_mutability(&mut self) -> Mutability {
         if self.eat_keyword(keywords::Mut) {
@@ -1945,7 +1927,7 @@ pub fn parse_field(&mut self) -> Field {
         let lo = self.span.lo;
         let i = self.parse_ident();
         let hi = self.last_span.hi;
-        self.expect(&token::COLON);
+        self.expect(&token::Colon);
         let e = self.parse_expr();
         ast::Field {
             ident: spanned(lo, hi, i),
@@ -2043,31 +2025,31 @@ pub fn parse_bottom_expr(&mut self) -> P<Expr> {
         let ex: Expr_;
 
         match self.token {
-            token::LPAREN => {
+            token::LParen => {
                 self.bump();
                 // (e) is parenthesized e
                 // (e,) is a tuple with only one field, e
                 let mut trailing_comma = false;
-                if self.token == token::RPAREN {
+                if self.token == token::RParen {
                     hi = self.span.hi;
                     self.bump();
                     let lit = P(spanned(lo, hi, LitNil));
                     return self.mk_expr(lo, hi, ExprLit(lit));
                 }
                 let mut es = vec!(self.parse_expr());
-                self.commit_expr(&**es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]);
-                while self.token == token::COMMA {
+                self.commit_expr(&**es.last().unwrap(), &[], &[token::Comma, token::RParen]);
+                while self.token == token::Comma {
                     self.bump();
-                    if self.token != token::RPAREN {
+                    if self.token != token::RParen {
                         es.push(self.parse_expr());
                         self.commit_expr(&**es.last().unwrap(), &[],
-                                         &[token::COMMA, token::RPAREN]);
+                                         &[token::Comma, token::RParen]);
                     } else {
                         trailing_comma = true;
                     }
                 }
                 hi = self.span.hi;
-                self.commit_expr_expecting(&**es.last().unwrap(), token::RPAREN);
+                self.commit_expr_expecting(&**es.last().unwrap(), token::RParen);
 
                 return if es.len() == 1 && !trailing_comma {
                    self.mk_expr(lo, hi, ExprParen(es.into_iter().nth(0).unwrap()))
@@ -2075,50 +2057,50 @@ pub fn parse_bottom_expr(&mut self) -> P<Expr> {
                     self.mk_expr(lo, hi, ExprTup(es))
                 }
             },
-            token::LBRACE => {
+            token::LBrace => {
                 self.bump();
                 let blk = self.parse_block_tail(lo, DefaultBlock);
                 return self.mk_expr(blk.span.lo, blk.span.hi,
                                     ExprBlock(blk));
             },
-            token::BINOP(token::OR) |  token::OROR => {
+            token::BinOp(token::Or) |  token::OrOr => {
                 return self.parse_lambda_expr(CaptureByRef);
             },
             // FIXME #13626: Should be able to stick in
             // token::SELF_KEYWORD_NAME
-            token::IDENT(id @ ast::Ident{
-                        name: ast::Name(token::SELF_KEYWORD_NAME_NUM),
-                        ctxt: _
-                    } ,false) => {
+            token::Ident(id @ ast::Ident {
+                            name: ast::Name(token::SELF_KEYWORD_NAME_NUM),
+                            ctxt: _
+                         }, token::Plain) => {
                 self.bump();
                 let path = ast_util::ident_to_path(mk_sp(lo, hi), id);
                 ex = ExprPath(path);
                 hi = self.last_span.hi;
             }
-            token::LBRACKET => {
+            token::LBracket => {
                 self.bump();
 
-                if self.token == token::RBRACKET {
+                if self.token == token::RBracket {
                     // Empty vector.
                     self.bump();
                     ex = ExprVec(Vec::new());
                 } else {
                     // Nonempty vector.
                     let first_expr = self.parse_expr();
-                    if self.token == token::COMMA &&
-                        self.look_ahead(1, |t| *t == token::DOTDOT) {
+                    if self.token == token::Comma &&
+                        self.look_ahead(1, |t| *t == token::DotDot) {
                         // Repeating vector syntax: [ 0, ..512 ]
                         self.bump();
                         self.bump();
                         let count = self.parse_expr();
-                        self.expect(&token::RBRACKET);
+                        self.expect(&token::RBracket);
                         ex = ExprRepeat(first_expr, count);
-                    } else if self.token == token::COMMA {
+                    } else if self.token == token::Comma {
                         // Vector with two or more elements.
                         self.bump();
                         let remaining_exprs = self.parse_seq_to_end(
-                            &token::RBRACKET,
-                            seq_sep_trailing_allowed(token::COMMA),
+                            &token::RBracket,
+                            seq_sep_trailing_allowed(token::Comma),
                             |p| p.parse_expr()
                                 );
                         let mut exprs = vec!(first_expr);
@@ -2126,7 +2108,7 @@ pub fn parse_bottom_expr(&mut self) -> P<Expr> {
                         ex = ExprVec(exprs);
                     } else {
                         // Vector with one element.
-                        self.expect(&token::RBRACKET);
+                        self.expect(&token::RBracket);
                         ex = ExprVec(vec!(first_expr));
                     }
                 }
@@ -2158,10 +2140,10 @@ pub fn parse_bottom_expr(&mut self) -> P<Expr> {
                 if self.eat_keyword(keywords::While) {
                     return self.parse_while_expr(None);
                 }
-                if Parser::token_is_lifetime(&self.token) {
+                if self.token.is_lifetime() {
                     let lifetime = self.get_lifetime();
                     self.bump();
-                    self.expect(&token::COLON);
+                    self.expect(&token::Colon);
                     if self.eat_keyword(keywords::While) {
                         return self.parse_while_expr(Some(lifetime))
                     }
@@ -2178,7 +2160,7 @@ pub fn parse_bottom_expr(&mut self) -> P<Expr> {
                 }
                 if self.eat_keyword(keywords::Continue) {
                     let lo = self.span.lo;
-                    let ex = if Parser::token_is_lifetime(&self.token) {
+                    let ex = if self.token.is_lifetime() {
                         let lifetime = self.get_lifetime();
                         self.bump();
                         ExprAgain(Some(lifetime))
@@ -2198,7 +2180,7 @@ pub fn parse_bottom_expr(&mut self) -> P<Expr> {
                 }
                 if self.eat_keyword(keywords::Return) {
                     // RETURN expression
-                    if can_begin_expr(&self.token) {
+                    if self.token.can_begin_expr() {
                         let e = self.parse_expr();
                         hi = e.span.hi;
                         ex = ExprRet(Some(e));
@@ -2207,7 +2189,7 @@ pub fn parse_bottom_expr(&mut self) -> P<Expr> {
                     }
                 } else if self.eat_keyword(keywords::Break) {
                     // BREAK expression
-                    if Parser::token_is_lifetime(&self.token) {
+                    if self.token.is_lifetime() {
                         let lifetime = self.get_lifetime();
                         self.bump();
                         ex = ExprBreak(Some(lifetime));
@@ -2215,19 +2197,19 @@ pub fn parse_bottom_expr(&mut self) -> P<Expr> {
                         ex = ExprBreak(None);
                     }
                     hi = self.span.hi;
-                } else if self.token == token::MOD_SEP ||
-                        is_ident(&self.token) &&
-                        !self.is_keyword(keywords::True) &&
-                        !self.is_keyword(keywords::False) {
+                } else if self.token == token::ModSep ||
+                        self.token.is_ident() &&
+                        !self.token.is_keyword(keywords::True) &&
+                        !self.token.is_keyword(keywords::False) {
                     let pth =
                         self.parse_path(LifetimeAndTypesWithColons).path;
 
                     // `!`, as an operator, is prefix, so we know this isn't that
-                    if self.token == token::NOT {
+                    if self.token == token::Not {
                         // MACRO INVOCATION expression
                         self.bump();
 
-                        let ket = token::close_delimiter_for(&self.token)
+                        let ket = self.token.get_close_delimiter()
                             .unwrap_or_else(|| {
                                 self.fatal("expected open delimiter")
                             });
@@ -2245,7 +2227,7 @@ pub fn parse_bottom_expr(&mut self) -> P<Expr> {
                                                            tts,
                                                            EMPTY_CTXT));
                     }
-                    if self.token == token::LBRACE {
+                    if self.token == token::LBrace {
                         // This is a struct literal, unless we're prohibited
                         // from parsing struct literals here.
                         if !self.restrictions.contains(RESTRICTION_NO_STRUCT_LITERAL) {
@@ -2254,16 +2236,16 @@ pub fn parse_bottom_expr(&mut self) -> P<Expr> {
                             let mut fields = Vec::new();
                             let mut base = None;
 
-                            while self.token != token::RBRACE {
-                                if self.eat(&token::DOTDOT) {
+                            while self.token != token::RBrace {
+                                if self.eat(&token::DotDot) {
                                     base = Some(self.parse_expr());
                                     break;
                                 }
 
                                 fields.push(self.parse_field());
                                 self.commit_expr(&*fields.last().unwrap().expr,
-                                                 &[token::COMMA],
-                                                 &[token::RBRACE]);
+                                                 &[token::Comma],
+                                                 &[token::RBrace]);
                             }
 
                             if fields.len() == 0 && base.is_none() {
@@ -2276,7 +2258,7 @@ pub fn parse_bottom_expr(&mut self) -> P<Expr> {
                             }
 
                             hi = self.span.hi;
-                            self.expect(&token::RBRACE);
+                            self.expect(&token::RBrace);
                             ex = ExprStruct(pth, fields, base);
                             return self.mk_expr(lo, hi, ex);
                         }
@@ -2299,7 +2281,7 @@ pub fn parse_bottom_expr(&mut self) -> P<Expr> {
     /// Parse a block or unsafe block
     pub fn parse_block_expr(&mut self, lo: BytePos, blk_mode: BlockCheckMode)
                             -> P<Expr> {
-        self.expect(&token::LBRACE);
+        self.expect(&token::LBrace);
         let blk = self.parse_block_tail(lo, blk_mode);
         return self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk));
     }
@@ -2316,13 +2298,13 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: P<Expr>) -> P<Expr> {
         let mut hi;
         loop {
             // expr.f
-            if self.eat(&token::DOT) {
+            if self.eat(&token::Dot) {
                 match self.token {
-                  token::IDENT(i, _) => {
+                  token::Ident(i, _) => {
                     let dot = self.last_span.hi;
                     hi = self.span.hi;
                     self.bump();
-                    let (_, tys) = if self.eat(&token::MOD_SEP) {
+                    let (_, tys) = if self.eat(&token::ModSep) {
                         self.expect_lt();
                         self.parse_generic_values_after_lt()
                     } else {
@@ -2331,11 +2313,11 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: P<Expr>) -> P<Expr> {
 
                     // expr.f() method call
                     match self.token {
-                        token::LPAREN => {
+                        token::LParen => {
                             let mut es = self.parse_unspanned_seq(
-                                &token::LPAREN,
-                                &token::RPAREN,
-                                seq_sep_trailing_allowed(token::COMMA),
+                                &token::LParen,
+                                &token::RParen,
+                                seq_sep_trailing_allowed(token::Comma),
                                 |p| p.parse_expr()
                             );
                             hi = self.last_span.hi;
@@ -2352,12 +2334,12 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: P<Expr>) -> P<Expr> {
                         }
                     }
                   }
-                  token::LIT_INTEGER(n) => {
+                  token::LitInteger(n) => {
                     let index = n.as_str();
                     let dot = self.last_span.hi;
                     hi = self.span.hi;
                     self.bump();
-                    let (_, tys) = if self.eat(&token::MOD_SEP) {
+                    let (_, tys) = if self.eat(&token::ModSep) {
                         self.expect_lt();
                         self.parse_generic_values_after_lt()
                     } else {
@@ -2377,7 +2359,7 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: P<Expr>) -> P<Expr> {
                         }
                     }
                   }
-                  token::LIT_FLOAT(n) => {
+                  token::LitFloat(n) => {
                     self.bump();
                     let last_span = self.last_span;
                     self.span_err(last_span,
@@ -2394,11 +2376,11 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: P<Expr>) -> P<Expr> {
             if self.expr_is_complete(&*e) { break; }
             match self.token {
               // expr(...)
-              token::LPAREN => {
+              token::LParen => {
                 let es = self.parse_unspanned_seq(
-                    &token::LPAREN,
-                    &token::RPAREN,
-                    seq_sep_trailing_allowed(token::COMMA),
+                    &token::LParen,
+                    &token::RParen,
+                    seq_sep_trailing_allowed(token::Comma),
                     |p| p.parse_expr()
                 );
                 hi = self.last_span.hi;
@@ -2411,7 +2393,7 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: P<Expr>) -> P<Expr> {
               // Could be either an index expression or a slicing expression.
               // Any slicing non-terminal can have a mutable version with `mut`
               // after the opening square bracket.
-              token::LBRACKET => {
+              token::LBracket => {
                 self.bump();
                 let mutbl = if self.eat_keyword(keywords::Mut) {
                     MutMutable
@@ -2420,18 +2402,18 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: P<Expr>) -> P<Expr> {
                 };
                 match self.token {
                     // e[]
-                    token::RBRACKET => {
+                    token::RBracket => {
                         self.bump();
                         hi = self.span.hi;
                         let slice = self.mk_slice(e, None, None, mutbl);
                         e = self.mk_expr(lo, hi, slice)
                     }
                     // e[..e]
-                    token::DOTDOT => {
+                    token::DotDot => {
                         self.bump();
                         match self.token {
                             // e[..]
-                            token::RBRACKET => {
+                            token::RBracket => {
                                 self.bump();
                                 hi = self.span.hi;
                                 let slice = self.mk_slice(e, None, None, mutbl);
@@ -2445,7 +2427,7 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: P<Expr>) -> P<Expr> {
                             _ => {
                                 hi = self.span.hi;
                                 let e2 = self.parse_expr();
-                                self.commit_expr_expecting(&*e2, token::RBRACKET);
+                                self.commit_expr_expecting(&*e2, token::RBracket);
                                 let slice = self.mk_slice(e, None, Some(e2), mutbl);
                                 e = self.mk_expr(lo, hi, slice)
                             }
@@ -2456,18 +2438,18 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: P<Expr>) -> P<Expr> {
                         let ix = self.parse_expr();
                         match self.token {
                             // e[e..] | e[e..e]
-                            token::DOTDOT => {
+                            token::DotDot => {
                                 self.bump();
                                 let e2 = match self.token {
                                     // e[e..]
-                                    token::RBRACKET => {
+                                    token::RBracket => {
                                         self.bump();
                                         None
                                     }
                                     // e[e..e]
                                     _ => {
                                         let e2 = self.parse_expr();
-                                        self.commit_expr_expecting(&*e2, token::RBRACKET);
+                                        self.commit_expr_expecting(&*e2, token::RBracket);
                                         Some(e2)
                                     }
                                 };
@@ -2482,7 +2464,7 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: P<Expr>) -> P<Expr> {
                                                   "`mut` keyword is invalid in index expressions");
                                 }
                                 hi = self.span.hi;
-                                self.commit_expr_expecting(&*ix, token::RBRACKET);
+                                self.commit_expr_expecting(&*ix, token::RBracket);
                                 let index = self.mk_index(e, ix);
                                 e = self.mk_expr(lo, hi, index)
                             }
@@ -2497,27 +2479,30 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: P<Expr>) -> P<Expr> {
         return e;
     }
 
-    /// Parse an optional separator followed by a kleene-style
+    /// Parse an optional separator followed by a Kleene-style
     /// repetition token (+ or *).
-    pub fn parse_sep_and_zerok(&mut self) -> (Option<token::Token>, bool) {
-        fn parse_zerok(parser: &mut Parser) -> Option<bool> {
+    pub fn parse_sep_and_kleene_op(&mut self) -> (Option<token::Token>, ast::KleeneOp) {
+        fn parse_kleene_op(parser: &mut Parser) -> Option<ast::KleeneOp> {
             match parser.token {
-                token::BINOP(token::STAR) | token::BINOP(token::PLUS) => {
-                    let zerok = parser.token == token::BINOP(token::STAR);
+                token::BinOp(token::Star) => {
                     parser.bump();
-                    Some(zerok)
+                    Some(ast::ZeroOrMore)
+                },
+                token::BinOp(token::Plus) => {
+                    parser.bump();
+                    Some(ast::OneOrMore)
                 },
                 _ => None
             }
         };
 
-        match parse_zerok(self) {
-            Some(zerok) => return (None, zerok),
+        match parse_kleene_op(self) {
+            Some(kleene_op) => return (None, kleene_op),
             None => {}
         }
 
         let separator = self.bump_and_get();
-        match parse_zerok(self) {
+        match parse_kleene_op(self) {
             Some(zerok) => (Some(separator), zerok),
             None => self.fatal("expected `*` or `+`")
         }
@@ -2526,8 +2511,8 @@ fn parse_zerok(parser: &mut Parser) -> Option<bool> {
     /// parse a single token tree from the input.
     pub fn parse_token_tree(&mut self) -> TokenTree {
         // FIXME #6994: currently, this is too eager. It
-        // parses token trees but also identifies TTSeq's
-        // and TTNonterminal's; it's too early to know yet
+        // parses token trees but also identifies TtSequence's
+        // and TtNonterminal's; it's too early to know yet
         // whether something will be a nonterminal or a seq
         // yet.
         maybe_whole!(deref self, NtTT);
@@ -2540,7 +2525,7 @@ pub fn parse_token_tree(&mut self) -> TokenTree {
         fn parse_non_delim_tt_tok(p: &mut Parser) -> TokenTree {
             maybe_whole!(deref p, NtTT);
             match p.token {
-              token::RPAREN | token::RBRACE | token::RBRACKET => {
+              token::RParen | token::RBrace | token::RBracket => {
                   // This is a conservative error: only report the last unclosed delimiter. The
                   // previous unclosed delimiters could actually be closed! The parser just hasn't
                   // gotten to them yet.
@@ -2553,39 +2538,34 @@ fn parse_non_delim_tt_tok(p: &mut Parser) -> TokenTree {
                                   token_str).as_slice())
               },
               /* we ought to allow different depths of unquotation */
-              token::DOLLAR if p.quote_depth > 0u => {
+              token::Dollar if p.quote_depth > 0u => {
                 p.bump();
                 let sp = p.span;
 
-                if p.token == token::LPAREN {
+                if p.token == token::LParen {
                     let seq = p.parse_seq(
-                        &token::LPAREN,
-                        &token::RPAREN,
+                        &token::LParen,
+                        &token::RParen,
                         seq_sep_none(),
                         |p| p.parse_token_tree()
                     );
-                    let (s, z) = p.parse_sep_and_zerok();
+                    let (sep, repeat) = p.parse_sep_and_kleene_op();
                     let seq = match seq {
                         Spanned { node, .. } => node,
                     };
-                    TTSeq(mk_sp(sp.lo, p.span.hi), Rc::new(seq), s, z)
+                    TtSequence(mk_sp(sp.lo, p.span.hi), Rc::new(seq), sep, repeat)
                 } else {
-                    TTNonterminal(sp, p.parse_ident())
+                    TtNonterminal(sp, p.parse_ident())
                 }
               }
               _ => {
-                  parse_any_tt_tok(p)
+                  TtToken(p.span, p.bump_and_get())
               }
             }
         }
 
-        // turn the next token into a TTTok:
-        fn parse_any_tt_tok(p: &mut Parser) -> TokenTree {
-            TTTok(p.span, p.bump_and_get())
-        }
-
-        match (&self.token, token::close_delimiter_for(&self.token)) {
-            (&token::EOF, _) => {
+        match (&self.token, self.token.get_close_delimiter()) {
+            (&token::Eof, _) => {
                 let open_braces = self.open_braces.clone();
                 for sp in open_braces.iter() {
                     self.span_note(*sp, "Did you mean to close this delimiter?");
@@ -2595,21 +2575,32 @@ fn parse_any_tt_tok(p: &mut Parser) -> TokenTree {
                 self.fatal("this file contains an un-closed delimiter ");
             }
             (_, Some(close_delim)) => {
+                // The span for beginning of the delimited section
+                let pre_span = self.span;
+
                 // Parse the open delimiter.
                 self.open_braces.push(self.span);
-                let mut result = vec!(parse_any_tt_tok(self));
+                let open = Delimiter {
+                    span: self.span,
+                    token: self.bump_and_get(),
+                };
 
-                let trees =
-                    self.parse_seq_to_before_end(&close_delim,
-                                                 seq_sep_none(),
-                                                 |p| p.parse_token_tree());
-                result.extend(trees.into_iter());
+                // Parse the token trees within the delimeters
+                let tts = self.parse_seq_to_before_end(
+                    &close_delim, seq_sep_none(), |p| p.parse_token_tree()
+                );
 
                 // Parse the close delimiter.
-                result.push(parse_any_tt_tok(self));
+                let close = Delimiter {
+                    span: self.span,
+                    token: self.bump_and_get(),
+                };
                 self.open_braces.pop().unwrap();
 
-                TTDelim(Rc::new(result))
+                // Expand to cover the entire delimited token tree
+                let span = Span { hi: self.span.hi, ..pre_span };
+
+                TtDelimited(span, Rc::new((open, tts, close)))
             }
             _ => parse_non_delim_tt_tok(self)
         }
@@ -2619,7 +2610,7 @@ fn parse_any_tt_tok(p: &mut Parser) -> TokenTree {
     // up to EOF.
     pub fn parse_all_token_trees(&mut self) -> Vec<TokenTree> {
         let mut tts = Vec::new();
-        while self.token != token::EOF {
+        while self.token != token::Eof {
             tts.push(self.parse_token_tree());
         }
         tts
@@ -2630,7 +2621,7 @@ pub fn parse_matchers(&mut self) -> Vec<Matcher> {
         // the interpolation of Matcher's
         maybe_whole!(self, NtMatchers);
         let mut name_idx = 0u;
-        match token::close_delimiter_for(&self.token) {
+        match self.token.get_close_delimiter() {
             Some(other_delimiter) => {
                 self.bump();
                 self.parse_matcher_subseq_upto(&mut name_idx, &other_delimiter)
@@ -2650,8 +2641,8 @@ pub fn parse_matcher_subseq_upto(&mut self,
         let mut lparens = 0u;
 
         while self.token != *ket || lparens > 0u {
-            if self.token == token::LPAREN { lparens += 1u; }
-            if self.token == token::RPAREN { lparens -= 1u; }
+            if self.token == token::LParen { lparens += 1u; }
+            if self.token == token::RParen { lparens -= 1u; }
             ret_val.push(self.parse_matcher(name_idx));
         }
 
@@ -2663,21 +2654,21 @@ pub fn parse_matcher_subseq_upto(&mut self,
     pub fn parse_matcher(&mut self, name_idx: &mut uint) -> Matcher {
         let lo = self.span.lo;
 
-        let m = if self.token == token::DOLLAR {
+        let m = if self.token == token::Dollar {
             self.bump();
-            if self.token == token::LPAREN {
+            if self.token == token::LParen {
                 let name_idx_lo = *name_idx;
                 self.bump();
                 let ms = self.parse_matcher_subseq_upto(name_idx,
-                                                        &token::RPAREN);
+                                                        &token::RParen);
                 if ms.len() == 0u {
                     self.fatal("repetition body must be nonempty");
                 }
-                let (sep, zerok) = self.parse_sep_and_zerok();
-                MatchSeq(ms, sep, zerok, name_idx_lo, *name_idx)
+                let (sep, kleene_op) = self.parse_sep_and_kleene_op();
+                MatchSeq(ms, sep, kleene_op, name_idx_lo, *name_idx)
             } else {
                 let bound_to = self.parse_ident();
-                self.expect(&token::COLON);
+                self.expect(&token::Colon);
                 let nt_name = self.parse_ident();
                 let m = MatchNonterminal(bound_to, nt_name, *name_idx);
                 *name_idx += 1;
@@ -2697,36 +2688,36 @@ pub fn parse_prefix_expr(&mut self) -> P<Expr> {
 
         let ex;
         match self.token {
-          token::NOT => {
+          token::Not => {
             self.bump();
             let e = self.parse_prefix_expr();
             hi = e.span.hi;
             ex = self.mk_unary(UnNot, e);
           }
-          token::BINOP(token::MINUS) => {
+          token::BinOp(token::Minus) => {
             self.bump();
             let e = self.parse_prefix_expr();
             hi = e.span.hi;
             ex = self.mk_unary(UnNeg, e);
           }
-          token::BINOP(token::STAR) => {
+          token::BinOp(token::Star) => {
             self.bump();
             let e = self.parse_prefix_expr();
             hi = e.span.hi;
             ex = self.mk_unary(UnDeref, e);
           }
-          token::BINOP(token::AND) | token::ANDAND => {
+          token::BinOp(token::And) | token::AndAnd => {
             self.expect_and();
             let m = self.parse_mutability();
             let e = self.parse_prefix_expr();
             hi = e.span.hi;
             ex = ExprAddrOf(m, e);
           }
-          token::TILDE => {
+          token::Tilde => {
             self.bump();
             let last_span = self.last_span;
             match self.token {
-                token::LBRACKET => self.obsolete(last_span, ObsoleteOwnedVector),
+                token::LBracket => self.obsolete(last_span, ObsoleteOwnedVector),
                 _ => self.obsolete(last_span, ObsoleteOwnedExpr)
             }
 
@@ -2734,19 +2725,19 @@ pub fn parse_prefix_expr(&mut self) -> P<Expr> {
             hi = e.span.hi;
             ex = self.mk_unary(UnUniq, e);
           }
-          token::IDENT(_, _) => {
-            if !self.is_keyword(keywords::Box) {
+          token::Ident(_, _) => {
+            if !self.token.is_keyword(keywords::Box) {
                 return self.parse_dot_or_call_expr();
             }
 
             self.bump();
 
             // Check for a place: `box(PLACE) EXPR`.
-            if self.eat(&token::LPAREN) {
+            if self.eat(&token::LParen) {
                 // Support `box() EXPR` as the default.
-                if !self.eat(&token::RPAREN) {
+                if !self.eat(&token::RParen) {
                     let place = self.parse_expr();
-                    self.expect(&token::RPAREN);
+                    self.expect(&token::RParen);
                     let subexpression = self.parse_prefix_expr();
                     hi = subexpression.span.hi;
                     ex = ExprBox(place, subexpression);
@@ -2776,12 +2767,12 @@ pub fn parse_more_binops(&mut self, lhs: P<Expr>, min_prec: uint) -> P<Expr> {
 
         // Prevent dynamic borrow errors later on by limiting the
         // scope of the borrows.
-        if self.token == token::BINOP(token::OR) &&
+        if self.token == token::BinOp(token::Or) &&
             self.restrictions.contains(RESTRICTION_NO_BAR_OP) {
             return lhs;
         }
 
-        let cur_opt = token_to_binop(&self.token);
+        let cur_opt = self.token.to_binop();
         match cur_opt {
             Some(cur_op) => {
                 let cur_prec = operator_prec(cur_op);
@@ -2820,25 +2811,25 @@ pub fn parse_assign_expr(&mut self) -> P<Expr> {
         let lhs = self.parse_binops();
         let restrictions = self.restrictions & RESTRICTION_NO_STRUCT_LITERAL;
         match self.token {
-          token::EQ => {
+          token::Eq => {
               self.bump();
               let rhs = self.parse_expr_res(restrictions);
               self.mk_expr(lo, rhs.span.hi, ExprAssign(lhs, rhs))
           }
-          token::BINOPEQ(op) => {
+          token::BinOpEq(op) => {
               self.bump();
               let rhs = self.parse_expr_res(restrictions);
               let aop = match op {
-                  token::PLUS =>    BiAdd,
-                  token::MINUS =>   BiSub,
-                  token::STAR =>    BiMul,
-                  token::SLASH =>   BiDiv,
-                  token::PERCENT => BiRem,
-                  token::CARET =>   BiBitXor,
-                  token::AND =>     BiBitAnd,
-                  token::OR =>      BiBitOr,
-                  token::SHL =>     BiShl,
-                  token::SHR =>     BiShr
+                  token::Plus =>    BiAdd,
+                  token::Minus =>   BiSub,
+                  token::Star =>    BiMul,
+                  token::Slash =>   BiDiv,
+                  token::Percent => BiRem,
+                  token::Caret =>   BiBitXor,
+                  token::And =>     BiBitAnd,
+                  token::Or =>      BiBitOr,
+                  token::Shl =>     BiShl,
+                  token::Shr =>     BiShr
               };
               let rhs_span = rhs.span;
               let assign_op = self.mk_assign_op(aop, lhs, rhs);
@@ -2852,7 +2843,7 @@ pub fn parse_assign_expr(&mut self) -> P<Expr> {
 
     /// Parse an 'if' or 'if let' expression ('if' token already eaten)
     pub fn parse_if_expr(&mut self) -> P<Expr> {
-        if self.is_keyword(keywords::Let) {
+        if self.token.is_keyword(keywords::Let) {
             return self.parse_if_let_expr();
         }
         let lo = self.last_span.lo;
@@ -2873,7 +2864,7 @@ pub fn parse_if_let_expr(&mut self) -> P<Expr> {
         let lo = self.last_span.lo;
         self.expect_keyword(keywords::Let);
         let pat = self.parse_pat();
-        self.expect(&token::EQ);
+        self.expect(&token::Eq);
         let expr = self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL);
         let thn = self.parse_block();
         let (hi, els) = if self.eat_keyword(keywords::Else) {
@@ -2943,7 +2934,7 @@ pub fn parse_for_expr(&mut self, opt_ident: Option<ast::Ident>) -> P<Expr> {
 
     /// Parse a 'while' or 'while let' expression ('while' token already eaten)
     pub fn parse_while_expr(&mut self, opt_ident: Option<ast::Ident>) -> P<Expr> {
-        if self.is_keyword(keywords::Let) {
+        if self.token.is_keyword(keywords::Let) {
             return self.parse_while_let_expr(opt_ident);
         }
         let lo = self.last_span.lo;
@@ -2958,7 +2949,7 @@ pub fn parse_while_let_expr(&mut self, opt_ident: Option<ast::Ident>) -> P<Expr>
         let lo = self.last_span.lo;
         self.expect_keyword(keywords::Let);
         let pat = self.parse_pat();
-        self.expect(&token::EQ);
+        self.expect(&token::Eq);
         let expr = self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL);
         let body = self.parse_block();
         let hi = body.span.hi;
@@ -2975,9 +2966,9 @@ pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::Ident>) -> P<Expr> {
     fn parse_match_expr(&mut self) -> P<Expr> {
         let lo = self.last_span.lo;
         let discriminant = self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL);
-        self.commit_expr_expecting(&*discriminant, token::LBRACE);
+        self.commit_expr_expecting(&*discriminant, token::LBrace);
         let mut arms: Vec<Arm> = Vec::new();
-        while self.token != token::RBRACE {
+        while self.token != token::RBrace {
             arms.push(self.parse_arm());
         }
         let hi = self.span.hi;
@@ -2992,17 +2983,17 @@ pub fn parse_arm(&mut self) -> Arm {
         if self.eat_keyword(keywords::If) {
             guard = Some(self.parse_expr());
         }
-        self.expect(&token::FAT_ARROW);
+        self.expect(&token::FatArrow);
         let expr = self.parse_expr_res(RESTRICTION_STMT_EXPR);
 
         let require_comma =
             !classify::expr_is_simple_block(&*expr)
-            && self.token != token::RBRACE;
+            && self.token != token::RBrace;
 
         if require_comma {
-            self.commit_expr(&*expr, &[token::COMMA], &[token::RBRACE]);
+            self.commit_expr(&*expr, &[token::Comma], &[token::RBrace]);
         } else {
-            self.eat(&token::COMMA);
+            self.eat(&token::Comma);
         }
 
         ast::Arm {
@@ -3029,7 +3020,7 @@ pub fn parse_expr_res(&mut self, r: Restrictions) -> P<Expr> {
 
     /// Parse the RHS of a local variable declaration (e.g. '= 14;')
     fn parse_initializer(&mut self) -> Option<P<Expr>> {
-        if self.token == token::EQ {
+        if self.token == token::Eq {
             self.bump();
             Some(self.parse_expr())
         } else {
@@ -3042,7 +3033,7 @@ fn parse_pats(&mut self) -> Vec<P<Pat>> {
         let mut pats = Vec::new();
         loop {
             pats.push(self.parse_pat());
-            if self.token == token::BINOP(token::OR) { self.bump(); }
+            if self.token == token::BinOp(token::Or) { self.bump(); }
             else { return pats; }
         };
     }
@@ -3056,19 +3047,19 @@ fn parse_pat_vec_elements(
         let mut first = true;
         let mut before_slice = true;
 
-        while self.token != token::RBRACKET {
+        while self.token != token::RBracket {
             if first {
                 first = false;
             } else {
-                self.expect(&token::COMMA);
+                self.expect(&token::Comma);
             }
 
             if before_slice {
-                if self.token == token::DOTDOT {
+                if self.token == token::DotDot {
                     self.bump();
 
-                    if self.token == token::COMMA ||
-                            self.token == token::RBRACKET {
+                    if self.token == token::Comma ||
+                            self.token == token::RBracket {
                         slice = Some(P(ast::Pat {
                             id: ast::DUMMY_NODE_ID,
                             node: PatWild(PatWildMulti),
@@ -3085,7 +3076,7 @@ fn parse_pat_vec_elements(
             }
 
             let subpat = self.parse_pat();
-            if before_slice && self.token == token::DOTDOT {
+            if before_slice && self.token == token::DotDot {
                 self.bump();
                 slice = Some(subpat);
                 before_slice = false;
@@ -3104,21 +3095,21 @@ fn parse_pat_fields(&mut self) -> (Vec<codemap::Spanned<ast::FieldPat>> , bool)
         let mut fields = Vec::new();
         let mut etc = false;
         let mut first = true;
-        while self.token != token::RBRACE {
+        while self.token != token::RBrace {
             if first {
                 first = false;
             } else {
-                self.expect(&token::COMMA);
+                self.expect(&token::Comma);
                 // accept trailing commas
-                if self.token == token::RBRACE { break }
+                if self.token == token::RBrace { break }
             }
 
             let lo = self.span.lo;
             let hi;
 
-            if self.token == token::DOTDOT {
+            if self.token == token::DotDot {
                 self.bump();
-                if self.token != token::RBRACE {
+                if self.token != token::RBrace {
                     let token_str = self.this_token_to_string();
                     self.fatal(format!("expected `{}`, found `{}`", "}",
                                        token_str).as_slice())
@@ -3137,7 +3128,7 @@ fn parse_pat_fields(&mut self) -> (Vec<codemap::Spanned<ast::FieldPat>> , bool)
 
             let fieldname = self.parse_ident();
 
-            let (subpat, is_shorthand) = if self.token == token::COLON {
+            let (subpat, is_shorthand) = if self.token == token::Colon {
                 match bind_type {
                     BindByRef(..) | BindByValue(MutMutable) => {
                         let token_str = self.this_token_to_string();
@@ -3177,7 +3168,7 @@ pub fn parse_pat(&mut self) -> P<Pat> {
         let pat;
         match self.token {
             // parse _
-          token::UNDERSCORE => {
+          token::Underscore => {
             self.bump();
             pat = PatWild(PatWildSingle);
             hi = self.last_span.hi;
@@ -3187,7 +3178,7 @@ pub fn parse_pat(&mut self) -> P<Pat> {
                 span: mk_sp(lo, hi)
             })
           }
-          token::TILDE => {
+          token::Tilde => {
             // parse ~pat
             self.bump();
             let sub = self.parse_pat();
@@ -3201,7 +3192,7 @@ pub fn parse_pat(&mut self) -> P<Pat> {
                 span: mk_sp(lo, hi)
             })
           }
-          token::BINOP(token::AND) | token::ANDAND => {
+          token::BinOp(token::And) | token::AndAnd => {
             // parse &pat
             let lo = self.span.lo;
             self.expect_and();
@@ -3214,10 +3205,10 @@ pub fn parse_pat(&mut self) -> P<Pat> {
                 span: mk_sp(lo, hi)
             })
           }
-          token::LPAREN => {
+          token::LParen => {
             // parse (pat,pat,pat,...) as tuple
             self.bump();
-            if self.token == token::RPAREN {
+            if self.token == token::RParen {
                 hi = self.span.hi;
                 self.bump();
                 let lit = P(codemap::Spanned {
@@ -3227,15 +3218,15 @@ pub fn parse_pat(&mut self) -> P<Pat> {
                 pat = PatLit(expr);
             } else {
                 let mut fields = vec!(self.parse_pat());
-                if self.look_ahead(1, |t| *t != token::RPAREN) {
-                    while self.token == token::COMMA {
+                if self.look_ahead(1, |t| *t != token::RParen) {
+                    while self.token == token::Comma {
                         self.bump();
-                        if self.token == token::RPAREN { break; }
+                        if self.token == token::RParen { break; }
                         fields.push(self.parse_pat());
                     }
                 }
-                if fields.len() == 1 { self.expect(&token::COMMA); }
-                self.expect(&token::RPAREN);
+                if fields.len() == 1 { self.expect(&token::Comma); }
+                self.expect(&token::RParen);
                 pat = PatTup(fields);
             }
             hi = self.last_span.hi;
@@ -3245,13 +3236,13 @@ pub fn parse_pat(&mut self) -> P<Pat> {
                 span: mk_sp(lo, hi)
             })
           }
-          token::LBRACKET => {
+          token::LBracket => {
             // parse [pat,pat,...] as vector pattern
             self.bump();
             let (before, slice, after) =
                 self.parse_pat_vec_elements();
 
-            self.expect(&token::RBRACKET);
+            self.expect(&token::RBracket);
             pat = ast::PatVec(before, slice, after);
             hi = self.last_span.hi;
             return P(ast::Pat {
@@ -3264,20 +3255,21 @@ pub fn parse_pat(&mut self) -> P<Pat> {
         }
         // at this point, token != _, ~, &, &&, (, [
 
-        if (!is_ident_or_path(&self.token) && self.token != token::MOD_SEP)
-                || self.is_keyword(keywords::True)
-                || self.is_keyword(keywords::False) {
+        if (!(self.token.is_ident() || self.token.is_path())
+              && self.token != token::ModSep)
+                || self.token.is_keyword(keywords::True)
+                || self.token.is_keyword(keywords::False) {
             // Parse an expression pattern or exp .. exp.
             //
             // These expressions are limited to literals (possibly
             // preceded by unary-minus) or identifiers.
             let val = self.parse_literal_maybe_minus();
-            if (self.token == token::DOTDOTDOT) &&
+            if (self.token == token::DotDotDot) &&
                     self.look_ahead(1, |t| {
-                        *t != token::COMMA && *t != token::RBRACKET
+                        *t != token::Comma && *t != token::RBracket
                     }) {
                 self.bump();
-                let end = if is_ident_or_path(&self.token) {
+                let end = if self.token.is_ident() || self.token.is_path() {
                     let path = self.parse_path(LifetimeAndTypesWithColons)
                                    .path;
                     let hi = self.span.hi;
@@ -3311,27 +3303,27 @@ pub fn parse_pat(&mut self) -> P<Pat> {
         } else {
             let can_be_enum_or_struct = self.look_ahead(1, |t| {
                 match *t {
-                    token::LPAREN | token::LBRACKET | token::LT |
-                    token::LBRACE | token::MOD_SEP => true,
+                    token::LParen | token::LBracket | token::Lt |
+                    token::LBrace | token::ModSep => true,
                     _ => false,
                 }
             });
 
-            if self.look_ahead(1, |t| *t == token::DOTDOTDOT) &&
+            if self.look_ahead(1, |t| *t == token::DotDotDot) &&
                     self.look_ahead(2, |t| {
-                        *t != token::COMMA && *t != token::RBRACKET
+                        *t != token::Comma && *t != token::RBracket
                     }) {
                 let start = self.parse_expr_res(RESTRICTION_NO_BAR_OP);
-                self.eat(&token::DOTDOTDOT);
+                self.eat(&token::DotDotDot);
                 let end = self.parse_expr_res(RESTRICTION_NO_BAR_OP);
                 pat = PatRange(start, end);
-            } else if is_plain_ident(&self.token) && !can_be_enum_or_struct {
+            } else if self.token.is_plain_ident() && !can_be_enum_or_struct {
                 let id = self.parse_ident();
                 let id_span = self.last_span;
                 let pth1 = codemap::Spanned{span:id_span, node: id};
-                if self.eat(&token::NOT) {
+                if self.eat(&token::Not) {
                     // macro invocation
-                    let ket = token::close_delimiter_for(&self.token)
+                    let ket = self.token.get_close_delimiter()
                                     .unwrap_or_else(|| self.fatal("expected open delimiter"));
                     self.bump();
 
@@ -3342,7 +3334,7 @@ pub fn parse_pat(&mut self) -> P<Pat> {
                     let mac = MacInvocTT(ident_to_path(id_span,id), tts, EMPTY_CTXT);
                     pat = ast::PatMac(codemap::Spanned {node: mac, span: self.span});
                 } else {
-                    let sub = if self.eat(&token::AT) {
+                    let sub = if self.eat(&token::At) {
                         // parse foo @ pat
                         Some(self.parse_pat())
                     } else {
@@ -3356,7 +3348,7 @@ pub fn parse_pat(&mut self) -> P<Pat> {
                 let enum_path = self.parse_path(LifetimeAndTypesWithColons)
                                     .path;
                 match self.token {
-                    token::LBRACE => {
+                    token::LBrace => {
                         self.bump();
                         let (fields, etc) =
                             self.parse_pat_fields();
@@ -3366,10 +3358,10 @@ pub fn parse_pat(&mut self) -> P<Pat> {
                     _ => {
                         let mut args: Vec<P<Pat>> = Vec::new();
                         match self.token {
-                          token::LPAREN => {
+                          token::LParen => {
                             let is_dotdot = self.look_ahead(1, |t| {
                                 match *t {
-                                    token::DOTDOT => true,
+                                    token::DotDot => true,
                                     _ => false,
                                 }
                             });
@@ -3377,13 +3369,13 @@ pub fn parse_pat(&mut self) -> P<Pat> {
                                 // This is a "top constructor only" pat
                                 self.bump();
                                 self.bump();
-                                self.expect(&token::RPAREN);
+                                self.expect(&token::RParen);
                                 pat = PatEnum(enum_path, None);
                             } else {
                                 args = self.parse_enum_variant_seq(
-                                    &token::LPAREN,
-                                    &token::RPAREN,
-                                    seq_sep_trailing_allowed(token::COMMA),
+                                    &token::LParen,
+                                    &token::RParen,
+                                    seq_sep_trailing_allowed(token::Comma),
                                     |p| p.parse_pat()
                                 );
                                 pat = PatEnum(enum_path, Some(args));
@@ -3430,7 +3422,7 @@ pub fn parse_pat(&mut self) -> P<Pat> {
     fn parse_pat_ident(&mut self,
                        binding_mode: ast::BindingMode)
                        -> ast::Pat_ {
-        if !is_plain_ident(&self.token) {
+        if !self.token.is_plain_ident() {
             let span = self.span;
             let tok_str = self.this_token_to_string();
             self.span_fatal(span,
@@ -3439,7 +3431,7 @@ fn parse_pat_ident(&mut self,
         let ident = self.parse_ident();
         let last_span = self.last_span;
         let name = codemap::Spanned{span: last_span, node: ident};
-        let sub = if self.eat(&token::AT) {
+        let sub = if self.eat(&token::At) {
             Some(self.parse_pat())
         } else {
             None
@@ -3451,7 +3443,7 @@ fn parse_pat_ident(&mut self,
         // leads to a parse error.  Note that if there is no explicit
         // binding mode then we do not end up here, because the lookahead
         // will direct us over to parse_enum_variant()
-        if self.token == token::LPAREN {
+        if self.token == token::LParen {
             let last_span = self.last_span;
             self.span_fatal(
                 last_span,
@@ -3471,7 +3463,7 @@ fn parse_local(&mut self) -> P<Local> {
             node: TyInfer,
             span: mk_sp(lo, lo),
         });
-        if self.eat(&token::COLON) {
+        if self.eat(&token::Colon) {
             ty = self.parse_ty(true);
         }
         let init = self.parse_initializer();
@@ -3496,11 +3488,11 @@ fn parse_let(&mut self) -> P<Decl> {
     fn parse_name_and_ty(&mut self, pr: Visibility,
                          attrs: Vec<Attribute> ) -> StructField {
         let lo = self.span.lo;
-        if !is_plain_ident(&self.token) {
+        if !self.token.is_plain_ident() {
             self.fatal("expected ident");
         }
         let name = self.parse_ident();
-        self.expect(&token::COLON);
+        self.expect(&token::Colon);
         let ty = self.parse_ty(true);
         spanned(lo, self.last_span.hi, ast::StructField_ {
             kind: NamedField(name, pr),
@@ -3534,14 +3526,14 @@ fn check_expected_item(p: &mut Parser, attrs: &[Attribute]) {
         }
 
         let lo = self.span.lo;
-        if self.is_keyword(keywords::Let) {
+        if self.token.is_keyword(keywords::Let) {
             check_expected_item(self, item_attrs.as_slice());
             self.expect_keyword(keywords::Let);
             let decl = self.parse_let();
             P(spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID)))
-        } else if is_ident(&self.token)
-            && !token::is_any_keyword(&self.token)
-            && self.look_ahead(1, |t| *t == token::NOT) {
+        } else if self.token.is_ident()
+            && !self.token.is_any_keyword()
+            && self.look_ahead(1, |t| *t == token::Not) {
             // it's a macro invocation:
 
             check_expected_item(self, item_attrs.as_slice());
@@ -3551,7 +3543,7 @@ fn check_expected_item(p: &mut Parser, attrs: &[Attribute]) {
             let pth = self.parse_path(NoTypesAllowed).path;
             self.bump();
 
-            let id = if token::close_delimiter_for(&self.token).is_some() {
+            let id = if self.token.get_close_delimiter().is_some() {
                 token::special_idents::invalid // no special identifier
             } else {
                 self.parse_ident()
@@ -3560,7 +3552,7 @@ fn check_expected_item(p: &mut Parser, attrs: &[Attribute]) {
             // check that we're pointing at delimiters (need to check
             // again after the `if`, because of `parse_ident`
             // consuming more tokens).
-            let (bra, ket) = match token::close_delimiter_for(&self.token) {
+            let (bra, ket) = match self.token.get_close_delimiter() {
                 Some(ket) => (self.token.clone(), ket),
                 None      => {
                     // we only expect an ident if we didn't parse one
@@ -3640,7 +3632,7 @@ pub fn parse_block(&mut self) -> P<Block> {
         maybe_whole!(no_clone self, NtBlock);
 
         let lo = self.span.lo;
-        self.expect(&token::LBRACE);
+        self.expect(&token::LBrace);
 
         return self.parse_block_tail_(lo, DefaultBlock, Vec::new());
     }
@@ -3652,7 +3644,7 @@ fn parse_inner_attrs_and_block(&mut self)
         maybe_whole!(pair_empty self, NtBlock);
 
         let lo = self.span.lo;
-        self.expect(&token::LBRACE);
+        self.expect(&token::LBrace);
         let (inner, next) = self.parse_inner_attrs_and_next();
 
         (inner, self.parse_block_tail_(lo, DefaultBlock, next))
@@ -3689,12 +3681,12 @@ fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
 
         let mut attributes_box = attrs_remaining;
 
-        while self.token != token::RBRACE {
+        while self.token != token::RBrace {
             // parsing items even when they're not allowed lets us give
             // better error messages and recover more gracefully.
             attributes_box.push_all(self.parse_outer_attributes().as_slice());
             match self.token {
-                token::SEMI => {
+                token::Semi => {
                     if !attributes_box.is_empty() {
                         let last_span = self.last_span;
                         self.span_err(last_span,
@@ -3703,7 +3695,7 @@ fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
                     }
                     self.bump(); // empty
                 }
-                token::RBRACE => {
+                token::RBrace => {
                     // fall through and out.
                 }
                 _ => {
@@ -3714,11 +3706,11 @@ fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
                             // expression without semicolon
                             if classify::expr_requires_semi_to_be_stmt(&*e) {
                                 // Just check for errors and recover; do not eat semicolon yet.
-                                self.commit_stmt(&[], &[token::SEMI, token::RBRACE]);
+                                self.commit_stmt(&[], &[token::Semi, token::RBrace]);
                             }
 
                             match self.token {
-                                token::SEMI => {
+                                token::Semi => {
                                     self.bump();
                                     let span_with_semi = Span {
                                         lo: span.lo,
@@ -3730,7 +3722,7 @@ fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
                                         span: span_with_semi,
                                     }));
                                 }
-                                token::RBRACE => {
+                                token::RBrace => {
                                     expr = Some(e);
                                 }
                                 _ => {
@@ -3744,14 +3736,14 @@ fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
                         StmtMac(m, semi) => {
                             // statement macro; might be an expr
                             match self.token {
-                                token::SEMI => {
+                                token::Semi => {
                                     stmts.push(P(Spanned {
                                         node: StmtMac(m, true),
                                         span: span,
                                     }));
                                     self.bump();
                                 }
-                                token::RBRACE => {
+                                token::RBrace => {
                                     // if a block ends in `m!(arg)` without
                                     // a `;`, it must be an expr
                                     expr = Some(
@@ -3769,7 +3761,7 @@ fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
                         }
                         _ => { // all other kinds of statements:
                             if classify::stmt_ends_with_semi(&node) {
-                                self.commit_stmt_expecting(token::SEMI);
+                                self.commit_stmt_expecting(token::Semi);
                             }
 
                             stmts.push(P(Spanned {
@@ -3805,7 +3797,7 @@ fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
     fn parse_colon_then_ty_param_bounds(&mut self)
                                         -> OwnedSlice<TyParamBound>
     {
-        if !self.eat(&token::COLON) {
+        if !self.eat(&token::Colon) {
             OwnedSlice::empty()
         } else {
             self.parse_ty_param_bounds()
@@ -3821,7 +3813,7 @@ fn parse_ty_param_bounds(&mut self)
     {
         let mut result = vec!();
         loop {
-            let lifetime_defs = if self.eat(&token::LT) {
+            let lifetime_defs = if self.eat(&token::Lt) {
                 let lifetime_defs = self.parse_lifetime_defs();
                 self.expect_gt();
                 lifetime_defs
@@ -3829,7 +3821,7 @@ fn parse_ty_param_bounds(&mut self)
                 Vec::new()
             };
             match self.token {
-                token::LIFETIME(lifetime) => {
+                token::Lifetime(lifetime) => {
                     if lifetime_defs.len() > 0 {
                         let span = self.last_span;
                         self.span_err(span, "lifetime declarations are not \
@@ -3843,14 +3835,14 @@ fn parse_ty_param_bounds(&mut self)
                     }));
                     self.bump();
                 }
-                token::MOD_SEP | token::IDENT(..) => {
+                token::ModSep | token::Ident(..) => {
                     let path =
                         self.parse_path(LifetimeAndTypesWithoutColons).path;
-                    if self.token == token::LPAREN {
+                    if self.token == token::LParen {
                         self.bump();
                         let inputs = self.parse_seq_to_end(
-                            &token::RPAREN,
-                            seq_sep_trailing_allowed(token::COMMA),
+                            &token::RParen,
+                            seq_sep_trailing_allowed(token::Comma),
                             |p| p.parse_arg_general(false));
                         let (return_style, output) = self.parse_ret_ty();
                         result.push(UnboxedFnTyParamBound(P(UnboxedFnBound {
@@ -3875,7 +3867,7 @@ fn parse_ty_param_bounds(&mut self)
                 _ => break,
             }
 
-            if !self.eat(&token::BINOP(token::PLUS)) {
+            if !self.eat(&token::BinOp(token::Plus)) {
                 break;
             }
         }
@@ -3911,7 +3903,7 @@ fn parse_ty_param(&mut self) -> TyParam {
         let mut span = self.span;
         let mut ident = self.parse_ident();
         let mut unbound = None;
-        if self.eat(&token::QUESTION) {
+        if self.eat(&token::Question) {
             let tref = Parser::trait_ref_from_ident(ident, span);
             unbound = Some(TraitTyParamBound(tref));
             span = self.span;
@@ -3920,7 +3912,7 @@ fn parse_ty_param(&mut self) -> TyParam {
 
         let bounds = self.parse_colon_then_ty_param_bounds();
 
-        let default = if self.token == token::EQ {
+        let default = if self.token == token::Eq {
             self.bump();
             Some(self.parse_ty(true))
         }
@@ -3944,10 +3936,10 @@ fn parse_ty_param(&mut self) -> TyParam {
     ///                  | ( < lifetimes , typaramseq ( , )? > )
     /// where   typaramseq = ( typaram ) | ( typaram , typaramseq )
     pub fn parse_generics(&mut self) -> ast::Generics {
-        if self.eat(&token::LT) {
+        if self.eat(&token::Lt) {
             let lifetime_defs = self.parse_lifetime_defs();
             let mut seen_default = false;
-            let ty_params = self.parse_seq_to_gt(Some(token::COMMA), |p| {
+            let ty_params = self.parse_seq_to_gt(Some(token::Comma), |p| {
                 p.forbid_lifetime();
                 let ty_param = p.parse_ty_param();
                 if ty_param.default.is_some() {
@@ -3973,9 +3965,9 @@ pub fn parse_generics(&mut self) -> ast::Generics {
     }
 
     fn parse_generic_values_after_lt(&mut self) -> (Vec<ast::Lifetime>, Vec<P<Ty>> ) {
-        let lifetimes = self.parse_lifetimes(token::COMMA);
+        let lifetimes = self.parse_lifetimes(token::Comma);
         let result = self.parse_seq_to_gt(
-            Some(token::COMMA),
+            Some(token::Comma),
             |p| {
                 p.forbid_lifetime();
                 p.parse_ty(true)
@@ -3985,7 +3977,7 @@ fn parse_generic_values_after_lt(&mut self) -> (Vec<ast::Lifetime>, Vec<P<Ty>> )
     }
 
     fn forbid_lifetime(&mut self) {
-        if Parser::token_is_lifetime(&self.token) {
+        if self.token.is_lifetime() {
             let span = self.span;
             self.span_fatal(span, "lifetime parameters must be declared \
                                         prior to type parameters");
@@ -4002,10 +3994,10 @@ fn parse_where_clause(&mut self, generics: &mut ast::Generics) {
         loop {
             let lo = self.span.lo;
             let ident = match self.token {
-                token::IDENT(..) => self.parse_ident(),
+                token::Ident(..) => self.parse_ident(),
                 _ => break,
             };
-            self.expect(&token::COLON);
+            self.expect(&token::Colon);
 
             let bounds = self.parse_ty_param_bounds();
             let hi = self.span.hi;
@@ -4025,7 +4017,7 @@ fn parse_where_clause(&mut self, generics: &mut ast::Generics) {
             });
             parsed_something = true;
 
-            if !self.eat(&token::COMMA) {
+            if !self.eat(&token::Comma) {
                 break
             }
         }
@@ -4043,14 +4035,14 @@ fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool)
         let sp = self.span;
         let mut args: Vec<Option<Arg>> =
             self.parse_unspanned_seq(
-                &token::LPAREN,
-                &token::RPAREN,
-                seq_sep_trailing_allowed(token::COMMA),
+                &token::LParen,
+                &token::RParen,
+                seq_sep_trailing_allowed(token::Comma),
                 |p| {
-                    if p.token == token::DOTDOTDOT {
+                    if p.token == token::DotDotDot {
                         p.bump();
                         if allow_variadic {
-                            if p.token != token::RPAREN {
+                            if p.token != token::RParen {
                                 let span = p.span;
                                 p.span_fatal(span,
                                     "`...` must be last in argument list for variadic function");
@@ -4103,14 +4095,14 @@ pub fn parse_fn_decl(&mut self, allow_variadic: bool) -> P<FnDecl> {
 
     fn is_self_ident(&mut self) -> bool {
         match self.token {
-          token::IDENT(id, false) => id.name == special_idents::self_.name,
+          token::Ident(id, token::Plain) => id.name == special_idents::self_.name,
           _ => false
         }
     }
 
     fn expect_self_ident(&mut self) -> ast::Ident {
         match self.token {
-            token::IDENT(id, false) if id.name == special_idents::self_.name => {
+            token::Ident(id, token::Plain) if id.name == special_idents::self_.name => {
                 self.bump();
                 id
             },
@@ -4137,29 +4129,22 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
             //
             // We already know that the current token is `&`.
 
-            if this.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) {
+            if this.look_ahead(1, |t| t.is_keyword(keywords::Self)) {
                 this.bump();
                 SelfRegion(None, MutImmutable, this.expect_self_ident())
-            } else if this.look_ahead(1, |t| Parser::token_is_mutability(t)) &&
-                    this.look_ahead(2,
-                                    |t| token::is_keyword(keywords::Self,
-                                                          t)) {
+            } else if this.look_ahead(1, |t| t.is_mutability()) &&
+                      this.look_ahead(2, |t| t.is_keyword(keywords::Self)) {
                 this.bump();
                 let mutability = this.parse_mutability();
                 SelfRegion(None, mutability, this.expect_self_ident())
-            } else if this.look_ahead(1, |t| Parser::token_is_lifetime(t)) &&
-                       this.look_ahead(2,
-                                       |t| token::is_keyword(keywords::Self,
-                                                             t)) {
+            } else if this.look_ahead(1, |t| t.is_lifetime()) &&
+                      this.look_ahead(2, |t| t.is_keyword(keywords::Self)) {
                 this.bump();
                 let lifetime = this.parse_lifetime();
                 SelfRegion(Some(lifetime), MutImmutable, this.expect_self_ident())
-            } else if this.look_ahead(1, |t| Parser::token_is_lifetime(t)) &&
-                      this.look_ahead(2, |t| {
-                          Parser::token_is_mutability(t)
-                      }) &&
-                      this.look_ahead(3, |t| token::is_keyword(keywords::Self,
-                                                               t)) {
+            } else if this.look_ahead(1, |t| t.is_lifetime()) &&
+                      this.look_ahead(2, |t| t.is_mutability()) &&
+                      this.look_ahead(3, |t| t.is_keyword(keywords::Self)) {
                 this.bump();
                 let lifetime = this.parse_lifetime();
                 let mutability = this.parse_mutability();
@@ -4169,7 +4154,7 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
             }
         }
 
-        self.expect(&token::LPAREN);
+        self.expect(&token::LParen);
 
         // A bit of complexity and lookahead is needed here in order to be
         // backwards compatible.
@@ -4179,15 +4164,15 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
 
         let mut mutbl_self = MutImmutable;
         let explicit_self = match self.token {
-            token::BINOP(token::AND) => {
+            token::BinOp(token::And) => {
                 let eself = maybe_parse_borrowed_explicit_self(self);
                 self_ident_lo = self.last_span.lo;
                 self_ident_hi = self.last_span.hi;
                 eself
             }
-            token::TILDE => {
+            token::Tilde => {
                 // We need to make sure it isn't a type
-                if self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) {
+                if self.look_ahead(1, |t| t.is_keyword(keywords::Self)) {
                     self.bump();
                     drop(self.expect_self_ident());
                     let last_span = self.last_span;
@@ -4195,11 +4180,11 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
                 }
                 SelfStatic
             }
-            token::BINOP(token::STAR) => {
+            token::BinOp(token::Star) => {
                 // Possibly "*self" or "*mut self" -- not supported. Try to avoid
                 // emitting cryptic "unexpected token" errors.
                 self.bump();
-                let _mutability = if Parser::token_is_mutability(&self.token) {
+                let _mutability = if self.token.is_mutability() {
                     self.parse_mutability()
                 } else {
                     MutImmutable
@@ -4212,36 +4197,32 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
                 // error case, making bogus self ident:
                 SelfValue(special_idents::self_)
             }
-            token::IDENT(..) => {
+            token::Ident(..) => {
                 if self.is_self_ident() {
                     let self_ident = self.expect_self_ident();
 
                     // Determine whether this is the fully explicit form, `self:
                     // TYPE`.
-                    if self.eat(&token::COLON) {
+                    if self.eat(&token::Colon) {
                         SelfExplicit(self.parse_ty(false), self_ident)
                     } else {
                         SelfValue(self_ident)
                     }
-                } else if Parser::token_is_mutability(&self.token) &&
-                        self.look_ahead(1, |t| {
-                            token::is_keyword(keywords::Self, t)
-                        }) {
+                } else if self.token.is_mutability() &&
+                        self.look_ahead(1, |t| t.is_keyword(keywords::Self)) {
                     mutbl_self = self.parse_mutability();
                     let self_ident = self.expect_self_ident();
 
                     // Determine whether this is the fully explicit form,
                     // `self: TYPE`.
-                    if self.eat(&token::COLON) {
+                    if self.eat(&token::Colon) {
                         SelfExplicit(self.parse_ty(false), self_ident)
                     } else {
                         SelfValue(self_ident)
                     }
-                } else if Parser::token_is_mutability(&self.token) &&
-                        self.look_ahead(1, |t| *t == token::TILDE) &&
-                        self.look_ahead(2, |t| {
-                            token::is_keyword(keywords::Self, t)
-                        }) {
+                } else if self.token.is_mutability() &&
+                        self.look_ahead(1, |t| *t == token::Tilde) &&
+                        self.look_ahead(2, |t| t.is_keyword(keywords::Self)) {
                     mutbl_self = self.parse_mutability();
                     self.bump();
                     drop(self.expect_self_ident());
@@ -4264,18 +4245,18 @@ macro_rules! parse_remaining_arguments {
             {
             // If we parsed a self type, expect a comma before the argument list.
             match self.token {
-                token::COMMA => {
+                token::Comma => {
                     self.bump();
-                    let sep = seq_sep_trailing_allowed(token::COMMA);
+                    let sep = seq_sep_trailing_allowed(token::Comma);
                     let mut fn_inputs = self.parse_seq_to_before_end(
-                        &token::RPAREN,
+                        &token::RParen,
                         sep,
                         parse_arg_fn
                     );
                     fn_inputs.insert(0, Arg::new_self(explicit_self_sp, mutbl_self, $self_id));
                     fn_inputs
                 }
-                token::RPAREN => {
+                token::RParen => {
                     vec!(Arg::new_self(explicit_self_sp, mutbl_self, $self_id))
                 }
                 _ => {
@@ -4289,8 +4270,8 @@ macro_rules! parse_remaining_arguments {
 
         let fn_inputs = match explicit_self {
             SelfStatic =>  {
-                let sep = seq_sep_trailing_allowed(token::COMMA);
-                self.parse_seq_to_before_end(&token::RPAREN, sep, parse_arg_fn)
+                let sep = seq_sep_trailing_allowed(token::Comma);
+                self.parse_seq_to_before_end(&token::RParen, sep, parse_arg_fn)
             }
             SelfValue(id) => parse_remaining_arguments!(id),
             SelfRegion(_,_,id) => parse_remaining_arguments!(id),
@@ -4298,7 +4279,7 @@ macro_rules! parse_remaining_arguments {
         };
 
 
-        self.expect(&token::RPAREN);
+        self.expect(&token::RParen);
 
         let hi = self.span.hi;
 
@@ -4318,22 +4299,22 @@ macro_rules! parse_remaining_arguments {
     fn parse_fn_block_decl(&mut self)
                            -> (P<FnDecl>, Option<UnboxedClosureKind>) {
         let (optional_unboxed_closure_kind, inputs_captures) = {
-            if self.eat(&token::OROR) {
+            if self.eat(&token::OrOr) {
                 (None, Vec::new())
             } else {
-                self.expect(&token::BINOP(token::OR));
+                self.expect(&token::BinOp(token::Or));
                 let optional_unboxed_closure_kind =
                     self.parse_optional_unboxed_closure_kind();
                 let args = self.parse_seq_to_before_end(
-                    &token::BINOP(token::OR),
-                    seq_sep_trailing_allowed(token::COMMA),
+                    &token::BinOp(token::Or),
+                    seq_sep_trailing_allowed(token::Comma),
                     |p| p.parse_fn_block_arg()
                 );
                 self.bump();
                 (optional_unboxed_closure_kind, args)
             }
         };
-        let (style, output) = if self.token == token::RARROW {
+        let (style, output) = if self.token == token::RArrow {
             self.parse_ret_ty()
         } else {
             (Return, P(Ty {
@@ -4354,12 +4335,12 @@ fn parse_fn_block_decl(&mut self)
     /// Parses the `(arg, arg) -> return_type` header on a procedure.
     fn parse_proc_decl(&mut self) -> P<FnDecl> {
         let inputs =
-            self.parse_unspanned_seq(&token::LPAREN,
-                                     &token::RPAREN,
-                                     seq_sep_trailing_allowed(token::COMMA),
+            self.parse_unspanned_seq(&token::LParen,
+                                     &token::RParen,
+                                     seq_sep_trailing_allowed(token::Comma),
                                      |p| p.parse_fn_block_arg());
 
-        let (style, output) = if self.token == token::RARROW {
+        let (style, output) = if self.token == token::RArrow {
             self.parse_ret_ty()
         } else {
             (Return, P(Ty {
@@ -4422,16 +4403,16 @@ pub fn parse_method(&mut self,
 
         // code copied from parse_macro_use_or_failure... abstraction!
         let (method_, hi, new_attrs) = {
-            if !token::is_any_keyword(&self.token)
-                && self.look_ahead(1, |t| *t == token::NOT)
-                && (self.look_ahead(2, |t| *t == token::LPAREN)
-                    || self.look_ahead(2, |t| *t == token::LBRACE)) {
+            if !self.token.is_any_keyword()
+                && self.look_ahead(1, |t| *t == token::Not)
+                && (self.look_ahead(2, |t| *t == token::LParen)
+                    || self.look_ahead(2, |t| *t == token::LBrace)) {
                 // method macro.
                 let pth = self.parse_path(NoTypesAllowed).path;
-                self.expect(&token::NOT);
+                self.expect(&token::Not);
 
                 // eat a matched-delimiter token tree:
-                let tts = match token::close_delimiter_for(&self.token) {
+                let tts = match self.token.get_close_delimiter() {
                     Some(ket) => {
                         self.bump();
                         self.parse_seq_to_end(&ket,
@@ -4503,10 +4484,10 @@ fn parse_item_trait(&mut self) -> ItemInfo {
 
     fn parse_impl_items(&mut self) -> (Vec<ImplItem>, Vec<Attribute>) {
         let mut impl_items = Vec::new();
-        self.expect(&token::LBRACE);
+        self.expect(&token::LBrace);
         let (inner_attrs, mut method_attrs) =
             self.parse_inner_attrs_and_next();
-        while !self.eat(&token::RBRACE) {
+        while !self.eat(&token::RBrace) {
             method_attrs.extend(self.parse_outer_attributes().into_iter());
             let vis = self.parse_visibility();
             if self.eat_keyword(keywords::Type) {
@@ -4532,7 +4513,7 @@ fn parse_item_impl(&mut self) -> ItemInfo {
 
         // Special case: if the next identifier that follows is '(', don't
         // allow this to be parsed as a trait.
-        let could_be_trait = self.token != token::LPAREN;
+        let could_be_trait = self.token != token::LParen;
 
         // Parse the trait.
         let mut ty = self.parse_ty(true);
@@ -4580,7 +4561,7 @@ fn parse_item_struct(&mut self) -> ItemInfo {
         let class_name = self.parse_ident();
         let mut generics = self.parse_generics();
 
-        if self.eat(&token::COLON) {
+        if self.eat(&token::Colon) {
             let ty = self.parse_ty(true);
             self.span_err(ty.span, "`virtual` structs have been removed from the language");
         }
@@ -4590,11 +4571,11 @@ fn parse_item_struct(&mut self) -> ItemInfo {
         let mut fields: Vec<StructField>;
         let is_tuple_like;
 
-        if self.eat(&token::LBRACE) {
+        if self.eat(&token::LBrace) {
             // It's a record-like struct.
             is_tuple_like = false;
             fields = Vec::new();
-            while self.token != token::RBRACE {
+            while self.token != token::RBrace {
                 fields.push(self.parse_struct_decl_field());
             }
             if fields.len() == 0 {
@@ -4603,13 +4584,13 @@ fn parse_item_struct(&mut self) -> ItemInfo {
                                    token::get_ident(class_name)).as_slice());
             }
             self.bump();
-        } else if self.token == token::LPAREN {
+        } else if self.token == token::LParen {
             // It's a tuple-like struct.
             is_tuple_like = true;
             fields = self.parse_unspanned_seq(
-                &token::LPAREN,
-                &token::RPAREN,
-                seq_sep_trailing_allowed(token::COMMA),
+                &token::LParen,
+                &token::RParen,
+                seq_sep_trailing_allowed(token::Comma),
                 |p| {
                 let attrs = p.parse_outer_attributes();
                 let lo = p.span.lo;
@@ -4626,8 +4607,8 @@ fn parse_item_struct(&mut self) -> ItemInfo {
                                     written as `struct {};`",
                                    token::get_ident(class_name)).as_slice());
             }
-            self.expect(&token::SEMI);
-        } else if self.eat(&token::SEMI) {
+            self.expect(&token::Semi);
+        } else if self.eat(&token::Semi) {
             // It's a unit-like struct.
             is_tuple_like = true;
             fields = Vec::new();
@@ -4655,10 +4636,10 @@ pub fn parse_single_struct_field(&mut self,
                                      -> StructField {
         let a_var = self.parse_name_and_ty(vis, attrs);
         match self.token {
-            token::COMMA => {
+            token::Comma => {
                 self.bump();
             }
-            token::RBRACE => {}
+            token::RBrace => {}
             _ => {
                 let span = self.span;
                 let token_str = self.this_token_to_string();
@@ -4692,7 +4673,7 @@ fn parse_for_sized(&mut self) -> Option<ast::TyParamBound> {
         if self.eat_keyword(keywords::For) {
             let span = self.span;
             let ident = self.parse_ident();
-            if !self.eat(&token::QUESTION) {
+            if !self.eat(&token::Question) {
                 self.span_err(span,
                     "expected 'Sized?' after `for` in trait item");
                 return None;
@@ -4767,11 +4748,11 @@ fn parse_mod_items(&mut self,
 
     fn parse_item_const(&mut self, m: Option<Mutability>) -> ItemInfo {
         let id = self.parse_ident();
-        self.expect(&token::COLON);
+        self.expect(&token::Colon);
         let ty = self.parse_ty(true);
-        self.expect(&token::EQ);
+        self.expect(&token::Eq);
         let e = self.parse_expr();
-        self.commit_expr_expecting(&*e, token::SEMI);
+        self.commit_expr_expecting(&*e, token::Semi);
         let item = match m {
             Some(m) => ItemStatic(ty, m, e),
             None => ItemConst(ty, e),
@@ -4783,20 +4764,20 @@ fn parse_item_const(&mut self, m: Option<Mutability>) -> ItemInfo {
     fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> ItemInfo {
         let id_span = self.span;
         let id = self.parse_ident();
-        if self.token == token::SEMI {
+        if self.token == token::Semi {
             self.bump();
             // This mod is in an external file. Let's go get it!
             let (m, attrs) = self.eval_src_mod(id, outer_attrs, id_span);
             (id, m, Some(attrs))
         } else {
             self.push_mod_path(id, outer_attrs);
-            self.expect(&token::LBRACE);
+            self.expect(&token::LBrace);
             let mod_inner_lo = self.span.lo;
             let old_owns_directory = self.owns_directory;
             self.owns_directory = true;
             let (inner, next) = self.parse_inner_attrs_and_next();
-            let m = self.parse_mod_items(token::RBRACE, next, mod_inner_lo);
-            self.expect(&token::RBRACE);
+            let m = self.parse_mod_items(token::RBrace, next, mod_inner_lo);
+            self.expect(&token::RBrace);
             self.owns_directory = old_owns_directory;
             self.pop_mod_path();
             (id, ItemMod(m), Some(inner))
@@ -4920,7 +4901,7 @@ fn eval_src_mod_from_path(&mut self,
         let mod_inner_lo = p0.span.lo;
         let (mod_attrs, next) = p0.parse_inner_attrs_and_next();
         let first_item_outer_attrs = next;
-        let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs, mod_inner_lo);
+        let m0 = p0.parse_mod_items(token::Eof, first_item_outer_attrs, mod_inner_lo);
         self.sess.included_mod_stack.borrow_mut().pop();
         return (ast::ItemMod(m0), mod_attrs);
     }
@@ -4935,7 +4916,7 @@ fn parse_item_foreign_fn(&mut self, vis: ast::Visibility,
         let decl = self.parse_fn_decl(true);
         self.parse_where_clause(&mut generics);
         let hi = self.span.hi;
-        self.expect(&token::SEMI);
+        self.expect(&token::Semi);
         P(ast::ForeignItem {
             ident: ident,
             attrs: attrs,
@@ -4955,10 +4936,10 @@ fn parse_item_foreign_static(&mut self, vis: ast::Visibility,
         let mutbl = self.eat_keyword(keywords::Mut);
 
         let ident = self.parse_ident();
-        self.expect(&token::COLON);
+        self.expect(&token::Colon);
         let ty = self.parse_ty(true);
         let hi = self.span.hi;
-        self.expect(&token::SEMI);
+        self.expect(&token::Semi);
         P(ForeignItem {
             ident: ident,
             attrs: attrs,
@@ -4997,7 +4978,7 @@ fn parse_foreign_mod_items(&mut self,
             self.span_err(last_span,
                           Parser::expected_item_err(attrs_remaining.as_slice()));
         }
-        assert!(self.token == token::RBRACE);
+        assert!(self.token == token::RBrace);
         ast::ForeignMod {
             abi: abi,
             view_items: view_items,
@@ -5020,16 +5001,16 @@ fn parse_item_extern_crate(&mut self,
 
         let span = self.span;
         let (maybe_path, ident) = match self.token {
-            token::IDENT(..) => {
+            token::Ident(..) => {
                 let the_ident = self.parse_ident();
-                let path = if self.eat(&token::EQ) {
+                let path = if self.eat(&token::Eq) {
                     let path = self.parse_str();
                     let span = self.span;
                     self.obsolete(span, ObsoleteExternCrateRenaming);
                     Some(path)
                 } else if self.eat_keyword(keywords::As) {
                     // skip the ident if there is one
-                    if is_ident(&self.token) { self.bump(); }
+                    if self.token.is_ident() { self.bump(); }
 
                     self.span_err(span,
                                   format!("expected `;`, found `as`; perhaps you meant \
@@ -5039,14 +5020,14 @@ fn parse_item_extern_crate(&mut self,
                 } else {
                     None
                 };
-                self.expect(&token::SEMI);
+                self.expect(&token::Semi);
                 (path, the_ident)
             },
-            token::LIT_STR(..) | token::LIT_STR_RAW(..) => {
+            token::LitStr(..) | token::LitStrRaw(..) => {
                 let path = self.parse_str();
                 self.expect_keyword(keywords::As);
                 let the_ident = self.parse_ident();
-                self.expect(&token::SEMI);
+                self.expect(&token::Semi);
                 (Some(path), the_ident)
             },
             _ => {
@@ -5084,13 +5065,13 @@ fn parse_item_foreign_mod(&mut self,
                               attrs: Vec<Attribute> )
                               -> ItemOrViewItem {
 
-        self.expect(&token::LBRACE);
+        self.expect(&token::LBrace);
 
         let abi = opt_abi.unwrap_or(abi::C);
 
         let (inner, next) = self.parse_inner_attrs_and_next();
         let m = self.parse_foreign_mod_items(abi, next);
-        self.expect(&token::RBRACE);
+        self.expect(&token::RBrace);
 
         let last_span = self.last_span;
         let item = self.mk_item(lo,
@@ -5107,9 +5088,9 @@ fn parse_item_type(&mut self) -> ItemInfo {
         let ident = self.parse_ident();
         let mut tps = self.parse_generics();
         self.parse_where_clause(&mut tps);
-        self.expect(&token::EQ);
+        self.expect(&token::Eq);
         let ty = self.parse_ty(true);
-        self.expect(&token::SEMI);
+        self.expect(&token::Semi);
         (ident, ItemTy(ty, tps), None)
     }
 
@@ -5117,7 +5098,7 @@ fn parse_item_type(&mut self) -> ItemInfo {
     /// this should probably be renamed or refactored...
     fn parse_struct_def(&mut self) -> P<StructDef> {
         let mut fields: Vec<StructField> = Vec::new();
-        while self.token != token::RBRACE {
+        while self.token != token::RBrace {
             fields.push(self.parse_struct_decl_field());
         }
         self.bump();
@@ -5133,7 +5114,7 @@ fn parse_enum_def(&mut self, _generics: &ast::Generics) -> EnumDef {
         let mut variants = Vec::new();
         let mut all_nullary = true;
         let mut any_disr = None;
-        while self.token != token::RBRACE {
+        while self.token != token::RBrace {
             let variant_attrs = self.parse_outer_attributes();
             let vlo = self.span.lo;
 
@@ -5144,16 +5125,16 @@ fn parse_enum_def(&mut self, _generics: &ast::Generics) -> EnumDef {
             let mut args = Vec::new();
             let mut disr_expr = None;
             ident = self.parse_ident();
-            if self.eat(&token::LBRACE) {
+            if self.eat(&token::LBrace) {
                 // Parse a struct variant.
                 all_nullary = false;
                 kind = StructVariantKind(self.parse_struct_def());
-            } else if self.token == token::LPAREN {
+            } else if self.token == token::LParen {
                 all_nullary = false;
                 let arg_tys = self.parse_enum_variant_seq(
-                    &token::LPAREN,
-                    &token::RPAREN,
-                    seq_sep_trailing_allowed(token::COMMA),
+                    &token::LParen,
+                    &token::RParen,
+                    seq_sep_trailing_allowed(token::Comma),
                     |p| p.parse_ty(true)
                 );
                 for ty in arg_tys.into_iter() {
@@ -5163,7 +5144,7 @@ fn parse_enum_def(&mut self, _generics: &ast::Generics) -> EnumDef {
                     });
                 }
                 kind = TupleVariantKind(args);
-            } else if self.eat(&token::EQ) {
+            } else if self.eat(&token::Eq) {
                 disr_expr = Some(self.parse_expr());
                 any_disr = disr_expr.as_ref().map(|expr| expr.span);
                 kind = TupleVariantKind(args);
@@ -5181,9 +5162,9 @@ fn parse_enum_def(&mut self, _generics: &ast::Generics) -> EnumDef {
             };
             variants.push(P(spanned(vlo, self.last_span.hi, vr)));
 
-            if !self.eat(&token::COMMA) { break; }
+            if !self.eat(&token::Comma) { break; }
         }
-        self.expect(&token::RBRACE);
+        self.expect(&token::RBrace);
         match any_disr {
             Some(disr_span) if !all_nullary =>
                 self.span_err(disr_span,
@@ -5199,7 +5180,7 @@ fn parse_item_enum(&mut self) -> ItemInfo {
         let id = self.parse_ident();
         let mut generics = self.parse_generics();
         self.parse_where_clause(&mut generics);
-        self.expect(&token::LBRACE);
+        self.expect(&token::LBrace);
 
         let enum_definition = self.parse_enum_def(&generics);
         (id, ItemEnum(enum_definition, generics), None)
@@ -5207,7 +5188,7 @@ fn parse_item_enum(&mut self) -> ItemInfo {
 
     fn fn_expr_lookahead(tok: &token::Token) -> bool {
         match *tok {
-          token::LPAREN | token::AT | token::TILDE | token::BINOP(_) => true,
+          token::LParen | token::At | token::Tilde | token::BinOp(_) => true,
           _ => false
         }
     }
@@ -5216,7 +5197,7 @@ fn fn_expr_lookahead(tok: &token::Token) -> bool {
     /// the `extern` keyword, if one is found.
     fn parse_opt_abi(&mut self) -> Option<abi::Abi> {
         match self.token {
-            token::LIT_STR(s) | token::LIT_STR_RAW(s, _) => {
+            token::LitStr(s) | token::LitStrRaw(s, _) => {
                 self.bump();
                 let the_string = s.as_str();
                 match abi::lookup(the_string) {
@@ -5247,7 +5228,7 @@ fn parse_item_or_view_item(&mut self,
                                macros_allowed: bool)
                                -> ItemOrViewItem {
         let nt_item = match self.token {
-            INTERPOLATED(token::NtItem(ref item)) => {
+            token::Interpolated(token::NtItem(ref item)) => {
                 Some((**item).clone())
             }
             _ => None
@@ -5271,7 +5252,7 @@ fn parse_item_or_view_item(&mut self,
         if self.eat_keyword(keywords::Use) {
             // USE ITEM (IoviViewItem)
             let view_item = self.parse_use();
-            self.expect(&token::SEMI);
+            self.expect(&token::Semi);
             return IoviViewItem(ast::ViewItem {
                 node: view_item,
                 attrs: attrs,
@@ -5310,7 +5291,7 @@ fn parse_item_or_view_item(&mut self,
                                         visibility,
                                         maybe_append(attrs, extra_attrs));
                 return IoviItem(item);
-            } else if self.token == token::LBRACE {
+            } else if self.token == token::LBrace {
                 return self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs);
             }
 
@@ -5327,7 +5308,7 @@ fn parse_item_or_view_item(&mut self,
         }
 
         // the rest are all guaranteed to be items:
-        if self.is_keyword(keywords::Static) {
+        if self.token.is_keyword(keywords::Static) {
             // STATIC ITEM
             self.bump();
             let m = if self.eat_keyword(keywords::Mut) {MutMutable} else {MutImmutable};
@@ -5341,7 +5322,7 @@ fn parse_item_or_view_item(&mut self,
                                     maybe_append(attrs, extra_attrs));
             return IoviItem(item);
         }
-        if self.is_keyword(keywords::Const) {
+        if self.token.is_keyword(keywords::Const) {
             // CONST ITEM
             self.bump();
             if self.eat_keyword(keywords::Mut) {
@@ -5359,7 +5340,7 @@ fn parse_item_or_view_item(&mut self,
                                     maybe_append(attrs, extra_attrs));
             return IoviItem(item);
         }
-        if self.is_keyword(keywords::Fn) &&
+        if self.token.is_keyword(keywords::Fn) &&
                 self.look_ahead(1, |f| !Parser::fn_expr_lookahead(f)) {
             // FUNCTION ITEM
             self.bump();
@@ -5374,8 +5355,8 @@ fn parse_item_or_view_item(&mut self,
                                     maybe_append(attrs, extra_attrs));
             return IoviItem(item);
         }
-        if self.is_keyword(keywords::Unsafe)
-            && self.look_ahead(1u, |t| *t != token::LBRACE) {
+        if self.token.is_keyword(keywords::Unsafe)
+            && self.look_ahead(1u, |t| *t != token::LBrace) {
             // UNSAFE FUNCTION ITEM
             self.bump();
             let abi = if self.eat_keyword(keywords::Extern) {
@@ -5481,12 +5462,12 @@ fn parse_foreign_item(&mut self,
 
         let visibility = self.parse_visibility();
 
-        if self.is_keyword(keywords::Static) {
+        if self.token.is_keyword(keywords::Static) {
             // FOREIGN STATIC ITEM
             let item = self.parse_item_foreign_static(visibility, attrs);
             return IoviForeignItem(item);
         }
-        if self.is_keyword(keywords::Fn) || self.is_keyword(keywords::Unsafe) {
+        if self.token.is_keyword(keywords::Fn) || self.token.is_keyword(keywords::Unsafe) {
             // FOREIGN FUNCTION ITEM
             let item = self.parse_item_foreign_fn(visibility, attrs);
             return IoviForeignItem(item);
@@ -5502,27 +5483,27 @@ fn parse_macro_use_or_failure(
         lo: BytePos,
         visibility: Visibility
     ) -> ItemOrViewItem {
-        if macros_allowed && !token::is_any_keyword(&self.token)
-                && self.look_ahead(1, |t| *t == token::NOT)
-                && (self.look_ahead(2, |t| is_plain_ident(t))
-                    || self.look_ahead(2, |t| *t == token::LPAREN)
-                    || self.look_ahead(2, |t| *t == token::LBRACE)) {
+        if macros_allowed && !self.token.is_any_keyword()
+                && self.look_ahead(1, |t| *t == token::Not)
+                && (self.look_ahead(2, |t| t.is_plain_ident())
+                    || self.look_ahead(2, |t| *t == token::LParen)
+                    || self.look_ahead(2, |t| *t == token::LBrace)) {
             // MACRO INVOCATION ITEM
 
             // item macro.
             let pth = self.parse_path(NoTypesAllowed).path;
-            self.expect(&token::NOT);
+            self.expect(&token::Not);
 
             // a 'special' identifier (like what `macro_rules!` uses)
             // is optional. We should eventually unify invoc syntax
             // and remove this.
-            let id = if is_plain_ident(&self.token) {
+            let id = if self.token.is_plain_ident() {
                 self.parse_ident()
             } else {
                 token::special_idents::invalid // no special identifier
             };
             // eat a matched-delimiter token tree:
-            let tts = match token::close_delimiter_for(&self.token) {
+            let tts = match self.token.get_close_delimiter() {
                 Some(ket) => {
                     self.bump();
                     self.parse_seq_to_end(&ket,
@@ -5592,11 +5573,11 @@ fn parse_use(&mut self) -> ViewItem_ {
     fn parse_view_path(&mut self) -> P<ViewPath> {
         let lo = self.span.lo;
 
-        if self.token == token::LBRACE {
+        if self.token == token::LBrace {
             // use {foo,bar}
             let idents = self.parse_unspanned_seq(
-                &token::LBRACE, &token::RBRACE,
-                seq_sep_trailing_allowed(token::COMMA),
+                &token::LBrace, &token::RBrace,
+                seq_sep_trailing_allowed(token::Comma),
                 |p| p.parse_path_list_item());
             let path = ast::Path {
                 span: mk_sp(lo, self.span.hi),
@@ -5610,12 +5591,12 @@ fn parse_view_path(&mut self) -> P<ViewPath> {
         let first_ident = self.parse_ident();
         let mut path = vec!(first_ident);
         match self.token {
-          token::EQ => {
+          token::Eq => {
             // x = foo::bar
             self.bump();
             let path_lo = self.span.lo;
             path = vec!(self.parse_ident());
-            while self.token == token::MOD_SEP {
+            while self.token == token::ModSep {
                 self.bump();
                 let id = self.parse_ident();
                 path.push(id);
@@ -5638,23 +5619,23 @@ fn parse_view_path(&mut self) -> P<ViewPath> {
                                            ast::DUMMY_NODE_ID)));
           }
 
-          token::MOD_SEP => {
+          token::ModSep => {
             // foo::bar or foo::{a,b,c} or foo::*
-            while self.token == token::MOD_SEP {
+            while self.token == token::ModSep {
                 self.bump();
 
                 match self.token {
-                  token::IDENT(i, _) => {
+                  token::Ident(i, _) => {
                     self.bump();
                     path.push(i);
                   }
 
                   // foo::bar::{a,b,c}
-                  token::LBRACE => {
+                  token::LBrace => {
                     let idents = self.parse_unspanned_seq(
-                        &token::LBRACE,
-                        &token::RBRACE,
-                        seq_sep_trailing_allowed(token::COMMA),
+                        &token::LBrace,
+                        &token::RBrace,
+                        seq_sep_trailing_allowed(token::Comma),
                         |p| p.parse_path_list_item()
                     );
                     let path = ast::Path {
@@ -5673,7 +5654,7 @@ fn parse_view_path(&mut self) -> P<ViewPath> {
                   }
 
                   // foo::bar::*
-                  token::BINOP(token::STAR) => {
+                  token::BinOp(token::Star) => {
                     self.bump();
                     let path = ast::Path {
                         span: mk_sp(lo, self.span.hi),
@@ -5765,7 +5746,7 @@ fn parse_items_and_view_items(&mut self,
                     break;
                 }
                 IoviForeignItem(_) => {
-                    fail!();
+                    panic!();
                 }
             }
             attrs = self.parse_outer_attributes();
@@ -5788,7 +5769,7 @@ fn parse_items_and_view_items(&mut self,
                     items.push(item)
                 }
                 IoviForeignItem(_) => {
-                    fail!();
+                    panic!();
                 }
             }
         }
@@ -5812,7 +5793,7 @@ fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute> ,
         loop {
             match self.parse_foreign_item(attrs, macros_allowed) {
                 IoviNone(returned_attrs) => {
-                    if self.token == token::RBRACE {
+                    if self.token == token::RBrace {
                         attrs = returned_attrs;
                         break
                     }
@@ -5851,7 +5832,7 @@ pub fn parse_crate_mod(&mut self) -> Crate {
         let (inner, next) = self.parse_inner_attrs_and_next();
         let first_item_outer_attrs = next;
         // parse the items inside the crate:
-        let m = self.parse_mod_items(token::EOF, first_item_outer_attrs, lo);
+        let m = self.parse_mod_items(token::Eof, first_item_outer_attrs, lo);
 
         ast::Crate {
             module: m,
@@ -5865,8 +5846,8 @@ pub fn parse_crate_mod(&mut self) -> Crate {
     pub fn parse_optional_str(&mut self)
                               -> Option<(InternedString, ast::StrStyle)> {
         let (s, style) = match self.token {
-            token::LIT_STR(s) => (self.id_to_interned_str(s.ident()), ast::CookedStr),
-            token::LIT_STR_RAW(s, n) => {
+            token::LitStr(s) => (self.id_to_interned_str(s.ident()), ast::CookedStr),
+            token::LitStrRaw(s, n) => {
                 (self.id_to_interned_str(s.ident()), ast::RawStr(n))
             }
             _ => return None
index fa6b0c5ad4ae785d079c36dd2f345892c751e19a..9ed8e4bc3a70752e81ba5ce85684a9c6ffefa78c 100644 (file)
@@ -9,9 +9,7 @@
 // except according to those terms.
 
 use ast;
-use ast::{Ident, Name, Mrk};
 use ext::mtwt;
-use parse::token;
 use ptr::P;
 use util::interner::{RcStr, StrInterner};
 use util::interner;
 use std::path::BytesContainer;
 use std::rc::Rc;
 
+// NOTE(stage0): remove these re-exports after the next snapshot
+// (needed to allow quotations to pass stage0)
+#[cfg(stage0)] pub use self::Plus           as PLUS;
+#[cfg(stage0)] pub use self::Minus          as MINUS;
+#[cfg(stage0)] pub use self::Star           as STAR;
+#[cfg(stage0)] pub use self::Slash          as SLASH;
+#[cfg(stage0)] pub use self::Percent        as PERCENT;
+#[cfg(stage0)] pub use self::Caret          as CARET;
+#[cfg(stage0)] pub use self::And            as AND;
+#[cfg(stage0)] pub use self::Or             as OR;
+#[cfg(stage0)] pub use self::Shl            as SHL;
+#[cfg(stage0)] pub use self::Shr            as SHR;
+#[cfg(stage0)] pub use self::Eq             as EQ;
+#[cfg(stage0)] pub use self::Lt             as LT;
+#[cfg(stage0)] pub use self::Le             as LE;
+#[cfg(stage0)] pub use self::EqEq           as EQEQ;
+#[cfg(stage0)] pub use self::Ne             as NE;
+#[cfg(stage0)] pub use self::Ge             as GE;
+#[cfg(stage0)] pub use self::Gt             as GT;
+#[cfg(stage0)] pub use self::AndAnd         as ANDAND;
+#[cfg(stage0)] pub use self::OrOr           as OROR;
+#[cfg(stage0)] pub use self::Not            as NOT;
+#[cfg(stage0)] pub use self::Tilde          as TILDE;
+#[cfg(stage0)] pub use self::BinOp          as BINOP;
+#[cfg(stage0)] pub use self::BinOpEq        as BINOPEQ;
+#[cfg(stage0)] pub use self::At             as AT;
+#[cfg(stage0)] pub use self::Dot            as DOT;
+#[cfg(stage0)] pub use self::DotDot         as DOTDOT;
+#[cfg(stage0)] pub use self::DotDotDot      as DOTDOTDOT;
+#[cfg(stage0)] pub use self::Comma          as COMMA;
+#[cfg(stage0)] pub use self::Semi           as SEMI;
+#[cfg(stage0)] pub use self::Colon          as COLON;
+#[cfg(stage0)] pub use self::ModSep         as MOD_SEP;
+#[cfg(stage0)] pub use self::RArrow         as RARROW;
+#[cfg(stage0)] pub use self::LArrow         as LARROW;
+#[cfg(stage0)] pub use self::FatArrow       as FAT_ARROW;
+#[cfg(stage0)] pub use self::LParen         as LPAREN;
+#[cfg(stage0)] pub use self::RParen         as RPAREN;
+#[cfg(stage0)] pub use self::LBracket       as LBRACKET;
+#[cfg(stage0)] pub use self::RBracket       as RBRACKET;
+#[cfg(stage0)] pub use self::LBrace         as LBRACE;
+#[cfg(stage0)] pub use self::RBrace         as RBRACE;
+#[cfg(stage0)] pub use self::Pound          as POUND;
+#[cfg(stage0)] pub use self::Dollar         as DOLLAR;
+#[cfg(stage0)] pub use self::Question       as QUESTION;
+#[cfg(stage0)] pub use self::LitByte        as LIT_BYTE;
+#[cfg(stage0)] pub use self::LitChar        as LIT_CHAR;
+#[cfg(stage0)] pub use self::LitInteger     as LIT_INTEGER;
+#[cfg(stage0)] pub use self::LitFloat       as LIT_FLOAT;
+#[cfg(stage0)] pub use self::LitStr         as LIT_STR;
+#[cfg(stage0)] pub use self::LitStrRaw      as LIT_STR_RAW;
+#[cfg(stage0)] pub use self::LitBinary      as LIT_BINARY;
+#[cfg(stage0)] pub use self::LitBinaryRaw   as LIT_BINARY_RAW;
+#[cfg(stage0)] pub use self::Ident          as IDENT;
+#[cfg(stage0)] pub use self::Underscore     as UNDERSCORE;
+#[cfg(stage0)] pub use self::Lifetime       as LIFETIME;
+#[cfg(stage0)] pub use self::Interpolated   as INTERPOLATED;
+#[cfg(stage0)] pub use self::DocComment     as DOC_COMMENT;
+#[cfg(stage0)] pub use self::Whitespace     as WS;
+#[cfg(stage0)] pub use self::Comment        as COMMENT;
+#[cfg(stage0)] pub use self::Shebang        as SHEBANG;
+#[cfg(stage0)] pub use self::Eof            as EOF;
+
 #[allow(non_camel_case_types)]
 #[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash, Show)]
-pub enum BinOp {
-    PLUS,
-    MINUS,
-    STAR,
-    SLASH,
-    PERCENT,
-    CARET,
-    AND,
-    OR,
-    SHL,
-    SHR,
+pub enum BinOpToken {
+    Plus,
+    Minus,
+    Star,
+    Slash,
+    Percent,
+    Caret,
+    And,
+    Or,
+    Shl,
+    Shr,
+}
+
+#[cfg(stage0)]
+#[allow(non_uppercase_statics)]
+pub const ModName: bool = true;
+#[cfg(stage0)]
+#[allow(non_uppercase_statics)]
+pub const Plain: bool = false;
+
+#[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash, Show)]
+#[cfg(not(stage0))]
+pub enum IdentStyle {
+    /// `::` follows the identifier with no whitespace in-between.
+    ModName,
+    Plain,
 }
 
 #[allow(non_camel_case_types)]
 #[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash, Show)]
 pub enum Token {
     /* Expression-operator symbols. */
-    EQ,
-    LT,
-    LE,
-    EQEQ,
-    NE,
-    GE,
-    GT,
-    ANDAND,
-    OROR,
-    NOT,
-    TILDE,
-    BINOP(BinOp),
-    BINOPEQ(BinOp),
+    Eq,
+    Lt,
+    Le,
+    EqEq,
+    Ne,
+    Ge,
+    Gt,
+    AndAnd,
+    OrOr,
+    Not,
+    Tilde,
+    BinOp(BinOpToken),
+    BinOpEq(BinOpToken),
 
     /* Structural symbols */
-    AT,
-    DOT,
-    DOTDOT,
-    DOTDOTDOT,
-    COMMA,
-    SEMI,
-    COLON,
-    MOD_SEP,
-    RARROW,
-    LARROW,
-    FAT_ARROW,
-    LPAREN,
-    RPAREN,
-    LBRACKET,
-    RBRACKET,
-    LBRACE,
-    RBRACE,
-    POUND,
-    DOLLAR,
-    QUESTION,
+    At,
+    Dot,
+    DotDot,
+    DotDotDot,
+    Comma,
+    Semi,
+    Colon,
+    ModSep,
+    RArrow,
+    LArrow,
+    FatArrow,
+    LParen,
+    RParen,
+    LBracket,
+    RBracket,
+    LBrace,
+    RBrace,
+    Pound,
+    Dollar,
+    Question,
 
     /* Literals */
-    LIT_BYTE(Name),
-    LIT_CHAR(Name),
-    LIT_INTEGER(Name),
-    LIT_FLOAT(Name),
-    LIT_STR(Name),
-    LIT_STR_RAW(Name, uint), /* raw str delimited by n hash symbols */
-    LIT_BINARY(Name),
-    LIT_BINARY_RAW(Name, uint), /* raw binary str delimited by n hash symbols */
+    LitByte(ast::Name),
+    LitChar(ast::Name),
+    LitInteger(ast::Name),
+    LitFloat(ast::Name),
+    LitStr(ast::Name),
+    LitStrRaw(ast::Name, uint), /* raw str delimited by n hash symbols */
+    LitBinary(ast::Name),
+    LitBinaryRaw(ast::Name, uint), /* raw binary str delimited by n hash symbols */
 
     /* Name components */
-    /// An identifier contains an "is_mod_name" boolean,
-    /// indicating whether :: follows this token with no
-    /// whitespace in between.
-    IDENT(Ident, bool),
-    UNDERSCORE,
-    LIFETIME(Ident),
+    #[cfg(stage0)]
+    Ident(ast::Ident, bool),
+    #[cfg(not(stage0))]
+    Ident(ast::Ident, IdentStyle),
+    Underscore,
+    Lifetime(ast::Ident),
 
     /* For interpolation */
-    INTERPOLATED(Nonterminal),
-    DOC_COMMENT(Name),
+    Interpolated(Nonterminal),
+    DocComment(ast::Name),
 
     // Junk. These carry no data because we don't really care about the data
     // they *would* carry, and don't really want to allocate a new ident for
     // them. Instead, users could extract that from the associated span.
 
     /// Whitespace
-    WS,
+    Whitespace,
     /// Comment
-    COMMENT,
-    SHEBANG(Name),
+    Comment,
+    Shebang(ast::Name),
 
-    EOF,
+    Eof,
+}
+
+impl Token {
+    /// Returns `true` if the token can appear at the start of an expression.
+    pub fn can_begin_expr(&self) -> bool {
+        match *self {
+            LParen                      => true,
+            LBrace                      => true,
+            LBracket                    => true,
+            Ident(_, _)                 => true,
+            Underscore                  => true,
+            Tilde                       => true,
+            LitByte(_)                  => true,
+            LitChar(_)                  => true,
+            LitInteger(_)               => true,
+            LitFloat(_)                 => true,
+            LitStr(_)                   => true,
+            LitStrRaw(_, _)             => true,
+            LitBinary(_)                => true,
+            LitBinaryRaw(_, _)          => true,
+            Pound                       => true,
+            At                          => true,
+            Not                         => true,
+            BinOp(Minus)                => true,
+            BinOp(Star)                 => true,
+            BinOp(And)                  => true,
+            BinOp(Or)                   => true, // in lambda syntax
+            OrOr                        => true, // in lambda syntax
+            ModSep                      => true,
+            Interpolated(NtExpr(..))    => true,
+            Interpolated(NtIdent(..))   => true,
+            Interpolated(NtBlock(..))   => true,
+            Interpolated(NtPath(..))    => true,
+            _                           => false,
+        }
+    }
+
+    /// Returns the matching close delimiter if this is an open delimiter,
+    /// otherwise `None`.
+    pub fn get_close_delimiter(&self) -> Option<Token> {
+        match *self {
+            LParen   => Some(RParen),
+            LBrace   => Some(RBrace),
+            LBracket => Some(RBracket),
+            _        => None,
+        }
+    }
+
+    /// Returns `true` if the token is any literal
+    pub fn is_lit(&self) -> bool {
+        match *self {
+            LitByte(_)          => true,
+            LitChar(_)          => true,
+            LitInteger(_)       => true,
+            LitFloat(_)         => true,
+            LitStr(_)           => true,
+            LitStrRaw(_, _)     => true,
+            LitBinary(_)        => true,
+            LitBinaryRaw(_, _)  => true,
+            _                   => false,
+        }
+    }
+
+    /// Returns `true` if the token is an identifier.
+    pub fn is_ident(&self) -> bool {
+        match *self {
+            Ident(_, _) => true,
+            _           => false,
+        }
+    }
+
+    /// Returns `true` if the token is an interpolated path.
+    pub fn is_path(&self) -> bool {
+        match *self {
+            Interpolated(NtPath(..))    => true,
+            _                           => false,
+        }
+    }
+
+    /// Returns `true` if the token is a path that is not followed by a `::`
+    /// token.
+    #[allow(non_uppercase_statics)] // NOTE(stage0): remove this attribute after the next snapshot
+    pub fn is_plain_ident(&self) -> bool {
+        match *self {
+            Ident(_, Plain) => true,
+            _                    => false,
+        }
+    }
+
+    /// Returns `true` if the token is a lifetime.
+    pub fn is_lifetime(&self) -> bool {
+        match *self {
+            Lifetime(..) => true,
+            _            => false,
+        }
+    }
+
+    /// Returns `true` if the token is either the `mut` or `const` keyword.
+    pub fn is_mutability(&self) -> bool {
+        self.is_keyword(keywords::Mut) ||
+        self.is_keyword(keywords::Const)
+    }
+
+    /// Maps a token to its corresponding binary operator.
+    pub fn to_binop(&self) -> Option<ast::BinOp> {
+        match *self {
+            BinOp(Star)     => Some(ast::BiMul),
+            BinOp(Slash)    => Some(ast::BiDiv),
+            BinOp(Percent)  => Some(ast::BiRem),
+            BinOp(Plus)     => Some(ast::BiAdd),
+            BinOp(Minus)    => Some(ast::BiSub),
+            BinOp(Shl)      => Some(ast::BiShl),
+            BinOp(Shr)      => Some(ast::BiShr),
+            BinOp(And)      => Some(ast::BiBitAnd),
+            BinOp(Caret)    => Some(ast::BiBitXor),
+            BinOp(Or)       => Some(ast::BiBitOr),
+            Lt              => Some(ast::BiLt),
+            Le              => Some(ast::BiLe),
+            Ge              => Some(ast::BiGe),
+            Gt              => Some(ast::BiGt),
+            EqEq            => Some(ast::BiEq),
+            Ne              => Some(ast::BiNe),
+            AndAnd          => Some(ast::BiAnd),
+            OrOr            => Some(ast::BiOr),
+            _               => None,
+        }
+    }
+
+    /// Returns `true` if the token is a given keyword, `kw`.
+    #[allow(non_uppercase_statics)] // NOTE(stage0): remove this attribute after the next snapshot
+    pub fn is_keyword(&self, kw: keywords::Keyword) -> bool {
+        match *self {
+            Ident(sid, Plain) => kw.to_name() == sid.name,
+            _                      => false,
+        }
+    }
+
+    /// Returns `true` if the token is either a special identifier, or a strict
+    /// or reserved keyword.
+    #[allow(non_uppercase_statics)] // NOTE(stage0): remove this attribute after the next snapshot
+    pub fn is_any_keyword(&self) -> bool {
+        match *self {
+            Ident(sid, Plain) => {
+                let n = sid.name;
+
+                   n == SELF_KEYWORD_NAME
+                || n == STATIC_KEYWORD_NAME
+                || n == SUPER_KEYWORD_NAME
+                || STRICT_KEYWORD_START <= n
+                && n <= RESERVED_KEYWORD_FINAL
+            },
+            _ => false
+        }
+    }
+
+    /// Returns `true` if the token may not appear as an identifier.
+    #[allow(non_uppercase_statics)] // NOTE(stage0): remove this attribute after the next snapshot
+    pub fn is_strict_keyword(&self) -> bool {
+        match *self {
+            Ident(sid, Plain) => {
+                let n = sid.name;
+
+                   n == SELF_KEYWORD_NAME
+                || n == STATIC_KEYWORD_NAME
+                || n == SUPER_KEYWORD_NAME
+                || STRICT_KEYWORD_START <= n
+                && n <= STRICT_KEYWORD_FINAL
+            },
+            Ident(sid, ModName) => {
+                let n = sid.name;
+
+                   n != SELF_KEYWORD_NAME
+                && n != SUPER_KEYWORD_NAME
+                && STRICT_KEYWORD_START <= n
+                && n <= STRICT_KEYWORD_FINAL
+            }
+            _ => false,
+        }
+    }
+
+    /// Returns `true` if the token is a keyword that has been reserved for
+    /// possible future use.
+    #[allow(non_uppercase_statics)] // NOTE(stage0): remove this attribute after the next snapshot
+    pub fn is_reserved_keyword(&self) -> bool {
+        match *self {
+            Ident(sid, Plain) => {
+                let n = sid.name;
+
+                   RESERVED_KEYWORD_START <= n
+                && n <= RESERVED_KEYWORD_FINAL
+            },
+            _ => false,
+        }
+    }
+
+    /// Hygienic identifier equality comparison.
+    ///
+    /// See `styntax::ext::mtwt`.
+    pub fn mtwt_eq(&self, other : &Token) -> bool {
+        match (self, other) {
+            (&Ident(id1,_), &Ident(id2,_)) | (&Lifetime(id1), &Lifetime(id2)) =>
+                mtwt::resolve(id1) == mtwt::resolve(id2),
+            _ => *self == *other
+        }
+    }
 }
 
 #[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash)]
@@ -121,8 +402,10 @@ pub enum Nonterminal {
     NtPat(  P<ast::Pat>),
     NtExpr( P<ast::Expr>),
     NtTy(   P<ast::Ty>),
-    /// See IDENT, above, for meaning of bool in NtIdent:
-    NtIdent(Box<Ident>, bool),
+    #[cfg(stage0)]
+    NtIdent(Box<ast::Ident>, bool),
+    #[cfg(not(stage0))]
+    NtIdent(Box<ast::Ident>, IdentStyle),
     /// Stuff inside brackets for attributes
     NtMeta( P<ast::MetaItem>),
     NtPath(Box<ast::Path>),
@@ -148,204 +431,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-pub fn binop_to_string(o: BinOp) -> &'static str {
-    match o {
-      PLUS => "+",
-      MINUS => "-",
-      STAR => "*",
-      SLASH => "/",
-      PERCENT => "%",
-      CARET => "^",
-      AND => "&",
-      OR => "|",
-      SHL => "<<",
-      SHR => ">>"
-    }
-}
-
-pub fn to_string(t: &Token) -> String {
-    match *t {
-      EQ => "=".into_string(),
-      LT => "<".into_string(),
-      LE => "<=".into_string(),
-      EQEQ => "==".into_string(),
-      NE => "!=".into_string(),
-      GE => ">=".into_string(),
-      GT => ">".into_string(),
-      NOT => "!".into_string(),
-      TILDE => "~".into_string(),
-      OROR => "||".into_string(),
-      ANDAND => "&&".into_string(),
-      BINOP(op) => binop_to_string(op).into_string(),
-      BINOPEQ(op) => {
-          let mut s = binop_to_string(op).into_string();
-          s.push_str("=");
-          s
-      }
-
-      /* Structural symbols */
-      AT => "@".into_string(),
-      DOT => ".".into_string(),
-      DOTDOT => "..".into_string(),
-      DOTDOTDOT => "...".into_string(),
-      COMMA => ",".into_string(),
-      SEMI => ";".into_string(),
-      COLON => ":".into_string(),
-      MOD_SEP => "::".into_string(),
-      RARROW => "->".into_string(),
-      LARROW => "<-".into_string(),
-      FAT_ARROW => "=>".into_string(),
-      LPAREN => "(".into_string(),
-      RPAREN => ")".into_string(),
-      LBRACKET => "[".into_string(),
-      RBRACKET => "]".into_string(),
-      LBRACE => "{".into_string(),
-      RBRACE => "}".into_string(),
-      POUND => "#".into_string(),
-      DOLLAR => "$".into_string(),
-      QUESTION => "?".into_string(),
-
-      /* Literals */
-      LIT_BYTE(b) => {
-          format!("b'{}'", b.as_str())
-      }
-      LIT_CHAR(c) => {
-          format!("'{}'", c.as_str())
-      }
-      LIT_INTEGER(c) | LIT_FLOAT(c) => {
-          c.as_str().into_string()
-      }
-
-      LIT_STR(s) => {
-          format!("\"{}\"", s.as_str())
-      }
-      LIT_STR_RAW(s, n) => {
-        format!("r{delim}\"{string}\"{delim}",
-                 delim="#".repeat(n), string=s.as_str())
-      }
-      LIT_BINARY(v) => {
-          format!("b\"{}\"", v.as_str())
-      }
-      LIT_BINARY_RAW(s, n) => {
-        format!("br{delim}\"{string}\"{delim}",
-                 delim="#".repeat(n), string=s.as_str())
-      }
-
-      /* Name components */
-      IDENT(s, _) => get_ident(s).get().into_string(),
-      LIFETIME(s) => {
-          format!("{}", get_ident(s))
-      }
-      UNDERSCORE => "_".into_string(),
-
-      /* Other */
-      DOC_COMMENT(s) => s.as_str().into_string(),
-      EOF => "<eof>".into_string(),
-      WS => " ".into_string(),
-      COMMENT => "/* */".into_string(),
-      SHEBANG(s) => format!("/* shebang: {}*/", s.as_str()),
-
-      INTERPOLATED(ref nt) => {
-        match nt {
-            &NtExpr(ref e) => ::print::pprust::expr_to_string(&**e),
-            &NtMeta(ref e) => ::print::pprust::meta_item_to_string(&**e),
-            &NtTy(ref e) => ::print::pprust::ty_to_string(&**e),
-            &NtPath(ref e) => ::print::pprust::path_to_string(&**e),
-            _ => {
-                let mut s = "an interpolated ".into_string();
-                match *nt {
-                    NtItem(..) => s.push_str("item"),
-                    NtBlock(..) => s.push_str("block"),
-                    NtStmt(..) => s.push_str("statement"),
-                    NtPat(..) => s.push_str("pattern"),
-                    NtMeta(..) => fail!("should have been handled"),
-                    NtExpr(..) => fail!("should have been handled"),
-                    NtTy(..) => fail!("should have been handled"),
-                    NtIdent(..) => s.push_str("identifier"),
-                    NtPath(..) => fail!("should have been handled"),
-                    NtTT(..) => s.push_str("tt"),
-                    NtMatchers(..) => s.push_str("matcher sequence")
-                };
-                s
-            }
-        }
-      }
-    }
-}
-
-pub fn can_begin_expr(t: &Token) -> bool {
-    match *t {
-      LPAREN => true,
-      LBRACE => true,
-      LBRACKET => true,
-      IDENT(_, _) => true,
-      UNDERSCORE => true,
-      TILDE => true,
-      LIT_BYTE(_) => true,
-      LIT_CHAR(_) => true,
-      LIT_INTEGER(_) => true,
-      LIT_FLOAT(_) => true,
-      LIT_STR(_) => true,
-      LIT_STR_RAW(_, _) => true,
-      LIT_BINARY(_) => true,
-      LIT_BINARY_RAW(_, _) => true,
-      POUND => true,
-      AT => true,
-      NOT => true,
-      BINOP(MINUS) => true,
-      BINOP(STAR) => true,
-      BINOP(AND) => true,
-      BINOP(OR) => true, // in lambda syntax
-      OROR => true, // in lambda syntax
-      MOD_SEP => true,
-      INTERPOLATED(NtExpr(..))
-      | INTERPOLATED(NtIdent(..))
-      | INTERPOLATED(NtBlock(..))
-      | INTERPOLATED(NtPath(..)) => true,
-      _ => false
-    }
-}
-
-/// Returns the matching close delimiter if this is an open delimiter,
-/// otherwise `None`.
-pub fn close_delimiter_for(t: &Token) -> Option<Token> {
-    match *t {
-        LPAREN   => Some(RPAREN),
-        LBRACE   => Some(RBRACE),
-        LBRACKET => Some(RBRACKET),
-        _        => None
-    }
-}
-
-pub fn is_lit(t: &Token) -> bool {
-    match *t {
-      LIT_BYTE(_) => true,
-      LIT_CHAR(_) => true,
-      LIT_INTEGER(_) => true,
-      LIT_FLOAT(_) => true,
-      LIT_STR(_) => true,
-      LIT_STR_RAW(_, _) => true,
-      LIT_BINARY(_) => true,
-      LIT_BINARY_RAW(_, _) => true,
-      _ => false
-    }
-}
-
-pub fn is_ident(t: &Token) -> bool {
-    match *t { IDENT(_, _) => true, _ => false }
-}
-
-pub fn is_ident_or_path(t: &Token) -> bool {
-    match *t {
-      IDENT(_, _) | INTERPOLATED(NtPath(..)) => true,
-      _ => false
-    }
-}
-
-pub fn is_plain_ident(t: &Token) -> bool {
-    match *t { IDENT(_, false) => true, _ => false }
-}
-
 // Get the first "argument"
 macro_rules! first {
     ( $first:expr, $( $remainder:expr, )* ) => ( $first )
@@ -376,22 +461,28 @@ pub mod keywords {
         $( ($rk_name:expr, $rk_variant:ident, $rk_str:expr); )*
     }
 ) => {
-    static STRICT_KEYWORD_START: Name = first!($( Name($sk_name), )*);
-    static STRICT_KEYWORD_FINAL: Name = last!($( Name($sk_name), )*);
-    static RESERVED_KEYWORD_START: Name = first!($( Name($rk_name), )*);
-    static RESERVED_KEYWORD_FINAL: Name = last!($( Name($rk_name), )*);
+    static STRICT_KEYWORD_START: ast::Name = first!($( ast::Name($sk_name), )*);
+    static STRICT_KEYWORD_FINAL: ast::Name = last!($( ast::Name($sk_name), )*);
+    static RESERVED_KEYWORD_START: ast::Name = first!($( ast::Name($rk_name), )*);
+    static RESERVED_KEYWORD_FINAL: ast::Name = last!($( ast::Name($rk_name), )*);
 
     pub mod special_idents {
-        use ast::{Ident, Name};
+        use ast;
         $(
             #[allow(non_uppercase_statics)]
-            pub const $si_static: Ident = Ident { name: Name($si_name), ctxt: 0 };
+            pub const $si_static: ast::Ident = ast::Ident {
+                name: ast::Name($si_name),
+                ctxt: 0,
+            };
          )*
     }
 
     pub mod special_names {
-        use ast::Name;
-        $( #[allow(non_uppercase_statics)] pub const $si_static: Name =  Name($si_name); )*
+        use ast;
+        $(
+            #[allow(non_uppercase_statics)]
+            pub const $si_static: ast::Name =  ast::Name($si_name);
+        )*
     }
 
     /**
@@ -402,7 +493,7 @@ pub mod special_names {
      * the language and may not appear as identifiers.
      */
     pub mod keywords {
-        use ast::Name;
+        use ast;
 
         pub enum Keyword {
             $( $sk_variant, )*
@@ -410,10 +501,10 @@ pub enum Keyword {
         }
 
         impl Keyword {
-            pub fn to_name(&self) -> Name {
+            pub fn to_name(&self) -> ast::Name {
                 match *self {
-                    $( $sk_variant => Name($sk_name), )*
-                    $( $rk_variant => Name($rk_name), )*
+                    $( $sk_variant => ast::Name($sk_name), )*
+                    $( $rk_variant => ast::Name($rk_name), )*
                 }
             }
         }
@@ -432,9 +523,9 @@ fn mk_fresh_ident_interner() -> IdentInterner {
 }}
 
 // If the special idents get renumbered, remember to modify these two as appropriate
-pub const SELF_KEYWORD_NAME: Name = Name(SELF_KEYWORD_NAME_NUM);
-const STATIC_KEYWORD_NAME: Name = Name(STATIC_KEYWORD_NAME_NUM);
-const SUPER_KEYWORD_NAME: Name = Name(SUPER_KEYWORD_NAME_NUM);
+pub const SELF_KEYWORD_NAME: ast::Name = ast::Name(SELF_KEYWORD_NAME_NUM);
+const STATIC_KEYWORD_NAME: ast::Name = ast::Name(STATIC_KEYWORD_NAME_NUM);
+const SUPER_KEYWORD_NAME: ast::Name = ast::Name(SUPER_KEYWORD_NAME_NUM);
 
 pub const SELF_KEYWORD_NAME_NUM: u32 = 1;
 const STATIC_KEYWORD_NAME_NUM: u32 = 2;
@@ -526,34 +617,6 @@ pub mod keywords {
     }
 }
 
-/**
- * Maps a token to a record specifying the corresponding binary
- * operator
- */
-pub fn token_to_binop(tok: &Token) -> Option<ast::BinOp> {
-  match *tok {
-      BINOP(STAR)    => Some(ast::BiMul),
-      BINOP(SLASH)   => Some(ast::BiDiv),
-      BINOP(PERCENT) => Some(ast::BiRem),
-      BINOP(PLUS)    => Some(ast::BiAdd),
-      BINOP(MINUS)   => Some(ast::BiSub),
-      BINOP(SHL)     => Some(ast::BiShl),
-      BINOP(SHR)     => Some(ast::BiShr),
-      BINOP(AND)     => Some(ast::BiBitAnd),
-      BINOP(CARET)   => Some(ast::BiBitXor),
-      BINOP(OR)      => Some(ast::BiBitOr),
-      LT             => Some(ast::BiLt),
-      LE             => Some(ast::BiLe),
-      GE             => Some(ast::BiGe),
-      GT             => Some(ast::BiGt),
-      EQEQ           => Some(ast::BiEq),
-      NE             => Some(ast::BiNe),
-      ANDAND         => Some(ast::BiAnd),
-      OROR           => Some(ast::BiOr),
-      _              => None
-  }
-}
-
 // looks like we can get rid of this completely...
 pub type IdentInterner = StrInterner;
 
@@ -646,7 +709,7 @@ fn encode(&self, s: &mut S) -> Result<(), E> {
 
 /// Returns the string contents of a name, using the task-local interner.
 #[inline]
-pub fn get_name(name: Name) -> InternedString {
+pub fn get_name(name: ast::Name) -> InternedString {
     let interner = get_ident_interner();
     InternedString::new_from_rc_str(interner.get(name))
 }
@@ -654,7 +717,7 @@ pub fn get_name(name: Name) -> InternedString {
 /// Returns the string contents of an identifier, using the task-local
 /// interner.
 #[inline]
-pub fn get_ident(ident: Ident) -> InternedString {
+pub fn get_ident(ident: ast::Ident) -> InternedString {
     get_name(ident.name)
 }
 
@@ -667,32 +730,32 @@ pub fn intern_and_get_ident(s: &str) -> InternedString {
 
 /// Maps a string to its interned representation.
 #[inline]
-pub fn intern(s: &str) -> Name {
+pub fn intern(s: &str) -> ast::Name {
     get_ident_interner().intern(s)
 }
 
 /// gensym's a new uint, using the current interner.
 #[inline]
-pub fn gensym(s: &str) -> Name {
+pub fn gensym(s: &str) -> ast::Name {
     get_ident_interner().gensym(s)
 }
 
 /// Maps a string to an identifier with an empty syntax context.
 #[inline]
-pub fn str_to_ident(s: &str) -> Ident {
-    Ident::new(intern(s))
+pub fn str_to_ident(s: &str) -> ast::Ident {
+    ast::Ident::new(intern(s))
 }
 
 /// Maps a string to a gensym'ed identifier.
 #[inline]
-pub fn gensym_ident(s: &str) -> Ident {
-    Ident::new(gensym(s))
+pub fn gensym_ident(s: &str) -> ast::Ident {
+    ast::Ident::new(gensym(s))
 }
 
 // create a fresh name that maps to the same string as the old one.
 // note that this guarantees that str_ptr_eq(ident_to_string(src),interner_get(fresh_name(src)));
 // that is, that the new name and the old one are connected to ptr_eq strings.
-pub fn fresh_name(src: &Ident) -> Name {
+pub fn fresh_name(src: &ast::Ident) -> ast::Name {
     let interner = get_ident_interner();
     interner.gensym_copy(src.name)
     // following: debug version. Could work in final except that it's incompatible with
@@ -703,78 +766,10 @@ pub fn fresh_name(src: &Ident) -> Name {
 }
 
 // create a fresh mark.
-pub fn fresh_mark() -> Mrk {
+pub fn fresh_mark() -> ast::Mrk {
     gensym("mark").uint() as u32
 }
 
-// See the macro above about the types of keywords
-
-pub fn is_keyword(kw: keywords::Keyword, tok: &Token) -> bool {
-    match *tok {
-        token::IDENT(sid, false) => { kw.to_name() == sid.name }
-        _ => { false }
-    }
-}
-
-pub fn is_any_keyword(tok: &Token) -> bool {
-    match *tok {
-        token::IDENT(sid, false) => {
-            let n = sid.name;
-
-               n == SELF_KEYWORD_NAME
-            || n == STATIC_KEYWORD_NAME
-            || n == SUPER_KEYWORD_NAME
-            || STRICT_KEYWORD_START <= n
-            && n <= RESERVED_KEYWORD_FINAL
-        },
-        _ => false
-    }
-}
-
-pub fn is_strict_keyword(tok: &Token) -> bool {
-    match *tok {
-        token::IDENT(sid, false) => {
-            let n = sid.name;
-
-               n == SELF_KEYWORD_NAME
-            || n == STATIC_KEYWORD_NAME
-            || n == SUPER_KEYWORD_NAME
-            || STRICT_KEYWORD_START <= n
-            && n <= STRICT_KEYWORD_FINAL
-        },
-        token::IDENT(sid, true) => {
-            let n = sid.name;
-
-               n != SELF_KEYWORD_NAME
-            && n != SUPER_KEYWORD_NAME
-            && STRICT_KEYWORD_START <= n
-            && n <= STRICT_KEYWORD_FINAL
-        }
-        _ => false,
-    }
-}
-
-pub fn is_reserved_keyword(tok: &Token) -> bool {
-    match *tok {
-        token::IDENT(sid, false) => {
-            let n = sid.name;
-
-               RESERVED_KEYWORD_START <= n
-            && n <= RESERVED_KEYWORD_FINAL
-        },
-        _ => false,
-    }
-}
-
-pub fn mtwt_token_eq(t1 : &Token, t2 : &Token) -> bool {
-    match (t1,t2) {
-        (&IDENT(id1,_),&IDENT(id2,_)) | (&LIFETIME(id1),&LIFETIME(id2)) =>
-            mtwt::resolve(id1) == mtwt::resolve(id2),
-        _ => *t1 == *t2
-    }
-}
-
-
 #[cfg(test)]
 mod test {
     use super::*;
@@ -786,9 +781,9 @@ fn mark_ident(id : ast::Ident, m : ast::Mrk) -> ast::Ident {
     }
 
     #[test] fn mtwt_token_eq_test() {
-        assert!(mtwt_token_eq(&GT,&GT));
+        assert!(Gt.mtwt_eq(&Gt));
         let a = str_to_ident("bac");
         let a1 = mark_ident(a,92);
-        assert!(mtwt_token_eq(&IDENT(a,true),&IDENT(a1,false)));
+        assert!(Ident(a, ModName).mtwt_eq(&Ident(a1, Plain)));
     }
 }
index 65efd4f00425b744f43ea8dc47226ee545aee653..57c72ca77c616072695867235d9981986c7fa63f 100644 (file)
@@ -600,7 +600,7 @@ pub fn print(&mut self, x: Token, l: int) -> io::IoResult<()> {
           }
           Eof => {
             // Eof should never get here.
-            fail!();
+            panic!();
           }
         }
     }
index b63f9b0120b9ee2e65614a9a36a9a0decfd9df1c..d347d0199a724797a79615cf7b520b8d8edb0889 100644 (file)
@@ -21,6 +21,7 @@
 use codemap::{CodeMap, BytePos};
 use codemap;
 use diagnostic;
+use parse::token::{BinOpToken, Token};
 use parse::token;
 use parse::lexer::comments;
 use parse;
@@ -181,6 +182,101 @@ pub fn to_string(f: |&mut State| -> IoResult<()>) -> String {
     }
 }
 
+pub fn binop_to_string(op: BinOpToken) -> &'static str {
+    match op {
+        token::Plus     => "+",
+        token::Minus    => "-",
+        token::Star     => "*",
+        token::Slash    => "/",
+        token::Percent  => "%",
+        token::Caret    => "^",
+        token::And      => "&",
+        token::Or       => "|",
+        token::Shl      => "<<",
+        token::Shr      => ">>",
+    }
+}
+
+pub fn token_to_string(tok: &Token) -> String {
+    match *tok {
+        token::Eq                   => "=".into_string(),
+        token::Lt                   => "<".into_string(),
+        token::Le                   => "<=".into_string(),
+        token::EqEq                 => "==".into_string(),
+        token::Ne                   => "!=".into_string(),
+        token::Ge                   => ">=".into_string(),
+        token::Gt                   => ">".into_string(),
+        token::Not                  => "!".into_string(),
+        token::Tilde                => "~".into_string(),
+        token::OrOr                 => "||".into_string(),
+        token::AndAnd               => "&&".into_string(),
+        token::BinOp(op)            => binop_to_string(op).into_string(),
+        token::BinOpEq(op)          => format!("{}=", binop_to_string(op)),
+
+        /* Structural symbols */
+        token::At                   => "@".into_string(),
+        token::Dot                  => ".".into_string(),
+        token::DotDot               => "..".into_string(),
+        token::DotDotDot            => "...".into_string(),
+        token::Comma                => ",".into_string(),
+        token::Semi                 => ";".into_string(),
+        token::Colon                => ":".into_string(),
+        token::ModSep               => "::".into_string(),
+        token::RArrow               => "->".into_string(),
+        token::LArrow               => "<-".into_string(),
+        token::FatArrow             => "=>".into_string(),
+        token::LParen               => "(".into_string(),
+        token::RParen               => ")".into_string(),
+        token::LBracket             => "[".into_string(),
+        token::RBracket             => "]".into_string(),
+        token::LBrace               => "{".into_string(),
+        token::RBrace               => "}".into_string(),
+        token::Pound                => "#".into_string(),
+        token::Dollar               => "$".into_string(),
+        token::Question             => "?".into_string(),
+
+        /* Literals */
+        token::LitByte(b)           => format!("b'{}'", b.as_str()),
+        token::LitChar(c)           => format!("'{}'", c.as_str()),
+        token::LitFloat(c)          => c.as_str().into_string(),
+        token::LitInteger(c)        => c.as_str().into_string(),
+        token::LitStr(s)            => format!("\"{}\"", s.as_str()),
+        token::LitStrRaw(s, n)      => format!("r{delim}\"{string}\"{delim}",
+                                               delim="#".repeat(n),
+                                               string=s.as_str()),
+        token::LitBinary(v)         => format!("b\"{}\"", v.as_str()),
+        token::LitBinaryRaw(s, n)   => format!("br{delim}\"{string}\"{delim}",
+                                               delim="#".repeat(n),
+                                               string=s.as_str()),
+
+        /* Name components */
+        token::Ident(s, _)          => token::get_ident(s).get().into_string(),
+        token::Lifetime(s)          => format!("{}", token::get_ident(s)),
+        token::Underscore           => "_".into_string(),
+
+        /* Other */
+        token::DocComment(s)        => s.as_str().into_string(),
+        token::Eof                  => "<eof>".into_string(),
+        token::Whitespace           => " ".into_string(),
+        token::Comment              => "/* */".into_string(),
+        token::Shebang(s)           => format!("/* shebang: {}*/", s.as_str()),
+
+        token::Interpolated(ref nt) => match *nt {
+            token::NtExpr(ref e)  => expr_to_string(&**e),
+            token::NtMeta(ref e)  => meta_item_to_string(&**e),
+            token::NtTy(ref e)    => ty_to_string(&**e),
+            token::NtPath(ref e)  => path_to_string(&**e),
+            token::NtItem(..)     => "an interpolated item".into_string(),
+            token::NtBlock(..)    => "an interpolated block".into_string(),
+            token::NtStmt(..)     => "an interpolated statement".into_string(),
+            token::NtPat(..)      => "an interpolated pattern".into_string(),
+            token::NtIdent(..)    => "an interpolated identifier".into_string(),
+            token::NtTT(..)       => "an interpolated tt".into_string(),
+            token::NtMatchers(..) => "an interpolated matcher sequence".into_string(),
+        }
+    }
+}
+
 // FIXME (Issue #16472): the thing_to_string_impls macro should go away
 // after we revise the syntax::ext::quote::ToToken impls to go directly
 // to token-trees instead of thing -> string -> token-trees.
@@ -224,6 +320,10 @@ pub fn item_to_string(i: &ast::Item) -> String {
     $to_string(|s| s.print_item(i))
 }
 
+pub fn view_item_to_string(i: &ast::ViewItem) -> String {
+    $to_string(|s| s.print_view_item(i))
+}
+
 pub fn generics_to_string(generics: &ast::Generics) -> String {
     $to_string(|s| s.print_generics(generics))
 }
@@ -972,7 +1072,7 @@ pub fn print_struct(&mut self,
                     Inconsistent, struct_def.fields.as_slice(),
                     |s, field| {
                         match field.node.kind {
-                            ast::NamedField(..) => fail!("unexpected named field"),
+                            ast::NamedField(..) => panic!("unexpected named field"),
                             ast::UnnamedField(vis) => {
                                 try!(s.print_visibility(vis));
                                 try!(s.maybe_print_comment(field.span.lo));
@@ -993,7 +1093,7 @@ pub fn print_struct(&mut self,
 
             for field in struct_def.fields.iter() {
                 match field.node.kind {
-                    ast::UnnamedField(..) => fail!("unexpected unnamed field"),
+                    ast::UnnamedField(..) => panic!("unexpected unnamed field"),
                     ast::NamedField(ident, visibility) => {
                         try!(self.hardbreak_if_not_bol());
                         try!(self.maybe_print_comment(field.span.lo));
@@ -1020,32 +1120,41 @@ pub fn print_struct(&mut self,
     /// expression arguments as expressions). It can be done! I think.
     pub fn print_tt(&mut self, tt: &ast::TokenTree) -> IoResult<()> {
         match *tt {
-            ast::TTDelim(ref tts) => self.print_tts(tts.as_slice()),
-            ast::TTTok(_, ref tk) => {
-                try!(word(&mut self.s, parse::token::to_string(tk).as_slice()));
+            ast::TtDelimited(_, ref delimed) => {
+                let (ref open, ref tts, ref close) = **delimed;
+                try!(word(&mut self.s, token_to_string(&open.token).as_slice()));
+                try!(space(&mut self.s));
+                try!(self.print_tts(tts.as_slice()));
+                try!(space(&mut self.s));
+                word(&mut self.s, token_to_string(&close.token).as_slice())
+            },
+            ast::TtToken(_, ref tk) => {
+                try!(word(&mut self.s, token_to_string(tk).as_slice()));
                 match *tk {
-                    parse::token::DOC_COMMENT(..) => {
+                    parse::token::DocComment(..) => {
                         hardbreak(&mut self.s)
                     }
                     _ => Ok(())
                 }
             }
-            ast::TTSeq(_, ref tts, ref sep, zerok) => {
+            ast::TtSequence(_, ref tts, ref separator, kleene_op) => {
                 try!(word(&mut self.s, "$("));
                 for tt_elt in (*tts).iter() {
                     try!(self.print_tt(tt_elt));
                 }
                 try!(word(&mut self.s, ")"));
-                match *sep {
+                match *separator {
                     Some(ref tk) => {
-                        try!(word(&mut self.s,
-                                  parse::token::to_string(tk).as_slice()));
+                        try!(word(&mut self.s, token_to_string(tk).as_slice()));
                     }
-                    None => ()
+                    None => {},
+                }
+                match kleene_op {
+                    ast::ZeroOrMore => word(&mut self.s, "*"),
+                    ast::OneOrMore => word(&mut self.s, "+"),
                 }
-                word(&mut self.s, if zerok { "*" } else { "+" })
             }
-            ast::TTNonterminal(_, name) => {
+            ast::TtNonterminal(_, name) => {
                 try!(word(&mut self.s, "$"));
                 self.print_ident(name)
             }
@@ -1331,7 +1440,7 @@ fn print_else(&mut self, els: Option<&ast::Expr>) -> IoResult<()> {
                     }
                     // BLEAH, constraints would be great here
                     _ => {
-                        fail!("print_if saw if with weird alternative");
+                        panic!("print_if saw if with weird alternative");
                     }
                 }
             }
@@ -1983,8 +2092,10 @@ pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> {
                     Consistent, fields.as_slice(),
                     |s, f| {
                         try!(s.cbox(indent_unit));
-                        try!(s.print_ident(f.node.ident));
-                        try!(s.word_nbsp(":"));
+                        if !f.node.is_shorthand {
+                            try!(s.print_ident(f.node.ident));
+                            try!(s.word_nbsp(":"));
+                        }
                         try!(s.print_pat(&*f.node.pat));
                         s.end()
                     },
index 60ba5f6615b92e22dacdf67743b6748960d69f80..422c2d5c75bd7cefe836cd69ffd3d72cb20a2539 100644 (file)
@@ -99,7 +99,7 @@ pub fn get<'a>(&'a self, idx: uint) -> &'a T {
         match self.repr {
             One(ref v) if idx == 0 => v,
             Many(ref vs) => &vs[idx],
-            _ => fail!("out of bounds access")
+            _ => panic!("out of bounds access")
         }
     }
 
@@ -110,10 +110,10 @@ pub fn expect_one(self, err: &'static str) -> T {
                 if v.len() == 1 {
                     v.into_iter().next().unwrap()
                 } else {
-                    fail!(err)
+                    panic!(err)
                 }
             }
-            _ => fail!(err)
+            _ => panic!(err)
         }
     }
 
index f2d56f53d22caef7098f0ca490d870222d075586..bec72e88f99b98560010a38a53a8c5421d562c62 100644 (file)
@@ -103,7 +103,7 @@ fn visit_explicit_self(&mut self, es: &'v ExplicitSelf) {
         walk_explicit_self(self, es)
     }
     fn visit_mac(&mut self, _macro: &'v Mac) {
-        fail!("visit_mac disabled by default");
+        panic!("visit_mac disabled by default");
         // NB: see note about macros above.
         // if you really want a visitor that
         // works on macros, use this
index fbf17b76d6201397a5bb0b3315b9c83fdb4d77ef..2e93f6badf2c96ec9995e0db3bebe17e2dc3fd71 100644 (file)
@@ -89,30 +89,25 @@ fn flush(&mut self) -> IoResult<()> {
 /// Return a Terminal wrapping stdout, or None if a terminal couldn't be
 /// opened.
 pub fn stdout() -> Option<Box<Terminal<WriterWrapper> + Send>> {
-    let ti: Option<TerminfoTerminal<WriterWrapper>>
-        = Terminal::new(WriterWrapper {
-            wrapped: box std::io::stdout() as Box<Writer + Send>,
-        });
-    ti.map(|t| box t as Box<Terminal<WriterWrapper> + Send>)
+    TerminfoTerminal::new(WriterWrapper {
+        wrapped: box std::io::stdout() as Box<Writer + Send>,
+    })
 }
 
 #[cfg(windows)]
 /// Return a Terminal wrapping stdout, or None if a terminal couldn't be
 /// opened.
 pub fn stdout() -> Option<Box<Terminal<WriterWrapper> + Send>> {
-    let ti: Option<TerminfoTerminal<WriterWrapper>>
-        = Terminal::new(WriterWrapper {
-            wrapped: box std::io::stdout() as Box<Writer + Send>,
-        });
+    let ti = TerminfoTerminal::new(WriterWrapper {
+        wrapped: box std::io::stdout() as Box<Writer + Send>,
+    });
 
     match ti {
-        Some(t) => Some(box t as Box<Terminal<WriterWrapper> + Send>),
+        Some(t) => Some(t),
         None => {
-            let wc: Option<WinConsole<WriterWrapper>>
-                = Terminal::new(WriterWrapper {
-                    wrapped: box std::io::stdout() as Box<Writer + Send>,
-                });
-            wc.map(|w| box w as Box<Terminal<WriterWrapper> + Send>)
+            WinConsole::new(WriterWrapper {
+                wrapped: box std::io::stdout() as Box<Writer + Send>,
+            })
         }
     }
 }
@@ -121,30 +116,25 @@ pub fn stdout() -> Option<Box<Terminal<WriterWrapper> + Send>> {
 /// Return a Terminal wrapping stderr, or None if a terminal couldn't be
 /// opened.
 pub fn stderr() -> Option<Box<Terminal<WriterWrapper> + Send> + Send> {
-    let ti: Option<TerminfoTerminal<WriterWrapper>>
-        = Terminal::new(WriterWrapper {
-            wrapped: box std::io::stderr() as Box<Writer + Send>,
-        });
-    ti.map(|t| box t as Box<Terminal<WriterWrapper> + Send>)
+    TerminfoTerminal::new(WriterWrapper {
+        wrapped: box std::io::stderr() as Box<Writer + Send>,
+    })
 }
 
 #[cfg(windows)]
 /// Return a Terminal wrapping stderr, or None if a terminal couldn't be
 /// opened.
 pub fn stderr() -> Option<Box<Terminal<WriterWrapper> + Send> + Send> {
-    let ti: Option<TerminfoTerminal<WriterWrapper>>
-        = Terminal::new(WriterWrapper {
-            wrapped: box std::io::stderr() as Box<Writer + Send>,
-        });
+    let ti = TerminfoTerminal::new(WriterWrapper {
+        wrapped: box std::io::stderr() as Box<Writer + Send>,
+    });
 
     match ti {
-        Some(t) => Some(box t as Box<Terminal<WriterWrapper> + Send>),
+        Some(t) => Some(t),
         None => {
-            let wc: Option<WinConsole<WriterWrapper>>
-                = Terminal::new(WriterWrapper {
-                    wrapped: box std::io::stderr() as Box<Writer + Send>,
-                });
-            wc.map(|w| box w as Box<Terminal<WriterWrapper> + Send>)
+            WinConsole::new(WriterWrapper {
+                wrapped: box std::io::stderr() as Box<Writer + Send>,
+            })
         }
     }
 }
@@ -208,10 +198,6 @@ pub enum Attr {
 /// A terminal with similar capabilities to an ANSI Terminal
 /// (foreground/background colors etc).
 pub trait Terminal<T: Writer>: Writer {
-    /// Returns `None` whenever the terminal cannot be created for some
-    /// reason.
-    fn new(out: T) -> Option<Self>;
-
     /// Sets the foreground color to the given color.
     ///
     /// If the color is a bright color, but the terminal only supports 8 colors,
@@ -242,12 +228,15 @@ pub trait Terminal<T: Writer>: Writer {
     /// Returns `Ok()`.
     fn reset(&mut self) -> IoResult<()>;
 
-    /// Returns the contained stream, destroying the `Terminal`
-    fn unwrap(self) -> T;
-
     /// Gets an immutable reference to the stream inside
     fn get_ref<'a>(&'a self) -> &'a T;
 
     /// Gets a mutable reference to the stream inside
     fn get_mut<'a>(&'a mut self) -> &'a mut T;
 }
+
+/// A terminal which can be unwrapped.
+pub trait UnwrappableTerminal<T: Writer>: Terminal<T> {
+    /// Returns the contained stream, destroying the `Terminal`
+    fn unwrap(self) -> T;
+}
index 36883c8fcf4f244a0a9bff76d7d8aef991a7a1c5..73edcf948921687719cbf081923266081bb1553b 100644 (file)
@@ -17,6 +17,7 @@
 use attr;
 use color;
 use Terminal;
+use UnwrappableTerminal;
 use self::searcher::open;
 use self::parser::compiled::{parse, msys_terminfo};
 use self::parm::{expand, Number, Variables};
@@ -71,44 +72,7 @@ pub struct TerminfoTerminal<T> {
     ti: Box<TermInfo>
 }
 
-impl<T: Writer> Terminal<T> for TerminfoTerminal<T> {
-    fn new(out: T) -> Option<TerminfoTerminal<T>> {
-        let term = match os::getenv("TERM") {
-            Some(t) => t,
-            None => {
-                debug!("TERM environment variable not defined");
-                return None;
-            }
-        };
-
-        let entry = open(term.as_slice());
-        if entry.is_err() {
-            if os::getenv("MSYSCON").map_or(false, |s| {
-                    "mintty.exe" == s.as_slice()
-                }) {
-                // msys terminal
-                return Some(TerminfoTerminal {out: out, ti: msys_terminfo(), num_colors: 8});
-            }
-            debug!("error finding terminfo entry: {}", entry.err().unwrap());
-            return None;
-        }
-
-        let mut file = entry.unwrap();
-        let ti = parse(&mut file, false);
-        if ti.is_err() {
-            debug!("error parsing terminfo entry: {}", ti.unwrap_err());
-            return None;
-        }
-
-        let inf = ti.unwrap();
-        let nc = if inf.strings.find_equiv(&("setaf")).is_some()
-                 && inf.strings.find_equiv(&("setab")).is_some() {
-                     inf.numbers.find_equiv(&("colors")).map_or(0, |&n| n)
-                 } else { 0 };
-
-        return Some(TerminfoTerminal {out: out, ti: inf, num_colors: nc});
-    }
-
+impl<T: Writer+Send> Terminal<T> for TerminfoTerminal<T> {
     fn fg(&mut self, color: color::Color) -> IoResult<bool> {
         let color = self.dim_if_necessary(color);
         if self.num_colors > color {
@@ -195,14 +159,59 @@ fn reset(&mut self) -> IoResult<()> {
         Ok(())
     }
 
-    fn unwrap(self) -> T { self.out }
-
     fn get_ref<'a>(&'a self) -> &'a T { &self.out }
 
     fn get_mut<'a>(&'a mut self) -> &'a mut T { &mut self.out }
 }
 
-impl<T: Writer> TerminfoTerminal<T> {
+impl<T: Writer+Send> UnwrappableTerminal<T> for TerminfoTerminal<T> {
+    fn unwrap(self) -> T { self.out }
+}
+
+impl<T: Writer+Send> TerminfoTerminal<T> {
+    /// Returns `None` whenever the terminal cannot be created for some
+    /// reason.
+    pub fn new(out: T) -> Option<Box<Terminal<T>+Send+'static>> {
+        let term = match os::getenv("TERM") {
+            Some(t) => t,
+            None => {
+                debug!("TERM environment variable not defined");
+                return None;
+            }
+        };
+
+        let entry = open(term.as_slice());
+        if entry.is_err() {
+            if os::getenv("MSYSCON").map_or(false, |s| {
+                    "mintty.exe" == s.as_slice()
+                }) {
+                // msys terminal
+                return Some(box TerminfoTerminal {out: out,
+                                                  ti: msys_terminfo(),
+                                                  num_colors: 8} as Box<Terminal<T>+Send>);
+            }
+            debug!("error finding terminfo entry: {}", entry.err().unwrap());
+            return None;
+        }
+
+        let mut file = entry.unwrap();
+        let ti = parse(&mut file, false);
+        if ti.is_err() {
+            debug!("error parsing terminfo entry: {}", ti.unwrap_err());
+            return None;
+        }
+
+        let inf = ti.unwrap();
+        let nc = if inf.strings.find_equiv(&("setaf")).is_some()
+                 && inf.strings.find_equiv(&("setab")).is_some() {
+                     inf.numbers.find_equiv(&("colors")).map_or(0, |&n| n)
+                 } else { 0 };
+
+        return Some(box TerminfoTerminal {out: out,
+                                          ti: inf,
+                                          num_colors: nc} as Box<Terminal<T>+Send>);
+    }
+
     fn dim_if_necessary(&self, color: color::Color) -> color::Color {
         if color >= self.num_colors && color >= 8 && color < 16 {
             color-8
index 586f420dc3e002fff1848b424a504bd073d04348..a3482dc85c63bcdb5a3351d9589393851a859d44 100644 (file)
@@ -474,7 +474,7 @@ fn from_char(c: char) -> FormatOp {
             'x' => FormatHex,
             'X' => FormatHEX,
             's' => FormatString,
-            _ => fail!("bad FormatOp char")
+            _ => panic!("bad FormatOp char")
         }
     }
     fn to_char(self) -> char {
index 0aae85503d07ddaf5647950e410a1762c029f871..7ce6fb658b56d36a5998da51f3507a844b3c8d60 100644 (file)
@@ -18,7 +18,7 @@
 
 use attr;
 use color;
-use Terminal;
+use {Terminal,UnwrappableTerminal};
 
 /// A Terminal implementation which uses the Win32 Console API.
 pub struct WinConsole<T> {
@@ -71,7 +71,8 @@ fn color_to_bits(color: color::Color) -> u16 {
 }
 
 fn bits_to_color(bits: u16) -> color::Color {
-    let color = match bits & 0x7 {
+    let bits = bits & 0x7;
+    let color = match bits {
         0 => color::BLACK,
         0x1 => color::BLUE,
         0x2 => color::GREEN,
@@ -90,7 +91,7 @@ fn bits_to_color(bits: u16) -> color::Color {
     }
 }
 
-impl<T: Writer> WinConsole<T> {
+impl<T: Writer+Send> WinConsole<T> {
     fn apply(&mut self) {
         let _unused = self.buf.flush();
         let mut accum: libc::WORD = 0;
@@ -111,20 +112,10 @@ fn apply(&mut self) {
             SetConsoleTextAttribute(out, accum);
         }
     }
-}
-
-impl<T: Writer> Writer for WinConsole<T> {
-    fn write(&mut self, buf: &[u8]) -> IoResult<()> {
-        self.buf.write(buf)
-    }
-
-    fn flush(&mut self) -> IoResult<()> {
-        self.buf.flush()
-    }
-}
 
-impl<T: Writer> Terminal<T> for WinConsole<T> {
-    fn new(out: T) -> Option<WinConsole<T>> {
+    /// Returns `None` whenever the terminal cannot be created for some
+    /// reason.
+    pub fn new(out: T) -> Option<Box<Terminal<T>+Send+'static>> {
         let fg;
         let bg;
         unsafe {
@@ -137,11 +128,23 @@ fn new(out: T) -> Option<WinConsole<T>> {
                 bg = color::BLACK;
             }
         }
-        Some(WinConsole { buf: out,
-                          def_foreground: fg, def_background: bg,
-                          foreground: fg, background: bg } )
+        Some(box WinConsole { buf: out,
+                              def_foreground: fg, def_background: bg,
+                              foreground: fg, background: bg } as Box<Terminal<T>+Send>)
     }
+}
 
+impl<T: Writer> Writer for WinConsole<T> {
+    fn write(&mut self, buf: &[u8]) -> IoResult<()> {
+        self.buf.write(buf)
+    }
+
+    fn flush(&mut self) -> IoResult<()> {
+        self.buf.flush()
+    }
+}
+
+impl<T: Writer+Send> Terminal<T> for WinConsole<T> {
     fn fg(&mut self, color: color::Color) -> IoResult<bool> {
         self.foreground = color;
         self.apply();
@@ -189,9 +192,11 @@ fn reset(&mut self) -> IoResult<()> {
         Ok(())
     }
 
-    fn unwrap(self) -> T { self.buf }
-
     fn get_ref<'a>(&'a self) -> &'a T { &self.buf }
 
     fn get_mut<'a>(&'a mut self) -> &'a mut T { &mut self.buf }
 }
+
+impl<T: Writer+Send> UnwrappableTerminal<T> for WinConsole<T> {
+    fn unwrap(self) -> T { self.buf }
+}
index 307c4b27886a400d5e580a293f6f718ef5b3f695..81d0bb76d1497babe4c89f8ea0e58bd28425529d 100644 (file)
@@ -130,7 +130,7 @@ pub trait TDynBenchFn {
 }
 
 // A function that runs a test. If the function returns successfully,
-// the test succeeds; if the function fails then the test fails. We
+// the test succeeds; if the function panics then the test fails. We
 // may need to come up with a more clever definition of test in order
 // to support isolation of tests into tasks.
 pub enum TestFn {
@@ -235,18 +235,18 @@ pub fn test_main(args: &[String], tests: Vec<TestDescAndFn> ) {
     let opts =
         match parse_opts(args) {
             Some(Ok(o)) => o,
-            Some(Err(msg)) => fail!("{}", msg),
+            Some(Err(msg)) => panic!("{}", msg),
             None => return
         };
     match run_tests_console(&opts, tests) {
         Ok(true) => {}
-        Ok(false) => fail!("Some tests failed"),
-        Err(e) => fail!("io error when running tests: {}", e),
+        Ok(false) => panic!("Some tests failed"),
+        Err(e) => panic!("io error when running tests: {}", e),
     }
 }
 
 // A variant optimized for invocation with a static test vector.
-// This will fail (intentionally) when fed any dynamic tests, because
+// This will panic (intentionally) when fed any dynamic tests, because
 // it is copying the static values out into a dynamic vector and cannot
 // copy dynamic values. It is doing this because from this point on
 // a ~[TestDescAndFn] is used in order to effect ownership-transfer
@@ -257,7 +257,7 @@ pub fn test_main_static(args: &[String], tests: &[TestDescAndFn]) {
         match t.testfn {
             StaticTestFn(f) => TestDescAndFn { testfn: StaticTestFn(f), desc: t.desc.clone() },
             StaticBenchFn(f) => TestDescAndFn { testfn: StaticBenchFn(f), desc: t.desc.clone() },
-            _ => fail!("non-static tests passed to test::test_main_static")
+            _ => panic!("non-static tests passed to test::test_main_static")
         }
     }).collect();
     test_main(args, owned_tests)
@@ -352,7 +352,7 @@ fn usage(binary: &str) {
     #[bench]       - Indicates a function is a benchmark to be run. This
                      function takes one argument (test::Bencher).
     #[should_fail] - This function (also labeled with #[test]) will only pass if
-                     the code causes a failure (an assertion failure or fail!)
+                     the code causes a failure (an assertion failure or panic!)
     #[ignore]      - When applied to a function which is already attributed as a
                      test, then the test runner will ignore these tests during
                      normal test runs. Running with --ignored will run these
@@ -445,7 +445,7 @@ pub fn opt_shard(maybestr: Option<String>) -> Option<(uint,uint)> {
                    it.next()) {
                 (Some(a), Some(b), None) => {
                     if a <= 0 || a > b {
-                        fail!("tried to run shard {a}.{b}, but {a} is out of bounds \
+                        panic!("tried to run shard {a}.{b}, but {a} is out of bounds \
                               (should be between 1 and {b}", a=a, b=b)
                     }
                     Some((a, b))
@@ -964,7 +964,7 @@ fn get_concurrency() -> uint {
             let opt_n: Option<uint> = FromStr::from_str(s.as_slice());
             match opt_n {
                 Some(n) if n > 0 => n,
-                _ => fail!("RUST_TEST_TASKS is `{}`, should be a positive integer.", s)
+                _ => panic!("RUST_TEST_TASKS is `{}`, should be a positive integer.", s)
             }
         }
         None => {
@@ -1120,7 +1120,7 @@ pub fn new() -> MetricMap {
     ///
     /// # Failure
     ///
-    /// This function will fail if the path does not exist or the path does not
+    /// This function will panic if the path does not exist or the path does not
     /// contain a valid metric map.
     pub fn load(p: &Path) -> MetricMap {
         assert!(p.exists());
@@ -1129,7 +1129,7 @@ pub fn load(p: &Path) -> MetricMap {
         let mut decoder = json::Decoder::new(value);
         MetricMap(match Decodable::decode(&mut decoder) {
             Ok(t) => t,
-            Err(e) => fail!("failure decoding JSON: {}", e)
+            Err(e) => panic!("failure decoding JSON: {}", e)
         })
     }
 
@@ -1401,7 +1401,7 @@ mod tests {
 
     #[test]
     pub fn do_not_run_ignored_tests() {
-        fn f() { fail!(); }
+        fn f() { panic!(); }
         let desc = TestDescAndFn {
             desc: TestDesc {
                 name: StaticTestName("whatever"),
@@ -1435,7 +1435,7 @@ fn f() { }
 
     #[test]
     fn test_should_fail() {
-        fn f() { fail!(); }
+        fn f() { panic!(); }
         let desc = TestDescAndFn {
             desc: TestDesc {
                 name: StaticTestName("whatever"),
@@ -1472,7 +1472,7 @@ fn first_free_arg_should_be_a_filter() {
         let args = vec!("progname".to_string(), "some_regex_filter".to_string());
         let opts = match parse_opts(args.as_slice()) {
             Some(Ok(o)) => o,
-            _ => fail!("Malformed arg in first_free_arg_should_be_a_filter")
+            _ => panic!("Malformed arg in first_free_arg_should_be_a_filter")
         };
         assert!(opts.filter.expect("should've found filter").is_match("some_regex_filter"))
     }
@@ -1484,7 +1484,7 @@ fn parse_ignored_flag() {
                         "--ignored".to_string());
         let opts = match parse_opts(args.as_slice()) {
             Some(Ok(o)) => o,
-            _ => fail!("Malformed arg in parse_ignored_flag")
+            _ => panic!("Malformed arg in parse_ignored_flag")
         };
         assert!((opts.run_ignored));
     }
index ee06c3f6caa347d0844529cfd9f0f8a6114d0d8f..590d0bfdcabc42cd610254846f262046074cead8 100644 (file)
@@ -1305,7 +1305,7 @@ fn test_strptime() {
             == Err(InvalidTime));
 
         match strptime("Fri Feb 13 15:31:30.01234 2009", format) {
-          Err(e) => fail!(e),
+          Err(e) => panic!(e),
           Ok(ref tm) => {
             assert!(tm.tm_sec == 30_i32);
             assert!(tm.tm_min == 31_i32);
@@ -1324,7 +1324,7 @@ fn test_strptime() {
         fn test(s: &str, format: &str) -> bool {
             match strptime(s, format) {
               Ok(ref tm) => tm.strftime(format).unwrap() == s.to_string(),
-              Err(e) => fail!(e)
+              Err(e) => panic!(e)
             }
         }
 
index 88f9c2b4ce39db28e04856b7c65aec1bcf962570..e4148440252afae255ca54954bcd09dd1086d13a 100644 (file)
@@ -21,6 +21,7 @@
 use core::cmp;
 use core::collections::Collection;
 use core::iter::{Filter, AdditiveIterator, Iterator, DoubleEndedIterator};
+use core::kinds::Sized;
 use core::option::{Option, None, Some};
 use core::str::{CharSplits, StrSlice};
 use u_char;
@@ -32,7 +33,7 @@
     Filter<'a, &'a str, CharSplits<'a, extern "Rust" fn(char) -> bool>>;
 
 /// Methods for Unicode string slices
-pub trait UnicodeStrSlice<'a> {
+pub trait UnicodeStrSlice for Sized? {
     /// Returns an iterator over the
     /// [grapheme clusters](http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries)
     /// of the string.
@@ -52,7 +53,7 @@ pub trait UnicodeStrSlice<'a> {
     /// let b: &[_] = &["a", "\r\n", "b", "🇷🇺🇸🇹"];
     /// assert_eq!(gr2.as_slice(), b);
     /// ```
-    fn graphemes(&self, is_extended: bool) -> Graphemes<'a>;
+    fn graphemes<'a>(&'a self, is_extended: bool) -> Graphemes<'a>;
 
     /// Returns an iterator over the grapheme clusters of self and their byte offsets.
     /// See `graphemes()` method for more information.
@@ -64,7 +65,7 @@ pub trait UnicodeStrSlice<'a> {
     /// let b: &[_] = &[(0u, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")];
     /// assert_eq!(gr_inds.as_slice(), b);
     /// ```
-    fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices<'a>;
+    fn grapheme_indices<'a>(&'a self, is_extended: bool) -> GraphemeIndices<'a>;
 
     /// An iterator over the words of a string (subsequences separated
     /// by any sequence of whitespace). Sequences of whitespace are
@@ -77,7 +78,7 @@ pub trait UnicodeStrSlice<'a> {
     /// let v: Vec<&str> = some_words.words().collect();
     /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]);
     /// ```
-    fn words(&self) -> Words<'a>;
+    fn words<'a>(&'a self) -> Words<'a>;
 
     /// Returns true if the string contains only whitespace.
     ///
@@ -120,28 +121,28 @@ pub trait UnicodeStrSlice<'a> {
     fn width(&self, is_cjk: bool) -> uint;
 
     /// Returns a string with leading and trailing whitespace removed.
-    fn trim(&self) -> &'a str;
+    fn trim<'a>(&'a self) -> &'a str;
 
     /// Returns a string with leading whitespace removed.
-    fn trim_left(&self) -> &'a str;
+    fn trim_left<'a>(&'a self) -> &'a str;
 
     /// Returns a string with trailing whitespace removed.
-    fn trim_right(&self) -> &'a str;
+    fn trim_right<'a>(&'a self) -> &'a str;
 }
 
-impl<'a> UnicodeStrSlice<'a> for &'a str {
+impl UnicodeStrSlice for str {
     #[inline]
-    fn graphemes(&self, is_extended: bool) -> Graphemes<'a> {
-        Graphemes { string: *self, extended: is_extended, cat: None, catb: None }
+    fn graphemes(&self, is_extended: bool) -> Graphemes {
+        Graphemes { string: self, extended: is_extended, cat: None, catb: None }
     }
 
     #[inline]
-    fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices<'a> {
+    fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices {
         GraphemeIndices { start_offset: self.as_ptr() as uint, iter: self.graphemes(is_extended) }
     }
 
     #[inline]
-    fn words(&self) -> Words<'a> {
+    fn words(&self) -> Words {
         self.split(u_char::is_whitespace).filter(|s| !s.is_empty())
     }
 
@@ -157,17 +158,17 @@ fn width(&self, is_cjk: bool) -> uint {
     }
 
     #[inline]
-    fn trim(&self) -> &'a str {
+    fn trim(&self) -> &str {
         self.trim_left().trim_right()
     }
 
     #[inline]
-    fn trim_left(&self) -> &'a str {
+    fn trim_left(&self) -> &str {
         self.trim_left_chars(u_char::is_whitespace)
     }
 
     #[inline]
-    fn trim_right(&self) -> &'a str {
+    fn trim_right(&self) -> &str {
         self.trim_right_chars(u_char::is_whitespace)
     }
 }
index 4d88fd6a03164e8c2cb81880651b0771650e5c93..f6eea15d8cfcf1325106320aef9c723b1c66fc8e 100644 (file)
@@ -1,3 +1,12 @@
+S 2014-10-22 d44ea72
+  freebsd-x86_64 8bf5ee7c1ca8ab880800cf3a535e16bb7ffbf9e8
+  linux-i386 1fc8302b405406a3fc183b23c8397bef5a56c52a
+  linux-x86_64 3e04d8197a96b0c858e4e2763b3893df35ae2fb3
+  macos-i386 b9823771ae6237a3c1c19eb2e98a2372ce23439d
+  macos-x86_64 3cf9fc1cd252a80430d8673e35a1256674e122ae
+  winnt-i386 5a6d2ad82a31deffad5b6a17487a8cd5c21f7636
+  winnt-x86_64 7468b87eb5be238993ccd41ad74bbd88dd176d31
+
 S 2014-10-10 78a7676
   freebsd-x86_64 511061af382e2e837a6d615823e1a952e8281483
   linux-i386 0644637db852db8a6c603ded0531ccaa60291bd3
index bbaf7991fd3cc5510c99ed9e1a5f1bc7529c2537..44d001d45fda24656063404ee45a7692a693251c 100644 (file)
@@ -38,7 +38,7 @@ pub fn alist_get<A:Clone + 'static,
             return entry.value.clone();
         }
     }
-    fail!();
+    panic!();
 }
 
 #[inline]
diff --git a/src/test/auxiliary/check_static_recursion_foreign_helper.rs b/src/test/auxiliary/check_static_recursion_foreign_helper.rs
new file mode 100644 (file)
index 0000000..b5c2a4f
--- /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.
+
+// Helper definition for test/run-pass/check-static-recursion-foreign.rs.
+
+#[crate_id = "check_static_recursion_foreign_helper"]
+#[crate_type = "lib"]
+
+extern crate libc;
+
+#[no_mangle]
+pub static test_static: libc::c_int = 0;
index 16b743baa3d1323e901e236b7f7fb32916ebd3e0..bd8857ceef7ea4f55f14b0fa3bb6b9f06edad684 100644 (file)
@@ -10,5 +10,5 @@
 
 
 pub unsafe fn f(xs: Vec<int> ) {
-    xs.iter().map(|_x| { unsafe fn q() { fail!(); } }).collect::<Vec<()>>();
+    xs.iter().map(|_x| { unsafe fn q() { panic!(); } }).collect::<Vec<()>>();
 }
index 967f49924d4054f3a1698593b304b308f44f76a1..ea2461ccfa8efc280ce2a96e30c59ddca818fcaf 100644 (file)
@@ -14,8 +14,8 @@
 #[lang="sized"]
 pub trait Sized for Sized? {}
 
-#[lang="fail"]
-fn fail(_: &(&'static str, &'static str, uint)) -> ! { loop {} }
+#[lang="panic"]
+fn panic(_: &(&'static str, &'static str, uint)) -> ! { loop {} }
 
 #[lang = "stack_exhausted"]
 extern fn stack_exhausted() {}
index 6bc5b677a2730ac62c650641affe6ce3ba01403a..fad70a917980d66735b0e8ecbc2319208561745b 100644 (file)
@@ -12,6 +12,6 @@
 #[phase(plugin, link)] extern crate log;
 
 pub fn foo<T>() {
-    fn death() -> int { fail!() }
+    fn death() -> int { panic!() }
     debug!("{}", (||{ death() })());
 }
index 000e42b9703566de3eb358f77012dabbfd4f04ec..9c0716e2cc2a5e7e92786906e996817858d2d54b 100644 (file)
@@ -36,7 +36,7 @@ pub trait IntoMaybeOwned<'a> {
 }
 
 impl<'a> IntoMaybeOwned<'a> for Inv<'a> {
-    fn into_maybe_owned(self) -> MaybeOwned<'a> { fail!() }
-    fn into_inv(self) -> Inv<'a> { fail!() }
-    fn bigger_region<'b:'a>(self, b: Inv<'b>) { fail!() }
+    fn into_maybe_owned(self) -> MaybeOwned<'a> { panic!() }
+    fn into_inv(self) -> Inv<'a> { panic!() }
+    fn bigger_region<'b:'a>(self, b: Inv<'b>) { panic!() }
 }
index 43842fae70f802412bb5ed2261060ef7e8715ab5..519f32fc248bd325bc7805edb1e86357f8fa359b 100644 (file)
@@ -17,8 +17,8 @@
 extern crate rustc;
 
 use syntax::codemap::Span;
-use syntax::parse::token::{IDENT, get_ident};
-use syntax::ast::{TokenTree, TTTok};
+use syntax::parse::token;
+use syntax::ast::{TokenTree, TtToken};
 use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacExpr};
 use syntax::ext::build::AstBuilder;  // trait for expr_uint
 use rustc::plugin::Registry;
@@ -39,7 +39,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
         ("I",    1)];
 
     let text = match args {
-        [TTTok(_, IDENT(s, _))] => get_ident(s).to_string(),
+        [TtToken(_, token::Ident(s, _))] => token::get_ident(s).to_string(),
         _ => {
             cx.span_err(sp, "argument should be a single identifier");
             return DummyResult::any(sp);
index eef2fdbfea9d9114a1168b51e3b4bb6093d8f220..811d8f116923980eb5cabe6f0fc7a536b609bfa4 100644 (file)
@@ -36,6 +36,6 @@ fn readMaybe(s: String) -> Option<bool> {
 pub fn read<T:read>(s: String) -> T {
     match read::readMaybe(s) {
       Some(x) => x,
-      _ => fail!("read failed!")
+      _ => panic!("read panicked!")
     }
 }
index c998e362d7e34f96a3a93a3a16da8fd6d8e9e265..6a1f8588b60d74002f10cf696f5d4820c97c0a82 100644 (file)
@@ -28,7 +28,7 @@ fn drop(&mut self) {}
 
 pub fn foo() {
     let _a = A;
-    fail!("wut");
+    panic!("wut");
 }
 
 mod std {
index 404e2e31b05770560b83b9c657d3545f54a4cbaf..39057215b5e6909b1146caed37946b2c559140b9 100644 (file)
@@ -145,7 +145,7 @@ fn is_utf8_ascii() {
     for _ in range(0u, 20000) {
         v.push('b' as u8);
         if !str::is_utf8(v.as_slice()) {
-            fail!("is_utf8 failed");
+            panic!("is_utf8 panicked");
         }
     }
 }
@@ -156,7 +156,7 @@ fn is_utf8_multibyte() {
     for _ in range(0u, 5000) {
         v.push_all(s.as_bytes());
         if !str::is_utf8(v.as_slice()) {
-            fail!("is_utf8 failed");
+            panic!("is_utf8 panicked");
         }
     }
 }
index 4ed0de2a13883699f2ca6c684a7c0a53dd8f6c66..abcd9f90333438473b78e555b1eceae061d5250e 100644 (file)
@@ -90,7 +90,7 @@ fn show_digit(nn: uint) -> &'static str {
         7 => {" seven"}
         8 => {" eight"}
         9 => {" nine"}
-        _ => {fail!("expected digits from 0 to 9...")}
+        _ => {panic!("expected digits from 0 to 9...")}
     }
 }
 
index 1799504eb4782eb29f9728add818c8ec969b5823..d0e6aacdbb2ad0c30a026322913d760808b26087 100644 (file)
@@ -225,7 +225,7 @@ fn pack_symbol(c: u8) -> u8 {
         'C' => 1,
         'G' => 2,
         'T' => 3,
-        _ => fail!("{}", c as char),
+        _ => panic!("{}", c as char),
     }
 }
 
index 8e8378641853bbe30994bc9447028b595e0953e1..6e80c07a1a2aa583c08f76873ad07410308bc27c 100644 (file)
@@ -207,7 +207,7 @@ fn get_id(m: u64) -> u8 {
     for id in range(0u8, 10) {
         if m & (1 << (id + 50) as uint) != 0 {return id;}
     }
-    fail!("{:016x} does not have a valid identifier", m);
+    panic!("{:016x} does not have a valid identifier", m);
 }
 
 // Converts a list of mask to a Vec<u8>.
index 91b9e058e8feacee390c12f2963103fe8e698986..425b2e3e7140bbb9171a7e6484c94cb4a4867331 100644 (file)
@@ -61,7 +61,7 @@ fn parse_opts(argv: Vec<String> ) -> Config {
       Ok(ref m) => {
           return Config {stress: m.opt_present("stress")}
       }
-      Err(_) => { fail!(); }
+      Err(_) => { panic!(); }
     }
 }
 
index dc54374f0fa74d23575dd10a7327b075deaf112b..5ce1b2fc40d0464709888cee39636cd450d99453 100644 (file)
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 // OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// ignore-android doesn't terminate?
+// ignore-android see #10393 #13206
 
-#![feature(slicing_syntax, asm, if_let, tuple_indexing)]
+#![feature(slicing_syntax, unboxed_closures, overloaded_calls)]
 
 extern crate libc;
 
 use std::io::stdio::{stdin_raw, stdout_raw};
-use std::sync::{Future};
 use std::num::{div_rem};
 use std::ptr::{copy_memory};
 use std::io::{IoResult, EndOfFile};
-use std::slice::raw::{mut_buf_as_slice};
 
-use shared_memory::{SharedMemory};
-
-mod tables {
-    use std::sync::{Once, ONCE_INIT};
-
-    /// Lookup tables.
-    static mut CPL16: [u16, ..1 << 16] = [0, ..1 << 16];
-    static mut CPL8:  [u8,  ..1 << 8]  = [0, ..1 << 8];
-
-    /// Generates the tables.
-    pub fn get() -> Tables {
-        /// To make sure we initialize the tables only once.
-        static INIT: Once = ONCE_INIT;
-        INIT.doit(|| {
-            unsafe {
-                for i in range(0, 1 << 8) {
-                    CPL8[i] = match i as u8 {
-                        b'A' | b'a' => b'T',
-                        b'C' | b'c' => b'G',
-                        b'G' | b'g' => b'C',
-                        b'T' | b't' => b'A',
-                        b'U' | b'u' => b'A',
-                        b'M' | b'm' => b'K',
-                        b'R' | b'r' => b'Y',
-                        b'W' | b'w' => b'W',
-                        b'S' | b's' => b'S',
-                        b'Y' | b'y' => b'R',
-                        b'K' | b'k' => b'M',
-                        b'V' | b'v' => b'B',
-                        b'H' | b'h' => b'D',
-                        b'D' | b'd' => b'H',
-                        b'B' | b'b' => b'V',
-                        b'N' | b'n' => b'N',
-                        i => i,
-                    };
-                }
-
-                for (i, v) in CPL16.iter_mut().enumerate() {
-                    *v = *CPL8.unsafe_get(i & 255) as u16 << 8 |
-                         *CPL8.unsafe_get(i >> 8)  as u16;
-                }
-            }
-        });
-        Tables { _dummy: () }
-    }
-
-    /// Accessor for the static arrays.
-    ///
-    /// To make sure that the tables can't be accessed without having been initialized.
-    pub struct Tables {
-        _dummy: ()
-    }
-
-    impl Tables {
-        /// Retreives the complement for `i`.
-        pub fn cpl8(self, i: u8) -> u8 {
-            // Not really unsafe.
-            unsafe { CPL8[i as uint] }
-        }
-
-        /// Retreives the complement for `i`.
-        pub fn cpl16(self, i: u16) -> u16 {
-            unsafe { CPL16[i as uint] }
-        }
-    }
+struct Tables {
+    table8: [u8, ..1 << 8],
+    table16: [u16, ..1 << 16]
 }
 
-mod shared_memory {
-    use std::sync::{Arc};
-    use std::mem::{transmute};
-    use std::raw::{Slice};
-
-    /// Structure for sharing disjoint parts of a vector mutably across tasks.
-    pub struct SharedMemory {
-        ptr: Arc<Vec<u8>>,
-        start: uint,
-        len: uint,
-    }
-
-    impl SharedMemory {
-        pub fn new(ptr: Vec<u8>) -> SharedMemory {
-            let len = ptr.len();
-            SharedMemory {
-                ptr: Arc::new(ptr),
-                start: 0,
-                len: len,
-            }
+impl Tables {
+    fn new() -> Tables {
+        let mut table8 = [0, ..1 << 8];
+        for (i, v) in table8.iter_mut().enumerate() {
+            *v = Tables::computed_cpl8(i as u8);
         }
-
-        pub fn as_mut_slice(&mut self) -> &mut [u8] {
-            unsafe {
-                transmute(Slice {
-                    data: self.ptr.as_ptr().offset(self.start as int) as *const u8,
-                    len: self.len,
-                })
-            }
+        let mut table16 = [0, ..1 << 16];
+        for (i, v) in table16.iter_mut().enumerate() {
+            *v = table8[i & 255] as u16 << 8 |
+                 table8[i >> 8]  as u16;
         }
+        Tables { table8: table8, table16: table16 }
+    }
 
-        pub fn len(&self) -> uint {
-            self.len
+    fn computed_cpl8(c: u8) -> u8 {
+        match c {
+            b'A' | b'a' => b'T',
+            b'C' | b'c' => b'G',
+            b'G' | b'g' => b'C',
+            b'T' | b't' => b'A',
+            b'U' | b'u' => b'A',
+            b'M' | b'm' => b'K',
+            b'R' | b'r' => b'Y',
+            b'W' | b'w' => b'W',
+            b'S' | b's' => b'S',
+            b'Y' | b'y' => b'R',
+            b'K' | b'k' => b'M',
+            b'V' | b'v' => b'B',
+            b'H' | b'h' => b'D',
+            b'D' | b'd' => b'H',
+            b'B' | b'b' => b'V',
+            b'N' | b'n' => b'N',
+            i => i,
         }
+    }
 
-        pub fn split_at(self, mid: uint) -> (SharedMemory, SharedMemory) {
-            assert!(mid <= self.len);
-            let left = SharedMemory {
-                ptr: self.ptr.clone(),
-                start: self.start,
-                len: mid,
-            };
-            let right = SharedMemory {
-                ptr: self.ptr,
-                start: self.start + mid,
-                len: self.len - mid,
-            };
-            (left, right)
-        }
+    /// Retreives the complement for `i`.
+    fn cpl8(&self, i: u8) -> u8 {
+        self.table8[i as uint]
+    }
 
-        /// Resets the object so that it covers the whole range of the contained vector.
-        ///
-        /// You must not call this method if `self` is not the only reference to the
-        /// shared memory.
-        ///
-        /// FIXME: If `Arc` had a method to check if the reference is unique, then we
-        /// wouldn't need the `unsafe` here.
-        ///
-        /// FIXME: If `Arc` had a method to unwrap the contained value, then we could
-        /// simply unwrap here.
-        pub unsafe fn reset(self) -> SharedMemory {
-            let len = self.ptr.len();
-            SharedMemory {
-                ptr: self.ptr,
-                start: 0,
-                len: len,
-            }
-        }
+    /// Retreives the complement for `i`.
+    fn cpl16(&self, i: u16) -> u16 {
+        self.table16[i as uint]
     }
 }
 
-
 /// Reads all remaining bytes from the stream.
 fn read_to_end<R: Reader>(r: &mut R) -> IoResult<Vec<u8>> {
+    // As reading the input stream in memory is a bottleneck, we tune
+    // Reader::read_to_end() with a fast growing policy to limit
+    // recopies.  If MREMAP_RETAIN is implemented in the linux kernel
+    // and jemalloc use it, this trick will become useless.
     const CHUNK: uint = 64 * 1024;
 
-    let mut vec = Vec::with_capacity(1024 * 1024);
+    let mut vec = Vec::with_capacity(CHUNK);
     loop {
+        // workaround: very fast growing
         if vec.capacity() - vec.len() < CHUNK {
             let cap = vec.capacity();
             let mult = if cap < 256 * 1024 * 1024 {
-                // FIXME (mahkoh): Temporary workaround for jemalloc on linux. Replace
-                // this by 2x once the jemalloc preformance issue has been fixed.
                 16
             } else {
                 2
             };
             vec.reserve_exact(mult * cap);
         }
-        unsafe {
-            let ptr = vec.as_mut_ptr().offset(vec.len() as int);
-            match mut_buf_as_slice(ptr, CHUNK, |s| r.read(s)) {
-                Ok(n) => {
-                    let len = vec.len();
-                    vec.set_len(len + n);
-                },
-                Err(ref e) if e.kind == EndOfFile => break,
-                Err(e) => return Err(e),
-            }
+        match r.push_at_least(1, CHUNK, &mut vec) {
+            Ok(_) => {}
+            Err(ref e) if e.kind == EndOfFile => break,
+            Err(e) => return Err(e)
         }
     }
     Ok(vec)
@@ -225,11 +133,8 @@ fn read_to_end<R: Reader>(r: &mut R) -> IoResult<Vec<u8>> {
 /// Finds the first position at which `b` occurs in `s`.
 fn memchr(h: &[u8], n: u8) -> Option<uint> {
     use libc::{c_void, c_int, size_t};
-    extern {
-        fn memchr(h: *const c_void, n: c_int, s: size_t) -> *mut c_void;
-    }
     let res = unsafe {
-        memchr(h.as_ptr() as *const c_void, n as c_int, h.len() as size_t)
+        libc::memchr(h.as_ptr() as *const c_void, n as c_int, h.len() as size_t)
     };
     if res.is_null() {
         None
@@ -238,13 +143,36 @@ fn memchr(h: &[u8], n: u8) -> Option<uint> {
     }
 }
 
+/// A mutable iterator over DNA sequences
+struct MutDnaSeqs<'a> { s: &'a mut [u8] }
+fn mut_dna_seqs<'a>(s: &'a mut [u8]) -> MutDnaSeqs<'a> {
+    MutDnaSeqs { s: s }
+}
+impl<'a> Iterator<&'a mut [u8]> for MutDnaSeqs<'a> {
+    fn next(&mut self) -> Option<&'a mut [u8]> {
+        let tmp = std::mem::replace(&mut self.s, &mut []);
+        let tmp = match memchr(tmp, b'\n') {
+            Some(i) => tmp.slice_from_mut(i + 1),
+            None => return None,
+        };
+        let (seq, tmp) = match memchr(tmp, b'>') {
+            Some(i) => tmp.split_at_mut(i),
+            None => {
+                let len = tmp.len();
+                tmp.split_at_mut(len)
+            }
+        };
+        self.s = tmp;
+        Some(seq)
+    }
+}
+
 /// Length of a normal line without the terminating \n.
 const LINE_LEN: uint = 60;
 
 /// Compute the reverse complement.
-fn reverse_complement(mut view: SharedMemory, tables: tables::Tables) {
-    // Drop the last newline
-    let seq = view.as_mut_slice().init_mut();
+fn reverse_complement(seq: &mut [u8], tables: &Tables) {
+    let seq = seq.init_mut();// Drop the last newline
     let len = seq.len();
     let off = LINE_LEN - len % (LINE_LEN + 1);
     let mut i = LINE_LEN;
@@ -290,34 +218,36 @@ fn reverse_complement(mut view: SharedMemory, tables: tables::Tables) {
     }
 }
 
-fn main() {
-    let mut data = SharedMemory::new(read_to_end(&mut stdin_raw()).unwrap());
-    let tables = tables::get();
-
-    let mut futures = vec!();
-    loop {
-        let (_, mut tmp_data) = match memchr(data.as_mut_slice(), b'\n') {
-            Some(i) => data.split_at(i + 1),
-            _ => break,
-        };
-        let (view, tmp_data) = match memchr(tmp_data.as_mut_slice(), b'>') {
-            Some(i) => tmp_data.split_at(i),
-            None => {
-                let len = tmp_data.len();
-                tmp_data.split_at(len)
-            },
-        };
-        futures.push(Future::spawn(proc() reverse_complement(view, tables)));
-        data = tmp_data;
-    }
-
-    for f in futures.iter_mut() {
-        f.get();
+/// Executes a closure in parallel over the given iterator over mutable slice.
+/// The closure `f` is run in parallel with an element of `iter`.
+fn parallel<'a, I, T, F>(mut iter: I, f: F)
+        where T: Send + Sync,
+              I: Iterator<&'a mut [T]>,
+              F: Fn(&'a mut [T]) + Sync {
+    use std::mem;
+    use std::raw::Repr;
+
+    let (tx, rx) = channel();
+    for chunk in iter {
+        let tx = tx.clone();
+
+        // Need to convert `f` and `chunk` to something that can cross the task
+        // boundary.
+        let f = &f as *const F as *const uint;
+        let raw = chunk.repr();
+        spawn(proc() {
+            let f = f as *const F;
+            unsafe { (*f)(mem::transmute(raw)) }
+            drop(tx)
+        });
     }
+    drop(tx);
+    for () in rx.iter() {}
+}
 
-    // Not actually unsafe. If Arc had a way to check uniqueness then we could do that in
-    // `reset` and it would tell us that, yes, it is unique at this point.
-    data = unsafe { data.reset() };
-
+fn main() {
+    let mut data = read_to_end(&mut stdin_raw()).unwrap();
+    let tables = &Tables::new();
+    parallel(mut_dna_seqs(data[mut]), |&: seq| reverse_complement(seq, tables));
     stdout_raw().write(data.as_mut_slice()).unwrap();
 }
index 01c412c6d3195420ecb903608f56d782e34415bf..ae7594ea8a20e74b29cd49e0c71f19ebdfadbcd3 100644 (file)
@@ -83,7 +83,7 @@ pub fn read(mut reader: BufferedReader<StdReader>) -> Sudoku {
                     from_str::<uint>(comps[2]).unwrap() as u8;
             }
             else {
-                fail!("Invalid sudoku file");
+                panic!("Invalid sudoku file");
             }
         }
         return Sudoku::new(g)
@@ -123,7 +123,7 @@ pub fn solve(&mut self) {
                 ptr = ptr + 1u;
             } else {
                 // no: redo this field aft recoloring pred; unless there is none
-                if ptr == 0u { fail!("No solution found for this sudoku"); }
+                if ptr == 0u { panic!("No solution found for this sudoku"); }
                 ptr = ptr - 1u;
             }
         }
index bdeee5fb6e0bf6b6ca47968d72d630e5189ed6d7..5d96c90197cce0390f442855c6f65033e9d3cf00 100644 (file)
@@ -39,7 +39,7 @@ fn run(repeat: int, depth: int) {
     for _ in range(0, repeat) {
         println!("starting {:.4f}", precise_time_s());
         task::try(proc() {
-            recurse_or_fail(depth, None)
+            recurse_or_panic(depth, None)
         });
         println!("stopping {:.4f}", precise_time_s());
     }
@@ -70,10 +70,10 @@ fn r(l: Box<nillist>) -> r {
     }
 }
 
-fn recurse_or_fail(depth: int, st: Option<State>) {
+fn recurse_or_panic(depth: int, st: Option<State>) {
     if depth == 0 {
         println!("unwinding {:.4f}", precise_time_s());
-        fail!();
+        panic!();
     } else {
         let depth = depth - 1;
 
@@ -96,6 +96,6 @@ fn recurse_or_fail(depth: int, st: Option<State>) {
             }
         };
 
-        recurse_or_fail(depth, Some(st));
+        recurse_or_panic(depth, Some(st));
     }
 }
index 9ebdbf0682d79d5e6e374e4bc54a80b413bf9da9..3d2822e14597ff4d8400eb88144d19ac367c1d61 100644 (file)
@@ -51,6 +51,6 @@ fn main() {
     let (tx, rx) = channel();
     child_generation(from_str::<uint>(args[1].as_slice()).unwrap(), tx);
     if rx.recv_opt().is_err() {
-        fail!("it happened when we slumbered");
+        panic!("it happened when we slumbered");
     }
 }
index 943169be00452630ad0ec8ca8ea66378e180de7e..d204c8c750aae28797abd76cd3e1804076910690 100644 (file)
@@ -11,8 +11,7 @@
 // Tests that a function with a ! annotation always actually fails
 
 fn bad_bang(i: uint) -> ! {
-    return 7u;
-    //~^ ERROR expected `!`, found `uint`
+    return 7u; //~ ERROR `return` in a function declared as diverging [E0166]
 }
 
 fn main() { bad_bang(5u); }
index 18b98eb3a3881dacb81f740a4906652758abf790..7e8142dbb2908de386b67d3b067ceaaf3fc8c9f1 100644 (file)
@@ -10,9 +10,8 @@
 
 // Tests that a function with a ! annotation always actually fails
 
-fn bad_bang(i: uint) -> ! {
-    if i < 0u { } else { fail!(); }
-    //~^ ERROR expected `!`, found `()`
+fn bad_bang(i: uint) -> ! { //~ ERROR computation may converge in a function marked as diverging
+    if i < 0u { } else { panic!(); }
 }
 
 fn main() { bad_bang(5u); }
index ff95f05279eea003c4c7d1abb1a6f826c00f562c..ec576ff4bd8c25f3964ae32a3be836387fba3469 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn f() -> ! {
-    3i //~ ERROR expected `!`, found `int`
+fn f() -> ! { //~ ERROR computation may converge in a function marked as diverging
+    3i
 }
 fn main() { }
index 87904399e032fca326f83f5ee3eedeff52e9ad3e..2a5c7136dc377ba5475ca833b219db6d89768125 100644 (file)
@@ -20,6 +20,6 @@ fn main() {
     let x = Some((X { x: () }, X { x: () }));
     match x {
         Some((ref _y, _z)) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern
-        None => fail!()
+        None => panic!()
     }
 }
index ba011d289255f7b47bb89400d3b68e5d1ee7fb7f..ae568a5277ce8d0e0215fdc3dfc22c1ec2813223 100644 (file)
@@ -22,6 +22,6 @@ fn main() {
     let x = some2(X { x: () }, X { x: () });
     match x {
         some2(ref _y, _z) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern
-        none2 => fail!()
+        none2 => panic!()
     }
 }
index 6858b7200db6ce8527bcda458fd35ab1f02a57b4..8c7542fbe6b3d02c1c84aefdb3957891eff73a7c 100644 (file)
@@ -20,6 +20,6 @@ fn main() {
     let x = Some((X { x: () }, X { x: () }));
     match x {
         Some((_y, ref _z)) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern
-        None => fail!()
+        None => panic!()
     }
 }
index 5602aff5cadcfd1b7441dd25b1cc9c8361b5b008..18534db0dd5a074450bc65b564b45f591d2d5980 100644 (file)
@@ -13,8 +13,8 @@ fn main() {
     let x = Some(rx);
     tx.send(false);
     match x {
-        Some(z) if z.recv() => { fail!() }, //~ ERROR cannot bind by-move into a pattern guard
+        Some(z) if z.recv() => { panic!() }, //~ ERROR cannot bind by-move into a pattern guard
         Some(z) => { assert!(!z.recv()); },
-        None => fail!()
+        None => panic!()
     }
 }
diff --git a/src/test/compile-fail/binop-fail-3.rs b/src/test/compile-fail/binop-fail-3.rs
new file mode 100644 (file)
index 0000000..097a52b
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn foo() -> ! { panic!("quux"); }
+fn main() {
+    foo() //~ ERROR the type of this value must be known in this context
+    ==
+    foo();
+}
index 12624a49f7a295508a0e954c32f85eeeed1b080f..3e0cd05cba346b89d98a94e28f058327c932272a 100644 (file)
@@ -20,12 +20,12 @@ fn distinct_variant() {
 
     let a = match y {
       Y(ref mut a, _) => a,
-      X => fail!()
+      X => panic!()
     };
 
     let b = match y {
       Y(_, ref mut b) => b,
-      X => fail!()
+      X => panic!()
     };
 
     *a += 1;
@@ -37,12 +37,12 @@ fn same_variant() {
 
     let a = match y {
       Y(ref mut a, _) => a,
-      X => fail!()
+      X => panic!()
     };
 
     let b = match y {
       Y(ref mut b, _) => b, //~ ERROR cannot borrow
-      X => fail!()
+      X => panic!()
     };
 
     *a += 1;
index 2a2a3dee1dfa6724cb9462dfc9807c3ebc0788ce..4c6088969f3595a8c31fcb56f2ce2e55a3f4ae3b 100644 (file)
@@ -28,7 +28,7 @@ fn main() {
                     x = X(Left((0,0)));
                     (*f)()
                 },
-                _ => fail!()
+                _ => panic!()
             }
         })
 }
index 208f58f6b54c1956b35d071ddfa2932bdd32a1c4..c071691c94707c0a27c8b2578096fb89495c829d 100644 (file)
@@ -19,7 +19,7 @@ struct Bar {
   int2: int,
 }
 
-fn make_foo() -> Box<Foo> { fail!() }
+fn make_foo() -> Box<Foo> { panic!() }
 
 fn borrow_same_field_twice_mut_mut() {
     let mut foo = make_foo();
index cdcf50c906e3655234f3a9cdd276d505a8e99355..3a85b45ad126dffe44dcaede60251ddfb7ed67fc 100644 (file)
@@ -18,7 +18,7 @@ struct Bar {
   int2: int,
 }
 
-fn make_foo() -> Foo { fail!() }
+fn make_foo() -> Foo { panic!() }
 
 fn borrow_same_field_twice_mut_mut() {
     let mut foo = make_foo();
index 61c77ce7bbaa9ac2acaa571ac4e126775d3ae845..febc84ccd44613c8fb7401c8c852cad9c880ca8b 100644 (file)
@@ -43,7 +43,7 @@ fn d(x: &mut int) {
 }
 
 fn e(x: &mut int) {
-    let c1: || = || x = fail!(); //~ ERROR closure cannot assign to immutable local variable
+    let c1: || = || x = panic!(); //~ ERROR closure cannot assign to immutable local variable
 }
 
 fn main() {
index e556b1bc184e3e207bdf9cc64c455e8f63bde492..8a7ecde700ae6f7cbab94f64f68d198002007978 100644 (file)
@@ -17,9 +17,9 @@
 
 fn borrow(_v: &int) {}
 fn borrow_mut(_v: &mut int) {}
-fn cond() -> bool { fail!() }
-fn for_func(_f: || -> bool) { fail!() }
-fn produce<T>() -> T { fail!(); }
+fn cond() -> bool { panic!() }
+fn for_func(_f: || -> bool) { panic!() }
+fn produce<T>() -> T { panic!(); }
 
 fn inc(v: &mut Box<int>) {
     *v = box() (**v + 1);
index 12e1240d10d633ed60cd64f8dfca1c5c2d409278..6adcfad33f46c58c582f7ffe1d14538f2cefa762 100644 (file)
@@ -17,8 +17,8 @@
 
 fn borrow(_v: &int) {}
 fn borrow_mut(_v: &mut int) {}
-fn cond() -> bool { fail!() }
-fn produce<T>() -> T { fail!(); }
+fn cond() -> bool { panic!() }
+fn produce<T>() -> T { panic!(); }
 
 fn inc(v: &mut Box<int>) {
     *v = box() (**v + 1);
index 7ad2d9040940ceca723de4e88e9060fca3d2e457..de8c7d9def4e1b709f2441091e18a809c0a42384 100644 (file)
@@ -17,9 +17,9 @@
 
 fn borrow(_v: &int) {}
 fn borrow_mut(_v: &mut int) {}
-fn cond() -> bool { fail!() }
-fn for_func(_f: || -> bool) { fail!() }
-fn produce<T>() -> T { fail!(); }
+fn cond() -> bool { panic!() }
+fn for_func(_f: || -> bool) { panic!() }
+fn produce<T>() -> T { panic!(); }
 
 fn inc(v: &mut Box<int>) {
     *v = box() (**v + 1);
index 30d57d4d755f04ade8515289684b84ab6950fe1a..376832ada4ef5b433cdc38dab5ed796b41353137 100644 (file)
@@ -16,7 +16,7 @@ fn f(x: &mut Either<int,f64>, y: &Either<int,f64>) -> int {
                 *x = Right(1.0);
                 *z
             }
-            _ => fail!()
+            _ => panic!()
         }
     }
 
index ba1d3a9ddba795c749f2e6b5a4660cbfcf71cbc8..726d4bcdf1d083a222c2680b15e8a1dc49f6fc00 100644 (file)
@@ -14,7 +14,7 @@ fn main() {
         Some(ref m) => { //~ ERROR borrowed value does not live long enough
             msg = m;
         },
-        None => { fail!() }
+        None => { panic!() }
     }
     println!("{}", *msg);
 }
index d256b033298ed988d7d6b292eaaed6b426b2cfdf..4a5418a4f20c21b3dca027a7bb4415a47514a64d 100644 (file)
@@ -15,7 +15,7 @@ fn a<'a>() -> &'a [int] {
     let vec: &[int] = vec.as_slice(); //~ ERROR does not live long enough
     let tail = match vec {
         [_, tail..] => tail,
-        _ => fail!("a")
+        _ => panic!("a")
     };
     tail
 }
@@ -25,7 +25,7 @@ fn b<'a>() -> &'a [int] {
     let vec: &[int] = vec.as_slice(); //~ ERROR does not live long enough
     let init = match vec {
         [init.., _] => init,
-        _ => fail!("b")
+        _ => panic!("b")
     };
     init
 }
@@ -35,7 +35,7 @@ fn c<'a>() -> &'a [int] {
     let vec: &[int] = vec.as_slice(); //~ ERROR does not live long enough
     let slice = match vec {
         [_, slice.., _] => slice,
-        _ => fail!("c")
+        _ => panic!("c")
     };
     slice
 }
index 2c9cf7d1b65be0abf147be7a86b1e360afb9a0f9..852eb172c59d10335e37783a4c0f94092c84ea57 100644 (file)
@@ -13,7 +13,7 @@ fn a<'a>() -> &'a int {
     let vec: &[int] = vec.as_slice(); //~ ERROR `vec` does not live long enough
     let tail = match vec {
         [_a, tail..] => &tail[0],
-        _ => fail!("foo")
+        _ => panic!("foo")
     };
     tail
 }
index 7ce8e95a761f2bddfcca5d1ad5dd3863f9fbc032..7a1ebed0a82acb433a9d128ae54485fce6fe090b 100644 (file)
@@ -12,9 +12,9 @@ fn foo(f: || -> !) {}
 
 fn main() {
     // Type inference didn't use to be able to handle this:
-    foo(|| fail!());
-    foo(|| -> ! fail!());
-    foo(|| 22); //~ ERROR mismatched types
-    foo(|| -> ! 22); //~ ERROR mismatched types
-    let x = || -> ! 1; //~ ERROR mismatched types
+    foo(|| panic!());
+    foo(|| -> ! panic!());
+    foo(|| 22i); //~ ERROR computation may converge in a function marked as diverging
+    foo(|| -> ! 22i); //~ ERROR computation may converge in a function marked as diverging
+    let x = || -> ! 1i; //~ ERROR computation may converge in a function marked as diverging
 }
index 578de06b74780da03fd72c4cda87673aab1a1012..da2e6200eb65f222a90d753236204aeb3f6d4eb2 100644 (file)
@@ -20,7 +20,7 @@ trait MyTrait<T> {
 
 impl<T> MyTrait<T> for T { //~ ERROR E0119
     fn get(&self) -> T {
-        fail!()
+        panic!()
     }
 }
 
index 96e8378a35df8e8e6da67e7a73cb9c5114827a49..3179b1815609f9bbc87a94874dd485e69262d786 100644 (file)
@@ -11,7 +11,7 @@
 #![deny(unreachable_code)]
 
 fn main() {
-    let x: || -> ! = || fail!();
+    let x: || -> ! = || panic!();
     x();
     println!("Foo bar"); //~ ERROR: unreachable statement
 }
index 7b1b0f6243ac4321b22ebd7470b7d8be4441979e..1c711c0145d90f936d11a375c3294ad47f9956d8 100644 (file)
@@ -10,6 +10,6 @@
 
 fn main() {
   match *1 { //~ ERROR: cannot be dereferenced
-      _ => { fail!(); }
+      _ => { panic!(); }
   }
 }
index 58ecdec538e0bc2a25c6f4d834d3333a72b87ac0..49a927b9879e491eb62c98b8f71aebd2f5c217c7 100644 (file)
 fn foo() { //~ ERROR function is never used
 
     // none of these should have any dead_code exposed to the user
-    fail!();
+    panic!();
 
-    fail!("foo");
+    panic!("foo");
 
-    fail!("bar {}", "baz")
+    panic!("bar {}", "baz")
 }
 
 
index 897710609fd41685e750b7ea1c1bbcf850dd9e82..6e5d3a313556e3809e85324e6e03f2b68bb61b8d 100644 (file)
 fn foo() { //~ ERROR function is never used
 
     // none of these should have any dead_code exposed to the user
-    fail!();
+    panic!();
 
-    fail!("foo");
+    panic!("foo");
 
-    fail!("bar {}", "baz")
+    panic!("bar {}", "baz")
 }
 
 
index 19c1aa1ba204f7109406577b9d6e6386c0402e18..97b709592a9c9434487e739fb6804aeaeac595c4 100644 (file)
@@ -11,5 +11,5 @@
 
 // error-pattern:unexpected token
 fn main() {
-  fail!(@);
+  panic!(@);
 }
index 8b52324848bf4409d101d22347823ff9f7e44209..651072d2118e5f3648070ef49d6018883d2ead93 100644 (file)
@@ -23,7 +23,7 @@ trait Foo<'a> {
 }
 
 impl<'a> Foo<'a> for &'a str {
-    fn bar<T: Bar<'a>>(self) -> &'a str { fail!() } //~ ERROR lifetime
+    fn bar<T: Bar<'a>>(self) -> &'a str { panic!() } //~ ERROR lifetime
 }
 
 fn main() {
index cf05cf51640e9246b616a34b83bb43df7b46faca..bd01d45fd44ecfd3af74c46da7e134114759e41d 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 fn main() {
-    (return)[0u]; //~ ERROR cannot index a value of type `!`
+    (return)[0u]; //~ ERROR the type of this value must be known in this context
 }
index 8d7125d7fdd3a991c1ea2f6ca541b057f7c94fec..2cbb59cc15a204a2e7ae84e2d0ef580c57939144 100644 (file)
@@ -10,7 +10,7 @@
 
 struct A { foo: int }
 
-fn a() -> A { fail!() }
+fn a() -> A { panic!() }
 
 fn main() {
     let A { .., } = a(); //~ ERROR: expected `}`
index 455704376d6f946d5ffe7a883bc97e6d365d6b5c..4d0e02c6310c202670c4cbdb62fe624422d47c8d 100644 (file)
@@ -10,7 +10,7 @@
 
 struct A { foo: int }
 
-fn a() -> A { fail!() }
+fn a() -> A { panic!() }
 
 fn main() {
     let A { , } = a(); //~ ERROR: expected ident
index e5400bf60c361c227b70986c24c9e09b9a2ea5c0..55c12b051b94d85bc49e0b3380e1228e7c03a299 100644 (file)
@@ -13,7 +13,7 @@ fn main() {
     match a {
         Ok(a) => //~ ERROR: mismatched types
             println!("{}",a),
-        None => fail!()
+        None => panic!()
     }
 }
 
index a80e405d05ca2ee077b2a613df28c9079cb43926..cc0841a6856caa3bcc4d9d1fc36f7bfaa14a88d4 100644 (file)
@@ -18,7 +18,7 @@ fn tail(source_list: &IntList) -> IntList {
         &Cons(val, box ref next_list) => tail(next_list),
         &Cons(val, box Nil)           => Cons(val, box Nil),
         //~^ ERROR: unreachable pattern
-        _                          => fail!()
+        _                          => panic!()
     }
 }
 
index 356d95452b3e1788789d9acfcdedd8b038479455..74423b041dda327b231e43c827ad48575bcdc59d 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 fn new<T>() -> &'static T {
-    fail!()
+    panic!()
 }
 
 fn main() {
index a67d9dee9768f206e9e0ed6e9c1632f5c969b4c3..af5c8b45a483e4ad118bd3f97ed1415dcf320705 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 fn new<'r, T>() -> &'r T {
-    fail!()
+    panic!()
 }
 
 fn main() {
diff --git a/src/test/compile-fail/issue-12863.rs b/src/test/compile-fail/issue-12863.rs
new file mode 100644 (file)
index 0000000..0767667
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+mod foo { pub fn bar() {} }
+
+fn main() {
+    match () {
+        foo::bar => {} //~ ERROR `bar` is not an enum variant, struct or const
+    }
+}
index 14cc0a82df5b24105f8e2db6f8ea12e66362f88f..e150c1a0f2fc83f8484419a5fc311f5ca9f416e0 100644 (file)
@@ -16,6 +16,6 @@ pub fn main() {
     // tricked into looking up a non-existing second type parameter.
     let _x: uint = match Some(1u) {
         Ok(u) => u, //~ ERROR  mismatched types: expected `core::option::Option<uint>`
-        Err(e) => fail!(e)  //~ ERROR mismatched types: expected `core::option::Option<uint>`
+        Err(e) => panic!(e)  //~ ERROR mismatched types: expected `core::option::Option<uint>`
     };
 }
index fb6d1d4fc6efe9ecfe06259debfde2bc79197e72..aa823d9a70e7c3f5b631f8743345a98fc8b5c856 100644 (file)
@@ -9,6 +9,5 @@
 // except according to those terms.
 
 fn main() {
-    return.is_failure
-//~^ ERROR attempted access of field `is_failure` on type `!`, but no field with that name was found
+    return.is_failure //~ ERROR the type of this value must be known in this context
 }
diff --git a/src/test/compile-fail/issue-14721.rs b/src/test/compile-fail/issue-14721.rs
new file mode 100644 (file)
index 0000000..92add18
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let foo = "str";
+    println!("{}", foo.desc); //~ ERROR attempted access of field `desc` on type `&str`,
+                              //        but no field with that name was found
+}
index f1c0b622ae4373391e1c73df7d4f4a2fbbd2272b..37fcabef0ed9b0b4195dfbaa982beb56469f834c 100644 (file)
@@ -9,5 +9,9 @@
 // except according to those terms.
 
 fn main() {
-    loop { break.push(1); } //~ ERROR type `!` does not implement any method in scope named `push`
+    loop {
+        break.push(1) //~ ERROR the type of this value must be known in this context
+        //~^ ERROR multiple applicable methods in scope
+        ;
+    }
 }
index 410b1f94293a9e0ab571bcef2c319cf64e281ecc..856cd1b0f3f26c3397da7a98ced7b8a668c7cf3a 100644 (file)
@@ -9,5 +9,10 @@
 // except according to those terms.
 
 fn main() {
-    return { return () } (); //~ ERROR expected function, found `!`
+    return
+        { return () } //~ ERROR the type of this value must be known in this context
+    () //~^ ERROR the type of this value must be known in this context
+//~^^ ERROR notation; the first type parameter for the function trait is neither a tuple nor unit
+//~^^^ ERROR overloaded calls are experimental
+    ;
 }
diff --git a/src/test/compile-fail/issue-16683.rs b/src/test/compile-fail/issue-16683.rs
new file mode 100644 (file)
index 0000000..d9dfaac
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait T<'a> {
+    fn a(&'a self) -> &'a bool;
+    fn b(&self) {
+        self.a(); //~ ERROR mismatched types: expected `&'a Self`, found `&Self` (lifetime mismatch)
+    }
+}
+
+fn main() {}
index 9cfae2662ac00da602c7dd6a6c83bbbb9c2fb781..6895893adc4d0d503ccb14bf4a1af6ee17898b6b 100644 (file)
@@ -9,5 +9,6 @@
 // except according to those terms.
 
 fn main() {
-    *return; //~ ERROR type `!` cannot be dereferenced
+    *return //~ ERROR the type of this value must be known in this context
+    ;
 }
diff --git a/src/test/compile-fail/issue-17458.rs b/src/test/compile-fail/issue-17458.rs
new file mode 100644 (file)
index 0000000..b1fbe6f
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+static X: uint = 0 as *const uint as uint;
+//~^ ERROR: can not cast a pointer to an integer in a constant expression
+
+fn main() {
+    assert_eq!(X, 0);
+}
diff --git a/src/test/compile-fail/issue-17551.rs b/src/test/compile-fail/issue-17551.rs
new file mode 100644 (file)
index 0000000..197319b
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(unboxed_closures)]
+
+struct B<T>;
+
+fn main() {
+    let foo = B; //~ ERROR unable to infer enough type information to locate the impl of the trait
+    let closure = |:| foo;
+}
diff --git a/src/test/compile-fail/issue-18118.rs b/src/test/compile-fail/issue-18118.rs
new file mode 100644 (file)
index 0000000..4497c80
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn main() {
+    static z: &'static int = {
+        let p = 3;
+        &p
+//~^ ERROR cannot borrow a local variable inside a static block, define a separate static instead
+    };
+}
diff --git a/src/test/compile-fail/issue-18252.rs b/src/test/compile-fail/issue-18252.rs
new file mode 100644 (file)
index 0000000..c884f02
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(struct_variant)]
+
+enum Foo {
+    Variant { x: uint }
+}
+
+fn main() {
+    let f = Variant(42u); //~ ERROR expected function, found `Foo`
+}
diff --git a/src/test/compile-fail/issue-18294.rs b/src/test/compile-fail/issue-18294.rs
new file mode 100644 (file)
index 0000000..ca4cf52
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    const X: u32 = 1;
+    const Y: uint = &X as *const u32 as uint; //~ ERROR E0018
+    println!("{}", Y);
+}
diff --git a/src/test/compile-fail/issue-18343.rs b/src/test/compile-fail/issue-18343.rs
new file mode 100644 (file)
index 0000000..1608d21
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Obj<'a> {
+    closure: ||: 'a -> u32
+}
+
+fn main() {
+    let o = Obj { closure: || 42 };
+    o.closure(); //~ ERROR type `Obj<'_>` does not implement any method in scope named `closure`
+    //~^ NOTE use `(s.closure)(...)` if you meant to call the function stored in the `closure` field
+}
index 19d210f190595ea8ca7899e5bed01303a86a94f6..e64d674b7c862f1c379c33f447c614a461950d13 100644 (file)
@@ -15,7 +15,7 @@ trait vec_monad<A> {
 
 impl<A> vec_monad<A> for Vec<A> {
     fn bind<B>(&self, f: |A| -> Vec<B> ) {
-        let mut r = fail!();
+        let mut r = panic!();
         for elt in self.iter() { r = r + f(*elt); }
         //~^ ERROR the type of this value must be known
         //~^^ ERROR not implemented
index 7457a1020cee1c31c7fdf01bfaa6663fdb5497c9..468fed1eff5ad8d73825f10ea2a2d7dd58777203 100644 (file)
@@ -14,7 +14,7 @@
 
 fn fail_len(v: Vec<int> ) -> uint {
     let mut i = 3;
-    fail!();
+    panic!();
     for x in v.iter() { i += 1u; }
     //~^ ERROR: unreachable statement
     return i;
index 5559ba344ed17a44e61bc775f65e77413276e033..fbd8f9163b5df9a9a5238ac36adc09e9e57414b4 100644 (file)
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 fn main() {
-    let x = fail!();
+    let x = panic!();
     x.clone(); //~ ERROR the type of this value must be known in this context
 }
index e46dbaf0ae0e638cc41bbcb82594355a241e5a0c..6291b0240533f2170a02dee2ef9fe7949215a830 100644 (file)
@@ -16,7 +16,7 @@ trait channel<T> {
 
 // `chan` is not a trait, it's an enum
 impl chan for int { //~ ERROR `chan` is not a trait
-    fn send(&self, v: int) { fail!() }
+    fn send(&self, v: int) { panic!() }
 }
 
 fn main() {
index a2bb56fdf5f65b38b0cb4c15ca839924cb8ee556..93f38a50b05821f32972530a46f94aae91eb7ee3 100644 (file)
@@ -10,8 +10,8 @@
 
 fn foo() { //~ NOTE Did you mean to close this delimiter?
   match Some(x) {
-      Some(y) { fail!(); }
-      None    { fail!(); }
+      Some(y) { panic!(); }
+      None    { panic!(); }
 }
 
 fn bar() {
index 42b70c28be6045cdd944be8771bb50fdf392e394..70ffa86359d5a5a2d9ffe38a43301183f1f12681 100644 (file)
@@ -20,7 +20,7 @@ struct E {
 }
 
 impl A for E {
-  fn b<F: Sync, G>(_x: F) -> F { fail!() } //~ ERROR type parameter 0 requires `Sync`
+  fn b<F: Sync, G>(_x: F) -> F { panic!() } //~ ERROR type parameter 0 requires `Sync`
 }
 
 fn main() {}
index 9b8346da5c5d932dc2886938037bb32cbe931fb3..2eda5d67edd8e5409353dd8a6b9dc84bc07a34cb 100644 (file)
@@ -21,7 +21,7 @@ struct E {
 
 impl A for E {
   // n.b. The error message is awful -- see #3404
-  fn b<F:Clone,G>(&self, _x: G) -> G { fail!() } //~ ERROR method `b` has an incompatible type
+  fn b<F:Clone,G>(&self, _x: G) -> G { panic!() } //~ ERROR method `b` has an incompatible type
 }
 
 fn main() {}
index d44d81b7fe01d1d7a399c901461cacb8ff2ad4ef..578f100eba40b967e84c5ae098acdbb0606cfe6c 100644 (file)
@@ -23,7 +23,7 @@ fn reset(&self) {
            //~^ ERROR unresolved name `k0`.
         }
     }
-    fail!();
+    panic!();
 }
 
 fn main() {}
index dd27314e14fa3e03f7674c3c68f8ea7985d998c4..2716d49fe69a8d3171883f8d94e6e493dcde7b54 100644 (file)
@@ -38,6 +38,6 @@ fn main() {
         box Element(ed) => match ed.kind { //~ ERROR non-exhaustive patterns
             box HTMLImageElement(ref d) if d.image.is_some() => { true }
         },
-        _ => fail!("WAT") //~ ERROR unreachable pattern
+        _ => panic!("WAT") //~ ERROR unreachable pattern
     };
 }
index cccf730095bdfad0ba5ad1a0902c717d934322bd..9c31dc1e38ef8ff312193b105a73e9346e9d0153 100644 (file)
@@ -17,7 +17,7 @@ impl PTrait for P {
    fn getChildOption(&self) -> Option<Box<P>> {
        static childVal: Box<P> = self.child.get();
        //~^ ERROR attempt to use a non-constant value in a constant
-       fail!();
+       panic!();
    }
 }
 
index 6524056df888b86b4a36fa92a649e963d3d283f2..3ddb713528c5511f8a158bda4cc8a18f1875ed94 100644 (file)
@@ -27,13 +27,13 @@ fn main() {
 
     match (true, false) {
         box (true, false) => ()
-        //~^ ERROR mismatched types: expected `(bool,bool)`, found `Box<<generic #11>>`
+        //~^ ERROR mismatched types: expected `(bool,bool)`, found `Box<<generic #15>>`
         //         (expected tuple, found box)
     }
 
     match (true, false) {
         &(true, false) => ()
-        //~^ ERROR mismatched types: expected `(bool,bool)`, found `&<generic #15>`
+        //~^ ERROR mismatched types: expected `(bool,bool)`, found `&<generic #21>`
         //         (expected tuple, found &-ptr)
     }
 
index e1779a1db8697203fd7e2bc3d09a788cd4c4de54..0edcfa8a5477d19178891e0275c672f5b904bfe3 100644 (file)
@@ -16,5 +16,5 @@ fn main() {
     let a = 5;
     let _iter = TrieMapIterator{node: &a};
     _iter.node = & //~ ERROR cannot assign to immutable field
-    fail!()
+    panic!()
 }
diff --git a/src/test/compile-fail/issue-5500.rs b/src/test/compile-fail/issue-5500.rs
new file mode 100644 (file)
index 0000000..86ff29a
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    &panic!()
+    //~^ ERROR mismatched types: expected `()`, found `&<generic #2>` (expected (), found &-ptr)
+}
index cb3ffae5dbae3df047b03159c3daeed3e38a0259..52a57fa2f4411322505b2d23f188990230f8b305 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 fn foo<T>(t: T) {}
-fn main() { foo(fail!()) }
+fn main() { foo(panic!()) }
     //~^ ERROR type annotations required
diff --git a/src/test/compile-fail/issue-6991.rs b/src/test/compile-fail/issue-6991.rs
new file mode 100644 (file)
index 0000000..a5d23c7
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+static x: &'static uint = &1;
+static y: uint = *x;
+//~^ ERROR cannot refer to other statics by value,
+//         use the address-of operator or a constant instead
+fn main() {}
diff --git a/src/test/compile-fail/issue-7867.rs b/src/test/compile-fail/issue-7867.rs
new file mode 100644 (file)
index 0000000..0ab5516
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+enum A { B, C }
+
+mod foo { pub fn bar() {} }
+
+fn main() {
+    match (true, false) {
+        B => (), //~ ERROR expected `(bool,bool)`, found `A` (expected tuple, found enum A)
+        _ => ()
+    }
+
+    match &Some(42i) {
+        Some(x) => (), //~ ERROR expected `&core::option::Option<int>`,
+                       //        found `core::option::Option<<generic #4>>`
+        None => ()     //~ ERROR expected `&core::option::Option<int>`,
+                       //        found `core::option::Option<<generic #5>>`
+    }
+}
index 45b45dbaf5da4edf25cdc495ff0fccca20e714e0..659b1426bd3f99a86d830adc8ee3c21b2b1f7179 100644 (file)
 
 #![deny(unreachable_code)]
 
-fn g() -> ! { fail!(); }
+fn g() -> ! { panic!(); }
 fn f() -> ! {
-    return g();
-    g(); //~ ERROR: unreachable statement
+    return g(); //~ ERROR `return` in a function declared as diverging
+    g();
+}
+fn h() -> ! {
+    loop {}
+    g();
 }
 
 fn main() { f() }
index f3429b97cfcb97b213398242909f9daabcce8dc0..b9cfbd695b0473049a1963b7c321c43051f41e84 100644 (file)
@@ -8,13 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern: unreachable statement
-
 #![deny(unreachable_code)]
 
 fn f() -> ! {
-    return fail!();
-    fail!(); // the unreachable statement error is in <std macro>, at this line, there
+    return panic!(); //~ ERROR `return` in a function declared as diverging
+    panic!(); // the unreachable statement error is in <std macro>, at this line, there
              // only is a note
 }
 
index 5fa8c5db5b01c95a9dd9f73c17ad3e6cbae96c82..849f337743b77d86e42512594afab680ba8a0fb1 100644 (file)
 // Lifetime annotation needed because we have no arguments.
 fn f() -> &int {    //~ ERROR missing lifetime specifier
 //~^ NOTE there is no value for it to be borrowed from
-    fail!()
+    panic!()
 }
 
 // Lifetime annotation needed because we have two by-reference parameters.
 fn g(_x: &int, _y: &int) -> &int {    //~ ERROR missing lifetime specifier
 //~^ NOTE the signature does not say whether it is borrowed from `_x` or `_y`
-    fail!()
+    panic!()
 }
 
 struct Foo<'a> {
@@ -28,7 +28,7 @@ struct Foo<'a> {
 // and one on the reference.
 fn h(_x: &Foo) -> &int { //~ ERROR missing lifetime specifier
 //~^ NOTE the signature does not say which one of `_x`'s 2 elided lifetimes it is borrowed from
-    fail!()
+    panic!()
 }
 
 fn main() {}
index 8ae3f1fdd0d74bc76efe6ba3a745d1885edb2771..df3feefa881f3f28231da76f42a16c03d62c80c4 100644 (file)
@@ -20,7 +20,7 @@ mod foo {
     }
 }
 
-fn callback<T>(_f: || -> T) -> T { fail!() }
+fn callback<T>(_f: || -> T) -> T { panic!() }
 unsafe fn unsf() {}
 
 fn bad1() { unsafe {} }                  //~ ERROR: unnecessary `unsafe` block
@@ -50,7 +50,7 @@ fn good2() {
        sure that when purity is inherited that the source of the unsafe-ness
        is tracked correctly */
     unsafe {
-        unsafe fn what() -> Vec<String> { fail!() }
+        unsafe fn what() -> Vec<String> { panic!() }
 
         callback(|| {
             what();
index 4a4032d2ab932ddbddb3e99fc7e81d8f86427492..55ffdcd7f9fb314a51b242411976726a07c5fd67 100644 (file)
 pub struct Public<T>;
 
 impl Private<Public<int>> {
-    pub fn a(&self) -> Private<int> { fail!() }
-    fn b(&self) -> Private<int> { fail!() }
+    pub fn a(&self) -> Private<int> { panic!() }
+    fn b(&self) -> Private<int> { panic!() }
 
-    pub fn c() -> Private<int> { fail!() }
-    fn d() -> Private<int> { fail!() }
+    pub fn c() -> Private<int> { panic!() }
+    fn d() -> Private<int> { panic!() }
 }
 impl Private<int> {
-    pub fn e(&self) -> Private<int> { fail!() }
-    fn f(&self) -> Private<int> { fail!() }
+    pub fn e(&self) -> Private<int> { panic!() }
+    fn f(&self) -> Private<int> { panic!() }
 }
 
 impl Public<Private<int>> {
-    pub fn a(&self) -> Private<int> { fail!() }
-    fn b(&self) -> Private<int> { fail!() }
+    pub fn a(&self) -> Private<int> { panic!() }
+    fn b(&self) -> Private<int> { panic!() }
 
-    pub fn c() -> Private<int> { fail!() } //~ ERROR private type in exported type signature
-    fn d() -> Private<int> { fail!() }
+    pub fn c() -> Private<int> { panic!() } //~ ERROR private type in exported type signature
+    fn d() -> Private<int> { panic!() }
 }
 impl Public<int> {
-    pub fn e(&self) -> Private<int> { fail!() } //~ ERROR private type in exported type signature
-    fn f(&self) -> Private<int> { fail!() }
+    pub fn e(&self) -> Private<int> { panic!() } //~ ERROR private type in exported type signature
+    fn f(&self) -> Private<int> { panic!() }
 }
 
 pub fn x(_: Private<int>) {} //~ ERROR private type in exported type signature
@@ -70,39 +70,39 @@ enum Qux {
 }
 
 pub trait PubTrait {
-    fn foo(&self) -> Private<int> { fail!( )} //~ ERROR private type in exported type signature
+    fn foo(&self) -> Private<int> { panic!( )} //~ ERROR private type in exported type signature
     fn bar(&self) -> Private<int>; //~ ERROR private type in exported type signature
     fn baz() -> Private<int>; //~ ERROR private type in exported type signature
 }
 
 impl PubTrait for Public<int> {
-    fn bar(&self) -> Private<int> { fail!() }
-    fn baz() -> Private<int> { fail!() }
+    fn bar(&self) -> Private<int> { panic!() }
+    fn baz() -> Private<int> { panic!() }
 }
 impl PubTrait for Public<Private<int>> {
-    fn bar(&self) -> Private<int> { fail!() }
-    fn baz() -> Private<int> { fail!() }
+    fn bar(&self) -> Private<int> { panic!() }
+    fn baz() -> Private<int> { panic!() }
 }
 
 impl PubTrait for Private<int> {
-    fn bar(&self) -> Private<int> { fail!() }
-    fn baz() -> Private<int> { fail!() }
+    fn bar(&self) -> Private<int> { panic!() }
+    fn baz() -> Private<int> { panic!() }
 }
 impl PubTrait for (Private<int>,) {
-    fn bar(&self) -> Private<int> { fail!() }
-    fn baz() -> Private<int> { fail!() }
+    fn bar(&self) -> Private<int> { panic!() }
+    fn baz() -> Private<int> { panic!() }
 }
 
 
 trait PrivTrait {
-    fn foo(&self) -> Private<int> { fail!( )}
+    fn foo(&self) -> Private<int> { panic!( )}
     fn bar(&self) -> Private<int>;
 }
 impl PrivTrait for Private<int> {
-    fn bar(&self) -> Private<int> { fail!() }
+    fn bar(&self) -> Private<int> { panic!() }
 }
 impl PrivTrait for (Private<int>,) {
-    fn bar(&self) -> Private<int> { fail!() }
+    fn bar(&self) -> Private<int> { panic!() }
 }
 
 pub trait ParamTrait<T> {
@@ -111,14 +111,14 @@ pub trait ParamTrait<T> {
 
 impl ParamTrait<Private<int>> //~ ERROR private type in exported type signature
    for Public<int> {
-    fn foo() -> Private<int> { fail!() }
+    fn foo() -> Private<int> { panic!() }
 }
 
 impl ParamTrait<Private<int>> for Private<int> {
-    fn foo() -> Private<int> { fail!( )}
+    fn foo() -> Private<int> { panic!( )}
 }
 
 impl<T: ParamTrait<Private<int>>>  //~ ERROR private type in exported type signature
      ParamTrait<T> for Public<i8> {
-    fn foo() -> T { fail!() }
+    fn foo() -> T { panic!() }
 }
index f5ad5e6af0c8a81c10a35a197d97e64ace9bf571..04364e4e01088341af757036c32137862eca738a 100644 (file)
@@ -9,8 +9,9 @@
 // except according to those terms.
 
 // Tests that a function with a ! annotation always actually fails
-// error-pattern: some control paths may return
 
-fn bad_bang(i: uint) -> ! { println!("{}", 3i); }
+fn bad_bang(i: uint) -> ! { //~ ERROR computation may converge in a function marked as diverging
+    println!("{}", 3i);
+}
 
 fn main() { bad_bang(5u); }
index 54d0b2d00c776c8f308585a8f3b407477afcccdb..1ad696503e7f9994b5467479ace60a69a27422fc 100644 (file)
@@ -11,7 +11,7 @@
 fn send<T:Send + std::fmt::Show>(ch: _chan<T>, data: T) {
     println!("{}", ch);
     println!("{}", data);
-    fail!();
+    panic!();
 }
 
 #[deriving(Show)]
@@ -24,4 +24,4 @@ fn test00_start(ch: _chan<Box<int>>, message: Box<int>, _count: Box<int>) {
     println!("{}", message); //~ ERROR use of moved value: `message`
 }
 
-fn main() { fail!(); }
+fn main() { panic!(); }
index d0e5249305493523ad48208d5ffbf2ddc5d58a4f..9488e6bf969f023449c784ce977c34bea2bc9aab 100644 (file)
@@ -14,7 +14,7 @@ fn forever() -> ! {
   loop {
     break;
   }
-  return 42i; //~ ERROR expected `!`, found `int`
+  return 42i; //~ ERROR `return` in a function declared as diverging
 }
 
 fn main() {
index febe5f45d96b07bcee63a2c52f5b193e245d0f9e..df39e9e894eae8dcf9f4a7aede27c096919473c9 100644 (file)
@@ -33,7 +33,8 @@ pub fn opt_str1<'a>(maybestr: &'a Option<String>) -> &'a str {
 }
 
 pub fn opt_str2<'a>(maybestr: &'a Option<String>) -> &'static str {
-    match *maybestr {  //~ ERROR cannot infer an appropriate lifetime for automatic coercion due to
+    match *maybestr {
+    //~^ ERROR cannot infer an appropriate lifetime due to conflicting requirements
         None => "(none)",
         Some(ref s) => {
             let s: &'a str = s.as_slice();
@@ -43,7 +44,8 @@ pub fn opt_str2<'a>(maybestr: &'a Option<String>) -> &'static str {
 }
 
 pub fn opt_str3<'a>(maybestr: &'a Option<String>) -> &'static str {
-    match *maybestr {  //~ ERROR cannot infer an appropriate lifetime for automatic coercion due to
+    match *maybestr {
+    //~^ ERROR cannot infer an appropriate lifetime due to conflicting requirements
         Some(ref s) => {
             let s: &'a str = s.as_slice();
             s
index de44a005fc33ad599c66f92421b86a550a23a0e5..8064ef0e427a37e6b300db3e92af6e2612146037 100644 (file)
 // a good test that we merge paths correctly in the presence of a
 // variable that's used before it's declared
 
-fn my_fail() -> ! { fail!(); }
+fn my_panic() -> ! { panic!(); }
 
 fn main() {
-    match true { false => { my_fail(); } true => { } }
+    match true { false => { my_panic(); } true => { } }
 
     println!("{}", x); //~ ERROR unresolved name `x`.
     let x: int;
index 1d6dc504ab43b7baaea5f1e4310a4660fd98a890..678808f166cde90c7f094e97b7e14241aea31357 100644 (file)
@@ -13,7 +13,7 @@
 
 
 struct Foo<A> { f: A }
-fn guard(_s: String) -> bool {fail!()}
+fn guard(_s: String) -> bool {panic!()}
 fn touch<A>(_a: &A) {}
 
 fn f10() {
index 65ae25396c8d625502a099a354afc2676ab1e144..7d209467caf2a6f75cadb25948a6625c02c163d4 100644 (file)
@@ -13,7 +13,7 @@
 // terms of the binding, not the discriminant.
 
 struct Foo<A> { f: A }
-fn guard(_s: String) -> bool {fail!()}
+fn guard(_s: String) -> bool {panic!()}
 fn touch<A>(_a: &A) {}
 
 fn f10() {
index ff5ad2c5e193604a0cc2ecdfef7ebb503c673cbd..2a73b769895eeeb75be648157400f0bc3d73d75d 100644 (file)
@@ -31,7 +31,7 @@ fn innocent_looking_victim() {
                     //~^ ERROR: cannot borrow `*f` as mutable because
                     println!("{}", msg);
                 },
-                None => fail!("oops"),
+                None => panic!("oops"),
             }
         }
     })
index 439c82a6df08b19f858cd68de06f24abe731a74d..eb946a90c376c5d3ef4f700ffc27f2988caa903a 100644 (file)
@@ -23,7 +23,7 @@ fn match_nested_vecs<'a, T>(l1: Option<&'a [T]>, l2: Result<&'a [T], ()>) -> &'s
 fn main() {
     let x = a(c);
     match x { //~ ERROR non-exhaustive patterns: `a(c)` not covered
-        a(d) => { fail!("hello"); }
-        b => { fail!("goodbye"); }
+        a(d) => { panic!("hello"); }
+        b => { panic!("goodbye"); }
     }
 }
index 57eca3666ef14ef3dc363b4e1f8c32f719f26b58..2deb9591a834d08082dae64cce1d76e222eebb6f 100644 (file)
@@ -13,7 +13,7 @@
 // unrelated errors.
 
 fn foo(a: int, b: int, c: int, d:int) {
-  fail!();
+  panic!();
 }
 
 fn main() {
index 38669a99b498f1964e8f7405c26ed6857335d57b..7da62ef4db7daf976f6cafed7c850ee3c22f22ea 100644 (file)
@@ -11,7 +11,7 @@
 enum bar { t1((), Option<Vec<int>>), t2, }
 
 // n.b. my change changes this error message, but I think it's right -- tjc
-fn foo(t: bar) -> int { match t { t1(_, Some(x)) => { return x * 3; } _ => { fail!(); } } }
+fn foo(t: bar) -> int { match t { t1(_, Some(x)) => { return x * 3; } _ => { panic!(); } } }
 //~^ ERROR binary operation `*` cannot be applied to
 
 fn main() { }
index efb98a74538f2e6a3409f19db909d55f56100387..7752ea521f7e35a1b1ce1da989bbae1c009498d8 100644 (file)
@@ -17,7 +17,7 @@ fn foo(t: bar) {
       t1(_, Some::<int>(x)) => {
         println!("{}", x);
       }
-      _ => { fail!(); }
+      _ => { panic!(); }
     }
 }
 
index 06d473baea878403c7d12375fd41129b8cb19de2..deae9a83866038256d0fa9785dd93b3b48622b74 100644 (file)
@@ -64,5 +64,5 @@ fn main() {
 }
 
 fn check_pp<T>(expr: T, f: |pprust::ps, T|, expect: str) {
-    fail!();
+    panic!();
 }
index f63dd91eb2bc14465beefa07878d214028736f72..94485dddd136b01c45a2617a341c2182cab84f61 100644 (file)
@@ -57,5 +57,5 @@ fn main() {
 }
 
 fn check_pp<T>(expr: T, f: |pprust::ps, T|, expect: str) {
-    fail!();
+    panic!();
 }
index 6791b7c5870e06b41c9ef80f0d6ede0494ad028c..dfeba04109281fdf594a2db5d22560a55eea08e8 100644 (file)
 // Test that attempts to implicitly coerce a value into an
 // object respect the lifetime bound on the object type.
 
-fn a(v: &[u8]) -> Box<Clone + 'static> {
-    let x: Box<Clone + 'static> = box v; //~ ERROR does not outlive
+trait Foo {}
+impl<'a> Foo for &'a [u8] {}
+
+fn a(v: &[u8]) -> Box<Foo + 'static> {
+    let x: Box<Foo + 'static> = box v; //~ ERROR does not outlive
     x
 }
 
-fn b(v: &[u8]) -> Box<Clone + 'static> {
+fn b(v: &[u8]) -> Box<Foo + 'static> {
     box v //~ ERROR does not outlive
 }
 
-fn c(v: &[u8]) -> Box<Clone> {
+fn c(v: &[u8]) -> Box<Foo> {
     box v // OK thanks to lifetime elision
 }
 
-fn d<'a,'b>(v: &'a [u8]) -> Box<Clone+'b> {
+fn d<'a,'b>(v: &'a [u8]) -> Box<Foo+'b> {
     box v //~ ERROR does not outlive
 }
 
-fn e<'a:'b,'b>(v: &'a [u8]) -> Box<Clone+'b> {
+fn e<'a:'b,'b>(v: &'a [u8]) -> Box<Foo+'b> {
     box v // OK, thanks to 'a:'b
 }
 
index b3b5993bf915bd06d51143ba57dec3fd1fa18cab..c2b52b79f6c87cc894c533570e5a15f5f8cba867 100644 (file)
@@ -21,8 +21,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn of<T>() -> |T| { fail!(); }
-fn subtype<T>(x: |T|) { fail!(); }
+fn of<T>() -> |T| { panic!(); }
+fn subtype<T>(x: |T|) { panic!(); }
 
 fn test_fn<'x, 'y, 'z, T>(_x: &'x T, _y: &'y T, _z: &'z T) {
     // Here, x, y, and z are free.  Other letters
index 2d20634cdc41de8a9bcdfe0d8fa336f227cf68c6..72004f8714c6e361d87eb92def4fed742f0069ed 100644 (file)
@@ -31,17 +31,17 @@ fn want_G(f: G) { }
 
 // Should meet both.
 fn foo(x: &S) -> &'static S {
-    fail!()
+    panic!()
 }
 
 // Should meet both.
 fn bar<'a,'b>(x: &'a S) -> &'b S {
-    fail!()
+    panic!()
 }
 
 // Meets F, but not G.
 fn baz(x: &S) -> &S {
-    fail!()
+    panic!()
 }
 
 fn supply_F() {
index 30b33e82a4b79b32dd71aed7c7b87ca6d0f6b2eb..8e8d892a39f22dd0f4a5d5189c804e3690d8d755 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn of<'a,T>() -> |T|:'a { fail!(); }
-fn subtype<T>(x: |T|) { fail!(); }
+fn of<'a,T>() -> |T|:'a { panic!(); }
+fn subtype<T>(x: |T|) { panic!(); }
 
 fn test_fn<'x,'y,'z,T>(_x: &'x T, _y: &'y T, _z: &'z T) {
     // Here, x, y, and z are free.  Other letters
index 26cf3be429bd6dc36063cac66aff5996ec37f559..435d10a0a29a1c07db7a43a40d2ca3bfee547143 100644 (file)
@@ -27,7 +27,7 @@ fn ordering3<'a, 'b>(x: &'a uint, y: &'b uint) -> &'a &'b uint {
     // Do not infer an ordering from the return value.
     let z: &'b uint = &*x;
     //~^ ERROR cannot infer
-    fail!();
+    panic!();
 }
 
 fn ordering4<'a, 'b>(a: &'a uint, b: &'b uint, x: |&'a &'b uint|) {
index 38c5122c2c3f4403d1f4d0aae60d8885b6e7f27e..b3fa04d8025bdf137aa6e5beaf53576af108ef5c 100644 (file)
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-type t = { f: () }; //~ ERROR expected type, found token LBRACE
+type t = { f: () }; //~ ERROR expected type, found token LBrace
diff --git a/src/test/compile-fail/selftype-traittype.rs b/src/test/compile-fail/selftype-traittype.rs
deleted file mode 100644 (file)
index 44ee500..0000000
+++ /dev/null
@@ -1,20 +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.
-
-
-trait add {
-    fn plus(&self, x: Self) -> Self;
-}
-
-fn do_add(x: Box<add+'static>, y: Box<add+'static>) -> Box<add+'static> {
-    x.plus(y) //~ ERROR E0038
-}
-
-fn main() {}
index 9615e32bb1acf28f88ff00da9d2907467393bfe0..a9df449032e6fef4d9a22e03b57131458ed0ee03 100644 (file)
@@ -15,7 +15,7 @@
 use std::vec::Vec;
 
 fn last<T>(v: Vec<&T> ) -> std::option::Option<T> {
-    fail!();
+    panic!();
 }
 
 fn main() {
index f2ef1d1952505c09ba85aae43a1eda241b026277..5785a13b006821cef87cd4a4cd852bce4b093ebe 100644 (file)
@@ -14,4 +14,4 @@ enum quux<T> { bar }
 
 fn foo(c: quux) { assert!((false)); }
 
-fn main() { fail!(); }
+fn main() { panic!(); }
index 4233fa843eb611d0ca02e51b74a11f428b121a53..52035c09dd6dd3ce9d089bef98307b7e6658ec9f 100644 (file)
@@ -20,7 +20,7 @@ fn main() {
         x: 3i
     };
 
-    let baz: Foo<uint> = fail!();
+    let baz: Foo<uint> = panic!();
     //~^ ERROR not implemented
 }
 
diff --git a/src/test/compile-fail/trait-objects.rs b/src/test/compile-fail/trait-objects.rs
new file mode 100644 (file)
index 0000000..88b907a
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait Foo {
+    fn foo(self);
+}
+
+trait Bar {
+    fn bar(&self, x: &Self);
+}
+
+trait Baz {
+    fn baz<T>(&self, x: &T);
+}
+
+impl Foo for int {
+    fn foo(self) {}
+}
+
+impl Bar for int {
+    fn bar(&self, _x: &int) {}
+}
+
+impl Baz for int {
+    fn baz<T>(&self, _x: &T) {}
+}
+
+fn main() {
+    let _: &Foo = &42i; //~ ERROR cannot convert to a trait object
+    let _: &Bar = &42i; //~ ERROR cannot convert to a trait object
+    let _: &Baz = &42i; //~ ERROR cannot convert to a trait object
+
+    let _ = &42i as &Foo; //~ ERROR cannot convert to a trait object
+    let _ = &42i as &Bar; //~ ERROR cannot convert to a trait object
+    let _ = &42i as &Baz; //~ ERROR cannot convert to a trait object
+}
index 3dce0178597cfdda50f123c6a65c6630dbe6a8b0..a24f7710d7b61c88c740c9565cbb7e530dea96b1 100644 (file)
@@ -16,5 +16,5 @@ impl bar for uint { fn dup(&self) -> uint { *self } fn blah<X>(&self) {} }
 fn main() {
     10i.dup::<int>(); //~ ERROR does not take type parameters
     10i.blah::<int, int>(); //~ ERROR incorrect number of type parameters
-    (box 10i as Box<bar>).dup(); //~ ERROR contains a self-type
+    (box 10i as Box<bar>).dup(); //~ ERROR cannot convert to a trait object
 }
diff --git a/src/test/compile-fail/unboxed-closure-immutable-capture.rs b/src/test/compile-fail/unboxed-closure-immutable-capture.rs
new file mode 100644 (file)
index 0000000..e28abaf
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(unboxed_closures)]
+
+// Test that even unboxed closures that are capable of mutating their
+// environment cannot mutate captured variables that have not been
+// declared mutable (#18335)
+
+fn set(x: &mut uint) { *x = 0; }
+
+fn main() {
+    let x = 0u;
+    move |&mut:| x = 1; //~ ERROR cannot assign
+    move |&mut:| set(&mut x); //~ ERROR cannot borrow
+    move |:| x = 1; //~ ERROR cannot assign
+    move |:| set(&mut x); //~ ERROR cannot borrow
+    |&mut:| x = 1; //~ ERROR cannot assign
+    // FIXME: this should be `cannot borrow` (issue #18330)
+    |&mut:| set(&mut x); //~ ERROR cannot assign
+    |:| x = 1; //~ ERROR cannot assign
+    // FIXME: this should be `cannot borrow` (issue #18330)
+    |:| set(&mut x); //~ ERROR cannot assign
+}
index ecc52c0ee7d58491b5f59f2d063b0ca078bcf7d4..124bd9c4d5b4ef997b47d0b92968ee1793e78c3c 100644 (file)
@@ -17,7 +17,7 @@ enum MustUse { Test }
 #[must_use = "some message"]
 enum MustUseMsg { Test2 }
 
-fn foo<T>() -> T { fail!() }
+fn foo<T>() -> T { panic!() }
 
 fn bar() -> int { return foo::<int>(); }
 fn baz() -> MustUse { return foo::<MustUse>(); }
index 74ec56f7bd90a5193b0f6cb970dd24fe2cdc5d42..baac192cbf0227fd3f8accf8b81ad1a92a9a7981 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:weak-lang-items.rs
-// error-pattern: language item required, but not found: `fail_fmt`
+// error-pattern: language item required, but not found: `panic_fmt`
 // error-pattern: language item required, but not found: `stack_exhausted`
 // error-pattern: language item required, but not found: `eh_personality`
 
index d67a6b1e200499c2667321940d55e0ca51f8952b..dae1aca4ed37cce85d23ea8164a641f909766e4d 100644 (file)
@@ -72,4 +72,4 @@ fn main() {
 }
 
 fn _zzz() {()}
-fn _yyy() -> ! {fail!()}
+fn _yyy() -> ! {panic!()}
index 85b71e4e86cc7bcb47feb1b664ccffff412ef138..377f4669ffc8cb7b6f08ab7cab0285a08e356d7f 100644 (file)
@@ -8,6 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn f() { if (1i == fail!()) { } else { } }
+fn f() { if (1i == panic!()) { } else { } }
 
 fn main() { }
diff --git a/src/test/pretty/struct-pattern.rs b/src/test/pretty/struct-pattern.rs
new file mode 100644 (file)
index 0000000..b0795bb
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// pp-exact
+// pretty-compare-only
+// Testing that shorthand struct patterns are preserved
+
+fn main() { let Foo { a, ref b, mut c, x: y, z: z } = foo; }
index 5e1b7bb69bb2bf29ec81d6f57fa0065f99f62b0e..4878ec59fd4bcb632e366b92d48fa8a521c055c7 100644 (file)
@@ -11,6 +11,6 @@
 
 // error-pattern:meep
 
-fn f(_a: int, _b: int, _c: Box<int>) { fail!("moop"); }
+fn f(_a: int, _b: int, _c: Box<int>) { panic!("moop"); }
 
-fn main() { f(1, fail!("meep"), box 42); }
+fn main() { f(1, panic!("meep"), box 42); }
index 8e70c2c3561a2fce2364f19b98791a4929bc5981..197ed59c07f4400afaf57716322369b01d1215b8 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:failed at 'assertion failed: false'
+// error-pattern:panicked at 'assertion failed: false'
 
 fn main() {
     assert!(false);
index 72222ce43627eaa45028a00ba7b5acf88b8f136d..223c60d6ae43898d6f77ecc1f6b14fad52fce66d 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:failed at 'test-assert-fmt 42 rust'
+// error-pattern:panicked at 'test-assert-fmt 42 rust'
 
 fn main() {
     assert!(false, "test-assert-fmt {} {}", 42i, "rust");
index a1a8eb6a092dc146d21bd027d28568bd6f6893da..e68aef10de891c5134b967609739564b924ccb69 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:failed at 'test-assert-owned'
+// error-pattern:panicked at 'test-assert-owned'
 
 fn main() {
     assert!(false, "test-assert-owned".to_string());
index a35258462deaa7f4ad569034ee07916d4981e939..59be468e0cb900510d6c3b13a98143af81633e52 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:failed at 'test-assert-static'
+// error-pattern:panicked at 'test-assert-static'
 
 fn main() {
     assert!(false, "test-assert-static");
diff --git a/src/test/run-fail/binop-fail-3.rs b/src/test/run-fail/binop-fail-3.rs
deleted file mode 100644 (file)
index 150544f..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern:quux
-fn foo() -> ! { fail!("quux"); }
-fn main() { foo() == foo(); }
index 1ae520bbf1a74d2e3628e3f384605e34e48c3911..ac85b218ec0306f9aeb9e6fb6b178c01078a2ce4 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 // error-pattern:quux
-fn my_err(s: String) -> ! { println!("{}", s); fail!("quux"); }
+fn my_err(s: String) -> ! { println!("{}", s); panic!("quux"); }
 fn main() { 3u == my_err("bye".to_string()); }
index 8ca317e1dd77399956211c2fb3048d936ca2939e..06712841823e850666205fd058cfc9ed0ad0cbc4 100644 (file)
@@ -16,7 +16,7 @@
 fn main() {
     let x = vec!(1u,2u,3u);
 
-    // This should cause a bounds-check failure, but may not if we do our
+    // This should cause a bounds-check panic, but may not if we do our
     // bounds checking by comparing a scaled index value to the vector's
     // length (in bytes), because the scaling of the index will cause it to
     // wrap around to a small number.
@@ -24,6 +24,6 @@ fn main() {
     let idx = uint::MAX & !(uint::MAX >> 1u);
     println!("ov2 idx = 0x%x", idx);
 
-    // This should fail.
+    // This should panic.
     println!("ov2 0x%x",  x[idx]);
 }
index 6106abc76c3f7259a823c610d8f2fdaf04968dd2..22a9fffb2fb2312074c5af1f57c072004463c6a1 100644 (file)
@@ -17,7 +17,7 @@
 fn main() {
     let x = vec!(1u,2u,3u);
 
-    // This should cause a bounds-check failure, but may not if we do our
+    // This should cause a bounds-check panic, but may not if we do our
     // bounds checking by truncating the index value to the size of the
     // machine word, losing relevant bits of the index value.
 
@@ -28,13 +28,13 @@ fn main() {
            (idx >> 32) as uint,
            idx as uint);
 
-    // This should fail.
+    // This should panic.
     println!("ov3 0x%x",  x.as_slice()[idx]);
 }
 
 #[cfg(target_arch="x86_64")]
 fn main() {
-    // This version just fails anyways, for symmetry on 64-bit hosts.
+    // This version just panics anyways, for symmetry on 64-bit hosts.
     let x = vec!(1u,2u,3u);
     error!("ov3 0x%x",  x.as_slice()[200]);
 }
index 9123342f09a5c07edcc7e47f52a2fcb2563898d2..f8686d0dbb56fdb8494af6a0824b446452e4b274 100644 (file)
@@ -14,7 +14,7 @@
 
 fn main() {
 
-    // This should cause a bounds-check failure, but may not if we do our
+    // This should cause a bounds-check panic, but may not if we do our
     // bounds checking by comparing the scaled index to the vector's
     // address-bounds, since we've scaled the index to wrap around to the
     // address of the 0th cell in the array (even though the index is
@@ -30,6 +30,6 @@ fn main() {
     println!("ov1 idx * sizeof::<uint>() = 0x{:x}",
            idx * mem::size_of::<uint>());
 
-    // This should fail.
+    // This should panic.
     println!("ov1 0x{:x}", x[idx]);
 }
index 2a256b9a4e384d8310e6b53d52b7033b41fb4b88..e46564f80760c6c62cc2b5d8ee474b65f7ea6b69 100644 (file)
@@ -19,6 +19,6 @@ struct chan_t<T> {
     port: port_id,
 }
 
-fn send<T:Send>(_ch: chan_t<T>, _data: T) { fail!(); }
+fn send<T:Send>(_ch: chan_t<T>, _data: T) { panic!(); }
 
-fn main() { fail!("quux"); }
+fn main() { panic!("quux"); }
diff --git a/src/test/run-fail/by-value-self-objects-fail.rs b/src/test/run-fail/by-value-self-objects-fail.rs
deleted file mode 100644 (file)
index 7488926..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern:explicit failure
-
-trait Foo {
-    fn foo(self, x: int);
-}
-
-struct S {
-    x: int,
-    y: int,
-    z: int,
-    s: String,
-}
-
-impl Foo for S {
-    fn foo(self, x: int) {
-        fail!()
-    }
-}
-
-impl Drop for S {
-    fn drop(&mut self) {
-        println!("bye 1!");
-    }
-}
-
-fn f() {
-    let s = S {
-        x: 2,
-        y: 3,
-        z: 4,
-        s: "hello".to_string(),
-    };
-    let st = box s as Box<Foo>;
-    st.foo(5);
-}
-
-fn main() {
-    f();
-}
-
-
index 7f7eddd86cf67e6fbc5db21293ec1b5621fdaa7a..2014a108b3dabf49e1dc6984c9b5c10728bfd300 100644 (file)
@@ -11,5 +11,5 @@
 // error-pattern:test
 
 fn main() {
-    let _i: int = fail!("test");
+    let _i: int = panic!("test");
 }
index f1d9b15c42a0b09fd0f6ae7d0186554fddebd7cc..b54bf1c0c68d6ce985d6e93d8276a42677e2d70a 100644 (file)
@@ -11,7 +11,7 @@
 // error-pattern:test
 
 fn f() {
-    fail!("test");
+    panic!("test");
 }
 
 fn main() {
index 82e790c5d9fd90f7f916afb8577bd46663d389c4..811bd6e037dd45377c2aa1e3a7d297603c4ad2c6 100644 (file)
@@ -11,5 +11,5 @@
 // error-pattern:test
 
 fn main() {
-    fail!("test");
+    panic!("test");
 }
index 4f3dfaa80b939a0913583fa98560f446497d62dc..3835a16a5c2631beb29f745a31e1e9f80042c00d 100644 (file)
@@ -12,6 +12,6 @@
 
 //error-pattern:One
 fn main() {
-    fail!("One");
-    fail!("Two");
+    panic!("One");
+    panic!("Two");
 }
index 4af9b82ec7e22edf440ded5f61caab38f6812cea..f6d27cf99592a2084b042f89b8cc9509e7fabf86 100644 (file)
@@ -15,5 +15,5 @@
 fn main() {
     let mut a = 1i;
     if 1i == 1 { a = 2; }
-    fail!(format!("woooo{}", "o"));
+    panic!(format!("woooo{}", "o"));
 }
index 8c204b66e3657f2010776d4c370f977438567a24..4699897bf8abea7d73caa7b5ff4bdcca4610ad07 100644 (file)
@@ -12,4 +12,4 @@
 
 
 // error-pattern:explicit
-fn main() { fail!(); }
+fn main() { panic!(); }
index e645ea34df5647b5c204396ae33327844729db05..8cf018fb7702dc44ccf92760a2191e891777be95 100644 (file)
@@ -8,10 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// error-pattern:explicit panic
 
-
-
-// error-pattern:explicit failure
-fn f() -> ! { fail!() }
+fn f() -> ! { panic!() }
 
 fn main() { f(); }
index 99f798147f28f3e615fc8c5d30874ca6bce63739..987bee55c606d617d30a0070f197628f7e0a66e4 100644 (file)
@@ -8,11 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// error-pattern:explicit panic
 
-
-
-// error-pattern:explicit failure
-fn f() -> ! { fail!() }
+fn f() -> ! { panic!() }
 
 fn g() -> int { let x = if true { f() } else { 10 }; return x; }
 
index 55d86bc6493245722ce004567b6eefc7505af0f4..f04c94a3bf47f326285419abd5effa965776e4da 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// error-pattern:explicit panic
 
-
-
-// error-pattern:explicit failure
-fn main() { let _x = if false { 0i } else if true { fail!() } else { 10i }; }
+fn main() { let _x = if false { 0i } else if true { panic!() } else { 10i }; }
index 6476e57a35b842b3ca89cd4192f54c3afacaa74d..069c1d5ed35574fdd6c54c06318d5b0bfa661b91 100644 (file)
@@ -8,11 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// error-pattern:explicit panic
 
-
-
-// error-pattern:explicit failure
-fn f() -> ! { fail!() }
+fn f() -> ! { panic!() }
 
 fn g() -> int { let x = match true { true => { f() } false => { 10 } }; return x; }
 
index d15ec3f7b486ab00150fea6c0915a37e168c1d5a..d5c005b7029a5b11326ee3521da5cb05af36a128 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// error-pattern:explicit panic
 
-
-
-// error-pattern:explicit failure
-fn main() { let _x = match true { false => { 0i } true => { fail!() } }; }
+fn main() { let _x = match true { false => { 0i } true => { panic!() } }; }
index c11d269a89755e41351e8fe3d24f0f64c11cb55e..21a332a46cb5976d38ed2ff93ba31ed658af2105 100644 (file)
@@ -45,7 +45,7 @@ fn main() {
         task::spawn(proc() {
             let result = count(5u);
             println!("result = %?", result);
-            fail!();
+            panic!();
         });
     }
 }
index e23145ec2535798c676df3b5bb918e2624932b7d..4d4f931751067929c8c2afe8a9a2e52c44de1dac 100644 (file)
@@ -11,4 +11,4 @@
 // error-pattern:woe
 fn f(a: int) { println!("{}", a); }
 
-fn main() { f(fail!("woe")); }
+fn main() { f(panic!("woe")); }
index e1eea1d89b9db13e51906320e9f439acc391a6e8..e25390a798628f7051cd2b669338ae4b270357eb 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:failed at 'Box<Any>'
+// error-pattern:panicked at 'Box<Any>'
 
 fn main() {
-    fail!(box 612_i64);
+    panic!(box 612_i64);
 }
index 528f18dde0d3bacdf06a02801f42702ba3ec1f25..b73c66c4f21659473e29238ca4d8db546e8a29d1 100644 (file)
@@ -8,9 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:failed at 'Box<Any>'
-
+// error-pattern:panicked at 'Box<Any>'
 
 fn main() {
-    fail!(box 413i as Box<::std::any::Any+Send>);
+    panic!(box 413i as Box<::std::any::Any+Send>);
 }
index 13e3a6a31a8fa535139ddbe6710d9d5a41925781..a8565549a03ed9ed8a4395c7fa4b791764f76677 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:failed at 'explicit failure'
+// error-pattern:panicked at 'explicit panic'
 
 fn main() {
-    fail!();
+    panic!();
 }
index b3984c210b5b412ea8f08a8ea6f484f0eb5381be..ac50f02cf33c3ca7721eab998ee00cb156d93c60 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:failed at 'test-fail-fmt 42 rust'
+// error-pattern:panicked at 'test-fail-fmt 42 rust'
 
 fn main() {
-    fail!("test-fail-fmt {} {}", 42i, "rust");
+    panic!("test-fail-fmt {} {}", 42i, "rust");
 }
index e59f5bdcaa1797d8e2507614879291f3f9488f1e..2f695c4e4b70cfebba5d361a55af784eb3d96bee 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:failed at 'test-fail-owned'
+// error-pattern:panicked at 'test-fail-owned'
 
 fn main() {
-    fail!("test-fail-owned");
+    panic!("test-fail-owned");
 }
index 688ca4ce7e5720145a6a7f2efc721753639c3bae..c62162da09b7c79a95936f9a48f2bceb677c3807 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:failed at 'test-fail-static'
+// error-pattern:panicked at 'test-fail-static'
 
 fn main() {
-    fail!("test-fail-static");
+    panic!("test-fail-static");
 }
index f90530a4435b1770da42f8cd9a30e38e1e18853f..877ea9cd0a4308524c0da40fcc115dd8bcccd0fb 100644 (file)
@@ -9,4 +9,4 @@
 // except according to those terms.
 
 // error-pattern:moop
-fn main() { fail!("moop"); }
+fn main() { panic!("moop"); }
index 88720b421e6870d7f397147e7400362f7b1fb698..8b013199369a31789d69555c9d411ad4bbb12824 100644 (file)
@@ -12,7 +12,7 @@
 // Previously failed formating invalid utf8.
 // cc #16877
 
-// error-pattern:failed at 'hello�'
+// error-pattern:panicked at 'hello�'
 
 struct Foo;
 impl std::fmt::Show for Foo {
@@ -22,5 +22,5 @@ fn fmt(&self, fmtr:&mut std::fmt::Formatter) -> std::fmt::Result {
     }
 }
 fn main() {
-    fail!("{}", Foo)
+    panic!("{}", Foo)
 }
index 90a44e42759377e416135c568cda77a819f96388..06655e4c6813277c0b0b70e7fab4cdfc8964d7fc 100644 (file)
 // certain positions
 // error-pattern:oops
 
-fn bigfail() {
-    while (fail!("oops")) { if (fail!()) {
-        match (fail!()) { () => {
+fn bigpanic() {
+    while (panic!("oops")) { if (panic!()) {
+        match (panic!()) { () => {
         }
                      }
     }};
 }
 
-fn main() { bigfail(); }
+fn main() { bigpanic(); }
index 75d23d0f4fdf2e47919a99d619e64d732c2059b4..3f8abc41ff74a472cb3b0a53318be28d2dc38291 100644 (file)
@@ -8,13 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:task '<unnamed>' failed at 'test'
+// error-pattern:task '<unnamed>' panicked at 'test'
 
 use std::task;
 
 fn main() {
     let r: Result<int,_> = task::try(proc() {
-        fail!("test");
+        panic!("test");
         1i
     });
     assert!(r.is_ok());
index edb03b2d6b461ec110fe191f4c36a8d9a1b2d79c..0a303475a29ff1705b1aed7bdeb9fa94f43036c2 100644 (file)
@@ -8,14 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:task 'owned name' failed at 'test'
+// error-pattern:task 'owned name' panicked at 'test'
 
 use std::task::TaskBuilder;
 
 fn main() {
     let r: Result<int,_> = TaskBuilder::new().named("owned name".to_string())
                                              .try(proc() {
-        fail!("test");
+        panic!("test");
         1i
     });
     assert!(r.is_ok());
index 0a74009977828e4ffa152f6d29131eaed7b86820..73fca2465909304619b726bde793285722998773 100644 (file)
@@ -8,13 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:task 'send name' failed at 'test'
+// error-pattern:task 'send name' panicked at 'test'
 
 fn main() {
     let r: Result<int,_> =
         ::std::task::TaskBuilder::new().named("send name".into_maybe_owned())
                                        .try(proc() {
-            fail!("test");
+            panic!("test");
             3i
         });
     assert!(r.is_ok());
index 0b2901889cbf233e6d9e2975f6befe26224edf31..21c019e1a7422f00b3a701665427afc8153d75eb 100644 (file)
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:task 'static name' failed at 'test'
+// error-pattern:task 'static name' panicked at 'test'
 
 fn main() {
     let r: Result<int,_> =
         ::std::task::TaskBuilder::new().named("static name").try(proc() {
-            fail!("test");
+            panic!("test");
         });
     assert!(r.is_ok());
 }
index ae89f9518406a2ac1f87dfce70aefd8722289d77..22e81480867a9d46c70f1020ae24623e7d96e579 100644 (file)
@@ -12,5 +12,5 @@
 
 fn main() {
     let str_var: String = "meh".to_string();
-    fail!("{}", str_var);
+    panic!("{}", str_var);
 }
index 508463599a32fe36c2551dd958014c84365e6840..472c8ae15b99249c9daf225957654bb85307d5f5 100644 (file)
@@ -10,4 +10,4 @@
 
 // error-pattern:moop
 
-fn main() { for _ in range(0u, 10u) { fail!("moop"); } }
+fn main() { for _ in range(0u, 10u) { panic!("moop"); } }
index bf04789bbc7738ddbb8ee4e8e3012f8feaa3f8d6..939845a7b349a0d9353a0d6b3fae82f9bd54d251 100644 (file)
 //
 // Expanded pretty printing causes resolve conflicts.
 
-// error-pattern:fail works
+// error-pattern:panic works
 #![feature(globs)]
 
 use std::*;
 
 fn main() {
-    fail!("fail works")
+    panic!("panic works")
 }
index b5f39e73fcb1a3bda1968b9c6a6d7a5d4dc53e7d..1ead81b00919d42d7f22826d64921a19f4430821 100644 (file)
@@ -19,7 +19,7 @@ fn foo(x: uint) {
     if even(x) {
         println!("{}", x);
     } else {
-        fail!("Number is odd");
+        panic!("Number is odd");
     }
 }
 
index d80ae967f0e2c2e1c35a31b73284e4b5b4230f39..f38b00ab46d90ee92785f022456ee5a04393a025 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 // error-pattern:quux
-fn my_err(s: String) -> ! { println!("{}", s); fail!("quux"); }
+fn my_err(s: String) -> ! { println!("{}", s); panic!("quux"); }
 fn main() { if my_err("bye".to_string()) { } }
index b5b8d4855ab8d0aedfae3cd08e4a86e30375d415..8dbfc06152a0feccdbebb7e3b57d842e75706eec 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:explicit failure
+// error-pattern:explicit panic
 
 pub fn main() {
-    fail!(); println!("{}", 1i);
+    panic!(); println!("{}", 1i);
 }
index 80006936f22c0969d581154910b9265b62dbad14..57b7dfc1eecd605e61cd5601eb963f6c37a15e84 100644 (file)
@@ -11,5 +11,5 @@
 // error-pattern:bad input
 
 fn main() {
-    Some("foo").unwrap_or(fail!("bad input")).to_string();
+    Some("foo").unwrap_or(panic!("bad input")).to_string();
 }
index 9a5a8e7c38f81be52786510ddccca6455c495693..2b20540501ec043554dc9eea5d6ab98851eaca42 100644 (file)
@@ -8,13 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:explicit failure
+// error-pattern:explicit panic
 
 use std::sync::Arc;
 
 enum e<T> { ee(Arc<T>) }
 
-fn foo() -> e<int> {fail!();}
+fn foo() -> e<int> {panic!();}
 
 fn main() {
    let _f = foo();
index 539d2adc7d45caebecf69f46893ac8648a6225db..686277c8c09a00493028631609613f6b5c73eb48 100644 (file)
@@ -17,6 +17,6 @@
 fn main() {
     let mut x = Vec::new();
     let y = vec!(3i);
-    fail!("so long");
+    panic!("so long");
     x.extend(y.into_iter());
 }
diff --git a/src/test/run-fail/issue-5500.rs b/src/test/run-fail/issue-5500.rs
deleted file mode 100644 (file)
index 45dbe11..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern:explicit failure
-
-fn main() {
-    &fail!()
-}
index 5669131aeee536946b88a1763af14251d5d9b160..878a293c373162af45198de4a90cbb421bf2e5ce 100644 (file)
@@ -16,5 +16,5 @@ struct Point { x: int, y: int }
 
 fn main() {
     let origin = Point {x: 0, y: 0};
-    let f: Point = Point {x: (fail!("beep boop")),.. origin};
+    let f: Point = Point {x: (panic!("beep boop")),.. origin};
 }
index ca219fe21837d5041200ee1ef83fd157537185bf..b750501c265d57088abb82dfffef7f0143792b15 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:task '<main>' failed at
+// error-pattern:task '<main>' panicked at
 
 fn main() {
-    fail!()
+    panic!()
 }
index 9d80f07de0af9173049ee15a7d7896df9c7d3195..1b7cace14b079e7f8f49d8ec1f22d01676d9344a 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:explicit failure
+// error-pattern:explicit panic
 
 #![allow(unreachable_code)]
 #![allow(unused_variable)]
@@ -17,6 +17,6 @@ fn foo(s: String) { }
 
 fn main() {
     let i =
-        match Some::<int>(3) { None::<int> => { fail!() } Some::<int>(_) => { fail!() } };
+        match Some::<int>(3) { None::<int> => { panic!() } Some::<int>(_) => { panic!() } };
     foo(i);
 }
index 13ccd118c61861ac0f4eaebf90c45b9517c0edc2..da08f53fcde56d24573b5afdc8a6922ddf108acf 100644 (file)
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 // error-pattern:quux
-fn f() -> ! { fail!("quux") }
+fn f() -> ! { panic!("quux") }
 fn g() -> int { match f() { true => { 1 } false => { 0 } } }
 fn main() { g(); }
index a4a6739bfc1d49a858e5b9a1b7744e648b1e92ee..5c1a9e1a5e7125bee72556f53f1ac9cd4932508c 100644 (file)
@@ -11,9 +11,9 @@
 // error-pattern:squirrelcupcake
 fn cmp() -> int {
     match (Some('a'), None::<char>) {
-        (Some(_), _) => { fail!("squirrelcupcake"); }
-        (_, Some(_)) => { fail!(); }
-        _                    => { fail!("wat"); }
+        (Some(_), _) => { panic!("squirrelcupcake"); }
+        (_, Some(_)) => { panic!(); }
+        _                    => { panic!("wat"); }
     }
 }
 
index ae3924ba9356cbd7525c7b72a82b9eb8cd518a33..0b261676cb2df24621081c3e5b778529c208c35a 100644 (file)
@@ -9,13 +9,13 @@
 // except according to those terms.
 
 // ignore-android (FIXME #11419)
-// error-pattern:explicit failure
+// error-pattern:explicit panic
 
 extern crate native;
 
 #[start]
 fn start(argc: int, argv: *const *const u8) -> int {
     native::start(argc, argv, proc() {
-        fail!();
+        panic!();
     })
 }
index d607ec76c351de4856bd3b41736042e38b361eff..ec19e08c74f72066c910da763d62d887516a18df 100644 (file)
@@ -18,6 +18,6 @@
 struct T { t: String }
 
 fn main() {
-    let pth = fail!("bye");
+    let pth = panic!("bye");
     let _rs: T = T {t: pth};
 }
index c960679a43f1e074e56667b13c7cc1f3ac893cfe..e524a2432ac4ef1248601ad4c02f3e035734b336 100644 (file)
@@ -17,8 +17,8 @@
 fn main() {
     error!("whatever");
     // Setting the exit status only works when the scheduler terminates
-    // normally. In this case we're going to fail, so instead of
+    // normally. In this case we're going to panic, so instead of
     // returning 50 the process will return the typical rt failure code.
     os::set_exit_status(50);
-    fail!();
+    panic!();
 }
index 22985d57936a29a1237b5c898dffc022fa097a1c..1cfc6c36a6397f844bd5d29cc870f242d637b608 100644 (file)
@@ -20,7 +20,7 @@ struct r {
 }
 
 // Setting the exit status after the runtime has already
-// failed has no effect and the process exits with the
+// panicked has no effect and the process exits with the
 // runtime's exit code
 impl Drop for r {
     fn drop(&mut self) {
@@ -39,5 +39,5 @@ fn main() {
     task::spawn(proc() {
       let _i = r(5);
     });
-    fail!();
+    panic!();
 }
index d08cb198802ad38892d5fb9c91a3b67659ae3e4e..bddf9b5a7ea5970b414c6aba90b7854b694c0ffa 100644 (file)
@@ -16,7 +16,7 @@
 
 fn main() {
     error!("whatever");
-    // 101 is the code the runtime uses on task failure and the value
+    // 101 is the code the runtime uses on task panic and the value
     // compiletest expects run-fail tests to return.
     os::set_exit_status(101);
 }
index 70ef4a0c0c3d307e9895ccbe78cc4560f8977ce6..0e218740ab1cfb83db5db6819b8486077a9910d0 100644 (file)
@@ -17,5 +17,5 @@ mod m {
     pub fn exported() { }
 
     #[test]
-    fn unexported() { fail!("runned an unexported test"); }
+    fn unexported() { panic!("runned an unexported test"); }
 }
index c3ee76047d13428060432d2ded9cd7359bd79cb1..a9c0030fecaf7aa8094dc96446dc4832838744ab 100644 (file)
@@ -13,6 +13,6 @@
 fn main() {
     let s: String = "hello".to_string();
 
-    // Bounds-check failure.
+    // Bounds-check panic.
     assert_eq!(s.as_bytes()[5], 0x0 as u8);
 }
index e7fd97f8d31f386deeef8e56a82c32995370d82a..dfc3238662cfef413ef446f3847b46b0bc4fca2b 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:Ensure that the child task runs by failing
+// error-pattern:Ensure that the child task runs by panicking
 
 use std::task;
 
@@ -17,10 +17,10 @@ fn main() {
     // works when provided with a bare function:
     let r = task::try(startfn);
     if r.is_err() {
-        fail!()
+        panic!()
     }
 }
 
 fn startfn() {
-    assert!("Ensure that the child task runs by failing".is_empty());
+    assert!("Ensure that the child task runs by panicking".is_empty());
 }
index b628f101fd5766b67e7315d0d5d8291ff5ee2aef..cd2ec834d82acdd29be61e284d50fca05acfd859 100644 (file)
@@ -9,12 +9,12 @@
 // except according to those terms.
 
 // check-stdout
-// error-pattern:task 'test_foo' failed at
+// error-pattern:task 'test_foo' panicked at
 // compile-flags: --test
 // ignore-pretty: does not work well with `--test`
 
 #[test]
 fn test_foo() {
-    fail!()
+    panic!()
 }
 
index 1858ceb2836485bed7fa8ca2f73170b363d36654..5b44e3757047b83db80c3030602f323417f8b5bd 100644 (file)
@@ -15,5 +15,5 @@
 
 fn main() {
     os::args();
-    fail!("please have a nonzero exit status");
+    panic!("please have a nonzero exit status");
 }
index 04733552969c510e3f8d2db016de554509337bd5..2ec670c3306db044ddd8f1239d0d4b38fd8e5d1f 100644 (file)
@@ -11,7 +11,7 @@
 // ignore-test leaks
 // error-pattern:ran out of stack
 
-// Test that the task fails after hitting the recursion limit
+// Test that the task panicks after hitting the recursion limit
 // during unwinding
 
 fn recurse() {
index f1804c10691893c1ac756a5c69984b82268d95f7..07c9a21c5c1107066cdefcfbe7900c82c6df0eea 100644 (file)
@@ -8,5 +8,5 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern: fail
-fn main() { box fail!(); }
+// error-pattern: panic
+fn main() { box panic!(); }
index f6a3aa48def9b224e78d5b4b833eb7b7cddd142c..5012ded28b5c38763778eb6fab81c6655744c11f 100644 (file)
@@ -12,7 +12,7 @@
 
 fn a() { }
 
-fn b() { fail!(); }
+fn b() { panic!(); }
 
 fn main() {
     let _x = vec!(0i);
index 9c96970f0e7f116685a85ffd1d9e67c3f98b2642..1c72686b60287ace08d2905f00c68075da791f68 100644 (file)
@@ -12,7 +12,7 @@
 
 
 fn build() -> Vec<int> {
-    fail!();
+    panic!();
 }
 
 struct Blk { node: Vec<int> }
index 178d0a8ab327c4e06b2f9051de274f4bb8ea351b..943b4cd76715c35e3490e8624af652137a685a00 100644 (file)
@@ -16,7 +16,7 @@ fn build1() -> Vec<int> {
 }
 
 fn build2() -> Vec<int> {
-    fail!();
+    panic!();
 }
 
 struct Blk { node: Vec<int> , span: Vec<int> }
index 233d367c4b1e16b2b7fee4b109dbe0926b4c93ab..6b5aefbab802b6c638977c61d5364bf6a81712d2 100644 (file)
@@ -12,7 +12,7 @@
 
 
 fn failfn() {
-    fail!();
+    panic!();
 }
 
 fn main() {
index 281523a807ef8a368090ea951c329f7214bbadfb..c378e852f897e2dbe7524acedfa590f9033c4ea4 100644 (file)
@@ -15,7 +15,7 @@ fn main() {
     let v: Vec<int> = vec!(10);
     let x: uint = 0;
     assert_eq!(v[x], 10);
-    // Bounds-check failure.
+    // Bounds-check panic.
 
     assert_eq!(v[x + 2], 20);
 }
index 0a0b26083579df730a8ea8fafaa78484ef7a290a..6a7d0a1d73e8fe7170d65a7b2c4446d52432190b 100644 (file)
@@ -11,4 +11,4 @@
 #![allow(while_true)]
 
 // error-pattern:quux
-fn main() { let _x: int = { while true { fail!("quux"); } ; 8 } ; }
+fn main() { let _x: int = { while true { panic!("quux"); } ; 8 } ; }
index 24058c4fb936efed6303d86694885c1983070a71..f6081e497bffefaf16ae06f9706acd149b252233 100644 (file)
@@ -12,5 +12,5 @@
 
 // error-pattern:giraffe
 fn main() {
-    fail!({ while true { fail!("giraffe") }; "clandestine" });
+    panic!({ while true { panic!("giraffe") }; "clandestine" });
 }
index 721d16b4810c8f708b0b4fc33ffc3fba632a2394..1183475610584d0cab9ec404dd6bd1d13b1ff28b 100644 (file)
@@ -19,4 +19,4 @@
 
 #[lang = "stack_exhausted"] fn stack_exhausted() {}
 #[lang = "eh_personality"] fn eh_personality() {}
-#[lang = "fail_fmt"] fn fail_fmt() -> ! { loop {} }
+#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
index 3382cc207997288494f09f77e0fade89e0ad9c8e..61a2a51da08644e51bc09f7878e06e94af25053d 100644 (file)
@@ -19,4 +19,4 @@
 
 #[lang = "stack_exhausted"] fn stack_exhausted() {}
 #[lang = "eh_personality"] fn eh_personality() {}
-#[lang = "fail_fmt"] fn fail_fmt() -> ! { loop {} }
+#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
index 9fe78cc2553e742ac3263245433bed9fedede75d..9918fbb1ab70186db32aa26ae06df8007c97650c 100644 (file)
@@ -24,7 +24,7 @@ fn drop(&mut self) {
 fn main() {
     task::try(proc() {
         let _a = A;
-        lib::callback(|| fail!());
+        lib::callback(|| panic!());
         1i
     });
 
index 8ae2c1600aa28eb9294342ba6dd97d23feeec1d4..2f5e72491bef390e14493300e7cea306840d6291 100644 (file)
@@ -10,7 +10,7 @@
 
 
 pub fn main() {
-    fail!()
+    panic!()
 }
 
 #[main]
index f487a1c6be5ced06433e50904c9ace67f23442a9..7e7399c403a734e3007ea60a3aad5de6e1a7ccc3 100644 (file)
@@ -26,16 +26,16 @@ fn start(argc: int, argv: *const *const u8) -> int {
 fn foo() {
     let _v = vec![1i, 2, 3];
     if os::getenv("IS_TEST").is_some() {
-        fail!()
+        panic!()
     }
 }
 
 #[inline(never)]
 fn double() {
     (|| {
-        fail!("once");
+        panic!("once");
     }).finally(|| {
-        fail!("twice");
+        panic!("twice");
     })
 }
 
index 9c6e6ab60abe20f453088638355561f7f16b6037..8235b91273b521df5d9bbafa25a5d36ed7f18d88 100644 (file)
@@ -11,6 +11,6 @@
 // Check that issue #954 stays fixed
 
 pub fn main() {
-    match -1i { -1 => {}, _ => fail!("wat") }
+    match -1i { -1 => {}, _ => panic!("wat") }
     assert_eq!(1i-1, 0i);
 }
index a7d3d99e45892f33829761d569e797ec304ad0d5..a9fa8449d0f1ac654474da7fac604d30f43ac048 100644 (file)
@@ -16,6 +16,6 @@ pub fn main() {
     let x = Some(p);
     match x {
         Some(z) => { dispose(z); },
-        None => fail!()
+        None => panic!()
     }
 }
index 10835730fa54eccb705906045f855502fef7cd70..415c660221d406844e6d1c6f80b949a5a88dc41d 100644 (file)
@@ -32,11 +32,11 @@ macro_rules! declare(
     );
     match s {
       box Bar2(id, rest) => declare!(id, self.elaborate_stm(rest)),
-      _ => fail!()
+      _ => panic!()
     }
   }
 
-  fn check_id(&mut self, s: int) { fail!() }
+  fn check_id(&mut self, s: int) { panic!() }
 }
 
 pub fn main() { }
diff --git a/src/test/run-pass/by-value-self-objects.rs b/src/test/run-pass/by-value-self-objects.rs
deleted file mode 100644 (file)
index 3a58836..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static mut destructor_count: uint = 0;
-
-trait Foo {
-    fn foo(self, x: int);
-}
-
-struct S {
-    x: int,
-    y: int,
-    z: int,
-    s: String,
-}
-
-impl Foo for S {
-    fn foo(self, x: int) {
-        assert!(self.x == 2);
-        assert!(self.y == 3);
-        assert!(self.z == 4);
-        assert!(self.s.as_slice() == "hello");
-        assert!(x == 5);
-    }
-}
-
-impl Drop for S {
-    fn drop(&mut self) {
-        println!("bye 1!");
-        unsafe {
-            destructor_count += 1;
-        }
-    }
-}
-
-impl Foo for int {
-    fn foo(self, x: int) {
-        println!("{}", x * x);
-    }
-}
-
-fn f() {
-    let s = S {
-        x: 2,
-        y: 3,
-        z: 4,
-        s: "hello".to_string(),
-    };
-    let st = box s as Box<Foo>;
-    st.foo(5);
-    println!("bye 2!");
-}
-
-fn g() {
-    let s = 2i;
-    let st = box s as Box<Foo>;
-    st.foo(3);
-    println!("bye 3!");
-}
-
-fn main() {
-    f();
-
-    unsafe {
-        assert!(destructor_count == 1);
-    }
-
-    g();
-}
-
index aa45bfd14541cded421085bd0d12c309baabf2e7..ee8a58a0d337f01c67b64c93efd32e59203dfd1b 100644 (file)
@@ -29,12 +29,12 @@ pub fn main() {
 
     match 42 {
         b'*' => {},
-        _ => fail!()
+        _ => panic!()
     }
 
     match 100 {
         b'a' ... b'z' => {},
-        _ => fail!()
+        _ => panic!()
     }
 
     let expected: &[_] = &[97u8, 10u8, 13u8, 9u8, 92u8, 39u8, 34u8, 0u8, 240u8];
@@ -48,7 +48,7 @@ pub fn main() {
     let val: &[_] = &[97u8, 10u8];
     match val {
         b"a\n" => {},
-        _ => fail!(),
+        _ => panic!(),
     }
 
     let buf = vec!(97u8, 98, 99, 100);
index 97310fd9ad2e61cb04c41b1d653d73faf549a47e..c7c655b3db48c444f2a9abbe6b1dcfc194095af5 100644 (file)
@@ -20,7 +20,7 @@ fn clone(&self) -> Foo {
         // invoked -- after all, that would permit evil user code to
         // abuse `Cell` and trigger crashes.
 
-        fail!();
+        panic!();
     }
 }
 
diff --git a/src/test/run-pass/check-static-recursion-foreign.rs b/src/test/run-pass/check-static-recursion-foreign.rs
new file mode 100644 (file)
index 0000000..9acc0b3
--- /dev/null
@@ -0,0 +1,27 @@
+// 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.
+
+// Static recursion check shouldn't fail when given a foreign item (#18279)
+
+// aux-build:check_static_recursion_foreign_helper.rs
+extern crate check_static_recursion_foreign_helper;
+extern crate libc;
+
+use libc::c_int;
+
+#[link_name = "check_static_recursion_foreign_helper"]
+extern "C" {
+    #[allow(dead_code)]
+    static test_static: c_int;
+}
+
+static B: &'static c_int = &test_static;
+
+pub fn main() {}
index dd3a7b86bea830b98840f99fb232beba55c673fd..aab06c0339be209a1a1ccb26acb9af6060e3ba0d 100644 (file)
@@ -75,7 +75,7 @@ fn insert(&mut self, k: int, _: T) -> bool {
         true
     }
 
-    fn find_mut(&mut self, _k: &int) -> Option<&mut T> { fail!() }
+    fn find_mut(&mut self, _k: &int) -> Option<&mut T> { panic!() }
 
     fn remove(&mut self, k: &int) -> bool {
         if self.find(k).is_some() {
@@ -85,16 +85,16 @@ fn remove(&mut self, k: &int) -> bool {
         }
     }
 
-    fn pop(&mut self, _k: &int) -> Option<T> { fail!() }
+    fn pop(&mut self, _k: &int) -> Option<T> { panic!() }
 
-    fn swap(&mut self, _k: int, _v: T) -> Option<T> { fail!() }
+    fn swap(&mut self, _k: int, _v: T) -> Option<T> { panic!() }
 }
 
 impl<T> cat<T> {
     pub fn get(&self, k: &int) -> &T {
         match self.find(k) {
           Some(v) => { v }
-          None    => { fail!("epic fail"); }
+          None    => { panic!("epic fail"); }
         }
     }
 
index fda4a31375bcdbe6d662fc28dd2a681fd96853e6..97134a9d38937519678c3841fb907b3e5efbf8ec 100644 (file)
@@ -14,7 +14,7 @@
 //
 // 1. Partial cleanup of `box` is in scope,
 // 2. cleanup of return value from `get_bar()` is in scope,
-// 3. do_it() fails.
+// 3. do_it() panics.
 //
 // This led to a bug because `the top-most frame that was to be
 // cleaned (which happens to be the partial cleanup of `box`) required
@@ -33,7 +33,7 @@ enum Conzabble {
 struct Foo { field: Box<uint> }
 
 fn do_it(x: &[uint]) -> Foo {
-    fail!()
+    panic!()
 }
 
 fn get_bar(x: uint) -> Vec<uint> { vec!(x * 2) }
index e164aeca013b2533fb609d9f8a3530983d5c7337..9b4033ae0d7221ddec9828abbc7367d215b5e675 100644 (file)
@@ -15,6 +15,6 @@ fn f(x: || -> !) -> ! {
 }
 
 fn main() {
-    let x: || -> ! = || fail!();
+    let x: || -> ! = || panic!();
     let _y: || -> ! = || x();
 }
index b5a94a02b346b319ad6c8e7d0c599ea78e4d089b..9d98a7ac12f9ba1809d7845d3630ea3a3fde7ac9 100644 (file)
@@ -9,6 +9,9 @@
 // except according to those terms.
 
 #![allow(dead_code)]
+#![feature(unboxed_closures, unboxed_closure_sugar)]
+
+// compile-flags:-g
 
 fn foo<T>() {}
 
@@ -82,6 +85,9 @@ fn bar<'b>() {
     // issue #13490
     let _ = || -> ! loop {};
     let _ = proc() -> ! loop {};
+
+    // issue #17021
+    let c = box |&:| {};
 }
 
 struct B<T>;
index 116aa462a0ae2d20d685e55d71a63793ce0a079f..e5891b2f48dff788d7dd6abe59373029669b82ad 100644 (file)
@@ -80,7 +80,7 @@ pub fn f() { }
 // Since the bogus configuration isn't defined main will just be
 // parsed, but nothing further will be done with it
 #[cfg(bogus)]
-pub fn main() { fail!() }
+pub fn main() { panic!() }
 
 pub fn main() {
     // Exercise some of the configured items in ways that wouldn't be possible
@@ -94,7 +94,7 @@ pub fn main() {
 
 fn test_in_fn_ctxt() {
     #[cfg(bogus)]
-    fn f() { fail!() }
+    fn f() { panic!() }
     fn f() { }
     f();
 
index 29d329d46a05a748a664c5c1e4241d0c6753af29..f87d92dc16f7f22933cbf31d2d0c0880e3625912 100644 (file)
@@ -16,6 +16,6 @@
 extern crate log;
 
 pub fn main() {
-    // only fails if println! evaluates its argument.
-    debug!("{}", { if true { fail!() } });
+    // only panics if println! evaluates its argument.
+    debug!("{}", { if true { panic!() } });
 }
index 9d09740f3b45e85620b78d9c5b84e2b4c1ad1c8e..0591828bb132b1dde473de1112095ca701eb7cf6 100644 (file)
@@ -12,8 +12,8 @@
 
 pub fn main() {
     // exits early if println! evaluates its arguments, otherwise it
-    // will hit the fail.
+    // will hit the panic.
     println!("{}", { if true { return; } });
 
-    fail!();
+    panic!();
 }
index ac2e879ceacc931b266366e665372f9f94c31ead..1b9bd5e5692af573ea06c65fae02c3bffb2d9a3e 100644 (file)
@@ -19,18 +19,18 @@ enum Foo {
 pub fn main() {
     match X {
         Baz => {}
-        _ => fail!()
+        _ => panic!()
     }
     match Y {
         Bar(s) => assert!(s == 2654435769),
-        _ => fail!()
+        _ => panic!()
     }
     match Z {
         Quux(d,h) => {
             assert_eq!(d, 0x123456789abcdef0);
             assert_eq!(h, 0x1234);
         }
-        _ => fail!()
+        _ => panic!()
     }
 }
 
index eaca18be93a1368f469a087af9b5d5f040a9c07b..465830c6e129829dbb6d029640343cc0e1405514 100644 (file)
@@ -15,7 +15,7 @@ impl E {
     pub fn method(&self) {
         match *self {
             V => {}
-            VV(..) => fail!()
+            VV(..) => panic!()
         }
     }
 }
index ee7e3c7c66300ec85b7963e2506c650670a5f0bf..4cad4acf147fff812cb5d68d881ede086885d457 100644 (file)
@@ -14,7 +14,7 @@ enum E { V, VV(int) }
 fn f(a: &E) {
     match *a {
         V => {}
-        VV(..) => fail!()
+        VV(..) => panic!()
     }
 }
 
index c1e3889d613d922dfcd3bd5f6a2ae3d869492379..02d8fcf201d83937c9cd33427a2c37568b75f2cf 100644 (file)
@@ -14,6 +14,6 @@ enum E { V0, V1(int) }
 pub fn main() {
     match *C {
         V0 => (),
-        _ => fail!()
+        _ => panic!()
     }
 }
index c4e36ba7b4e39d2432bca9299fd3ca2b41dca4a2..3cd7db69f074afacbbd426986cd84239818a2e1c 100644 (file)
@@ -19,7 +19,7 @@ enum E {
 
 pub fn main() {
     match C {
-        S0 { .. } => fail!(),
+        S0 { .. } => panic!(),
         S1 { u } => assert!(u == 23)
     }
 }
index 2a00daa3c038c53ce173f07c5fbaf681f9e524b9..9177cad9d62411658a808a6c81ffea2aba047f46 100644 (file)
@@ -19,19 +19,19 @@ enum E { V1(int), V0 }
 pub fn main() {
     match C0 {
         V0 => (),
-        _ => fail!()
+        _ => panic!()
     }
     match C1 {
         V1(n) => assert!(n == 0xDEADBEE),
-        _ => fail!()
+        _ => panic!()
     }
 
     match D0 {
         V0 => (),
-        _ => fail!()
+        _ => panic!()
     }
     match D1 {
         V1(n) => assert!(n == 0xDEADBEE),
-        _ => fail!()
+        _ => panic!()
     }
 }
index 95c4ed836c7698610affe5f2bd1f2972900e8714..8723b2815dabe46a6e32ed2847ffc1cc2fc9e7e6 100644 (file)
@@ -14,10 +14,10 @@ enum E { V1(int), V0 }
 pub fn main() {
     match C[1] {
         V1(n) => assert!(n == 0xDEADBEE),
-        _ => fail!()
+        _ => panic!()
     }
     match C[2] {
         V0 => (),
-        _ => fail!()
+        _ => panic!()
     }
 }
index 3dc5b918f7f583db6518f2c6b8093caeae0db652..e94e1de2e2d1eca5cdd0dd8680531a0c68145cf0 100644 (file)
@@ -14,10 +14,10 @@ enum E { V1(int), V0 }
 pub fn main() {
     match C[1] {
         V1(n) => assert!(n == 0xDEADBEE),
-        _ => fail!()
+        _ => panic!()
     }
     match C[2] {
         V0 => (),
-        _ => fail!()
+        _ => panic!()
     }
 }
index bc61c8e9aecf5e47bba25f8abaa74e3d8f0a3e78..2d023317db623a2c3a342c938345c921b6fe9c99 100644 (file)
@@ -19,11 +19,11 @@ enum Foo {
 pub fn main() {
     match X {
         Bar => {}
-        Baz | Boo => fail!()
+        Baz | Boo => panic!()
     }
     match Y {
         Baz => {}
-        Bar | Boo => fail!()
+        Bar | Boo => panic!()
     }
 }
 
index b4a54b599fe8a680f5c18145f3f6c9072f00a1e6..d8dfb433e6d4910f36384fd5c8f1ded4330c86d7 100644 (file)
 use std::str;
 
 macro_rules! succeed( ($e:expr) => (
-    match $e { Ok(..) => {}, Err(e) => fail!("failure: {}", e) }
+    match $e { Ok(..) => {}, Err(e) => panic!("panic: {}", e) }
 ) )
 
 fn test_destroy_once() {
     let mut p = sleeper();
     match p.signal_exit() {
         Ok(()) => {}
-        Err(e) => fail!("error: {}", e),
+        Err(e) => panic!("error: {}", e),
     }
 }
 
@@ -91,7 +91,7 @@ pub fn test_destroy_actually_kills(force: bool) {
         }
     });
     match p.wait().unwrap() {
-        ExitStatus(..) => fail!("expected a signal"),
+        ExitStatus(..) => panic!("expected a signal"),
         ExitSignal(..) => tx.send(()),
     }
 }
index df5c58ff04b6d7f8cc8c0c7dad5bc9f9c86f35b9..fd59b804da3769c93bb027f19b265d14cbb9ea95 100644 (file)
@@ -9,22 +9,22 @@
 // except according to those terms.
 
 // check that the derived impls for the comparison traits shortcircuit
-// where possible, by having a type that fails when compared as the
+// where possible, by having a type that panics when compared as the
 // second element, so this passes iff the instances shortcircuit.
 
 pub struct FailCmp;
 impl PartialEq for FailCmp {
-    fn eq(&self, _: &FailCmp) -> bool { fail!("eq") }
+    fn eq(&self, _: &FailCmp) -> bool { panic!("eq") }
 }
 
 impl PartialOrd for FailCmp {
-    fn partial_cmp(&self, _: &FailCmp) -> Option<Ordering> { fail!("partial_cmp") }
+    fn partial_cmp(&self, _: &FailCmp) -> Option<Ordering> { panic!("partial_cmp") }
 }
 
 impl Eq for FailCmp {}
 
 impl Ord for FailCmp {
-    fn cmp(&self, _: &FailCmp) -> Ordering { fail!("cmp") }
+    fn cmp(&self, _: &FailCmp) -> Ordering { panic!("cmp") }
 }
 
 #[deriving(PartialEq,PartialOrd,Eq,Ord)]
index df1e4132cb737cd63d0d9918420c8311a44c534f..565e33ce01e17721a17f2e98a08f11d274fc19a1 100644 (file)
@@ -8,14 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Just testing that fail!() type checks in statement or expr
+// Just testing that panic!() type checks in statement or expr
 
 #![allow(unreachable_code)]
 
 fn f() {
-    fail!();
+    panic!();
 
-    let _x: int = fail!();
+    let _x: int = panic!();
 }
 
 pub fn main() {
index 977eaa13fc108e03b53901b11ee55a5602c1b657..6f4e927abd5da556020fb686328a3879e8ac3688 100644 (file)
@@ -44,7 +44,7 @@ fn drop(&mut self) {
                 sender.send(DestructorRan);
             }
             &FailingVariant { .. } => {
-                fail!("Failed");
+                panic!("Failed");
             }
         }
     }
index 1c9d5cd3afe4d6c2a8b997090bd864ec694e9936..dbad546ce1ae3fd1a427b91afa99d06deecaed6f 100644 (file)
@@ -28,7 +28,7 @@ pub fn main() {
 
     let x: *mut S = &mut S;
 
-    // Test we can chnage the mutability from mut to const.
+    // Test we can change the mutability from mut to const.
     let x: &T = &mut S;
     let x: *const T = &mut S;
 }
index 465529ac90941e1006bc0375aa56c3d344127f8a..c2707a1ae6e905e7c5ddba2325341432394f7a05 100644 (file)
@@ -16,7 +16,7 @@ pub struct Arr {
 
 impl Deref<[uint]> for Arr {
     fn deref(&self) -> &[uint] {
-        fail!();
+        panic!();
     }
 }
 
index a1ef12a7657fe50deaab40a2b319979f3e1dca0f..27560986e02532a45fd9bf5362064459aa857134 100644 (file)
@@ -24,7 +24,7 @@ fn is_aligned<T>(ptr: &T) -> bool {
 pub fn main() {
     let x = Some(0u64);
     match x {
-        None => fail!(),
+        None => panic!(),
         Some(ref y) => assert!(is_aligned(y))
     }
 }
index 24fb503aea3a96ebf549fe9892d789aa0f1272a1..d6cdce7390a6097f2deaef14af8f3d7a7c87afe6 100644 (file)
@@ -20,6 +20,6 @@ pub fn main() {
     match Cons(10i, box Nil) {
         Cons(10i, _) => {}
         Nil => {}
-        _ => fail!()
+        _ => panic!()
     }
 }
index 8e56011e6dcec71da8d7416d2600fd5cfa852404..0dd7ddc3f846a9e2ee05c2164eaa1152a589a934 100644 (file)
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// When all branches of an if expression result in fail, the entire if
-// expression results in fail.
+// When all branches of an if expression result in panic, the entire if
+// expression results in panic.
 pub fn main() {
     let _x = if true {
         10i
     } else {
-        if true { fail!() } else { fail!() }
+        if true { panic!() } else { panic!() }
     };
 }
index e9f116fcdd4259a78ad6e443f0e8f6347f25d04d..aa4240c60f1dfcdcbda217723eb8cc69fd3b4034 100644 (file)
@@ -8,19 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn test_if_fail() {
-    let x = if false { fail!() } else { 10i };
+fn test_if_panic() {
+    let x = if false { panic!() } else { 10i };
     assert!((x == 10));
 }
 
-fn test_else_fail() {
-    let x = if true { 10i } else { fail!() };
+fn test_else_panic() {
+    let x = if true { 10i } else { panic!() };
     assert_eq!(x, 10i);
 }
 
-fn test_elseif_fail() {
-    let x = if false { 0i } else if false { fail!() } else { 10i };
+fn test_elseif_panic() {
+    let x = if false { 0i } else if false { panic!() } else { 10i };
     assert_eq!(x, 10i);
 }
 
-pub fn main() { test_if_fail(); test_else_fail(); test_elseif_fail(); }
+pub fn main() { test_if_panic(); test_else_panic(); test_elseif_panic(); }
index 0d23098d8fc77b94634726296da3765a9e671c11..3b33c18bbbd59bd6e8c843854ecfae1d6b9cc99d 100644 (file)
 
 
 
-// When all branches of a match expression result in fail, the entire
-// match expression results in fail.
+// When all branches of a match expression result in panic, the entire
+// match expression results in panic.
 pub fn main() {
     let _x =
         match true {
           true => { 10i }
-          false => { match true { true => { fail!() } false => { fail!() } } }
+          false => { match true { true => { panic!() } false => { panic!() } } }
         };
 }
index 1f246581687b1317cf4bcfd3d2d6a5aa87676f0b..d8ee21dfdc6b963fe8682d545f9abef6351795c4 100644 (file)
 
 
 fn test_simple() {
-    let r = match true { true => { true } false => { fail!() } };
+    let r = match true { true => { true } false => { panic!() } };
     assert_eq!(r, true);
 }
 
 fn test_box() {
-    let r = match true { true => { vec!(10i) } false => { fail!() } };
+    let r = match true { true => { vec!(10i) } false => { panic!() } };
     assert_eq!(r[0], 10i);
 }
 
index e2f8f7c8ebf0a6348b4fc267cefa6bb00e59ce81..aed4024b5bc5cb140490c32c2a60db94636bf871 100644 (file)
@@ -14,7 +14,7 @@
 fn test_generic<T:Clone>(expected: Box<T>, eq: compare<T>) {
     let actual: Box<T> = match true {
         true => { expected.clone() },
-        _ => fail!("wat")
+        _ => panic!("wat")
     };
     assert!((eq(expected, actual)));
 }
index a9b02a6e79938ee7ec8e662201166ddb67ed38b6..89adef378f1a1dabc6aa48639bd80a7cf22c0967 100644 (file)
@@ -14,7 +14,7 @@
 fn test_generic<T:Clone>(expected: T, eq: compare<T>) {
     let actual: T = match true {
         true => expected.clone(),
-        _ => fail!("wat")
+        _ => panic!("wat")
     };
     assert!((eq(expected, actual)));
 }
index ff19862fee3435e4ab49a9d693c8250eeec7804b..c74caf4de4bdc252faf11238f4bfcbd0062d5321 100644 (file)
@@ -12,7 +12,7 @@
 type compare<T> = extern "Rust" fn(T, T) -> bool;
 
 fn test_generic<T:Clone>(expected: T, eq: compare<T>) {
-  let actual: T = match true { true => { expected.clone() }, _ => fail!("wat") };
+  let actual: T = match true { true => { expected.clone() }, _ => panic!("wat") };
     assert!((eq(expected, actual)));
 }
 
index 3d01c6653a7a002bc082e5dbaf22c50dfd89af0e..21b0c28495e6b93a02dfda1618cac1b6c6072f24 100644 (file)
@@ -16,7 +16,7 @@
 struct R { i: int }
 
 fn test_rec() {
-    let rs = match true { true => R {i: 100}, _ => fail!() };
+    let rs = match true { true => R {i: 100}, _ => panic!() };
     assert_eq!(rs.i, 100);
 }
 
index 3ee0a232d19c06377253a9bd04172a5730bfa4e3..83f2ada02b0ffd60b20b00b660b669720bb1a467 100644 (file)
@@ -11,7 +11,7 @@
 
 // Tests for match as expressions resulting in boxed types
 fn test_box() {
-    let res = match true { true => { box 100i }, _ => fail!() };
+    let res = match true { true => { box 100i }, _ => panic!() };
     assert_eq!(*res, 100i);
 }
 
index 3faa30c4c8a20e896e0d17e594bdfdffedea91c0..2f0d6cf90aa5a16af38112ab00d13c1f21647e18 100644 (file)
@@ -16,7 +16,7 @@
 impl Drop for Foo {
     fn drop(&mut self) {
         unsafe { DROPS += 1; }
-        fail!()
+        panic!()
     }
 }
 
index be4a497989ce8d239ed6f2d1a1e19c88ca65a4a9..46924c74a8c46d71eabad6c0591152b1e08d18ba 100644 (file)
@@ -22,7 +22,7 @@ struct B {
 
 impl Drop for A {
     fn drop(&mut self) {
-        fail!()
+        panic!()
     }
 }
 
index c0f6b14dc27489f031813b1f8215a7d6de779830..d157da3139fdb4bf9a57365cc9b6a16227a5d699 100644 (file)
@@ -9,4 +9,4 @@
 // except according to those terms.
 
 
-pub fn main() { let x: Vec<int> = Vec::new(); for _ in x.iter() { fail!("moop"); } }
+pub fn main() { let x: Vec<int> = Vec::new(); for _ in x.iter() { panic!("moop"); } }
index afa4b7a1ad0be5a747de69a0ee2e6076f843fb86..a3df98afcb0c52e39c06908bdc7f315065f87b49 100644 (file)
@@ -19,7 +19,7 @@ pub fn main() {
     match getopts(args.as_slice(), opts.as_slice()) {
         Ok(ref m)  =>
             assert!(!m.opt_present("b")),
-        Err(ref f) => fail!("{}", *f)
+        Err(ref f) => panic!("{}", *f)
     };
 
 }
index abb0bdab71f8b72498993ebfd528fc940386b216..53c081ff83e0e906b354731a5b75cdd8706f47d7 100644 (file)
@@ -35,23 +35,23 @@ pub fn main() {
     'x: for _ in range(0i, 1) {
         // this 'x should refer to the outer loop, lexically
         loop_x!(break 'x);
-        fail!("break doesn't act hygienically inside for loop");
+        panic!("break doesn't act hygienically inside for loop");
     }
 
     'x: loop {
         // ditto
         loop_x!(break 'x);
-        fail!("break doesn't act hygienically inside infinite loop");
+        panic!("break doesn't act hygienically inside infinite loop");
     }
 
     'x: while 1i + 1 == 2 {
         while_x!(break 'x);
-        fail!("break doesn't act hygienically inside infinite while loop");
+        panic!("break doesn't act hygienically inside infinite while loop");
     }
 
     'x: for _ in range(0i, 1) {
         // ditto
         run_once!(continue 'x);
-        fail!("continue doesn't act hygienically inside for loop");
+        panic!("continue doesn't act hygienically inside for loop");
     }
 }
index bfe3e9beddc54c4a33718376c9a7d447a0a9f1dc..44c834d233fe7f02d45fce3dc112a8c46140c676 100644 (file)
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 pub fn main() {
-    let i: int = if false { fail!() } else { 5 };
+    let i: int = if false { panic!() } else { 5 };
     println!("{}", i);
 }
index 22b5281ef38f04b07d7617e70f77bed03edb29ec..660a6147d08d432e7b100b540f59fdd9e7f2d280 100644 (file)
@@ -18,7 +18,7 @@ fn foo(x: uint) {
     if even(x) {
         println!("{}", x);
     } else {
-        fail!();
+        panic!();
     }
 }
 
index 4bf3a85677c7216f13b9161f5c66f409fa006ad9..a07b783278672558d97454216e5d865d2e988035 100644 (file)
@@ -15,7 +15,7 @@ pub fn main() {
     if let Some(y) = x {
         assert_eq!(y, 3i);
     } else {
-        fail!("if-let failed");
+        panic!("if-let panicked");
     }
     let mut worked = false;
     if let Some(_) = x {
@@ -35,9 +35,9 @@ pub fn main() {
     assert_eq!(clause, 4u);
 
     if 3i > 4 {
-        fail!("bad math");
+        panic!("bad math");
     } else if let 1 = 2i {
-        fail!("bad pattern match");
+        panic!("bad pattern match");
     }
 
     enum Foo {
@@ -48,22 +48,22 @@ enum Foo {
 
     let foo = Three("three".to_string(), 42i);
     if let One = foo {
-        fail!("bad pattern match");
+        panic!("bad pattern match");
     } else if let Two(_x) = foo {
-        fail!("bad pattern match");
+        panic!("bad pattern match");
     } else if let Three(s, _) = foo {
         assert_eq!(s.as_slice(), "three");
     } else {
-        fail!("bad else");
+        panic!("bad else");
     }
 
     if false {
-        fail!("wat");
+        panic!("wat");
     } else if let a@Two(_) = Two(42u) {
         if let Two(b) = a {
             assert_eq!(b, 42u);
         } else {
-            fail!("fail in nested if-let");
+            panic!("panic in nested if-let");
         }
     }
 }
index 416c070180454e4b4cec12686f596bf3b5b5062c..6643636c5704d8afba613a1fcff4f53271a3bb7f 100644 (file)
@@ -13,7 +13,7 @@
 impl Foo {
     #[allow(dead_code)]
     fn foo(self) {
-        fail!("wrong method!")
+        panic!("wrong method!")
     }
 }
 
index 796fae7dc329808ac6b2d7f23170f9ffc948d497..1aa9c96de1a9418f66ae165e73fd98cac338e52e 100644 (file)
@@ -11,8 +11,8 @@
 struct A { foo: int }
 struct B { a: int, b: int, c: int }
 
-fn mka() -> A { fail!() }
-fn mkb() -> B { fail!() }
+fn mka() -> A { panic!() }
+fn mkb() -> B { panic!() }
 
 fn test() {
     let A { foo, } = mka();
index a30cf71732851c2ebcbb7617696510be94fa4e93..1c267f48337525910e2dc6858c01d824721471bc 100644 (file)
@@ -35,7 +35,7 @@ pub fn main() {
 
     // An `if false {} else { expr }` statement should compile the same as `{ expr }`.
     if false {
-        fail!();
+        panic!();
     } else {
         let _a = Foo{ dropped: false };
     }
index 53659a72132ef7b6a0726ee18eaefae158f81cb7..f08805fe49c2c9c7ae74e3e3db39f7de49cccb68 100644 (file)
 
 struct Empty;
 
-impl Iterator<int> for Empty {
+trait T<U> {
+    fn next(&mut self) -> Option<U>;
+}
+impl T<int> for Empty {
     fn next(&mut self) -> Option<int> { None }
 }
 
-fn do_something_with(a : &mut Iterator<int>) {
+fn do_something_with(a : &mut T<int>) {
     println!("{}", a.next())
 }
 
index 42b5bbc8623e40c6d54823ec30430798d27b4b68..106bb7f701c9631eb4c90eb54c52c894e36785e8 100644 (file)
@@ -20,7 +20,7 @@ fn fas(n: &Noun) -> Noun
 {
     match n {
         &Cell(box Atom(2), box Cell(ref a, _)) => (**a).clone(),
-        _ => fail!("Invalid fas pattern")
+        _ => panic!("Invalid fas pattern")
     }
 }
 
index d299b853aeeb195353235a0ca091f9b26a747f7e..0567a5836abfae4bfd0a9b75db64462aa449dc3a 100644 (file)
 
 // ignore-pretty
 
-// Don't fail on blocks without results
+// Don't panic on blocks without results
 // There are several tests in this run-pass that raised
 // when this bug was opened. The cases where the compiler
-// failed before the fix have a comment.
+// panics before the fix have a comment.
 
 struct S {x:()}
 
@@ -31,8 +31,8 @@ fn not(b: bool) -> bool {
     if b {
         !b
     } else {
-        // `fail!(...)` would break
-        fail!("Break the compiler");
+        // `panic!(...)` would break
+        panic!("Break the compiler");
     }
 }
 
diff --git a/src/test/run-pass/issue-12028.rs b/src/test/run-pass/issue-12028.rs
new file mode 100644 (file)
index 0000000..4d64103
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait Hash<H> {
+    fn hash2(&self, hasher: &H) -> u64;
+}
+
+trait Stream {
+    fn input(&mut self, bytes: &[u8]);
+    fn result(&self) -> u64;
+}
+
+trait StreamHasher<S: Stream> {
+    fn stream(&self) -> S;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+trait StreamHash<S: Stream, H: StreamHasher<S>>: Hash<H> {
+    fn input_stream(&self, stream: &mut S);
+}
+
+impl<S: Stream, H: StreamHasher<S>> Hash<H> for u8 {
+    fn hash2(&self, hasher: &H) -> u64 {
+        let mut stream = hasher.stream();
+        self.input_stream(&mut stream);
+        stream.result()
+    }
+}
+
+impl<S: Stream, H: StreamHasher<S>> StreamHash<S, H> for u8 {
+    fn input_stream(&self, stream: &mut S) {
+        stream.input([*self]);
+    }
+}
+
+fn main() {}
index 1a909db92e3283711fc00a60061fd0b116065d43..0e42bdbd6add7c9b44e42b10d9d789837866cc6c 100644 (file)
@@ -32,7 +32,7 @@ pub fn test() {
             FormatMessageW(0x1000, 0 as *mut c_void, 1, 0x400,
                            buf.as_mut_ptr(), buf.len() as u32, 0 as *const c_void)
         };
-        // On some 32-bit Windowses (Win7-8 at least) this will fail with segmented
+        // On some 32-bit Windowses (Win7-8 at least) this will panic with segmented
         // stacks taking control of pvArbitrary
         assert!(ret != 0);
     }
index f0477817281a163a95db07bacefa90b7d46fce13..afebcb3cdfc7dae4a97b31ff6a34a0c97fd9d01d 100644 (file)
@@ -17,5 +17,4 @@ fn main() {
         unsafe { libc::exit(0 as libc::c_int); }
     });
     2u + (loop {});
-    -(loop {});
 }
index c84b1eae8e0978540ad088c3cbc02e968e9bfd12..e3cc653909f33832f5afdf4647bf517352759acd 100644 (file)
@@ -17,14 +17,14 @@ fn main() {
     let x = match Foo(42) {
         Foo(..) => 1i,
         _ if true => 0,
-        Bar(..) => fail!("Oh dear")
+        Bar(..) => panic!("Oh dear")
     };
     assert_eq!(x, 1);
 
     let x = match Foo(42) {
         _ if true => 0i,
         Foo(..) => 1,
-        Bar(..) => fail!("Oh dear")
+        Bar(..) => panic!("Oh dear")
     };
     assert_eq!(x, 0);
 }
diff --git a/src/test/run-pass/issue-14901.rs b/src/test/run-pass/issue-14901.rs
new file mode 100644 (file)
index 0000000..f93347f
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::io::Reader;
+
+enum Wrapper<'a> {
+    WrapReader(&'a Reader + 'a)
+}
+
+trait Wrap<'a> {
+    fn wrap(self) -> Wrapper<'a>;
+}
+
+impl<'a, R: Reader> Wrap<'a> for &'a mut R {
+    fn wrap(self) -> Wrapper<'a> {
+        WrapReader(self as &'a mut Reader)
+    }
+}
+
+pub fn main() {}
index 3aaa480d776c23845ab8b86a26c5630ff0e56d30..3c5af9ca032c100df1112e981c02075ff253f3f7 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 pub fn main() {
-    let early_error: |&str|: 'static -> ! = |_msg| { fail!() };
+    let early_error: |&str|: 'static -> ! = |_msg| { panic!() };
 }
index 6e3599bda149acf5c9621061bc05c960842424bd..0c09e456930c2d83f3d2b6debdfd4f953a6c1dc9 100644 (file)
@@ -60,16 +60,16 @@ fn dd() -> Result<int, int> {
 }
 
 trait A {
-    fn aaa(self) -> int {
+    fn aaa(&self) -> int {
         3
     }
-    fn bbb(self) -> int {
+    fn bbb(&self) -> int {
         return 3;
     }
-    fn ccc(self) -> Result<int, int> {
+    fn ccc(&self) -> Result<int, int> {
         Ok(3)
     }
-    fn ddd(self) -> Result<int, int> {
+    fn ddd(&self) -> Result<int, int> {
         return Ok(3);
     }
 }
diff --git a/src/test/run-pass/issue-16560.rs b/src/test/run-pass/issue-16560.rs
new file mode 100644 (file)
index 0000000..77eba02
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(unboxed_closures)]
+
+use std::mem;
+
+fn main() {
+    let y = 0u8;
+    let closure = move |&: x| y + x;
+
+    // Check that both closures are capturing by value
+    assert_eq!(1, mem::size_of_val(&closure));
+
+    spawn(proc() {
+        let ok = closure;
+    })
+}
diff --git a/src/test/run-pass/issue-16668.rs b/src/test/run-pass/issue-16668.rs
new file mode 100644 (file)
index 0000000..b66fb43
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-pretty
+
+#![feature(unboxed_closures)]
+
+struct Parser<'a, I, O> {
+    parse: Box<FnMut<(I,), Result<O, String>> + 'a>
+}
+
+impl<'a, I, O: 'a> Parser<'a, I, O> {
+    fn compose<K: 'a>(mut self, mut rhs: Parser<O, K>) -> Parser<'a, I, K> {
+        Parser {
+            parse: box move |&mut: x: I| {
+                match self.parse.call_mut((x,)) {
+                    Ok(r) => rhs.parse.call_mut((r,)),
+                    Err(e) => Err(e)
+                }
+            }
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/test/run-pass/issue-17361.rs b/src/test/run-pass/issue-17361.rs
new file mode 100644 (file)
index 0000000..fa38dcc
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that astconv doesn't forget about mutability of &mut str
+
+fn main() {
+    fn foo<Sized? T>(_: &mut T) {}
+    let _f: fn(&mut str) = foo;
+}
diff --git a/src/test/run-pass/issue-17458.rs b/src/test/run-pass/issue-17458.rs
deleted file mode 100644 (file)
index a32a31e..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static X: uint = 0 as *const uint as uint;
-
-fn main() {
-    assert_eq!(X, 0);
-}
diff --git a/src/test/run-pass/issue-18352.rs b/src/test/run-pass/issue-18352.rs
new file mode 100644 (file)
index 0000000..7878d69
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+const X: &'static str = "12345";
+
+fn test(s: String) -> bool {
+    match s.as_slice() {
+        X => true,
+        _ => false
+    }
+}
+
+fn main() {
+    assert!(test("12345".to_string()));
+}
index b03bfb958af1b2af92258db09dad4f7471aa6ba5..e0b98ab19652a40e302c4c5ef0d470aecffea249 100644 (file)
@@ -15,7 +15,7 @@ struct foo<A> {
 
 impl<A> foo<A> {
    pub fn bar<B,C:clam<A>>(&self, _c: C) -> B {
-     fail!();
+     panic!();
    }
 }
 
index 14b5efe904db8c4b5036704f50bac4c728abec23..8c597552d75aadb81a502a9e1050c5dab682d7e9 100644 (file)
@@ -15,7 +15,7 @@ trait clam<A> { }
 struct foo(int);
 
 impl foo {
-    pub fn bar<B,C:clam<B>>(&self, _c: C) -> B { fail!(); }
+    pub fn bar<B,C:clam<B>>(&self, _c: C) -> B { panic!(); }
 }
 
 pub fn main() { }
index 8a9e2d28776a78fb3e0309075b86bf914f8ee1c4..2608c89d15567d1a6d83739150c5a250ad2209dd 100644 (file)
@@ -20,7 +20,7 @@ struct E {
 }
 
 impl A for E {
-  fn b<F,G>(_x: F) -> F { fail!() }
+  fn b<F,G>(_x: F) -> F { panic!() }
   //~^ ERROR in method `b`, type parameter 0 has 1 bound, but
 }
 
index c52dd5ce5e4e34aca6dbb7f81d517e4588413237..cb17b7f6a6cc032472a1b17fb55dc3f0d0c352dc 100644 (file)
@@ -56,9 +56,9 @@ pub fn packet<T:Send>() -> *const packet<T> {
     }
 
     mod rusti {
-      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!(); }
+      pub fn atomic_xchg(_dst: &mut int, _src: int) -> int { panic!(); }
+      pub fn atomic_xchg_acq(_dst: &mut int, _src: int) -> int { panic!(); }
+      pub fn atomic_xchg_rel(_dst: &mut int, _src: int) -> int { panic!(); }
     }
 
     // We should consider moving this to ::std::unsafe, although I
@@ -92,7 +92,7 @@ pub fn send<T:Send>(mut p: send_packet<T>, payload: T) {
             // The receiver will eventually clean this up.
             unsafe { forget(p); }
           }
-          full => { fail!("duplicate send") }
+          full => { panic!("duplicate send") }
           blocked => {
 
             // The receiver will eventually clean this up.
@@ -134,7 +134,7 @@ pub fn sender_terminate<T:Send>(p: *const packet<T>) {
           }
           full => {
             // This is impossible
-            fail!("you dun goofed")
+            panic!("you dun goofed")
           }
           terminated => {
             // I have to clean up, use drop_glue
@@ -151,7 +151,7 @@ pub fn receiver_terminate<T:Send>(p: *const packet<T>) {
           }
           blocked => {
             // this shouldn't happen.
-            fail!("terminating a blocked packet")
+            panic!("terminating a blocked packet")
           }
           terminated | full => {
             // I have to clean up, use drop_glue
@@ -236,7 +236,7 @@ pub fn liberate_ping(p: ping) -> ::pipes::send_packet<pong> {
             let _addr : *const ::pipes::send_packet<pong> = match &p {
               &ping(ref x) => { mem::transmute(x) }
             };
-            fail!()
+            panic!()
         }
     }
 
@@ -245,7 +245,7 @@ pub fn liberate_pong(p: pong) -> ::pipes::send_packet<ping> {
             let _addr : *const ::pipes::send_packet<ping> = match &p {
               &pong(ref x) => { mem::transmute(x) }
             };
-            fail!()
+            panic!()
         }
     }
 
@@ -269,7 +269,7 @@ pub fn do_ping(c: ping) -> pong {
         pub fn do_pong(c: pong) -> (ping, ()) {
             let packet = ::pipes::recv(c);
             if packet.is_none() {
-                fail!("sender closed the connection")
+                panic!("sender closed the connection")
             }
             (pingpong::liberate_pong(packet.unwrap()), ())
         }
@@ -284,7 +284,7 @@ pub mod server {
         pub fn do_ping(c: ping) -> (pong, ()) {
             let packet = ::pipes::recv(c);
             if packet.is_none() {
-                fail!("sender closed the connection")
+                panic!("sender closed the connection")
             }
             (pingpong::liberate_ping(packet.unwrap()), ())
         }
index 1964001cebd8e7971fe63000e6230b490a53276d..04866c56913b1cfb6f1bd252e25d1b1365eadb3c 100644 (file)
@@ -53,7 +53,7 @@ fn square_from_char(c: char) -> square {
       ' '  => { empty }
       _ => {
         println!("invalid square: {}", c);
-        fail!()
+        panic!()
       }
     }
 }
index efe0cb8d491d9fa4dd8c289a97830c626db7a536..ee075db272350933f13225e6e0a1a27a60081bd1 100644 (file)
@@ -13,6 +13,6 @@ enum State { BadChar, BadSyntax }
 
     match BadChar {
         _ if true => BadChar,
-        BadChar | BadSyntax => fail!() ,
+        BadChar | BadSyntax => panic!() ,
     };
 }
index 20b818f47d47749fd636244232f7cf2a0f4417c0..e5cc8414f064b631ff04e8ad192022209efc8e04 100644 (file)
@@ -19,7 +19,7 @@ fn exec<T: JD>() {
     let doc = json::from_str("").unwrap();
     let mut decoder = json::Decoder::new(doc);
     let _v: T = Decodable::decode(&mut decoder).unwrap();
-    fail!()
+    panic!()
 }
 
 pub fn main() {}
index d8c08f8ac321487967b097190bd5d245921e356f..3130c0441a5bd279ca1b89c8ce7093f9248b8a24 100644 (file)
@@ -48,7 +48,7 @@ enum Result {
         let v = match io.read_char() {
             '$' => parse_bulk(io),
             ':' => parse_int(io),
-             _ => fail!()
+             _ => panic!()
         };
         list.push(v);
     }
@@ -61,26 +61,26 @@ enum Result {
 
 priv fn parse_bulk(io: @io::Reader) -> Result {
     match from_str::<int>(chop(io.read_line())) {
-    None => fail!(),
+    None => panic!(),
     Some(-1) => Nil,
     Some(len) if len >= 0 => parse_data(len as uint, io),
-    Some(_) => fail!()
+    Some(_) => panic!()
     }
 }
 
 priv fn parse_multi(io: @io::Reader) -> Result {
     match from_str::<int>(chop(io.read_line())) {
-    None => fail!(),
+    None => panic!(),
     Some(-1) => Nil,
     Some(0) => List(~[]),
     Some(len) if len >= 0 => parse_list(len as uint, io),
-    Some(_) => fail!()
+    Some(_) => panic!()
     }
 }
 
 priv fn parse_int(io: @io::Reader) -> Result {
     match from_str::<int>(chop(io.read_line())) {
-    None => fail!(),
+    None => panic!(),
     Some(i) => Int(i)
     }
 }
@@ -92,7 +92,7 @@ enum Result {
     '+' => Status(chop(io.read_line())),
     '-' => Error(chop(io.read_line())),
     ':' => parse_int(io),
-    _ => fail!()
+    _ => panic!()
     }
 }
 
index be75c7230427bed3ee5513a092af43b7d3ee909c..fb0e8e599eb2af9477cdbffce70a292b28b7ffd4 100644 (file)
@@ -15,7 +15,7 @@
 
 fn bar(a: foo::map) {
     if false {
-        fail!();
+        panic!();
     } else {
         let _b = &(*a)[2];
     }
index 29775e4a69921ef873a3aaea1d4e8f113d0a9100..4b31f39330932e2b84dc6ef2845f7009430345a8 100644 (file)
@@ -19,7 +19,7 @@ trait Graph<Node, Edge> {
 
 impl<E> Graph<int, E> for HashMap<int, int> {
     fn f(&self, _e: E) {
-        fail!();
+        panic!();
     }
 }
 
index 48e2890b2594fbd231f05f2e2af080b31a533826..5a6dea8d15bff6ecb745d58499f1421fa7ceb5ef 100644 (file)
@@ -20,25 +20,25 @@ enum Other {
 
 fn main() {
     match Baz {
-        ::Bar(3) => fail!(),
-        ::Bar(_) if false => fail!(),
-        ::Bar(..) if false => fail!(),
-        ::Bar(_n) => fail!(),
+        ::Bar(3) => panic!(),
+        ::Bar(_) if false => panic!(),
+        ::Bar(..) if false => panic!(),
+        ::Bar(_n) => panic!(),
         ::Baz => {}
     }
     match Bar(3) {
         ::Bar(3) => {}
-        ::Bar(_) if false => fail!(),
-        ::Bar(..) if false => fail!(),
-        ::Bar(_n) => fail!(),
-        ::Baz => fail!(),
+        ::Bar(_) if false => panic!(),
+        ::Bar(..) if false => panic!(),
+        ::Bar(_n) => panic!(),
+        ::Baz => panic!(),
     }
     match Bar(4) {
-        ::Bar(3) => fail!(),
-        ::Bar(_) if false => fail!(),
-        ::Bar(..) if false => fail!(),
+        ::Bar(3) => panic!(),
+        ::Bar(_) if false => panic!(),
+        ::Bar(..) if false => panic!(),
         ::Bar(n) => assert_eq!(n, 4),
-        ::Baz => fail!(),
+        ::Baz => panic!(),
     }
 
     match Other1(Baz) {
index ac389c8e4947af55123ec5304fcff7146a2c7333..c1d5bb0961bbafa690a984fc7d654785d5096918 100644 (file)
@@ -18,8 +18,8 @@ enum E {
 pub fn main() {
     let e = Foo{f: 0};
     match e {
-        Foo{f: 1} => fail!(),
+        Foo{f: 1} => panic!(),
         Foo{..} => (),
-        _ => fail!(),
+        _ => panic!(),
     }
 }
index 9ce24200d690b0a8eb15f9e419d0f83e0e40fd87..28b37826812a35ea0588c3cff5390d439eea442e 100644 (file)
@@ -18,8 +18,8 @@ enum E {
 pub fn main() {
     let e = Foo{f: 0, b: false};
     match e {
-        Foo{f: 1, b: true} => fail!(),
+        Foo{f: 1, b: true} => panic!(),
         Foo{b: false, f: 0} => (),
-        _ => fail!(),
+        _ => panic!(),
     }
 }
index 05bf8e01c5874f6dd73efe95988b1df58c95c9aa..c0dcf9e609418a4839dca2cc60e60769774a058f 100644 (file)
@@ -15,7 +15,7 @@ fn lp<T>(s: String, f: |String| -> T) -> T {
         let r = f(s);
         return (r);
     }
-    fail!();
+    panic!();
 }
 
 fn apply<T>(s: String, f: |String| -> T) -> T {
index 7975af434d2846339e1a8f9196ecdd17caf34697..4b97d274fbae420f453df14d18fefd9ef127fcb3 100644 (file)
@@ -17,6 +17,6 @@
 
 pub fn main() {
     if log_enabled!(log::DEBUG) {
-        fail!("what?! debugging?");
+        panic!("what?! debugging?");
     }
 }
index 184ac713c899bfa178e0dd1f5ea2193f7d44344a..c4f7b1492ab57e1c20903c8f964d8c7aa590a211 100644 (file)
@@ -16,9 +16,9 @@
 
 pub fn main() {
     if log_enabled!(log::DEBUG) {
-        fail!("what?! debugging?");
+        panic!("what?! debugging?");
     }
     if !log_enabled!(log::INFO) {
-        fail!("what?! no info?");
+        panic!("what?! no info?");
     }
 }
index 31c2ae891e068832368599ba1a54f60872bb615a..ced1fdc4455194f734595ed133c8c3d6b7fb4eef 100644 (file)
 // monomorphized functions from other crates had logging turned on (their
 // logging module names were all incorrect). This test ensures that this no
 // longer happens by enabling logging for *this* crate and then invoking a
-// function in an external crate which will fail when logging is enabled.
+// function in an external crate which will panic when logging is enabled.
 
 extern crate logging_right_crate;
 
 pub fn main() {
-    // this function fails if logging is turned on
+    // this function panicks if logging is turned on
     logging_right_crate::foo::<int>();
 }
index 14aee4c3be81d001e25ab0dc0a5d5ccb1ed0a597..0f4dd881698a4198a1f0e101d593f54ce55dd009 100644 (file)
@@ -13,7 +13,7 @@
 impl Drop for S { fn drop(&mut self) { } }
 
 // user-defined function "returning" bottom (i.e. no return at all).
-fn my_fail() -> ! { loop {} }
+fn my_panic() -> ! { loop {} }
 
 pub fn step(f: bool) {
     let mut g = S;
@@ -30,7 +30,7 @@ pub fn step(f: bool) {
             continue;
         }
 
-        my_fail();
+        my_panic();
 
         // we never get here, so we do not need to re-initialize g.
     }
index 76fc05deb0eae69ecc522096d2e3e9aefcd1ab09..672efa68398ec8923598287099a13e49e3047799 100644 (file)
@@ -18,7 +18,7 @@ fn $fnname($arg: $ty) -> Option<$ty> $body
           Some($pat) => {
             $res
           }
-          _ => { fail!(); }
+          _ => { panic!(); }
         }
     })
 
index f3c299bd1f9138c9a9469b8fcc076f417d11fc02..5b48d0ff5080988cf30d5c917fc9ece76de87c69 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 // n.b. This was only ever failing with optimization disabled.
-fn a() -> int { match return 1i { 2i => 3i, _ => fail!() } }
+fn a() -> int { match return 1i { 2i => 3i, _ => panic!() } }
 pub fn main() { a(); }
index 7e55e227cc07b660dadcf1e0896c90687cae503d..74cf3faea46ee1646441319f0f7debae7b5a7fe3 100644 (file)
@@ -11,6 +11,6 @@
 
 pub fn main() {
     let i: int =
-        match Some::<int>(3) { None::<int> => { fail!() } Some::<int>(_) => { 5 } };
+        match Some::<int>(3) { None::<int> => { panic!() } Some::<int>(_) => { 5 } };
     println!("{}", i);
 }
index fef7555af5e4209271d49d20b8096deba231fb7b..6b18f3c19da2b0a3b7896c502df1c7de49c21a30 100644 (file)
@@ -20,7 +20,7 @@ enum E {
 pub fn main() {
     let e = Bar;
     match e {
-        Foo{f: _f} => fail!(),
+        Foo{f: _f} => panic!(),
         _ => (),
     }
 }
index 12902fb738e97a5d43c379c7926c37f18c8d6edd..451b8f63e9576f8a7f2ad86e40562465ee8f305b 100644 (file)
@@ -19,10 +19,10 @@ pub fn main() {
     let e = Foo{f: 1};
     match e {
         Foo{..} => (),
-        _ => fail!(),
+        _ => panic!(),
     }
     match e {
         Foo{f: _f} => (),
-        _ => fail!(),
+        _ => panic!(),
     }
 }
index 9d59b197d3ab755ccf70beaaa32cf8090a70eaed..4265d0a5406aa9c59b842c54ddd5a65f762d6182 100644 (file)
@@ -14,7 +14,7 @@ fn altlit(f: int) -> int {
     match f {
       10 => { println!("case 10"); return 20; }
       11 => { println!("case 11"); return 22; }
-      _  => fail!("the impossible happened")
+      _  => panic!("the impossible happened")
     }
 }
 
index 2169e996577bf89756a9f515749638e19cc85ab9..ed2f7c5cb47c2be48952407158cc4630087febeb 100644 (file)
@@ -15,7 +15,7 @@ fn test1() {
                 assert_eq!(a, "a".to_string());
                 assert_eq!(b, "b".to_string());
             },
-            _ => fail!(),
+            _ => panic!(),
     }
 }
 
@@ -25,7 +25,7 @@ fn test2() {
             assert_eq!(a, 2);
             assert_eq!(b, 3);
         },
-        _ => fail!(),
+        _ => panic!(),
     }
 }
 
@@ -35,7 +35,7 @@ fn test3() {
             assert_eq!(*a, 2);
             assert_eq!(*b, 3);
         },
-        _ => fail!(),
+        _ => panic!(),
     }
 }
 
@@ -45,7 +45,7 @@ fn test4() {
             assert_eq!(a, 2);
             assert_eq!(b, 3);
         },
-        _ => fail!(),
+        _ => panic!(),
     }
 }
 
@@ -55,7 +55,7 @@ fn test5() {
             assert_eq!(*a, 2);
             assert_eq!(*b, 3);
         },
-        _ => fail!(),
+        _ => panic!(),
     }
 }
 
index 4761d2606fc2a9185beaa5f4ec7ffcfd5c9d437b..83066c126ce140bb94e1e5b127e07ff335ff0f02 100644 (file)
 pub fn main() {
     match 5u {
       1u...5u => {}
-      _ => fail!("should match range"),
+      _ => panic!("should match range"),
     }
     match 5u {
-      6u...7u => fail!("shouldn't match range"),
+      6u...7u => panic!("shouldn't match range"),
       _ => {}
     }
     match 5u {
-      1u => fail!("should match non-first range"),
+      1u => panic!("should match non-first range"),
       2u...6u => {}
-      _ => fail!("math is broken")
+      _ => panic!("math is broken")
     }
     match 'c' {
       'a'...'z' => {}
-      _ => fail!("should suppport char ranges")
+      _ => panic!("should suppport char ranges")
     }
     match -3i {
       -7...5 => {}
-      _ => fail!("should match signed range")
+      _ => panic!("should match signed range")
     }
     match 3.0f64 {
       1.0...5.0 => {}
-      _ => fail!("should match float range")
+      _ => panic!("should match float range")
     }
     match -1.5f64 {
       -3.6...3.6 => {}
-      _ => fail!("should match negative float range")
+      _ => panic!("should match negative float range")
     }
 }
index a07c63490e78e2624088c609056db816a6406ec3..243c87c0eeb0095221cb2d5105ee77754879691c 100644 (file)
@@ -15,7 +15,7 @@ pub fn main() {
             Some(ref z) if *z.lock() => {
                 assert!(*z.lock());
             },
-            _ => fail!()
+            _ => panic!()
         }
     }
 }
index d31f7a60715105b63b7e6d28984e86ebf2a8dded..651f56e894ac8e0b77a70b6061d16a233498665a 100644 (file)
 // Issue #53
 
 pub fn main() {
-    match "test" { "not-test" => fail!(), "test" => (), _ => fail!() }
+    match "test" { "not-test" => panic!(), "test" => (), _ => panic!() }
 
     enum t { tag1(String), tag2, }
 
 
     match tag1("test".to_string()) {
-      tag2 => fail!(),
-      tag1(ref s) if "test" != s.as_slice() => fail!(),
+      tag2 => panic!(),
+      tag1(ref s) if "test" != s.as_slice() => panic!(),
       tag1(ref s) if "test" == s.as_slice() => (),
-      _ => fail!()
+      _ => panic!()
     }
 
-    let x = match "a" { "a" => 1i, "b" => 2i, _ => fail!() };
+    let x = match "a" { "a" => 1i, "b" => 2i, _ => panic!() };
     assert_eq!(x, 1);
 
-    match "a" { "a" => { } "b" => { }, _ => fail!() }
+    match "a" { "a" => { } "b" => { }, _ => panic!() }
 
 }
index 769a5ab5460a7150c65b5b7607461373ca87ef20..6d5658aa13cbfcebc746a231053f359e761663ec 100644 (file)
@@ -15,15 +15,15 @@ struct Foo{
 pub fn main() {
     let f = Foo{f: 1};
     match f {
-        Foo{f: 0} => fail!(),
+        Foo{f: 0} => panic!(),
         Foo{..} => (),
     }
     match f {
-        Foo{f: 0} => fail!(),
+        Foo{f: 0} => panic!(),
         Foo{f: _f} => (),
     }
     match f {
-        Foo{f: 0} => fail!(),
+        Foo{f: 0} => panic!(),
         _ => (),
     }
 }
index 148c1c9f0cfafb714c52d1bf333541e31ba6dcc3..4bf91bf703523616c7948d63d0ecc226dde91531 100644 (file)
@@ -11,6 +11,6 @@
 pub fn main() {
     match -5i {
       -5 => {}
-      _ => { fail!() }
+      _ => { panic!() }
     }
 }
index 0cbe46cb4ef17e9c691da6716b17d9c4dedcd0f4..a6d932935ade6b1a227112b36af992e3a8a89974 100644 (file)
@@ -11,7 +11,7 @@
 /* This test checks that nested comments are supported
 
    /*
-     This should not fail
+     This should not panic
    */
 */
 
index 927f8160f7e4aba76ccafe98d5861978d004cff3..19eba0808c88237cdc4f5b79430a57ad24dfd238 100644 (file)
@@ -23,7 +23,7 @@ fn b(i:int) -> b {
         }
     }
 
-    //  fn b(x:int) -> int { fail!(); }
+    //  fn b(x:int) -> int { panic!(); }
 
     let z = b(42);
     assert_eq!(z.i, 42);
index fa28025afa077b3b0fa6cf9a80bff8b76dfde34e..55c1de2700f9520a31edbdf317bb1831d084c809 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn baz() -> ! { fail!(); }
+fn baz() -> ! { panic!(); }
 
 fn foo() {
     match Some::<int>(5) {
index bc03b0d27ca8dcc201bdb3371319d6de756a5aee..7fe50d667087c1b6b3126f1814af11cdc0871f4f 100644 (file)
@@ -16,7 +16,7 @@ enum t { foo(int, uint), bar(int, Option<int>), }
 
 fn nested(o: t) {
     match o {
-        bar(_i, Some::<int>(_)) => { println!("wrong pattern matched"); fail!(); }
+        bar(_i, Some::<int>(_)) => { println!("wrong pattern matched"); panic!(); }
         _ => { println!("succeeded"); }
     }
 }
index bc7987f4a27e2f893f7c17e7d3c145f860e4252a..eda36fad215fed6fac17d19f747770c6209f2325 100644 (file)
@@ -25,7 +25,7 @@ fn drop(&mut self) {
 fn main() {
     task::try::<()>(proc() {
         let _a = A;
-        fail!();
+        panic!();
     });
     assert!(unsafe { !HIT });
 }
index 9d7130ecb8c554a1a7e23ddbcc3eec4ec4a7f6c3..450034e12403b999c1807a33168de60259115f74 100644 (file)
@@ -30,7 +30,7 @@ fn is_none(&self) -> bool {
     }
     fn get_ref(&self) -> (int, &T) {
         match *self {
-            Nothing(..) => fail!("E::get_ref(Nothing::<{}>)",  stringify!(T)),
+            Nothing(..) => panic!("E::get_ref(Nothing::<{}>)",  stringify!(T)),
             Thing(x, ref y) => (x, y)
         }
     }
@@ -59,7 +59,7 @@ macro_rules! check_fancy {
         let t_ = Thing::<$T>(23, e);
         match t_.get_ref() {
             (23, $v) => { $chk }
-            _ => fail!("Thing::<{}>(23, {}).get_ref() != (23, _)",
+            _ => panic!("Thing::<{}>(23, {}).get_ref() != (23, _)",
                        stringify!($T), stringify!($e))
         }
     }}
index 8bdae89e523fd3e102c146a7cad8f712d5f488cf..71323016e835e4ed965e2bfd8a7b551054700d4e 100644 (file)
@@ -26,7 +26,7 @@ fn drop(&mut self) {
 fn unwrap<T>(o: Option<T>) -> T {
     match o {
       Some(v) => v,
-      None => fail!()
+      None => panic!()
     }
 }
 
diff --git a/src/test/run-pass/out-pointer-aliasing.rs b/src/test/run-pass/out-pointer-aliasing.rs
new file mode 100644 (file)
index 0000000..2a44df7
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub struct Foo {
+    f1: int,
+    _f2: int,
+}
+
+#[inline(never)]
+pub fn foo(f: &mut Foo) -> Foo {
+    let ret = *f;
+    f.f1 = 0;
+    ret
+}
+
+pub fn main() {
+    let mut f = Foo {
+        f1: 8,
+        _f2: 9,
+    };
+    f = foo(&mut f);
+    assert_eq!(f.f1, 8);
+}
index d047f02fe2f6585c5d96c134d09c60a0ec463953..7c6ad45a9efe1ce84088467bab71e2d3b2c872ca 100644 (file)
@@ -35,7 +35,7 @@ fn index<'a>(&'a self, index: &K) -> &'a V {
                 return &pair.value
             }
         }
-        fail!("No value found for key: {}", index);
+        panic!("No value found for key: {}", index);
     }
 }
 
index a0686e7f17f8bdc55f2a29909f8cab96522a45f1..2975b209d0690a20e550118a804134a87ad7fde8 100644 (file)
@@ -36,7 +36,7 @@ pub fn main() {
 
     let mut_s = Rc::new(RefCell::new(String::from_str("foo")));
     mut_s.borrow_mut().push_str("bar");
-    // HACK assert_eq! would fail here because it stores the LHS and RHS in two locals.
+    // HACK assert_eq! would panic here because it stores the LHS and RHS in two locals.
     assert!(mut_s.borrow().as_slice() == "foobar");
     assert!(mut_s.borrow_mut().as_slice() == "foobar");
 
index cdd56f64d273dd8899d9529c969311600d56dc5f..b63db29cf916ed97c796786a3738da82c63aaf97 100644 (file)
@@ -34,7 +34,7 @@ pub fn main() {
 
     let mut_s = Rc::new(RefCell::new(String::from_str("foo")));
     (*(*mut_s).borrow_mut()).push_str("bar");
-    // assert_eq! would fail here because it stores the LHS and RHS in two locals.
+    // assert_eq! would panic here because it stores the LHS and RHS in two locals.
     assert!((*(*mut_s).borrow()).as_slice() == "foobar");
     assert!((*(*mut_s).borrow_mut()).as_slice() == "foobar");
 
index 34c5bf0234f18c16b5af1c6a182eb5dc917ed99e..0dbba3654b689ee251ec33382af34bdd98be1503 100644 (file)
@@ -10,6 +10,6 @@
 
 #![allow(unreachable_code)]
 
-fn dont_call_me() { fail!(); println!("{}", 1i); }
+fn dont_call_me() { panic!(); println!("{}", 1i); }
 
 pub fn main() { }
index 569d4acb4c610c2087250698b75d7e64c33cfd3c..4c078a66f0882279f3ccf6c269529da989611e89 100644 (file)
@@ -44,6 +44,6 @@ fn main() {
     drop(p.stdin.take());
     match p.wait().unwrap() {
         process::ExitStatus(..) => {}
-        process::ExitSignal(..) => fail!()
+        process::ExitSignal(..) => panic!()
     }
 }
index d8f48c7e6623bb4dfb5150b4504c19b36f3a9c43..966e34dfe49c6902ae161768403ebf9dfd167608 100644 (file)
@@ -30,7 +30,7 @@ unsafe fn test_triangle() -> bool {
     let ascend = ascend.as_mut_slice();
     static ALIGN : uint = 1;
 
-    // Checks that `ascend` forms triangle of acending size formed
+    // Checks that `ascend` forms triangle of ascending size formed
     // from pairs of rows (where each pair of rows is equally sized),
     // and the elements of the triangle match their row-pair index.
     unsafe fn sanity_check(ascend: &[*mut u8]) {
index dbc5bf6626af1086d04f27562617a5f722c0681d..75c52f63041a5f037d445f1839162f11bf13904f 100644 (file)
@@ -10,7 +10,7 @@
 
 // A very limited test of the "bottom" region
 
-fn produce_static<T>() -> &'static T { fail!(); }
+fn produce_static<T>() -> &'static T { panic!(); }
 
 fn foo<T>(_x: &T) -> &uint { produce_static() }
 
index 68a451b62acc436d306de6e2ecb7047905dadc43..f074ca9a8892104175c3f39e2f193f0fd34446c5 100644 (file)
@@ -58,21 +58,21 @@ fn get_v5(a: &A, _i: uint) -> &int {
 fn get_v6_a(a: &A, _i: uint) -> &int {
     match a.value.v6 {
         Some(ref v) => &v.f,
-        None => fail!()
+        None => panic!()
     }
 }
 
 fn get_v6_b(a: &A, _i: uint) -> &int {
     match *a {
         A { value: B { v6: Some(ref v), .. } } => &v.f,
-        _ => fail!()
+        _ => panic!()
     }
 }
 
 fn get_v6_c(a: &A, _i: uint) -> &int {
     match a {
         &A { value: B { v6: Some(ref v), .. } } => &v.f,
-        _ => fail!()
+        _ => panic!()
     }
 }
 
index c732d20a1560584306400cf4fcf197f94a056d16..5de5e39a4545b39b398420baa60dc8cf78d1f802 100644 (file)
@@ -91,13 +91,13 @@ impl<'l> List<'l> {
     fn car<'m>(&'m self) -> int {
         match self {
             &Cons(car, _) => car,
-            &Null => fail!(),
+            &Null => panic!(),
         }
     }
     fn cdr<'n>(&'n self) -> &'l List<'l> {
         match self {
             &Cons(_, cdr) => cdr,
-            &Null => fail!(),
+            &Null => panic!(),
         }
     }
 }
index f6971a8b4ad30e189cc61b720ae589e78ba30a86..54458f0d0df0330d6ab054e3cc1d7e5da4042f5c 100644 (file)
@@ -11,7 +11,7 @@
 fn get<T>(opt: &Option<T>) -> &T {
     match *opt {
       Some(ref v) => v,
-      None => fail!("none")
+      None => panic!("none")
     }
 }
 
index 42e5c8731e269f45e9b30fa0eb10309e51d9bdd6..ff4932e8453e454fa4bb0fda7974fcfd383adadf 100644 (file)
@@ -11,7 +11,7 @@
 
 
 
-fn my_err(s: String) -> ! { println!("{}", s); fail!(); }
+fn my_err(s: String) -> ! { println!("{}", s); panic!(); }
 
 fn okay(i: uint) -> int {
     if i == 3u {
index 1756d74a81e1789dedd8a0c9dd6c495179b80d03..2709904fb4cac0c3bc2fd53c2dd3451f30e5caa7 100644 (file)
@@ -17,7 +17,7 @@ fn surrounding() {
         unsafe { calls += 1 }
 
         if n >= 0 { return; }
-        fail!()
+        panic!()
     };
 
     return_works(10);
@@ -28,7 +28,7 @@ fn surrounding() {
         unsafe { calls += 1 }
 
         if n >= 0 { return; }
-        fail!()
+        panic!()
     };
 
     return_works_proc(10);
index d0762d1f3d8f22dbf3928eabd5bb5a783ae7e2c8..942542a6bcdbd71543325fc663871cbcb348abdd 100644 (file)
@@ -25,12 +25,12 @@ fn start(argc: int, argv: *const *const u8) -> int {
                 1 => {}
                 2 => println!("foo"),
                 3 => assert!(try(|| {}).is_ok()),
-                4 => assert!(try(|| fail!()).is_err()),
+                4 => assert!(try(|| panic!()).is_err()),
                 5 => assert!(try(|| spawn(proc() {})).is_err()),
                 6 => assert!(Command::new("test").spawn().is_err()),
                 7 => assert!(foo.get().is_none()),
                 8 => assert!(try(|| { foo.replace(Some(3)); }).is_err()),
-                _ => fail!()
+                _ => panic!()
             }
         }
         return 0
index 5d154e02af67085e5d7808de78d1500517fb37b7..c2c7a48815cc04e3abb07bace9cd0145c3d689a8 100644 (file)
@@ -23,7 +23,7 @@ fn pad() -> uint { 0 }
 
 mod a {
     pub fn f() {
-        fail!();
+        panic!();
     }
 }
 
index 52fa8e1132e2fec927ad732a52c3ae37a0f1fe94..dc72b6b05390ba1f6ee675cfd7df934933a9f45d 100644 (file)
@@ -25,7 +25,7 @@ pub fn main() {
         match status {
             ExitSignal(_) if cfg!(unix) => {},
             ExitStatus(0xC0000028) if cfg!(windows) => {},
-            _ => fail!("invalid termination (was not signalled): {}", status)
+            _ => panic!("invalid termination (was not signalled): {}", status)
         }
     }
 }
index 65928fd7bf33292ba9dfa1de81c34610d7af8b16..afb6c21d3f41a472ba59caebf93a6e2dbfea4d55 100644 (file)
@@ -15,7 +15,7 @@ fn uhoh<T>(v: Vec<clam<T>> ) {
       a::<T>(ref _t, ref u) => {
           println!("incorrect");
           println!("{}", u);
-          fail!();
+          panic!();
       }
       b::<T> => { println!("correct"); }
     }
index a2aecc1d5cd56e3b62d415006d7e2634ceedbe18..0ac7a2001fc678472f7338d0f4bbd76fca8c08a9 100644 (file)
@@ -23,7 +23,7 @@ impl Drop for Foo {
 }
 
 fn bar() -> uint {
-    fail!();
+    panic!();
 }
 
 fn foo() {
index 65307c5e7b559d498c0a57cdfc8109140082a9a0..2877aa6bd3be1a317b0d8f41596a3f5c4d19e9ca 100644 (file)
@@ -22,7 +22,7 @@
 
 #[lang = "stack_exhausted"] extern fn stack_exhausted() {}
 #[lang = "eh_personality"] extern fn eh_personality() {}
-#[lang = "fail_fmt"] fn fail_fmt() -> ! { loop {} }
+#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
 
 #[start]
 #[no_stack_check]
index 8f67532d89d6bdc64810ceca8746befcaa709946..8c888ff03624f701aed29c3f1c38bc38b2cfbe49 100644 (file)
 
 pub fn main() {
     // check
-    if ! cfg!(foo) { fail!() }
-    if   cfg!(not(foo)) { fail!() }
+    if ! cfg!(foo) { panic!() }
+    if   cfg!(not(foo)) { panic!() }
 
-    if ! cfg!(qux="foo") { fail!() }
-    if   cfg!(not(qux="foo")) { fail!() }
+    if ! cfg!(qux="foo") { panic!() }
+    if   cfg!(not(qux="foo")) { panic!() }
 
-    if ! cfg!(all(foo, qux="foo")) { fail!() }
-    if   cfg!(not(all(foo, qux="foo"))) { fail!() }
-    if   cfg!(all(not(all(foo, qux="foo")))) { fail!() }
+    if ! cfg!(all(foo, qux="foo")) { panic!() }
+    if   cfg!(not(all(foo, qux="foo"))) { panic!() }
+    if   cfg!(all(not(all(foo, qux="foo")))) { panic!() }
 
-    if cfg!(not_a_cfg) { fail!() }
-    if cfg!(all(not_a_cfg, foo, qux="foo")) { fail!() }
-    if cfg!(all(not_a_cfg, foo, qux="foo")) { fail!() }
-    if ! cfg!(any(not_a_cfg, foo)) { fail!() }
+    if cfg!(not_a_cfg) { panic!() }
+    if cfg!(all(not_a_cfg, foo, qux="foo")) { panic!() }
+    if cfg!(all(not_a_cfg, foo, qux="foo")) { panic!() }
+    if ! cfg!(any(not_a_cfg, foo)) { panic!() }
 
-    if ! cfg!(not(not_a_cfg)) { fail!() }
-    if ! cfg!(all(not(not_a_cfg), foo, qux="foo")) { fail!() }
+    if ! cfg!(not(not_a_cfg)) { panic!() }
+    if ! cfg!(all(not(not_a_cfg), foo, qux="foo")) { panic!() }
 }
index ceffd1e363667d313ce04f3cf3a4e226a14361a9..0dbe74d722bca34605bb8bec4021f7971097ee06 100644 (file)
@@ -17,7 +17,7 @@ fn main() {
     let stderr = ChanWriter::new(tx);
 
     let res = TaskBuilder::new().stderr(box stderr as Box<Writer + Send>).try(proc() -> () {
-        fail!("Hello, world!")
+        panic!("Hello, world!")
     });
     assert!(res.is_err());
 
index fe882937ca0189fbae6d41ad094b9b682a7e6729..bf6fe5a9d26d90519c502f8694b56e911ba0b7c0 100644 (file)
@@ -45,7 +45,7 @@ fn test() {
                         }
                     }
                     Err(ref e) if e.kind == EndOfFile => break,
-                    Err(e) => fail!("{}", e),
+                    Err(e) => panic!("{}", e),
                 }
             }
             srv_tx.send(());
@@ -67,7 +67,7 @@ fn test() {
     // wait for senders
     if cli_rx.iter().take(N).count() != N {
         a.close_accept().unwrap();
-        fail!("clients failed");
+        panic!("clients panicked");
     }
 
     // wait for one acceptor to die
index e186f63e0a45e00f357682a8bbc3b3e1f4e1c447..07fc1212d7899b9ff7ee913acce460214001c80b 100644 (file)
@@ -48,10 +48,10 @@ fn eventual_timeout() {
         match TcpStream::connect_timeout(addr, Duration::milliseconds(100)) {
             Ok(e) => v.push(e),
             Err(ref e) if e.kind == io::TimedOut => return,
-            Err(e) => fail!("other error: {}", e),
+            Err(e) => panic!("other error: {}", e),
         }
     }
-    fail!("never timed out!");
+    panic!("never timed out!");
 }
 
 fn timeout_success() {
index 91c07c259a2d8b60d8f0da09267053192f84da47..8d2a8a6ccfe205c62523dc094092ee28eb8aec88 100644 (file)
@@ -40,7 +40,7 @@ fn main() {
             let mut stream = match acceptor.accept() {
                 Ok(stream) => stream,
                 Err(error) => {
-                    debug!("accept failed: {}", error);
+                    debug!("accept panicked: {}", error);
                     continue;
                 }
             };
index eceafa40265f92828865b3d98ae9973841c0f9e0..476278405ca8a88a8a00eacd6c0f2c5709e501b1 100644 (file)
@@ -39,7 +39,7 @@ fn test_rm_tempdir() {
     let f: proc():Send = proc() {
         let tmp = TempDir::new("test_rm_tempdir").unwrap();
         tx.send(tmp.path().clone());
-        fail!("fail to unwind past `tmp`");
+        panic!("panic to unwind past `tmp`");
     };
     task::try(f);
     let path = rx.recv();
@@ -49,7 +49,7 @@ fn test_rm_tempdir() {
     let path = tmp.path().clone();
     let f: proc():Send = proc() {
         let _tmp = tmp;
-        fail!("fail to unwind past `tmp`");
+        panic!("panic to unwind past `tmp`");
     };
     task::try(f);
     assert!(!path.exists());
@@ -81,7 +81,7 @@ fn test_rm_tempdir_close() {
         let tmp = TempDir::new("test_rm_tempdir").unwrap();
         tx.send(tmp.path().clone());
         tmp.close();
-        fail!("fail to unwind past `tmp`");
+        panic!("panic when unwinding past `tmp`");
     };
     task::try(f);
     let path = rx.recv();
@@ -92,7 +92,7 @@ fn test_rm_tempdir_close() {
     let f: proc():Send = proc() {
         let tmp = tmp;
         tmp.close();
-        fail!("fail to unwind past `tmp`");
+        panic!("panic when unwinding past `tmp`");
     };
     task::try(f);
     assert!(!path.exists());
@@ -175,15 +175,15 @@ pub fn test_rmdir_recursive_ok() {
     assert!(!root.join("bar").join("blat").exists());
 }
 
-pub fn dont_double_fail() {
+pub fn dont_double_panic() {
     let r: Result<(), _> = task::try(proc() {
         let tmpdir = TempDir::new("test").unwrap();
         // Remove the temporary directory so that TempDir sees
         // an error on drop
         fs::rmdir(tmpdir.path());
-        // Trigger failure. If TempDir fails *again* due to the rmdir
+        // Panic. If TempDir panics *again* due to the rmdir
         // error then the process will abort.
-        fail!();
+        panic!();
     });
     assert!(r.is_err());
 }
@@ -203,5 +203,5 @@ pub fn main() {
     in_tmpdir(recursive_mkdir_dot);
     in_tmpdir(recursive_mkdir_rel_2);
     in_tmpdir(test_rmdir_recursive_ok);
-    in_tmpdir(dont_double_fail);
+    in_tmpdir(dont_double_panic);
 }
index 41a9e6e53f251772d893ab56406fd7c56c000730..2a71148216d6407452a4b49c8043fa15dc178f98 100644 (file)
 
 fn test_ret() { let _x: Box<int> = return; }
 
-fn test_fail() {
-    fn f() { let _x: Box<int> = fail!(); }
+fn test_panic() {
+    fn f() { let _x: Box<int> = panic!(); }
     task::try(proc() f() );
 }
 
-fn test_fail_indirect() {
-    fn f() -> ! { fail!(); }
+fn test_panic_indirect() {
+    fn f() -> ! { panic!(); }
     fn g() { let _x: Box<int> = f(); }
     task::try(proc() g() );
 }
@@ -35,6 +35,6 @@ pub fn main() {
     test_break();
     test_cont();
     test_ret();
-    test_fail();
-    test_fail_indirect();
+    test_panic();
+    test_panic_indirect();
 }
index 9b658ee1dae53a3cab4aad0e2c1e346d0d9daddd..839e91f3793d4e9d6d7e6578c5f7ea86ba7a5533 100644 (file)
@@ -13,4 +13,4 @@
 
 // Building as a test runner means that a synthetic main will be run,
 // not ours
-pub fn main() { fail!(); }
+pub fn main() { panic!(); }
diff --git a/src/test/run-pass/trait-cache-issue-18209.rs b/src/test/run-pass/trait-cache-issue-18209.rs
new file mode 100644 (file)
index 0000000..a5efb32
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that the cache results from the default method do not pollute
+// the cache for the later call in `load()`.
+//
+// See issue #18209.
+
+pub trait Foo {
+    fn load_from() -> Box<Self>;
+    fn load() -> Box<Self> {
+        Foo::load_from()
+    }
+}
+
+pub fn load<M: Foo>() -> Box<M> {
+    Foo::load()
+}
+
+fn main() { }
diff --git a/src/test/run-pass/trait-cast-generic.rs b/src/test/run-pass/trait-cast-generic.rs
deleted file mode 100644 (file)
index 8f0ec5e..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Testing casting of a generic Struct to a Trait with a generic method.
-// This is test for issue 10955.
-#![allow(unused_variable)]
-
-trait Foo {
-    fn f<A>(a: A) -> A {
-        a
-    }
-}
-
-struct Bar<T> {
-    x: T,
-}
-
-impl<T> Foo for Bar<T> { }
-
-pub fn main() {
-    let a = Bar { x: 1u };
-    let b = &a as &Foo;
-}
index f88522facdfdfeb74bae434982fc9a0fdfd0e776..c4880e97c458bef96152d15ddd9df87fdd8b2363 100644 (file)
@@ -72,9 +72,6 @@ pub fn main() {
     assert_eq!(g(0i, 3.14f64, 1i), (3.14f64, 1i));
     assert_eq!(g(false, 3.14f64, 1i), (3.14, 1));
 
-    let obj = box 0i as Box<A>;
-    assert_eq!(obj.h(), 11);
-
 
     // Trying out a real one
     assert!(12i.test_neq(&10i));
index ed4712ff3be9c55bd8ba81e1b64498f0fee7445c..93aa367feee82ebf352d04ee6d0fa2c5bd491426 100644 (file)
@@ -57,10 +57,10 @@ fn non_default_instance() -> &'static Request {
 pub fn main() {
     match default_instance() {
         &Request { foo: TestNone, bar: 17 } => {},
-        _ => fail!(),
+        _ => panic!(),
     };
     match non_default_instance() {
         &Request { foo: TestSome(0x1020304050607080), bar: 19 } => {},
-        _ => fail!(),
+        _ => panic!(),
     };
 }
index 6be79cb62dd7f09ccf6c1f32ffc1c14cd1b0d1a4..48d073e28aa753092fc0fd98b9323082e76474d9 100644 (file)
@@ -26,7 +26,7 @@ fn foo(a:T, b:T) -> T {
             match (a, b) {
                 (A($id1), A($id2)) => A($e),
                 (B($id1), B($id2)) => B($e),
-                _ => fail!()
+                _ => panic!()
             }
         }
     )
diff --git a/src/test/run-pass/unboxed-closures-monomorphization.rs b/src/test/run-pass/unboxed-closures-monomorphization.rs
new file mode 100644 (file)
index 0000000..43fb4b2
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that unboxed closures in contexts with free type parameters
+// monomorphize correctly (issue #16791)
+
+#![feature(unboxed_closures)]
+
+fn main(){
+    fn bar<'a, T:'a> (t: T) -> Box<FnOnce<(),T> + 'a> {
+        box move |:| t
+    }
+
+    let f = bar(42u);
+    assert_eq!(f.call_once(()), 42);
+
+    let f = bar("forty-two");
+    assert_eq!(f.call_once(()), "forty-two");
+
+    let x = 42u;
+    let f = bar(&x);
+    assert_eq!(f.call_once(()), &x);
+
+    #[deriving(Show, PartialEq)]
+    struct Foo(uint, &'static str);
+    let x = Foo(42, "forty-two");
+    let f = bar(x);
+    assert_eq!(f.call_once(()), x);
+}
diff --git a/src/test/run-pass/unboxed-closures-move-mutable.rs b/src/test/run-pass/unboxed-closures-move-mutable.rs
new file mode 100644 (file)
index 0000000..f7e1e46
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(unboxed_closures)]
+#![deny(unused_mut)]
+
+// Test that mutating a mutable upvar in a capture-by-value unboxed
+// closure does not ice (issue #18238) and marks the upvar as used
+// mutably so we do not get a spurious warning about it not needing to
+// be declared mutable (issue #18336).
+
+fn main() {
+    {
+        let mut x = 0u;
+        move |&mut:| x += 1;
+    }
+    {
+        let mut x = 0u;
+        move |:| x += 1;
+    }
+}
index 762a74b24551c29a36123080584f22a9545f5054..3c67eaee0a6a2a83bb9882c5ca7d6dca79bc6ce6 100644 (file)
@@ -17,13 +17,13 @@ enum t { t1(int), t2(int), }
       t1(a) {
         assert_eq!(a, 10);
       }
-      _ { fail!(); }
+      _ { panic!(); }
     }*/
 
     /*alt x {
       box t1(a) {
         assert_eq!(a, 10);
       }
-      _ { fail!(); }
+      _ { panic!(); }
     }*/
 }
index 7f894a8c324b55b3074c63b284e7ff59ee3a523d..a902fef288f002dff362435962264d8573ae728e 100644 (file)
@@ -14,5 +14,5 @@ pub fn main() {
 }
 
 fn f(_i: Box<int>) -> Box<int> {
-    fail!();
+    panic!();
 }
index 297ded0222d1f4be69dcb3d8bb2a216b1e280309..a0eee7e3cb6ee770560795d1e5a0f192f9c2993d 100644 (file)
@@ -11,7 +11,7 @@
 fn simple() {
     match box true {
       box true => { }
-      _ => { fail!(); }
+      _ => { panic!(); }
     }
 }
 
index 3a1cc0331a3e6c04ef39c12cfd896361f2660dab..c12303b009f46c588d128582ce1627d0502cd6fe 100644 (file)
@@ -17,7 +17,7 @@
 
 impl Drop for Foo {
     fn drop(&mut self) {
-        fail!("This failure should happen.");
+        panic!("This panic should happen.");
     }
 }
 
@@ -27,5 +27,5 @@ pub fn main() {
     });
 
     let s = x.unwrap_err().downcast::<&'static str>().unwrap();
-    assert_eq!(s.as_slice(), "This failure should happen.");
+    assert_eq!(s.as_slice(), "This panic should happen.");
 }
index 42b78e4ec661639c73c428a2583db655a4c5d22e..b2ef1a044db808e8e51b95b556fb05f415c170e2 100644 (file)
@@ -87,7 +87,7 @@ fn main() {
     };
 
     match process::Process::spawn(cfg) {
-        Ok(_) => { fail!("spawn() should have failled"); }
+        Ok(_) => { panic!("spawn() should have panicked"); }
         Err(rtio::IoError { code: err, ..}) => {
             assert_eq!(err as c_int, EXPECTED_ERRNO);
         }
index fa24cc44f90079c2cb6464e49fd1ee7cc18b63c2..d8a8913e58ad9b1bc8fdcd5cd34893940db3fa23 100644 (file)
@@ -14,7 +14,7 @@
 fn id(x: bool) -> bool { x }
 
 fn call_id() {
-    let c = fail!();
+    let c = panic!();
     id(c); //~ WARNING unreachable statement
 }
 
index 6b6754f34326d67b618bcc65136ba89a8c778cf6..a9ac78c5d76fd81d30a6a480402d8e4a7f08245e 100644 (file)
@@ -15,7 +15,7 @@
 fn id(x: bool) -> bool { x }
 
 fn call_id() {
-    let c = fail!();
+    let c = panic!();
     id(c);
 }
 
@@ -23,8 +23,6 @@ fn call_id() {
 
 fn call_id_3() { id(return) && id(return); }
 
-fn ret_ret() -> int { return (return 2i) + 3i; }
-
 fn ret_guard() {
     match 2i {
       x if (return) => { x; }
index 13370ea340f656aa4132b4926285ac7c6bdd3760..60f07663bef0e38ee714fcef07e0213c4d577542 100644 (file)
@@ -32,7 +32,7 @@ fn complainer(tx: Sender<bool>) -> complainer {
 
 fn f(tx: Sender<bool>) {
     let _tx = complainer(tx);
-    fail!();
+    panic!();
 }
 
 pub fn main() {
index e5497427755fd23eeeb695949c226df2719889f2..2f31ee25b5daab80d30235b8006052299a198fb9 100644 (file)
@@ -12,7 +12,7 @@
 
 fn f() {
     let _a = box 0i;
-    fail!();
+    panic!();
 }
 
 pub fn main() {
index b5d2b9ef84c574a89609abc18cadc253d4f6a6b1..9337d064d2397a293a3c474f3154c687225a2be8 100644 (file)
@@ -13,7 +13,7 @@
 fn foo<T>(o: myoption<T>) -> int {
     let mut x: int;
     match o {
-        none::<T> => { fail!(); }
+        none::<T> => { panic!(); }
         some::<T>(_t) => { x = 5; }
     }
     return x;
index 2fe8f4bdf011ae70aab7a2890c8b2a997faa3b0f..11b58948e0535d1f928630cf16740ece3ce9efb2 100644 (file)
@@ -10,7 +10,7 @@
 
 fn sub_expr() {
     // Test for a &[T] => &&[T] coercion in sub-expression position
-    // (surpisingly, this can cause errors which are not caused by either of:
+    // (surprisingly, this can cause errors which are not caused by either of:
     //    `let x = vec.slice_mut(0, 2);`
     //    `foo(vec.slice_mut(0, 2));` ).
     let mut vec: Vec<int> = vec!(1, 2, 3, 4);
index 9992c059ac4e6b13884cf2af764a8cf74222d12f..6476f734ae650b3dcfcc0257e954797ed351290f 100644 (file)
 pub fn main() {
     let x = [1i, 2, 3];
     match x {
-        [2, _, _] => fail!(),
+        [2, _, _] => panic!(),
         [1, a, b] => {
             assert!([a, b] == [2, 3]);
         }
-        [_, _, _] => fail!(),
+        [_, _, _] => panic!(),
     }
 
     let y = ([(1i, true), (2i, false)], 0.5f64);
@@ -24,7 +24,7 @@ pub fn main() {
             assert_eq!(a, true);
             assert_eq!(b, 2);
         }
-        ([_, _], 0.5) => fail!(),
-        ([_, _], _) => fail!(),
+        ([_, _], 0.5) => panic!(),
+        ([_, _], _) => panic!(),
     }
 }
index 187d97f483ddaa6ff787ac23cff471f0b4089018..77226df7fa2025f27b6dd8a297e3a61e78cd4404 100644 (file)
@@ -57,7 +57,7 @@ fn b() {
 fn c() {
     let x = [1i];
     match x {
-        [2, ..] => fail!(),
+        [2, ..] => panic!(),
         [..] => ()
     }
 }
index 10c37651a86350e07c4c9c1465e7ae659a5ae2db..ce9cc68bd3654f5ba18820e26c3e852739d3535a 100644 (file)
@@ -68,8 +68,8 @@ pub fn main() {
             let mut count = 0;
             main.clone().as_mut_slice().sort_by(|a, b| { count += 1; a.cmp(b) });
 
-            // ... and then fail on each and every single one.
-            for fail_countdown in range(0i, count) {
+            // ... and then panic on each and every single one.
+            for panic_countdown in range(0i, count) {
                 // refresh the counters.
                 for c in drop_counts.iter() {
                     c.store(0, Relaxed);
@@ -79,12 +79,12 @@ pub fn main() {
 
                 let _ = task::try(proc() {
                         let mut v = v;
-                        let mut fail_countdown = fail_countdown;
+                        let mut panic_countdown = panic_countdown;
                         v.as_mut_slice().sort_by(|a, b| {
-                                if fail_countdown == 0 {
-                                    fail!()
+                                if panic_countdown == 0 {
+                                    panic!()
                                 }
-                                fail_countdown -= 1;
+                                panic_countdown -= 1;
                                 a.cmp(b)
                             })
                     });
index 72204c28f82ade773eb42141ea6cc504ec2f3df1..f73800b89db642e28f0333f1366401dfd01d5bac 100644 (file)
@@ -71,7 +71,7 @@ fn p() -> bool { true }
 fn angrydome() {
     loop { if break { } }
     let mut i = 0i;
-    loop { i += 1; if i == 1 { match (continue) { 1i => { }, _ => fail!("wat") } }
+    loop { i += 1; if i == 1 { match (continue) { 1i => { }, _ => panic!("wat") } }
       break; }
 }
 
index dd53ac889f5056b4ccd561037792ea3c56fccd6d..41712f7c64d29c28fa1b2a9ba23ae0cdec82b25f 100644 (file)
@@ -15,7 +15,7 @@ pub fn main() {
         i -= 1;
         if i == 95 {
             break 'w;
-            fail!("Should have broken out of loop");
+            panic!("Should have broken out of loop");
         }
     }
     assert_eq!(i, 95);
index 6d57bff1bd673b7ac49724948adeadc8518c78cd..ae49c07093b11818fbce833496afa8228dff3ce8 100644 (file)
@@ -20,7 +20,7 @@ pub fn main() {
             Some(ref z) if *z.lock() => {
                 assert!(*z.lock());
             },
-            _ => fail!()
+            _ => panic!()
         }
     }
 }