]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #11784 : eminence/rust/fix_run_tests, r=alexcrichton
authorbors <bors@rust-lang.org>
Fri, 31 Jan 2014 02:11:30 +0000 (18:11 -0800)
committerbors <bors@rust-lang.org>
Fri, 31 Jan 2014 02:11:30 +0000 (18:11 -0800)
This test is designed to ensure that running a non-existent executable
results in a correct error message (FileNotFound in this case of this
test).  However, if you try to run an executable that doesn't exist, and
that requires searching through the $PATH, and one of the $PATH components
is not readable, then a PermissionDenied error will be returned, instead
of FileNotFound.

Using an absolute path skips the $PATH search logic in exec, thus by-passing the logic in exec that would have returned a PermissionDenied

In the specific case of my machine, /usr/bin/games was part of $PATH, but my user account wasn't in the games group (thus being unable to read /usr/bin/games)

See the man pages for execv and execve for more details.

I've tested this on Linux and OSX, and I am fairly certain that there will be no problems on Windows

524 files changed:
.gitignore
AUTHORS.txt
Makefile.in
configure
doc/complement-cheatsheet.md
doc/guide-conditions.md
doc/guide-container.md
doc/guide-ffi.md
doc/guide-lifetimes.md
doc/guide-pointers.md
doc/guide-runtime.md
doc/guide-tasks.md
doc/index.md
doc/po/ja/complement-cheatsheet.md.po
doc/po/ja/guide-ffi.md.po
doc/po/ja/guide-lifetimes.md.po
doc/po/ja/guide-pointers.md.po
doc/po/ja/guide-rustpkg.md.po
doc/po/ja/rust.md.po
doc/po/ja/tutorial.md.po
doc/rust.md
doc/tutorial.md
mk/clean.mk
mk/crates.mk [new file with mode: 0644]
mk/docs.mk
mk/host.mk
mk/install.mk
mk/platform.mk
mk/rt.mk
mk/rustllvm.mk
mk/target.mk
mk/tests.mk
mk/tools.mk [deleted file]
src/compiletest/runtest.rs
src/etc/check-summary.py
src/etc/extract-tests.py
src/etc/gedit/share/gtksourceview-3.0/language-specs/rust.lang
src/etc/generate-deriving-span-tests.py [new file with mode: 0755]
src/etc/kate/rust.xml
src/etc/tidy.py
src/etc/vim/syntax/rust.vim
src/libarena/lib.rs [new file with mode: 0644]
src/libextra/arc.rs
src/libextra/arena.rs [deleted file]
src/libextra/base64.rs
src/libextra/bitv.rs
src/libextra/btree.rs
src/libextra/comm.rs
src/libextra/dlist.rs
src/libextra/ebml.rs
src/libextra/flate.rs [deleted file]
src/libextra/future.rs
src/libextra/getopts.rs
src/libextra/glob.rs [deleted file]
src/libextra/json.rs
src/libextra/lib.rs
src/libextra/lru_cache.rs
src/libextra/num/bigint.rs
src/libextra/ringbuf.rs
src/libextra/sync.rs
src/libextra/task_pool.rs
src/libextra/test.rs
src/libextra/treemap.rs
src/libextra/url.rs
src/libextra/workcache.rs
src/libflate/lib.rs [new file with mode: 0644]
src/libglob/lib.rs [new file with mode: 0644]
src/libgreen/basic.rs
src/libgreen/context.rs
src/libgreen/coroutine.rs
src/libgreen/lib.rs
src/libgreen/macros.rs
src/libgreen/sched.rs
src/libgreen/stack.rs
src/libgreen/task.rs
src/libnative/io/addrinfo.rs [new file with mode: 0644]
src/libnative/io/file.rs
src/libnative/io/mod.rs
src/libnative/io/net.rs
src/libnative/io/process.rs
src/libnative/io/timer_helper.rs
src/libnative/io/timer_other.rs
src/libnative/io/timer_timerfd.rs
src/libnative/task.rs
src/librustc/back/abi.rs
src/librustc/back/link.rs
src/librustc/driver/driver.rs
src/librustc/driver/session.rs
src/librustc/front/feature_gate.rs
src/librustc/front/std_inject.rs
src/librustc/lib.rs
src/librustc/lib/llvm.rs
src/librustc/metadata/common.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/encoder.rs
src/librustc/metadata/filesearch.rs
src/librustc/metadata/loader.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/gather_moves.rs
src/librustc/middle/borrowck/gather_loans/lifetime.rs
src/librustc/middle/borrowck/gather_loans/mod.rs
src/librustc/middle/borrowck/gather_loans/restrictions.rs
src/librustc/middle/borrowck/mod.rs
src/librustc/middle/borrowck/move_data.rs
src/librustc/middle/cfg/construct.rs
src/librustc/middle/dataflow.rs
src/librustc/middle/effect.rs
src/librustc/middle/freevars.rs
src/librustc/middle/graph.rs
src/librustc/middle/kind.rs
src/librustc/middle/lint.rs
src/librustc/middle/liveness.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/moves.rs
src/librustc/middle/privacy.rs
src/librustc/middle/reachable.rs
src/librustc/middle/region.rs
src/librustc/middle/resolve.rs
src/librustc/middle/subst.rs
src/librustc/middle/trans/_match.rs
src/librustc/middle/trans/adt.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/builder.rs
src/librustc/middle/trans/callee.rs
src/librustc/middle/trans/cleanup.rs
src/librustc/middle/trans/closure.rs
src/librustc/middle/trans/common.rs
src/librustc/middle/trans/consts.rs
src/librustc/middle/trans/context.rs
src/librustc/middle/trans/controlflow.rs
src/librustc/middle/trans/datum.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/expr.rs
src/librustc/middle/trans/foreign.rs
src/librustc/middle/trans/glue.rs
src/librustc/middle/trans/inline.rs
src/librustc/middle/trans/intrinsic.rs
src/librustc/middle/trans/machine.rs
src/librustc/middle/trans/meth.rs
src/librustc/middle/trans/monomorphize.rs
src/librustc/middle/trans/reflect.rs
src/librustc/middle/trans/tvec.rs
src/librustc/middle/trans/type_.rs
src/librustc/middle/trans/type_of.rs
src/librustc/middle/ty.rs
src/librustc/middle/ty_fold.rs
src/librustc/middle/typeck/astconv.rs
src/librustc/middle/typeck/check/method.rs
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/check/regionck.rs
src/librustc/middle/typeck/check/regionmanip.rs
src/librustc/middle/typeck/check/vtable.rs
src/librustc/middle/typeck/check/writeback.rs
src/librustc/middle/typeck/coherence.rs
src/librustc/middle/typeck/collect.rs
src/librustc/middle/typeck/infer/coercion.rs
src/librustc/middle/typeck/infer/mod.rs
src/librustc/middle/typeck/infer/region_inference/mod.rs
src/librustc/middle/typeck/infer/sub.rs
src/librustc/middle/typeck/infer/test.rs
src/librustc/middle/typeck/mod.rs
src/librustc/middle/typeck/variance.rs
src/librustc/util/ppaux.rs
src/librustc/util/sha2.rs
src/librustdoc/clean.rs
src/librustdoc/core.rs
src/librustdoc/html/format.rs
src/librustdoc/html/markdown.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/main.js
src/librustdoc/lib.rs
src/librustdoc/passes.rs
src/librustdoc/test.rs
src/librustpkg/lib.rs
src/librustpkg/package_source.rs
src/librustpkg/sha1.rs
src/librustpkg/tests.rs
src/librustpkg/testsuite/pass/src/c-dependencies/pkg.rs
src/librustpkg/util.rs
src/librustuv/addrinfo.rs
src/librustuv/async.rs
src/librustuv/file.rs
src/librustuv/homing.rs
src/librustuv/lib.rs
src/librustuv/net.rs
src/librustuv/pipe.rs
src/librustuv/signal.rs
src/librustuv/stream.rs
src/librustuv/timer.rs
src/librustuv/uvio.rs
src/librustuv/uvll.rs
src/libstd/borrow.rs [deleted file]
src/libstd/c_str.rs
src/libstd/cleanup.rs
src/libstd/comm/mod.rs
src/libstd/comm/select.rs
src/libstd/fmt/mod.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/addrinfo.rs
src/libstd/io/net/tcp.rs
src/libstd/io/net/udp.rs
src/libstd/io/net/unix.rs
src/libstd/io/pipe.rs
src/libstd/io/signal.rs
src/libstd/io/stdio.rs
src/libstd/io/test.rs
src/libstd/io/timer.rs
src/libstd/iter.rs
src/libstd/lib.rs
src/libstd/libc.rs
src/libstd/local_data.rs
src/libstd/macros.rs [new file with mode: 0644]
src/libstd/num/int.rs
src/libstd/num/int_macros.rs
src/libstd/num/mod.rs
src/libstd/num/strconv.rs
src/libstd/num/uint.rs
src/libstd/num/uint_macros.rs
src/libstd/option.rs
src/libstd/os.rs
src/libstd/path/mod.rs
src/libstd/path/posix.rs
src/libstd/path/windows.rs
src/libstd/prelude.rs
src/libstd/rand/distributions/mod.rs
src/libstd/rand/isaac.rs
src/libstd/rand/os.rs
src/libstd/rand/rand_impls.rs
src/libstd/reference.rs [new file with mode: 0644]
src/libstd/reflect.rs
src/libstd/repr.rs
src/libstd/result.rs
src/libstd/rt/crate_map.rs
src/libstd/rt/env.rs
src/libstd/rt/local.rs
src/libstd/rt/local_heap.rs
src/libstd/rt/mod.rs
src/libstd/rt/rtio.rs
src/libstd/rt/task.rs
src/libstd/rt/thread.rs
src/libstd/rt/unwind.rs
src/libstd/rt/util.rs
src/libstd/run.rs
src/libstd/send_str.rs
src/libstd/str.rs
src/libstd/sync/deque.rs
src/libstd/sync/mpmc_bounded_queue.rs
src/libstd/sync/mpsc_queue.rs
src/libstd/sync/spsc_queue.rs
src/libstd/task.rs
src/libstd/trie.rs
src/libstd/tuple.rs
src/libstd/unstable/intrinsics.rs
src/libstd/unstable/mod.rs
src/libstd/unstable/mutex.rs
src/libstd/unstable/simd.rs
src/libstd/unstable/sync.rs
src/libstd/vec.rs
src/libsyntax/ast.rs
src/libsyntax/ast_map.rs
src/libsyntax/ast_util.rs
src/libsyntax/codemap.rs
src/libsyntax/diagnostic.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/deriving/clone.rs
src/libsyntax/ext/deriving/cmp/ord.rs
src/libsyntax/ext/deriving/decodable.rs
src/libsyntax/ext/deriving/default.rs
src/libsyntax/ext/deriving/encodable.rs
src/libsyntax/ext/deriving/generic.rs
src/libsyntax/ext/deriving/iter_bytes.rs
src/libsyntax/ext/deriving/primitive.rs
src/libsyntax/ext/deriving/rand.rs
src/libsyntax/ext/deriving/ty.rs
src/libsyntax/ext/deriving/zero.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/tt/macro_parser.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/ext/tt/transcribe.rs
src/libsyntax/fold.rs
src/libsyntax/parse/classify.rs
src/libsyntax/parse/comments.rs
src/libsyntax/parse/lexer.rs
src/libsyntax/parse/parser.rs
src/libsyntax/parse/token.rs
src/libsyntax/print/pprust.rs
src/libsyntax/visit.rs
src/llvm
src/rt/rust_uv.c
src/rustllvm/PassWrapper.cpp
src/rustllvm/RustWrapper.cpp
src/rustllvm/llvm-auto-clean-trigger
src/rustllvm/rustllvm.h
src/test/auxiliary/cci_capture_clause.rs
src/test/auxiliary/default_type_params_xc.rs [new file with mode: 0644]
src/test/auxiliary/iss.rs
src/test/auxiliary/issue_10031_aux.rs [new file with mode: 0644]
src/test/auxiliary/macro_crate_test.rs
src/test/auxiliary/struct-field-privacy.rs [new file with mode: 0644]
src/test/bench/msgsend-pipes-shared.rs
src/test/bench/msgsend-pipes.rs
src/test/bench/msgsend-ring-mutex-arcs.rs
src/test/bench/msgsend-ring-rw-arcs.rs
src/test/bench/rt-messaging-ping-pong.rs
src/test/bench/rt-parfib.rs
src/test/bench/rt-spawn-rate.rs
src/test/bench/shootout-binarytrees.rs
src/test/bench/shootout-chameneos-redux.rs
src/test/bench/shootout-fasta-redux.rs
src/test/bench/shootout-k-nucleotide-pipes.rs
src/test/bench/shootout-k-nucleotide.rs
src/test/bench/shootout-meteor.rs
src/test/bench/shootout-pfib.rs
src/test/bench/shootout-spectralnorm.rs
src/test/bench/shootout-threadring.rs
src/test/bench/silly-test-spawn.rs [new file with mode: 0644]
src/test/bench/spawnone.rs [new file with mode: 0644]
src/test/bench/task-perf-alloc-unwind.rs
src/test/bench/task-perf-jargon-metal-smoke.rs
src/test/bench/task-perf-linked-failure.rs
src/test/bench/task-perf-one-million.rs
src/test/compile-fail/arc-rw-read-mode-shouldnt-escape.rs
src/test/compile-fail/arc-rw-write-mode-shouldnt-escape.rs
src/test/compile-fail/bad-mid-path-type-params.rs
src/test/compile-fail/borrowck-lend-flow-loop.rs
src/test/compile-fail/borrowck-loan-blocks-move-cc.rs
src/test/compile-fail/coerce-bare-fn-to-closure-and-proc.rs [new file with mode: 0644]
src/test/compile-fail/deriving-field-span-enum-struct-variant.rs [deleted file]
src/test/compile-fail/deriving-field-span-enum.rs [deleted file]
src/test/compile-fail/deriving-field-span-struct.rs [deleted file]
src/test/compile-fail/deriving-field-span-tuple-struct.rs [deleted file]
src/test/compile-fail/deriving-no-inner-impl-error-message.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-Clone-enum-struct-variant.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-Clone-enum.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-Clone-struct.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-Clone-tuple-struct.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-DeepClone-enum-struct-variant.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-DeepClone-enum.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-DeepClone-struct.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-DeepClone-tuple-struct.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-Default-struct.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-Default-tuple-struct.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-Eq-enum-struct-variant.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-Eq-enum.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-Eq-struct.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-Eq-tuple-struct.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-Ord-enum-struct-variant.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-Ord-enum.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-Ord-struct.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-Ord-tuple-struct.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-Rand-enum-struct-variant.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-Rand-enum.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-Rand-struct.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-Rand-tuple-struct.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-TotalEq-enum-struct-variant.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-TotalEq-enum.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-TotalEq-struct.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-TotalEq-tuple-struct.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-TotalOrd-enum-struct-variant.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-TotalOrd-enum.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-TotalOrd-struct.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-TotalOrd-tuple-struct.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-Zero-struct.rs [new file with mode: 0644]
src/test/compile-fail/deriving-span-Zero-tuple-struct.rs [new file with mode: 0644]
src/test/compile-fail/do-lambda-requires-braces.rs [deleted file]
src/test/compile-fail/do1.rs [deleted file]
src/test/compile-fail/do2.rs [deleted file]
src/test/compile-fail/gated-default-type-params.rs [new file with mode: 0644]
src/test/compile-fail/gated-simd.rs [new file with mode: 0644]
src/test/compile-fail/gated-trace_macros.rs [new file with mode: 0644]
src/test/compile-fail/generic-impl-less-params-with-defaults.rs [new file with mode: 0644]
src/test/compile-fail/generic-impl-more-params-with-defaults.rs [new file with mode: 0644]
src/test/compile-fail/generic-non-trailing-defaults.rs [new file with mode: 0644]
src/test/compile-fail/generic-type-less-params-with-defaults.rs [new file with mode: 0644]
src/test/compile-fail/generic-type-more-params-with-defaults.rs [new file with mode: 0644]
src/test/compile-fail/generic-type-params-name-repr.rs [new file with mode: 0644]
src/test/compile-fail/implicit-method-bind.rs
src/test/compile-fail/issue-3008-1.rs [new file with mode: 0644]
src/test/compile-fail/issue-3008-2.rs [new file with mode: 0644]
src/test/compile-fail/issue-3008-3.rs [new file with mode: 0644]
src/test/compile-fail/issue-3044.rs
src/test/compile-fail/issue-3243.rs [deleted file]
src/test/compile-fail/issue-3779.rs [new file with mode: 0644]
src/test/compile-fail/issue-511.rs [deleted file]
src/test/compile-fail/issue-6642.rs
src/test/compile-fail/keyword-do-as-identifier.rs [deleted file]
src/test/compile-fail/kindck-implicit-close-over-mut-var.rs [deleted file]
src/test/compile-fail/lint-default-type-param-usage.rs [new file with mode: 0644]
src/test/compile-fail/lint-missing-doc.rs
src/test/compile-fail/lint-stability.rs
src/test/compile-fail/lint-unused-mut-self.rs [new file with mode: 0644]
src/test/compile-fail/macros-nonfatal-errors.rs
src/test/compile-fail/moves-based-on-type-capture-clause-bad.rs
src/test/compile-fail/mutable-class-fields-2.rs
src/test/compile-fail/mutable-class-fields.rs
src/test/compile-fail/mutex-arc-nested.rs
src/test/compile-fail/no-capture-arc.rs
src/test/compile-fail/no-reuse-move-arc.rs
src/test/compile-fail/no-send-res-ports.rs
src/test/compile-fail/once-cant-call-twice-on-heap.rs
src/test/compile-fail/regions-lifetime-of-struct-or-enum-variant.rs [new file with mode: 0644]
src/test/compile-fail/regions-return-stack-allocated-vec.rs [new file with mode: 0644]
src/test/compile-fail/simd-experimental.rs [new file with mode: 0644]
src/test/compile-fail/simd-type.rs
src/test/compile-fail/struct-field-privacy.rs [new file with mode: 0644]
src/test/compile-fail/sync-rwlock-read-mode-shouldnt-escape.rs
src/test/compile-fail/sync-rwlock-write-mode-shouldnt-escape.rs
src/test/compile-fail/tag-that-dare-not-speak-its-name.rs
src/test/compile-fail/trait-impl-different-num-params.rs
src/test/compile-fail/unused-result.rs [new file with mode: 0644]
src/test/compile-fail/useless-priv.rs
src/test/debug-info/function-prologue-stepping-no-split-stack.rs
src/test/debug-info/issue11600.rs [new file with mode: 0644]
src/test/run-fail/bounds-check-no-overflow.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/extern-fail.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/morestack2.rs
src/test/run-fail/morestack3.rs
src/test/run-fail/morestack4.rs
src/test/run-fail/native-failure.rs
src/test/run-fail/rt-set-exit-status-fail2.rs
src/test/run-make/bootstrap-from-c-with-green/lib.rs
src/test/run-make/bootstrap-from-c-with-native/lib.rs
src/test/run-make/static-unwinding/main.rs
src/test/run-pass-fulldeps/qquote.rs
src/test/run-pass/auto-ref-slice-plus-ref.rs
src/test/run-pass/bitv-perf-test.rs
src/test/run-pass/block-arg-can-be-followed-by-binop.rs [deleted file]
src/test/run-pass/block-arg-can-be-followed-by-block-arg.rs [deleted file]
src/test/run-pass/block-arg-can-be-followed-by-call.rs [deleted file]
src/test/run-pass/block-arg-in-parentheses.rs [deleted file]
src/test/run-pass/block-arg-used-as-any.rs [deleted file]
src/test/run-pass/block-arg.rs
src/test/run-pass/borrowck-borrow-from-expr-block.rs
src/test/run-pass/capture_nil.rs
src/test/run-pass/capturing-logging.rs
src/test/run-pass/cast-region-to-uint.rs
src/test/run-pass/class-cast-to-trait-multiple-types.rs
src/test/run-pass/class-cast-to-trait.rs
src/test/run-pass/class-impl-very-parameterized-trait.rs
src/test/run-pass/class-implement-trait-cross-crate.rs
src/test/run-pass/class-implement-traits.rs
src/test/run-pass/class-methods.rs
src/test/run-pass/class-poly-methods.rs
src/test/run-pass/class-separate-impl.rs
src/test/run-pass/class-typarams.rs
src/test/run-pass/classes-simple-method.rs
src/test/run-pass/classes-simple.rs
src/test/run-pass/classes.rs
src/test/run-pass/closure-bounds-can-capture-chan.rs
src/test/run-pass/closure-reform.rs
src/test/run-pass/coerce-to-closure-and-proc.rs [new file with mode: 0644]
src/test/run-pass/deriving-encodable-decodable.rs
src/test/run-pass/deriving-primitive.rs
src/test/run-pass/deriving-rand.rs
src/test/run-pass/deriving-self-lifetime-totalord-totaleq.rs
src/test/run-pass/deriving-self-lifetime.rs
src/test/run-pass/do-empty-args.rs [deleted file]
src/test/run-pass/do-no-args.rs [deleted file]
src/test/run-pass/do1.rs [deleted file]
src/test/run-pass/do2.rs [deleted file]
src/test/run-pass/do3.rs [deleted file]
src/test/run-pass/expr-block-fn.rs
src/test/run-pass/extern-call-deep2.rs
src/test/run-pass/extern-call-scrub.rs
src/test/run-pass/extern-stress.rs
src/test/run-pass/extern-yield.rs
src/test/run-pass/fail-in-dtor-drops-fields.rs
src/test/run-pass/foreign-call-no-runtime.rs
src/test/run-pass/generic-default-type-params-cross-crate.rs [new file with mode: 0644]
src/test/run-pass/generic-default-type-params.rs [new file with mode: 0644]
src/test/run-pass/glob-std.rs
src/test/run-pass/infinite-loops.rs
src/test/run-pass/issue-10031.rs [new file with mode: 0644]
src/test/run-pass/issue-2185.rs
src/test/run-pass/issue-3168.rs
src/test/run-pass/issue-3211.rs
src/test/run-pass/issue-3563-3.rs
src/test/run-pass/issue-3609.rs
src/test/run-pass/issue-4241.rs
src/test/run-pass/issue-4401.rs
src/test/run-pass/issue-4446.rs
src/test/run-pass/issue-4448.rs
src/test/run-pass/issue-5321-immediates-with-bare-self.rs
src/test/run-pass/issue-6157.rs [new file with mode: 0644]
src/test/run-pass/kindck-implicit-close-over-mut-var.rs [new file with mode: 0644]
src/test/run-pass/logging-only-prints-once.rs
src/test/run-pass/moves-based-on-type-capture-clause.rs
src/test/run-pass/native-always-waits.rs
src/test/run-pass/no-landing-pads.rs
src/test/run-pass/numeric-method-autoexport.rs
src/test/run-pass/once-move-out-on-heap.rs
src/test/run-pass/placement-new-arena.rs
src/test/run-pass/preempt.rs
src/test/run-pass/private-class-field.rs
src/test/run-pass/private-method.rs
src/test/run-pass/reflect-visit-data.rs
src/test/run-pass/reflect-visit-type.rs
src/test/run-pass/regions-lifetime-static-items-enclosing-scopes.rs [new file with mode: 0644]
src/test/run-pass/regions-mock-tcx.rs
src/test/run-pass/send-resource.rs
src/test/run-pass/simd-binop.rs
src/test/run-pass/simd-type.rs
src/test/run-pass/struct-lit-functional-update-no-fields.rs [new file with mode: 0644]
src/test/run-pass/task-comm-12.rs
src/test/run-pass/task-comm-7.rs
src/test/run-pass/task-comm-9.rs
src/test/run-pass/task-killjoin-rsrc.rs
src/test/run-pass/trait-bounds-in-arc.rs
src/test/run-pass/unit-like-struct-drop-run.rs

index 37a98c45a6bafe74a7dc563a27b9b74e22127688..a4d7203c2b41a047ccb0c955677dc88d256872b5 100644 (file)
@@ -74,11 +74,15 @@ src/.DS_Store
 /doc/html
 /doc/latex
 /doc/std
+/doc/arena
 /doc/extra
+/doc/flate
+/doc/glob
 /doc/green
 /doc/native
 /doc/rustc
 /doc/syntax
+/doc/rustdoc
 /doc/rustuv
 /doc/rustpkg
 /nd/
index 842ebcf9500ae55250c4601e942239f904734bd9..2d0cc16d189dc1bd1412459d17a20365c02e796f 100644 (file)
@@ -351,7 +351,7 @@ Vincent Belliard <vincent@famillebelliard.fr>
 Vivek Galatage <vivekgalatage@gmail.com>
 Volker Mische <volker.mische@gmail.com>
 Wade Mealing <wmealing@gmail.com>
-William Ting <william.h.ting@gmail.com>
+William Ting <io@williamting.com>
 Yasuhiro Fujii <y-fujii@mimosa-pudica.net>
 Young-il Choi <duddlf.choi@samsung.com>
 Youngmin Yoo <youngmin.yoo@samsung.com>
index aab1e2ff556ae975a981400559381eee03eda96b..1b3a85e8947bcbe66266a1fd00ebc5c69d30a29e 100644 (file)
@@ -124,6 +124,12 @@ endif
 ifdef TRACE
   CFG_RUSTC_FLAGS += -Z trace
 endif
+ifdef CFG_DISABLE_RPATH
+# NOTE: make this CFG_RUSTC_FLAGS after stage0 snapshot
+RUSTFLAGS_STAGE1 += --no-rpath
+RUSTFLAGS_STAGE2 += --no-rpath
+RUSTFLAGS_STAGE3 += --no-rpath
+endif
 
 # The executables crated during this compilation process have no need to include
 # static copies of libstd and libextra. We also generate dynamic versions of all
@@ -216,72 +222,27 @@ GENERATED :=
 
 
 ######################################################################
-# Crates
+# Cleaning out old crates
 ######################################################################
 
-define DEF_LIBS
-
-CFG_RUNTIME_$(1) :=$(call CFG_STATIC_LIB_NAME_$(1),rustrt)
-CFG_RUSTLLVM_$(1) :=$(call CFG_STATIC_LIB_NAME_$(1),rustllvm)
-CFG_STDLIB_$(1) :=$(call CFG_LIB_NAME_$(1),std)
-CFG_EXTRALIB_$(1) :=$(call CFG_LIB_NAME_$(1),extra)
-CFG_LIBRUSTC_$(1) :=$(call CFG_LIB_NAME_$(1),rustc)
-CFG_LIBSYNTAX_$(1) :=$(call CFG_LIB_NAME_$(1),syntax)
-CFG_LIBRUSTPKG_$(1) :=$(call CFG_LIB_NAME_$(1),rustpkg)
-CFG_LIBRUSTDOC_$(1) :=$(call CFG_LIB_NAME_$(1),rustdoc)
-CFG_LIBRUSTUV_$(1) :=$(call CFG_LIB_NAME_$(1),rustuv)
-CFG_LIBGREEN_$(1) :=$(call CFG_LIB_NAME_$(1),green)
-CFG_LIBNATIVE_$(1) :=$(call CFG_LIB_NAME_$(1),native)
-
-EXTRALIB_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),extra)
-STDLIB_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),std)
-LIBRUSTC_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustc)
-LIBSYNTAX_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),syntax)
-LIBRUSTPKG_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustpkg)
-LIBRUSTDOC_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustdoc)
-LIBRUSTUV_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustuv)
-LIBGREEN_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),green)
-LIBNATIVE_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),native)
-EXTRALIB_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),extra)
-STDLIB_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),std)
-LIBRUSTC_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustc)
-LIBSYNTAX_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),syntax)
-LIBRUSTPKG_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustpkg)
-LIBRUSTDOC_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustdoc)
-LIBRUSTUV_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustuv)
-LIBGREEN_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),green)
-LIBNATIVE_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),native)
-
-EXTRALIB_RGLOB_$(1) :=$(call CFG_RLIB_GLOB,extra)
-STDLIB_RGLOB_$(1) :=$(call CFG_RLIB_GLOB,std)
-LIBRUSTUV_RGLOB_$(1) :=$(call CFG_RLIB_GLOB,rustuv)
-LIBSYNTAX_RGLOB_$(1) :=$(call CFG_RLIB_GLOB,syntax)
-LIBRUSTC_RGLOB_$(1) :=$(call CFG_RLIB_GLOB,rustc)
-LIBNATIVE_RGLOB_$(1) :=$(call CFG_RLIB_GLOB,native)
-LIBGREEN_RGLOB_$(1) :=$(call CFG_RLIB_GLOB,green)
-
-endef
-
 # $(1) is the path for directory to match against
 # $(2) is the glob to use in the match
-# $(3) is filename (usually the target being created) to filter out from match
-#      (i.e. filename is not out-of-date artifact from prior Rust version/build)
 #
 # Note that a common bug is to accidentally construct the glob denoted
 # by $(2) with a space character prefix, which invalidates the
 # construction $(1)$(2).
-define CHECK_FOR_OLD_GLOB_MATCHES_EXCEPT
-  $(Q)MATCHES="$(filter-out %$(3),$(wildcard $(1)/$(2)))"; if [ -n "$$MATCHES" ] ; then echo "warning: there are previous" \'$(2)\' "libraries:" $$MATCHES; fi
+define CHECK_FOR_OLD_GLOB_MATCHES
+  $(Q)MATCHES="$(wildcard $(1))"; if [ -n "$$MATCHES" ] ; then echo "warning: there are previous" \'$(notdir $(2))\' "libraries:" $$MATCHES; fi
 endef
 
 # Same interface as above, but deletes rather than just listing the files.
 ifdef VERBOSE
-define REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT
-  $(Q)MATCHES="$(filter-out %$(3),$(wildcard $(1)/$(2)))"; if [ -n "$$MATCHES" ] ; then echo "warning: removing previous" \'$(2)\' "libraries:" $$MATCHES; rm $$MATCHES ; fi
+define REMOVE_ALL_OLD_GLOB_MATCHES
+  $(Q)MATCHES="$(wildcard $(1))"; if [ -n "$$MATCHES" ] ; then echo "warning: removing previous" \'$(notdir $(1))\' "libraries:" $$MATCHES; rm $$MATCHES ; fi
 endef
 else
-define REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT
-  $(Q)MATCHES="$(filter-out %$(3),$(wildcard $(1)/$(2)))"; if [ -n "$$MATCHES" ] ; then rm $$MATCHES ; fi
+define REMOVE_ALL_OLD_GLOB_MATCHES
+  $(Q)MATCHES="$(wildcard $(1))"; if [ -n "$$MATCHES" ] ; then rm $$MATCHES ; fi
 endef
 endif
 
@@ -292,72 +253,15 @@ endif
 # soon. (This is in contrast to the macros above, which are meant to
 # be run at the outset of a command list in a rule.)
 ifdef VERBOSE
-define LIST_ALL_OLD_GLOB_MATCHES_EXCEPT
-  @echo "info: now are following matches for" '$(2)' "libraries:"
-  @( cd $(1) && ( ls $(2) 2>/dev/null || true ) | grep -v $(3) || true )
+define LIST_ALL_OLD_GLOB_MATCHES
+  @echo "info: now are following matches for" '$(notdir $(1))' "libraries:"
+  @( ls $(1) 2>/dev/null || true )
 endef
 else
-define LIST_ALL_OLD_GLOB_MATCHES_EXCEPT
+define LIST_ALL_OLD_GLOB_MATCHES
 endef
 endif
 
-$(foreach target,$(CFG_TARGET),\
-  $(eval $(call DEF_LIBS,$(target))))
-
-######################################################################
-# Standard library variables
-######################################################################
-
-STDLIB_CRATE := $(S)src/libstd/lib.rs
-STDLIB_INPUTS := $(wildcard $(addprefix $(S)src/libstd/,        \
-                                           *.rs */*.rs */*/*rs */*/*/*rs))
-
-######################################################################
-# Extra library variables
-######################################################################
-
-EXTRALIB_CRATE := $(S)src/libextra/lib.rs
-EXTRALIB_INPUTS := $(wildcard $(addprefix $(S)src/libextra/,          \
-                                          *.rs */*.rs))
-
-######################################################################
-# Rust UV library variables
-######################################################################
-
-LIBRUSTUV_CRATE := $(S)src/librustuv/lib.rs
-LIBRUSTUV_INPUTS := $(wildcard $(addprefix $(S)src/librustuv/,          \
-                                          *.rs */*.rs))
-
-######################################################################
-# Green threading library variables
-######################################################################
-
-LIBGREEN_CRATE := $(S)src/libgreen/lib.rs
-LIBGREEN_INPUTS := $(wildcard $(addprefix $(S)src/libgreen/,          \
-                                          *.rs */*.rs))
-
-######################################################################
-# Native threading library variables
-######################################################################
-
-LIBNATIVE_CRATE := $(S)src/libnative/lib.rs
-LIBNATIVE_INPUTS := $(wildcard $(addprefix $(S)src/libnative/,          \
-                                          *.rs */*.rs))
-
-######################################################################
-# rustc crate variables
-######################################################################
-
-COMPILER_CRATE := $(S)src/librustc/lib.rs
-COMPILER_INPUTS := $(wildcard $(addprefix $(S)src/librustc/,      \
-                           *.rs */*.rs */*/*.rs */*/*/*.rs))
-
-LIBSYNTAX_CRATE := $(S)src/libsyntax/lib.rs
-LIBSYNTAX_INPUTS := $(wildcard $(addprefix $(S)src/libsyntax/, \
-                           *.rs */*.rs */*/*.rs */*/*/*.rs))
-
-DRIVER_CRATE := $(S)src/driver/driver.rs
-
 ######################################################################
 # LLVM macros
 ######################################################################
@@ -418,14 +322,12 @@ export CFG_RUSTLIBDIR
 export CFG_LIBDIR_RELATIVE
 export CFG_DISABLE_INJECT_STD_VERSION
 
-######################################################################
-# Subprograms
-######################################################################
-
 ######################################################################
 # Per-stage targets and runner
 ######################################################################
 
+include $(CFG_SRC_DIR)mk/crates.mk
+
 define SREQ
 # $(1) is the stage number
 # $(2) is the target triple
@@ -441,84 +343,37 @@ TROOT$(1)_T_$(2)_H_$(3) = $$(HLIB$(1)_H_$(3))/$$(CFG_RUSTLIBDIR)/$(2)
 TBIN$(1)_T_$(2)_H_$(3) = $$(TROOT$(1)_T_$(2)_H_$(3))/bin
 TLIB$(1)_T_$(2)_H_$(3) = $$(TROOT$(1)_T_$(2)_H_$(3))/lib
 
-# The name of the standard and extra libraries used by rustc
-HSTDLIB_DEFAULT$(1)_H_$(3) = \
-  $$(HLIB$(1)_H_$(3))/$(CFG_STDLIB_$(3))
-TSTDLIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
-  $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2))
-
-HEXTRALIB_DEFAULT$(1)_H_$(3) = \
-  $$(HLIB$(1)_H_$(3))/$(CFG_EXTRALIB_$(3))
-TEXTRALIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
-  $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2))
-
-HLIBRUSTC_DEFAULT$(1)_H_$(3) = \
-  $$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTC_$(3))
-TLIBRUSTC_DEFAULT$(1)_T_$(2)_H_$(3) = \
-  $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(2))
-
-HLIBRUSTUV_DEFAULT$(1)_H_$(3) = \
-  $$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTUV_$(3))
-TLIBRUSTUV_DEFAULT$(1)_T_$(2)_H_$(3) = \
-  $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTUV_$(2))
-
-HLIBGREEN_DEFAULT$(1)_H_$(3) = \
-  $$(HLIB$(1)_H_$(3))/$(CFG_LIBGREEN_$(3))
-TLIBGREEN_DEFAULT$(1)_T_$(2)_H_$(3) = \
-  $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBGREEN_$(2))
-
-HLIBNATIVE_DEFAULT$(1)_H_$(3) = \
-  $$(HLIB$(1)_H_$(3))/$(CFG_LIBNATIVE_$(3))
-TLIBNATIVE_DEFAULT$(1)_T_$(2)_H_$(3) = \
-  $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBNATIVE_$(2))
-
 # Preqrequisites for using the stageN compiler
 ifeq ($(1),0)
 HSREQ$(1)_H_$(3) = $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3))
 else
 HSREQ$(1)_H_$(3) = \
        $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
-       $$(HSTDLIB_DEFAULT$(1)_H_$(3)) \
-       $$(HEXTRALIB_DEFAULT$(1)_H_$(3)) \
-       $$(HLIBSYNTAX_DEFAULT$(1)_H_$(3)) \
-       $$(HLIBRUSTC_DEFAULT$(1)_H_$(3)) \
-       $$(HLIBRUSTUV_DEFAULT$(1)_H_$(3)) \
-       $$(HLIBGREEN_DEFAULT$(1)_H_$(3)) \
-       $$(HLIBNATIVE_DEFAULT$(1)_H_$(3)) \
+       $$(HLIB$(1)_H_$(3))/stamp.rustc \
+       $$(foreach dep,$$(RUST_DEPS_rustc),$$(HLIB$(1)_H_$(3))/stamp.$$(dep)) \
        $$(MKFILE_DEPS)
 endif
 
 # Prerequisites for using the stageN compiler to build target artifacts
 TSREQ$(1)_T_$(2)_H_$(3) = \
        $$(HSREQ$(1)_H_$(3)) \
-       $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUNTIME_$(2)) \
        $$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a
 
-# Prerequisites for a working stageN compiler and libraries, for a specific target
+# Prerequisites for a working stageN compiler and libraries, for a specific
+# target
 SREQ$(1)_T_$(2)_H_$(3) = \
        $$(TSREQ$(1)_T_$(2)_H_$(3)) \
-       $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)) \
-       $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2)) \
-       $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTUV_$(2)) \
-       $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBGREEN_$(2)) \
-       $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBNATIVE_$(2))
+       $$(foreach dep,$$(TARGET_CRATES),\
+           $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(dep))
 
-# Prerequisites for a working stageN compiler and libraries, for a specific target
+# Prerequisites for a working stageN compiler and complete set of target
+# libraries
 CSREQ$(1)_T_$(2)_H_$(3) = \
        $$(TSREQ$(1)_T_$(2)_H_$(3)) \
        $$(HBIN$(1)_H_$(3))/rustpkg$$(X_$(3)) \
        $$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \
-       $$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTPKG_$(3)) \
-       $$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTDOC_$(3)) \
-       $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)) \
-       $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2))  \
-       $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(2))  \
-       $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(2)) \
-       $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTPKG_$(2)) \
-       $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTDOC_$(2)) \
-       $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTUV_$(2)) \
-       $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBGREEN_$(2)) \
-       $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBNATIVE_$(2))
+       $$(foreach dep,$$(CRATES),$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(dep)) \
+       $$(foreach dep,$$(HOST_CRATES),$$(HLIB$(1)_H_$(3))/stamp.$$(dep))
 
 ifeq ($(1),0)
 # Don't run the the stage0 compiler under valgrind - that ship has sailed
@@ -541,17 +396,30 @@ CFGFLAG$(1)_T_$(2)_H_$(3) = stage1
 endif
 endif
 
+ifdef CFG_DISABLE_RPATH
+ifeq ($$(OSTYPE_$(3)),apple-darwin)
+  RPATH_VAR$(1)_T_$(2)_H_$(3) := \
+      DYLD_LIBRARY_PATH="$$$$DYLD_LIBRARY_PATH:$$(HLIB$(1)_H_$(3))"
+else
+  RPATH_VAR$(1)_T_$(2)_H_$(3) := \
+      LD_LIBRARY_PATH="$$$$LD_LIBRARY_PATH:$$(HLIB$(1)_H_$(3))"
+endif
+else
+    RPATH_VAR$(1)_T_$(2)_H_$(3) :=
+endif
+
 STAGE$(1)_T_$(2)_H_$(3) :=                                             \
-       $$(Q)$$(call CFG_RUN_TARG_$(3),$(1),                            \
-               $$(CFG_VALGRIND_COMPILE$(1))                    \
+       $$(Q)$$(RPATH_VAR$(1)_T_$(2)_H_$(3))                            \
+               $$(call CFG_RUN_TARG_$(3),$(1),                         \
+               $$(CFG_VALGRIND_COMPILE$(1))                            \
                $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3))                     \
                --cfg $$(CFGFLAG$(1)_T_$(2)_H_$(3))                     \
                $$(CFG_RUSTC_FLAGS) $$(EXTRAFLAGS_STAGE$(1)) --target=$(2)) \
                 $$(RUSTC_FLAGS_$(2))
 
-PERF_STAGE$(1)_T_$(2)_H_$(3) :=                                \
+PERF_STAGE$(1)_T_$(2)_H_$(3) :=                                                \
        $$(Q)$$(call CFG_RUN_TARG_$(3),$(1),                            \
-               $$(CFG_PERF_TOOL)                                               \
+               $$(CFG_PERF_TOOL)                                       \
                $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3))                     \
                --cfg $$(CFGFLAG$(1)_T_$(2)_H_$(3))                     \
                $$(CFG_RUSTC_FLAGS) $$(EXTRAFLAGS_STAGE$(1)) --target=$(2)) \
@@ -575,13 +443,12 @@ define DEF_RUSTC_STAGE_TARGET
 # $(2) == stage
 
 rustc-stage$(2)-H-$(1):                                                        \
-       $$(foreach target,$$(CFG_TARGET),       \
-               $$(SREQ$(2)_T_$$(target)_H_$(1)))
+       $$(foreach target,$$(CFG_TARGET),$$(SREQ$(2)_T_$$(target)_H_$(1)))
 
 endef
 
-$(foreach host,$(CFG_HOST),                                                    \
- $(eval $(foreach stage,1 2 3,                                                                 \
+$(foreach host,$(CFG_HOST),                                            \
+ $(eval $(foreach stage,1 2 3,                                         \
   $(eval $(call DEF_RUSTC_STAGE_TARGET,$(host),$(stage))))))
 
 rustc-stage1: rustc-stage1-H-$(CFG_BUILD)
@@ -617,7 +484,7 @@ CFG_INFO := $(info cfg: *** compiler is in snapshot transition ***)
 CFG_INFO := $(info cfg: *** stage2 and later will not be built ***)
 CFG_INFO := $(info cfg:)
 
-#XXX This is surely busted
+#FIXME This is surely busted
 all: $(SREQ1$(CFG_BUILD)) $(GENERATED) docs
 
 else
@@ -682,7 +549,6 @@ include $(CFG_SRC_DIR)mk/target.mk
 include $(CFG_SRC_DIR)mk/host.mk
 include $(CFG_SRC_DIR)mk/stage0.mk
 include $(CFG_SRC_DIR)mk/rustllvm.mk
-include $(CFG_SRC_DIR)mk/tools.mk
 include $(CFG_SRC_DIR)mk/docs.mk
 include $(CFG_SRC_DIR)mk/llvm.mk
 
index f758d75fe760032a47979dc242f7e754e167c7ad..b771e3923ce4561ba0c101cd3538a2a0b49dbf68 100755 (executable)
--- a/configure
+++ b/configure
@@ -382,6 +382,7 @@ opt ccache 0 "invoke gcc/clang via ccache to reuse object files between builds"
 opt local-rust 0 "use an installed rustc rather than downloading a snapshot"
 opt pax-flags 0 "apply PaX flags to rustc binaries (required for GRSecurity/PaX-patched kernels)"
 opt inject-std-version 1 "inject the current compiler version of libstd into programs"
+opt rpath 1 "build rpaths into rustc itself"
 valopt prefix "/usr/local" "set installation prefix"
 valopt local-rust-root "/usr/local" "set prefix for local rust binary"
 valopt llvm-root "" "set LLVM root"
@@ -915,6 +916,10 @@ do
         LLVM_OPTS="$LLVM_OPTS --disable-terminfo"
         # Try to have LLVM pull in as few dependencies as possible (#9397)
         LLVM_OPTS="$LLVM_OPTS --disable-zlib --disable-libffi"
+        # LLVM says it needs a "new" clang/gcc, but we seem to get by ok with
+        # older versions on the bots. Get by for a little longer by asking it to
+        # not do version detection
+        LLVM_OPTS="$LLVM_OPTS --disable-compiler-version-checks"
 
         # Use win32 native thread/lock apis instead of pthread wrapper.
         # (llvm's configure tries to find pthread first, so we have to disable it explicitly.)
index 770b0ad14218e5fae64b754b754705faf5c718ee..a92980d5e703d35965030567b90167eae2c70d2c 100644 (file)
@@ -48,7 +48,7 @@ let y: i64 = x.unwrap();
 
 Use [`File::open`](http://static.rust-lang.org/doc/master/std/io/fs/struct.File.html#method.open) to create a [`File`](http://static.rust-lang.org/doc/master/std/io/fs/struct.File.html) struct, which implements the [`Reader`](http://static.rust-lang.org/doc/master/std/io/trait.Reader.html) trait.
 
-~~~ {.xfail-test}
+~~~ {.ignore}
 use std::path::Path;
 use std::io::fs::File;
 
@@ -168,7 +168,7 @@ let _ = close(Door::<Open>(~"front"));
 
 Attempting to close a closed door is prevented statically:
 
-~~~ {.xfail-test}
+~~~ {.ignore}
 let _ = close(Door::<Closed>(~"front")); // error: mismatched types: expected `main::Door<main::Open>` but found `main::Door<main::Closed>`
 ~~~
 
@@ -196,7 +196,7 @@ Window* createWindow(int width, int height);
 
 You can use a zero-element `enum` ([phantom type](#how-do-i-express-phantom-types)) to represent the opaque object handle. The FFI would look like this:
 
-~~~ {.xfail-test}
+~~~ {.ignore}
 enum Window {}
 extern "C" {
     fn createWindow(width: c_int, height: c_int) -> *Window;
index 3099cc62b1a3ab44877cee17a323ae7f17a8c9ff..d97de7799024cbacb5e6ba8811e87bc9003f1349 100644 (file)
@@ -45,7 +45,6 @@ An example program that does this task reads like this:
 
 ~~~~
 # #[allow(unused_imports)];
-# extern mod extra;
 use std::io::{BufferedReader, File};
 # mod BufferedReader {
 #     use std::io::File;
@@ -243,7 +242,6 @@ and trapping its exit status using `task::try`:
 
 ~~~~
 # #[allow(unused_imports)];
-# extern mod extra;
 use std::io::{BufferedReader, File};
 use std::task;
 # mod BufferedReader {
@@ -263,7 +261,7 @@ use std::task;
 fn main() {
 
     // Isolate failure within a subtask.
-    let result = do task::try {
+    let result = task::try(proc() {
 
         // The protected logic.
         let pairs = read_int_pairs();
@@ -271,7 +269,7 @@ fn main() {
             println!("{:4.4d}, {:4.4d}", a, b);
         }
 
-    };
+    });
     if result.is_err() {
             println!("parsing failed");
     }
@@ -347,7 +345,6 @@ but similarly clear as the version that used `fail!` in the logic where the erro
 
 ~~~~
 # #[allow(unused_imports)];
-# extern mod extra;
 use std::io::{BufferedReader, File};
 # mod BufferedReader {
 #     use std::io::File;
@@ -416,7 +413,6 @@ and replaces bad input lines with the pair `(-1,-1)`:
 
 ~~~~
 # #[allow(unused_imports)];
-# extern mod extra;
 use std::io::{BufferedReader, File};
 # mod BufferedReader {
 #     use std::io::File;
@@ -491,7 +487,6 @@ Changing the condition's return type from `(int,int)` to `Option<(int,int)>` wil
 
 ~~~~
 # #[allow(unused_imports)];
-# extern mod extra;
 use std::io::{BufferedReader, File};
 # mod BufferedReader {
 #     use std::io::File;
@@ -576,8 +571,7 @@ This can be encoded in the handler API by introducing a helper type: `enum Malfo
 
 ~~~~
 # #[allow(unused_imports)];
-# extern mod extra;
-use std::io::File;
+use std::io::{BufferedReader, File};
 # mod BufferedReader {
 #     use std::io::File;
 #     use std::io::MemReader;
@@ -700,7 +694,6 @@ a second condition and a helper function will suffice:
 
 ~~~~
 # #[allow(unused_imports)];
-# extern mod extra;
 use std::io::{BufferedReader, File};
 # mod BufferedReader {
 #     use std::io::File;
index 628e4f223b446b19396c3fc08f2d5e54cea26c9f..1c79be1eb824777f83b979b34b454a1f36012297 100644 (file)
@@ -90,7 +90,7 @@ Reaching the end of the iterator is signalled by returning `None` instead of
 # fn main() {}
 /// A stream of N zeroes
 struct ZeroStream {
-    priv remaining: uint
+    remaining: uint
 }
 
 impl ZeroStream {
@@ -270,7 +270,7 @@ Containers can provide conversion from iterators through `collect` by
 implementing the `FromIterator` trait. For example, the implementation for
 vectors is as follows:
 
-~~~ {.xfail-test}
+~~~ {.ignore}
 impl<A> FromIterator<A> for ~[A] {
     pub fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> ~[A] {
         let (lower, _) = iterator.size_hint();
@@ -288,7 +288,7 @@ impl<A> FromIterator<A> for ~[A] {
 The `Iterator` trait provides a `size_hint` default method, returning a lower
 bound and optionally on upper bound on the length of the iterator:
 
-~~~ {.xfail-test}
+~~~ {.ignore}
 fn size_hint(&self) -> (uint, Option<uint>) { (0, None) }
 ~~~
 
@@ -305,7 +305,7 @@ The `ZeroStream` from earlier can provide an exact lower and upper bound:
 # fn main() {}
 /// A stream of N zeroes
 struct ZeroStream {
-    priv remaining: uint
+    remaining: uint
 }
 
 impl ZeroStream {
index 217eab527582ef020f97e251c173eb392bb81edd..c892c06902a35ce7ffdbce4bde37d0578c7677a6 100644 (file)
@@ -11,7 +11,7 @@ snappy includes a C interface (documented in
 The following is a minimal example of calling a foreign function which will
 compile if snappy is installed:
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 use std::libc::size_t;
 
 #[link(name = "snappy")]
@@ -43,7 +43,7 @@ keeping the binding correct at runtime.
 
 The `extern` block can be extended to cover the entire snappy API:
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 use std::libc::{c_int, size_t};
 
 #[link(name = "snappy")]
@@ -76,7 +76,7 @@ vectors as pointers to memory. Rust's vectors are guaranteed to be a contiguous
 length is number of elements currently contained, and the capacity is the total size in elements of
 the allocated memory. The length is less than or equal to the capacity.
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 pub fn validate_compressed_buffer(src: &[u8]) -> bool {
     unsafe {
         snappy_validate_compressed_buffer(src.as_ptr(), src.len() as size_t) == 0
@@ -96,7 +96,7 @@ required capacity to hold the compressed output. The vector can then be passed t
 `snappy_compress` function as an output parameter. An output parameter is also passed to retrieve
 the true length after compression for setting the length.
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 pub fn compress(src: &[u8]) -> ~[u8] {
     unsafe {
         let srclen = src.len() as size_t;
@@ -116,7 +116,7 @@ pub fn compress(src: &[u8]) -> ~[u8] {
 Decompression is similar, because snappy stores the uncompressed size as part of the compression
 format and `snappy_uncompressed_length` will retrieve the exact buffer size required.
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 pub fn uncompress(src: &[u8]) -> Option<~[u8]> {
     unsafe {
         let srclen = src.len() as size_t;
@@ -263,7 +263,7 @@ to the C library and afterwards be invoked from there.
 A basic example is:
 
 Rust code:
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 extern fn callback(a:i32) {
     println!("I'm called from C with value {0}", a);
 }
@@ -283,7 +283,7 @@ fn main() {
 ~~~~
 
 C code:
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 typedef void (*rust_callback)(int32_t);
 rust_callback cb;
 
@@ -303,18 +303,18 @@ which would call back to `callback()` in Rust.
 
 ## Targetting callbacks to Rust objects
 
-The former example showed how a global function can be called from C-Code.
+The former example showed how a global function can be called from C code.
 However it is often desired that the callback is targetted to a special
 Rust object. This could be the object that represents the wrapper for the
 respective C object. 
 
 This can be achieved by passing an unsafe pointer to the object down to the
 C library. The C library can then include the pointer to the Rust object in
-the notification. This will provide a unsafe possibility to access the 
-referenced Rust object in callback.
+the notification. This will allow the callback to unsafely access the
+referenced Rust object.
 
 Rust code:
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 
 struct RustObject {
     a: i32,
@@ -346,7 +346,7 @@ fn main() {
 ~~~~
 
 C code:
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 typedef void (*rust_callback)(int32_t);
 void* cb_target;
 rust_callback cb;
@@ -364,25 +364,25 @@ void trigger_callback() {
 
 ## Asynchronous callbacks
 
-In the already given examples the callbacks are invoked as a direct reaction
+In the previously given examples the callbacks are invoked as a direct reaction
 to a function call to the external C library.
-The control over the current thread switched from Rust to C to Rust for the
+The control over the current thread is switched from Rust to C to Rust for the
 execution of the callback, but in the end the callback is executed on the
 same thread (and Rust task) that lead called the function which triggered
 the callback.
 
-Things get more complicated when the external library spawns it's own threads
+Things get more complicated when the external library spawns its own threads
 and invokes callbacks from there.
-In these cases access to Rust data structures inside he callbacks is
+In these cases access to Rust data structures inside the callbacks is
 especially unsafe and proper synchronization mechanisms must be used.
-Besides classical synchronization mechanisms like mutexes one possibility in
+Besides classical synchronization mechanisms like mutexes, one possibility in
 Rust is to use channels (in `std::comm`) to forward data from the C thread
 that invoked the callback into a Rust task.
 
 If an asychronous callback targets a special object in the Rust address space
 it is also absolutely necessary that no more callbacks are performed by the 
-C library after the respective Rust object get's destroyed. 
-This can be achieved by unregistering the callback it the object's
+C library after the respective Rust object gets destroyed. 
+This can be achieved by unregistering the callback in the object's
 destructor and designing the library in a way that guarantees that no
 callback will be performed after unregistration.
 
@@ -440,7 +440,7 @@ the `link_args` attribute. This attribute is applied to `extern` blocks and
 specifies raw flags which need to get passed to the linker when producing an
 artifact. An example usage would be:
 
-~~~ {.xfail-test}
+~~~ {.ignore}
 #[link_args = "-foo -bar -baz"]
 extern {}
 ~~~
@@ -476,7 +476,7 @@ Foreign APIs often export a global variable which could do something like track
 global state. In order to access these variables, you declare them in `extern`
 blocks with the `static` keyword:
 
-~~~{.xfail-test}
+~~~{.ignore}
 use std::libc;
 
 #[link(name = "readline")]
@@ -494,7 +494,7 @@ Alternatively, you may need to alter global state provided by a foreign
 interface. To do this, statics can be declared with `mut` so rust can mutate
 them.
 
-~~~{.xfail-test}
+~~~{.ignore}
 use std::libc;
 use std::ptr;
 
index ad1fed54c97262b9ed9a589c5cc9ad690008e50a..d31b0eed8492a8548f07dc4ce3e3e0cd141d7bf7 100644 (file)
@@ -299,7 +299,7 @@ _as soon as its owning reference changes or goes out of
 scope_. Therefore, a program like this is illegal (and would be
 rejected by the compiler):
 
-~~~ {.xfail-test}
+~~~ {.ignore}
 fn example3() -> int {
     let mut x = ~X {f: 3};
     let y = &x.f;
@@ -346,7 +346,7 @@ modify the previous example to introduce additional owned pointers
 and structs, and the compiler will still be able to detect possible
 mutations:
 
-~~~ {.xfail-test}
+~~~ {.ignore}
 fn example3() -> int {
     struct R { g: int }
     struct S { f: ~R }
@@ -524,7 +524,7 @@ the compiler accepts the function `get_x()`.
 To emphasize this point, let’s look at a variation on the example, this
 time one that does not compile:
 
-~~~ {.xfail-test}
+~~~ {.ignore}
 struct Point {x: f64, y: f64}
 fn get_x_sh(p: @Point) -> &f64 {
     &p.x // Error reported here
@@ -597,7 +597,7 @@ example:
 # }
                                                      // -+ r
 fn select_based_on_unit_circle<'r, T>(               //  |-+ B
-    threshold: f64, a: &'r T, b: &'r T) -> &'r T { //  | |
+    threshold: f64, a: &'r T, b: &'r T) -> &'r T {   //  | |
                                                      //  | |
     let shape = Circle(Point {x: 0., y: 0.}, 1.);    //  | |
     select(&shape, threshold, a, b)                  //  | |
index caa149c6e140f8406bc0988b87fd4d00a8586de7..19696b42a3747e7ff156c52611a355ae9263fe21 100644 (file)
@@ -21,7 +21,7 @@ fn succ(x: &int) -> int { *x + 1 }
 
 So I wrote this code to try it out:
 
-~~~rust{.xfail-test}
+~~~rust{.ignore}
 fn main() {
     let number = 5;
     let succ_number = succ(number);
@@ -221,9 +221,9 @@ struct Point {
 
 fn main() {
     let a = Point { x: 10, y: 20 };
-    do spawn {
+    spawn(proc() {
         println!("{}", a.x);
-    }
+    });
 }
 ~~~
 
@@ -238,9 +238,9 @@ struct Point {
 
 fn main() {
     let a = ~Point { x: 10, y: 20 };
-    do spawn {
+    spawn(proc() {
         println!("{}", a.x);
-    }
+    });
 }
 ~~~
 
@@ -261,7 +261,7 @@ program is very large and complicated.
 
 For example, let's say you're using an owned pointer, and you want to do this:
 
-~~~rust{.xfail-test}
+~~~rust{.ignore}
 struct Point {
     x: int,
     y: int,
@@ -369,7 +369,7 @@ This theory is called 'region pointers,' and involve a concept called
 'lifetimes'. Here's the simple explanation: would you expect this code to
 compile?
 
-~~~rust{.xfail-test}
+~~~rust{.ignore}
 fn main() {
     println!("{}", x);
     let x = 5;
@@ -398,7 +398,7 @@ Here, we're borrowing a pointer to `x` inside of the `if`. The compiler, however
 is able to determine that that pointer will go out of scope without `x` being
 mutated, and therefore, lets us pass. This wouldn't work:
 
-~~~rust{.xfail-test}
+~~~rust{.ignore}
 fn main() {
     let mut x = ~5;
     if *x < 10 {
index 86a8c23d947b1f0d0d3f31868852ac5e96a94abb..b6a54b042e96acf77887d2a8305ae22929730467 100644 (file)
@@ -176,7 +176,7 @@ implemented in user-space.
 The primary concern of an M:N runtime is that a Rust task cannot block itself in
 a syscall. If this happens, then the entire OS thread is frozen and unavailable
 for running more Rust tasks, making this a (M-1):N runtime (and you can see how
-this can reach 0/deadlock. By using asynchronous I/O under the hood (all I/O
+this can reach 0/deadlock). By using asynchronous I/O under the hood (all I/O
 still looks synchronous in terms of code), OS threads are never blocked until
 the appropriate time comes.
 
@@ -202,7 +202,7 @@ Some benefits of using libgreen are:
 
 M:N threading is built upon the concept of a pool of M OS threads (which
 libgreen refers to as schedulers), able to run N Rust tasks. This abstraction is
-encompassed in libgreen's [`SchedPool`][schedpool] type. This type allows for
+encompassed in libgreen's [`SchedPool`](green/struct.SchedPool.html) type. This type allows for
 fine-grained control over the pool of schedulers which will be used to run Rust
 tasks.
 
@@ -236,9 +236,9 @@ extern mod green;
 
 #[start]
 fn start(argc: int, argv: **u8) -> int {
-    do green::start(argc, argv) {
+    green::start(argc, argv, proc() {
         main();
-    }
+    })
 }
 
 fn main() {}
index 746e7f065cca98ce4520b4a7d561925158c7eaa2..c3bdbe3a3ee8992126abee557864b10b84052caa 100644 (file)
@@ -77,11 +77,6 @@ spawn(print_message);
 
 // Print something more profound in a different task using a lambda expression
 spawn(proc() println!("I am also running in a different task!") );
-
-// The canonical way to spawn is using `do` notation
-do spawn {
-    println!("I too am running in a different task!");
-}
 ~~~~
 
 In Rust, there is nothing special about creating tasks: a task is not a
@@ -103,10 +98,10 @@ an environment that it carries across tasks.
 // Generate some state locally
 let child_task_number = generate_task_number();
 
-do spawn {
+spawn(proc() {
     // Capture it in the remote task
     println!("I am child number {}", child_task_number);
-}
+});
 ~~~
 
 ## Communication
@@ -132,10 +127,10 @@ concurrently:
 
 let (port, chan): (Port<int>, Chan<int>) = Chan::new();
 
-do spawn || {
+spawn(proc() {
     let result = some_expensive_computation();
     chan.send(result);
-}
+});
 
 some_other_expensive_computation();
 let result = port.recv();
@@ -160,10 +155,10 @@ spawns the child task.
 # use std::task::spawn;
 # fn some_expensive_computation() -> int { 42 }
 # let (port, chan) = Chan::new();
-do spawn || {
+spawn(proc() {
     let result = some_expensive_computation();
     chan.send(result);
-}
+});
 ~~~~
 
 Notice that the creation of the task closure transfers `chan` to the child
@@ -190,20 +185,20 @@ senders cannot use a single `Chan`, and multiple receivers cannot use a single
 `Port`.  What if our example needed to compute multiple results across a number
 of tasks? The following program is ill-typed:
 
-~~~ {.xfail-test}
+~~~ {.ignore}
 # use std::task::{spawn};
 # fn some_expensive_computation() -> int { 42 }
 let (port, chan) = Chan::new();
 
-do spawn {
+spawn(proc() {
     chan.send(some_expensive_computation());
-}
+});
 
 // ERROR! The previous spawn statement already owns the channel,
 // so the compiler will not allow it to be captured again
-do spawn {
+spawn(proc() {
     chan.send(some_expensive_computation());
-}
+});
 ~~~
 
 Instead we can use a `SharedChan`, a type that allows a single
@@ -217,9 +212,9 @@ let (port, chan) = SharedChan::new();
 for init_val in range(0u, 3) {
     // Create a new channel handle to distribute to the child task
     let child_chan = chan.clone();
-    do spawn {
+    spawn(proc() {
         child_chan.send(some_expensive_computation(init_val));
-    }
+    });
 }
 
 let result = port.recv() + port.recv() + port.recv();
@@ -247,9 +242,9 @@ might look like the example below.
 // Create a vector of ports, one for each child task
 let ports = vec::from_fn(3, |init_val| {
     let (port, chan) = Chan::new();
-    do spawn {
+    spawn(proc() {
         chan.send(some_expensive_computation(init_val));
-    }
+    });
     port
 });
 
@@ -296,7 +291,7 @@ fn partial_sum(start: uint) -> f64 {
 }
 
 fn main() {
-    let mut futures = vec::from_fn(1000, |ind| do extra::future::Future::spawn { partial_sum(ind) });
+    let mut futures = vec::from_fn(1000, |ind| extra::future::Future::spawn( proc() { partial_sum(ind) }));
 
     let mut final_res = 0f64;
     for ft in futures.mut_iter()  {
@@ -339,11 +334,11 @@ fn main() {
         let (port, chan)  = Chan::new();
         chan.send(numbers_arc.clone());
 
-        do spawn {
+        spawn(proc() {
             let local_arc : Arc<~[f64]> = port.recv();
             let task_numbers = local_arc.get();
             println!("{}-norm = {}", num, pnorm(task_numbers, num));
-        }
+        });
     }
 }
 ~~~
@@ -413,17 +408,17 @@ pattern-match on a result to check whether it's an `Ok` result with an `int`
 field (representing a successful result) or an `Err` result (representing
 termination with an error).
 
-~~~{.xfail-test .linked-failure}
+~~~{.ignore .linked-failure}
 # use std::task;
 # fn some_condition() -> bool { false }
 # fn calculate_result() -> int { 0 }
-let result: Result<int, ()> = do task::try {
+let result: Result<int, ()> = task::try(proc() {
     if some_condition() {
         calculate_result()
     } else {
         fail!("oops!");
     }
-};
+});
 assert!(result.is_err());
 ~~~
 
@@ -463,7 +458,7 @@ that repeatedly receives a `uint` message, converts it to a string, and sends
 the string in response.  The child terminates when it receives `0`.
 Here is the function that implements the child task:
 
-~~~{.xfail-test .linked-failure}
+~~~{.ignore .linked-failure}
 # use extra::comm::DuplexStream;
 # use std::uint;
 fn stringifier(channel: &DuplexStream<~str, uint>) {
@@ -486,7 +481,7 @@ response itself is simply the stringified version of the received value,
 
 Here is the code for the parent task:
 
-~~~{.xfail-test .linked-failure}
+~~~{.ignore .linked-failure}
 # use std::task::spawn;
 # use std::uint;
 # use extra::comm::DuplexStream;
@@ -502,9 +497,9 @@ Here is the code for the parent task:
 
 let (from_child, to_child) = DuplexStream::new();
 
-do spawn {
+spawn(proc() {
     stringifier(&to_child);
-};
+});
 
 from_child.send(22);
 assert!(from_child.recv() == ~"22");
index 53ad4217145aa29593984dd69c601fab298bd5a4..d3270a96d803682a317ec6cbca01a3d4cc22fa73 100644 (file)
@@ -37,6 +37,10 @@ li {list-style-type: none; }
 * [The Rust parser, `libsyntax`](syntax/index.html)
 * [The Rust compiler, `librustc`](rustc/index.html)
 
+* [The `arena` allocation library](arena/index.html)
+* [The `flate` compression library](flate/index.html)
+* [The `glob` file path matching library](glob/index.html)
+
 # Tooling
 
 * [The `rustdoc` manual](rustdoc.html)
@@ -47,11 +51,11 @@ li {list-style-type: none; }
 * [Language FAQ](complement-lang-faq.html)
 * [Project FAQ](complement-project-faq.html)
 * [Usage FAQ](complement-usage-faq.html)
-* [Code cheatsheet](complement-cheatsheet.html) - "How do I do X?"  
+* [Code cheatsheet](complement-cheatsheet.html) - "How do I do X?"
 * [How to submit a bug report](complement-bugreport.html)
 
 # External resources
 
-* The Rust [IRC channel](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust) - `#rust` on irc.mozilla.org  
+* The Rust [IRC channel](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust) - `#rust` on irc.mozilla.org
 * The Rust community on [Reddit](http://reddit.com/r/rust)
 * The Rust [wiki](http://github.com/mozilla/rust/wiki)
index 5c13cd20c3d48ff3c539ff6bb138d423edfc9db2..0089e4a81a3f2f793e33232dd7aacd64ecaed33a 100644 (file)
@@ -112,7 +112,7 @@ msgstr "## 演算子"
 #: doc/complement-cheatsheet.md:54
 #, fuzzy
 #| msgid "~~~~ use std::task::spawn;"
-msgid "~~~ {.xfail-test} use std::path::Path; use std::io::fs::File;"
+msgid "~~~ {.ignore} use std::path::Path; use std::io::fs::File;"
 msgstr ""
 "~~~~\n"
 "use std::task::spawn;"
index b61c8efece1fecac74f2de272bb83ab5f078043a..af1b566a0f4e7ffde9779291667eddc48d6ccf7b 100644 (file)
@@ -34,7 +34,7 @@ msgstr "[他言語間インターフェース (foreign function inferface)][ffi]
 #: doc/guide-ffi.md:16
 #, fuzzy
 #| msgid "~~~~ use std::task::spawn;"
-msgid "~~~~ {.xfail-test} use std::libc::size_t;"
+msgid "~~~~ {.ignore} use std::libc::size_t;"
 msgstr ""
 "~~~~\n"
 "use std::task::spawn;"
@@ -43,7 +43,7 @@ msgstr ""
 #: doc/guide-ffi.md:48
 #, fuzzy
 #| msgid "~~~~ use std::task::spawn;"
-msgid "~~~~ {.xfail-test} use std::libc::{c_int, size_t};"
+msgid "~~~~ {.ignore} use std::libc::{c_int, size_t};"
 msgstr ""
 "~~~~\n"
 "use std::task::spawn;"
@@ -67,7 +67,7 @@ msgstr ""
 #: doc/guide-ffi.md:344
 #, fuzzy
 #| msgid "~~~~ use std::task::spawn;"
-msgid "~~~{.xfail-test} use std::libc;"
+msgid "~~~{.ignore} use std::libc;"
 msgstr ""
 "~~~~\n"
 "use std::task::spawn;"
@@ -76,7 +76,7 @@ msgstr ""
 #: doc/guide-ffi.md:363
 #, fuzzy
 #| msgid "~~~~ use std::task::spawn;"
-msgid "~~~{.xfail-test} use std::libc; use std::ptr;"
+msgid "~~~{.ignore} use std::libc; use std::ptr;"
 msgstr ""
 "~~~~\n"
 "use std::task::spawn;"
index e491afcfee766030da0ed97b75696c49d40f8c42..ef7c51f52cf0f98961d750fa77888a58af7d12c4 100644 (file)
@@ -63,7 +63,7 @@ msgstr ""
 #. type: Plain text
 #: doc/guide-lifetimes.md:48
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
 msgid ""
 "~~~\n"
 "# struct Point {x: f64, y: f64}\n"
@@ -72,7 +72,7 @@ msgid ""
 "let owned_box    : ~Point = ~Point {x: 7.0, y: 9.0};\n"
 "~~~\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "# struct Point { x: f64, y: f64 }\n"
 "let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
 "let origin = Point { x: 0.0, y: 0.0 };"
@@ -123,7 +123,7 @@ msgstr ""
 #. type: Plain text
 #: doc/guide-lifetimes.md:82
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
 msgid ""
 "~~~\n"
 "# struct Point {x: f64, y: f64}\n"
@@ -135,7 +135,7 @@ msgid ""
 "compute_distance(managed_box, owned_box);\n"
 "~~~\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "# struct Point { x: f64, y: f64 }\n"
 "let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
 "let origin = Point { x: 0.0, y: 0.0 };"
index bd23e1a466694280bec4869384fcf87235e1eb9d..e270babac8515052079c3eaf71c8ca3682ee05cc 100644 (file)
@@ -46,7 +46,7 @@ msgstr ""
 #. type: Plain text
 #: doc/guide-pointers.md:115
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
 msgid ""
 "fn main() {\n"
 "    let p0 = Point { x: 5, y: 10};\n"
@@ -54,7 +54,7 @@ msgid ""
 "    println!(\"{:?}\", p1);\n"
 "}\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "# struct Point { x: f64, y: f64 }\n"
 "let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
 "let origin = Point { x: 0.0, y: 0.0 };"
@@ -62,7 +62,7 @@ msgstr ""
 #. type: Plain text
 #: doc/guide-pointers.md:129
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
 msgid ""
 "~~~rust\n"
 "# struct Point {\n"
@@ -74,7 +74,7 @@ msgid ""
 "    Point { x: p.x + 1, y: p.y + 1}\n"
 "}\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "# struct Point { x: f64, y: f64 }\n"
 "let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
 "let origin = Point { x: 0.0, y: 0.0 };"
@@ -82,13 +82,13 @@ msgstr ""
 #. type: Plain text
 #: doc/guide-pointers.md:145
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
 msgid ""
 "fn transform(p: Point) -> Point {\n"
 "    Point { x: p.x + 1, y: p.y + 1}\n"
 "}\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "# struct Point { x: f64, y: f64 }\n"
 "let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
 "let origin = Point { x: 0.0, y: 0.0 };"
@@ -96,7 +96,7 @@ msgstr ""
 #. type: Plain text
 #: doc/guide-pointers.md:152
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
 msgid ""
 "fn main() {\n"
 "    let p0 = Point { x: 5, y: 10};\n"
@@ -105,7 +105,7 @@ msgid ""
 "}\n"
 "~~~\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "# struct Point { x: f64, y: f64 }\n"
 "let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
 "let origin = Point { x: 0.0, y: 0.0 };"
@@ -133,7 +133,7 @@ msgstr "# データ構造"
 #. type: Plain text
 #: doc/guide-pointers.md:229
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
 msgid ""
 "fn main() {\n"
 "    let a = Point { x: 10, y: 20 };\n"
@@ -143,7 +143,7 @@ msgid ""
 "}\n"
 "~~~\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "# struct Point { x: f64, y: f64 }\n"
 "let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
 "let origin = Point { x: 0.0, y: 0.0 };"
@@ -151,7 +151,7 @@ msgstr ""
 #. type: Plain text
 #: doc/guide-pointers.md:246
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
 msgid ""
 "fn main() {\n"
 "    let a = ~Point { x: 10, y: 20 };\n"
@@ -161,7 +161,7 @@ msgid ""
 "}\n"
 "~~~\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "# struct Point { x: f64, y: f64 }\n"
 "let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
 "let origin = Point { x: 0.0, y: 0.0 };"
@@ -176,7 +176,7 @@ msgstr "## マネージドボックス"
 #. type: Plain text
 #: doc/guide-pointers.md:277
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
 msgid ""
 "fn main() {\n"
 "    let a = ~Point { x: 10, y: 20 };\n"
@@ -186,7 +186,7 @@ msgid ""
 "}\n"
 "~~~\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "# struct Point { x: f64, y: f64 }\n"
 "let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
 "let origin = Point { x: 0.0, y: 0.0 };"
@@ -194,7 +194,7 @@ msgstr ""
 #. type: Plain text
 #: doc/guide-pointers.md:308
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
 msgid ""
 "fn main() {\n"
 "    let a = @Point { x: 10, y: 20 };\n"
@@ -204,7 +204,7 @@ msgid ""
 "}\n"
 "~~~\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "# struct Point { x: f64, y: f64 }\n"
 "let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
 "let origin = Point { x: 0.0, y: 0.0 };"
@@ -227,13 +227,13 @@ msgstr ""
 #. type: Plain text
 #: doc/guide-pointers.md:352
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
 msgid ""
 "fn main() {\n"
 "    let origin = @Point { x: 0.0, y: 0.0 };\n"
 "    let p1     = ~Point { x: 5.0, y: 3.0 };\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "# struct Point { x: f64, y: f64 }\n"
 "let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
 "let origin = Point { x: 0.0, y: 0.0 };"
@@ -241,16 +241,16 @@ msgstr ""
 #. type: Plain text
 #: doc/guide-pointers.md:378
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
 msgid ""
-"~~~rust{.xfail-test}\n"
+"~~~rust{.ignore}\n"
 "fn main() {\n"
 "    println!(\"{}\", x);\n"
 "    let x = 5;\n"
 "}\n"
 "~~~\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "// main.rs\n"
 "extern mod world;\n"
 "fn main() { println(~\"hello \" + world::explore()); }\n"
index d8d2b808e9d5a50b876817022a7dc40c57852083..04ac982d420c2114bd50be3ca43b25f29d387a20 100644 (file)
@@ -40,14 +40,14 @@ msgstr "## 他のクレートの利用"
 #. type: Plain text
 #: doc/guide-rustpkg.md:22
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
 msgid ""
 "fn main() {\n"
 "    hello::world();\n"
 "}\n"
 "~~~~\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "// main.rs\n"
 "extern mod world;\n"
 "fn main() { println(~\"hello \" + world::explore()); }\n"
@@ -77,14 +77,14 @@ msgstr "# イントロダクション"
 #. type: Plain text
 #: doc/guide-rustpkg.md:149
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
 msgid ""
 "pub fn world() {\n"
 "    println!(\"Hello, world.\");\n"
 "}\n"
 "~~~\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "// main.rs\n"
 "extern mod world;\n"
 "fn main() { println(~\"hello \" + world::explore()); }\n"
index d3567449e0e9eb3f4fe953e2a4d0c25e9edb381e..c43d7ed5c8b27a30d02c7c5df7d88c124094f127 100644 (file)
@@ -164,7 +164,7 @@ msgstr "## 他のクレートの利用"
 #: doc/rust.md:788
 #, fuzzy
 #| msgid "~~~~ {.ignore} let foo = 10;"
-msgid "~~~~ {.xfail-test} extern mod pcre;"
+msgid "~~~~ {.ignore} extern mod pcre;"
 msgstr ""
 "~~~~ {.ignore}\n"
 "let foo = 10;"
@@ -413,19 +413,19 @@ msgstr ""
 #: doc/rust.md:1395
 #, fuzzy
 #| msgid ""
-#| "~~~ {.xfail-test} use std::f64::consts::pi; # trait Shape { fn "
+#| "~~~ {.ignore} use std::f64::consts::pi; # trait Shape { fn "
 #| "area(&self) -> f64; } # trait Circle : Shape { fn radius(&self) -> f64; } "
 #| "# struct Point { x: f64, y: f64 } # struct CircleStruct { center: Point, "
 #| "radius: f64 } # impl Circle for CircleStruct { fn radius(&self) -> f64 "
 #| "{ (self.area() / pi).sqrt() } } # impl Shape for CircleStruct { fn "
 #| "area(&self) -> f64 { pi * square(self.radius) } }"
 msgid ""
-"~~~~ {.xfail-test} # trait Shape { fn area(&self) -> f64; } # trait Circle : "
+"~~~~ {.ignore} # trait Shape { fn area(&self) -> f64; } # trait Circle : "
 "Shape { fn radius(&self) -> f64; } # impl Shape for int { fn area(&self) -> "
 "f64 { 0.0 } } # impl Circle for int { fn radius(&self) -> f64 { 0.0 } } # "
 "let mycircle = 0;"
 msgstr ""
-"~~~ {.xfail-test}\n"
+"~~~ {.ignore}\n"
 "use std::f64::consts::pi;\n"
 "# trait Shape { fn area(&self) -> f64; }\n"
 "# trait Circle : Shape { fn radius(&self) -> f64; }\n"
@@ -613,7 +613,7 @@ msgstr "## 構文拡張"
 #: doc/rust.md:2400
 #, fuzzy
 #| msgid "~~~~ use std::task::spawn;"
-msgid "~~~~ {.xfail-test} # use std::task; # do task::spawn {"
+msgid "~~~~ {.ignore} # use std::task; # do task::spawn {"
 msgstr ""
 "~~~~\n"
 "use std::task::spawn;"
@@ -928,14 +928,14 @@ msgstr "# クロージャ"
 #. type: Plain text
 #: doc/rust.md:3299
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
 msgid ""
 "fn main() {\n"
 "   print(@10 as @Printable);\n"
 "}\n"
 "~~~~\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "// main.rs\n"
 "extern mod world;\n"
 "fn main() { println(~\"hello \" + world::explore()); }\n"
index 1c47dba9f04b4e3b4b8ec4431e93a08f905e5ca9..ddbef4c93cca573942cec5ac033edd54041ac889 100644 (file)
@@ -422,7 +422,7 @@ msgstr ""
 #. type: Plain text
 #: doc/tutorial.md:136
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
 msgid ""
 "~~~~\n"
 "fn main() {\n"
@@ -430,7 +430,7 @@ msgid ""
 "}\n"
 "~~~~\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "// main.rs\n"
 "extern mod world;\n"
 "fn main() { println(~\"hello \" + world::explore()); }\n"
@@ -1390,10 +1390,10 @@ msgstr ""
 #. type: Plain text
 #: doc/tutorial.md:604
 msgid ""
-"~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point "
+"~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point "
 "{ x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "# struct Point { x: f64, y: f64 }\n"
 "let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
 "let origin = Point { x: 0.0, y: 0.0 };"
@@ -2213,7 +2213,7 @@ msgstr ""
 #. type: Plain text
 #: doc/tutorial.md:1372
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
 msgid ""
 "~~~\n"
 "# struct Point { x: f64, y: f64 }\n"
@@ -2222,7 +2222,7 @@ msgid ""
 "let owned_box    : ~Point = ~Point { x: 7.0, y: 9.0 };\n"
 "~~~\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "# struct Point { x: f64, y: f64 }\n"
 "let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
 "let origin = Point { x: 0.0, y: 0.0 };"
@@ -2265,7 +2265,7 @@ msgstr ""
 #. type: Plain text
 #: doc/tutorial.md:1404
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
 msgid ""
 "~~~\n"
 "# struct Point{ x: f64, y: f64 };\n"
@@ -2277,7 +2277,7 @@ msgid ""
 "compute_distance(managed_box, owned_box);\n"
 "~~~\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "# struct Point { x: f64, y: f64 }\n"
 "let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
 "let origin = Point { x: 0.0, y: 0.0 };"
@@ -3442,14 +3442,14 @@ msgstr ""
 #: doc/tutorial.md:2067
 #, no-wrap
 msgid ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "// This does not compile\n"
 "fn head_bad<T>(v: &[T]) -> T {\n"
 "    v[0] // error: copying a non-copyable value\n"
 "}\n"
 "~~~~\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "// このコードはコンパイルできない\n"
 "fn head_bad<T>(v: &[T]) -> T {\n"
 "    v[0] // error: copying a non-copyable value\n"
@@ -3622,7 +3622,7 @@ msgstr ""
 #. type: Plain text
 #: doc/tutorial.md:2148
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
 msgid ""
 "~~~~\n"
 "trait Printable {\n"
@@ -3630,7 +3630,7 @@ msgid ""
 "}\n"
 "~~~~\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "// main.rs\n"
 "extern mod world;\n"
 "fn main() { println(~\"hello \" + world::explore()); }\n"
@@ -4077,7 +4077,7 @@ msgstr "`Circle` トレイトの実装は、 `Shape` を実装した型につい
 #. type: Plain text
 #: doc/tutorial.md:2488
 #, fuzzy, no-wrap
-#| msgid "~~~ {.xfail-test} use std::f64::consts::pi; # trait Shape { fn area(&self) -> f64; } # trait Circle : Shape { fn radius(&self) -> f64; } # struct Point { x: f64, y: f64 } # struct CircleStruct { center: Point, radius: f64 } # impl Circle for CircleStruct { fn radius(&self) -> f64 { (self.area() / pi).sqrt() } } # impl Shape for CircleStruct { fn area(&self) -> f64 { pi * square(self.radius) } }"
+#| msgid "~~~ {.ignore} use std::f64::consts::pi; # trait Shape { fn area(&self) -> f64; } # trait Circle : Shape { fn radius(&self) -> f64; } # struct Point { x: f64, y: f64 } # struct CircleStruct { center: Point, radius: f64 } # impl Circle for CircleStruct { fn radius(&self) -> f64 { (self.area() / pi).sqrt() } } # impl Shape for CircleStruct { fn area(&self) -> f64 { pi * square(self.radius) } }"
 msgid ""
 "~~~~\n"
 "use std::f64::consts::PI;\n"
@@ -4094,7 +4094,7 @@ msgid ""
 "}\n"
 "~~~~\n"
 msgstr ""
-"~~~ {.xfail-test}\n"
+"~~~ {.ignore}\n"
 "use std::f64::consts::pi;\n"
 "# trait Shape { fn area(&self) -> f64; }\n"
 "# trait Circle : Shape { fn radius(&self) -> f64; }\n"
@@ -4153,21 +4153,21 @@ msgstr ""
 #: doc/tutorial.md:2517
 #, fuzzy
 #| msgid ""
-#| "~~~ {.xfail-test} use std::f64::consts::pi; # trait Shape { fn "
+#| "~~~ {.ignore} use std::f64::consts::pi; # trait Shape { fn "
 #| "area(&self) -> f64; } # trait Circle : Shape { fn radius(&self) -> f64; } "
 #| "# struct Point { x: f64, y: f64 } # struct CircleStruct { center: Point, "
 #| "radius: f64 } # impl Circle for CircleStruct { fn radius(&self) -> f64 "
 #| "{ (self.area() / pi).sqrt() } } # impl Shape for CircleStruct { fn "
 #| "area(&self) -> f64 { pi * square(self.radius) } }"
 msgid ""
-"~~~ {.xfail-test} use std::f64::consts::PI; # trait Shape { fn area(&self) -"
+"~~~ {.ignore} use std::f64::consts::PI; # trait Shape { fn area(&self) -"
 "> f64; } # trait Circle : Shape { fn radius(&self) -> f64; } # struct Point "
 "{ x: f64, y: f64 } # struct CircleStruct { center: Point, radius: f64 } # "
 "impl Circle for CircleStruct { fn radius(&self) -> f64 { (self.area() / PI)."
 "sqrt() } } # impl Shape for CircleStruct { fn area(&self) -> f64 { PI * "
 "square(self.radius) } }"
 msgstr ""
-"~~~ {.xfail-test}\n"
+"~~~ {.ignore}\n"
 "use std::f64::consts::pi;\n"
 "# trait Shape { fn area(&self) -> f64; }\n"
 "# trait Circle : Shape { fn radius(&self) -> f64; }\n"
@@ -4265,7 +4265,7 @@ msgstr "## クレート"
 #. type: Plain text
 #: doc/tutorial.md:2567
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
 msgid ""
 "~~~~\n"
 "// main.rs\n"
@@ -4274,7 +4274,7 @@ msgid ""
 "}\n"
 "~~~~\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "// main.rs\n"
 "extern mod world;\n"
 "fn main() { println(~\"hello \" + world::explore()); }\n"
@@ -4305,14 +4305,14 @@ msgstr "## 標準ライブラリ"
 #. type: Plain text
 #: doc/tutorial.md:2600
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
 msgid ""
 "fn main() {\n"
 "    println!(\"Hello farm!\");\n"
 "}\n"
 "~~~~\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "// main.rs\n"
 "extern mod world;\n"
 "fn main() { println(~\"hello \" + world::explore()); }\n"
@@ -4328,12 +4328,12 @@ msgstr "## マネージドクロージャ"
 #. type: Plain text
 #: doc/tutorial.md:2620
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
 msgid ""
 "fn main() {\n"
 "    println!(\"Hello chicken!\");\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "// main.rs\n"
 "extern mod world;\n"
 "fn main() { println(~\"hello \" + world::explore()); }\n"
@@ -4374,7 +4374,7 @@ msgstr "# モジュールとクレート"
 #. type: Plain text
 #: doc/tutorial.md:2732
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
 msgid ""
 "fn main() {\n"
 "    println!(\"Hello farm!\");\n"
@@ -4382,7 +4382,7 @@ msgid ""
 "}\n"
 "~~~~\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "// main.rs\n"
 "extern mod world;\n"
 "fn main() { println(~\"hello \" + world::explore()); }\n"
@@ -4400,12 +4400,12 @@ msgstr ""
 #. type: Plain text
 #: doc/tutorial.md:2929
 #, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
 msgid ""
 "fn main() {\n"
 "    println!(\"Hello farm!\");\n"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "// main.rs\n"
 "extern mod world;\n"
 "fn main() { println(~\"hello \" + world::explore()); }\n"
@@ -4438,14 +4438,14 @@ msgstr ""
 #: doc/tutorial.md:3144
 #, fuzzy
 #| msgid ""
-#| "~~~~ {.xfail-test} extern mod farm; extern mod my_farm (name = \"farm\", "
+#| "~~~~ {.ignore} extern mod farm; extern mod my_farm (name = \"farm\", "
 #| "vers = \"2.5\"); extern mod my_auxiliary_farm (name = \"farm\", author = "
 #| "\"mjh\"); ~~~~"
 msgid ""
-"~~~~ {.xfail-test} extern mod farm; extern mod farm = \"farm#2.5\"; extern "
+"~~~~ {.ignore} extern mod farm; extern mod farm = \"farm#2.5\"; extern "
 "mod my_farm = \"farm\"; ~~~~"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "extern mod farm;\n"
 "extern mod my_farm (name = \"farm\", vers = \"2.5\");\n"
 "extern mod my_auxiliary_farm (name = \"farm\", author = \"mjh\");\n"
@@ -4507,13 +4507,13 @@ msgstr ""
 #: doc/tutorial.md:3185
 #, fuzzy
 #| msgid ""
-#| "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~"
+#| "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~"
 #| "\"hello \" + world::explore()); } ~~~~"
 msgid ""
-"~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println!(\"hello "
+"~~~~ {.ignore} // main.rs extern mod world; fn main() { println!(\"hello "
 "{}\", world::explore()); } ~~~~"
 msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
 "// main.rs\n"
 "extern mod world;\n"
 "fn main() { println(~\"hello \" + world::explore()); }\n"
index a4c2d269b001307b6786e36ff65084f54b08d327..503d1a1072b91abe1b35797db59c7f6855b7d3a2 100644 (file)
@@ -727,7 +727,7 @@ name as the module, plus the `.rs` extension.
 When a nested submodule is loaded from an external file,
 it is loaded from a subdirectory path that mirrors the module hierarchy.
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 // Load the `vec` module from `vec.rs`
 mod vec;
 
@@ -740,7 +740,7 @@ mod task {
 The directories and files used for loading external file modules can be influenced
 with the `path` attribute.
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 #[path = "task_files"]
 mod task {
     // Load the `local_data` module from `task_files/tls.rs`
@@ -784,7 +784,7 @@ assumed, equal to the `ident` given in the `extern_mod_decl`.
 
 Four examples of `extern mod` declarations:
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 extern mod pcre;
 
 extern mod extra; // equivalent to: extern mod extra = "extra";
@@ -939,7 +939,7 @@ appear in its signature. Each type parameter must be explicitly
 declared, in an angle-bracket-enclosed, comma-separated list following
 the function name.
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 fn iter<T>(seq: &[T], f: |T|) {
     for elt in seq.iter() { f(elt); }
 }
@@ -1389,7 +1389,7 @@ fn radius_times_area<T: Circle>(c: T) -> f64 {
 
 Likewise, supertrait methods may also be called on trait objects.
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 # trait Shape { fn area(&self) -> f64; }
 # trait Circle : Shape { fn radius(&self) -> f64; }
 # impl Shape for int { fn area(&self) -> f64 { 0.0 } }
@@ -1491,7 +1491,7 @@ By default external blocks assume that the library they are calling
 uses the standard C "cdecl" ABI.  Other ABIs may be specified using
 an `abi` string, as shown here:
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 // Interface to the Windows API
 extern "stdcall" { }
 ~~~~
@@ -1500,7 +1500,7 @@ The `link` attribute allows the name of the library to be specified. When
 specified the compiler will attempt to link against the native library of the
 specified name.
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 #[link(name = "crypto")]
 extern { }
 ~~~~
@@ -1704,7 +1704,7 @@ within. Attributes that are not terminated by a semi-colon apply to the next ent
 
 An example of attributes:
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 // General metadata applied to the enclosing module or crate.
 #[license = "BSD"];
 
@@ -1768,7 +1768,7 @@ For any lint check `C`:
 The lint checks supported by the compiler can be found via `rustc -W help`,
 along with their default settings.
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 mod m1 {
     // Missing documentation is ignored here
     #[allow(missing_doc)]
@@ -1787,7 +1787,7 @@ mod m1 {
 This example shows how one can use `allow` and `warn` to toggle
 a particular check on and off.
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 #[warn(missing_doc)]
 mod m2{
     #[allow(missing_doc)]
@@ -1809,7 +1809,7 @@ mod m2{
 This example shows how one can use `forbid` to disallow uses
 of `allow` for that lint check.
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 #[forbid(missing_doc)]
 mod m3 {
     // Attempting to toggle warning signals an error here
@@ -1827,7 +1827,7 @@ The definitions of these operations have to be easy for the compiler to find.
 The `lang` attribute makes it possible to declare these operations.
 For example, the `str` module in the Rust standard library defines the string equality function:
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 #[lang="str_eq"]
 pub fn eq_slice(a: &str, b: &str) -> bool {
     // details elided
@@ -2007,7 +2007,7 @@ by default. Items with not marked with a stability are considered to
 be unstable for the purposes of the lint. One can give an optional
 string that will be displayed when the lint flags the use of an item.
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 #[warn(unstable)];
 
 #[deprecated="replaced by `best`"]
@@ -2046,7 +2046,7 @@ considered a full-fleged language feature.
 
 For this reason, rust recognizes a special crate-level attribute of the form:
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 #[feature(feature1, feature2, feature3)]
 ~~~~
 
@@ -2403,7 +2403,7 @@ 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_.
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 # use std::task;
 # do task::spawn {
 
@@ -2751,52 +2751,6 @@ but must enclose it.
 
 A `loop` expression is only permitted in the body of a loop.
 
-### Do expressions
-
-~~~~ {.ebnf .gram}
-do_expr : "do" expr [ '|' ident_list '|' ] ? '{' block '}' ;
-~~~~
-
-A _do expression_ provides a more-familiar block syntax
-for invoking a function and passing it a newly-created a procedure.
-
-The optional `ident_list` and `block` provided in a `do` expression are parsed
-as though they constitute a procedure expression;
-if the `ident_list` is missing, an empty `ident_list` is implied.
-
-The procedure expression is then provided as a _trailing argument_
-to the outermost [call](#call-expressions) or
-[method call](#method-call-expressions) expression
-in the `expr` following `do`.
-If the `expr` is a [path expression](#path-expressions), it is parsed as though it is a call expression.
-If the `expr` is a [field expression](#field-expressions), it is parsed as though it is a method call expression.
-
-In this example, both calls to `f` are equivalent:
-
-~~~~
-# fn f(f: proc(int)) { }
-# fn g(i: int) { }
-
-f(proc(j) { g(j) });
-
-do f |j| {
-    g(j);
-}
-~~~~
-
-In this example, both calls to the (binary) function `k` are equivalent:
-
-~~~~
-# fn k(x:int, f: proc(int)) { }
-# fn l(i: int) { }
-
-k(3, proc(j) { l(j) });
-
-do k(3) |j| {
-   l(j);
-}
-~~~~
-
 ### For expressions
 
 ~~~~ {.ebnf .gram}
@@ -2864,14 +2818,15 @@ match_pat : pat [ ".." pat ] ? [ "if" expr ] ;
 
 A `match` expression branches on a *pattern*. The exact form of matching that
 occurs depends on the pattern. Patterns consist of some combination of
-literals, destructured enum constructors, structures, records and tuples, variable binding
-specifications, wildcards (`*`), and placeholders (`_`). A `match` expression has a *head
-expression*, which is the value to compare to the patterns. The type of the
-patterns must equal the type of the head expression.
+literals, destructured vectors or enum constructors, structures, records and
+tuples, variable binding specifications, wildcards (`..`), and placeholders
+(`_`). A `match` expression has a *head expression*, which is the value to
+compare to the patterns. The type of the patterns must equal the type of the
+head expression.
 
-In a pattern whose head expression has an `enum` type, a placeholder (`_`) stands for a
-*single* data field, whereas a wildcard `..` stands for *all* the fields of a particular
-variant. For example:
+In a pattern whose head expression has an `enum` type, a placeholder (`_`)
+stands for a *single* data field, whereas a wildcard `..` stands for *all* the
+fields of a particular variant. For example:
 
 ~~~~
 enum List<X> { Nil, Cons(X, ~List<X>) }
@@ -2885,11 +2840,35 @@ match x {
 }
 ~~~~
 
-The first pattern matches lists constructed by applying `Cons` to any head value, and a
-tail value of `~Nil`. The second pattern matches _any_ list constructed with `Cons`,
-ignoring the values of its arguments. The difference between `_` and `*` is that the pattern
-`C(_)` is only type-correct if `C` has exactly one argument, while the pattern `C(..)` is
-type-correct for any enum variant `C`, regardless of how many arguments `C` has.
+The first pattern matches lists constructed by applying `Cons` to any head
+value, and a tail value of `~Nil`. The second pattern matches _any_ list
+constructed with `Cons`, ignoring the values of its arguments. The difference
+between `_` and `..` is that the pattern `C(_)` is only type-correct if `C` has
+exactly one argument, while the pattern `C(..)` is type-correct for any enum
+variant `C`, regardless of how many arguments `C` has.
+
+Used inside a vector pattern, `..` stands for any number of elements. This
+wildcard can be used at most once for a given vector, which implies that it
+cannot be used to specifically match elements that are at an unknown distance
+from both ends of a vector, like `[.., 42, ..]`. If followed by a variable name,
+it will bind the corresponding slice to the variable. Example:
+
+~~~~
+fn is_symmetric(list: &[uint]) -> bool {
+    match list {
+        [] | [_]                   => true,
+        [x, ..inside, y] if x == y => is_symmetric(inside),
+        _                          => false
+    }
+}
+
+fn main() {
+    let sym     = &[0, 1, 4, 2, 4, 1, 0];
+    let not_sym = &[0, 1, 7, 2, 4, 1, 0];
+    assert!(is_symmetric(sym));
+    assert!(!is_symmetric(not_sym));
+}
+~~~~
 
 A `match` behaves differently depending on whether or not the head expression
 is an [lvalue or an rvalue](#lvalues-rvalues-and-temporaries).
@@ -2939,6 +2918,27 @@ This can be changed to bind to a reference by
 using the `ref` keyword,
 or to a mutable reference using `ref mut`.
 
+Subpatterns can also be bound to variables by the use of the syntax
+`variable @ pattern`.
+For example:
+
+~~~~
+enum List { Nil, Cons(uint, ~List) }
+
+fn is_sorted(list: &List) -> bool {
+    match *list {
+        Nil | Cons(_, ~Nil) => true,
+        Cons(x, ref r @ ~Cons(y, _)) => (x <= y) && is_sorted(*r)
+    }
+}
+
+fn main() {
+    let a = Cons(6, ~Cons(7, ~Cons(42, ~Nil)));
+    assert!(is_sorted(&a));
+}
+
+~~~~
+
 Patterns can also dereference pointers by using the `&`,
 `~` or `@` symbols, as appropriate. For example, these two matches
 on `x: &int` are equivalent:
@@ -2951,7 +2951,7 @@ let z = match x { &0 => "zero", _ => "some" };
 assert_eq!(y, z);
 ~~~~
 
-A pattern that's just an identifier, like `Nil` in the previous answer,
+A pattern that's just an identifier, like `Nil` in the previous example,
 could either refer to an enum variant that's in scope, or bind a new variable.
 The compiler resolves this ambiguity by forbidding variable bindings that occur
 in `match` patterns from shadowing names of variants that are in scope.
index cc8dd6edd3f99ce78210fe20193d3d1069fd8dbb..9304badb1c6e68402300d39657e04a0b59a5bded 100644 (file)
@@ -520,6 +520,16 @@ to the value of the matched value inside of the arm's action. Thus, `(0.0,
 y)` matches any tuple whose first element is zero, and binds `y` to
 the second element. `(x, y)` matches any two-element tuple, and binds both
 elements to variables.
+A subpattern can also be bound to a variable, using `variable @ pattern`. For
+example:
+
+~~~~
+# let age = 23;
+match age {
+    a @ 0..20 => println!("{} years old", a),
+    _ => println!("older than 21")
+}
+~~~~
 
 Any `match` arm can have a guard clause (written `if EXPR`), called a
 *pattern guard*, which is an expression of type `bool` that
@@ -597,7 +607,7 @@ With a value (say, `mypoint`) of such a type in a mutable location, you can do
 `mypoint.y += 1.0`. But in an immutable location, such an assignment to a
 struct without inherited mutability would result in a type error.
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 # struct Point { x: f64, y: f64 }
 let mut mypoint = Point { x: 1.0, y: 1.0 };
 let origin = Point { x: 0.0, y: 0.0 };
@@ -938,7 +948,7 @@ An `enum` is a natural fit for describing a linked list, because it can express
 a `List` type as being *either* the end of the list (`Nil`) or another node
 (`Cons`). The full definition of the `Cons` variant will require some thought.
 
-~~~ {.xfail-test}
+~~~ {.ignore}
 enum List {
     Cons(...), // an incomplete definition of the next element in a List
     Nil        // the end of a List
@@ -948,7 +958,7 @@ enum List {
 The obvious approach is to define `Cons` as containing an element in the list
 along with the next `List` node. However, this will generate a compiler error.
 
-~~~ {.xfail-test}
+~~~ {.ignore}
 // error: illegal recursive enum type; wrap the inner value in a box to make it representable
 enum List {
     Cons(u32, List), // an element (`u32`) and the next node in the list
@@ -1082,7 +1092,7 @@ let z = x; // no new memory allocated, x can no longer be used
 The `clone` method is provided by the `Clone` trait, and can be derived for
 our `List` type. Traits will be explained in detail later.
 
-~~~{.xfail-test}
+~~~{.ignore}
 #[deriving(Clone)]
 enum List {
     Cons(u32, ~List),
@@ -1096,7 +1106,7 @@ let y = x.clone();
 
 let z = x;
 
-// and now, it can no longer be used since it has been moved from
+// and now, it can no longer be used since it has been moved
 ~~~
 
 The mutability of a value may be changed by moving it to a new owner:
@@ -1134,7 +1144,7 @@ ownership of a list to be passed in rather than just mutating it in-place.
 
 The obvious signature for a `List` equality comparison is the following:
 
-~~~{.xfail-test}
+~~~{.ignore}
 fn eq(xs: List, ys: List) -> bool { ... }
 ~~~
 
@@ -1142,7 +1152,7 @@ However, this will cause both lists to be moved into the function. Ownership
 isn't required to compare the lists, so the function should take *references*
 (&T) instead.
 
-~~~{.xfail-test}
+~~~{.ignore}
 fn eq(xs: &List, ys: &List) -> bool { ... }
 ~~~
 
@@ -1786,48 +1796,20 @@ call_it(proc(n) {
 });
 ~~~~
 
-This is such a useful pattern that Rust has a special form of function
-call for these functions.
-
-~~~~
-# fn call_it(op: proc(v: int)) { }
-do call_it() |n| {
-    println!("{}", n);
-}
-~~~~
-
-The call is prefixed with the keyword `do` and, instead of writing the
-final procedure inside the argument list, it appears outside of the
-parentheses, where it looks more like a typical block of
-code.
-
-`do` is a convenient way to create tasks with the `task::spawn`
-function.  `spawn` has the signature `spawn(fn: proc())`. In other
-words, it is a function that takes an owned closure that takes no
-arguments.
+A practical example of this pattern is found when using the `spawn` function,
+which starts a new task.
 
 ~~~~
 use std::task::spawn;
-
-do spawn() || {
-    debug!("I'm a task, whatever");
-}
-~~~~
-
-Look at all those bars and parentheses -- that's two empty argument
-lists back to back. Since that is so unsightly, empty argument lists
-may be omitted from `do` expressions.
-
-~~~~
-use std::task::spawn;
-
-do spawn {
-   debug!("Kablam!");
-}
+spawn(proc() {
+    debug!("I'm a new task")
+});
 ~~~~
 
-If you want to see the output of `debug!` statements, you will need to turn on `debug!` logging.
-To enable `debug!` logging, set the RUST_LOG environment variable to the name of your crate, which, for a file named `foo.rs`, will be `foo` (e.g., with bash, `export RUST_LOG=foo`).
+If you want to see the output of `debug!` statements, you will need to turn on
+`debug!` logging.  To enable `debug!` logging, set the RUST_LOG environment
+variable to the name of your crate, which, for a file named `foo.rs`, will be
+`foo` (e.g., with bash, `export RUST_LOG=foo`).
 
 # Methods
 
@@ -1939,7 +1921,7 @@ Implementations may also define standalone (sometimes called "static")
 methods. The absence of a `self` parameter distinguishes such methods.
 These methods are the preferred way to define constructor functions.
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 impl Circle {
     fn area(&self) -> f64 { ... }
     fn new(area: f64) -> Circle { ... }
@@ -2063,7 +2045,7 @@ can we copy values of type `T` inside that function?
 In Rust, we can't,
 and if we try to run the following code the compiler will complain.
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 // This does not compile
 fn head_bad<T>(v: &[T]) -> T {
     v[0] // error: copying a non-copyable value
@@ -2511,7 +2493,7 @@ fn radius_times_area<T: Circle>(c: T) -> f64 {
 
 Likewise, supertrait methods may also be called on trait objects.
 
-~~~ {.xfail-test}
+~~~ {.ignore}
 use std::f64::consts::PI;
 # trait Shape { fn area(&self) -> f64; }
 # trait Circle : Shape { fn radius(&self) -> f64; }
@@ -2614,7 +2596,7 @@ which contains a function `hay`.
 We've now defined a nice module hierarchy. But how do we access the items in it from our `main` function?
 One way to do it is to simply fully qualifying it:
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 mod farm {
     fn chicken() { println!("cluck cluck"); }
     // ...
@@ -2885,7 +2867,7 @@ and only if that results in no match look at items you brought in
 scope with corresponding `use` statements.
 
 ~~~ {.ignore}
-# // XXX: Allow unused import in doc test
+# // FIXME: Allow unused import in doc test
 use farm::cow;
 // ...
 # mod farm { pub fn cow() { println!("Hidden ninja cow is hidden.") } }
@@ -3142,7 +3124,7 @@ You can also specify package ID information in a `extern mod` statement.  For
 example, these `extern mod` statements would both accept and select the
 crate define above:
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 extern mod farm;
 extern mod farm = "farm#2.5";
 extern mod my_farm = "farm";
@@ -3183,7 +3165,7 @@ pub fn explore() -> &'static str { "world" }
 # fn main() {}
 ~~~~
 
-~~~~ {.xfail-test}
+~~~~ {.ignore}
 // main.rs
 extern mod world;
 fn main() { println!("hello {}", world::explore()); }
index 14998cfbb224d5e4e9a2c14d2962158dc93990bf..27c779f107d4b932d9f83408f0ba4a59629ef944 100644 (file)
@@ -63,6 +63,7 @@ clean-generic-$(2)-$(1):
          -name '*.[odasS]' -o \
          -name '*.so' -o      \
          -name '*.dylib' -o   \
+         -name 'stamp.*' -o   \
          -name '*.lib' -o     \
          -name '*.dll' -o     \
          -name '*.def' -o     \
@@ -78,37 +79,16 @@ $(foreach targ, $(CFG_TARGET), $(eval $(call CLEAN_GENERIC,$(targ),T)))
 
 define CLEAN_HOST_STAGE_N
 
-clean$(1)_H_$(2):
-       $(Q)rm -f $$(HBIN$(1)_H_$(2))/rustc$(X_$(2))
-       $(Q)rm -f $$(HBIN$(1)_H_$(2))/rustpkg$(X_$(2))
-       $(Q)rm -f $$(HBIN$(1)_H_$(2))/serializer$(X_$(2))
-       $(Q)rm -f $$(HBIN$(1)_H_$(2))/rustdoc$(X_$(2))
-       $(Q)rm -f $$(HBIN$(1)_H_$(2))/rust$(X_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTPKG_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTDOC_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_RUNTIME_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_STDLIB_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_EXTRALIB_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTUV_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBNATIVE_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBGREEN_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTC_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBSYNTAX_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(STDLIB_GLOB_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(STDLIB_RGLOB_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(EXTRALIB_GLOB_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(EXTRALIB_RGLOB_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTUV_GLOB_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTUV_RGLOB_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBNATIVE_GLOB_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBNATIVE_RGLOB_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBGREEN_GLOB_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBGREEN_RGLOB_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTC_GLOB_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBSYNTAX_GLOB_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTPKG_GLOB_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTDOC_GLOB_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_RUSTLLVM_$(2))
+clean$(1)_H_$(2):                                                          \
+           $$(foreach crate,$$(CRATES),clean$(1)_H_$(2)-lib-$$(crate))     \
+           $$(foreach tool,$$(TOOLS),clean$(1)_H_$(2)-tool-$$(tool))
+
+clean$(1)_H_$(2)-tool-%:
+       $$(Q)rm -f $$(HBIN$(1)_H_$(2))/$$*$$(X_$(2))
+
+clean$(1)_H_$(2)-lib-%:
+       $$(Q)rm -f $$(HLIB$(1)_H_$(2))/$$(call CFG_LIB_GLOB_$(2),$$*)
+       $$(Q)rm -f $$(HLIB$(1)_H_$(2))/$$(call CFG_RLIB_GLOB,$$*)
 
 endef
 
@@ -118,42 +98,19 @@ $(foreach host, $(CFG_HOST), \
 
 define CLEAN_TARGET_STAGE_N
 
-clean$(1)_T_$(2)_H_$(3):
-       $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rustc$(X_$(2))
-       $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rustpkg$(X_$(2))
-       $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/serializer$(X_$(2))
-       $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rustdoc$(X_$(2))
-       $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rust$(X_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTPKG_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTDOC_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUNTIME_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTUV_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBGREEN_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBNATIVE_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(STDLIB_GLOB_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(STDLIB_RGLOB_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(EXTRALIB_GLOB_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(EXTRALIB_RGLOB_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTUV_GLOB_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTUV_RGLOB_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBNATIVE_GLOB_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBNATIVE_RGLOB_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBGREEN_GLOB_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBGREEN_RGLOB_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTC_GLOB_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTC_RGLOB_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBSYNTAX_GLOB_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBSYNTAX_RGLOB_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTPKG_GLOB_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTDOC_GLOB_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUSTLLVM_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a
+clean$(1)_T_$(2)_H_$(3):                                                      \
+           $$(foreach crate,$$(CRATES),clean$(1)_T_$(2)_H_$(3)-lib-$$(crate))  \
+           $$(foreach tool,$$(TOOLS),clean$(1)_T_$(2)_H_$(3)-tool-$$(tool))
+       $$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/librun_pass_stage* # For unix
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/run_pass_stage* # For windows
+
+clean$(1)_T_$(2)_H_$(3)-tool-%:
+       $$(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/$$*$$(X_$(2))
+
+clean$(1)_T_$(2)_H_$(3)-lib-%:
+       $$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$$(call CFG_LIB_GLOB_$(2),$$*)
+       $$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$$(call CFG_RLIB_GLOB,$$*)
 endef
 
 $(foreach host, $(CFG_HOST), \
diff --git a/mk/crates.mk b/mk/crates.mk
new file mode 100644 (file)
index 0000000..a8f14ba
--- /dev/null
@@ -0,0 +1,107 @@
+# 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.
+
+################################################################################
+# Rust's standard distribution of crates and tools
+#
+# The crates outlined below are the standard distribution of libraries provided
+# in a rust installation. These rules are meant to abstract over the
+# dependencies (both native and rust) of crates and basically generate all the
+# necessary makefile rules necessary to build everything.
+#
+# Here's an explanation of the variables below
+#
+#   TARGET_CRATES
+#      This list of crates will be built for all targets, including
+#      cross-compiled targets
+#
+#   HOST_CRATES
+#      This list of crates will be compiled for only host targets. Note that
+#      this set is explicitly *not* a subset of TARGET_CRATES, but rather it is
+#      a disjoint set. Nothing in the TARGET_CRATES set can depend on crates in
+#      the HOST_CRATES set, but the HOST_CRATES set can depend on target
+#      crates.
+#
+#   TOOLS
+#      A list of all tools which will be built as part of the compilation
+#      process. It is currently assumed that most tools are built through
+#      src/driver/driver.rs with a particular configuration (there's a
+#      corresponding library providing the implementation)
+#
+#   DEPS_<crate>
+#      These lists are the dependencies of the <crate> that is to be built.
+#      Rust dependencies are listed bare (i.e. std, extra, green) and native
+#      dependencies have a "native:" prefix (i.e. native:sundown). All deps
+#      will be built before the crate itself is built.
+#
+#   TOOL_DEPS_<tool>/TOOL_SOURCE_<tool>
+#      Similar to the DEPS variable, this is the library crate dependencies
+#      list for tool as well as the source file for the specified tool
+#
+# You shouldn't need to modify much other than these variables. Crates are
+# automatically generated for all stage/host/target combinations.
+################################################################################
+
+TARGET_CRATES := std extra green rustuv native flate arena glob
+HOST_CRATES := syntax rustc rustdoc rustpkg
+CRATES := $(TARGET_CRATES) $(HOST_CRATES)
+TOOLS := compiletest rustpkg rustdoc rustc
+
+DEPS_std := native:rustrt
+DEPS_extra := std
+DEPS_green := std
+DEPS_rustuv := std native:uv native:uv_support
+DEPS_native := std
+DEPS_syntax := std extra
+DEPS_rustc := syntax native:rustllvm flate arena
+DEPS_rustdoc := rustc native:sundown
+DEPS_rustpkg := rustc
+DEPS_flate := std native:miniz
+DEPS_arena := std extra
+DEPS_glob := std
+
+TOOL_DEPS_compiletest := extra green rustuv
+TOOL_DEPS_rustpkg := rustpkg green rustuv
+TOOL_DEPS_rustdoc := rustdoc green rustuv
+TOOL_DEPS_rustc := rustc green rustuv
+TOOL_SOURCE_compiletest := $(S)src/compiletest/compiletest.rs
+TOOL_SOURCE_rustpkg := $(S)src/driver/driver.rs
+TOOL_SOURCE_rustdoc := $(S)src/driver/driver.rs
+TOOL_SOURCE_rustc := $(S)src/driver/driver.rs
+
+################################################################################
+# You should not need to edit below this line
+################################################################################
+
+DOC_CRATES := $(filter-out rustc, $(filter-out syntax, $(CRATES)))
+
+# This macro creates some simple definitions for each crate being built, just
+# some munging of all of the parameters above.
+#
+# $(1) is the crate to generate variables for
+define RUST_CRATE
+CRATEFILE_$(1) := $$(S)src/lib$(1)/lib.rs
+RSINPUTS_$(1) := $$(wildcard $$(addprefix $(S)src/lib$(1), \
+                               *.rs */*.rs */*/*.rs */*/*/*.rs))
+RUST_DEPS_$(1) := $$(filter-out native:%,$$(DEPS_$(1)))
+NATIVE_DEPS_$(1) := $$(patsubst native:%,%,$$(filter native:%,$$(DEPS_$(1))))
+endef
+
+$(foreach crate,$(CRATES),$(eval $(call RUST_CRATE,$(crate))))
+
+# Similar to the macro above for crates, this macro is for tools
+#
+# $(1) is the crate to generate variables for
+define RUST_TOOL
+TOOL_INPUTS_$(1) := $$(wildcard $$(addprefix $(S)$$(dir $$(TOOL_SOURCE_$(1))), \
+                               *.rs */*.rs */*/*.rs */*/*/*.rs))
+endef
+
+$(foreach crate,$(TOOLS),$(eval $(call RUST_TOOL,$(crate))))
index bacf39e1307db520f3346e37514a9c1421f06932..2eb12ae47cc0ebb16833bfefffe2e8d516b0745e 100644 (file)
@@ -290,38 +290,27 @@ endif
 RUSTDOC = $(HBIN2_H_$(CFG_BUILD))/rustdoc$(X_$(CFG_BUILD))
 
 # The library documenting macro
+#
 # $(1) - The crate name (std/extra)
-# $(2) - The crate file
-# $(3) - The relevant host build triple (to depend on libstd)
 #
 # Passes --cfg stage2 to rustdoc because it uses the stage2 librustc.
 define libdoc
-doc/$(1)/index.html: $$(RUSTDOC) $$(TLIB2_T_$(3)_H_$(3))/$(CFG_STDLIB_$(3)) \
-               $(foreach name,$(4),$$(TLIB2_T_$(3)_H_$(3))/$$(CFG_$(name)_$(3)))
-       @$$(call E, rustdoc: $$@)
-       $(Q)$(RUSTDOC) --cfg stage2 $(2)
-
-DOCS += doc/$(1)/index.html
-endef
-
-define compiledoc
-doc/$(1)/index.html: $$(RUSTDOC) $$(TLIB2_T_$(3)_H_$(3))/$(CFG_STDLIB_$(3))
+doc/$(1)/index.html:                                                       \
+           $$(CRATEFILE_$(1))                                              \
+           $$(RSINPUTS_$(1))                                               \
+           $$(RUSTDOC)                                                     \
+           $$(foreach dep,$$(RUST_DEPS_$(1)),                              \
+               $$(TLIB2_T_$(CFG_BUILD)_H_$(CFG_BUILD))/stamp.$$(dep))
        @$$(call E, rustdoc: $$@)
-       $(Q)$(RUSTDOC) --cfg stage2 $(2)
-
-CDOCS += doc/$(1)/index.html
+       $$(Q)$$(RUSTDOC) --cfg stage2 $$<
 endef
 
-$(eval $(call libdoc,std,$(STDLIB_CRATE),$(CFG_BUILD)))
-$(eval $(call libdoc,extra,$(EXTRALIB_CRATE),$(CFG_BUILD)))
-$(eval $(call libdoc,native,$(LIBNATIVE_CRATE),$(CFG_BUILD)))
-$(eval $(call libdoc,green,$(LIBGREEN_CRATE),$(CFG_BUILD)))
-$(eval $(call libdoc,rustuv,$(LIBRUSTUV_CRATE),$(CFG_BUILD)))
-$(eval $(call libdoc,rustpkg,$(RUSTPKG_LIB),$(CFG_BUILD),EXTRALIB LIBRUSTC))
+$(foreach crate,$(CRATES),$(eval $(call libdoc,$(crate))))
 
-$(eval $(call compiledoc,rustc,$(COMPILER_CRATE),$(CFG_BUILD)))
-$(eval $(call compiledoc,syntax,$(LIBSYNTAX_CRATE),$(CFG_BUILD)))
+DOCS += $(DOC_CRATES:%=doc/%/index.html)
 
+CDOCS += doc/rustc/index.html
+CDOCS += doc/syntax/index.html
 
 ifdef CFG_DISABLE_DOCS
   $(info cfg: disabling doc build (CFG_DISABLE_DOCS))
index 5de12f90bcf73dcc457e8ffe0f8c54985b188abd..7a3664d897d0ffe80523487cd76ed3aedb5ed7fa 100644 (file)
 # option. This file may not be copied, modified, or distributed
 # except according to those terms.
 
-# CP_HOST_STAGE_N template: arg 1 is the N we're promoting *from*, arg
-# 2 is N+1. Must be invoked to promote target artifacts to host
-# artifacts for stage 1-3 (stage0 host artifacts come from the
-# snapshot).  Arg 3 is the triple we're copying FROM and arg 4 is the
-# triple we're copying TO.
+# Generic rule for copying any target crate to a host crate. This rule will also
+# promote any dependent rust crates up to their host locations as well
 #
-# The easiest way to read this template is to assume we're promoting
-# stage1 to stage2 and mentally gloss $(1) as 1, $(2) as 2.
-
-define CP_HOST_STAGE_N
-
-# Host libraries and executables (stage$(2)/bin/rustc and its runtime needs)
-
-# Note: $(3) and $(4) are both the same!
-
-$$(HBIN$(2)_H_$(4))/rustc$$(X_$(4)): \
-       $$(TBIN$(1)_T_$(4)_H_$(3))/rustc$$(X_$(4)) \
-       $$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTC_$(4)) \
-       | $$(HBIN$(2)_H_$(4))/
-       @$$(call E, cp: $$@)
-       $$(Q)cp $$< $$@
-
-$$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTC_$(4)): \
-       $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTC_$(4)) \
-       $$(HLIB$(2)_H_$(4))/$(CFG_LIBSYNTAX_$(4)) \
+# $(1) - the stage to copy from
+# $(2) - the stage to copy to
+# $(3) - the host triple
+# $(4) - the target triple (same as $(3))
+# $(5) - the name of the crate being processed
+define CP_HOST_STAGE_N_CRATE
+
+$$(HLIB$(2)_H_$(4))/stamp.$(5):                                        \
+       $$(TLIB$(1)_T_$(3)_H_$(4))/stamp.$(5)                   \
+       $$(RUST_DEPS_$(5):%=$$(HLIB$(2)_H_$(4))/stamp.%)        \
        | $$(HLIB$(2)_H_$(4))/
-
-       @$$(call E, cp: $$@)
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTC_GLOB_$(4)),$$(notdir $$@))
+       @$$(call E, cp: $$(@D)/lib$(5))
+       $$(call REMOVE_ALL_OLD_GLOB_MATCHES,\
+           $$(dir $$@)$$(call CFG_LIB_GLOB_$(3),$(5)))
        $$(Q)cp $$< $$@
-       $$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTC_GLOB_$(4)) \
-               $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTC_DSYM_GLOB_$(4))) \
+       $$(Q)cp -R $$(TLIB$(1)_T_$(3)_H_$(4))/$$(call CFG_LIB_GLOB_$(3),$(5)) \
                $$(HLIB$(2)_H_$(4))
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTC_GLOB_$(4)),$$(notdir $$@))
+       $$(call LIST_ALL_OLD_GLOB_MATCHES,\
+           $$(dir $$@)$$(call CFG_LIB_GLOB_$(3),$(5)))
 
-$$(HLIB$(2)_H_$(4))/$(CFG_LIBSYNTAX_$(4)): \
-       $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBSYNTAX_$(4)) \
-       $$(HSTDLIB_DEFAULT$(2)_H_$(4)) \
-       $$(HEXTRALIB_DEFAULT$(2)_H_$(4)) \
-       $$(HLIBRUSTUV_DEFAULT$(2)_H_$(4)) \
-       $$(HLIBGREEN_DEFAULT$(2)_H_$(4)) \
-       $$(HLIBNATIVE_DEFAULT$(2)_H_$(4)) \
-       | $$(HLIB$(2)_H_$(4))/
-       @$$(call E, cp: $$@)
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBSYNTAX_GLOB_$(4)),$$(notdir $$@))
-       $$(Q)cp $$< $$@
-       $$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBSYNTAX_GLOB_$(4)) \
-               $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBSYNTAX_DSYM_GLOB_$(4))) \
-               $$(HLIB$(2)_H_$(4))
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBSYNTAX_GLOB_$(4)),$$(notdir $$@))
+endef
 
-$$(HLIB$(2)_H_$(4))/$(CFG_RUNTIME_$(4)): \
-       $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_RUNTIME_$(4)) \
-       | $$(HLIB$(2)_H_$(4))/
-       @$$(call E, cp: $$@)
-       $$(Q)cp $$< $$@
+# Same as the above macro, but for tools instead of crates
+define CP_HOST_STAGE_N_TOOL
 
-$$(HLIB$(2)_H_$(4))/$(CFG_STDLIB_$(4)): \
-       $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4)) \
-       | $$(HLIB$(2)_H_$(4))/
-       @$$(call E, cp: $$@)
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(STDLIB_GLOB_$(4)),$$(notdir $$@))
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(STDLIB_RGLOB_$(4)),$$(notdir $$@))
-       $$(Q)cp $$< $$@
-# Subtle: We do not let the shell expand $$(STDLIB_DSYM_GLOB) directly rather
-# we use Make's $$(wildcard) facility. The reason is that, on mac, when using
-# USE_SNAPSHOT_STDLIB, we copy the std.dylib file out of the snapshot.
-# In that case, there is no .dSYM file.  Annoyingly, bash then refuses to expand
-# glob, and cp reports an error because libstd-*.dylib.dsym does not exist.
-# Make instead expands the glob to nothing, which gives us the correct behavior.
-# (Copy .dsym file if it exists, but do nothing otherwise)
-       $$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(STDLIB_GLOB_$(4)) \
-               $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(STDLIB_RGLOB_$(4))) \
-               $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(STDLIB_DSYM_GLOB_$(4))) \
-               $$(HLIB$(2)_H_$(4))
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(STDLIB_GLOB_$(4)),$$(notdir $$@))
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(STDLIB_RGLOB_$(4)),$$(notdir $$@))
-
-$$(HLIB$(2)_H_$(4))/$(CFG_EXTRALIB_$(4)): \
-       $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4)) \
-       $$(HSTDLIB_DEFAULT$(2)_H_$(4)) \
-       | $$(HLIB$(2)_H_$(4))/
+$$(HBIN$(2)_H_$(4))/$(5)$$(X_$(3)): \
+       $$(TBIN$(1)_T_$(3)_H_$(4))/$(5)$$(X_$(3)) \
+       $$(TOOL_DEPS_$(5):%=$$(HLIB$(2)_H_$(4))/stamp.%) \
+       | $$(HBIN$(2)_H_$(4))/
        @$$(call E, cp: $$@)
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(EXTRALIB_GLOB_$(4)),$$(notdir $$@))
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(EXTRALIB_RGLOB_$(4)),$$(notdir $$@))
        $$(Q)cp $$< $$@
-       $$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(EXTRALIB_GLOB_$(4)) \
-               $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(EXTRALIB_RGLOB_$(4))) \
-               $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(EXTRALIB_DSYM_GLOB_$(4))) \
-               $$(HLIB$(2)_H_$(4))
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(EXTRALIB_GLOB_$(4)),$$(notdir $$@))
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(EXTRALIB_RGLOB_$(4)),$$(notdir $$@))
 
-$$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTUV_$(4)): \
-       $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTUV_$(4)) \
-       $$(HLIB$(2)_H_$(4))/$(CFG_STDLIB_$(4)) \
-       | $$(HLIB$(2)_H_$(4))/
-       @$$(call E, cp: $$@)
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTUV_GLOB_$(4)),$$(notdir $$@))
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTUV_RGLOB_$(4)),$$(notdir $$@))
-       $$(Q)cp $$< $$@
-       $$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTUV_GLOB_$(4)) \
-               $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTUV_RGLOB_$(4))) \
-               $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTUV_DSYM_GLOB_$(4))) \
-               $$(HLIB$(2)_H_$(4))
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTUV_GLOB_$(4)),$$(notdir $$@))
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTUV_RGLOB_$(4)),$$(notdir $$@))
+endef
 
-$$(HLIB$(2)_H_$(4))/$(CFG_LIBGREEN_$(4)): \
-       $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBGREEN_$(4)) \
-       $$(HLIB$(2)_H_$(4))/$(CFG_STDLIB_$(4)) \
-       | $$(HLIB$(2)_H_$(4))/
-       @$$(call E, cp: $$@)
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBGREEN_GLOB_$(4)),$$(notdir $$@))
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBGREEN_RGLOB_$(4)),$$(notdir $$@))
-       $$(Q)cp $$< $$@
-       $$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBGREEN_GLOB_$(4)) \
-               $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBGREEN_RGLOB_$(4))) \
-               $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBGREEN_DSYM_GLOB_$(4))) \
-               $$(HLIB$(2)_H_$(4))
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBGREEN_GLOB_$(4)),$$(notdir $$@))
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBGREEN_RGLOB_$(4)),$$(notdir $$@))
 
-$$(HLIB$(2)_H_$(4))/$(CFG_LIBNATIVE_$(4)): \
-       $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBNATIVE_$(4)) \
-       $$(HLIB$(2)_H_$(4))/$(CFG_STDLIB_$(4)) \
-       | $$(HLIB$(2)_H_$(4))/
-       @$$(call E, cp: $$@)
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBNATIVE_GLOB_$(4)),$$(notdir $$@))
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBNATIVE_RGLOB_$(4)),$$(notdir $$@))
-       $$(Q)cp $$< $$@
-       $$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBNATIVE_GLOB_$(4)) \
-               $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBNATIVE_RGLOB_$(4))) \
-               $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBNATIVE_DSYM_GLOB_$(4))) \
-               $$(HLIB$(2)_H_$(4))
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBNATIVE_GLOB_$(4)),$$(notdir $$@))
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBNATIVE_RGLOB_$(4)),$$(notdir $$@))
+# Miscellaneous rules for just making a few directories.
+#
+# $(1) - the stage to copy from
+# $(2) - the stage to copy to
+# $(3) - the target triple
+# $(4) - the host triple (same as $(3))
+define CP_HOST_STAGE_N
 
 $$(HBIN$(2)_H_$(4))/:
-       mkdir -p $$@
+       @mkdir -p $$@
 
 ifneq ($(CFG_LIBDIR_RELATIVE),bin)
 $$(HLIB$(2)_H_$(4))/:
-       mkdir -p $$@
+       @mkdir -p $$@
 endif
 
 endef
 
-$(foreach t,$(CFG_HOST),                                       \
-       $(eval $(call CP_HOST_STAGE_N,0,1,$(t),$(t)))   \
-       $(eval $(call CP_HOST_STAGE_N,1,2,$(t),$(t)))   \
+$(foreach t,$(CFG_HOST),                                                   \
+       $(eval $(call CP_HOST_STAGE_N,0,1,$(t),$(t)))                       \
+       $(eval $(call CP_HOST_STAGE_N,1,2,$(t),$(t)))                       \
        $(eval $(call CP_HOST_STAGE_N,2,3,$(t),$(t))))
+
+$(foreach crate,$(CRATES),                                                 \
+ $(foreach t,$(CFG_HOST),                                                  \
+  $(eval $(call CP_HOST_STAGE_N_CRATE,0,1,$(t),$(t),$(crate)))             \
+  $(eval $(call CP_HOST_STAGE_N_CRATE,1,2,$(t),$(t),$(crate)))             \
+  $(eval $(call CP_HOST_STAGE_N_CRATE,2,3,$(t),$(t),$(crate)))))
+
+$(foreach tool,$(TOOLS),                                                   \
+ $(foreach t,$(CFG_HOST),                                                  \
+  $(eval $(call CP_HOST_STAGE_N_TOOL,0,1,$(t),$(t),$(tool)))               \
+  $(eval $(call CP_HOST_STAGE_N_TOOL,1,2,$(t),$(t),$(tool)))               \
+  $(eval $(call CP_HOST_STAGE_N_TOOL,2,3,$(t),$(t),$(tool)))))
index f275f6fd9ff99f2649779c119d6e536a8302fe30..73c8f2cf8c32f2c708c65eaa8fe563e4513b9ff1 100644 (file)
@@ -65,6 +65,8 @@ PREFIX_ROOT = $(CFG_PREFIX)
 PREFIX_BIN = $(PREFIX_ROOT)/bin
 PREFIX_LIB = $(CFG_LIBDIR)
 
+INSTALL_TOOLS := $(filter-out compiletest, $(TOOLS))
+
 define INSTALL_PREPARE_N
   # $(1) is the target triple
   # $(2) is the host triple
@@ -86,43 +88,28 @@ $(foreach target,$(CFG_TARGET), \
 define INSTALL_TARGET_N
 install-target-$(1)-host-$(2): LIB_SOURCE_DIR=$$(TL$(1)$(2))
 install-target-$(1)-host-$(2): LIB_DESTIN_DIR=$$(PTL$(1)$(2))
-install-target-$(1)-host-$(2): $$(TSREQ$$(ISTAGE)_T_$(1)_H_$(2)) $$(SREQ$$(ISTAGE)_T_$(1)_H_$(2))
+install-target-$(1)-host-$(2):                                         \
+           $$(TSREQ$$(ISTAGE)_T_$(1)_H_$(2))                           \
+           $$(SREQ$$(ISTAGE)_T_$(1)_H_$(2))
        $$(Q)$$(call MK_INSTALL_DIR,$$(PTL$(1)$(2)))
-       $$(Q)$$(call INSTALL_LIB,$$(STDLIB_GLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(STDLIB_RGLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(EXTRALIB_GLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(EXTRALIB_RGLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(LIBRUSTUV_GLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(LIBRUSTUV_RGLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(LIBGREEN_GLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(LIBGREEN_RGLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(LIBNATIVE_GLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(LIBNATIVE_RGLOB_$(1)))
+       $$(Q)$$(foreach crate,$$(TARGET_CRATES),\
+               $$(call INSTALL_LIB,$$(call CFG_LIB_GLOB_$(1),$$(crate)));\
+               $$(call INSTALL_LIB,$$(call CFG_RLIB_GLOB,$$(crate)));)
        $$(Q)$$(call INSTALL_LIB,libmorestack.a)
 
 endef
 
 define INSTALL_HOST_N
+
 install-target-$(1)-host-$(2): LIB_SOURCE_DIR=$$(TL$(1)$(2))
 install-target-$(1)-host-$(2): LIB_DESTIN_DIR=$$(PTL$(1)$(2))
 install-target-$(1)-host-$(2): $$(CSREQ$$(ISTAGE)_T_$(1)_H_$(2))
        $$(Q)$$(call MK_INSTALL_DIR,$$(PTL$(1)$(2)))
-       $$(Q)$$(call INSTALL_LIB,$$(STDLIB_GLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(STDLIB_RGLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(EXTRALIB_GLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(EXTRALIB_RGLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(LIBRUSTUV_GLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(LIBRUSTUV_RGLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(LIBGREEN_GLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(LIBGREEN_RGLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(LIBNATIVE_GLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(LIBNATIVE_RGLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(LIBRUSTC_GLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(LIBSYNTAX_GLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(LIBRUSTPKG_GLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(LIBRUSTDOC_GLOB_$(1)))
+       $$(Q)$$(foreach crate,$$(CRATES),\
+           $$(call INSTALL_LIB,$$(call CFG_LIB_GLOB_$(1),$$(crate)));)
+       $$(Q)$$(foreach crate,$$(TARGET_CRATES),\
+           $$(call INSTALL_LIB,$$(call CFG_RLIB_GLOB,$$(crate)));)
        $$(Q)$$(call INSTALL_LIB,libmorestack.a)
-
 endef
 
 $(foreach target,$(CFG_TARGET), \
@@ -145,26 +132,35 @@ PHB = $(PREFIX_BIN)
 # Shorthand for the prefix bin directory
 PHL = $(PREFIX_LIB)
 
-install-host: LIB_SOURCE_DIR=$(HL)
-install-host: LIB_DESTIN_DIR=$(PHL)
-install-host: $(CSREQ$(ISTAGE)_T_$(CFG_BUILD_)_H_$(CFG_BUILD_))
+install-host%: LIB_SOURCE_DIR=$(HL)
+install-host%: LIB_DESTIN_DIR=$(PHL)
+install-host:                                                              \
+           install-host-prep                                               \
+           $(foreach tool,$(INSTALL_TOOLS),install-host-tool-$(tool))
+
+install-host-prep: $(CSREQ$(ISTAGE)_T_$(CFG_BUILD)_H_$(CFG_BUILD))
        $(Q)$(call MK_INSTALL_DIR,$(PREFIX_BIN))
        $(Q)$(call MK_INSTALL_DIR,$(PREFIX_LIB))
        $(Q)$(call MK_INSTALL_DIR,$(CFG_MANDIR)/man1)
-       $(Q)$(call INSTALL,$(HB2),$(PHB),rustc$(X_$(CFG_BUILD)))
-       $(Q)$(call INSTALL,$(HB2),$(PHB),rustpkg$(X_$(CFG_BUILD)))
-       $(Q)$(call INSTALL,$(HB2),$(PHB),rustdoc$(X_$(CFG_BUILD)))
-       $(Q)$(call INSTALL_LIB,$(STDLIB_GLOB_$(CFG_BUILD)))
-       $(Q)$(call INSTALL_LIB,$(EXTRALIB_GLOB_$(CFG_BUILD)))
-       $(Q)$(call INSTALL_LIB,$(LIBRUSTUV_GLOB_$(CFG_BUILD)))
-       $(Q)$(call INSTALL_LIB,$(LIBGREEN_GLOB_$(CFG_BUILD)))
-       $(Q)$(call INSTALL_LIB,$(LIBRUSTC_GLOB_$(CFG_BUILD)))
-       $(Q)$(call INSTALL_LIB,$(LIBSYNTAX_GLOB_$(CFG_BUILD)))
-       $(Q)$(call INSTALL_LIB,$(LIBRUSTPKG_GLOB_$(CFG_BUILD)))
-       $(Q)$(call INSTALL_LIB,$(LIBRUSTDOC_GLOB_$(CFG_BUILD)))
-       $(Q)$(call INSTALL,$(S)/man,$(CFG_MANDIR)/man1,rustc.1)
-       $(Q)$(call INSTALL,$(S)/man,$(CFG_MANDIR)/man1,rustdoc.1)
-       $(Q)$(call INSTALL,$(S)/man,$(CFG_MANDIR)/man1,rustpkg.1)
+
+define INSTALL_HOST_TOOL
+install-host-tool-$(1):                                                            \
+           $$(foreach dep,$$(TOOL_DEPS_$(1)),install-host-lib-$$(dep))     \
+           $$(CSREQ$$(ISTAGE)_T_$$(CFG_BUILD)_H_$$(CFG_BUILD))
+       $$(Q)$$(call INSTALL,$$(HB2),$$(PHB),$(1)$$(X_$$(CFG_BUILD)))
+       $$(Q)$$(call INSTALL,$$(S)/man,$$(CFG_MANDIR)/man1,$(1).1)
+endef
+
+$(foreach tool,$(INSTALL_TOOLS),$(eval $(call INSTALL_HOST_TOOL,$(tool))))
+
+define INSTALL_HOST_LIB
+install-host-lib-$(1):                                                     \
+           $$(foreach dep,$$(RUST_DEPS_$(1)),install-host-lib-$$(dep))     \
+           $$(CSREQ$$(ISTAGE)_T_$$(CFG_BUILD)_H_$$(CFG_BUILD))
+       $$(Q)$$(call INSTALL_LIB,$$(call CFG_LIB_GLOB_$$(CFG_BUILD),$(1)))
+endef
+
+$(foreach lib,$(CRATES),$(eval $(call INSTALL_HOST_LIB,$(lib))))
 
 install-targets: $(INSTALL_TARGET_RULES)
 
@@ -172,33 +168,23 @@ install-targets: $(INSTALL_TARGET_RULES)
 HOST_LIB_FROM_HL_GLOB = \
   $(patsubst $(HL)/%,$(PHL)/%,$(wildcard $(HL)/$(1)))
 
-uninstall:
-       $(Q)rm -f $(PHB)/rustc$(X_$(CFG_BUILD))
-       $(Q)rm -f $(PHB)/rustpkg$(X_$(CFG_BUILD))
-       $(Q)rm -f $(PHB)/rustdoc$(X_$(CFG_BUILD))
-       $(Q)for i in \
-          $(call HOST_LIB_FROM_HL_GLOB,$(STDLIB_GLOB_$(CFG_BUILD))) \
-          $(call HOST_LIB_FROM_HL_GLOB,$(STDLIB_RGLOB_$(CFG_BUILD))) \
-          $(call HOST_LIB_FROM_HL_GLOB,$(EXTRALIB_GLOB_$(CFG_BUILD))) \
-          $(call HOST_LIB_FROM_HL_GLOB,$(EXTRALIB_RGLOB_$(CFG_BUILD))) \
-          $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTUV_GLOB_$(CFG_BUILD))) \
-          $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTUV_RGLOB_$(CFG_BUILD))) \
-          $(call HOST_LIB_FROM_HL_GLOB,$(LIBGREEN_GLOB_$(CFG_BUILD))) \
-          $(call HOST_LIB_FROM_HL_GLOB,$(LIBGREEN_RGLOB_$(CFG_BUILD))) \
-          $(call HOST_LIB_FROM_HL_GLOB,$(LIBNATIVE_GLOB_$(CFG_BUILD))) \
-          $(call HOST_LIB_FROM_HL_GLOB,$(LIBNATIVE_RGLOB_$(CFG_BUILD))) \
-          $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTC_GLOB_$(CFG_BUILD))) \
-          $(call HOST_LIB_FROM_HL_GLOB,$(LIBSYNTAX_GLOB_$(CFG_BUILD))) \
-          $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTPKG_GLOB_$(CFG_BUILD))) \
-          $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTDOC_GLOB_$(CFG_BUILD))) \
-        ; \
-        do rm -f $$i ; \
-        done
+uninstall: $(foreach tool,$(INSTALL_TOOLS),uninstall-tool-$(tool))
        $(Q)rm -Rf $(PHL)/$(CFG_RUSTLIBDIR)
-       $(Q)rm -f $(CFG_MANDIR)/man1/rustc.1
-       $(Q)rm -f $(CFG_MANDIR)/man1/rustdoc.1
-       $(Q)rm -f $(CFG_MANDIR)/man1/rusti.1
-       $(Q)rm -f $(CFG_MANDIR)/man1/rustpkg.1
+
+define UNINSTALL_TOOL
+uninstall-tool-$(1): $$(foreach dep,$$(TOOL_DEPS_$(1)),uninstall-lib-$$(dep))
+       $$(Q)rm -f $$(PHB)/$(1)$$(X_$$(CFG_BUILD))
+       $$(Q)rm -f $$(CFG_MANDIR)/man1/$(1).1
+endef
+
+$(foreach tool,$(INSTALL_TOOLS),$(eval $(call UNINSTALL_TOOL,$(tool))))
+
+define UNINSTALL_LIB
+uninstall-lib-$(1): $$(foreach dep,$$(RUST_DEPS_$(1)),uninstall-lib-$$(dep))
+       $$(Q)rm -f $$(call HOST_LIB_FROM_HL_GLOB,$$(call CFG_LIB_GLOB_$$(CFG_BUILD),$(1)))
+endef
+
+$(foreach lib,$(CRATES),$(eval $(call UNINSTALL_LIB,$(lib))))
 
 # target platform specific variables
 # for arm-linux-androidabi
@@ -246,20 +232,17 @@ endif
 
 define INSTALL_RUNTIME_TARGET_N
 install-runtime-target-$(1)-host-$(2): $$(TSREQ$$(ISTAGE)_T_$(1)_H_$(2)) $$(SREQ$$(ISTAGE)_T_$(1)_H_$(2))
-       $(Q)$(call ADB_SHELL,mkdir,$(CFG_RUNTIME_PUSH_DIR))
-       $(Q)$(call ADB_PUSH,$$(TL$(1)$(2))/$$(STDLIB_GLOB_$(1)),$(CFG_RUNTIME_PUSH_DIR))
-       $(Q)$(call ADB_PUSH,$$(TL$(1)$(2))/$$(EXTRALIB_GLOB_$(1)),$(CFG_RUNTIME_PUSH_DIR))
-       $(Q)$(call ADB_PUSH,$$(TL$(1)$(2))/$$(LIBRUSTUV_GLOB_$(1)),$(CFG_RUNTIME_PUSH_DIR))
-       $(Q)$(call ADB_PUSH,$$(TL$(1)$(2))/$$(LIBGREEN_GLOB_$(1)),$(CFG_RUNTIME_PUSH_DIR))
+       $$(Q)$$(call ADB_SHELL,mkdir,$(CFG_RUNTIME_PUSH_DIR))
+       $$(Q)$$(foreach crate,$$(TARGET_CRATES),\
+           $$(call ADB_PUSH,$$(TL$(1)$(2))/$$(call CFG_LIB_GLOB_$(1),$$(crate)),\
+                       $$(CFG_RUNTIME_PUSH_DIR));)
 endef
 
 define INSTALL_RUNTIME_TARGET_CLEANUP_N
 install-runtime-target-$(1)-cleanup:
-       $(Q)$(call ADB,remount)
-       $(Q)$(call ADB_SHELL,rm,$(CFG_RUNTIME_PUSH_DIR)/$(STDLIB_GLOB_$(1)))
-       $(Q)$(call ADB_SHELL,rm,$(CFG_RUNTIME_PUSH_DIR)/$(EXTRALIB_GLOB_$(1)))
-       $(Q)$(call ADB_SHELL,rm,$(CFG_RUNTIME_PUSH_DIR)/$(LIBRUSTUV_GLOB_$(1)))
-       $(Q)$(call ADB_SHELL,rm,$(CFG_RUNTIME_PUSH_DIR)/$(LIBGREEN_GLOB_$(1)))
+       $$(Q)$$(call ADB,remount)
+       $$(Q)$$(foreach crate,$$(TARGET_CRATES),\
+           $$(call ADB_SHELL,rm,$$(CFG_RUNTIME_PUSH_DIR)/$$(call CFG_LIB_GLOB_$(1),$$(crate)));)
 endef
 
 $(eval $(call INSTALL_RUNTIME_TARGET_N,arm-linux-androideabi,$(CFG_BUILD)))
index 10c597e61d1b124768af7aaa84d416d6d1f696ad..f400809b616bf09ff53a3fcdf06c5feed103256a 100644 (file)
@@ -26,11 +26,6 @@ endef
 $(foreach t,$(CFG_TARGET),$(eval $(call DEF_OSTYPE_VAR,$(t))))
 $(foreach t,$(CFG_TARGET),$(info cfg: os for $(t) is $(OSTYPE_$(t))))
 
-# FIXME: no-omit-frame-pointer is just so that task_start_wrapper
-# has a frame pointer and the stack walker can understand it. Turning off
-# frame pointers everywhere is overkill
-CFG_GCCISH_CFLAGS += -fno-omit-frame-pointer
-
 # On Darwin, we need to run dsymutil so the debugging information ends
 # up in the right place.  On other platforms, it automatically gets
 # embedded into the executable, so use a no-op command.
@@ -160,7 +155,6 @@ 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_LIBUV_LINK_FLAGS_x86_64-unknown-linux-gnu =
-CFG_LLVM_BUILD_ENV_x86_64-unknown-linux-gnu="CXXFLAGS=-fno-omit-frame-pointer"
 CFG_EXE_SUFFIX_x86_64-unknown-linux-gnu =
 CFG_WINDOWSY_x86_64-unknown-linux-gnu :=
 CFG_UNIXY_x86_64-unknown-linux-gnu := 1
@@ -188,7 +182,6 @@ CFG_DEF_SUFFIX_i686-unknown-linux-gnu := .linux.def
 CFG_LLC_FLAGS_i686-unknown-linux-gnu :=
 CFG_INSTALL_NAME_i686-unknown-linux-gnu =
 CFG_LIBUV_LINK_FLAGS_i686-unknown-linux-gnu =
-CFG_LLVM_BUILD_ENV_i686-unknown-linux-gnu="CXXFLAGS=-fno-omit-frame-pointer"
 CFG_EXE_SUFFIX_i686-unknown-linux-gnu =
 CFG_WINDOWSY_i686-unknown-linux-gnu :=
 CFG_UNIXY_i686-unknown-linux-gnu := 1
@@ -596,7 +589,7 @@ define CFG_MAKE_TOOLCHAIN
   else
 
   # For the ARM and MIPS crosses, use the toolchain assembler
-  # XXX: We should be able to use the LLVM assembler
+  # FIXME: We should be able to use the LLVM assembler
   CFG_ASSEMBLE_$(1)=$$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \
                    $$(CFG_DEPEND_FLAGS) $$(2) -c -o $$(1)
 
index 38cc233b9336096ca3e296cb5c2ac88afb21ae85..269491649bb281470e88b20c2401917925cbbf66 100644 (file)
--- a/mk/rt.mk
+++ b/mk/rt.mk
-# This is a procedure to define the targets for building
-# the runtime.
+# 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.
 #
-# Argument 1 is the target triple.
+# 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.
+
+################################################################################
+# Native libraries built as part of the rust build process
 #
-# This is not really the right place to explain this, but
-# for those of you who are not Makefile gurus, let me briefly
-# cover the $ expansion system in use here, because it
-# confused me for a while!  The variable DEF_RUNTIME_TARGETS
-# will be defined once and then expanded with different
-# values substituted for $(1) each time it is called.
-# That resulting text is then eval'd.
+# This portion of the rust build system is meant to keep track of native
+# dependencies and how to build them. It is currently required that all native
+# dependencies are built as static libraries, as slinging around dynamic
+# libraries isn't exactly the most fun thing to do.
 #
-# For most variables, you could use a single $ sign.  The result
-# is that the substitution would occur when the CALL occurs,
-# I believe.  The problem is that the automatic variables $< and $@
-# need to be expanded-per-rule.  Therefore, for those variables at
-# least, you need $$< and $$@ in the variable text.  This way, after
-# the CALL substitution occurs, you will have $< and $@.  This text
-# will then be evaluated, and all will work as you like.
+# This section should need minimal modification to add new libraries. The
+# relevant variables are:
 #
-# Reader beware, this explanantion could be wrong, but it seems to
-# fit the experimental data (i.e., I was able to get the system
-# working under these assumptions).
+#   NATIVE_LIBS
+#      This is a list of all native libraries which are built as part of the
+#      build process. It will build all libraries into RT_OUTPUT_DIR with the
+#      appropriate name of static library as dictated by the target platform
+#
+#   NATIVE_DEPS_<lib>
+#      This is a list of files relative to the src/rt directory which are
+#      needed to build the native library. Each file will be compiled to an
+#      object file, and then all the object files will be assembled into an
+#      archive (static library). The list contains files of any extension
+#
+# If adding a new library, you should update the NATIVE_LIBS list, and then list
+# the required files below it. The list of required files is a list of files
+# that's per-target so you're allowed to conditionally add files based on the
+# target.
+################################################################################
+NATIVE_LIBS := rustrt sundown uv_support morestack miniz
+
+# $(1) is the target triple
+define NATIVE_LIBRARIES
+
+NATIVE_DEPS_sundown_$(1) := sundown/src/autolink.c \
+                       sundown/src/buffer.c \
+                       sundown/src/stack.c \
+                       sundown/src/markdown.c \
+                       sundown/html/houdini_href_e.c \
+                       sundown/html/houdini_html_e.c \
+                       sundown/html/html_smartypants.c \
+                       sundown/html/html.c
+NATIVE_DEPS_uv_support_$(1) := rust_uv.c
+NATIVE_DEPS_miniz_$(1) = miniz.c
+NATIVE_DEPS_rustrt_$(1) := rust_builtin.c \
+                       rust_android_dummy.c \
+                       rust_test_helpers.c \
+                       rust_try.ll \
+                       arch/$$(HOST_$(1))/_context.S \
+                       arch/$$(HOST_$(1))/record_sp.S
+NATIVE_DEPS_morestack_$(1) := arch/$$(HOST_$(1))/morestack.S
+
+################################################################################
+# You shouldn't find it that necessary to edit anything below this line.
+################################################################################
+
+# While we're defining the native libraries for each target, we define some
+# common rules used to build files for various targets.
 
-# when we're doing a snapshot build, we intentionally degrade as many
-# features in libuv and the runtime as possible, to ease portability.
+RT_OUTPUT_DIR_$(1) := $(1)/rt
+
+$$(RT_OUTPUT_DIR_$(1))/%.o: rt/%.ll $$(MKFILE_DEPS) $$(LLVM_CONFIG_$$(CFG_BUILD))
+       @mkdir -p $$(@D)
+       @$$(call E, compile: $$@)
+       $$(Q)$$(LLC_$$(CFG_BUILD)) $$(CFG_LLC_FLAGS_$(1)) \
+           -filetype=obj -mtriple=$(1) -relocation-model=pic -o $$@ $$<
+
+$$(RT_OUTPUT_DIR_$(1))/%.o: rt/%.c $$(MKFILE_DEPS)
+       @mkdir -p $$(@D)
+       @$$(call E, compile: $$@)
+       $$(Q)$$(call CFG_COMPILE_C_$(1), $$@, \
+               -I $$(S)src/rt/sundown/src -I $$(S)src/rt/sundown/html \
+               -I $$(S)src/libuv/include -I $$(S)src/rt \
+                 $$(RUNTIME_CFLAGS_$(1))) $$<
+
+$$(RT_OUTPUT_DIR_$(1))/%.o: rt/%.S $$(MKFILE_DEPS) $$(LLVM_CONFIG_$$(CFG_BUILD))
+       @mkdir -p $$(@D)
+       @$$(call E, compile: $$@)
+       $$(Q)$$(call CFG_ASSEMBLE_$(1),$$@,$$<)
+endef
+
+$(foreach target,$(CFG_TARGET),$(eval $(call NATIVE_LIBRARIES,$(target))))
+
+# A macro for devining how to build third party libraries listed above (based
+# on their dependencies).
+#
+# $(1) is the target
+# $(2) is the lib name
+define THIRD_PARTY_LIB
+
+OBJS_$(2)_$(1) := $$(NATIVE_DEPS_$(2)_$(1):%=$$(RT_OUTPUT_DIR_$(1))/%)
+OBJS_$(2)_$(1) := $$(OBJS_$(2)_$(1):.c=.o)
+OBJS_$(2)_$(1) := $$(OBJS_$(2)_$(1):.cpp=.o)
+OBJS_$(2)_$(1) := $$(OBJS_$(2)_$(1):.ll=.o)
+OBJS_$(2)_$(1) := $$(OBJS_$(2)_$(1):.S=.o)
+NATIVE_$(2)_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),$(2))
+$$(RT_OUTPUT_DIR_$(1))/$$(NATIVE_$(2)_$(1)): $$(OBJS_$(2)_$(1))
+       @$$(call E, link: $$@)
+       $$(Q)$$(AR_$(1)) rcs $$@ $$^
+
+endef
+
+$(foreach target,$(CFG_TARGET),                                            \
+ $(eval $(call RUNTIME_RULES,$(target))))
+$(foreach lib,$(NATIVE_LIBS),                                      \
+ $(foreach target,$(CFG_TARGET),                                   \
+  $(eval $(call THIRD_PARTY_LIB,$(target),$(lib)))))
 
-SNAP_DEFINES:=
-ifneq ($(strip $(findstring snap,$(MAKECMDGOALS))),)
-       SNAP_DEFINES=-DRUST_SNAPSHOT
-endif
+
+################################################################################
+# Building third-party targets with external build systems
+#
+# The only current member of this section is libuv, but long ago this used to
+# also be occupied by jemalloc. This location is meant for dependencies which
+# have external build systems. It is still assumed that the output of each of
+# these steps is a static library in the correct location.
+################################################################################
 
 define DEF_LIBUV_ARCH_VAR
   LIBUV_ARCH_$(1) = $$(subst i386,ia32,$$(subst x86_64,x64,$$(HOST_$(1))))
@@ -51,128 +144,10 @@ LIBUV_NO_LOAD = run-benchmarks.target.mk run-tests.target.mk \
 
 export PYTHONPATH := $(PYTHONPATH):$(S)src/gyp/pylib
 
-define DEF_RUNTIME_TARGETS
-
-######################################################################
-# Runtime (C++) library variables
-######################################################################
-
-# $(1) is the target triple
-# $(2) is the stage number
-
-RUNTIME_CFLAGS_$(1)_$(2) = -D_RUST_STAGE$(2)
-RUNTIME_CXXFLAGS_$(1)_$(2) = -D_RUST_STAGE$(2)
-
-# XXX: Like with --cfg stage0, pass the defines for stage1 to the stage0
-# build of non-build-triple host compilers
-ifeq ($(2),0)
-ifneq ($(strip $(CFG_BUILD)),$(strip $(1)))
-RUNTIME_CFLAGS_$(1)_$(2) = -D_RUST_STAGE1
-RUNTIME_CXXFLAGS_$(1)_$(2) = -D_RUST_STAGE1
-endif
-endif
-
-RUNTIME_CS_$(1)_$(2) := \
-              rt/rust_builtin.c \
-              rt/miniz.c \
-              rt/rust_android_dummy.c \
-              rt/rust_test_helpers.c
-
-RUNTIME_LL_$(1)_$(2) := \
-                       rt/rust_try.ll
-
-# stage0 remove this after the next snapshot
-%.cpp:
-       @touch tmp/foo.o
-
-RUNTIME_S_$(1)_$(2) := rt/arch/$$(HOST_$(1))/_context.S \
-                       rt/arch/$$(HOST_$(1))/record_sp.S
-
-RT_BUILD_DIR_$(1)_$(2) := $$(RT_OUTPUT_DIR_$(1))/stage$(2)
-
-RUNTIME_DEF_$(1)_$(2) := $$(RT_OUTPUT_DIR_$(1))/rustrt$$(CFG_DEF_SUFFIX_$(1))
-RUNTIME_INCS_$(1)_$(2) := -I $$(S)src/rt -I $$(S)src/rt/isaac -I $$(S)src/rt/uthash \
-                     -I $$(S)src/rt/arch/$$(HOST_$(1))
-RUNTIME_OBJS_$(1)_$(2) := \
-                     $$(RUNTIME_CS_$(1)_$(2):rt/%.c=$$(RT_BUILD_DIR_$(1)_$(2))/%.o) \
-                     $$(RUNTIME_S_$(1)_$(2):rt/%.S=$$(RT_BUILD_DIR_$(1)_$(2))/%.o) \
-                     $$(RUNTIME_LL_$(1)_$(2):rt/%.ll=$$(RT_BUILD_DIR_$(1)_$(2))/%.o)
-
-ALL_OBJ_FILES += $$(RUNTIME_OBJS_$(1)_$(2))
-
-MORESTACK_OBJS_$(1)_$(2) := $$(RT_BUILD_DIR_$(1)_$(2))/arch/$$(HOST_$(1))/morestack.o
-ALL_OBJ_FILES += $$(MORESTACK_OBJS_$(1)_$(2))
-
-$$(RT_BUILD_DIR_$(1)_$(2))/%.o: rt/%.c $$(MKFILE_DEPS)
-       @$$(call E, compile: $$@)
-       $$(Q)$$(call CFG_COMPILE_C_$(1), $$@, $$(RUNTIME_INCS_$(1)_$(2)) \
-                 $$(SNAP_DEFINES) $$(RUNTIME_CFLAGS_$(1)_$(2))) $$<
-
-$$(RT_BUILD_DIR_$(1)_$(2))/%.o: rt/%.S  $$(MKFILE_DEPS) \
-                     $$(LLVM_CONFIG_$$(CFG_BUILD))
-       @$$(call E, compile: $$@)
-       $$(Q)$$(call CFG_ASSEMBLE_$(1),$$@,$$<)
-
-$$(RT_BUILD_DIR_$(1)_$(2))/%.o: rt/%.ll  $$(MKFILE_DEPS) \
-                     $$(LLVM_CONFIG_$$(CFG_BUILD))
-       @$$(call E, compile: $$@)
-       $$(Q)$(LLC_$(CFG_BUILD)) $$(CFG_LLC_FLAGS_$(1)) -filetype=obj -mtriple=$(1) -relocation-model=pic -o $$@ $$<
-
-$$(RT_BUILD_DIR_$(1)_$(2))/arch/$$(HOST_$(1))/libmorestack.a: $$(MORESTACK_OBJS_$(1)_$(2))
-       @$$(call E, link: $$@)
-       $$(Q)$(AR_$(1)) rcs $$@ $$^
-
-$$(RT_BUILD_DIR_$(1)_$(2))/$(CFG_RUNTIME_$(1)): $$(RUNTIME_OBJS_$(1)_$(2)) $$(MKFILE_DEPS)
-       @$$(call E, link: $$@)
-       $$(Q)$(AR_$(1)) rcs $$@ $$(RUNTIME_OBJS_$(1)_$(2))
-
-# These could go in rt.mk or rustllvm.mk, they're needed for both.
-
-# This regexp has a single $$ escaped twice
-$(1)/%.bsd.def:    %.def.in $$(MKFILE_DEPS)
-       @$$(call E, def: $$@)
-       $$(Q)echo "{" > $$@
-       $$(Q)sed 's/.$$$$/&;/' $$< >> $$@
-       $$(Q)echo "};" >> $$@
-
-$(1)/%.linux.def:    %.def.in $$(MKFILE_DEPS)
-       @$$(call E, def: $$@)
-       $$(Q)echo "{" > $$@
-       $$(Q)sed 's/.$$$$/&;/' $$< >> $$@
-       $$(Q)echo "};" >> $$@
-
-$(1)/%.darwin.def:     %.def.in $$(MKFILE_DEPS)
-       @$$(call E, def: $$@)
-       $$(Q)sed 's/^./_&/' $$< > $$@
-
-$(1)/%.android.def:  %.def.in $$(MKFILE_DEPS)
-       @$$(call E, def: $$@)
-       $$(Q)echo "{" > $$@
-       $$(Q)sed 's/.$$$$/&;/' $$< >> $$@
-       $$(Q)echo "};" >> $$@
-
-$(1)/%.mingw32.def:    %.def.in $$(MKFILE_DEPS)
-       @$$(call E, def: $$@)
-       $$(Q)echo LIBRARY $$* > $$@
-       $$(Q)echo EXPORTS >> $$@
-       $$(Q)sed 's/^./    &/' $$< >> $$@
-
-endef
-
-
-######################################################################
-# Runtime third party targets (libuv, jemalloc, etc.)
-#
-# These targets do not need to be built once per stage, so these
-# rules just build them once and then we're done with them.
-######################################################################
-
 define DEF_THIRD_PARTY_TARGETS
 
 # $(1) is the target triple
 
-RT_OUTPUT_DIR_$(1) := $(1)/rt
-
 ifeq ($$(CFG_WINDOWSY_$(1)), 1)
   LIBUV_OSTYPE_$(1) := win
 else ifeq ($(OSTYPE_$(1)), apple-darwin)
@@ -188,7 +163,7 @@ endif
 
 LIBUV_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),uv)
 LIBUV_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/libuv
-LIBUV_LIB_$(1) := $$(LIBUV_DIR_$(1))/$$(LIBUV_NAME_$(1))
+LIBUV_LIB_$(1) := $$(RT_OUTPUT_DIR_$(1))/$$(LIBUV_NAME_$(1))
 
 LIBUV_MAKEFILE_$(1) := $$(CFG_BUILD_DIR)$$(RT_OUTPUT_DIR_$(1))/libuv/Makefile
 
@@ -224,7 +199,7 @@ $$(LIBUV_LIB_$(1)): $$(LIBUV_DEPS) $$(MKFILE_DEPS)
        $$(Q)cp $$(S)src/libuv/libuv.a $$@
 else
 $$(LIBUV_LIB_$(1)): $$(LIBUV_DIR_$(1))/Release/libuv.a $$(MKFILE_DEPS)
-       $$(Q)ln -f $$< $$@
+       $$(Q)cp $$< $$@
 $$(LIBUV_DIR_$(1))/Release/libuv.a: $$(LIBUV_DEPS) $$(LIBUV_MAKEFILE_$(1)) \
                                    $$(MKFILE_DEPS)
        $$(Q)$$(MAKE) -C $$(LIBUV_DIR_$(1)) \
@@ -237,60 +212,11 @@ $$(LIBUV_DIR_$(1))/Release/libuv.a: $$(LIBUV_DEPS) $$(LIBUV_MAKEFILE_$(1)) \
                BUILDTYPE=Release \
                NO_LOAD="$$(LIBUV_NO_LOAD)" \
                V=$$(VERBOSE)
-endif
-
-# libuv support functionality (extra C/C++ that we need to use libuv)
 
-UV_SUPPORT_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),uv_support)
-UV_SUPPORT_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/uv_support
-UV_SUPPORT_LIB_$(1) := $$(UV_SUPPORT_DIR_$(1))/$$(UV_SUPPORT_NAME_$(1))
-UV_SUPPORT_CS_$(1) := rt/rust_uv.c
-UV_SUPPORT_OBJS_$(1) := $$(UV_SUPPORT_CS_$(1):rt/%.c=$$(UV_SUPPORT_DIR_$(1))/%.o)
-
-$$(UV_SUPPORT_DIR_$(1))/%.o: rt/%.c
-       @$$(call E, compile: $$@)
-       @mkdir -p $$(@D)
-       $$(Q)$$(call CFG_COMPILE_C_$(1), $$@, \
-               -I $$(S)src/libuv/include \
-                 $$(RUNTIME_CFLAGS_$(1))) $$<
-
-$$(UV_SUPPORT_LIB_$(1)): $$(UV_SUPPORT_OBJS_$(1))
-       @$$(call E, link: $$@)
-       $$(Q)$$(AR_$(1)) rcs $$@ $$^
-
-# sundown markdown library (used by librustdoc)
-
-SUNDOWN_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),sundown)
-SUNDOWN_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/sundown
-SUNDOWN_LIB_$(1) := $$(SUNDOWN_DIR_$(1))/$$(SUNDOWN_NAME_$(1))
-
-SUNDOWN_CS_$(1) := rt/sundown/src/autolink.c \
-                       rt/sundown/src/buffer.c \
-                       rt/sundown/src/stack.c \
-                       rt/sundown/src/markdown.c \
-                       rt/sundown/html/houdini_href_e.c \
-                       rt/sundown/html/houdini_html_e.c \
-                       rt/sundown/html/html_smartypants.c \
-                       rt/sundown/html/html.c
-
-SUNDOWN_OBJS_$(1) := $$(SUNDOWN_CS_$(1):rt/%.c=$$(SUNDOWN_DIR_$(1))/%.o)
-
-$$(SUNDOWN_DIR_$(1))/%.o: rt/%.c
-       @$$(call E, compile: $$@)
-       @mkdir -p $$(@D)
-       $$(Q)$$(call CFG_COMPILE_C_$(1), $$@, \
-               -I $$(S)src/rt/sundown/src -I $$(S)src/rt/sundown/html \
-                 $$(RUNTIME_CFLAGS_$(1))) $$<
-
-$$(SUNDOWN_LIB_$(1)): $$(SUNDOWN_OBJS_$(1))
-       @$$(call E, link: $$@)
-       $$(Q)$$(AR_$(1)) rcs $$@ $$^
+endif
 
 endef
 
 # Instantiate template for all stages/targets
 $(foreach target,$(CFG_TARGET), \
      $(eval $(call DEF_THIRD_PARTY_TARGETS,$(target))))
-$(foreach stage,$(STAGES), \
-    $(foreach target,$(CFG_TARGET), \
-        $(eval $(call DEF_RUNTIME_TARGETS,$(target),$(stage)))))
index 89b31400d5c3da9c841f564aa985ca2c7114c99c..8d7abc020cc27a3ca4f9a62598a6ae8700e5811b 100644 (file)
@@ -32,7 +32,8 @@ RUSTLLVM_INCS_$(1) = $$(LLVM_EXTRA_INCDIRS_$(1)) \
 RUSTLLVM_OBJS_OBJS_$(1) := $$(RUSTLLVM_OBJS_CS_$(1):rustllvm/%.cpp=$(1)/rustllvm/%.o)
 ALL_OBJ_FILES += $$(RUSTLLVM_OBJS_OBJS_$(1))
 
-$(1)/rustllvm/$(CFG_RUSTLLVM_$(1)): $$(RUSTLLVM_OBJS_OBJS_$(1))
+$$(RT_OUTPUT_DIR_$(1))/$$(call CFG_STATIC_LIB_NAME_$(1),rustllvm): \
+           $$(RUSTLLVM_OBJS_OBJS_$(1))
        @$$(call E, link: $$@)
        $$(Q)$$(AR_$(1)) rcs $$@ $$(RUSTLLVM_OBJS_OBJS_$(1))
 
index 5fdc3a34bcbeb3b396216e27b759e7308b2c5568..c4bd082b3a28d123b35a719fd901919acb47f6d0 100644 (file)
@@ -21,13 +21,104 @@ WFLAGS_ST0 = -W warnings
 WFLAGS_ST1 = -D warnings
 WFLAGS_ST2 = -D warnings
 
-# TARGET_STAGE_N template: This defines how target artifacts are built
-# for all stage/target architecture combinations. The arguments:
+# Macro that generates the full list of dependencies for a crate at a particular
+# stage/target/host tuple.
+#
+# $(1) - stage
+# $(2) - target
+# $(3) - host
+# $(4) crate
+define RUST_CRATE_FULLDEPS
+CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4) :=                          \
+               $$(CRATEFILE_$(4))                                  \
+               $$(RSINPUTS_$(4))                                   \
+               $$(foreach dep,$$(RUST_DEPS_$(4)),                  \
+                 $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(dep))         \
+               $$(foreach dep,$$(NATIVE_DEPS_$(4)),                \
+                 $$(RT_OUTPUT_DIR_$(2))/$$(call CFG_STATIC_LIB_NAME_$(2),$$(dep)))
+endef
+
+$(foreach host,$(CFG_HOST),                                                \
+ $(foreach target,$(CFG_TARGET),                                           \
+  $(foreach stage,$(STAGES),                                               \
+   $(foreach crate,$(CRATES),                                              \
+    $(eval $(call RUST_CRATE_FULLDEPS,$(stage),$(target),$(host),$(crate)))))))
+
+# RUST_TARGET_STAGE_N template: This defines how target artifacts are built
+# for all stage/target architecture combinations. This is one giant rule which
+# works as follows:
+#
+#   1. The immediate dependencies are the rust source files
+#   2. Each rust crate dependency is listed (based on their stamp files),
+#      as well as all native dependencies (listed in RT_OUTPUT_DIR)
+#   3. The stage (n-1) compiler is required through the TSREQ dependency, along
+#      with the morestack library
+#   4. When actually executing the rule, the first thing we do is to clean out
+#      old libs and rlibs via the REMOVE_ALL_OLD_GLOB_MATCHES macro
+#   5. Finally, we get around to building the actual crate. It's just one
+#      "small" invocation of the previous stage rustc. We use -L to
+#      RT_OUTPUT_DIR so all the native dependencies are picked up.
+#      Additionally, we pass in the llvm dir so rustc can link against it.
+#   6. Some cleanup is done (listing what was just built) if verbose is turned
+#      on.
+#
 # $(1) is the stage
 # $(2) is the target triple
 # $(3) is the host triple
+# $(4) is the crate name
+define RUST_TARGET_STAGE_N
+
+$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): CFG_COMPILER = $(2)
+$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4):                             \
+               $$(CRATEFILE_$(4))                                  \
+               $$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4))          \
+               $$(TSREQ$(1)_T_$(2)_H_$(3))                         \
+               | $$(TLIB$(1)_T_$(2)_H_$(3))/
+       @$$(call E, compile_and_link: $$(@D)/lib$(4))
+       $$(call REMOVE_ALL_OLD_GLOB_MATCHES,\
+           $$(dir $$@)$$(call CFG_LIB_GLOB_$(2),$(4)))
+       $$(call REMOVE_ALL_OLD_GLOB_MATCHES,\
+           $$(dir $$@)$$(call CFG_RLIB_GLOB,$(4)))
+       $$(STAGE$(1)_T_$(2)_H_$(3)) \
+               $$(WFLAGS_ST$(1)) \
+               -L "$$(RT_OUTPUT_DIR_$(2))" \
+               -L "$$(LLVM_LIBDIR_$(2))" \
+               --out-dir $$(@D) $$<
+       @touch $$@
+       $$(call LIST_ALL_OLD_GLOB_MATCHES,\
+           $$(dir $$@)$$(call CFG_LIB_GLOB_$(2),$(4)))
+       $$(call LIST_ALL_OLD_GLOB_MATCHES,\
+           $$(dir $$@)$$(call CFG_RLIB_GLOB,$(4)))
+
+endef
+
+# Macro for building any tool as part of the rust compilation process. Each
+# tool is defined in crates.mk with a list of library dependencies as well as
+# the source file for the tool. Building each tool will also be passed '--cfg
+# <tool>' for usage in driver.rs
+#
+# This build rule is similar to the one found above, just tweaked for
+# locations and things.
+#
+# $(1) - stage
+# $(2) - target triple
+# $(3) - host triple
+# $(4) - name of the tool being built
+define TARGET_TOOL
+
+$$(TBIN$(1)_T_$(2)_H_$(3))/$(4)$$(X_$(2)):                     \
+               $$(TOOL_SOURCE_$(4))                            \
+               $$(TOOL_INPUTS_$(4))                            \
+               $$(foreach dep,$$(TOOL_DEPS_$(4)),              \
+                   $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(dep))   \
+               $$(TSREQ$(1)_T_$(2)_H_$(3))                     \
+               | $$(TBIN$(1)_T_$(4)_H_$(3))/
+       @$$(call E, compile_and_link: $$@)
+       $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --cfg $(4)
+
+endef
 
-# Every recipe in TARGET_STAGE_N outputs to $$(TLIB$(1)_T_$(2)_H_$(3),
+# Every recipe in RUST_TARGET_STAGE_N outputs to $$(TLIB$(1)_T_$(2)_H_$(3),
 # a directory that can be cleaned out during the middle of a run of
 # the get-snapshot.py script.  Therefore, every recipe needs to have
 # an order-only dependency either on $(SNAPSHOT_RUSTC_POST_CLEANUP) or
@@ -35,147 +126,11 @@ WFLAGS_ST2 = -D warnings
 # put into the target area until after the get-snapshot.py script has
 # had its chance to clean it out; otherwise the other products will be
 # inadvertantly included in the clean out.
-
 SNAPSHOT_RUSTC_POST_CLEANUP=$(HBIN0_H_$(CFG_BUILD))/rustc$(X_$(CFG_BUILD))
 
-define TARGET_STAGE_N
-
-$$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a: \
-               $(2)/rt/stage$(1)/arch/$$(HOST_$(2))/libmorestack.a \
-               | $$(TLIB$(1)_T_$(2)_H_$(3))/ \
-                 $(SNAPSHOT_RUSTC_POST_CLEANUP)
-       @$$(call E, cp: $$@)
-       $$(Q)cp $$< $$@
+define TARGET_HOST_RULES
 
-$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUNTIME_$(2)): \
-               $(2)/rt/stage$(1)/$(CFG_RUNTIME_$(2)) \
-               | $$(TLIB$(1)_T_$(2)_H_$(3))/ \
-                 $(SNAPSHOT_RUSTC_POST_CLEANUP)
-       @$$(call E, cp: $$@)
-       $$(Q)cp $$< $$@
-
-$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)): \
-               $$(STDLIB_CRATE) $$(STDLIB_INPUTS) \
-               $$(TSREQ$(1)_T_$(2)_H_$(3)) \
-               | $$(TLIB$(1)_T_$(2)_H_$(3))/
-       @$$(call E, compile_and_link: $$@)
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(STDLIB_GLOB_$(2)),$$(notdir $$@))
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(STDLIB_RGLOB_$(2)),$$(notdir $$@))
-       $$(STAGE$(1)_T_$(2)_H_$(3)) $$(WFLAGS_ST$(1)) \
-               --out-dir $$(@D) $$< && touch $$@
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(STDLIB_GLOB_$(2)),$$(notdir $$@))
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(STDLIB_RGLOB_$(2)),$$(notdir $$@))
-
-$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2)): \
-               $$(EXTRALIB_CRATE) $$(EXTRALIB_INPUTS) \
-               $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)) \
-               $$(TSREQ$(1)_T_$(2)_H_$(3)) \
-               | $$(TLIB$(1)_T_$(2)_H_$(3))/
-       @$$(call E, compile_and_link: $$@)
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(EXTRALIB_GLOB_$(2)),$$(notdir $$@))
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(EXTRALIB_RGLOB_$(2)),$$(notdir $$@))
-       $$(STAGE$(1)_T_$(2)_H_$(3)) $$(WFLAGS_ST$(1)) \
-               --out-dir $$(@D) $$< && touch $$@
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(EXTRALIB_GLOB_$(2)),$$(notdir $$@))
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(EXTRALIB_RGLOB_$(2)),$$(notdir $$@))
-
-$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTUV_$(2)): \
-               $$(LIBRUSTUV_CRATE) $$(LIBRUSTUV_INPUTS) \
-               $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)) \
-               $$(TSREQ$(1)_T_$(2)_H_$(3)) \
-               $$(LIBUV_LIB_$(2)) \
-               $$(UV_SUPPORT_LIB_$(2)) \
-               | $$(TLIB$(1)_T_$(2)_H_$(3))/
-       @$$(call E, compile_and_link: $$@)
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTUV_GLOB_$(2)),$$(notdir $$@))
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTUV_RGLOB_$(2)),$$(notdir $$@))
-       $$(STAGE$(1)_T_$(2)_H_$(3)) $$(WFLAGS_ST$(1)) \
-               -L $$(UV_SUPPORT_DIR_$(2)) \
-               -L $$(dir $$(LIBUV_LIB_$(2))) \
-               --out-dir $$(@D) $$< && touch $$@
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTUV_GLOB_$(2)),$$(notdir $$@))
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTUV_RGLOB_$(2)),$$(notdir $$@))
-
-$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBGREEN_$(2)): \
-               $$(LIBGREEN_CRATE) $$(LIBGREEN_INPUTS) \
-               $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)) \
-               $$(TSREQ$(1)_T_$(2)_H_$(3)) \
-               | $$(TLIB$(1)_T_$(2)_H_$(3))/
-       @$$(call E, compile_and_link: $$@)
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBGREEN_GLOB_$(2)),$$(notdir $$@))
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBGREEN_RGLOB_$(2)),$$(notdir $$@))
-       $$(STAGE$(1)_T_$(2)_H_$(3)) $$(WFLAGS_ST$(1)) \
-               --out-dir $$(@D) $$< && touch $$@
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBGREEN_GLOB_$(2)),$$(notdir $$@))
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBGREEN_RGLOB_$(2)),$$(notdir $$@))
-
-$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBNATIVE_$(2)): \
-               $$(LIBNATIVE_CRATE) $$(LIBNATIVE_INPUTS) \
-               $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)) \
-               $$(TSREQ$(1)_T_$(2)_H_$(3)) \
-               | $$(TLIB$(1)_T_$(2)_H_$(3))/
-       @$$(call E, compile_and_link: $$@)
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBNATIVE_GLOB_$(2)),$$(notdir $$@))
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBNATIVE_RGLOB_$(2)),$$(notdir $$@))
-       $$(STAGE$(1)_T_$(2)_H_$(3)) $$(WFLAGS_ST$(1)) \
-               --out-dir $$(@D) $$< && touch $$@
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBNATIVE_GLOB_$(2)),$$(notdir $$@))
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBNATIVE_RGLOB_$(2)),$$(notdir $$@))
-
-$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(3)): \
-                $$(LIBSYNTAX_CRATE) $$(LIBSYNTAX_INPUTS) \
-               $$(TSREQ$(1)_T_$(2)_H_$(3))                     \
-               $$(TSTDLIB_DEFAULT$(1)_T_$(2)_H_$(3))      \
-               $$(TEXTRALIB_DEFAULT$(1)_T_$(2)_H_$(3)) \
-               | $$(TLIB$(1)_T_$(2)_H_$(3))/
-       @$$(call E, compile_and_link: $$@)
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBSYNTAX_GLOB_$(2)),$$(notdir $$@))
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBSYNTAX_RGLOB_$(2)),$$(notdir $$@))
-       $$(STAGE$(1)_T_$(2)_H_$(3)) $$(WFLAGS_ST$(1)) $(BORROWCK) \
-           --out-dir $$(@D) $$< && touch $$@
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBSYNTAX_GLOB_$(2)),$$(notdir $$@))
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBSYNTAX_RGLOB_$(2)),$$(notdir $$@))
-
-# Only build the compiler for host triples
-ifneq ($$(findstring $(2),$$(CFG_HOST)),)
-
-$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUSTLLVM_$(3)): \
-               $(2)/rustllvm/$(CFG_RUSTLLVM_$(3)) \
-               | $$(TLIB$(1)_T_$(2)_H_$(3))/ \
-                 $(SNAPSHOT_RUSTC_POST_CLEANUP)
-       @$$(call E, cp: $$@)
-       $$(Q)cp $$< $$@
-
-$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(3)): CFG_COMPILER = $(2)
-$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(3)):               \
-               $$(COMPILER_CRATE) $$(COMPILER_INPUTS)          \
-               $(S)src/librustc/lib/llvmdeps.rs                \
-               $$(TSREQ$(1)_T_$(2)_H_$(3)) \
-                $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(3)) \
-                $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUSTLLVM_$(3)) \
-               | $$(TLIB$(1)_T_$(2)_H_$(3))/
-       @$$(call E, compile_and_link: $$@)
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTC_GLOB_$(2)),$$(notdir $$@))
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTC_RGLOB_$(2)),$$(notdir $$@))
-       $$(STAGE$(1)_T_$(2)_H_$(3)) $$(WFLAGS_ST$(1)) \
-           -L "$$(LLVM_LIBDIR_$(2))" \
-           --out-dir $$(@D) $$< && touch $$@
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTC_GLOB_$(2)),$$(notdir $$@))
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTC_RGLOB_$(2)),$$(notdir $$@))
-
-$$(TBIN$(1)_T_$(2)_H_$(3))/rustc$$(X_$(3)):                    \
-               $$(DRIVER_CRATE)                                \
-               $$(SREQ$(1)_T_$(2)_H_$(3)) \
-               $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(3)) \
-               | $$(TBIN$(1)_T_$(2)_H_$(3))/
-       @$$(call E, compile_and_link: $$@)
-       $$(STAGE$(1)_T_$(2)_H_$(3)) --cfg rustc -o $$@ $$<
-ifdef CFG_ENABLE_PAX_FLAGS
-       @$$(call E, apply PaX flags: $$@)
-       @"$(CFG_PAXCTL)" -cm "$$@"
-endif
-
-endif
+$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.rustc: $(S)src/librustc/lib/llvmdeps.rs
 
 $$(TBIN$(1)_T_$(2)_H_$(3))/:
        mkdir -p $$@
@@ -183,12 +138,31 @@ $$(TBIN$(1)_T_$(2)_H_$(3))/:
 $$(TLIB$(1)_T_$(2)_H_$(3))/:
        mkdir -p $$@
 
+$$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a: \
+           $$(RT_OUTPUT_DIR_$(2))/$$(call CFG_STATIC_LIB_NAME_$(2),morestack) \
+           | $$(TLIB$(1)_T_$(2)_H_$(3))/ $$(SNAPSHOT_RUSTC_POST_CLEANUP)
+       @$$(call E, cp: $$@)
+       $$(Q)cp $$< $$@
 endef
 
-# In principle, each host can build each target:
-$(foreach source,$(CFG_HOST),                          \
- $(foreach target,$(CFG_TARGET),                       \
-  $(eval $(call TARGET_STAGE_N,0,$(target),$(source)))         \
-  $(eval $(call TARGET_STAGE_N,1,$(target),$(source)))         \
-  $(eval $(call TARGET_STAGE_N,2,$(target),$(source)))         \
-  $(eval $(call TARGET_STAGE_N,3,$(target),$(source)))))
+$(foreach source,$(CFG_HOST),                                              \
+ $(foreach target,$(CFG_TARGET),                                           \
+  $(eval $(call TARGET_HOST_RULES,0,$(target),$(source)))                  \
+  $(eval $(call TARGET_HOST_RULES,1,$(target),$(source)))                  \
+  $(eval $(call TARGET_HOST_RULES,2,$(target),$(source)))                  \
+  $(eval $(call TARGET_HOST_RULES,3,$(target),$(source)))))
+
+# In principle, each host can build each target for both libs and tools
+$(foreach crate,$(CRATES),                                                 \
+ $(foreach source,$(CFG_HOST),                                             \
+  $(foreach target,$(CFG_TARGET),                                          \
+   $(eval $(call RUST_TARGET_STAGE_N,0,$(target),$(source),$(crate)))      \
+   $(eval $(call RUST_TARGET_STAGE_N,1,$(target),$(source),$(crate)))      \
+   $(eval $(call RUST_TARGET_STAGE_N,2,$(target),$(source),$(crate)))      \
+   $(eval $(call RUST_TARGET_STAGE_N,3,$(target),$(source),$(crate))))))
+
+$(foreach host,$(CFG_HOST),                                                \
+ $(foreach target,$(CFG_TARGET),                                           \
+  $(foreach stage,$(STAGES),                                               \
+   $(foreach tool,$(TOOLS),                                                \
+    $(eval $(call TARGET_TOOL,$(stage),$(target),$(host),$(tool)))))))
index 58f9ee2e81537818a329a0585db3062511df1a00..ab70b3afba975101fd1b44e55342c3a0ea352946 100644 (file)
@@ -14,9 +14,9 @@
 ######################################################################
 
 # The names of crates that must be tested
-TEST_TARGET_CRATES = std extra rustuv green native
-TEST_DOC_CRATES = std extra
-TEST_HOST_CRATES = rustpkg rustc rustdoc syntax
+TEST_TARGET_CRATES = $(TARGET_CRATES)
+TEST_DOC_CRATES = $(DOC_CRATES)
+TEST_HOST_CRATES = $(HOST_CRATES)
 TEST_CRATES = $(TEST_TARGET_CRATES) $(TEST_HOST_CRATES)
 
 # Markdown files under doc/ that should have their code extracted and run
@@ -156,16 +156,9 @@ $(info check: android device test dir $(CFG_ADB_TEST_DIR) ready \
  $(shell $(CFG_ADB) shell mkdir $(CFG_ADB_TEST_DIR)) \
  $(shell $(CFG_ADB) shell mkdir $(CFG_ADB_TEST_DIR)/tmp) \
  $(shell $(CFG_ADB) push $(S)src/etc/adb_run_wrapper.sh $(CFG_ADB_TEST_DIR) 1>/dev/null) \
- $(shell $(CFG_ADB) push $(TLIB2_T_arm-linux-androideabi_H_$(CFG_BUILD))/$(CFG_RUNTIME_arm-linux-androideabi) \
-                    $(CFG_ADB_TEST_DIR)) \
- $(shell $(CFG_ADB) push $(TLIB2_T_arm-linux-androideabi_H_$(CFG_BUILD))/$(STDLIB_GLOB_arm-linux-androideabi) \
-                    $(CFG_ADB_TEST_DIR)) \
- $(shell $(CFG_ADB) push $(TLIB2_T_arm-linux-androideabi_H_$(CFG_BUILD))/$(EXTRALIB_GLOB_arm-linux-androideabi) \
-                    $(CFG_ADB_TEST_DIR)) \
- $(shell $(CFG_ADB) push $(TLIB2_T_arm-linux-androideabi_H_$(CFG_BUILD))/$(LIBRUSTUV_GLOB_arm-linux-androideabi) \
-                    $(CFG_ADB_TEST_DIR)) \
- $(shell $(CFG_ADB) push $(TLIB2_T_arm-linux-androideabi_H_$(CFG_BUILD))/$(LIBGREEN_GLOB_arm-linux-androideabi) \
-                    $(CFG_ADB_TEST_DIR)) \
+ $(foreach crate,$(TARGET_CRATES),\
+    $(shell $(CFG_ADB) push $(TLIB2_T_arm-linux-androideabi_H_$(CFG_BUILD))/$(call CFG_LIB_GLOB_arm-linux-androideabi,$(crate)) \
+                    $(CFG_ADB_TEST_DIR)))\
  )
 else
 CFG_ADB_TEST_DIR=
@@ -341,89 +334,30 @@ define TEST_RUNNER
 # If NO_REBUILD is set then break the dependencies on extra so we can
 # test crates without rebuilding std and extra first
 ifeq ($(NO_REBUILD),)
-STDTESTDEP_$(1)_$(2)_$(3) = $$(SREQ$(1)_T_$(2)_H_$(3)) \
-                            $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_EXTRALIB_$(2)) \
-                            $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTUV_$(2)) \
-                            $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBGREEN_$(2))
+STDTESTDEP_$(1)_$(2)_$(3)_$(4) = $$(SREQ$(1)_T_$(2)_H_$(3)) \
+                           $$(foreach crate,$$(TARGET_CRATES),\
+                               $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(crate))
 else
-STDTESTDEP_$(1)_$(2)_$(3) =
+STDTESTDEP_$(1)_$(2)_$(3)_$(4) =
 endif
 
-$(3)/stage$(1)/test/stdtest-$(2)$$(X_$(2)):                    \
-               $$(STDLIB_CRATE) $$(STDLIB_INPUTS)              \
-               $$(STDTESTDEP_$(1)_$(2)_$(3))
+$(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2)): CFG_COMPILER = $(2)
+$(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2)):                           \
+               $$(CRATEFILE_$(4))                                      \
+               $$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4))              \
+               $$(STDTESTDEP_$(1)_$(2)_$(3)_$(4))
        @$$(call E, compile_and_link: $$@)
-       $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
-
-$(3)/stage$(1)/test/extratest-$(2)$$(X_$(2)):                  \
-               $$(EXTRALIB_CRATE) $$(EXTRALIB_INPUTS)          \
-               $$(STDTESTDEP_$(1)_$(2)_$(3))
-       @$$(call E, compile_and_link: $$@)
-       $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
-
-$(3)/stage$(1)/test/rustuvtest-$(2)$$(X_$(2)):                 \
-               $$(LIBRUSTUV_CRATE) $$(LIBRUSTUV_INPUTS)        \
-               $$(STDTESTDEP_$(1)_$(2)_$(3))
-       @$$(call E, compile_and_link: $$@)
-       $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test \
-               -L $$(UV_SUPPORT_DIR_$(2)) \
-               -L $$(dir $$(LIBUV_LIB_$(2)))
-
-$(3)/stage$(1)/test/nativetest-$(2)$$(X_$(2)):                 \
-               $$(LIBNATIVE_CRATE) $$(LIBNATIVE_INPUTS)        \
-               $$(STDTESTDEP_$(1)_$(2)_$(3))
-       @$$(call E, compile_and_link: $$@)
-       $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
-
-$(3)/stage$(1)/test/greentest-$(2)$$(X_$(2)):                  \
-               $$(LIBGREEN_CRATE) $$(LIBGREEN_INPUTS)  \
-               $$(STDTESTDEP_$(1)_$(2)_$(3))
-       @$$(call E, compile_and_link: $$@)
-       $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
-
-$(3)/stage$(1)/test/syntaxtest-$(2)$$(X_$(2)):                 \
-               $$(LIBSYNTAX_CRATE) $$(LIBSYNTAX_INPUTS)        \
-               $$(STDTESTDEP_$(1)_$(2)_$(3))
-       @$$(call E, compile_and_link: $$@)
-       $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
-
-$(3)/stage$(1)/test/rustctest-$(2)$$(X_$(2)): CFG_COMPILER = $(2)
-$(3)/stage$(1)/test/rustctest-$(2)$$(X_$(2)):                                  \
-               $$(COMPILER_CRATE) $$(COMPILER_INPUTS) \
-               $$(SREQ$(1)_T_$(2)_H_$(3)) \
-               $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_RUSTLLVM_$(2)) \
-               $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBSYNTAX_$(2))
-       @$$(call E, compile_and_link: $$@)
-       $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test \
-           -L "$$(LLVM_LIBDIR_$(2))"
-
-$(3)/stage$(1)/test/rustpkgtest-$(2)$$(X_$(2)):                                        \
-               $$(RUSTPKG_LIB) $$(RUSTPKG_INPUTS)              \
-               $$(SREQ$(1)_T_$(2)_H_$(3)) \
-               $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBSYNTAX_$(2)) \
-               $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC_$(2)) \
-               $$(HBIN$(1)_H_$(3))/rustpkg$$(X_$(2)) \
-               $$(TBIN$(1)_T_$(2)_H_$(3))/rustpkg$$(X_$(2)) \
-               $$(TBIN$(1)_T_$(2)_H_$(3))/rustc$$(X_$(2))
-       @$$(call E, compile_and_link: $$@)
-       $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
-
-$(3)/stage$(1)/test/rustdoctest-$(2)$$(X_$(2)):                                        \
-               $$(RUSTDOC_LIB) $$(RUSTDOC_INPUTS)              \
-               $$(SREQ$(1)_T_$(2)_H_$(3)) \
-               $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBSYNTAX_$(2)) \
-               $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC_$(2)) \
-               $$(SUNDOWN_LIB_$(2))
-       @$$(call E, compile_and_link: $$@)
-       $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test \
-               -L $$(SUNDOWN_DIR_$(2))
+       $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test   \
+               -L "$$(RT_OUTPUT_DIR_$(2))"             \
+               -L "$$(LLVM_LIBDIR_$(2))"
 
 endef
 
 $(foreach host,$(CFG_HOST), \
  $(eval $(foreach target,$(CFG_TARGET), \
   $(eval $(foreach stage,$(STAGES), \
-   $(eval $(call TEST_RUNNER,$(stage),$(target),$(host))))))))
+   $(eval $(foreach crate,$(TEST_CRATES), \
+    $(eval $(call TEST_RUNNER,$(stage),$(target),$(host),$(crate))))))))))
 
 define DEF_TEST_CRATE_RULES
 check-stage$(1)-T-$(2)-H-$(3)-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4))
@@ -629,7 +563,7 @@ CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3) :=                                              \
         --host $(3)                                       \
         --adb-path=$(CFG_ADB)                          \
         --adb-test-dir=$(CFG_ADB_TEST_DIR)                  \
-        --rustcflags "$(RUSTC_FLAGS_$(2)) $$(CTEST_RUSTC_FLAGS)" \
+        --rustcflags "$(RUSTC_FLAGS_$(2)) $$(CTEST_RUSTC_FLAGS) -L $$(RT_OUTPUT_DIR_$(2))" \
         $$(CTEST_TESTARGS)
 
 CTEST_DEPS_rpass_$(1)-T-$(2)-H-$(3) = $$(RPASS_TESTS)
@@ -758,20 +692,18 @@ $(foreach host,$(CFG_HOST), \
    $(foreach docname,$(DOC_TEST_NAMES), \
     $(eval $(call DEF_RUN_DOC_TEST,$(stage),$(target),$(host),$(docname)))))))
 
-CRATE_DOC_LIB-std = $(STDLIB_CRATE)
-CRATE_DOC_LIB-extra = $(EXTRALIB_CRATE)
-
 define DEF_CRATE_DOC_TEST
 
 check-stage$(1)-T-$(2)-H-$(3)-doc-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4))
 
 ifeq ($(2),$$(CFG_BUILD))
-$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)):         \
-               $$(TEST_SREQ$(1)_T_$(2)_H_$(3))         \
+$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)):                         \
+               $$(TEST_SREQ$(1)_T_$(2)_H_$(3))                         \
+               $$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4))              \
                $$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3))
        @$$(call E, run doc-$(4) [$(2)])
        $$(Q)$$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) --test \
-           $$(CRATE_DOC_LIB-$(4)) --test-args "$$(TESTARGS)" && touch $$@
+           $$(CRATEFILE_$(4)) --test-args "$$(TESTARGS)" && touch $$@
 else
 $$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)):
        touch $$@
@@ -915,14 +847,16 @@ $$(TLIB2_T_$(2)_H_$(3))/$$(FT_LIB): \
                tmp/$$(FT).rc \
                $$(SREQ2_T_$(2)_H_$(3))
        @$$(call E, compile_and_link: $$@)
-       $$(STAGE2_T_$(2)_H_$(3)) --lib -o $$@ $$<
+       $$(STAGE2_T_$(2)_H_$(3)) --lib -o $$@ $$< \
+         -L "$$(RT_OUTPUT_DIR_$(2))"
 
 $(3)/test/$$(FT_DRIVER)-$(2)$$(X_$(2)): \
                tmp/$$(FT_DRIVER).rs \
                $$(TLIB2_T_$(2)_H_$(3))/$$(FT_LIB) \
                $$(SREQ2_T_$(2)_H_$(3))
        @$$(call E, compile_and_link: $$@ $$<)
-       $$(STAGE2_T_$(2)_H_$(3)) -o $$@ $$<
+       $$(STAGE2_T_$(2)_H_$(3)) -o $$@ $$< \
+         -L "$$(RT_OUTPUT_DIR_$(2))"
 
 $(3)/test/$$(FT_DRIVER)-$(2).out: \
                $(3)/test/$$(FT_DRIVER)-$(2)$$(X_$(2)) \
diff --git a/mk/tools.mk b/mk/tools.mk
deleted file mode 100644 (file)
index 5ae33cb..0000000
+++ /dev/null
@@ -1,142 +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.
-
-# Rules for non-core tools built with the compiler, both for target
-# and host architectures
-
-# The test runner that runs the cfail/rfail/rpass and bxench tests
-COMPILETEST_CRATE := $(S)src/compiletest/compiletest.rs
-COMPILETEST_INPUTS := $(wildcard $(S)src/compiletest/*.rs)
-
-# Rustpkg, the package manager and build system
-RUSTPKG_LIB := $(S)src/librustpkg/lib.rs
-RUSTPKG_INPUTS := $(wildcard $(S)src/librustpkg/*.rs)
-
-# Rustdoc, the documentation tool
-RUSTDOC_LIB := $(S)src/librustdoc/lib.rs
-RUSTDOC_INPUTS := $(wildcard $(addprefix $(S)src/librustdoc/,        \
-                                           *.rs */*.rs */*/*.rs))
-
-# FIXME: These are only built for the host arch. Eventually we'll
-# have tools that need to built for other targets.
-define TOOLS_STAGE_N_TARGET
-
-$$(TBIN$(1)_T_$(4)_H_$(3))/compiletest$$(X_$(4)):                      \
-               $$(COMPILETEST_CRATE) $$(COMPILETEST_INPUTS)    \
-               $$(SREQ$(1)_T_$(4)_H_$(3))                      \
-               | $$(TBIN$(1)_T_$(4)_H_$(3))/
-       @$$(call E, compile_and_link: $$@)
-       $$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$<
-
-$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTPKG_$(4)):             \
-               $$(RUSTPKG_LIB) $$(RUSTPKG_INPUTS)                  \
-               $$(SREQ$(1)_T_$(4)_H_$(3))                      \
-               $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTC_$(4)) \
-               | $$(TLIB$(1)_T_$(4)_H_$(3))/
-       @$$(call E, compile_and_link: $$@)
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTPKG_GLOB_$(4)),$$(notdir $$@))
-       $$(STAGE$(1)_T_$(4)_H_$(3)) $$(WFLAGS_ST$(1)) --out-dir $$(@D) $$< && touch $$@
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTPKG_GLOB_$(4)),$$(notdir $$@))
-
-$$(TBIN$(1)_T_$(4)_H_$(3))/rustpkg$$(X_$(4)):                          \
-               $$(DRIVER_CRATE)                                                        \
-               $$(TSREQ$(1)_T_$(4)_H_$(3))                             \
-               $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTPKG_$(4))       \
-               | $$(TBIN$(1)_T_$(4)_H_$(3))/
-       @$$(call E, compile_and_link: $$@)
-       $$(STAGE$(1)_T_$(4)_H_$(3)) --cfg rustpkg -o $$@ $$<
-
-$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTDOC_$(4)):             \
-               $$(RUSTDOC_LIB) $$(RUSTDOC_INPUTS)                      \
-               $$(SREQ$(1)_T_$(4)_H_$(3))                      \
-               $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTC_$(4)) \
-               $$(SUNDOWN_LIB_$(4)) \
-               | $$(TLIB$(1)_T_$(4)_H_$(3))/
-       @$$(call E, compile_and_link: $$@)
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTDOC_GLOB_$(4)),$$(notdir $$@))
-       $$(STAGE$(1)_T_$(4)_H_$(3)) $$(WFLAGS_ST$(1)) \
-               -L $$(SUNDOWN_DIR_$(4)) --out-dir $$(@D) $$< && touch $$@
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTDOC_GLOB_$(4)),$$(notdir $$@))
-
-$$(TBIN$(1)_T_$(4)_H_$(3))/rustdoc$$(X_$(4)):                  \
-               $$(DRIVER_CRATE)                                                        \
-               $$(TSREQ$(1)_T_$(4)_H_$(3))                                             \
-               $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTDOC_$(4))                       \
-               | $$(TBIN$(1)_T_$(4)_H_$(3))/
-       @$$(call E, compile_and_link: $$@)
-       $$(STAGE$(1)_T_$(4)_H_$(3)) --cfg rustdoc -o $$@ $$<
-
-endef
-
-define TOOLS_STAGE_N_HOST
-
-$$(HBIN$(2)_H_$(4))/compiletest$$(X_$(4)):                             \
-               $$(TBIN$(1)_T_$(4)_H_$(3))/compiletest$$(X_$(4))        \
-               $$(HSREQ$(2)_H_$(4))                                    \
-               | $$(HBIN$(2)_H_$(4))/
-       @$$(call E, cp: $$@)
-       $$(Q)cp $$< $$@
-
-
-$$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTPKG_$(4)):                            \
-               $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTPKG_$(4))       \
-               $$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTC_$(4))                \
-               $$(HSREQ$(2)_H_$(4))                                    \
-               | $$(HLIB$(2)_H_$(4))/
-       @$$(call E, cp: $$@)
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTPKG_GLOB_$(4)),$$(notdir $$@))
-       $$(Q)cp $$< $$@
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTPKG_GLOB_$(4)),$$(notdir $$@))
-       $$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTPKG_GLOB_$(4)) \
-               $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTPKG_DSYM_GLOB_$(4))) \
-               $$(HLIB$(2)_H_$(4))
-
-$$(HBIN$(2)_H_$(4))/rustpkg$$(X_$(4)):                         \
-               $$(TBIN$(1)_T_$(4)_H_$(3))/rustpkg$$(X_$(4))    \
-               $$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTPKG_$(4))      \
-               $$(HSREQ$(2)_H_$(4))                            \
-               | $$(HBIN$(2)_H_$(4))/
-       @$$(call E, cp: $$@)
-       $$(Q)cp $$< $$@
-
-$$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTDOC_$(4)):                                    \
-               $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTDOC_$(4))       \
-               $$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTC_$(4))                        \
-               $$(HSREQ$(2)_H_$(4)) \
-               | $$(HLIB$(2)_H_$(4))/
-       @$$(call E, cp: $$@)
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTDOC_GLOB_$(4)),$$(notdir $$@))
-       $$(Q)cp $$< $$@
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTDOC_GLOB_$(4)),$$(notdir $$@))
-       $$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTDOC_GLOB_$(4)) \
-               $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTDOC_DSYM_GLOB_$(4))) \
-               $$(HLIB$(2)_H_$(4))
-
-$$(HBIN$(2)_H_$(4))/rustdoc$$(X_$(4)):                         \
-               $$(TBIN$(1)_T_$(4)_H_$(3))/rustdoc$$(X_$(4))    \
-               $$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTDOC_$(4))      \
-               $$(HSREQ$(2)_H_$(4))                            \
-               | $$(HBIN$(2)_H_$(4))/
-       @$$(call E, cp: $$@)
-       $$(Q)cp $$< $$@
-
-endef
-
-$(foreach host,$(CFG_HOST),                            \
-$(foreach target,$(CFG_TARGET),                                \
- $(eval $(call TOOLS_STAGE_N_TARGET,0,1,$(host),$(target)))    \
- $(eval $(call TOOLS_STAGE_N_TARGET,1,2,$(host),$(target)))    \
- $(eval $(call TOOLS_STAGE_N_TARGET,2,3,$(host),$(target)))    \
- $(eval $(call TOOLS_STAGE_N_TARGET,3,bogus,$(host),$(target)))))
-
-$(foreach host,$(CFG_HOST),                            \
- $(eval $(call TOOLS_STAGE_N_HOST,0,1,$(host),$(host)))        \
- $(eval $(call TOOLS_STAGE_N_HOST,1,2,$(host),$(host)))        \
- $(eval $(call TOOLS_STAGE_N_HOST,2,3,$(host),$(host))))
index 1d8e5a707edebbc7e6f57dc575565551bf291a88..c57d2492d459c9e8edaab12349e655818e0e8238 100644 (file)
@@ -317,10 +317,10 @@ fn run_debuginfo_test(config: &config, props: &TestProps, testfile: &Path) {
             loop {
                 //waiting 1 second for gdbserver start
                 timer::sleep(1000);
-                let result = do task::try {
+                let result = task::try(proc() {
                     tcp::TcpStream::connect(
                         SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 5039 });
-                };
+                });
                 if result.is_err() {
                     continue;
                 }
@@ -700,7 +700,7 @@ fn compose_and_run_compiler(
         let abs_ab = config.aux_base.join(rel_ab.as_slice());
         let aux_props = load_props(&abs_ab);
         let aux_args =
-            make_compile_args(config, &aux_props, ~[~"--lib"] + extra_link_args,
+            make_compile_args(config, &aux_props, ~[~"--dylib"] + extra_link_args,
                               |a,b| make_lib_name(a, b, testfile), &abs_ab);
         let auxres = compose_and_run(config, &abs_ab, aux_args, ~[],
                                      config.compile_lib_path, None);
index de777c997299d1d8b82efba5d91d573a9ed5655a..dbff82d2b6bbb626b97052bc6e811571ce09ff09 100755 (executable)
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 # xfail-license
 
+import glob
 import sys
 
 if __name__ == '__main__':
@@ -24,7 +25,8 @@ if __name__ == '__main__':
     def count(t):
         return sum(map(lambda (f, s): len(s.get(t, [])), summaries))
     logfiles = sys.argv[1:]
-    map(summarise, logfiles)
+    for files in map(glob.glob, logfiles):
+        map(summarise, files)
     ok = count('ok')
     failed = count('failed')
     ignored = count('ignored')
index ab2556f24c6d3d66e71dedfd320ae247d9be4c6a..bbc57b7eb73d86c34c832d65a3affcc9efd38e6c 100644 (file)
 # xfail-license
+# -*- coding: utf-8 -*-
+"""
+Script for extracting compilable fragments from markdown documentation. See
+prep.js for a description of the format recognized by this tool. Expects
+a directory fragments/ to exist under the current directory, and writes the
+fragments in there as individual .rs files.
+"""
+from __future__ import print_function
+from codecs import open
+from collections import deque
+from itertools import imap
+import os
+import re
+import sys
 
-# Script for extracting compilable fragments from markdown
-# documentation. See prep.js for a description of the format
-# recognized by this tool. Expects a directory fragments/ to exist
-# under the current directory, and writes the fragments in there as
-# individual .rs files.
-
-import sys, re
-
-if len(sys.argv) < 3:
-    print("Please provide an input filename")
-    sys.exit(1)
-
-filename = sys.argv[1]
-dest = sys.argv[2]
-f = open(filename)
-lines = f.readlines()
-f.close()
-
-cur = 0
-line = ""
-chapter = ""
-chapter_n = 0
-
-while cur < len(lines):
-    line = lines[cur]
-    cur += 1
-    chap = re.match("# (.*)", line)
-    if chap:
-        chapter = re.sub(r"\W", "_", chap.group(1)).lower()
-        chapter_n = 1
-    elif re.match("~~~", line):
-        # Parse the tags that open a code block in the pandoc format:
-        # ~~~ {.tag1 .tag2}
-        tags = re.findall("\.([\w-]*)", line)
-        block = ""
-        ignore = "notrust" in tags or "ignore" in tags
-        # Some tags used by the language ref that indicate not rust
-        ignore |= "ebnf" in tags
-        ignore |= "abnf" in tags
-        ignore |= "keyword" in tags
-        ignore |= "field" in tags
-        ignore |= "precedence" in tags
-        xfail = "xfail-test" in tags
-        while cur < len(lines):
-            line = lines[cur]
-            cur += 1
-            if re.match("~~~", line):
-                break
-            else:
-                # Lines beginning with '# ' are turned into valid code
-                line = re.sub("^# ", "", line)
-                # Allow ellipses in code snippets
-                line = re.sub("\.\.\.", "", line)
-                block += line
-        if not ignore:
-            if not re.search(r"\bfn main\b", block):
-                block = "fn main() {\n" + block + "\n}\n"
-            if not re.search(r"\bextern mod extra\b", block):
-                block = "extern mod extra;\n" + block
-            block = """#[ deny(warnings) ];
-#[ allow(unused_variable) ];\n
-#[ allow(dead_assignment) ];\n
-#[ allow(unused_mut) ];\n
-#[ allow(attribute_usage) ];\n
-#[ allow(dead_code) ];\n
-#[ feature(macro_rules, globs, struct_variant, managed_boxes) ];\n
-""" + block
-            if xfail:
-                block = "// xfail-test\n" + block
-            filename = (dest + "/" + str(chapter)
-                        + "_" + str(chapter_n) + ".rs")
-            chapter_n += 1
-            f = open(filename, 'w')
-            f.write(block)
-            f.close()
+# regexes
+CHAPTER_NAME_REGEX = re.compile(r'# (.*)')
+CODE_BLOCK_DELIM_REGEX = re.compile(r'~~~')
+COMMENT_REGEX = re.compile(r'^# ')
+COMPILER_DIRECTIVE_REGEX = re.compile(r'\#\[(.*)\];')
+ELLIPSES_REGEX = re.compile(r'\.\.\.')
+EXTERN_MOD_REGEX = re.compile(r'\bextern mod extra\b')
+MAIN_FUNCTION_REGEX = re.compile(r'\bfn main\b')
+TAGS_REGEX = re.compile(r'\.([\w-]*)')
+
+# tags to ignore
+IGNORE_TAGS = \
+        frozenset(["abnf", "ebnf", "field", "keyword", "notrust", "precedence"])
+
+# header for code snippet files
+OUTPUT_BLOCK_HEADER = '\n'.join((
+    "#[ deny(warnings) ];",
+    "#[ allow(unused_variable) ];",
+    "#[ allow(dead_assignment) ];",
+    "#[ allow(unused_mut) ];",
+    "#[ allow(attribute_usage) ];",
+    "#[ allow(dead_code) ];",
+    "#[ feature(macro_rules, globs, struct_variant, managed_boxes) ];\n",))
+
+
+def add_extern_mod(block):
+    if not has_extern_mod(block):
+        # add `extern mod extra;` after compiler directives
+        directives = []
+        while len(block) and is_compiler_directive(block[0]):
+            directives.append(block.popleft())
+
+        block.appendleft("\nextern mod extra;\n\n")
+        block.extendleft(reversed(directives))
+
+    return block
+
+
+def add_main_function(block):
+    if not has_main_function(block):
+        prepend_spaces = lambda x: '    ' + x
+        block = deque(imap(prepend_spaces, block))
+        block.appendleft("\nfn main() {\n")
+        block.append("\n}\n")
+    return block
+
+
+def extract_code_fragments(dest_dir, lines):
+    """
+    Extracts all the code fragments from a file that do not have ignored tags
+    writing them to the following file:
+
+        [dest dir]/[chapter name]_[chapter_index].rs
+    """
+    chapter_name = None
+    chapter_index = 0
+
+    for line in lines:
+        if is_chapter_title(line):
+            chapter_name = get_chapter_name(line)
+            chapter_index = 1
+            continue
+
+        if not is_code_block_delim(line):
+            continue
+
+        assert chapter_name, "Chapter name missing for code block."
+        tags = get_tags(line)
+        block = get_code_block(lines)
+
+        if tags & IGNORE_TAGS:
+            continue
+
+        block = add_extern_mod(add_main_function(block))
+        block.appendleft(OUTPUT_BLOCK_HEADER)
+
+        if "ignore" in tags:
+            block.appendleft("//xfail-test\n")
+        elif "should_fail" in tags:
+            block.appendleft("//should-fail\n")
+
+        output_filename = os.path.join(
+                dest_dir,
+                chapter_name + '_' + str(chapter_index) + '.rs')
+
+        write_file(output_filename, block)
+        chapter_index += 1
+
+
+def has_extern_mod(block):
+    """Checks if a code block has the line `extern mod extra`."""
+    find_extern_mod = lambda x: re.search(EXTERN_MOD_REGEX, x)
+    return any(imap(find_extern_mod, block))
+
+
+def has_main_function(block):
+    """Checks if a code block has a main function."""
+    find_main_fn = lambda x: re.search(MAIN_FUNCTION_REGEX, x)
+    return any(imap(find_main_fn, block))
+
+
+def is_chapter_title(line):
+    return re.match(CHAPTER_NAME_REGEX, line)
+
+
+def is_code_block_delim(line):
+    return re.match(CODE_BLOCK_DELIM_REGEX, line)
+
+
+def is_compiler_directive(line):
+    return re.match(COMPILER_DIRECTIVE_REGEX, line)
+
+
+def get_chapter_name(line):
+    """Get the chapter name from a `# Containers` line."""
+    return re.sub(
+            r'\W',
+            '_',
+            re.match(CHAPTER_NAME_REGEX, line).group(1)).lower()
+
+
+def get_code_block(lines):
+    """
+    Get a code block surrounded by ~~~, for example:
+
+        1: ~~~ { .tag }
+        2: let u: ~[u32] = ~[0, 1, 2];
+        3: let v: &[u32] = &[0, 1, 2, 3];
+        4: let w: [u32, .. 5] = [0, 1, 2, 3, 4];
+        5:
+        6: println!("u: {}, v: {}, w: {}", u.len(), v.len(), w.len());
+        7: ~~~
+
+    Returns lines 2-6. Assumes line 1 has been consumed by the caller.
+    """
+    strip_comments = lambda x: re.sub(COMMENT_REGEX, '', x)
+    strip_ellipses = lambda x: re.sub(ELLIPSES_REGEX, '', x)
+
+    result = deque()
+
+    for line in lines:
+        if is_code_block_delim(line):
+            break
+        result.append(strip_comments(strip_ellipses(line)))
+    return result
+
+
+def get_lines(filename):
+    with open(filename) as f:
+        for line in f:
+            yield line
+
+
+def get_tags(line):
+    """
+    Retrieves all tags from the line format:
+        ~~~ { .tag1 .tag2 .tag3 }
+    """
+    return set(re.findall(TAGS_REGEX, line))
+
+
+def write_file(filename, lines):
+    with open(filename, 'w', encoding='utf-8') as f:
+        for line in lines:
+            f.write(unicode(line, encoding='utf-8', errors='replace'))
+
+
+def main(argv=None):
+    if not argv:
+        argv = sys.argv
+
+    if len(sys.argv) < 2:
+        sys.stderr.write("Please provide an input filename.")
+        sys.exit(1)
+    elif len(sys.argv) < 3:
+        sys.stderr.write("Please provide a destination directory.")
+        sys.exit(1)
+
+    input_file = sys.argv[1]
+    dest_dir = sys.argv[2]
+
+    if not os.path.exists(input_file):
+        sys.stderr.write("Input file does not exist.")
+        sys.exit(1)
+
+    if not os.path.exists(dest_dir):
+        os.mkdir(dest_dir)
+
+    extract_code_fragments(dest_dir, get_lines(input_file))
+
+
+if __name__ == "__main__":
+    sys.exit(main())
index 43700c02b75f43ddcf96d32c7801c8d8b6343315..8864012970845060af95113f4cb93ca8a49b96ad 100644 (file)
@@ -87,7 +87,6 @@
                <keyword>f64</keyword>
                <keyword>char</keyword>
                <keyword>str</keyword>
-               <keyword>Either</keyword>
                <keyword>Option</keyword>
                <keyword>Result</keyword>
     </context>
                <keyword>false</keyword>
                <keyword>Some</keyword>
                <keyword>None</keyword>
-               <keyword>Left</keyword>
-               <keyword>Right</keyword>
                <keyword>Ok</keyword>
                <keyword>Err</keyword>
                <keyword>Success</keyword>
diff --git a/src/etc/generate-deriving-span-tests.py b/src/etc/generate-deriving-span-tests.py
new file mode 100755 (executable)
index 0000000..f00168a
--- /dev/null
@@ -0,0 +1,131 @@
+#!/usr/bin/env python
+# xfail-license
+# 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.
+
+"""
+This script creates a pile of compile-fail tests check that all the
+derivings have spans that point to the fields, rather than the
+#[deriving(...)] line.
+
+sample usage: src/etc/generate-deriving-span-tests.py
+"""
+
+import sys, os, datetime, stat
+
+TEST_DIR = os.path.abspath(
+    os.path.join(os.path.dirname(__file__), '../test/compile-fail'))
+
+YEAR = datetime.datetime.now().year
+
+TEMPLATE = """// Copyright {year} The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+{error_deriving}
+struct Error;
+{code}
+fn main() {{}}
+"""
+
+ENUM_STRING = """
+#[deriving({traits})]
+enum Enum {{
+   A(
+     Error {errors}
+     )
+}}
+"""
+ENUM_STRUCT_VARIANT_STRING = """
+#[deriving({traits})]
+enum Enum {{
+   A {{
+     x: Error {errors}
+   }}
+}}
+"""
+STRUCT_STRING = """
+#[deriving({traits})]
+struct Struct {{
+    x: Error {errors}
+}}
+"""
+STRUCT_TUPLE_STRING = """
+#[deriving({traits})]
+struct Struct(
+    Error {errors}
+);
+"""
+
+ENUM_TUPLE, ENUM_STRUCT, STRUCT_FIELDS, STRUCT_TUPLE = range(4)
+
+def create_test_case(type, trait, super_traits, number_of_errors):
+    string = [ENUM_STRING, ENUM_STRUCT_VARIANT_STRING, STRUCT_STRING, STRUCT_TUPLE_STRING][type]
+    all_traits = ','.join([trait] + super_traits)
+    super_traits = ','.join(super_traits)
+    error_deriving = '#[deriving(%s)]' % super_traits if super_traits else ''
+
+    errors = '\n'.join('//~%s ERROR' % ('^' * n) for n in range(error_count))
+    code = string.format(traits = all_traits, errors = errors)
+    return TEMPLATE.format(year = YEAR, error_deriving=error_deriving, code = code)
+
+def write_file(name, string):
+    test_file = os.path.join(TEST_DIR, 'deriving-span-%s.rs' % name)
+
+    # set write permission if file exists, so it can be changed
+    if os.path.exists(test_file):
+        os.chmod(test_file, stat.S_IWUSR)
+
+    with open(test_file, 'wt') as f:
+        f.write(string)
+
+    # mark file read-only
+    os.chmod(test_file, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH)
+
+
+
+ENUM = 1
+STRUCT = 2
+ALL = STRUCT | ENUM
+
+traits = {
+    'Zero': (STRUCT, [], 1),
+    'Default': (STRUCT, [], 1),
+    'FromPrimitive': (0, [], 0), # only works for C-like enums
+
+    'Decodable': (0, [], 0), # FIXME: quoting gives horrible spans
+    'Encodable': (0, [], 0), # FIXME: quoting gives horrible spans
+}
+
+for (trait, supers, errs) in [('Rand', [], 1),
+                              ('Clone', [], 1), ('DeepClone', ['Clone'], 1),
+                              ('Eq', [], 2), ('Ord', [], 8),
+                              ('TotalEq', [], 1), ('TotalOrd', ['TotalEq'], 1)]:
+    traits[trait] = (ALL, supers, errs)
+
+for (trait, (types, super_traits, error_count)) in traits.items():
+    mk = lambda ty: create_test_case(ty, trait, super_traits, error_count)
+    if types & ENUM:
+        write_file(trait + '-enum', mk(ENUM_TUPLE))
+        write_file(trait + '-enum-struct-variant', mk(ENUM_STRUCT))
+    if types & STRUCT:
+        write_file(trait + '-struct', mk(STRUCT_FIELDS))
+        write_file(trait + '-tuple-struct', mk(STRUCT_TUPLE))
index c1c5215ac0ff055205106cc1c69e63e58baff24b..c52473f5f07288713f5c8a8ecd18cc264470ae85 100644 (file)
@@ -86,7 +86,6 @@
                <item> float </item>
                <item> char </item>
                <item> str </item>
-               <item> Either </item>
                <item> Option </item>
                <item> Result </item>
                <item> Self </item>
                <item> false </item>
                <item> Some </item>
                <item> None </item>
-               <item> Left </item>
-               <item> Right </item>
                <item> Ok </item>
                <item> Err </item>
                <item> Success </item>
index 3364ddcb678072ca92d4a3dd1df0e135b6c8b808..8157ffba3efede0641d16ce5101669f9ced0c8d3 100644 (file)
@@ -45,9 +45,8 @@ try:
                                 openhook=fileinput.hook_encoded("utf-8")):
 
         if fileinput.filename().find("tidy.py") == -1:
-            if line.find("FIXME") != -1:
-                if re.search("FIXME.*#\d+", line) == None:
-                    report_err("FIXME without issue number")
+            if line.find("// XXX") != -1:
+                report_err("XXX is no longer necessary, use FIXME")
             if line.find("TODO") != -1:
                 report_err("TODO is deprecated; use FIXME")
             match = re.match(r'^.*//\s*(NOTE.*)$', line)
index 3b300b4cc2825b4fb7d870ea1f912f06ad244560..0d248354b737b47ac2416bbb2bc7ddbdfdb235db 100644 (file)
@@ -46,8 +46,6 @@ syn keyword   rustType        f64 i8 i16 i32 i64 str Self
 " to make it easy to update.
 
 " Core operators {{{3
-syn keyword   rustEnum        Either
-syn keyword   rustEnumVariant Left Right
 syn keyword   rustTrait       Sized
 syn keyword   rustTrait       Freeze Send
 syn keyword   rustTrait       Add Sub Mul Div Rem Neg Not
@@ -80,7 +78,6 @@ syn keyword rustTrait FromStr
 syn keyword rustTrait FromIterator Extendable
 syn keyword rustTrait Iterator DoubleEndedIterator RandomAccessIterator CloneableIterator
 syn keyword rustTrait OrdIterator MutableDoubleEndedIterator ExactSize
-syn keyword rustTrait Times
 
 syn keyword rustTrait Algebraic Trigonometric Exponential Hyperbolic
 syn keyword rustTrait Bitwise Bounded Integer Fractional Real RealExt
@@ -94,16 +91,16 @@ syn keyword rustTrait SendStr SendStrOwned SendStrStatic IntoSendStr
 syn keyword rustTrait Str StrVector StrSlice OwnedStr
 syn keyword rustTrait IterBytes
 syn keyword rustTrait ToStr IntoStr
-syn keyword rustTrait CopyableTuple ImmutableTuple
+syn keyword rustTrait CloneableTuple ImmutableTuple
 syn keyword rustTrait Tuple1 Tuple2 Tuple3 Tuple4
 syn keyword rustTrait Tuple5 Tuple6 Tuple7 Tuple8
 syn keyword rustTrait Tuple9 Tuple10 Tuple11 Tuple12
 syn keyword rustTrait ImmutableTuple1 ImmutableTuple2 ImmutableTuple3 ImmutableTuple4
 syn keyword rustTrait ImmutableTuple5 ImmutableTuple6 ImmutableTuple7 ImmutableTuple8
 syn keyword rustTrait ImmutableTuple9 ImmutableTuple10 ImmutableTuple11 ImmutableTuple12
-syn keyword rustTrait ImmutableEqVector ImmutableTotalOrdVector ImmutableCopyableVector
-syn keyword rustTrait OwnedVector OwnedCopyableVector OwnedEqVector MutableVector
-syn keyword rustTrait Vector VectorVector CopyableVector ImmutableVector
+syn keyword rustTrait ImmutableEqVector ImmutableTotalOrdVector ImmutableCloneableVector
+syn keyword rustTrait OwnedVector OwnedCloneableVector OwnedEqVector MutableVector
+syn keyword rustTrait Vector VectorVector CloneableVector ImmutableVector
 
 "syn keyword rustFunction stream
 syn keyword rustTrait Port Chan GenericChan GenericSmartChan GenericPort Peekable
@@ -113,7 +110,6 @@ syn keyword   rustSelf        self
 syn keyword   rustBoolean     true false
 
 syn keyword   rustConstant    Some None       " option
-syn keyword   rustConstant    Left Right      " either
 syn keyword   rustConstant    Ok Err          " result
 syn keyword   rustConstant    Less Equal Greater " Ordering
 
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs
new file mode 100644 (file)
index 0000000..27dad55
--- /dev/null
@@ -0,0 +1,609 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+//
+//! The arena, a fast but limited type of allocator.
+//!
+//! Arenas are a type of allocator that destroy the objects within, all at
+//! once, once the arena itself is destroyed. They do not support deallocation
+//! of individual objects while the arena itself is still alive. The benefit
+//! of an arena is very fast allocation; just a pointer bump.
+
+#[crate_id = "arena#0.10-pre"];
+#[crate_type = "rlib"];
+#[crate_type = "dylib"];
+#[license = "MIT/ASL2"];
+#[allow(missing_doc)];
+#[feature(managed_boxes)];
+
+extern mod extra;
+
+use extra::list::{List, Cons, Nil};
+use extra::list;
+
+use std::at_vec;
+use std::cast::{transmute, transmute_mut, transmute_mut_region};
+use std::cast;
+use std::cell::{Cell, RefCell};
+use std::num;
+use std::ptr;
+use std::mem;
+use std::rt::global_heap;
+use std::uint;
+use std::unstable::intrinsics::{TyDesc, get_tydesc};
+use std::unstable::intrinsics;
+use std::util;
+
+// The way arena uses arrays is really deeply awful. The arrays are
+// allocated, and have capacities reserved, but the fill for the array
+// will always stay at 0.
+#[deriving(Clone)]
+struct Chunk {
+    data: RefCell<@[u8]>,
+    fill: Cell<uint>,
+    is_pod: Cell<bool>,
+}
+
+// Arenas are used to quickly allocate objects that share a
+// lifetime. The arena uses ~[u8] vectors as a backing store to
+// allocate objects from. For each allocated object, the arena stores
+// a pointer to the type descriptor followed by the
+// object. (Potentially with alignment padding after each of them.)
+// 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 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 the most recent
+// object. To solve this without requiring extra space, we use the low
+// order bit of the tydesc pointer to encode whether the object it
+// describes has been fully initialized.
+
+// As an optimization, objects with destructors are stored in
+// different chunks than objects without destructors. This reduces
+// overhead when initializing plain-old-data and means we don't need
+// to waste time running the destructors of POD.
+#[no_freeze]
+pub struct Arena {
+    // The head is separated out from the list as a unbenchmarked
+    // microoptimization, to avoid needing to case on the list to
+    // access the head.
+    priv head: Chunk,
+    priv pod_head: Chunk,
+    priv chunks: RefCell<@List<Chunk>>,
+}
+
+impl Arena {
+    pub fn new() -> Arena {
+        Arena::new_with_size(32u)
+    }
+
+    pub fn new_with_size(initial_size: uint) -> Arena {
+        Arena {
+            head: chunk(initial_size, false),
+            pod_head: chunk(initial_size, true),
+            chunks: RefCell::new(@Nil),
+        }
+    }
+}
+
+fn chunk(size: uint, is_pod: bool) -> Chunk {
+    let mut v: @[u8] = @[];
+    unsafe { at_vec::raw::reserve(&mut v, size); }
+    Chunk {
+        data: RefCell::new(unsafe { cast::transmute(v) }),
+        fill: Cell::new(0u),
+        is_pod: Cell::new(is_pod),
+    }
+}
+
+#[unsafe_destructor]
+impl Drop for Arena {
+    fn drop(&mut self) {
+        unsafe {
+            destroy_chunk(&self.head);
+
+            list::each(self.chunks.get(), |chunk| {
+                if !chunk.is_pod.get() {
+                    destroy_chunk(chunk);
+                }
+                true
+            });
+        }
+    }
+}
+
+#[inline]
+fn round_up(base: uint, align: uint) -> uint {
+    (base.checked_add(&(align - 1))).unwrap() & !(&(align - 1))
+}
+
+// Walk down a chunk, running the destructors for any objects stored
+// in it.
+unsafe fn destroy_chunk(chunk: &Chunk) {
+    let mut idx = 0;
+    let buf = {
+        let data = chunk.data.borrow();
+        data.get().as_ptr()
+    };
+    let fill = chunk.fill.get();
+
+    while idx < fill {
+        let tydesc_data: *uint = transmute(ptr::offset(buf, idx as int));
+        let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data);
+        let (size, align) = ((*tydesc).size, (*tydesc).align);
+
+        let after_tydesc = idx + mem::size_of::<*TyDesc>();
+
+        let start = round_up(after_tydesc, align);
+
+        //debug!("freeing object: idx = {}, size = {}, align = {}, done = {}",
+        //       start, size, align, is_done);
+        if is_done {
+            ((*tydesc).drop_glue)(ptr::offset(buf, start as int) as *i8);
+        }
+
+        // Find where the next tydesc lives
+        idx = round_up(start + size, mem::pref_align_of::<*TyDesc>());
+    }
+}
+
+// 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
+// during an initializer.
+#[inline]
+unsafe fn bitpack_tydesc_ptr(p: *TyDesc, is_done: bool) -> uint {
+    let p_bits: uint = transmute(p);
+    p_bits | (is_done as uint)
+}
+#[inline]
+unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TyDesc, bool) {
+    (transmute(p & !1), p & 1 == 1)
+}
+
+impl Arena {
+    // Functions for the POD part of the arena
+    fn alloc_pod_grow(&mut self, n_bytes: uint, align: uint) -> *u8 {
+        // Allocate a new chunk.
+        let chunk_size = at_vec::capacity(self.pod_head.data.get());
+        let new_min_chunk_size = num::max(n_bytes, chunk_size);
+        self.chunks.set(@Cons(self.pod_head.clone(), self.chunks.get()));
+        self.pod_head =
+            chunk(uint::next_power_of_two(new_min_chunk_size + 1u), true);
+
+        return self.alloc_pod_inner(n_bytes, align);
+    }
+
+    #[inline]
+    fn alloc_pod_inner(&mut self, n_bytes: uint, align: uint) -> *u8 {
+        unsafe {
+            let this = transmute_mut_region(self);
+            let start = round_up(this.pod_head.fill.get(), align);
+            let end = start + n_bytes;
+            if end > at_vec::capacity(this.pod_head.data.get()) {
+                return this.alloc_pod_grow(n_bytes, align);
+            }
+            this.pod_head.fill.set(end);
+
+            //debug!("idx = {}, size = {}, align = {}, fill = {}",
+            //       start, n_bytes, align, head.fill.get());
+
+            ptr::offset(this.pod_head.data.get().as_ptr(), start as int)
+        }
+    }
+
+    #[inline]
+    fn alloc_pod<'a, T>(&'a mut self, op: || -> T) -> &'a T {
+        unsafe {
+            let tydesc = get_tydesc::<T>();
+            let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align);
+            let ptr: *mut T = transmute(ptr);
+            intrinsics::move_val_init(&mut (*ptr), op());
+            return transmute(ptr);
+        }
+    }
+
+    // Functions for the non-POD part of the arena
+    fn alloc_nonpod_grow(&mut self, n_bytes: uint, align: uint)
+                         -> (*u8, *u8) {
+        // Allocate a new chunk.
+        let chunk_size = at_vec::capacity(self.head.data.get());
+        let new_min_chunk_size = num::max(n_bytes, chunk_size);
+        self.chunks.set(@Cons(self.head.clone(), self.chunks.get()));
+        self.head =
+            chunk(uint::next_power_of_two(new_min_chunk_size + 1u), false);
+
+        return self.alloc_nonpod_inner(n_bytes, align);
+    }
+
+    #[inline]
+    fn alloc_nonpod_inner(&mut self, n_bytes: uint, align: uint)
+                          -> (*u8, *u8) {
+        unsafe {
+            let start;
+            let end;
+            let tydesc_start;
+            let after_tydesc;
+
+            {
+                let head = transmute_mut_region(&mut self.head);
+
+                tydesc_start = head.fill.get();
+                after_tydesc = head.fill.get() + mem::size_of::<*TyDesc>();
+                start = round_up(after_tydesc, align);
+                end = start + n_bytes;
+            }
+
+            if end > at_vec::capacity(self.head.data.get()) {
+                return self.alloc_nonpod_grow(n_bytes, align);
+            }
+
+            let head = transmute_mut_region(&mut self.head);
+            head.fill.set(round_up(end, mem::pref_align_of::<*TyDesc>()));
+
+            //debug!("idx = {}, size = {}, align = {}, fill = {}",
+            //       start, n_bytes, align, head.fill);
+
+            let buf = self.head.data.get().as_ptr();
+            return (ptr::offset(buf, tydesc_start as int), ptr::offset(buf, start as int));
+        }
+    }
+
+    #[inline]
+    fn alloc_nonpod<'a, T>(&'a mut self, op: || -> T) -> &'a T {
+        unsafe {
+            let tydesc = get_tydesc::<T>();
+            let (ty_ptr, ptr) =
+                self.alloc_nonpod_inner((*tydesc).size, (*tydesc).align);
+            let ty_ptr: *mut uint = transmute(ty_ptr);
+            let ptr: *mut T = transmute(ptr);
+            // Write in our tydesc along with a bit indicating that it
+            // has *not* been initialized yet.
+            *ty_ptr = transmute(tydesc);
+            // Actually initialize it
+            intrinsics::move_val_init(&mut(*ptr), op());
+            // Now that we are done, update the tydesc to indicate that
+            // the object is there.
+            *ty_ptr = bitpack_tydesc_ptr(tydesc, true);
+
+            return transmute(ptr);
+        }
+    }
+
+    // The external interface
+    #[inline]
+    pub fn alloc<'a, T>(&'a self, op: || -> T) -> &'a T {
+        unsafe {
+            // FIXME: Borrow check
+            let this = transmute_mut(self);
+            if intrinsics::needs_drop::<T>() {
+                this.alloc_nonpod(op)
+            } else {
+                this.alloc_pod(op)
+            }
+        }
+    }
+}
+
+#[test]
+fn test_arena_destructors() {
+    let arena = Arena::new();
+    for i in range(0u, 10) {
+        // Arena allocate something with drop glue to make sure it
+        // doesn't leak.
+        arena.alloc(|| @i);
+        // Allocate something with funny size and alignment, to keep
+        // things interesting.
+        arena.alloc(|| [0u8, 1u8, 2u8]);
+    }
+}
+
+#[test]
+#[should_fail]
+fn test_arena_destructors_fail() {
+    let arena = Arena::new();
+    // Put some stuff in the arena.
+    for i in range(0u, 10) {
+        // Arena allocate something with drop glue to make sure it
+        // doesn't leak.
+        arena.alloc(|| { @i });
+        // Allocate something with funny size and alignment, to keep
+        // things interesting.
+        arena.alloc(|| { [0u8, 1u8, 2u8] });
+    }
+    // Now, fail while allocating
+    arena.alloc::<@int>(|| {
+        // Now fail.
+        fail!();
+    });
+}
+
+/// An arena that can hold objects of only one type.
+///
+/// Safety note: Modifying objects in the arena that have already had their
+/// `drop` destructors run can cause leaks, because the destructor will not
+/// run again for these objects.
+pub struct TypedArena<T> {
+    /// A pointer to the next object to be allocated.
+    priv ptr: *T,
+
+    /// A pointer to the end of the allocated area. When this pointer is
+    /// reached, a new chunk is allocated.
+    priv end: *T,
+
+    /// The type descriptor of the objects in the arena. This should not be
+    /// necessary, but is until generic destructors are supported.
+    priv tydesc: *TyDesc,
+
+    /// A pointer to the first arena segment.
+    priv first: Option<~TypedArenaChunk>,
+}
+
+struct TypedArenaChunk {
+    /// Pointer to the next arena segment.
+    next: Option<~TypedArenaChunk>,
+
+    /// The number of elements that this chunk can hold.
+    capacity: uint,
+
+    // Objects follow here, suitably aligned.
+}
+
+impl TypedArenaChunk {
+    #[inline]
+    fn new<T>(next: Option<~TypedArenaChunk>, capacity: uint)
+           -> ~TypedArenaChunk {
+        let mut size = mem::size_of::<TypedArenaChunk>();
+        size = round_up(size, mem::min_align_of::<T>());
+        let elem_size = mem::size_of::<T>();
+        let elems_size = elem_size.checked_mul(&capacity).unwrap();
+        size = size.checked_add(&elems_size).unwrap();
+
+        let mut chunk = unsafe {
+            let chunk = global_heap::exchange_malloc(size);
+            let mut chunk: ~TypedArenaChunk = cast::transmute(chunk);
+            intrinsics::move_val_init(&mut chunk.next, next);
+            chunk
+        };
+
+        chunk.capacity = capacity;
+        chunk
+    }
+
+    /// Destroys this arena chunk. If the type descriptor is supplied, the
+    /// drop glue is called; otherwise, drop glue is not called.
+    #[inline]
+    unsafe fn destroy(&mut self, len: uint, opt_tydesc: Option<*TyDesc>) {
+        // Destroy all the allocated objects.
+        match opt_tydesc {
+            None => {}
+            Some(tydesc) => {
+                let mut start = self.start(tydesc);
+                for _ in range(0, len) {
+                    ((*tydesc).drop_glue)(start as *i8);
+                    start = start.offset((*tydesc).size as int)
+                }
+            }
+        }
+
+        // Destroy the next chunk.
+        let next_opt = util::replace(&mut self.next, None);
+        match next_opt {
+            None => {}
+            Some(mut next) => {
+                // We assume that the next chunk is completely filled.
+                next.destroy(next.capacity, opt_tydesc)
+            }
+        }
+    }
+
+    // Returns a pointer to the first allocated object.
+    #[inline]
+    fn start(&self, tydesc: *TyDesc) -> *u8 {
+        let this: *TypedArenaChunk = self;
+        unsafe {
+            cast::transmute(round_up(this.offset(1) as uint, (*tydesc).align))
+        }
+    }
+
+    // Returns a pointer to the end of the allocated space.
+    #[inline]
+    fn end(&self, tydesc: *TyDesc) -> *u8 {
+        unsafe {
+            let size = (*tydesc).size.checked_mul(&self.capacity).unwrap();
+            self.start(tydesc).offset(size as int)
+        }
+    }
+}
+
+impl<T> TypedArena<T> {
+    /// Creates a new arena with preallocated space for 8 objects.
+    #[inline]
+    pub fn new() -> TypedArena<T> {
+        TypedArena::with_capacity(8)
+    }
+
+    /// Creates a new arena with preallocated space for the given number of
+    /// objects.
+    #[inline]
+    pub fn with_capacity(capacity: uint) -> TypedArena<T> {
+        let chunk = TypedArenaChunk::new::<T>(None, capacity);
+        let tydesc = unsafe {
+            intrinsics::get_tydesc::<T>()
+        };
+        TypedArena {
+            ptr: chunk.start(tydesc) as *T,
+            end: chunk.end(tydesc) as *T,
+            tydesc: tydesc,
+            first: Some(chunk),
+        }
+    }
+
+    /// Allocates an object into this arena.
+    #[inline]
+    pub fn alloc<'a>(&'a self, object: T) -> &'a T {
+        unsafe {
+            let this = cast::transmute_mut(self);
+            if this.ptr == this.end {
+                this.grow()
+            }
+
+            let ptr: &'a mut T = cast::transmute(this.ptr);
+            intrinsics::move_val_init(ptr, object);
+            this.ptr = this.ptr.offset(1);
+            let ptr: &'a T = ptr;
+            ptr
+        }
+    }
+
+    /// Grows the arena.
+    #[inline(never)]
+    fn grow(&mut self) {
+        let chunk = self.first.take_unwrap();
+        let new_capacity = chunk.capacity.checked_mul(&2).unwrap();
+        let chunk = TypedArenaChunk::new::<T>(Some(chunk), new_capacity);
+        self.ptr = chunk.start(self.tydesc) as *T;
+        self.end = chunk.end(self.tydesc) as *T;
+        self.first = Some(chunk)
+    }
+}
+
+#[unsafe_destructor]
+impl<T> Drop for TypedArena<T> {
+    fn drop(&mut self) {
+        // Determine how much was filled.
+        let start = self.first.get_ref().start(self.tydesc) as uint;
+        let end = self.ptr as uint;
+        let diff = (end - start) / mem::size_of::<T>();
+
+        // Pass that to the `destroy` method.
+        unsafe {
+            let opt_tydesc = if intrinsics::needs_drop::<T>() {
+                Some(self.tydesc)
+            } else {
+                None
+            };
+            self.first.get_mut_ref().destroy(diff, opt_tydesc)
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::{Arena, TypedArena};
+    use extra::test::BenchHarness;
+
+    struct Point {
+        x: int,
+        y: int,
+        z: int,
+    }
+
+    #[test]
+    pub fn test_pod() {
+        let arena = TypedArena::new();
+        for _ in range(0, 100000) {
+            arena.alloc(Point {
+                x: 1,
+                y: 2,
+                z: 3,
+            });
+        }
+    }
+
+    #[bench]
+    pub fn bench_pod(bh: &mut BenchHarness) {
+        let arena = TypedArena::new();
+        bh.iter(|| {
+            arena.alloc(Point {
+                x: 1,
+                y: 2,
+                z: 3,
+            });
+        })
+    }
+
+    #[bench]
+    pub fn bench_pod_nonarena(bh: &mut BenchHarness) {
+        bh.iter(|| {
+            let _ = ~Point {
+                x: 1,
+                y: 2,
+                z: 3,
+            };
+        })
+    }
+
+    #[bench]
+    pub fn bench_pod_old_arena(bh: &mut BenchHarness) {
+        let arena = Arena::new();
+        bh.iter(|| {
+            arena.alloc(|| {
+                Point {
+                    x: 1,
+                    y: 2,
+                    z: 3,
+                }
+            });
+        })
+    }
+
+    struct Nonpod {
+        string: ~str,
+        array: ~[int],
+    }
+
+    #[test]
+    pub fn test_nonpod() {
+        let arena = TypedArena::new();
+        for _ in range(0, 100000) {
+            arena.alloc(Nonpod {
+                string: ~"hello world",
+                array: ~[ 1, 2, 3, 4, 5 ],
+            });
+        }
+    }
+
+    #[bench]
+    pub fn bench_nonpod(bh: &mut BenchHarness) {
+        let arena = TypedArena::new();
+        bh.iter(|| {
+            arena.alloc(Nonpod {
+                string: ~"hello world",
+                array: ~[ 1, 2, 3, 4, 5 ],
+            });
+        })
+    }
+
+    #[bench]
+    pub fn bench_nonpod_nonarena(bh: &mut BenchHarness) {
+        bh.iter(|| {
+            let _ = ~Nonpod {
+                string: ~"hello world",
+                array: ~[ 1, 2, 3, 4, 5 ],
+            };
+        })
+    }
+
+    #[bench]
+    pub fn bench_nonpod_old_arena(bh: &mut BenchHarness) {
+        let arena = Arena::new();
+        bh.iter(|| {
+            let _ = arena.alloc(|| Nonpod {
+                string: ~"hello world",
+                array: ~[ 1, 2, 3, 4, 5 ],
+            });
+        })
+    }
+}
+
+
index a411c4e9185b10d489161a6f124627870b5cd95b..1c6c3adf97228da68781e58a220603eee06e2567 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
  *       let (port, chan) = Chan::new();
  *       chan.send(shared_numbers.clone());
  *
- *       do spawn {
+ *       spawn(proc() {
  *           let shared_numbers = port.recv();
  *           let local_numbers = shared_numbers.get();
  *
  *           // Work with the local numbers
- *       }
+ *       });
  *   }
  * ```
  */
@@ -47,7 +47,6 @@
 use std::cast;
 use std::sync::arc::UnsafeArc;
 use std::task;
-use std::borrow;
 
 /// As sync::condvar, a mechanism for unlock-and-descheduling and signaling.
 pub struct Condvar<'a> {
@@ -148,7 +147,7 @@ fn clone(&self) -> Arc<T> {
  ****************************************************************************/
 
 #[doc(hidden)]
-struct MutexArcInner<T> { priv lock: Mutex, priv failed: bool, priv data: T }
+struct MutexArcInner<T> { lock: Mutex, failed: bool, data: T }
 
 /// An Arc with mutable data protected by a blocking mutex.
 #[no_freeze]
@@ -312,7 +311,7 @@ fn new<'a>(flag: &'a mut bool) -> PoisonOnFail {
  ****************************************************************************/
 
 #[doc(hidden)]
-struct RWArcInner<T> { priv lock: RWLock, priv failed: bool, priv data: T }
+struct RWArcInner<T> { lock: RWLock, failed: bool, data: T }
 /**
  * A dual-mode Arc protected by a reader-writer lock. The data can be accessed
  * mutably or immutably, and immutably-accessing tasks may run concurrently.
@@ -465,7 +464,7 @@ pub fn downgrade<'a>(&self, token: RWWriteMode<'a, T>)
             // of this cast is removing the mutability.)
             let new_data = data;
             // Downgrade ensured the token belonged to us. Just a sanity check.
-            assert!(borrow::ref_eq(&(*state).data, new_data));
+            assert!((&(*state).data as *T as uint) == (new_data as *mut T as uint));
             // Produce new token
             RWReadMode {
                 data: new_data,
@@ -567,12 +566,12 @@ fn manually_share_arc() {
 
         let (p, c) = Chan::new();
 
-        do task::spawn {
+        task::spawn(proc() {
             let arc_v: Arc<~[int]> = p.recv();
 
             let v = arc_v.get().clone();
             assert_eq!(v[3], 4);
-        };
+        });
 
         c.send(arc_v.clone());
 
@@ -587,14 +586,14 @@ fn test_mutex_arc_condvar() {
         let arc = ~MutexArc::new(false);
         let arc2 = ~arc.clone();
         let (p,c) = Chan::new();
-        do task::spawn {
+        task::spawn(proc() {
             // wait until parent gets in
             p.recv();
             arc2.access_cond(|state, cond| {
                 *state = true;
                 cond.signal();
             })
-        }
+        });
 
         arc.access_cond(|state, cond| {
             c.send(());
@@ -611,14 +610,14 @@ fn test_arc_condvar_poison() {
         let arc2 = ~arc.clone();
         let (p, c) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             let _ = p.recv();
             arc2.access_cond(|one, cond| {
                 cond.signal();
                 // Parent should fail when it wakes up.
                 assert_eq!(*one, 0);
             })
-        }
+        });
 
         arc.access_cond(|one, cond| {
             c.send(());
@@ -632,11 +631,11 @@ fn test_arc_condvar_poison() {
     fn test_mutex_arc_poison() {
         let arc = ~MutexArc::new(1);
         let arc2 = ~arc.clone();
-        do task::try || {
+        task::try(proc() {
             arc2.access(|one| {
                 assert_eq!(*one, 2);
             })
-        };
+        });
         arc.access(|one| {
             assert_eq!(*one, 1);
         })
@@ -649,13 +648,13 @@ fn test_unsafe_mutex_arc_nested() {
             // to underlaying data.
             let arc = ~MutexArc::new(1);
             let arc2 = ~MutexArc::new(*arc);
-            do task::spawn || {
+            task::spawn(proc() {
                 (*arc2).unsafe_access(|mutex| {
                     (*mutex).access(|one| {
                         assert!(*one == 1);
                     })
                 })
-            };
+            });
         }
     }
 
@@ -682,11 +681,11 @@ fn drop(&mut self) {
     fn test_rw_arc_poison_wr() {
         let arc = RWArc::new(1);
         let arc2 = arc.clone();
-        do task::try {
+        task::try(proc() {
             arc2.write(|one| {
                 assert_eq!(*one, 2);
             })
-        };
+        });
         arc.read(|one| {
             assert_eq!(*one, 1);
         })
@@ -696,11 +695,11 @@ fn test_rw_arc_poison_wr() {
     fn test_rw_arc_poison_ww() {
         let arc = RWArc::new(1);
         let arc2 = arc.clone();
-        do task::try {
+        task::try(proc() {
             arc2.write(|one| {
                 assert_eq!(*one, 2);
             })
-        };
+        });
         arc.write(|one| {
             assert_eq!(*one, 1);
         })
@@ -709,13 +708,13 @@ fn test_rw_arc_poison_ww() {
     fn test_rw_arc_poison_dw() {
         let arc = RWArc::new(1);
         let arc2 = arc.clone();
-        do task::try {
+        task::try(proc() {
             arc2.write_downgrade(|mut write_mode| {
                 write_mode.write(|one| {
                     assert_eq!(*one, 2);
                 })
             })
-        };
+        });
         arc.write(|one| {
             assert_eq!(*one, 1);
         })
@@ -724,11 +723,11 @@ fn test_rw_arc_poison_dw() {
     fn test_rw_arc_no_poison_rr() {
         let arc = RWArc::new(1);
         let arc2 = arc.clone();
-        do task::try {
+        task::try(proc() {
             arc2.read(|one| {
                 assert_eq!(*one, 2);
             })
-        };
+        });
         arc.read(|one| {
             assert_eq!(*one, 1);
         })
@@ -737,11 +736,11 @@ fn test_rw_arc_no_poison_rr() {
     fn test_rw_arc_no_poison_rw() {
         let arc = RWArc::new(1);
         let arc2 = arc.clone();
-        do task::try {
+        task::try(proc() {
             arc2.read(|one| {
                 assert_eq!(*one, 2);
             })
-        };
+        });
         arc.write(|one| {
             assert_eq!(*one, 1);
         })
@@ -750,14 +749,14 @@ fn test_rw_arc_no_poison_rw() {
     fn test_rw_arc_no_poison_dr() {
         let arc = RWArc::new(1);
         let arc2 = arc.clone();
-        do task::try {
+        task::try(proc() {
             arc2.write_downgrade(|write_mode| {
                 let read_mode = arc2.downgrade(write_mode);
                 read_mode.read(|one| {
                     assert_eq!(*one, 2);
                 })
             })
-        };
+        });
         arc.write(|one| {
             assert_eq!(*one, 1);
         })
@@ -768,30 +767,30 @@ fn test_rw_arc() {
         let arc2 = arc.clone();
         let (p, c) = Chan::new();
 
-        do task::spawn {
+        task::spawn(proc() {
             arc2.write(|num| {
-                10.times(|| {
+                for _ in range(0, 10) {
                     let tmp = *num;
                     *num = -1;
                     task::deschedule();
                     *num = tmp + 1;
-                });
+                }
                 c.send(());
             })
-        }
+        });
 
         // Readers try to catch the writer in the act
         let mut children = ~[];
-        5.times(|| {
+        for _ in range(0, 5) {
             let arc3 = arc.clone();
             let mut builder = task::task();
             children.push(builder.future_result());
-            do builder.spawn {
+            builder.spawn(proc() {
                 arc3.read(|num| {
                     assert!(*num >= 0);
                 })
-            }
-        });
+            });
+        }
 
         // Wait for children to pass their asserts
         for r in children.mut_iter() {
@@ -836,23 +835,23 @@ fn test_rw_downgrade() {
 
         // Reader tasks
         let mut reader_convos = ~[];
-        10.times(|| {
+        for _ in range(0, 10) {
             let ((rp1, rc1), (rp2, rc2)) = (Chan::new(), Chan::new());
             reader_convos.push((rc1, rp2));
             let arcn = arc.clone();
-            do task::spawn {
+            task::spawn(proc() {
                 rp1.recv(); // wait for downgrader to give go-ahead
                 arcn.read(|state| {
                     assert_eq!(*state, 31337);
                     rc2.send(());
                 })
-            }
-        });
+            });
+        }
 
         // Writer task
         let arc2 = arc.clone();
         let ((wp1, wc1), (wp2, wc2)) = (Chan::new(), Chan::new());
-        do task::spawn || {
+        task::spawn(proc() {
             wp1.recv();
             arc2.write_cond(|state, cond| {
                 assert_eq!(*state, 0);
@@ -867,7 +866,7 @@ fn test_rw_downgrade() {
                 *state = 42;
             });
             wc2.send(());
-        }
+        });
 
         // Downgrader (us)
         arc.write_downgrade(|mut write_mode| {
@@ -912,7 +911,7 @@ fn test_rw_write_cond_downgrade_read_race_helper() {
 
         // writer task
         let xw = x.clone();
-        do task::spawn {
+        task::spawn(proc() {
             xw.write_cond(|state, c| {
                 wc.send(()); // tell downgrader it's ok to go
                 c.wait();
@@ -921,7 +920,7 @@ fn test_rw_write_cond_downgrade_read_race_helper() {
                 // trying to receive the "reader cloud lock hand-off".
                 *state = false;
             })
-        }
+        });
 
         wp.recv(); // wait for writer to get in
 
@@ -934,17 +933,17 @@ fn test_rw_write_cond_downgrade_read_race_helper() {
             // make a reader task to trigger the "reader cloud lock" handoff
             let xr = x.clone();
             let (rp, rc) = Chan::new();
-            do task::spawn {
+            task::spawn(proc() {
                 rc.send(());
                 xr.read(|_state| { })
-            }
+            });
             rp.recv(); // wait for reader task to exist
 
             let read_mode = x.downgrade(write_mode);
             read_mode.read(|state| {
                 // if writer mistakenly got in, make sure it mutates state
                 // before we assert on it
-                5.times(|| task::deschedule());
+                for _ in range(0, 5) { task::deschedule(); }
                 // make sure writer didn't get in.
                 assert!(*state);
             })
@@ -956,6 +955,6 @@ fn test_rw_write_cond_downgrade_read_race() {
         // helped to expose the race nearly 100% of the time... but adding
         // deschedules in the intuitively-right locations made it even less likely,
         // and I wasn't sure why :( . This is a mediocre "next best" option.
-        8.times(|| test_rw_write_cond_downgrade_read_race_helper());
+        for _ in range(0, 8) { test_rw_write_cond_downgrade_read_race_helper(); }
     }
 }
diff --git a/src/libextra/arena.rs b/src/libextra/arena.rs
deleted file mode 100644 (file)
index d004086..0000000
+++ /dev/null
@@ -1,602 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-//
-//! The arena, a fast but limited type of allocator.
-//!
-//! Arenas are a type of allocator that destroy the objects within, all at
-//! once, once the arena itself is destroyed. They do not support deallocation
-//! of individual objects while the arena itself is still alive. The benefit
-//! of an arena is very fast allocation; just a pointer bump.
-
-#[allow(missing_doc)];
-
-use list::{List, Cons, Nil};
-use list;
-
-use std::at_vec;
-use std::cast::{transmute, transmute_mut, transmute_mut_region};
-use std::cast;
-use std::cell::{Cell, RefCell};
-use std::num;
-use std::ptr;
-use std::mem;
-use std::rt::global_heap;
-use std::uint;
-use std::unstable::intrinsics::{TyDesc, get_tydesc};
-use std::unstable::intrinsics;
-use std::util;
-
-// The way arena uses arrays is really deeply awful. The arrays are
-// allocated, and have capacities reserved, but the fill for the array
-// will always stay at 0.
-#[deriving(Clone)]
-struct Chunk {
-    data: RefCell<@[u8]>,
-    fill: Cell<uint>,
-    is_pod: Cell<bool>,
-}
-
-// Arenas are used to quickly allocate objects that share a
-// lifetime. The arena uses ~[u8] vectors as a backing store to
-// allocate objects from. For each allocated object, the arena stores
-// a pointer to the type descriptor followed by the
-// object. (Potentially with alignment padding after each of them.)
-// 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 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 the most recent
-// object. To solve this without requiring extra space, we use the low
-// order bit of the tydesc pointer to encode whether the object it
-// describes has been fully initialized.
-
-// As an optimization, objects with destructors are stored in
-// different chunks than objects without destructors. This reduces
-// overhead when initializing plain-old-data and means we don't need
-// to waste time running the destructors of POD.
-#[no_freeze]
-pub struct Arena {
-    // The head is separated out from the list as a unbenchmarked
-    // microoptimization, to avoid needing to case on the list to
-    // access the head.
-    priv head: Chunk,
-    priv pod_head: Chunk,
-    priv chunks: RefCell<@List<Chunk>>,
-}
-
-impl Arena {
-    pub fn new() -> Arena {
-        Arena::new_with_size(32u)
-    }
-
-    pub fn new_with_size(initial_size: uint) -> Arena {
-        Arena {
-            head: chunk(initial_size, false),
-            pod_head: chunk(initial_size, true),
-            chunks: RefCell::new(@Nil),
-        }
-    }
-}
-
-fn chunk(size: uint, is_pod: bool) -> Chunk {
-    let mut v: @[u8] = @[];
-    unsafe { at_vec::raw::reserve(&mut v, size); }
-    Chunk {
-        data: RefCell::new(unsafe { cast::transmute(v) }),
-        fill: Cell::new(0u),
-        is_pod: Cell::new(is_pod),
-    }
-}
-
-#[unsafe_destructor]
-impl Drop for Arena {
-    fn drop(&mut self) {
-        unsafe {
-            destroy_chunk(&self.head);
-
-            list::each(self.chunks.get(), |chunk| {
-                if !chunk.is_pod.get() {
-                    destroy_chunk(chunk);
-                }
-                true
-            });
-        }
-    }
-}
-
-#[inline]
-fn round_up(base: uint, align: uint) -> uint {
-    (base.checked_add(&(align - 1))).unwrap() & !(&(align - 1))
-}
-
-// Walk down a chunk, running the destructors for any objects stored
-// in it.
-unsafe fn destroy_chunk(chunk: &Chunk) {
-    let mut idx = 0;
-    let buf = {
-        let data = chunk.data.borrow();
-        data.get().as_ptr()
-    };
-    let fill = chunk.fill.get();
-
-    while idx < fill {
-        let tydesc_data: *uint = transmute(ptr::offset(buf, idx as int));
-        let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data);
-        let (size, align) = ((*tydesc).size, (*tydesc).align);
-
-        let after_tydesc = idx + mem::size_of::<*TyDesc>();
-
-        let start = round_up(after_tydesc, align);
-
-        //debug!("freeing object: idx = {}, size = {}, align = {}, done = {}",
-        //       start, size, align, is_done);
-        if is_done {
-            ((*tydesc).drop_glue)(ptr::offset(buf, start as int) as *i8);
-        }
-
-        // Find where the next tydesc lives
-        idx = round_up(start + size, mem::pref_align_of::<*TyDesc>());
-    }
-}
-
-// 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
-// during an initializer.
-#[inline]
-unsafe fn bitpack_tydesc_ptr(p: *TyDesc, is_done: bool) -> uint {
-    let p_bits: uint = transmute(p);
-    p_bits | (is_done as uint)
-}
-#[inline]
-unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TyDesc, bool) {
-    (transmute(p & !1), p & 1 == 1)
-}
-
-impl Arena {
-    // Functions for the POD part of the arena
-    fn alloc_pod_grow(&mut self, n_bytes: uint, align: uint) -> *u8 {
-        // Allocate a new chunk.
-        let chunk_size = at_vec::capacity(self.pod_head.data.get());
-        let new_min_chunk_size = num::max(n_bytes, chunk_size);
-        self.chunks.set(@Cons(self.pod_head.clone(), self.chunks.get()));
-        self.pod_head =
-            chunk(uint::next_power_of_two(new_min_chunk_size + 1u), true);
-
-        return self.alloc_pod_inner(n_bytes, align);
-    }
-
-    #[inline]
-    fn alloc_pod_inner(&mut self, n_bytes: uint, align: uint) -> *u8 {
-        unsafe {
-            let this = transmute_mut_region(self);
-            let start = round_up(this.pod_head.fill.get(), align);
-            let end = start + n_bytes;
-            if end > at_vec::capacity(this.pod_head.data.get()) {
-                return this.alloc_pod_grow(n_bytes, align);
-            }
-            this.pod_head.fill.set(end);
-
-            //debug!("idx = {}, size = {}, align = {}, fill = {}",
-            //       start, n_bytes, align, head.fill.get());
-
-            ptr::offset(this.pod_head.data.get().as_ptr(), start as int)
-        }
-    }
-
-    #[inline]
-    fn alloc_pod<'a, T>(&'a mut self, op: || -> T) -> &'a T {
-        unsafe {
-            let tydesc = get_tydesc::<T>();
-            let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align);
-            let ptr: *mut T = transmute(ptr);
-            intrinsics::move_val_init(&mut (*ptr), op());
-            return transmute(ptr);
-        }
-    }
-
-    // Functions for the non-POD part of the arena
-    fn alloc_nonpod_grow(&mut self, n_bytes: uint, align: uint)
-                         -> (*u8, *u8) {
-        // Allocate a new chunk.
-        let chunk_size = at_vec::capacity(self.head.data.get());
-        let new_min_chunk_size = num::max(n_bytes, chunk_size);
-        self.chunks.set(@Cons(self.head.clone(), self.chunks.get()));
-        self.head =
-            chunk(uint::next_power_of_two(new_min_chunk_size + 1u), false);
-
-        return self.alloc_nonpod_inner(n_bytes, align);
-    }
-
-    #[inline]
-    fn alloc_nonpod_inner(&mut self, n_bytes: uint, align: uint)
-                          -> (*u8, *u8) {
-        unsafe {
-            let start;
-            let end;
-            let tydesc_start;
-            let after_tydesc;
-
-            {
-                let head = transmute_mut_region(&mut self.head);
-
-                tydesc_start = head.fill.get();
-                after_tydesc = head.fill.get() + mem::size_of::<*TyDesc>();
-                start = round_up(after_tydesc, align);
-                end = start + n_bytes;
-            }
-
-            if end > at_vec::capacity(self.head.data.get()) {
-                return self.alloc_nonpod_grow(n_bytes, align);
-            }
-
-            let head = transmute_mut_region(&mut self.head);
-            head.fill.set(round_up(end, mem::pref_align_of::<*TyDesc>()));
-
-            //debug!("idx = {}, size = {}, align = {}, fill = {}",
-            //       start, n_bytes, align, head.fill);
-
-            let buf = self.head.data.get().as_ptr();
-            return (ptr::offset(buf, tydesc_start as int), ptr::offset(buf, start as int));
-        }
-    }
-
-    #[inline]
-    fn alloc_nonpod<'a, T>(&'a mut self, op: || -> T) -> &'a T {
-        unsafe {
-            let tydesc = get_tydesc::<T>();
-            let (ty_ptr, ptr) =
-                self.alloc_nonpod_inner((*tydesc).size, (*tydesc).align);
-            let ty_ptr: *mut uint = transmute(ty_ptr);
-            let ptr: *mut T = transmute(ptr);
-            // Write in our tydesc along with a bit indicating that it
-            // has *not* been initialized yet.
-            *ty_ptr = transmute(tydesc);
-            // Actually initialize it
-            intrinsics::move_val_init(&mut(*ptr), op());
-            // Now that we are done, update the tydesc to indicate that
-            // the object is there.
-            *ty_ptr = bitpack_tydesc_ptr(tydesc, true);
-
-            return transmute(ptr);
-        }
-    }
-
-    // The external interface
-    #[inline]
-    pub fn alloc<'a, T>(&'a self, op: || -> T) -> &'a T {
-        unsafe {
-            // XXX: Borrow check
-            let this = transmute_mut(self);
-            if intrinsics::needs_drop::<T>() {
-                this.alloc_nonpod(op)
-            } else {
-                this.alloc_pod(op)
-            }
-        }
-    }
-}
-
-#[test]
-fn test_arena_destructors() {
-    let arena = Arena::new();
-    for i in range(0u, 10) {
-        // Arena allocate something with drop glue to make sure it
-        // doesn't leak.
-        arena.alloc(|| @i);
-        // Allocate something with funny size and alignment, to keep
-        // things interesting.
-        arena.alloc(|| [0u8, 1u8, 2u8]);
-    }
-}
-
-#[test]
-#[should_fail]
-fn test_arena_destructors_fail() {
-    let arena = Arena::new();
-    // Put some stuff in the arena.
-    for i in range(0u, 10) {
-        // Arena allocate something with drop glue to make sure it
-        // doesn't leak.
-        arena.alloc(|| { @i });
-        // Allocate something with funny size and alignment, to keep
-        // things interesting.
-        arena.alloc(|| { [0u8, 1u8, 2u8] });
-    }
-    // Now, fail while allocating
-    arena.alloc::<@int>(|| {
-        // Now fail.
-        fail!();
-    });
-}
-
-/// An arena that can hold objects of only one type.
-///
-/// Safety note: Modifying objects in the arena that have already had their
-/// `drop` destructors run can cause leaks, because the destructor will not
-/// run again for these objects.
-pub struct TypedArena<T> {
-    /// A pointer to the next object to be allocated.
-    priv ptr: *T,
-
-    /// A pointer to the end of the allocated area. When this pointer is
-    /// reached, a new chunk is allocated.
-    priv end: *T,
-
-    /// The type descriptor of the objects in the arena. This should not be
-    /// necessary, but is until generic destructors are supported.
-    priv tydesc: *TyDesc,
-
-    /// A pointer to the first arena segment.
-    priv first: Option<~TypedArenaChunk>,
-}
-
-struct TypedArenaChunk {
-    /// Pointer to the next arena segment.
-    next: Option<~TypedArenaChunk>,
-
-    /// The number of elements that this chunk can hold.
-    capacity: uint,
-
-    // Objects follow here, suitably aligned.
-}
-
-impl TypedArenaChunk {
-    #[inline]
-    fn new<T>(next: Option<~TypedArenaChunk>, capacity: uint)
-           -> ~TypedArenaChunk {
-        let mut size = mem::size_of::<TypedArenaChunk>();
-        size = round_up(size, mem::min_align_of::<T>());
-        let elem_size = mem::size_of::<T>();
-        let elems_size = elem_size.checked_mul(&capacity).unwrap();
-        size = size.checked_add(&elems_size).unwrap();
-
-        let mut chunk = unsafe {
-            let chunk = global_heap::exchange_malloc(size);
-            let mut chunk: ~TypedArenaChunk = cast::transmute(chunk);
-            intrinsics::move_val_init(&mut chunk.next, next);
-            chunk
-        };
-
-        chunk.capacity = capacity;
-        chunk
-    }
-
-    /// Destroys this arena chunk. If the type descriptor is supplied, the
-    /// drop glue is called; otherwise, drop glue is not called.
-    #[inline]
-    unsafe fn destroy(&mut self, len: uint, opt_tydesc: Option<*TyDesc>) {
-        // Destroy all the allocated objects.
-        match opt_tydesc {
-            None => {}
-            Some(tydesc) => {
-                let mut start = self.start(tydesc);
-                for _ in range(0, len) {
-                    ((*tydesc).drop_glue)(start as *i8);
-                    start = start.offset((*tydesc).size as int)
-                }
-            }
-        }
-
-        // Destroy the next chunk.
-        let next_opt = util::replace(&mut self.next, None);
-        match next_opt {
-            None => {}
-            Some(mut next) => {
-                // We assume that the next chunk is completely filled.
-                next.destroy(next.capacity, opt_tydesc)
-            }
-        }
-    }
-
-    // Returns a pointer to the first allocated object.
-    #[inline]
-    fn start(&self, tydesc: *TyDesc) -> *u8 {
-        let this: *TypedArenaChunk = self;
-        unsafe {
-            cast::transmute(round_up(this.offset(1) as uint, (*tydesc).align))
-        }
-    }
-
-    // Returns a pointer to the end of the allocated space.
-    #[inline]
-    fn end(&self, tydesc: *TyDesc) -> *u8 {
-        unsafe {
-            let size = (*tydesc).size.checked_mul(&self.capacity).unwrap();
-            self.start(tydesc).offset(size as int)
-        }
-    }
-}
-
-impl<T> TypedArena<T> {
-    /// Creates a new arena with preallocated space for 8 objects.
-    #[inline]
-    pub fn new() -> TypedArena<T> {
-        TypedArena::with_capacity(8)
-    }
-
-    /// Creates a new arena with preallocated space for the given number of
-    /// objects.
-    #[inline]
-    pub fn with_capacity(capacity: uint) -> TypedArena<T> {
-        let chunk = TypedArenaChunk::new::<T>(None, capacity);
-        let tydesc = unsafe {
-            intrinsics::get_tydesc::<T>()
-        };
-        TypedArena {
-            ptr: chunk.start(tydesc) as *T,
-            end: chunk.end(tydesc) as *T,
-            tydesc: tydesc,
-            first: Some(chunk),
-        }
-    }
-
-    /// Allocates an object into this arena.
-    #[inline]
-    pub fn alloc<'a>(&'a self, object: T) -> &'a T {
-        unsafe {
-            let this = cast::transmute_mut(self);
-            if this.ptr == this.end {
-                this.grow()
-            }
-
-            let ptr: &'a mut T = cast::transmute(this.ptr);
-            intrinsics::move_val_init(ptr, object);
-            this.ptr = this.ptr.offset(1);
-            let ptr: &'a T = ptr;
-            ptr
-        }
-    }
-
-    /// Grows the arena.
-    #[inline(never)]
-    fn grow(&mut self) {
-        let chunk = self.first.take_unwrap();
-        let new_capacity = chunk.capacity.checked_mul(&2).unwrap();
-        let chunk = TypedArenaChunk::new::<T>(Some(chunk), new_capacity);
-        self.ptr = chunk.start(self.tydesc) as *T;
-        self.end = chunk.end(self.tydesc) as *T;
-        self.first = Some(chunk)
-    }
-}
-
-#[unsafe_destructor]
-impl<T> Drop for TypedArena<T> {
-    fn drop(&mut self) {
-        // Determine how much was filled.
-        let start = self.first.get_ref().start(self.tydesc) as uint;
-        let end = self.ptr as uint;
-        let diff = (end - start) / mem::size_of::<T>();
-
-        // Pass that to the `destroy` method.
-        unsafe {
-            let opt_tydesc = if intrinsics::needs_drop::<T>() {
-                Some(self.tydesc)
-            } else {
-                None
-            };
-            self.first.get_mut_ref().destroy(diff, opt_tydesc)
-        }
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use super::{Arena, TypedArena};
-    use test::BenchHarness;
-
-    struct Point {
-        x: int,
-        y: int,
-        z: int,
-    }
-
-    #[test]
-    pub fn test_pod() {
-        let arena = TypedArena::new();
-        for _ in range(0, 1000000) {
-            arena.alloc(Point {
-                x: 1,
-                y: 2,
-                z: 3,
-            });
-        }
-    }
-
-    #[bench]
-    pub fn bench_pod(bh: &mut BenchHarness) {
-        let arena = TypedArena::new();
-        bh.iter(|| {
-            arena.alloc(Point {
-                x: 1,
-                y: 2,
-                z: 3,
-            });
-        })
-    }
-
-    #[bench]
-    pub fn bench_pod_nonarena(bh: &mut BenchHarness) {
-        bh.iter(|| {
-            let _ = ~Point {
-                x: 1,
-                y: 2,
-                z: 3,
-            };
-        })
-    }
-
-    #[bench]
-    pub fn bench_pod_old_arena(bh: &mut BenchHarness) {
-        let arena = Arena::new();
-        bh.iter(|| {
-            arena.alloc(|| {
-                Point {
-                    x: 1,
-                    y: 2,
-                    z: 3,
-                }
-            });
-        })
-    }
-
-    struct Nonpod {
-        string: ~str,
-        array: ~[int],
-    }
-
-    #[test]
-    pub fn test_nonpod() {
-        let arena = TypedArena::new();
-        for _ in range(0, 1000000) {
-            arena.alloc(Nonpod {
-                string: ~"hello world",
-                array: ~[ 1, 2, 3, 4, 5 ],
-            });
-        }
-    }
-
-    #[bench]
-    pub fn bench_nonpod(bh: &mut BenchHarness) {
-        let arena = TypedArena::new();
-        bh.iter(|| {
-            arena.alloc(Nonpod {
-                string: ~"hello world",
-                array: ~[ 1, 2, 3, 4, 5 ],
-            });
-        })
-    }
-
-    #[bench]
-    pub fn bench_nonpod_nonarena(bh: &mut BenchHarness) {
-        bh.iter(|| {
-            let _ = ~Nonpod {
-                string: ~"hello world",
-                array: ~[ 1, 2, 3, 4, 5 ],
-            };
-        })
-    }
-
-    #[bench]
-    pub fn bench_nonpod_old_arena(bh: &mut BenchHarness) {
-        let arena = Arena::new();
-        bh.iter(|| {
-            let _ = arena.alloc(|| Nonpod {
-                string: ~"hello world",
-                array: ~[ 1, 2, 3, 4, 5 ],
-            });
-        })
-    }
-}
-
-
index 1fcce6d01eea1d1eb78d356e190d32927ffc8edf..738afcd5c5f9310c9cba780e4b51c0ee3121ec32 100644 (file)
@@ -336,11 +336,11 @@ fn test_base64_random() {
         use std::rand::{task_rng, random, Rng};
         use std::vec;
 
-        1000.times(|| {
+        for _ in range(0, 1000) {
             let times = task_rng().gen_range(1u, 100);
             let v = vec::from_fn(times, |_| random::<u8>());
             assert_eq!(v.to_base64(STANDARD).from_base64().unwrap(), v);
-        })
+        }
     }
 
     #[bench]
index 9df75ff044ab300fd74bd6f780ef3fb49c9b0986..7211907f483212578caaa14049ff69b10e7ffb48 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -121,8 +121,8 @@ struct BigBitv {
  */
 #[inline]
 fn big_mask(nbits: uint, elem: uint) -> uint {
-    let rmd = nbits % uint::bits;
-    let nelems = nbits/uint::bits + if rmd == 0 {0} else {1};
+    let rmd = nbits % uint::BITS;
+    let nelems = nbits/uint::BITS + if rmd == 0 {0} else {1};
 
     if elem < nelems - 1 || rmd == 0 {
         !0
@@ -192,16 +192,16 @@ pub fn difference(&mut self, b: &BigBitv, nbits: uint) -> bool {
 
     #[inline]
     pub fn get(&self, i: uint) -> bool {
-        let w = i / uint::bits;
-        let b = i % uint::bits;
+        let w = i / uint::BITS;
+        let b = i % uint::BITS;
         let x = 1 & self.storage[w] >> b;
         x == 1
     }
 
     #[inline]
     pub fn set(&mut self, i: uint, x: bool) {
-        let w = i / uint::bits;
-        let b = i % uint::bits;
+        let w = i / uint::BITS;
+        let b = i % uint::BITS;
         let flag = 1 << b;
         self.storage[w] = if x { self.storage[w] | flag }
                           else { self.storage[w] & !flag };
@@ -269,20 +269,20 @@ fn do_op(&mut self, op: Op, other: &Bitv) -> bool {
 
 impl Bitv {
     pub fn new(nbits: uint, init: bool) -> Bitv {
-        let rep = if nbits < uint::bits {
+        let rep = if nbits < uint::BITS {
             Small(SmallBitv::new(if init {(1<<nbits)-1} else {0}))
-        } else if nbits == uint::bits {
+        } else if nbits == uint::BITS {
             Small(SmallBitv::new(if init {!0} else {0}))
         } else {
-            let exact = nbits % uint::bits == 0;
-            let nelems = nbits/uint::bits + if exact {0} else {1};
+            let exact = nbits % uint::BITS == 0;
+            let nelems = nbits/uint::BITS + if exact {0} else {1};
             let s =
                 if init {
                     if exact {
                         vec::from_elem(nelems, !0u)
                     } else {
                         let mut v = vec::from_elem(nelems-1, !0u);
-                        v.push((1<<nbits % uint::bits)-1);
+                        v.push((1<<nbits % uint::BITS)-1);
                         v
                     }
                 } else { vec::from_elem(nelems, 0u)};
@@ -576,7 +576,7 @@ fn iterate_bits(base: uint, bits: uint, f: |uint| -> bool) -> bool {
     if bits == 0 {
         return true;
     }
-    for i in range(0u, uint::bits) {
+    for i in range(0u, uint::BITS) {
         if bits & (1 << i) != 0 {
             if !f(base + i) {
                 return false;
@@ -680,7 +680,7 @@ pub fn from_bitv(bitv: Bitv) -> BitvSet {
 
     /// Returns the capacity in bits for this bit vector. Inserting any
     /// element less than this amount will not trigger a resizing.
-    pub fn capacity(&self) -> uint { self.bitv.storage.len() * uint::bits }
+    pub fn capacity(&self) -> uint { self.bitv.storage.len() * uint::BITS }
 
     /// Consumes this set to return the underlying bit vector
     pub fn unwrap(self) -> Bitv {
@@ -693,7 +693,7 @@ pub fn unwrap(self) -> Bitv {
     fn other_op(&mut self, other: &BitvSet, f: |uint, uint| -> uint) {
         fn nbits(mut w: uint) -> uint {
             let mut bits = 0;
-            for _ in range(0u, uint::bits) {
+            for _ in range(0u, uint::BITS) {
                 if w == 0 {
                     break;
                 }
@@ -703,7 +703,7 @@ fn nbits(mut w: uint) -> uint {
             return bits;
         }
         if self.capacity() < other.capacity() {
-            self.bitv.storage.grow(other.capacity() / uint::bits, &0);
+            self.bitv.storage.grow(other.capacity() / uint::BITS, &0);
         }
         for (i, &w) in other.bitv.storage.iter().enumerate() {
             let old = self.bitv.storage[i];
@@ -808,7 +808,7 @@ fn clear(&mut self) {
 
 impl Set<uint> for BitvSet {
     fn contains(&self, value: &uint) -> bool {
-        *value < self.bitv.storage.len() * uint::bits && self.bitv.get(*value)
+        *value < self.bitv.storage.len() * uint::BITS && self.bitv.get(*value)
     }
 
     fn is_disjoint(&self, other: &BitvSet) -> bool {
@@ -846,7 +846,7 @@ fn insert(&mut self, value: uint) -> bool {
         }
         let nbits = self.capacity();
         if value >= nbits {
-            let newsize = num::max(value, nbits * 2) / uint::bits + 1;
+            let newsize = num::max(value, nbits * 2) / uint::BITS + 1;
             assert!(newsize > self.bitv.storage.len());
             self.bitv.storage.grow(newsize, &0);
         }
@@ -884,7 +884,7 @@ fn commons<'a>(&'a self, other: &'a BitvSet)
         let min = num::min(self.bitv.storage.len(), other.bitv.storage.len());
         self.bitv.storage.slice(0, min).iter().enumerate()
             .zip(Repeat::new(&other.bitv.storage))
-            .map(|((i, &w), o_store)| (i * uint::bits, w, o_store[i]))
+            .map(|((i, &w), o_store)| (i * uint::BITS, w, o_store[i]))
     }
 
     /// Visits each word in `self` or `other` that extends beyond the other. This
@@ -903,11 +903,11 @@ fn outliers<'a>(&'a self, other: &'a BitvSet)
         if olen < slen {
             self.bitv.storage.slice_from(olen).iter().enumerate()
                 .zip(Repeat::new(olen))
-                .map(|((i, &w), min)| (true, (i + min) * uint::bits, w))
+                .map(|((i, &w), min)| (true, (i + min) * uint::BITS, w))
         } else {
             other.bitv.storage.slice_from(slen).iter().enumerate()
                 .zip(Repeat::new(slen))
-                .map(|((i, &w), min)| (false, (i + min) * uint::bits, w))
+                .map(|((i, &w), min)| (false, (i + min) * uint::BITS, w))
         }
     }
 }
@@ -1529,7 +1529,7 @@ fn test_bitv_remove() {
 
         assert!(a.insert(1000));
         assert!(a.remove(&1000));
-        assert_eq!(a.capacity(), uint::bits);
+        assert_eq!(a.capacity(), uint::BITS);
     }
 
     #[test]
@@ -1561,16 +1561,16 @@ fn bench_uint_small(b: &mut BenchHarness) {
         let mut r = rng();
         let mut bitv = 0 as uint;
         b.iter(|| {
-            bitv |= (1 << ((r.next_u32() as uint) % uint::bits));
+            bitv |= (1 << ((r.next_u32() as uint) % uint::BITS));
         })
     }
 
     #[bench]
     fn bench_small_bitv_small(b: &mut BenchHarness) {
         let mut r = rng();
-        let mut bitv = SmallBitv::new(uint::bits);
+        let mut bitv = SmallBitv::new(uint::BITS);
         b.iter(|| {
-            bitv.set((r.next_u32() as uint) % uint::bits, true);
+            bitv.set((r.next_u32() as uint) % uint::BITS, true);
         })
     }
 
@@ -1579,7 +1579,7 @@ fn bench_big_bitv_small(b: &mut BenchHarness) {
         let mut r = rng();
         let mut bitv = BigBitv::new(~[0]);
         b.iter(|| {
-            bitv.set((r.next_u32() as uint) % uint::bits, true);
+            bitv.set((r.next_u32() as uint) % uint::BITS, true);
         })
     }
 
@@ -1587,7 +1587,7 @@ fn bench_big_bitv_small(b: &mut BenchHarness) {
     fn bench_big_bitv_big(b: &mut BenchHarness) {
         let mut r = rng();
         let mut storage = ~[];
-        storage.grow(BENCH_BITS / uint::bits, &0u);
+        storage.grow(BENCH_BITS / uint::BITS, &0u);
         let mut bitv = BigBitv::new(storage);
         b.iter(|| {
             bitv.set((r.next_u32() as uint) % BENCH_BITS, true);
@@ -1606,9 +1606,9 @@ fn bench_bitv_big(b: &mut BenchHarness) {
     #[bench]
     fn bench_bitv_small(b: &mut BenchHarness) {
         let mut r = rng();
-        let mut bitv = Bitv::new(uint::bits, false);
+        let mut bitv = Bitv::new(uint::BITS, false);
         b.iter(|| {
-            bitv.set((r.next_u32() as uint) % uint::bits, true);
+            bitv.set((r.next_u32() as uint) % uint::BITS, true);
         })
     }
 
@@ -1617,7 +1617,7 @@ fn bench_bitv_set_small(b: &mut BenchHarness) {
         let mut r = rng();
         let mut bitv = BitvSet::new();
         b.iter(|| {
-            bitv.insert((r.next_u32() as uint) % uint::bits);
+            bitv.insert((r.next_u32() as uint) % uint::BITS);
         })
     }
 
@@ -1641,7 +1641,7 @@ fn bench_bitv_big_union(b: &mut BenchHarness) {
 
     #[bench]
     fn bench_btv_small_iter(b: &mut BenchHarness) {
-        let bitv = Bitv::new(uint::bits, false);
+        let bitv = Bitv::new(uint::BITS, false);
         b.iter(|| {
             let mut _sum = 0;
             for pres in bitv.iter() {
index ee6d7e8f16fd62609a44230ff74b7be2bfd811ee..791673d75bb37009a2838b2325788bfd856cb20b 100644 (file)
 ///number of elements that a given node can contain.
 #[allow(missing_doc)]
 pub struct BTree<K, V> {
-    root: Node<K, V>,
-    len: uint,
-    lower_bound: uint,
-    upper_bound: uint
+    priv root: Node<K, V>,
+    priv len: uint,
+    priv lower_bound: uint,
+    priv upper_bound: uint
 }
 
 //We would probably want to remove the dependence on the Clone trait in the future.
@@ -47,9 +47,9 @@ pub fn new(k: K, v: V, lb: uint) -> BTree<K, V> {
 
     ///Helper function for clone: returns new BTree with supplied root node,
     ///length, and lower bound.  For use when the length is known already.
-    pub fn new_with_node_len(n: Node<K, V>,
-                             length: uint,
-                             lb: uint) -> BTree<K, V> {
+    fn new_with_node_len(n: Node<K, V>,
+                         length: uint,
+                         lb: uint) -> BTree<K, V> {
         BTree {
             root: n,
             len: length,
@@ -590,4 +590,3 @@ fn btree_tostr_test() {
     }
 
 }
-
index 748289080532cd5e343afbade51403824db5f997..c7d550762540a6ca9128bdf74d37df2da56c248f 100644 (file)
@@ -115,9 +115,9 @@ pub fn DuplexStream1() {
     pub fn basic_rendezvous_test() {
         let (port, chan) = rendezvous();
 
-        do spawn {
+        spawn(proc() {
             chan.send("abc");
-        }
+        });
 
         assert!(port.recv() == "abc");
     }
@@ -126,29 +126,29 @@ pub fn basic_rendezvous_test() {
     fn recv_a_lot() {
         // Rendezvous streams should be able to handle any number of messages being sent
         let (port, chan) = rendezvous();
-        do spawn {
-            10000.times(|| { chan.send(()) })
-        }
-        10000.times(|| { port.recv() })
+        spawn(proc() {
+            for _ in range(0, 10000) { chan.send(()); }
+        });
+        for _ in range(0, 10000) { port.recv(); }
     }
 
     #[test]
     fn send_and_fail_and_try_recv() {
         let (port, chan) = rendezvous();
-        do spawn {
+        spawn(proc() {
             chan.duplex_stream.send(()); // Can't access this field outside this module
             fail!()
-        }
+        });
         port.recv()
     }
 
     #[test]
     fn try_send_and_recv_then_fail_before_ack() {
         let (port, chan) = rendezvous();
-        do spawn {
+        spawn(proc() {
             port.duplex_stream.recv();
             fail!()
-        }
+        });
         chan.try_send(());
     }
 
@@ -156,10 +156,10 @@ fn try_send_and_recv_then_fail_before_ack() {
     #[should_fail]
     fn send_and_recv_then_fail_before_ack() {
         let (port, chan) = rendezvous();
-        do spawn {
+        spawn(proc() {
             port.duplex_stream.recv();
             fail!()
-        }
+        });
         chan.send(());
     }
 }
index fa6e7c15ee01801641b4e175445261328211f1b3..ee80fa1c4c46eacc569a89c475beadfbd4122ff1 100644 (file)
@@ -38,22 +38,26 @@ pub struct DList<T> {
 }
 
 type Link<T> = Option<~Node<T>>;
-struct Rawlink<T> { priv p: *mut T }
+struct Rawlink<T> { p: *mut T }
 
 struct Node<T> {
-    priv next: Link<T>,
-    priv prev: Rawlink<Node<T>>,
-    priv value: T,
+    next: Link<T>,
+    prev: Rawlink<Node<T>>,
+    value: T,
 }
 
 /// Double-ended DList iterator
-#[deriving(Clone)]
 pub struct Items<'a, T> {
     priv head: &'a Link<T>,
     priv tail: Rawlink<Node<T>>,
     priv nelem: uint,
 }
 
+// FIXME #11820: the &'a Option<> of the Link stops clone working.
+impl<'a, T> Clone for Items<'a, T> {
+    fn clone(&self) -> Items<'a, T> { *self }
+}
+
 /// Double-ended mutable DList iterator
 pub struct MutItems<'a, T> {
     priv list: &'a mut DList<T>,
@@ -967,10 +971,10 @@ fn test_mut_rev_iter() {
     #[test]
     fn test_send() {
         let n = list_from([1,2,3]);
-        do spawn {
+        spawn(proc() {
             check_links(&n);
             assert_eq!(~[&1,&2,&3], n.iter().collect::<~[&int]>());
-        }
+        });
     }
 
     #[test]
@@ -1032,11 +1036,11 @@ fn test_ord_nan() {
 
     #[test]
     fn test_fuzz() {
-        25.times(|| {
+        for _ in range(0, 25) {
             fuzz_test(3);
             fuzz_test(16);
             fuzz_test(189);
-        })
+        }
     }
 
     #[cfg(test)]
index aac8253b8428add2924158e230bc861662771a09..5bbea491ac208be083e0e96e7a1199226edb1904 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -364,7 +364,7 @@ fn read_u16(&mut self) -> u16 { doc_as_u16(self.next_doc(EsU16)) }
         fn read_u8 (&mut self) -> u8  { doc_as_u8 (self.next_doc(EsU8 )) }
         fn read_uint(&mut self) -> uint {
             let v = doc_as_u64(self.next_doc(EsUint));
-            if v > (::std::uint::max_value as u64) {
+            if v > (::std::uint::MAX as u64) {
                 fail!("uint {} too large for this architecture", v);
             }
             v as uint
@@ -384,7 +384,7 @@ fn read_i8 (&mut self) -> i8 {
         }
         fn read_int(&mut self) -> int {
             let v = doc_as_u64(self.next_doc(EsInt)) as i64;
-            if v > (int::max_value as i64) || v < (int::min_value as i64) {
+            if v > (int::MAX as i64) || v < (int::MIN as i64) {
                 debug!("FIXME \\#6122: Removing this makes this function miscompile");
                 fail!("int {} out of range for this architecture", v);
             }
@@ -630,7 +630,7 @@ pub fn Encoder<'a>(w: &'a mut MemWriter) -> Encoder<'a> {
 
     // FIXME (#2741): Provide a function to write the standard ebml header.
     impl<'a> Encoder<'a> {
-        /// XXX(pcwalton): Workaround for badness in trans. DO NOT USE ME.
+        /// FIXME(pcwalton): Workaround for badness in trans. DO NOT USE ME.
         pub unsafe fn unsafe_clone(&self) -> Encoder<'a> {
             Encoder {
                 writer: cast::transmute_copy(&self.writer),
diff --git a/src/libextra/flate.rs b/src/libextra/flate.rs
deleted file mode 100644 (file)
index faceb17..0000000
+++ /dev/null
@@ -1,129 +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.
-
-/*!
-
-Simple compression
-
-*/
-
-#[allow(missing_doc)];
-
-use std::libc::{c_void, size_t, c_int};
-use std::libc;
-use std::vec;
-
-pub mod rustrt {
-    use std::libc::{c_int, c_void, size_t};
-
-    #[link(name = "rustrt", kind = "static")]
-    extern {
-        pub fn tdefl_compress_mem_to_heap(psrc_buf: *c_void,
-                                          src_buf_len: size_t,
-                                          pout_len: *mut size_t,
-                                          flags: c_int)
-                                          -> *c_void;
-
-        pub fn tinfl_decompress_mem_to_heap(psrc_buf: *c_void,
-                                            src_buf_len: size_t,
-                                            pout_len: *mut size_t,
-                                            flags: c_int)
-                                            -> *c_void;
-    }
-}
-
-static LZ_NORM : c_int = 0x80;  // LZ with 128 probes, "normal"
-static TINFL_FLAG_PARSE_ZLIB_HEADER : c_int = 0x1; // parse zlib header and adler32 checksum
-static TDEFL_WRITE_ZLIB_HEADER : c_int = 0x01000; // write zlib header and adler32 checksum
-
-fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> ~[u8] {
-    unsafe {
-        let mut outsz : size_t = 0;
-        let res = rustrt::tdefl_compress_mem_to_heap(bytes.as_ptr() as *c_void,
-                                                     bytes.len() as size_t,
-                                                     &mut outsz,
-                                                     flags);
-        assert!(res as int != 0);
-            let out = vec::raw::from_buf_raw(res as *u8,
-                                             outsz as uint);
-        libc::free(res as *mut c_void);
-        out
-    }
-}
-
-pub fn deflate_bytes(bytes: &[u8]) -> ~[u8] {
-    deflate_bytes_internal(bytes, LZ_NORM)
-}
-
-pub fn deflate_bytes_zlib(bytes: &[u8]) -> ~[u8] {
-    deflate_bytes_internal(bytes, LZ_NORM | TDEFL_WRITE_ZLIB_HEADER)
-}
-
-fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> ~[u8] {
-    unsafe {
-        let mut outsz : size_t = 0;
-        let res = rustrt::tinfl_decompress_mem_to_heap(bytes.as_ptr() as *c_void,
-                                                       bytes.len() as size_t,
-                                                       &mut outsz,
-                                                       flags);
-        assert!(res as int != 0);
-        let out = vec::raw::from_buf_raw(res as *u8,
-                                         outsz as uint);
-        libc::free(res as *mut c_void);
-        out
-    }
-}
-
-pub fn inflate_bytes(bytes: &[u8]) -> ~[u8] {
-    inflate_bytes_internal(bytes, 0)
-}
-
-pub fn inflate_bytes_zlib(bytes: &[u8]) -> ~[u8] {
-    inflate_bytes_internal(bytes, TINFL_FLAG_PARSE_ZLIB_HEADER)
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use std::rand;
-    use std::rand::Rng;
-
-    #[test]
-    fn test_flate_round_trip() {
-        let mut r = rand::rng();
-        let mut words = ~[];
-        20.times(|| {
-            let range = r.gen_range(1u, 10);
-            words.push(r.gen_vec::<u8>(range));
-        });
-        20.times(|| {
-            let mut input = ~[];
-            2000.times(|| {
-                input.push_all(r.choose(words));
-            });
-            debug!("de/inflate of {} bytes of random word-sequences",
-                   input.len());
-            let cmp = deflate_bytes(input);
-            let out = inflate_bytes(cmp);
-            debug!("{} bytes deflated to {} ({:.1f}% size)",
-                   input.len(), cmp.len(),
-                   100.0 * ((cmp.len() as f64) / (input.len() as f64)));
-            assert_eq!(input, out);
-        });
-    }
-
-    #[test]
-    fn test_zlib_flate() {
-        let bytes = ~[1, 2, 3, 4, 5];
-        let deflated = deflate_bytes(bytes);
-        let inflated = inflate_bytes(deflated);
-        assert_eq!(inflated, bytes);
-    }
-}
index c6c876aff79356ba80163cf34d9996e82ddbed26..b9121290f33f4ba49abcf8d312192bf43d6a5e36 100644 (file)
@@ -18,7 +18,7 @@
  * use extra::future::Future;
  * # fn fib(n: uint) -> uint {42};
  * # fn make_a_sandwich() {};
- * let mut delayed_fib = do Future::spawn { fib(5000) };
+ * let mut delayed_fib = Future::spawn(proc() { fib(5000) });
  * make_a_sandwich();
  * println!("fib(5000) = {}", delayed_fib.get())
  * ```
@@ -112,9 +112,9 @@ pub fn from_port(port: Port<A>) -> Future<A> {
          * waiting for the result to be received on the port.
          */
 
-        do Future::from_fn {
+        Future::from_fn(proc() {
             port.recv()
-        }
+        })
     }
 
     pub fn spawn(blk: proc() -> A) -> Future<A> {
@@ -127,9 +127,9 @@ pub fn spawn(blk: proc() -> A) -> Future<A> {
 
         let (port, chan) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             chan.send(blk());
-        }
+        });
 
         Future::from_port(port)
     }
@@ -195,11 +195,11 @@ fn test_futurefail() {
     #[test]
     fn test_sendable_future() {
         let expected = "schlorf";
-        let f = do Future::spawn { expected };
-        do task::spawn {
+        let f = Future::spawn(proc() { expected });
+        task::spawn(proc() {
             let mut f = f;
             let actual = f.get();
             assert_eq!(actual, expected);
-        }
+        });
     }
 }
index 10d28eaafb0cdd85dc73759e5ade06c5cb7beea3..4293f04795e03a96db200c95fef66f36c968c577 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -726,9 +726,9 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> ~str {
             // here we just need to indent the start of the description
             let rowlen = row.char_len();
             if rowlen < 24 {
-                (24 - rowlen).times(|| {
-                    row.push_char(' ')
-                })
+                for _ in range(0, 24 - rowlen) {
+                    row.push_char(' ');
+                }
             } else {
                 row.push_str(desc_sep)
             }
@@ -848,7 +848,7 @@ fn t(s: &str, i: uint, u: &[~str]) {
         t("hello", 15, [~"hello"]);
         t("\nMary had a little lamb\nLittle lamb\n", 15,
             [~"Mary had a", ~"little lamb", ~"Little lamb"]);
-        t("\nMary had a little lamb\nLittle lamb\n", ::std::uint::max_value,
+        t("\nMary had a little lamb\nLittle lamb\n", ::std::uint::MAX,
             [~"Mary had a little lamb\nLittle lamb"]);
     }
 } // end groups module
diff --git a/src/libextra/glob.rs b/src/libextra/glob.rs
deleted file mode 100644 (file)
index 3e2aa51..0000000
+++ /dev/null
@@ -1,777 +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.
-
-/*!
- * Support for matching file paths against Unix shell style patterns.
- *
- * The `glob` and `glob_with` functions, in concert with the `Paths`
- * type, allow querying the filesystem for all files that match a particular
- * pattern - just like the libc `glob` function (for an example see the `glob`
- * documentation). The methods on the `Pattern` type provide functionality
- * for checking if individual paths match a particular pattern - in a similar
- * manner to the libc `fnmatch` function
- *
- * For consistency across platforms, and for Windows support, this module
- * is implemented entirely in Rust rather than deferring to the libc
- * `glob`/`fnmatch` functions.
- */
-
-use std::{os, path};
-use std::io;
-use std::io::fs;
-use std::path::is_sep;
-
-/**
- * An iterator that yields Paths from the filesystem that match a particular
- * pattern - see the `glob` function for more details.
- */
-pub struct Paths {
-    priv root: Path,
-    priv dir_patterns: ~[Pattern],
-    priv options: MatchOptions,
-    priv todo: ~[(Path,uint)]
-}
-
-///
-/// Return an iterator that produces all the Paths that match the given pattern,
-/// which may be absolute or relative to the current working directory.
-///
-/// is method uses the default match options and is equivalent to calling
-/// `glob_with(pattern, MatchOptions::new())`. Use `glob_with` directly if you
-/// want to use non-default match options.
-///
-/// # Example
-///
-/// Consider a directory `/media/pictures` containing only the files `kittens.jpg`,
-/// `puppies.jpg` and `hamsters.gif`:
-///
-/// ```rust
-/// use extra::glob::glob;
-///
-/// for path in glob("/media/pictures/*.jpg") {
-///     println!("{}", path.display());
-/// }
-/// ```
-///
-/// The above code will print:
-///
-/// ```
-/// /media/pictures/kittens.jpg
-/// /media/pictures/puppies.jpg
-/// ```
-///
-pub fn glob(pattern: &str) -> Paths {
-    glob_with(pattern, MatchOptions::new())
-}
-
-/**
- * Return an iterator that produces all the Paths that match the given pattern,
- * which may be absolute or relative to the current working directory.
- *
- * This function accepts Unix shell style patterns as described by `Pattern::new(..)`.
- * The options given are passed through unchanged to `Pattern::matches_with(..)` with
- * the exception that `require_literal_separator` is always set to `true` regardless of the
- * value passed to this function.
- *
- * Paths are yielded in alphabetical order, as absolute paths.
- */
-pub fn glob_with(pattern: &str, options: MatchOptions) -> Paths {
-    #[cfg(windows)]
-    fn check_windows_verbatim(p: &Path) -> bool { path::windows::is_verbatim(p) }
-    #[cfg(not(windows))]
-    fn check_windows_verbatim(_: &Path) -> bool { false }
-
-    // calculate root this way to handle volume-relative Windows paths correctly
-    let mut root = os::getcwd();
-    let pat_root = Path::new(pattern).root_path();
-    if pat_root.is_some() {
-        if check_windows_verbatim(pat_root.get_ref()) {
-            // XXX: How do we want to handle verbatim paths? I'm inclined to return nothing,
-            // since we can't very well find all UNC shares with a 1-letter server name.
-            return Paths { root: root, dir_patterns: ~[], options: options, todo: ~[] };
-        }
-        root.push(pat_root.get_ref());
-    }
-
-    let root_len = pat_root.map_or(0u, |p| p.as_vec().len());
-    let dir_patterns = pattern.slice_from(root_len.min(&pattern.len()))
-                       .split_terminator(is_sep).map(|s| Pattern::new(s)).to_owned_vec();
-
-    let todo = list_dir_sorted(&root).move_iter().map(|x|(x,0u)).to_owned_vec();
-
-    Paths {
-        root: root,
-        dir_patterns: dir_patterns,
-        options: options,
-        todo: todo,
-    }
-}
-
-impl Iterator<Path> for Paths {
-
-    fn next(&mut self) -> Option<Path> {
-        loop {
-            if self.dir_patterns.is_empty() || self.todo.is_empty() {
-                return None;
-            }
-
-            let (path,idx) = self.todo.pop().unwrap();
-            let ref pattern = self.dir_patterns[idx];
-
-            if pattern.matches_with(match path.filename_str() {
-                // this ugly match needs to go here to avoid a borrowck error
-                None => {
-                    // FIXME (#9639): How do we handle non-utf8 filenames? Ignore them for now
-                    // Ideally we'd still match them against a *
-                    continue;
-                }
-                Some(x) => x
-            }, self.options) {
-                if idx == self.dir_patterns.len() - 1 {
-                    // it is not possible for a pattern to match a directory *AND* its children
-                    // so we don't need to check the children
-                    return Some(path);
-                } else {
-                    self.todo.extend(&mut list_dir_sorted(&path).move_iter().map(|x|(x,idx+1)));
-                }
-            }
-        }
-    }
-
-}
-
-fn list_dir_sorted(path: &Path) -> ~[Path] {
-    match io::result(|| fs::readdir(path)) {
-        Ok(mut children) => {
-            children.sort_by(|p1, p2| p2.filename().cmp(&p1.filename()));
-            children
-        }
-        Err(..) => ~[]
-    }
-}
-
-/**
- * A compiled Unix shell style pattern.
- */
-#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes, Default)]
-pub struct Pattern {
-    priv tokens: ~[PatternToken]
-}
-
-#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes)]
-enum PatternToken {
-    Char(char),
-    AnyChar,
-    AnySequence,
-    AnyWithin(~[CharSpecifier]),
-    AnyExcept(~[CharSpecifier])
-}
-
-#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes)]
-enum CharSpecifier {
-    SingleChar(char),
-    CharRange(char, char)
-}
-
-#[deriving(Eq)]
-enum MatchResult {
-    Match,
-    SubPatternDoesntMatch,
-    EntirePatternDoesntMatch
-}
-
-impl Pattern {
-
-    /**
-     * This function compiles Unix shell style patterns: `?` matches any single
-     * character, `*` matches any (possibly empty) sequence of characters and
-     * `[...]` matches any character inside the brackets, unless the first
-     * character is `!` in which case it matches any character except those
-     * between the `!` and the `]`. Character sequences can also specify ranges
-     * of characters, as ordered by Unicode, so e.g. `[0-9]` specifies any
-     * character between 0 and 9 inclusive.
-     *
-     * The metacharacters `?`, `*`, `[`, `]` can be matched by using brackets
-     * (e.g. `[?]`).  When a `]` occurs immediately following `[` or `[!` then
-     * it is interpreted as being part of, rather then ending, the character
-     * set, so `]` and NOT `]` can be matched by `[]]` and `[!]]` respectively.
-     * The `-` character can be specified inside a character sequence pattern by
-     * placing it at the start or the end, e.g. `[abc-]`.
-     *
-     * When a `[` does not have a closing `]` before the end of the string then
-     * the `[` will be treated literally.
-     */
-    pub fn new(pattern: &str) -> Pattern {
-
-        let chars = pattern.chars().to_owned_vec();
-        let mut tokens = ~[];
-        let mut i = 0;
-
-        while i < chars.len() {
-            match chars[i] {
-                '?' => {
-                    tokens.push(AnyChar);
-                    i += 1;
-                }
-                '*' => {
-                    // *, **, ***, ****, ... are all equivalent
-                    while i < chars.len() && chars[i] == '*' {
-                        i += 1;
-                    }
-                    tokens.push(AnySequence);
-                }
-                '[' => {
-
-                    if i <= chars.len() - 4 && chars[i + 1] == '!' {
-                        match chars.slice_from(i + 3).position_elem(&']') {
-                            None => (),
-                            Some(j) => {
-                                let chars = chars.slice(i + 2, i + 3 + j);
-                                let cs = parse_char_specifiers(chars);
-                                tokens.push(AnyExcept(cs));
-                                i += j + 4;
-                                continue;
-                            }
-                        }
-                    }
-                    else if i <= chars.len() - 3 && chars[i + 1] != '!' {
-                        match chars.slice_from(i + 2).position_elem(&']') {
-                            None => (),
-                            Some(j) => {
-                                let cs = parse_char_specifiers(chars.slice(i + 1, i + 2 + j));
-                                tokens.push(AnyWithin(cs));
-                                i += j + 3;
-                                continue;
-                            }
-                        }
-                    }
-
-                    // if we get here then this is not a valid range pattern
-                    tokens.push(Char('['));
-                    i += 1;
-                }
-                c => {
-                    tokens.push(Char(c));
-                    i += 1;
-                }
-            }
-        }
-
-        Pattern { tokens: tokens }
-    }
-
-    /**
-     * Escape metacharacters within the given string by surrounding them in
-     * brackets. The resulting string will, when compiled into a `Pattern`,
-     * match the input string and nothing else.
-     */
-    pub fn escape(s: &str) -> ~str {
-        let mut escaped = ~"";
-        for c in s.chars() {
-            match c {
-                // note that ! does not need escaping because it is only special inside brackets
-                '?' | '*' | '[' | ']' => {
-                    escaped.push_char('[');
-                    escaped.push_char(c);
-                    escaped.push_char(']');
-                }
-                c => {
-                    escaped.push_char(c);
-                }
-            }
-        }
-        escaped
-    }
-
-    /**
-     * Return if the given `str` matches this `Pattern` using the default
-     * match options (i.e. `MatchOptions::new()`).
-     *
-     * # Example
-     *
-     * ```rust
-     * use extra::glob::Pattern;
-     *
-     * assert!(Pattern::new("c?t").matches("cat"));
-     * assert!(Pattern::new("k[!e]tteh").matches("kitteh"));
-     * assert!(Pattern::new("d*g").matches("doog"));
-     * ```
-     */
-    pub fn matches(&self, str: &str) -> bool {
-        self.matches_with(str, MatchOptions::new())
-    }
-
-    /**
-     * Return if the given `Path`, when converted to a `str`, matches this `Pattern`
-     * using the default match options (i.e. `MatchOptions::new()`).
-     */
-    pub fn matches_path(&self, path: &Path) -> bool {
-        // FIXME (#9639): This needs to handle non-utf8 paths
-        path.as_str().map_or(false, |s| {
-            self.matches(s)
-        })
-    }
-
-    /**
-     * Return if the given `str` matches this `Pattern` using the specified match options.
-     */
-    pub fn matches_with(&self, str: &str, options: MatchOptions) -> bool {
-        self.matches_from(None, str, 0, options) == Match
-    }
-
-    /**
-     * Return if the given `Path`, when converted to a `str`, matches this `Pattern`
-     * using the specified match options.
-     */
-    pub fn matches_path_with(&self, path: &Path, options: MatchOptions) -> bool {
-        // FIXME (#9639): This needs to handle non-utf8 paths
-        path.as_str().map_or(false, |s| {
-            self.matches_with(s, options)
-        })
-    }
-
-    fn matches_from(&self,
-                    mut prev_char: Option<char>,
-                    mut file: &str,
-                    i: uint,
-                    options: MatchOptions) -> MatchResult {
-
-        let require_literal = |c| {
-            (options.require_literal_separator && is_sep(c)) ||
-            (options.require_literal_leading_dot && c == '.'
-             && is_sep(prev_char.unwrap_or('/')))
-        };
-
-        for (ti, token) in self.tokens.slice_from(i).iter().enumerate() {
-            match *token {
-                AnySequence => {
-                    loop {
-                        match self.matches_from(prev_char, file, i + ti + 1, options) {
-                            SubPatternDoesntMatch => (), // keep trying
-                            m => return m,
-                        }
-
-                        if file.is_empty() {
-                            return EntirePatternDoesntMatch;
-                        }
-
-                        let (c, next) = file.slice_shift_char();
-                        if require_literal(c) {
-                            return SubPatternDoesntMatch;
-                        }
-                        prev_char = Some(c);
-                        file = next;
-                    }
-                }
-                _ => {
-                    if file.is_empty() {
-                        return EntirePatternDoesntMatch;
-                    }
-
-                    let (c, next) = file.slice_shift_char();
-                    let matches = match *token {
-                        AnyChar => {
-                            !require_literal(c)
-                        }
-                        AnyWithin(ref specifiers) => {
-                            !require_literal(c) && in_char_specifiers(*specifiers, c, options)
-                        }
-                        AnyExcept(ref specifiers) => {
-                            !require_literal(c) && !in_char_specifiers(*specifiers, c, options)
-                        }
-                        Char(c2) => {
-                            chars_eq(c, c2, options.case_sensitive)
-                        }
-                        AnySequence => {
-                            unreachable!()
-                        }
-                    };
-                    if !matches {
-                        return SubPatternDoesntMatch;
-                    }
-                    prev_char = Some(c);
-                    file = next;
-                }
-            }
-        }
-
-        if file.is_empty() {
-            Match
-        } else {
-            SubPatternDoesntMatch
-        }
-    }
-
-}
-
-fn parse_char_specifiers(s: &[char]) -> ~[CharSpecifier] {
-    let mut cs = ~[];
-    let mut i = 0;
-    while i < s.len() {
-        if i + 3 <= s.len() && s[i + 1] == '-' {
-            cs.push(CharRange(s[i], s[i + 2]));
-            i += 3;
-        } else {
-            cs.push(SingleChar(s[i]));
-            i += 1;
-        }
-    }
-    cs
-}
-
-fn in_char_specifiers(specifiers: &[CharSpecifier], c: char, options: MatchOptions) -> bool {
-
-    for &specifier in specifiers.iter() {
-        match specifier {
-            SingleChar(sc) => {
-                if chars_eq(c, sc, options.case_sensitive) {
-                    return true;
-                }
-            }
-            CharRange(start, end) => {
-
-                // FIXME: work with non-ascii chars properly (issue #1347)
-                if !options.case_sensitive && c.is_ascii() && start.is_ascii() && end.is_ascii() {
-
-                    let start = start.to_ascii().to_lower();
-                    let end = end.to_ascii().to_lower();
-
-                    let start_up = start.to_upper();
-                    let end_up = end.to_upper();
-
-                    // only allow case insensitive matching when
-                    // both start and end are within a-z or A-Z
-                    if start != start_up && end != end_up {
-                        let start = start.to_char();
-                        let end = end.to_char();
-                        let c = c.to_ascii().to_lower().to_char();
-                        if c >= start && c <= end {
-                            return true;
-                        }
-                    }
-                }
-
-                if c >= start && c <= end {
-                    return true;
-                }
-            }
-        }
-    }
-
-    false
-}
-
-/// A helper function to determine if two chars are (possibly case-insensitively) equal.
-fn chars_eq(a: char, b: char, case_sensitive: bool) -> bool {
-    if cfg!(windows) && path::windows::is_sep(a) && path::windows::is_sep(b) {
-        true
-    } else if !case_sensitive && a.is_ascii() && b.is_ascii() {
-        // FIXME: work with non-ascii chars properly (issue #1347)
-        a.to_ascii().eq_ignore_case(b.to_ascii())
-    } else {
-        a == b
-    }
-}
-
-/**
- * Configuration options to modify the behaviour of `Pattern::matches_with(..)`
- */
-#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes, Default)]
-pub struct MatchOptions {
-
-    /**
-     * Whether or not patterns should be matched in a case-sensitive manner. This
-     * currently only considers upper/lower case relationships between ASCII characters,
-     * but in future this might be extended to work with Unicode.
-     */
-    priv case_sensitive: bool,
-
-    /**
-     * If this is true then path-component separator characters (e.g. `/` on Posix)
-     * must be matched by a literal `/`, rather than by `*` or `?` or `[...]`
-     */
-    priv require_literal_separator: bool,
-
-    /**
-     * If this is true then paths that contain components that start with a `.` will
-     * not match unless the `.` appears literally in the pattern: `*`, `?` or `[...]`
-     * will not match. This is useful because such files are conventionally considered
-     * hidden on Unix systems and it might be desirable to skip them when listing files.
-     */
-    priv require_literal_leading_dot: bool
-}
-
-impl MatchOptions {
-
-    /**
-     * Constructs a new `MatchOptions` with default field values. This is used
-     * when calling functions that do not take an explicit `MatchOptions` parameter.
-     *
-     * This function always returns this value:
-     *
-     * ```rust,ignore
-     * MatchOptions {
-     *     case_sensitive: true,
-     *     require_literal_separator: false.
-     *     require_literal_leading_dot: false
-     * }
-     * ```
-     */
-    pub fn new() -> MatchOptions {
-        MatchOptions {
-            case_sensitive: true,
-            require_literal_separator: false,
-            require_literal_leading_dot: false
-        }
-    }
-
-}
-
-#[cfg(test)]
-mod test {
-    use std::os;
-    use super::*;
-
-    #[test]
-    fn test_absolute_pattern() {
-        // assume that the filesystem is not empty!
-        assert!(glob("/*").next().is_some());
-        assert!(glob("//").next().is_none());
-
-        // check windows absolute paths with host/device components
-        let root_with_device = os::getcwd().root_path().unwrap().join("*");
-        // FIXME (#9639): This needs to handle non-utf8 paths
-        assert!(glob(root_with_device.as_str().unwrap()).next().is_some());
-    }
-
-    #[test]
-    fn test_wildcard_optimizations() {
-        assert!(Pattern::new("a*b").matches("a___b"));
-        assert!(Pattern::new("a**b").matches("a___b"));
-        assert!(Pattern::new("a***b").matches("a___b"));
-        assert!(Pattern::new("a*b*c").matches("abc"));
-        assert!(!Pattern::new("a*b*c").matches("abcd"));
-        assert!(Pattern::new("a*b*c").matches("a_b_c"));
-        assert!(Pattern::new("a*b*c").matches("a___b___c"));
-        assert!(Pattern::new("abc*abc*abc").matches("abcabcabcabcabcabcabc"));
-        assert!(!Pattern::new("abc*abc*abc").matches("abcabcabcabcabcabcabca"));
-        assert!(Pattern::new("a*a*a*a*a*a*a*a*a").matches("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
-        assert!(Pattern::new("a*b[xyz]c*d").matches("abxcdbxcddd"));
-    }
-
-    #[test]
-    fn test_lots_of_files() {
-        // this is a good test because it touches lots of differently named files
-        glob("/*/*/*/*").skip(10000).next();
-    }
-
-    #[test]
-    fn test_range_pattern() {
-
-        let pat = Pattern::new("a[0-9]b");
-        for i in range(0, 10) {
-            assert!(pat.matches(format!("a{}b", i)));
-        }
-        assert!(!pat.matches("a_b"));
-
-        let pat = Pattern::new("a[!0-9]b");
-        for i in range(0, 10) {
-            assert!(!pat.matches(format!("a{}b", i)));
-        }
-        assert!(pat.matches("a_b"));
-
-        let pats = ["[a-z123]", "[1a-z23]", "[123a-z]"];
-        for &p in pats.iter() {
-            let pat = Pattern::new(p);
-            for c in "abcdefghijklmnopqrstuvwxyz".chars() {
-                assert!(pat.matches(c.to_str()));
-            }
-            for c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ".chars() {
-                let options = MatchOptions {case_sensitive: false, .. MatchOptions::new()};
-                assert!(pat.matches_with(c.to_str(), options));
-            }
-            assert!(pat.matches("1"));
-            assert!(pat.matches("2"));
-            assert!(pat.matches("3"));
-        }
-
-        let pats = ["[abc-]", "[-abc]", "[a-c-]"];
-        for &p in pats.iter() {
-            let pat = Pattern::new(p);
-            assert!(pat.matches("a"));
-            assert!(pat.matches("b"));
-            assert!(pat.matches("c"));
-            assert!(pat.matches("-"));
-            assert!(!pat.matches("d"));
-        }
-
-        let pat = Pattern::new("[2-1]");
-        assert!(!pat.matches("1"));
-        assert!(!pat.matches("2"));
-
-        assert!(Pattern::new("[-]").matches("-"));
-        assert!(!Pattern::new("[!-]").matches("-"));
-    }
-
-    #[test]
-    fn test_unclosed_bracket() {
-        // unclosed `[` should be treated literally
-        assert!(Pattern::new("abc[def").matches("abc[def"));
-        assert!(Pattern::new("abc[!def").matches("abc[!def"));
-        assert!(Pattern::new("abc[").matches("abc["));
-        assert!(Pattern::new("abc[!").matches("abc[!"));
-        assert!(Pattern::new("abc[d").matches("abc[d"));
-        assert!(Pattern::new("abc[!d").matches("abc[!d"));
-        assert!(Pattern::new("abc[]").matches("abc[]"));
-        assert!(Pattern::new("abc[!]").matches("abc[!]"));
-    }
-
-    #[test]
-    fn test_pattern_matches() {
-        let txt_pat = Pattern::new("*hello.txt");
-        assert!(txt_pat.matches("hello.txt"));
-        assert!(txt_pat.matches("gareth_says_hello.txt"));
-        assert!(txt_pat.matches("some/path/to/hello.txt"));
-        assert!(txt_pat.matches("some\\path\\to\\hello.txt"));
-        assert!(txt_pat.matches("/an/absolute/path/to/hello.txt"));
-        assert!(!txt_pat.matches("hello.txt-and-then-some"));
-        assert!(!txt_pat.matches("goodbye.txt"));
-
-        let dir_pat = Pattern::new("*some/path/to/hello.txt");
-        assert!(dir_pat.matches("some/path/to/hello.txt"));
-        assert!(dir_pat.matches("a/bigger/some/path/to/hello.txt"));
-        assert!(!dir_pat.matches("some/path/to/hello.txt-and-then-some"));
-        assert!(!dir_pat.matches("some/other/path/to/hello.txt"));
-    }
-
-    #[test]
-    fn test_pattern_escape() {
-        let s = "_[_]_?_*_!_";
-        assert_eq!(Pattern::escape(s), ~"_[[]_[]]_[?]_[*]_!_");
-        assert!(Pattern::new(Pattern::escape(s)).matches(s));
-    }
-
-    #[test]
-    fn test_pattern_matches_case_insensitive() {
-
-        let pat = Pattern::new("aBcDeFg");
-        let options = MatchOptions {
-            case_sensitive: false,
-            require_literal_separator: false,
-            require_literal_leading_dot: false
-        };
-
-        assert!(pat.matches_with("aBcDeFg", options));
-        assert!(pat.matches_with("abcdefg", options));
-        assert!(pat.matches_with("ABCDEFG", options));
-        assert!(pat.matches_with("AbCdEfG", options));
-    }
-
-    #[test]
-    fn test_pattern_matches_case_insensitive_range() {
-
-        let pat_within = Pattern::new("[a]");
-        let pat_except = Pattern::new("[!a]");
-
-        let options_case_insensitive = MatchOptions {
-            case_sensitive: false,
-            require_literal_separator: false,
-            require_literal_leading_dot: false
-        };
-        let options_case_sensitive = MatchOptions {
-            case_sensitive: true,
-            require_literal_separator: false,
-            require_literal_leading_dot: false
-        };
-
-        assert!(pat_within.matches_with("a", options_case_insensitive));
-        assert!(pat_within.matches_with("A", options_case_insensitive));
-        assert!(!pat_within.matches_with("A", options_case_sensitive));
-
-        assert!(!pat_except.matches_with("a", options_case_insensitive));
-        assert!(!pat_except.matches_with("A", options_case_insensitive));
-        assert!(pat_except.matches_with("A", options_case_sensitive));
-    }
-
-    #[test]
-    fn test_pattern_matches_require_literal_separator() {
-
-        let options_require_literal = MatchOptions {
-            case_sensitive: true,
-            require_literal_separator: true,
-            require_literal_leading_dot: false
-        };
-        let options_not_require_literal = MatchOptions {
-            case_sensitive: true,
-            require_literal_separator: false,
-            require_literal_leading_dot: false
-        };
-
-        assert!(Pattern::new("abc/def").matches_with("abc/def", options_require_literal));
-        assert!(!Pattern::new("abc?def").matches_with("abc/def", options_require_literal));
-        assert!(!Pattern::new("abc*def").matches_with("abc/def", options_require_literal));
-        assert!(!Pattern::new("abc[/]def").matches_with("abc/def", options_require_literal));
-
-        assert!(Pattern::new("abc/def").matches_with("abc/def", options_not_require_literal));
-        assert!(Pattern::new("abc?def").matches_with("abc/def", options_not_require_literal));
-        assert!(Pattern::new("abc*def").matches_with("abc/def", options_not_require_literal));
-        assert!(Pattern::new("abc[/]def").matches_with("abc/def", options_not_require_literal));
-    }
-
-    #[test]
-    fn test_pattern_matches_require_literal_leading_dot() {
-
-        let options_require_literal_leading_dot = MatchOptions {
-            case_sensitive: true,
-            require_literal_separator: false,
-            require_literal_leading_dot: true
-        };
-        let options_not_require_literal_leading_dot = MatchOptions {
-            case_sensitive: true,
-            require_literal_separator: false,
-            require_literal_leading_dot: false
-        };
-
-        let f = |options| Pattern::new("*.txt").matches_with(".hello.txt", options);
-        assert!(f(options_not_require_literal_leading_dot));
-        assert!(!f(options_require_literal_leading_dot));
-
-        let f = |options| Pattern::new(".*.*").matches_with(".hello.txt", options);
-        assert!(f(options_not_require_literal_leading_dot));
-        assert!(f(options_require_literal_leading_dot));
-
-        let f = |options| Pattern::new("aaa/bbb/*").matches_with("aaa/bbb/.ccc", options);
-        assert!(f(options_not_require_literal_leading_dot));
-        assert!(!f(options_require_literal_leading_dot));
-
-        let f = |options| Pattern::new("aaa/bbb/*").matches_with("aaa/bbb/c.c.c.", options);
-        assert!(f(options_not_require_literal_leading_dot));
-        assert!(f(options_require_literal_leading_dot));
-
-        let f = |options| Pattern::new("aaa/bbb/.*").matches_with("aaa/bbb/.ccc", options);
-        assert!(f(options_not_require_literal_leading_dot));
-        assert!(f(options_require_literal_leading_dot));
-
-        let f = |options| Pattern::new("aaa/?bbb").matches_with("aaa/.bbb", options);
-        assert!(f(options_not_require_literal_leading_dot));
-        assert!(!f(options_require_literal_leading_dot));
-
-        let f = |options| Pattern::new("aaa/[.]bbb").matches_with("aaa/.bbb", options);
-        assert!(f(options_not_require_literal_leading_dot));
-        assert!(!f(options_require_literal_leading_dot));
-    }
-
-    #[test]
-    fn test_matches_path() {
-        // on windows, (Path::new("a/b").as_str().unwrap() == "a\\b"), so this
-        // tests that / and \ are considered equivalent on windows
-        assert!(Pattern::new("a/b").matches_path(&Path::new("a/b")));
-    }
-}
index a35c474337d61ec2106c067d5df4d0db54f4135a..f8b1c216529b1bcfb0a44db98d87488f6d24293a 100644 (file)
@@ -282,7 +282,7 @@ fn escape_str(s: &str) -> ~str {
 
 fn spaces(n: uint) -> ~str {
     let mut ss = ~"";
-    n.times(|| ss.push_str(" "));
+    for _ in range(0, n) { ss.push_str(" "); }
     return ss;
 }
 
@@ -2201,7 +2201,7 @@ enum DecodeEnum {
     }
     fn check_err<T: Decodable<Decoder>>(to_parse: &'static str, expected_error: &str) {
         use std::task;
-        let res = do task::try {
+        let res = task::try(proc() {
             // either fails in `decode` (which is what we want), or
             // returns Some(error_message)/None if the string was
             // invalid or valid JSON.
@@ -2212,7 +2212,7 @@ fn check_err<T: Decodable<Decoder>>(to_parse: &'static str, expected_error: &str
                     None
                 }
             }
-        };
+        });
         match res {
             Ok(Some(parse_error)) => fail!("`{}` is not valid json: {}",
                                            to_parse, parse_error),
index fc0cc0451757773246bad0729deda1e684aaf45c..bb89915dfd13563654442e932cd511f03ab46aa2 100644 (file)
 pub mod getopts;
 pub mod json;
 pub mod tempfile;
-pub mod glob;
 pub mod term;
 pub mod time;
-pub mod arena;
 pub mod base64;
 pub mod workcache;
 pub mod enum_set;
@@ -82,7 +80,6 @@
 pub mod complex;
 pub mod stats;
 pub mod semver;
-pub mod flate;
 pub mod hex;
 pub mod uuid;
 
index e1cb54ae45296e1524e47855bc8c7c0a5c50feaf..f602db2e54d0aae760d5c7beec5777313f71645f 100644 (file)
 use std::ptr;
 use std::cast;
 
-struct KeyRef<K> { priv k: *K }
+struct KeyRef<K> { k: *K }
 
 struct LruEntry<K, V> {
-    priv key: Option<K>,
-    priv value: Option<V>,
-    priv next: *mut LruEntry<K, V>,
-    priv prev: *mut LruEntry<K, V>,
+    key: Option<K>,
+    value: Option<V>,
+    next: *mut LruEntry<K, V>,
+    prev: *mut LruEntry<K, V>,
 }
 
 /// An LRU Cache.
index 8729cf1b68553ece9aee7b3bc46b0eb8443a1d22..6dfe036d207b99f433e294b7006ad0d8b0381d0a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -1186,7 +1186,7 @@ fn to_i64(&self) -> Option<i64> {
                     if n < m {
                         Some(-(n as i64))
                     } else if n == m {
-                        Some(i64::min_value)
+                        Some(i64::MIN)
                     } else {
                         None
                     }
@@ -1213,7 +1213,7 @@ fn from_i64(n: i64) -> Option<BigInt> {
                 Some(BigInt::from_biguint(Plus, n))
             })
         } else if n < 0 {
-            FromPrimitive::from_u64(u64::max_value - (n as u64) + 1).and_then(
+            FromPrimitive::from_u64(u64::MAX - (n as u64) + 1).and_then(
                 |n| {
                     Some(BigInt::from_biguint(Minus, n))
                 })
@@ -1625,7 +1625,7 @@ fn check(b1: BigUint, i: i64) {
 
         check(Zero::zero(), 0);
         check(One::one(), 1);
-        check(i64::max_value.to_biguint().unwrap(), i64::max_value);
+        check(i64::MAX.to_biguint().unwrap(), i64::MAX);
 
         check(BigUint::new(~[                   ]), 0);
         check(BigUint::new(~[ 1                 ]), (1 << (0*BigDigit::bits)));
@@ -1635,9 +1635,9 @@ fn check(b1: BigUint, i: i64) {
         check(BigUint::new(~[ 0,  0,  1         ]), (1 << (2*BigDigit::bits)));
         check(BigUint::new(~[-1, -1, -1         ]), (1 << (3*BigDigit::bits)) - 1);
         check(BigUint::new(~[ 0,  0,  0,  1     ]), (1 << (3*BigDigit::bits)));
-        check(BigUint::new(~[-1, -1, -1, -1 >> 1]), i64::max_value);
+        check(BigUint::new(~[-1, -1, -1, -1 >> 1]), i64::MAX);
 
-        assert_eq!(i64::min_value.to_biguint(), None);
+        assert_eq!(i64::MIN.to_biguint(), None);
         assert_eq!(BigUint::new(~[-1, -1, -1, -1    ]).to_i64(), None);
         assert_eq!(BigUint::new(~[ 0,  0,  0,  0,  1]).to_i64(), None);
         assert_eq!(BigUint::new(~[-1, -1, -1, -1, -1]).to_i64(), None);
@@ -1654,15 +1654,15 @@ fn check(b1: BigUint, i: i64) {
 
         check(Zero::zero(), 0);
         check(One::one(), 1);
-        check(i64::max_value.to_biguint().unwrap(), i64::max_value);
+        check(i64::MAX.to_biguint().unwrap(), i64::MAX);
 
         check(BigUint::new(~[           ]), 0);
         check(BigUint::new(~[ 1         ]), (1 << (0*BigDigit::bits)));
         check(BigUint::new(~[-1         ]), (1 << (1*BigDigit::bits)) - 1);
         check(BigUint::new(~[ 0,  1     ]), (1 << (1*BigDigit::bits)));
-        check(BigUint::new(~[-1, -1 >> 1]), i64::max_value);
+        check(BigUint::new(~[-1, -1 >> 1]), i64::MAX);
 
-        assert_eq!(i64::min_value.to_biguint(), None);
+        assert_eq!(i64::MIN.to_biguint(), None);
         assert_eq!(BigUint::new(~[-1, -1    ]).to_i64(), None);
         assert_eq!(BigUint::new(~[ 0,  0,  1]).to_i64(), None);
         assert_eq!(BigUint::new(~[-1, -1, -1]).to_i64(), None);
@@ -1679,8 +1679,8 @@ fn check(b1: BigUint, u: u64) {
 
         check(Zero::zero(), 0);
         check(One::one(), 1);
-        check(u64::min_value.to_biguint().unwrap(), u64::min_value);
-        check(u64::max_value.to_biguint().unwrap(), u64::max_value);
+        check(u64::MIN.to_biguint().unwrap(), u64::MIN);
+        check(u64::MAX.to_biguint().unwrap(), u64::MAX);
 
         check(BigUint::new(~[              ]), 0);
         check(BigUint::new(~[ 1            ]), (1 << (0*BigDigit::bits)));
@@ -1690,7 +1690,7 @@ fn check(b1: BigUint, u: u64) {
         check(BigUint::new(~[ 0,  0,  1    ]), (1 << (2*BigDigit::bits)));
         check(BigUint::new(~[-1, -1, -1    ]), (1 << (3*BigDigit::bits)) - 1);
         check(BigUint::new(~[ 0,  0,  0,  1]), (1 << (3*BigDigit::bits)));
-        check(BigUint::new(~[-1, -1, -1, -1]), u64::max_value);
+        check(BigUint::new(~[-1, -1, -1, -1]), u64::MAX);
 
         assert_eq!(BigUint::new(~[ 0,  0,  0,  0,  1]).to_u64(), None);
         assert_eq!(BigUint::new(~[-1, -1, -1, -1, -1]).to_u64(), None);
@@ -1707,14 +1707,14 @@ fn check(b1: BigUint, u: u64) {
 
         check(Zero::zero(), 0);
         check(One::one(), 1);
-        check(u64::min_value.to_biguint().unwrap(), u64::min_value);
-        check(u64::max_value.to_biguint().unwrap(), u64::max_value);
+        check(u64::MIN.to_biguint().unwrap(), u64::MIN);
+        check(u64::MAX.to_biguint().unwrap(), u64::MAX);
 
         check(BigUint::new(~[      ]), 0);
         check(BigUint::new(~[ 1    ]), (1 << (0*BigDigit::bits)));
         check(BigUint::new(~[-1    ]), (1 << (1*BigDigit::bits)) - 1);
         check(BigUint::new(~[ 0,  1]), (1 << (1*BigDigit::bits)));
-        check(BigUint::new(~[-1, -1]), u64::max_value);
+        check(BigUint::new(~[-1, -1]), u64::MAX);
 
         assert_eq!(BigUint::new(~[ 0,  0,  1]).to_u64(), None);
         assert_eq!(BigUint::new(~[-1, -1, -1]).to_u64(), None);
@@ -2052,22 +2052,22 @@ fn test_rand() {
     fn test_rand_range() {
         let mut rng = task_rng();
 
-        10.times(|| {
+        for _ in range(0, 10) {
             assert_eq!(rng.gen_bigint_range(&FromPrimitive::from_uint(236).unwrap(),
                                             &FromPrimitive::from_uint(237).unwrap()),
                        FromPrimitive::from_uint(236).unwrap());
-        });
+        }
 
         let l = FromPrimitive::from_uint(403469000 + 2352).unwrap();
         let u = FromPrimitive::from_uint(403469000 + 3513).unwrap();
-        1000.times(|| {
+        for _ in range(0, 1000) {
             let n: BigUint = rng.gen_biguint_below(&u);
             assert!(n < u);
 
             let n: BigUint = rng.gen_biguint_range(&l, &u);
             assert!(n >= l);
             assert!(n < u);
-        })
+        }
     }
 
     #[test]
@@ -2166,11 +2166,11 @@ fn check(b1: BigInt, i: i64) {
 
         check(Zero::zero(), 0);
         check(One::one(), 1);
-        check(i64::min_value.to_bigint().unwrap(), i64::min_value);
-        check(i64::max_value.to_bigint().unwrap(), i64::max_value);
+        check(i64::MIN.to_bigint().unwrap(), i64::MIN);
+        check(i64::MAX.to_bigint().unwrap(), i64::MAX);
 
         assert_eq!(
-            (i64::max_value as u64 + 1).to_bigint().unwrap().to_i64(),
+            (i64::MAX as u64 + 1).to_bigint().unwrap().to_i64(),
             None);
 
         assert_eq!(
@@ -2196,14 +2196,14 @@ fn check(b1: BigInt, u: u64) {
 
         check(Zero::zero(), 0);
         check(One::one(), 1);
-        check(u64::min_value.to_bigint().unwrap(), u64::min_value);
-        check(u64::max_value.to_bigint().unwrap(), u64::max_value);
+        check(u64::MIN.to_bigint().unwrap(), u64::MIN);
+        check(u64::MAX.to_bigint().unwrap(), u64::MAX);
 
         assert_eq!(
             BigInt::from_biguint(Plus, BigUint::new(~[1, 2, 3, 4, 5])).to_u64(),
             None);
 
-        let max_value: BigUint = FromPrimitive::from_u64(u64::max_value).unwrap();
+        let max_value: BigUint = FromPrimitive::from_u64(u64::MAX).unwrap();
         assert_eq!(BigInt::from_biguint(Minus, max_value).to_u64(), None);
         assert_eq!(BigInt::from_biguint(Minus, BigUint::new(~[1, 2, 3, 4, 5])).to_u64(), None);
     }
@@ -2550,19 +2550,19 @@ fn test_rand() {
     fn test_rand_range() {
         let mut rng = task_rng();
 
-        10.times(|| {
+        for _ in range(0, 10) {
             assert_eq!(rng.gen_bigint_range(&FromPrimitive::from_uint(236).unwrap(),
                                             &FromPrimitive::from_uint(237).unwrap()),
                        FromPrimitive::from_uint(236).unwrap());
-        });
+        }
 
         fn check(l: BigInt, u: BigInt) {
             let mut rng = task_rng();
-            1000.times(|| {
+            for _ in range(0, 1000) {
                 let n: BigInt = rng.gen_bigint_range(&l, &u);
                 assert!(n >= l);
                 assert!(n < u);
-            });
+            }
         }
         let l: BigInt = FromPrimitive::from_uint(403469000 + 2352).unwrap();
         let u: BigInt = FromPrimitive::from_uint(403469000 + 3513).unwrap();
index 684aafd250090352437ec49f487750c159264f13..ddef2f0a37a8fb5328948dbb27278646b7ff0254 100644 (file)
@@ -571,9 +571,9 @@ fn bench_push_front(b: &mut test::BenchHarness) {
     fn bench_grow(b: &mut test::BenchHarness) {
         let mut deq = RingBuf::new();
         b.iter(|| {
-            65.times(|| {
+            for _ in range(0, 65) {
                 deq.push_front(1);
-            })
+            }
         })
     }
 
index 044e5e9e5098937c203a317433e309d82e28c797..26a555a646c58408fc774411d8b3103d5d128bed 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -18,7 +18,6 @@
  */
 
 
-use std::borrow;
 use std::comm;
 use std::unstable::sync::Exclusive;
 use std::sync::arc::UnsafeArc;
@@ -27,6 +26,8 @@
 use std::util;
 use std::util::NonCopyable;
 
+use arc::MutexArc;
+
 /****************************************************************************
  * Internals
  ****************************************************************************/
@@ -118,7 +119,7 @@ pub fn acquire(&self) {
                 }
             });
             // Uncomment if you wish to test for sem races. Not valgrind-friendly.
-            /* 1000.times(|| task::deschedule()); */
+            /* for _ in range(0, 1000) { task::deschedule(); } */
             // Need to wait outside the exclusive.
             if waiter_nobe.is_some() {
                 let _ = waiter_nobe.unwrap().recv();
@@ -153,7 +154,7 @@ impl Sem<~[WaitQueue]> {
     fn new_and_signal(count: int, num_condvars: uint)
         -> Sem<~[WaitQueue]> {
         let mut queues = ~[];
-        num_condvars.times(|| queues.push(WaitQueue::new()));
+        for _ in range(0, num_condvars) { queues.push(WaitQueue::new()); }
         Sem::new(count, queues)
     }
 }
@@ -632,7 +633,7 @@ pub fn write_downgrade<U>(&self, blk: |v: RWLockWriteMode| -> U) -> U {
     /// To be called inside of the write_downgrade block.
     pub fn downgrade<'a>(&self, token: RWLockWriteMode<'a>)
                          -> RWLockReadMode<'a> {
-        if !borrow::ref_eq(self, token.lock) {
+        if !((self as *RWLock) == (token.lock as *RWLock)) {
             fail!("Can't downgrade() with a different rwlock's write_mode!");
         }
         unsafe {
@@ -682,6 +683,68 @@ impl<'a> RWLockReadMode<'a> {
     pub fn read<U>(&self, blk: || -> U) -> U { blk() }
 }
 
+/// A barrier enables multiple tasks to synchronize the beginning
+/// of some computation.
+///
+/// ```rust
+/// use extra::sync::Barrier;
+///
+/// let barrier = Barrier::new(10);
+/// for _ in range(0, 10) {
+///     let c = barrier.clone();
+///     // The same messages will be printed together.
+///     // You will NOT see any interleaving.
+///     spawn(proc() {
+///         println!("before wait");
+///         c.wait();
+///         println!("after wait");
+///     });
+/// }
+/// ```
+#[deriving(Clone)]
+pub struct Barrier {
+    priv arc: MutexArc<BarrierState>,
+    priv num_tasks: uint,
+}
+
+// The inner state of a double barrier
+struct BarrierState {
+    count: uint,
+    generation_id: uint,
+}
+
+impl Barrier {
+    /// Create a new barrier that can block a given number of tasks.
+    pub fn new(num_tasks: uint) -> Barrier {
+        Barrier {
+            arc: MutexArc::new(BarrierState {
+                count: 0,
+                generation_id: 0,
+            }),
+            num_tasks: num_tasks,
+        }
+    }
+
+    /// Block the current task until a certain number of tasks is waiting.
+    pub fn wait(&self) {
+        self.arc.access_cond(|state, cond| {
+            let local_gen = state.generation_id;
+            state.count += 1;
+            if state.count < self.num_tasks {
+                // We need a while loop to guard against spurious wakeups.
+                // http://en.wikipedia.org/wiki/Spurious_wakeup
+                while local_gen == state.generation_id && state.count < self.num_tasks {
+                    cond.wait();
+                }
+            } else {
+                state.count = 0;
+                state.generation_id += 1;
+                cond.broadcast();
+            }
+        });
+    }
+}
+
 /****************************************************************************
  * Tests
  ****************************************************************************/
@@ -693,6 +756,7 @@ mod tests {
     use std::cast;
     use std::result;
     use std::task;
+    use std::comm::{SharedChan, Empty};
 
     /************************************************************************
      * Semaphore tests
@@ -713,13 +777,13 @@ fn test_sem_basic() {
     fn test_sem_as_mutex() {
         let s = Semaphore::new(1);
         let s2 = s.clone();
-        do task::spawn {
+        task::spawn(proc() {
             s2.access(|| {
-                5.times(|| { task::deschedule(); })
+                for _ in range(0, 5) { task::deschedule(); }
             })
-        }
+        });
         s.access(|| {
-            5.times(|| { task::deschedule(); })
+            for _ in range(0, 5) { task::deschedule(); }
         })
     }
     #[test]
@@ -728,11 +792,11 @@ fn test_sem_as_cvar() {
         let (p, c) = Chan::new();
         let s = Semaphore::new(0);
         let s2 = s.clone();
-        do task::spawn {
+        task::spawn(proc() {
             s2.acquire();
             c.send(());
-        }
-        5.times(|| { task::deschedule(); });
+        });
+        for _ in range(0, 5) { task::deschedule(); }
         s.release();
         let _ = p.recv();
 
@@ -740,11 +804,11 @@ fn test_sem_as_cvar() {
         let (p, c) = Chan::new();
         let s = Semaphore::new(0);
         let s2 = s.clone();
-        do task::spawn {
-            5.times(|| { task::deschedule(); });
+        task::spawn(proc() {
+            for _ in range(0, 5) { task::deschedule(); }
             s2.release();
             let _ = p.recv();
-        }
+        });
         s.acquire();
         c.send(());
     }
@@ -756,12 +820,12 @@ fn test_sem_multi_resource() {
         let s2 = s.clone();
         let (p1,c1) = Chan::new();
         let (p2,c2) = Chan::new();
-        do task::spawn {
+        task::spawn(proc() {
             s2.access(|| {
                 let _ = p2.recv();
                 c1.send(());
             })
-        }
+        });
         s.access(|| {
             c2.send(());
             let _ = p1.recv();
@@ -777,13 +841,13 @@ fn test_sem_runtime_friendly_blocking() {
         let mut child_data = Some((s2, c));
         s.access(|| {
             let (s2, c) = child_data.take_unwrap();
-            do task::spawn {
+            task::spawn(proc() {
                 c.send(());
                 s2.access(|| { });
                 c.send(());
-            }
+            });
             let _ = p.recv(); // wait for child to come alive
-            5.times(|| { task::deschedule(); }); // let the child contend
+            for _ in range(0, 5) { task::deschedule(); } // let the child contend
         });
         let _ = p.recv(); // wait for child to be done
     }
@@ -800,13 +864,12 @@ fn test_mutex_lock() {
         let mut sharedstate = ~0;
         {
             let ptr: *int = &*sharedstate;
-            do task::spawn {
+            task::spawn(proc() {
                 let sharedstate: &mut int =
                     unsafe { cast::transmute(ptr) };
                 access_shared(sharedstate, &m2, 10);
                 c.send(());
-
-            }
+            });
         }
         {
             access_shared(sharedstate, &m, 10);
@@ -816,13 +879,13 @@ fn test_mutex_lock() {
         }
 
         fn access_shared(sharedstate: &mut int, m: &Mutex, n: uint) {
-            n.times(|| {
+            for _ in range(0, n) {
                 m.lock(|| {
                     let oldval = *sharedstate;
                     task::deschedule();
                     *sharedstate = oldval + 1;
                 })
-            })
+            }
         }
     }
     #[test]
@@ -832,24 +895,24 @@ fn test_mutex_cond_wait() {
         // Child wakes up parent
         m.lock_cond(|cond| {
             let m2 = m.clone();
-            do task::spawn {
+            task::spawn(proc() {
                 m2.lock_cond(|cond| {
                     let woken = cond.signal();
                     assert!(woken);
                 })
-            }
+            });
             cond.wait();
         });
         // Parent wakes up child
         let (port,chan) = Chan::new();
         let m3 = m.clone();
-        do task::spawn {
+        task::spawn(proc() {
             m3.lock_cond(|cond| {
                 chan.send(());
                 cond.wait();
                 chan.send(());
             })
-        }
+        });
         let _ = port.recv(); // Wait until child gets in the mutex
         m.lock_cond(|cond| {
             let woken = cond.signal();
@@ -862,18 +925,18 @@ fn test_mutex_cond_broadcast_helper(num_waiters: uint) {
         let m = Mutex::new();
         let mut ports = ~[];
 
-        num_waiters.times(|| {
+        for _ in range(0, num_waiters) {
             let mi = m.clone();
             let (port, chan) = Chan::new();
             ports.push(port);
-            do task::spawn {
+            task::spawn(proc() {
                 mi.lock_cond(|cond| {
                     chan.send(());
                     cond.wait();
                     chan.send(());
                 })
-            }
-        });
+            });
+        }
 
         // wait until all children get in the mutex
         for port in ports.mut_iter() { let _ = port.recv(); }
@@ -896,9 +959,9 @@ fn test_mutex_cond_broadcast_none() {
     fn test_mutex_cond_no_waiter() {
         let m = Mutex::new();
         let m2 = m.clone();
-        do task::try {
+        task::try(proc() {
             m.lock_cond(|_x| { })
-        };
+        });
         m2.lock_cond(|cond| {
             assert!(!cond.signal());
         })
@@ -909,11 +972,11 @@ fn test_mutex_killed_simple() {
         let m = Mutex::new();
         let m2 = m.clone();
 
-        let result: result::Result<(), ~Any> = do task::try {
+        let result: result::Result<(), ~Any> = task::try(proc() {
             m2.lock(|| {
                 fail!();
             })
-        };
+        });
         assert!(result.is_err());
         // child task must have finished by the time try returns
         m.lock(|| { })
@@ -926,18 +989,18 @@ fn test_mutex_killed_cond() {
         let m = Mutex::new();
         let m2 = m.clone();
 
-        let result: result::Result<(), ~Any> = do task::try {
+        let result: result::Result<(), ~Any> = task::try(proc() {
             let (p, c) = Chan::new();
-            do task::spawn { // linked
+            task::spawn(proc() { // linked
                 let _ = p.recv(); // wait for sibling to get in the mutex
                 task::deschedule();
                 fail!();
-            }
+            });
             m2.lock_cond(|cond| {
                 c.send(()); // tell sibling go ahead
                 cond.wait(); // block forever
             })
-        };
+        });
         assert!(result.is_err());
         // child task must have finished by the time try returns
         m.lock_cond(|cond| {
@@ -954,14 +1017,14 @@ fn test_mutex_killed_broadcast() {
         let m2 = m.clone();
         let (p, c) = Chan::new();
 
-        let result: result::Result<(), ~Any> = do task::try {
+        let result: result::Result<(), ~Any> = task::try(proc() {
             let mut sibling_convos = ~[];
-            2.times(|| {
+            for _ in range(0, 2) {
                 let (p, c) = Chan::new();
                 sibling_convos.push(p);
                 let mi = m2.clone();
                 // spawn sibling task
-                do task::spawn { // linked
+                task::spawn(proc() { // linked
                     mi.lock_cond(|cond| {
                         c.send(()); // tell sibling to go ahead
                         (|| {
@@ -972,15 +1035,15 @@ fn test_mutex_killed_broadcast() {
                             error!("task unwinding and done sending");
                         })
                     })
-                }
-            });
+                });
+            }
             for p in sibling_convos.mut_iter() {
                 let _ = p.recv(); // wait for sibling to get in the mutex
             }
             m2.lock(|| { });
             c.send(sibling_convos); // let parent wait on all children
             fail!();
-        };
+        });
         assert!(result.is_err());
         // child task must have finished by the time try returns
         let mut r = p.recv();
@@ -996,52 +1059,52 @@ fn test_mutex_cond_signal_on_0() {
         let m = Mutex::new();
         m.lock_cond(|cond| {
             let m2 = m.clone();
-            do task::spawn {
+            task::spawn(proc() {
                 m2.lock_cond(|cond| {
                     cond.signal_on(0);
                 })
-            }
+            });
             cond.wait();
         })
     }
     #[test]
     #[ignore(reason = "linked failure?")]
     fn test_mutex_different_conds() {
-        let result = do task::try {
+        let result = task::try(proc() {
             let m = Mutex::new_with_condvars(2);
             let m2 = m.clone();
             let (p, c) = Chan::new();
-            do task::spawn {
+            task::spawn(proc() {
                 m2.lock_cond(|cond| {
                     c.send(());
                     cond.wait_on(1);
                 })
-            }
+            });
             let _ = p.recv();
             m.lock_cond(|cond| {
                 if !cond.signal_on(0) {
                     fail!(); // success; punt sibling awake.
                 }
             })
-        };
+        });
         assert!(result.is_err());
     }
     #[test]
     fn test_mutex_no_condvars() {
-        let result = do task::try {
+        let result = task::try(proc() {
             let m = Mutex::new_with_condvars(0);
             m.lock_cond(|cond| { cond.wait(); })
-        };
+        });
         assert!(result.is_err());
-        let result = do task::try {
+        let result = task::try(proc() {
             let m = Mutex::new_with_condvars(0);
             m.lock_cond(|cond| { cond.signal(); })
-        };
+        });
         assert!(result.is_err());
-        let result = do task::try {
+        let result = task::try(proc() {
             let m = Mutex::new_with_condvars(0);
             m.lock_cond(|cond| { cond.broadcast(); })
-        };
+        });
         assert!(result.is_err());
     }
     /************************************************************************
@@ -1076,12 +1139,12 @@ fn test_rwlock_exclusion(x: &RWLock,
         let mut sharedstate = ~0;
         {
             let ptr: *int = &*sharedstate;
-            do task::spawn {
+            task::spawn(proc() {
                 let sharedstate: &mut int =
                     unsafe { cast::transmute(ptr) };
                 access_shared(sharedstate, &x2, mode1, 10);
                 c.send(());
-            }
+            });
         }
         {
             access_shared(sharedstate, x, mode2, 10);
@@ -1092,13 +1155,13 @@ fn test_rwlock_exclusion(x: &RWLock,
 
         fn access_shared(sharedstate: &mut int, x: &RWLock, mode: RWLockMode,
                          n: uint) {
-            n.times(|| {
+            for _ in range(0, n) {
                 lock_rwlock_in_mode(x, mode, || {
                     let oldval = *sharedstate;
                     task::deschedule();
                     *sharedstate = oldval + 1;
                 })
-            })
+            }
         }
     }
     #[test]
@@ -1124,7 +1187,7 @@ fn test_rwlock_handshake(x: &RWLock,
         let x2 = x.clone();
         let (p1, c1) = Chan::new();
         let (p2, c2) = Chan::new();
-        do task::spawn {
+        task::spawn(proc() {
             if !make_mode2_go_first {
                 let _ = p2.recv(); // parent sends to us once it locks, or ...
             }
@@ -1135,7 +1198,7 @@ fn test_rwlock_handshake(x: &RWLock,
                 let _ = p2.recv();
                 c1.send(());
             })
-        }
+        });
         if make_mode2_go_first {
             let _ = p1.recv(); // child sends to us once it locks, or ...
         }
@@ -1179,24 +1242,24 @@ fn test_rwlock_cond_wait() {
         // Child wakes up parent
         x.write_cond(|cond| {
             let x2 = x.clone();
-            do task::spawn {
+            task::spawn(proc() {
                 x2.write_cond(|cond| {
                     let woken = cond.signal();
                     assert!(woken);
                 })
-            }
+            });
             cond.wait();
         });
         // Parent wakes up child
         let (port, chan) = Chan::new();
         let x3 = x.clone();
-        do task::spawn {
+        task::spawn(proc() {
             x3.write_cond(|cond| {
                 chan.send(());
                 cond.wait();
                 chan.send(());
             })
-        }
+        });
         let _ = port.recv(); // Wait until child gets in the rwlock
         x.read(|| { }); // Must be able to get in as a reader in the meantime
         x.write_cond(|cond| { // Or as another writer
@@ -1223,18 +1286,18 @@ fn lock_cond(x: &RWLock, downgrade: bool, blk: |c: &Condvar|) {
         let x = RWLock::new();
         let mut ports = ~[];
 
-        num_waiters.times(|| {
+        for _ in range(0, num_waiters) {
             let xi = x.clone();
             let (port, chan) = Chan::new();
             ports.push(port);
-            do task::spawn {
+            task::spawn(proc() {
                 lock_cond(&xi, dg1, |cond| {
                     chan.send(());
                     cond.wait();
                     chan.send(());
                 })
-            }
-        });
+            });
+        }
 
         // wait until all children get in the mutex
         for port in ports.mut_iter() { let _ = port.recv(); }
@@ -1262,11 +1325,11 @@ fn rwlock_kill_helper(mode1: RWLockMode, mode2: RWLockMode) {
         let x = RWLock::new();
         let x2 = x.clone();
 
-        let result: result::Result<(), ~Any> = do task::try || {
+        let result: result::Result<(), ~Any> = task::try(proc() {
             lock_rwlock_in_mode(&x2, mode1, || {
                 fail!();
             })
-        };
+        });
         assert!(result.is_err());
         // child task must have finished by the time try returns
         lock_rwlock_in_mode(&x, mode2, || { })
@@ -1315,4 +1378,35 @@ fn test_rwlock_downgrade_cant_swap() {
             })
         })
     }
+
+    /************************************************************************
+     * Barrier tests
+     ************************************************************************/
+    #[test]
+    fn test_barrier() {
+        let barrier = Barrier::new(10);
+        let (port, chan) = SharedChan::new();
+
+        for _ in range(0, 9) {
+            let c = barrier.clone();
+            let chan = chan.clone();
+            spawn(proc() {
+                c.wait();
+                chan.send(true);
+            });
+        }
+
+        // At this point, all spawned tasks should be blocked,
+        // so we shouldn't get anything from the port
+        assert!(match port.try_recv() {
+            Empty => true,
+            _ => false,
+        });
+
+        barrier.wait();
+        // Now, the barrier is cleared and we should get data.
+        for _ in range(0, 9) {
+            port.recv();
+        }
+    }
 }
index ba38f8762873120c69a53419375bdea054268b92..0d8cccfe2b9aec25595a2f40bb891c6337e477da 100644 (file)
@@ -86,7 +86,7 @@ fn test_task_pool() {
         g
     };
     let mut pool = TaskPool::new(4, f);
-    8.times(|| {
+    for _ in range(0, 8) {
         pool.execute(proc(i) println!("Hello from thread {}!", *i));
-    })
+    }
 }
index 1b98a9af548ae69064db118a6e76a25dc62a5e26..cd04cddba4a6937a864d7a0c4b64cdfe29e5be8d 100644 (file)
@@ -202,7 +202,8 @@ pub struct TestOpts {
     logfile: Option<Path>
 }
 
-type OptRes = Result<TestOpts, ~str>;
+/// Result of parsing the options.
+pub type OptRes = Result<TestOpts, ~str>;
 
 fn optgroups() -> ~[getopts::groups::OptGroup] {
     ~[groups::optflag("", "ignored", "Run ignored tests"),
@@ -722,7 +723,8 @@ enum TestEvent {
     TeResult(TestDesc, TestResult),
 }
 
-type MonitorMsg = (TestDesc, TestResult);
+/// The message sent to the test monitor from the individual runners.
+pub type MonitorMsg = (TestDesc, TestResult);
 
 fn run_tests(opts: &TestOpts,
              tests: ~[TestDescAndFn],
@@ -871,7 +873,7 @@ pub fn run_test(force_ignore: bool,
     fn run_test_inner(desc: TestDesc,
                       monitor_ch: SharedChan<MonitorMsg>,
                       testfn: proc()) {
-        do spawn {
+        spawn(proc() {
             let mut task = task::task();
             task.name(match desc.name {
                 DynTestName(ref name) => SendStrOwned(name.clone()),
@@ -883,7 +885,7 @@ fn run_test_inner(desc: TestDesc,
             let task_result = result_future.recv();
             let test_result = calc_result(&desc, task_result.is_ok());
             monitor_ch.send((desc.clone(), test_result));
-        }
+        });
     }
 
     match testfn {
@@ -893,7 +895,7 @@ fn run_test_inner(desc: TestDesc,
             return;
         }
         StaticBenchFn(benchfn) => {
-            let bs = ::test::bench::benchmark(benchfn);
+            let bs = ::test::bench::benchmark(|harness| benchfn(harness));
             monitor_ch.send((desc, TrBench(bs)));
             return;
         }
index 62b28074a27491f11839eccdaa47dec207517420..6605ea00c4413348558a0d5f3b04c0f4db0ffc62 100644 (file)
@@ -1150,8 +1150,8 @@ fn test_rand_int() {
 
         let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(&[42]);
 
-        3.times(|| {
-            90.times(|| {
+        for _ in range(0, 3) {
+            for _ in range(0, 90) {
                 let k = rng.gen();
                 let v = rng.gen();
                 if !ctrl.iter().any(|x| x == &(k, v)) {
@@ -1160,16 +1160,16 @@ fn test_rand_int() {
                     check_structure(&map);
                     check_equal(ctrl, &map);
                 }
-            });
+            }
 
-            30.times(|| {
+            for _ in range(0, 30) {
                 let r = rng.gen_range(0, ctrl.len());
                 let (key, _) = ctrl.remove(r).unwrap();
                 assert!(map.remove(&key));
                 check_structure(&map);
                 check_equal(ctrl, &map);
-            });
-        })
+            }
+        }
     }
 
     #[test]
index 7591f564da2b82283bd5c3ee5c3c71a7a97a3490..35c53c9307c49fdee13a7345a5cc0c64d8cd1332 100644 (file)
@@ -174,7 +174,7 @@ fn decode_inner(s: &str, full_url: bool) -> ~str {
             let mut bytes = [0, 0];
             match rdr.read(bytes) {
                 Some(2) => {}
-                _ => fail!() // XXX: malformed url?
+                _ => fail!() // FIXME: malformed url?
             }
             let ch = uint::parse_bytes(bytes, 16u).unwrap() as u8 as char;
 
@@ -308,7 +308,7 @@ pub fn decode_form_urlencoded(s: &[u8]) -> HashMap<~str, ~[~str]> {
                         let mut bytes = [0, 0];
                         match rdr.read(bytes) {
                             Some(2) => {}
-                            _ => fail!() // XXX: malformed?
+                            _ => fail!() // FIXME: malformed?
                         }
                         uint::parse_bytes(bytes, 16u).unwrap() as u8 as char
                     }
index cccca1309f4c3918581f6fc755b2dd32fad05385..70bbe02d32f1769839b08021c8a3706d45d93033 100644 (file)
@@ -413,15 +413,15 @@ fn exec_work<'a, T:Send +
                 let (port, chan) = Chan::new();
                 let blk = bo.take_unwrap();
 
-                // XXX: What happens if the task fails?
-                do spawn {
+                // FIXME: What happens if the task fails?
+                spawn(proc() {
                     let mut exe = Exec {
                         discovered_inputs: WorkMap::new(),
                         discovered_outputs: WorkMap::new(),
                     };
                     let v = blk(&mut exe);
                     chan.send((exe, v));
-                }
+                });
                 Work::from_task(self, port)
             }
         }
@@ -495,7 +495,7 @@ fn make_path(filename: ~str) -> Path {
 
         // FIXME (#9639): This needs to handle non-utf8 paths
         prep.declare_input("file", pth.as_str().unwrap(), file_content);
-        do prep.exec |_exe| {
+        prep.exec(proc(_exe) {
             let out = make_path(~"foo.o");
             // FIXME (#9639): This needs to handle non-utf8 paths
             run::process_status("gcc", [pth.as_str().unwrap().to_owned(),
@@ -507,7 +507,7 @@ fn make_path(filename: ~str) -> Path {
 
             // FIXME (#9639): This needs to handle non-utf8 paths
             out.as_str().unwrap().to_owned()
-        }
+        })
     });
 
     println!("{}", s);
diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs
new file mode 100644 (file)
index 0000000..d4a85b0
--- /dev/null
@@ -0,0 +1,133 @@
+// 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.
+
+/*!
+
+Simple compression
+
+*/
+
+#[crate_id = "flate#0.10-pre"];
+#[crate_type = "rlib"];
+#[crate_type = "dylib"];
+#[license = "MIT/ASL2"];
+#[allow(missing_doc)];
+
+use std::libc::{c_void, size_t, c_int};
+use std::libc;
+use std::vec;
+
+pub mod rustrt {
+    use std::libc::{c_int, c_void, size_t};
+
+    #[link(name = "miniz", kind = "static")]
+    extern {
+        pub fn tdefl_compress_mem_to_heap(psrc_buf: *c_void,
+                                          src_buf_len: size_t,
+                                          pout_len: *mut size_t,
+                                          flags: c_int)
+                                          -> *c_void;
+
+        pub fn tinfl_decompress_mem_to_heap(psrc_buf: *c_void,
+                                            src_buf_len: size_t,
+                                            pout_len: *mut size_t,
+                                            flags: c_int)
+                                            -> *c_void;
+    }
+}
+
+static LZ_NORM : c_int = 0x80;  // LZ with 128 probes, "normal"
+static TINFL_FLAG_PARSE_ZLIB_HEADER : c_int = 0x1; // parse zlib header and adler32 checksum
+static TDEFL_WRITE_ZLIB_HEADER : c_int = 0x01000; // write zlib header and adler32 checksum
+
+fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> ~[u8] {
+    unsafe {
+        let mut outsz : size_t = 0;
+        let res = rustrt::tdefl_compress_mem_to_heap(bytes.as_ptr() as *c_void,
+                                                     bytes.len() as size_t,
+                                                     &mut outsz,
+                                                     flags);
+        assert!(res as int != 0);
+            let out = vec::raw::from_buf_raw(res as *u8,
+                                             outsz as uint);
+        libc::free(res as *mut c_void);
+        out
+    }
+}
+
+pub fn deflate_bytes(bytes: &[u8]) -> ~[u8] {
+    deflate_bytes_internal(bytes, LZ_NORM)
+}
+
+pub fn deflate_bytes_zlib(bytes: &[u8]) -> ~[u8] {
+    deflate_bytes_internal(bytes, LZ_NORM | TDEFL_WRITE_ZLIB_HEADER)
+}
+
+fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> ~[u8] {
+    unsafe {
+        let mut outsz : size_t = 0;
+        let res = rustrt::tinfl_decompress_mem_to_heap(bytes.as_ptr() as *c_void,
+                                                       bytes.len() as size_t,
+                                                       &mut outsz,
+                                                       flags);
+        assert!(res as int != 0);
+        let out = vec::raw::from_buf_raw(res as *u8,
+                                         outsz as uint);
+        libc::free(res as *mut c_void);
+        out
+    }
+}
+
+pub fn inflate_bytes(bytes: &[u8]) -> ~[u8] {
+    inflate_bytes_internal(bytes, 0)
+}
+
+pub fn inflate_bytes_zlib(bytes: &[u8]) -> ~[u8] {
+    inflate_bytes_internal(bytes, TINFL_FLAG_PARSE_ZLIB_HEADER)
+}
+
+#[cfg(test)]
+mod tests {
+    use super::{inflate_bytes, deflate_bytes};
+    use std::rand;
+    use std::rand::Rng;
+
+    #[test]
+    fn test_flate_round_trip() {
+        let mut r = rand::rng();
+        let mut words = ~[];
+        for _ in range(0, 20) {
+            let range = r.gen_range(1u, 10);
+            words.push(r.gen_vec::<u8>(range));
+        }
+        for _ in range(0, 20) {
+            let mut input = ~[];
+            for _ in range(0, 2000) {
+                input.push_all(r.choose(words));
+            }
+            debug!("de/inflate of {} bytes of random word-sequences",
+                   input.len());
+            let cmp = deflate_bytes(input);
+            let out = inflate_bytes(cmp);
+            debug!("{} bytes deflated to {} ({:.1f}% size)",
+                   input.len(), cmp.len(),
+                   100.0 * ((cmp.len() as f64) / (input.len() as f64)));
+            assert_eq!(input, out);
+        }
+    }
+
+    #[test]
+    fn test_zlib_flate() {
+        let bytes = ~[1, 2, 3, 4, 5];
+        let deflated = deflate_bytes(bytes);
+        let inflated = inflate_bytes(deflated);
+        assert_eq!(inflated, bytes);
+    }
+}
diff --git a/src/libglob/lib.rs b/src/libglob/lib.rs
new file mode 100644 (file)
index 0000000..98bf553
--- /dev/null
@@ -0,0 +1,782 @@
+// 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.
+
+/*!
+ * Support for matching file paths against Unix shell style patterns.
+ *
+ * The `glob` and `glob_with` functions, in concert with the `Paths`
+ * type, allow querying the filesystem for all files that match a particular
+ * pattern - just like the libc `glob` function (for an example see the `glob`
+ * documentation). The methods on the `Pattern` type provide functionality
+ * for checking if individual paths match a particular pattern - in a similar
+ * manner to the libc `fnmatch` function
+ *
+ * For consistency across platforms, and for Windows support, this module
+ * is implemented entirely in Rust rather than deferring to the libc
+ * `glob`/`fnmatch` functions.
+ */
+
+#[crate_id = "glob#0.10-pre"];
+#[crate_type = "rlib"];
+#[crate_type = "dylib"];
+#[license = "MIT/ASL2"];
+
+use std::{os, path};
+use std::io;
+use std::io::fs;
+use std::path::is_sep;
+
+/**
+ * An iterator that yields Paths from the filesystem that match a particular
+ * pattern - see the `glob` function for more details.
+ */
+pub struct Paths {
+    priv root: Path,
+    priv dir_patterns: ~[Pattern],
+    priv options: MatchOptions,
+    priv todo: ~[(Path,uint)]
+}
+
+///
+/// Return an iterator that produces all the Paths that match the given pattern,
+/// which may be absolute or relative to the current working directory.
+///
+/// is method uses the default match options and is equivalent to calling
+/// `glob_with(pattern, MatchOptions::new())`. Use `glob_with` directly if you
+/// want to use non-default match options.
+///
+/// # Example
+///
+/// Consider a directory `/media/pictures` containing only the files `kittens.jpg`,
+/// `puppies.jpg` and `hamsters.gif`:
+///
+/// ```rust
+/// use glob::glob;
+///
+/// for path in glob("/media/pictures/*.jpg") {
+///     println!("{}", path.display());
+/// }
+/// ```
+///
+/// The above code will print:
+///
+/// ```
+/// /media/pictures/kittens.jpg
+/// /media/pictures/puppies.jpg
+/// ```
+///
+pub fn glob(pattern: &str) -> Paths {
+    glob_with(pattern, MatchOptions::new())
+}
+
+/**
+ * Return an iterator that produces all the Paths that match the given pattern,
+ * which may be absolute or relative to the current working directory.
+ *
+ * This function accepts Unix shell style patterns as described by `Pattern::new(..)`.
+ * The options given are passed through unchanged to `Pattern::matches_with(..)` with
+ * the exception that `require_literal_separator` is always set to `true` regardless of the
+ * value passed to this function.
+ *
+ * Paths are yielded in alphabetical order, as absolute paths.
+ */
+pub fn glob_with(pattern: &str, options: MatchOptions) -> Paths {
+    #[cfg(windows)]
+    fn check_windows_verbatim(p: &Path) -> bool { path::windows::is_verbatim(p) }
+    #[cfg(not(windows))]
+    fn check_windows_verbatim(_: &Path) -> bool { false }
+
+    // calculate root this way to handle volume-relative Windows paths correctly
+    let mut root = os::getcwd();
+    let pat_root = Path::new(pattern).root_path();
+    if pat_root.is_some() {
+        if check_windows_verbatim(pat_root.get_ref()) {
+            // FIXME: How do we want to handle verbatim paths? I'm inclined to return nothing,
+            // since we can't very well find all UNC shares with a 1-letter server name.
+            return Paths { root: root, dir_patterns: ~[], options: options, todo: ~[] };
+        }
+        root.push(pat_root.get_ref());
+    }
+
+    let root_len = pat_root.map_or(0u, |p| p.as_vec().len());
+    let dir_patterns = pattern.slice_from(root_len.min(&pattern.len()))
+                       .split_terminator(is_sep).map(|s| Pattern::new(s)).to_owned_vec();
+
+    let todo = list_dir_sorted(&root).move_iter().map(|x|(x,0u)).to_owned_vec();
+
+    Paths {
+        root: root,
+        dir_patterns: dir_patterns,
+        options: options,
+        todo: todo,
+    }
+}
+
+impl Iterator<Path> for Paths {
+
+    fn next(&mut self) -> Option<Path> {
+        loop {
+            if self.dir_patterns.is_empty() || self.todo.is_empty() {
+                return None;
+            }
+
+            let (path,idx) = self.todo.pop().unwrap();
+            let ref pattern = self.dir_patterns[idx];
+
+            if pattern.matches_with(match path.filename_str() {
+                // this ugly match needs to go here to avoid a borrowck error
+                None => {
+                    // FIXME (#9639): How do we handle non-utf8 filenames? Ignore them for now
+                    // Ideally we'd still match them against a *
+                    continue;
+                }
+                Some(x) => x
+            }, self.options) {
+                if idx == self.dir_patterns.len() - 1 {
+                    // it is not possible for a pattern to match a directory *AND* its children
+                    // so we don't need to check the children
+                    return Some(path);
+                } else {
+                    self.todo.extend(&mut list_dir_sorted(&path).move_iter().map(|x|(x,idx+1)));
+                }
+            }
+        }
+    }
+
+}
+
+fn list_dir_sorted(path: &Path) -> ~[Path] {
+    match io::result(|| fs::readdir(path)) {
+        Ok(mut children) => {
+            children.sort_by(|p1, p2| p2.filename().cmp(&p1.filename()));
+            children
+        }
+        Err(..) => ~[]
+    }
+}
+
+/**
+ * A compiled Unix shell style pattern.
+ */
+#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes, Default)]
+pub struct Pattern {
+    priv tokens: ~[PatternToken]
+}
+
+#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes)]
+enum PatternToken {
+    Char(char),
+    AnyChar,
+    AnySequence,
+    AnyWithin(~[CharSpecifier]),
+    AnyExcept(~[CharSpecifier])
+}
+
+#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes)]
+enum CharSpecifier {
+    SingleChar(char),
+    CharRange(char, char)
+}
+
+#[deriving(Eq)]
+enum MatchResult {
+    Match,
+    SubPatternDoesntMatch,
+    EntirePatternDoesntMatch
+}
+
+impl Pattern {
+
+    /**
+     * This function compiles Unix shell style patterns: `?` matches any single
+     * character, `*` matches any (possibly empty) sequence of characters and
+     * `[...]` matches any character inside the brackets, unless the first
+     * character is `!` in which case it matches any character except those
+     * between the `!` and the `]`. Character sequences can also specify ranges
+     * of characters, as ordered by Unicode, so e.g. `[0-9]` specifies any
+     * character between 0 and 9 inclusive.
+     *
+     * The metacharacters `?`, `*`, `[`, `]` can be matched by using brackets
+     * (e.g. `[?]`).  When a `]` occurs immediately following `[` or `[!` then
+     * it is interpreted as being part of, rather then ending, the character
+     * set, so `]` and NOT `]` can be matched by `[]]` and `[!]]` respectively.
+     * The `-` character can be specified inside a character sequence pattern by
+     * placing it at the start or the end, e.g. `[abc-]`.
+     *
+     * When a `[` does not have a closing `]` before the end of the string then
+     * the `[` will be treated literally.
+     */
+    pub fn new(pattern: &str) -> Pattern {
+
+        let chars = pattern.chars().to_owned_vec();
+        let mut tokens = ~[];
+        let mut i = 0;
+
+        while i < chars.len() {
+            match chars[i] {
+                '?' => {
+                    tokens.push(AnyChar);
+                    i += 1;
+                }
+                '*' => {
+                    // *, **, ***, ****, ... are all equivalent
+                    while i < chars.len() && chars[i] == '*' {
+                        i += 1;
+                    }
+                    tokens.push(AnySequence);
+                }
+                '[' => {
+
+                    if i <= chars.len() - 4 && chars[i + 1] == '!' {
+                        match chars.slice_from(i + 3).position_elem(&']') {
+                            None => (),
+                            Some(j) => {
+                                let chars = chars.slice(i + 2, i + 3 + j);
+                                let cs = parse_char_specifiers(chars);
+                                tokens.push(AnyExcept(cs));
+                                i += j + 4;
+                                continue;
+                            }
+                        }
+                    }
+                    else if i <= chars.len() - 3 && chars[i + 1] != '!' {
+                        match chars.slice_from(i + 2).position_elem(&']') {
+                            None => (),
+                            Some(j) => {
+                                let cs = parse_char_specifiers(chars.slice(i + 1, i + 2 + j));
+                                tokens.push(AnyWithin(cs));
+                                i += j + 3;
+                                continue;
+                            }
+                        }
+                    }
+
+                    // if we get here then this is not a valid range pattern
+                    tokens.push(Char('['));
+                    i += 1;
+                }
+                c => {
+                    tokens.push(Char(c));
+                    i += 1;
+                }
+            }
+        }
+
+        Pattern { tokens: tokens }
+    }
+
+    /**
+     * Escape metacharacters within the given string by surrounding them in
+     * brackets. The resulting string will, when compiled into a `Pattern`,
+     * match the input string and nothing else.
+     */
+    pub fn escape(s: &str) -> ~str {
+        let mut escaped = ~"";
+        for c in s.chars() {
+            match c {
+                // note that ! does not need escaping because it is only special inside brackets
+                '?' | '*' | '[' | ']' => {
+                    escaped.push_char('[');
+                    escaped.push_char(c);
+                    escaped.push_char(']');
+                }
+                c => {
+                    escaped.push_char(c);
+                }
+            }
+        }
+        escaped
+    }
+
+    /**
+     * Return if the given `str` matches this `Pattern` using the default
+     * match options (i.e. `MatchOptions::new()`).
+     *
+     * # Example
+     *
+     * ```rust
+     * use glob::Pattern;
+     *
+     * assert!(Pattern::new("c?t").matches("cat"));
+     * assert!(Pattern::new("k[!e]tteh").matches("kitteh"));
+     * assert!(Pattern::new("d*g").matches("doog"));
+     * ```
+     */
+    pub fn matches(&self, str: &str) -> bool {
+        self.matches_with(str, MatchOptions::new())
+    }
+
+    /**
+     * Return if the given `Path`, when converted to a `str`, matches this `Pattern`
+     * using the default match options (i.e. `MatchOptions::new()`).
+     */
+    pub fn matches_path(&self, path: &Path) -> bool {
+        // FIXME (#9639): This needs to handle non-utf8 paths
+        path.as_str().map_or(false, |s| {
+            self.matches(s)
+        })
+    }
+
+    /**
+     * Return if the given `str` matches this `Pattern` using the specified match options.
+     */
+    pub fn matches_with(&self, str: &str, options: MatchOptions) -> bool {
+        self.matches_from(None, str, 0, options) == Match
+    }
+
+    /**
+     * Return if the given `Path`, when converted to a `str`, matches this `Pattern`
+     * using the specified match options.
+     */
+    pub fn matches_path_with(&self, path: &Path, options: MatchOptions) -> bool {
+        // FIXME (#9639): This needs to handle non-utf8 paths
+        path.as_str().map_or(false, |s| {
+            self.matches_with(s, options)
+        })
+    }
+
+    fn matches_from(&self,
+                    mut prev_char: Option<char>,
+                    mut file: &str,
+                    i: uint,
+                    options: MatchOptions) -> MatchResult {
+
+        let require_literal = |c| {
+            (options.require_literal_separator && is_sep(c)) ||
+            (options.require_literal_leading_dot && c == '.'
+             && is_sep(prev_char.unwrap_or('/')))
+        };
+
+        for (ti, token) in self.tokens.slice_from(i).iter().enumerate() {
+            match *token {
+                AnySequence => {
+                    loop {
+                        match self.matches_from(prev_char, file, i + ti + 1, options) {
+                            SubPatternDoesntMatch => (), // keep trying
+                            m => return m,
+                        }
+
+                        if file.is_empty() {
+                            return EntirePatternDoesntMatch;
+                        }
+
+                        let (c, next) = file.slice_shift_char();
+                        if require_literal(c) {
+                            return SubPatternDoesntMatch;
+                        }
+                        prev_char = Some(c);
+                        file = next;
+                    }
+                }
+                _ => {
+                    if file.is_empty() {
+                        return EntirePatternDoesntMatch;
+                    }
+
+                    let (c, next) = file.slice_shift_char();
+                    let matches = match *token {
+                        AnyChar => {
+                            !require_literal(c)
+                        }
+                        AnyWithin(ref specifiers) => {
+                            !require_literal(c) && in_char_specifiers(*specifiers, c, options)
+                        }
+                        AnyExcept(ref specifiers) => {
+                            !require_literal(c) && !in_char_specifiers(*specifiers, c, options)
+                        }
+                        Char(c2) => {
+                            chars_eq(c, c2, options.case_sensitive)
+                        }
+                        AnySequence => {
+                            unreachable!()
+                        }
+                    };
+                    if !matches {
+                        return SubPatternDoesntMatch;
+                    }
+                    prev_char = Some(c);
+                    file = next;
+                }
+            }
+        }
+
+        if file.is_empty() {
+            Match
+        } else {
+            SubPatternDoesntMatch
+        }
+    }
+
+}
+
+fn parse_char_specifiers(s: &[char]) -> ~[CharSpecifier] {
+    let mut cs = ~[];
+    let mut i = 0;
+    while i < s.len() {
+        if i + 3 <= s.len() && s[i + 1] == '-' {
+            cs.push(CharRange(s[i], s[i + 2]));
+            i += 3;
+        } else {
+            cs.push(SingleChar(s[i]));
+            i += 1;
+        }
+    }
+    cs
+}
+
+fn in_char_specifiers(specifiers: &[CharSpecifier], c: char, options: MatchOptions) -> bool {
+
+    for &specifier in specifiers.iter() {
+        match specifier {
+            SingleChar(sc) => {
+                if chars_eq(c, sc, options.case_sensitive) {
+                    return true;
+                }
+            }
+            CharRange(start, end) => {
+
+                // FIXME: work with non-ascii chars properly (issue #1347)
+                if !options.case_sensitive && c.is_ascii() && start.is_ascii() && end.is_ascii() {
+
+                    let start = start.to_ascii().to_lower();
+                    let end = end.to_ascii().to_lower();
+
+                    let start_up = start.to_upper();
+                    let end_up = end.to_upper();
+
+                    // only allow case insensitive matching when
+                    // both start and end are within a-z or A-Z
+                    if start != start_up && end != end_up {
+                        let start = start.to_char();
+                        let end = end.to_char();
+                        let c = c.to_ascii().to_lower().to_char();
+                        if c >= start && c <= end {
+                            return true;
+                        }
+                    }
+                }
+
+                if c >= start && c <= end {
+                    return true;
+                }
+            }
+        }
+    }
+
+    false
+}
+
+/// A helper function to determine if two chars are (possibly case-insensitively) equal.
+fn chars_eq(a: char, b: char, case_sensitive: bool) -> bool {
+    if cfg!(windows) && path::windows::is_sep(a) && path::windows::is_sep(b) {
+        true
+    } else if !case_sensitive && a.is_ascii() && b.is_ascii() {
+        // FIXME: work with non-ascii chars properly (issue #1347)
+        a.to_ascii().eq_ignore_case(b.to_ascii())
+    } else {
+        a == b
+    }
+}
+
+/**
+ * Configuration options to modify the behaviour of `Pattern::matches_with(..)`
+ */
+#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes, Default)]
+pub struct MatchOptions {
+
+    /**
+     * Whether or not patterns should be matched in a case-sensitive manner. This
+     * currently only considers upper/lower case relationships between ASCII characters,
+     * but in future this might be extended to work with Unicode.
+     */
+    priv case_sensitive: bool,
+
+    /**
+     * If this is true then path-component separator characters (e.g. `/` on Posix)
+     * must be matched by a literal `/`, rather than by `*` or `?` or `[...]`
+     */
+    priv require_literal_separator: bool,
+
+    /**
+     * If this is true then paths that contain components that start with a `.` will
+     * not match unless the `.` appears literally in the pattern: `*`, `?` or `[...]`
+     * will not match. This is useful because such files are conventionally considered
+     * hidden on Unix systems and it might be desirable to skip them when listing files.
+     */
+    priv require_literal_leading_dot: bool
+}
+
+impl MatchOptions {
+
+    /**
+     * Constructs a new `MatchOptions` with default field values. This is used
+     * when calling functions that do not take an explicit `MatchOptions` parameter.
+     *
+     * This function always returns this value:
+     *
+     * ```rust,ignore
+     * MatchOptions {
+     *     case_sensitive: true,
+     *     require_literal_separator: false.
+     *     require_literal_leading_dot: false
+     * }
+     * ```
+     */
+    pub fn new() -> MatchOptions {
+        MatchOptions {
+            case_sensitive: true,
+            require_literal_separator: false,
+            require_literal_leading_dot: false
+        }
+    }
+
+}
+
+#[cfg(test)]
+mod test {
+    use std::os;
+    use super::{glob, Pattern, MatchOptions};
+
+    #[test]
+    fn test_absolute_pattern() {
+        // assume that the filesystem is not empty!
+        assert!(glob("/*").next().is_some());
+        assert!(glob("//").next().is_none());
+
+        // check windows absolute paths with host/device components
+        let root_with_device = os::getcwd().root_path().unwrap().join("*");
+        // FIXME (#9639): This needs to handle non-utf8 paths
+        assert!(glob(root_with_device.as_str().unwrap()).next().is_some());
+    }
+
+    #[test]
+    fn test_wildcard_optimizations() {
+        assert!(Pattern::new("a*b").matches("a___b"));
+        assert!(Pattern::new("a**b").matches("a___b"));
+        assert!(Pattern::new("a***b").matches("a___b"));
+        assert!(Pattern::new("a*b*c").matches("abc"));
+        assert!(!Pattern::new("a*b*c").matches("abcd"));
+        assert!(Pattern::new("a*b*c").matches("a_b_c"));
+        assert!(Pattern::new("a*b*c").matches("a___b___c"));
+        assert!(Pattern::new("abc*abc*abc").matches("abcabcabcabcabcabcabc"));
+        assert!(!Pattern::new("abc*abc*abc").matches("abcabcabcabcabcabcabca"));
+        assert!(Pattern::new("a*a*a*a*a*a*a*a*a").matches("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
+        assert!(Pattern::new("a*b[xyz]c*d").matches("abxcdbxcddd"));
+    }
+
+    #[test]
+    fn test_lots_of_files() {
+        // this is a good test because it touches lots of differently named files
+        glob("/*/*/*/*").skip(10000).next();
+    }
+
+    #[test]
+    fn test_range_pattern() {
+
+        let pat = Pattern::new("a[0-9]b");
+        for i in range(0, 10) {
+            assert!(pat.matches(format!("a{}b", i)));
+        }
+        assert!(!pat.matches("a_b"));
+
+        let pat = Pattern::new("a[!0-9]b");
+        for i in range(0, 10) {
+            assert!(!pat.matches(format!("a{}b", i)));
+        }
+        assert!(pat.matches("a_b"));
+
+        let pats = ["[a-z123]", "[1a-z23]", "[123a-z]"];
+        for &p in pats.iter() {
+            let pat = Pattern::new(p);
+            for c in "abcdefghijklmnopqrstuvwxyz".chars() {
+                assert!(pat.matches(c.to_str()));
+            }
+            for c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ".chars() {
+                let options = MatchOptions {case_sensitive: false, .. MatchOptions::new()};
+                assert!(pat.matches_with(c.to_str(), options));
+            }
+            assert!(pat.matches("1"));
+            assert!(pat.matches("2"));
+            assert!(pat.matches("3"));
+        }
+
+        let pats = ["[abc-]", "[-abc]", "[a-c-]"];
+        for &p in pats.iter() {
+            let pat = Pattern::new(p);
+            assert!(pat.matches("a"));
+            assert!(pat.matches("b"));
+            assert!(pat.matches("c"));
+            assert!(pat.matches("-"));
+            assert!(!pat.matches("d"));
+        }
+
+        let pat = Pattern::new("[2-1]");
+        assert!(!pat.matches("1"));
+        assert!(!pat.matches("2"));
+
+        assert!(Pattern::new("[-]").matches("-"));
+        assert!(!Pattern::new("[!-]").matches("-"));
+    }
+
+    #[test]
+    fn test_unclosed_bracket() {
+        // unclosed `[` should be treated literally
+        assert!(Pattern::new("abc[def").matches("abc[def"));
+        assert!(Pattern::new("abc[!def").matches("abc[!def"));
+        assert!(Pattern::new("abc[").matches("abc["));
+        assert!(Pattern::new("abc[!").matches("abc[!"));
+        assert!(Pattern::new("abc[d").matches("abc[d"));
+        assert!(Pattern::new("abc[!d").matches("abc[!d"));
+        assert!(Pattern::new("abc[]").matches("abc[]"));
+        assert!(Pattern::new("abc[!]").matches("abc[!]"));
+    }
+
+    #[test]
+    fn test_pattern_matches() {
+        let txt_pat = Pattern::new("*hello.txt");
+        assert!(txt_pat.matches("hello.txt"));
+        assert!(txt_pat.matches("gareth_says_hello.txt"));
+        assert!(txt_pat.matches("some/path/to/hello.txt"));
+        assert!(txt_pat.matches("some\\path\\to\\hello.txt"));
+        assert!(txt_pat.matches("/an/absolute/path/to/hello.txt"));
+        assert!(!txt_pat.matches("hello.txt-and-then-some"));
+        assert!(!txt_pat.matches("goodbye.txt"));
+
+        let dir_pat = Pattern::new("*some/path/to/hello.txt");
+        assert!(dir_pat.matches("some/path/to/hello.txt"));
+        assert!(dir_pat.matches("a/bigger/some/path/to/hello.txt"));
+        assert!(!dir_pat.matches("some/path/to/hello.txt-and-then-some"));
+        assert!(!dir_pat.matches("some/other/path/to/hello.txt"));
+    }
+
+    #[test]
+    fn test_pattern_escape() {
+        let s = "_[_]_?_*_!_";
+        assert_eq!(Pattern::escape(s), ~"_[[]_[]]_[?]_[*]_!_");
+        assert!(Pattern::new(Pattern::escape(s)).matches(s));
+    }
+
+    #[test]
+    fn test_pattern_matches_case_insensitive() {
+
+        let pat = Pattern::new("aBcDeFg");
+        let options = MatchOptions {
+            case_sensitive: false,
+            require_literal_separator: false,
+            require_literal_leading_dot: false
+        };
+
+        assert!(pat.matches_with("aBcDeFg", options));
+        assert!(pat.matches_with("abcdefg", options));
+        assert!(pat.matches_with("ABCDEFG", options));
+        assert!(pat.matches_with("AbCdEfG", options));
+    }
+
+    #[test]
+    fn test_pattern_matches_case_insensitive_range() {
+
+        let pat_within = Pattern::new("[a]");
+        let pat_except = Pattern::new("[!a]");
+
+        let options_case_insensitive = MatchOptions {
+            case_sensitive: false,
+            require_literal_separator: false,
+            require_literal_leading_dot: false
+        };
+        let options_case_sensitive = MatchOptions {
+            case_sensitive: true,
+            require_literal_separator: false,
+            require_literal_leading_dot: false
+        };
+
+        assert!(pat_within.matches_with("a", options_case_insensitive));
+        assert!(pat_within.matches_with("A", options_case_insensitive));
+        assert!(!pat_within.matches_with("A", options_case_sensitive));
+
+        assert!(!pat_except.matches_with("a", options_case_insensitive));
+        assert!(!pat_except.matches_with("A", options_case_insensitive));
+        assert!(pat_except.matches_with("A", options_case_sensitive));
+    }
+
+    #[test]
+    fn test_pattern_matches_require_literal_separator() {
+
+        let options_require_literal = MatchOptions {
+            case_sensitive: true,
+            require_literal_separator: true,
+            require_literal_leading_dot: false
+        };
+        let options_not_require_literal = MatchOptions {
+            case_sensitive: true,
+            require_literal_separator: false,
+            require_literal_leading_dot: false
+        };
+
+        assert!(Pattern::new("abc/def").matches_with("abc/def", options_require_literal));
+        assert!(!Pattern::new("abc?def").matches_with("abc/def", options_require_literal));
+        assert!(!Pattern::new("abc*def").matches_with("abc/def", options_require_literal));
+        assert!(!Pattern::new("abc[/]def").matches_with("abc/def", options_require_literal));
+
+        assert!(Pattern::new("abc/def").matches_with("abc/def", options_not_require_literal));
+        assert!(Pattern::new("abc?def").matches_with("abc/def", options_not_require_literal));
+        assert!(Pattern::new("abc*def").matches_with("abc/def", options_not_require_literal));
+        assert!(Pattern::new("abc[/]def").matches_with("abc/def", options_not_require_literal));
+    }
+
+    #[test]
+    fn test_pattern_matches_require_literal_leading_dot() {
+
+        let options_require_literal_leading_dot = MatchOptions {
+            case_sensitive: true,
+            require_literal_separator: false,
+            require_literal_leading_dot: true
+        };
+        let options_not_require_literal_leading_dot = MatchOptions {
+            case_sensitive: true,
+            require_literal_separator: false,
+            require_literal_leading_dot: false
+        };
+
+        let f = |options| Pattern::new("*.txt").matches_with(".hello.txt", options);
+        assert!(f(options_not_require_literal_leading_dot));
+        assert!(!f(options_require_literal_leading_dot));
+
+        let f = |options| Pattern::new(".*.*").matches_with(".hello.txt", options);
+        assert!(f(options_not_require_literal_leading_dot));
+        assert!(f(options_require_literal_leading_dot));
+
+        let f = |options| Pattern::new("aaa/bbb/*").matches_with("aaa/bbb/.ccc", options);
+        assert!(f(options_not_require_literal_leading_dot));
+        assert!(!f(options_require_literal_leading_dot));
+
+        let f = |options| Pattern::new("aaa/bbb/*").matches_with("aaa/bbb/c.c.c.", options);
+        assert!(f(options_not_require_literal_leading_dot));
+        assert!(f(options_require_literal_leading_dot));
+
+        let f = |options| Pattern::new("aaa/bbb/.*").matches_with("aaa/bbb/.ccc", options);
+        assert!(f(options_not_require_literal_leading_dot));
+        assert!(f(options_require_literal_leading_dot));
+
+        let f = |options| Pattern::new("aaa/?bbb").matches_with("aaa/.bbb", options);
+        assert!(f(options_not_require_literal_leading_dot));
+        assert!(!f(options_require_literal_leading_dot));
+
+        let f = |options| Pattern::new("aaa/[.]bbb").matches_with("aaa/.bbb", options);
+        assert!(f(options_not_require_literal_leading_dot));
+        assert!(!f(options_require_literal_leading_dot));
+    }
+
+    #[test]
+    fn test_matches_path() {
+        // on windows, (Path::new("a/b").as_str().unwrap() == "a\\b"), so this
+        // tests that / and \ are considered equivalent on windows
+        assert!(Pattern::new("a/b").matches_path(&Path::new("a/b")));
+    }
+}
index ef96f55451558759710a9ba6d89bef73cb0d7827..89c3398ab62d029795e5e658452cb076b12f6171 100644 (file)
@@ -139,7 +139,7 @@ fn callback(&mut self, f: proc()) {
         self.work.push(f);
     }
 
-    // XXX: Seems like a really weird requirement to have an event loop provide.
+    // FIXME: Seems like a really weird requirement to have an event loop provide.
     fn pausable_idle_callback(&mut self, cb: ~Callback) -> ~PausableIdleCallback {
         let callback = ~BasicPausable::new(self, cb);
         rtassert!(self.idle.is_none());
@@ -247,18 +247,18 @@ fn run(f: proc()) {
 
     #[test]
     fn smoke() {
-        do run {}
+        run(proc() {});
     }
 
     #[test]
     fn some_channels() {
-        do run {
+        run(proc() {
             let (p, c) = Chan::new();
-            do spawn {
+            spawn(proc() {
                 c.send(());
-            }
+            });
             p.recv();
-        }
+        });
     }
 
     #[test]
@@ -269,13 +269,13 @@ fn multi_thread() {
         });
 
         for _ in range(0, 20) {
-            do pool.spawn(TaskOpts::new()) {
+            pool.spawn(TaskOpts::new(), proc() {
                 let (p, c) = Chan::new();
-                do spawn {
+                spawn(proc() {
                     c.send(());
-                }
+                });
                 p.recv();
-            }
+            });
         }
 
         pool.shutdown();
index 8530e3e837ea811c4857aa87a2486be16b619871..4e626b3bec77800dbc8f06d188b80759d2b540ca 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
 use std::uint;
 use std::cast::{transmute, transmute_mut_unsafe,
                 transmute_region, transmute_mut_region};
+use stack::Stack;
 use std::unstable::stack;
 
-use stack::StackSegment;
-
 // FIXME #7761: Registers is boxed so that it is 16-byte aligned, for storing
 // SSE regs.  It would be marginally better not to do this. In C++ we
 // use an attribute on a struct.
@@ -41,7 +40,7 @@ pub fn empty() -> Context {
     }
 
     /// Create a new context that will resume execution by running proc()
-    pub fn new(start: proc(), stack: &mut StackSegment) -> Context {
+    pub fn new(start: proc(), stack: &mut Stack) -> Context {
         // The C-ABI function that is the task entry point
         //
         // Note that this function is a little sketchy. We're taking a
@@ -79,6 +78,7 @@ pub fn new(start: proc(), stack: &mut StackSegment) -> Context {
         // be passed to the spawn function.  Another unfortunate
         // allocation
         let start = ~start;
+
         initialize_call_frame(&mut *regs,
                               task_start_wrapper as *c_void,
                               unsafe { transmute(&*start) },
@@ -131,7 +131,7 @@ pub fn swap(out_context: &mut Context, in_context: &Context) {
                 // 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
-                None => stack::record_stack_bounds(0, uint::max_value),
+                None => stack::record_stack_bounds(0, uint::MAX),
             }
             rust_swap_registers(out_regs, in_regs)
         }
index 7bc5d0accfe3b2aae28920ce046a21266d5ca88f..c001d40a2465dccb08d65b1e04c370a5afc1edc4 100644 (file)
@@ -14,7 +14,7 @@
 use std::rt::env;
 
 use context::Context;
-use stack::{StackPool, StackSegment};
+use stack::{StackPool, Stack};
 
 /// A coroutine is nothing more than a (register context, stack) pair.
 pub struct Coroutine {
@@ -24,7 +24,7 @@ pub struct Coroutine {
     ///
     /// Servo needs this to be public in order to tell SpiderMonkey
     /// about the stack bounds.
-    current_stack_segment: StackSegment,
+    current_stack_segment: Stack,
 
     /// Always valid if the task is alive and not running.
     saved_context: Context
@@ -39,7 +39,7 @@ pub fn new(stack_pool: &mut StackPool,
             Some(size) => size,
             None => env::min_stack()
         };
-        let mut stack = stack_pool.take_segment(stack_size);
+        let mut stack = stack_pool.take_stack(stack_size);
         let initial_context = Context::new(start, &mut stack);
         Coroutine {
             current_stack_segment: stack,
@@ -49,7 +49,7 @@ pub fn new(stack_pool: &mut StackPool,
 
     pub fn empty() -> Coroutine {
         Coroutine {
-            current_stack_segment: StackSegment::new(0),
+            current_stack_segment: unsafe { Stack::dummy_stack() },
             saved_context: Context::empty()
         }
     }
@@ -57,6 +57,6 @@ pub fn empty() -> Coroutine {
     /// Destroy coroutine and try to reuse std::stack segment.
     pub fn recycle(self, stack_pool: &mut StackPool) {
         let Coroutine { current_stack_segment, .. } = self;
-        stack_pool.give_segment(current_stack_segment);
+        stack_pool.give_stack(current_stack_segment);
     }
 }
index d746d5012c4314b4a012b40e4598c12c2c80f7e7..f8d629589fc3c5f2a1d33b2cf062f57059ee455d 100644 (file)
 #[cfg(not(test))]
 pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int {
     use std::cast;
-    do start(argc, argv) {
+    start(argc, argv, proc() {
         let main: extern "Rust" fn() = unsafe { cast::transmute(main) };
         main();
-    }
+    })
 }
 
 /// Set up a default runtime configuration, given compiler-supplied arguments.
@@ -222,7 +222,7 @@ pub fn new(config: PoolConfig) -> SchedPool {
                                             pool.task_state.clone());
             pool.handles.push(sched.make_handle());
             let sched = sched;
-            pool.threads.push(do Thread::start { sched.bootstrap(); });
+            pool.threads.push(Thread::start(proc() { sched.bootstrap(); }));
         }
 
         return pool;
@@ -284,7 +284,7 @@ pub fn spawn_sched(&mut self) -> SchedHandle {
         let ret = sched.make_handle();
         self.handles.push(sched.make_handle());
         let sched = sched;
-        self.threads.push(do Thread::start { sched.bootstrap() });
+        self.threads.push(Thread::start(proc() { sched.bootstrap() }));
 
         return ret;
     }
index 12def918bc9e248ef4acaee0a667a9e14c6cc4f0..e07cc1ca00088951cd9c6cb50e1d7957128d5cc4 100644 (file)
@@ -8,14 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// XXX: this file probably shouldn't exist
+// FIXME: this file probably shouldn't exist
 
 #[macro_escape];
 
 use std::fmt;
 
 // Indicates whether we should perform expensive sanity checks, including rtassert!
-// XXX: Once the runtime matures remove the `true` below to turn off rtassert, etc.
+// FIXME: Once the runtime matures remove the `true` below to turn off rtassert, etc.
 pub static ENFORCE_SANITY: bool = true || !cfg!(rtopt) || cfg!(rtdebug) || cfg!(rtassert);
 
 macro_rules! rterrln (
index 989b8dc31f8a8d584f8e1a489eabb866cb78f6a0..a8071dd82eb9ba33a8a3626d9b9f881716d2379c 100644 (file)
@@ -32,7 +32,7 @@
 /// struct. The scheduler struct acts like a baton, all scheduling
 /// actions are transfers of the baton.
 ///
-/// XXX: This creates too many callbacks to run_sched_once, resulting
+/// FIXME: This creates too many callbacks to run_sched_once, resulting
 /// in too much allocation and too many events.
 pub struct Scheduler {
     /// ID number of the pool that this scheduler is a member of. When
@@ -171,7 +171,7 @@ pub fn new_special(pool_id: uint,
         return sched;
     }
 
-    // XXX: This may eventually need to be refactored so that
+    // FIXME: This may eventually need to be refactored so that
     // the scheduler itself doesn't have to call event_loop.run.
     // That will be important for embedding the runtime into external
     // event loops.
@@ -898,7 +898,7 @@ pub fn run(self, sched: &mut Scheduler) {
     }
 }
 
-// XXX: Some hacks to put a || closure in Scheduler without borrowck
+// FIXME: Some hacks to put a || closure in Scheduler without borrowck
 // complaining
 type UnsafeTaskReceiver = raw::Closure;
 trait ClosureConverter {
@@ -998,10 +998,10 @@ fn sched_id() -> uint {
     fn trivial_run_in_newsched_task_test() {
         let mut task_ran = false;
         let task_ran_ptr: *mut bool = &mut task_ran;
-        do run {
+        run(proc() {
             unsafe { *task_ran_ptr = true };
             rtdebug!("executed from the new scheduler")
-        }
+        });
         assert!(task_ran);
     }
 
@@ -1012,13 +1012,13 @@ fn multiple_task_test() {
         let task_run_count_ptr: *mut uint = &mut task_run_count;
         // with only one thread this is safe to run in without worries of
         // contention.
-        do run {
+        run(proc() {
             for _ in range(0u, total) {
-                do spawn || {
+                spawn(proc() {
                     unsafe { *task_run_count_ptr = *task_run_count_ptr + 1};
-                }
+                });
             }
-        }
+        });
         assert!(task_run_count == total);
     }
 
@@ -1026,17 +1026,17 @@ fn multiple_task_test() {
     fn multiple_task_nested_test() {
         let mut task_run_count = 0;
         let task_run_count_ptr: *mut uint = &mut task_run_count;
-        do run {
-            do spawn {
+        run(proc() {
+            spawn(proc() {
                 unsafe { *task_run_count_ptr = *task_run_count_ptr + 1 };
-                do spawn {
+                spawn(proc() {
                     unsafe { *task_run_count_ptr = *task_run_count_ptr + 1 };
-                    do spawn {
+                    spawn(proc() {
                         unsafe { *task_run_count_ptr = *task_run_count_ptr + 1 };
-                    }
-                }
-            }
-        }
+                    })
+                })
+            })
+        });
         assert!(task_run_count == 3);
     }
 
@@ -1052,15 +1052,15 @@ fn test_home_sched() {
             let mut handle1 = pool.spawn_sched();
             let mut handle2 = pool.spawn_sched();
 
-            handle1.send(TaskFromFriend(do pool.task(TaskOpts::new()) {
+            handle1.send(TaskFromFriend(pool.task(TaskOpts::new(), proc() {
                 chan.send(sched_id());
-            }));
+            })));
             let sched1_id = port.recv();
 
-            let mut task = do pool.task(TaskOpts::new()) {
+            let mut task = pool.task(TaskOpts::new(), proc() {
                 assert_eq!(sched_id(), sched1_id);
                 dchan.send(());
-            };
+            });
             task.give_home(HomeSched(handle1));
             handle2.send(TaskFromFriend(task));
         }
@@ -1080,7 +1080,7 @@ fn test_schedule_home_states() {
         use std::rt::thread::Thread;
         use std::sync::deque::BufferPool;
 
-        do run_in_bare_thread {
+        run_in_bare_thread(proc() {
             let sleepers = SleeperList::new();
             let mut pool = BufferPool::new();
             let (normal_worker, normal_stealer) = pool.deque();
@@ -1146,23 +1146,23 @@ fn on_appropriate_sched() -> bool {
                 ret
             }
 
-            let task1 = do GreenTask::new_homed(&mut special_sched.stack_pool,
-                                                None, HomeSched(t1_handle)) {
+            let task1 = GreenTask::new_homed(&mut special_sched.stack_pool,
+                                             None, HomeSched(t1_handle), proc() {
                 rtassert!(on_appropriate_sched());
-            };
+            });
 
-            let task2 = do GreenTask::new(&mut normal_sched.stack_pool, None) {
+            let task2 = GreenTask::new(&mut normal_sched.stack_pool, None, proc() {
                 rtassert!(on_appropriate_sched());
-            };
+            });
 
-            let task3 = do GreenTask::new(&mut normal_sched.stack_pool, None) {
+            let task3 = GreenTask::new(&mut normal_sched.stack_pool, None, proc() {
                 rtassert!(on_appropriate_sched());
-            };
+            });
 
-            let task4 = do GreenTask::new_homed(&mut special_sched.stack_pool,
-                                                None, HomeSched(t4_handle)) {
+            let task4 = GreenTask::new_homed(&mut special_sched.stack_pool,
+                                             None, HomeSched(t4_handle), proc() {
                 rtassert!(on_appropriate_sched());
-            };
+            });
 
             // Signal from the special task that we are done.
             let (port, chan) = Chan::<()>::new();
@@ -1173,8 +1173,7 @@ fn run(next: ~GreenTask) {
                 sched.run_task(task, next)
             }
 
-            let normal_task = do GreenTask::new(&mut normal_sched.stack_pool,
-                                                None) {
+            let normal_task = GreenTask::new(&mut normal_sched.stack_pool, None, proc() {
                 run(task2);
                 run(task4);
                 port.recv();
@@ -1182,26 +1181,25 @@ fn run(next: ~GreenTask) {
                 nh.send(Shutdown);
                 let mut sh = special_handle;
                 sh.send(Shutdown);
-            };
+            });
             normal_sched.enqueue_task(normal_task);
 
-            let special_task = do GreenTask::new(&mut special_sched.stack_pool,
-                                                 None) {
+            let special_task = GreenTask::new(&mut special_sched.stack_pool, None, proc() {
                 run(task1);
                 run(task3);
                 chan.send(());
-            };
+            });
             special_sched.enqueue_task(special_task);
 
             let normal_sched = normal_sched;
-            let normal_thread = do Thread::start { normal_sched.bootstrap() };
+            let normal_thread = Thread::start(proc() { normal_sched.bootstrap() });
 
             let special_sched = special_sched;
-            let special_thread = do Thread::start { special_sched.bootstrap() };
+            let special_thread = Thread::start(proc() { special_sched.bootstrap() });
 
             normal_thread.join();
             special_thread.join();
-        }
+        });
     }
 
     //#[test]
@@ -1226,11 +1224,11 @@ fn test_io_callback() {
         // the work queue, but we are performing I/O, that once we do put
         // something in the work queue again the scheduler picks it up and
         // doesn't exit before emptying the work queue
-        do pool.spawn(TaskOpts::new()) {
-            do spawn {
+        pool.spawn(TaskOpts::new(), proc() {
+            spawn(proc() {
                 timer::sleep(10);
-            }
-        }
+            });
+        });
 
         pool.shutdown();
     }
@@ -1243,19 +1241,19 @@ fn wakeup_across_scheds() {
         let mut pool1 = pool();
         let mut pool2 = pool();
 
-        do pool1.spawn(TaskOpts::new()) {
+        pool1.spawn(TaskOpts::new(), proc() {
             let id = sched_id();
             chan1.send(());
             port2.recv();
             assert_eq!(id, sched_id());
-        }
+        });
 
-        do pool2.spawn(TaskOpts::new()) {
+        pool2.spawn(TaskOpts::new(), proc() {
             let id = sched_id();
             port1.recv();
             assert_eq!(id, sched_id());
             chan2.send(());
-        }
+        });
 
         pool1.shutdown();
         pool2.shutdown();
@@ -1275,15 +1273,15 @@ fn no_missed_messages() {
 
     #[test]
     fn multithreading() {
-        do run {
+        run(proc() {
             let mut ports = ~[];
-            10.times(|| {
+            for _ in range(0, 10) {
                 let (port, chan) = Chan::new();
-                do spawn {
+                spawn(proc() {
                     chan.send(());
-                }
+                });
                 ports.push(port);
-            });
+            }
 
             loop {
                 match ports.pop() {
@@ -1291,12 +1289,12 @@ fn multithreading() {
                     None => break,
                 }
             }
-        }
+        });
     }
 
      #[test]
     fn thread_ring() {
-        do run {
+        run(proc() {
             let (end_port, end_chan) = Chan::new();
 
             let n_tasks = 10;
@@ -1309,19 +1307,19 @@ fn thread_ring() {
                 let (next_p, ch) = Chan::new();
                 let imm_i = i;
                 let imm_p = p;
-                do spawn {
+                spawn(proc() {
                     roundtrip(imm_i, n_tasks, &imm_p, &ch);
-                };
+                });
                 p = next_p;
                 i += 1;
             }
             let p = p;
-            do spawn {
+            spawn(proc() {
                 roundtrip(1, n_tasks, &p, &ch1);
-            }
+            });
 
             end_port.recv();
-        }
+        });
 
         fn roundtrip(id: int, n_tasks: int,
                      p: &Port<(int, Chan<()>)>,
@@ -1349,7 +1347,7 @@ fn roundtrip(id: int, n_tasks: int,
     fn start_closure_dtor() {
         // Regression test that the `start` task entrypoint can
         // contain dtors that use task resources
-        do run {
+        run(proc() {
             struct S { field: () }
 
             impl Drop for S {
@@ -1360,10 +1358,10 @@ fn drop(&mut self) {
 
             let s = S { field: () };
 
-            do spawn {
+            spawn(proc() {
                 let _ss = &s;
-            }
-        }
+            });
+        });
     }
 
     // FIXME: #9407: xfail-test
@@ -1374,36 +1372,36 @@ fn dont_starve_1() {
             threads: 2, // this must be > 1
             event_loop_factory: Some(basic::event_loop),
         });
-        do pool.spawn(TaskOpts::new()) {
+        pool.spawn(TaskOpts::new(), proc() {
             let (port, chan) = Chan::new();
 
             // This task should not be able to starve the sender;
             // The sender should get stolen to another thread.
-            do spawn {
+            spawn(proc() {
                 while port.try_recv() != comm::Data(()) { }
-            }
+            });
 
             chan.send(());
-        }
+        });
         pool.shutdown();
     }
 
     #[test]
     fn dont_starve_2() {
-        do run {
+        run(proc() {
             let (port, chan) = Chan::new();
             let (_port2, chan2) = Chan::new();
 
             // This task should not be able to starve the other task.
             // The sends should eventually yield.
-            do spawn {
+            spawn(proc() {
                 while port.try_recv() != comm::Data(()) {
                     chan2.send(());
                 }
-            }
+            });
 
             chan.send(());
-        }
+        });
     }
 
     // Regression test for a logic bug that would cause single-threaded
@@ -1411,9 +1409,9 @@ fn dont_starve_2() {
     #[test]
     fn single_threaded_yield() {
         use std::task::deschedule;
-        do run {
-            5.times(deschedule);
-        }
+        run(proc() {
+            for _ in range(0, 5) { deschedule(); }
+        });
     }
 
     #[test]
@@ -1461,11 +1459,11 @@ fn pingpong(po: &Port<int>, ch: &Chan<int>) {
 
                 let (setup_po, setup_ch) = Chan::new();
                 let (parent_po, parent_ch) = Chan::new();
-                do spawn {
+                spawn(proc() {
                     let (child_po, child_ch) = Chan::new();
                     setup_ch.send(child_ch);
                     pingpong(&child_po, &parent_ch);
-                };
+                });
 
                 let child_ch = setup_po.recv();
                 child_ch.send(20);
index 7e6dd02dd67e02807ae064887b205bbbe1ef53dc..4b3db5ef8ed908bb73e2a4c22b71da8cfa8bc83e 100644 (file)
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::vec;
-use std::libc::{c_uint, uintptr_t};
+use std::rt::env::max_cached_stacks;
+use std::os::{errno, page_size, MemoryMap, MapReadable, MapWritable,
+              MapNonStandardFlags, MapVirtual};
+use std::libc;
 
-pub struct StackSegment {
-    priv buf: ~[u8],
-    priv valgrind_id: c_uint
+/// A task's stack. The name "Stack" is a vestige of segmented stacks.
+pub struct Stack {
+    priv buf: MemoryMap,
+    priv min_size: uint,
+    priv valgrind_id: libc::c_uint,
 }
 
-impl StackSegment {
-    pub fn new(size: uint) -> StackSegment {
-        unsafe {
-            // Crate a block of uninitialized values
-            let mut stack = vec::with_capacity(size);
-            stack.set_len(size);
-
-            let mut stk = StackSegment {
-                buf: stack,
-                valgrind_id: 0
-            };
-
-            // XXX: Using the FFI to call a C macro. Slow
-            stk.valgrind_id = rust_valgrind_stack_register(stk.start(), stk.end());
-            return stk;
+// 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
+#[cfg(not(windows), not(target_os = "freebsd"))]
+static STACK_FLAGS: libc::c_int = libc::MAP_STACK | libc::MAP_PRIVATE |
+                                  libc::MAP_ANON;
+#[cfg(target_os = "freebsd")]
+static STACK_FLAGS: libc::c_int = libc::MAP_PRIVATE | libc::MAP_ANON;
+#[cfg(windows)]
+static STACK_FLAGS: libc::c_int = 0;
+
+impl Stack {
+    /// Allocate a new stack of `size`. If size = 0, this will fail. 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
+        // allocation failure, which would fail to spawn the task. But there's
+        // not many sensible things to do on OOM.  Failure seems fine (and is
+        // what the old stack allocation did).
+        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)
+        };
+
+        // Change the last page to be inaccessible. This is to provide safety;
+        // when an FFI function overflows it will (hopefully) hit this guard
+        // 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={}",
+                  stack, errno());
+        }
+
+        let mut stk = Stack {
+            buf: stack,
+            min_size: size,
+            valgrind_id: 0
+        };
+
+        // FIXME: Using the FFI to call a C macro. Slow
+        stk.valgrind_id = unsafe {
+            rust_valgrind_stack_register(stk.start(), stk.end())
+        };
+        return stk;
+    }
+
+    /// Create a 0-length stack which starts (and ends) at 0.
+    pub unsafe fn dummy_stack() -> Stack {
+        Stack {
+            buf: MemoryMap { data: 0 as *mut u8, len: 0, kind: MapVirtual },
+            min_size: 0,
+            valgrind_id: 0
         }
     }
 
     /// Point to the low end of the allocated stack
     pub fn start(&self) -> *uint {
-        self.buf.as_ptr() as *uint
+        self.buf.data as *uint
     }
 
-    /// Point one word beyond the high end of the allocated stack
+    /// Point one uint beyond the high end of the allocated stack
     pub fn end(&self) -> *uint {
         unsafe {
-            self.buf.as_ptr().offset(self.buf.len() as int) as *uint
+            self.buf.data.offset(self.buf.len as int) as *uint
         }
     }
 }
 
-impl Drop for StackSegment {
+#[cfg(unix)]
+fn protect_last_page(stack: &MemoryMap) -> bool {
+    unsafe {
+        // This may seem backwards: the start of the segment is the last page?
+        // Yes! The stack grows from higher addresses (the end of the allocated
+        // block) to lower addresses (the start of the allocated block).
+        let last_page = stack.data as *libc::c_void;
+        libc::mprotect(last_page, page_size() as libc::size_t,
+                       libc::PROT_NONE) != -1
+    }
+}
+
+#[cfg(windows)]
+fn protect_last_page(stack: &MemoryMap) -> bool {
+    unsafe {
+        // see above
+        let last_page = stack.data as *mut libc::c_void;
+        let mut old_prot: libc::DWORD = 0;
+        libc::VirtualProtect(last_page, page_size() as libc::SIZE_T,
+                             libc::PAGE_NOACCESS,
+                             &mut old_prot as libc::LPDWORD) != 0
+    }
+}
+
+impl Drop for Stack {
     fn drop(&mut self) {
         unsafe {
-            // XXX: Using the FFI to call a C macro. Slow
+            // FIXME: Using the FFI to call a C macro. Slow
             rust_valgrind_stack_deregister(self.valgrind_id);
         }
     }
 }
 
-pub struct StackPool(());
+pub struct StackPool {
+    // Ideally this would be some datastructure that preserved ordering on
+    // Stack.min_size.
+    priv stacks: ~[Stack],
+}
 
 impl StackPool {
-    pub fn new() -> StackPool { StackPool(()) }
+    pub fn new() -> StackPool {
+        StackPool {
+            stacks: ~[],
+        }
+    }
 
-    pub fn take_segment(&self, min_size: uint) -> StackSegment {
-        StackSegment::new(min_size)
+    pub fn take_stack(&mut self, min_size: uint) -> Stack {
+        // Ideally this would be a binary search
+        match self.stacks.iter().position(|s| s.min_size < min_size) {
+            Some(idx) => self.stacks.swap_remove(idx),
+            None      => Stack::new(min_size)
+        }
     }
 
-    pub fn give_segment(&self, _stack: StackSegment) {
+    pub fn give_stack(&mut self, stack: Stack) {
+        if self.stacks.len() <= max_cached_stacks() {
+            self.stacks.push(stack)
+        }
     }
 }
 
 extern {
-    fn rust_valgrind_stack_register(start: *uintptr_t, end: *uintptr_t) -> c_uint;
-    fn rust_valgrind_stack_deregister(id: c_uint);
+    fn rust_valgrind_stack_register(start: *libc::uintptr_t,
+                                    end: *libc::uintptr_t) -> libc::c_uint;
+    fn rust_valgrind_stack_deregister(id: libc::c_uint);
 }
index 31752941231cb9328e57a77becc1a6fe3b0e655e..a2ecaf6fa9cac89176cfbf490ebea515307d6775 100644 (file)
@@ -494,19 +494,19 @@ fn spawn_opts(opts: TaskOpts, f: proc()) {
     #[test]
     fn smoke() {
         let (p, c) = Chan::new();
-        do spawn_opts(TaskOpts::new()) {
+        spawn_opts(TaskOpts::new(), proc() {
             c.send(());
-        }
+        });
         p.recv();
     }
 
     #[test]
     fn smoke_fail() {
         let (p, c) = Chan::<()>::new();
-        do spawn_opts(TaskOpts::new()) {
+        spawn_opts(TaskOpts::new(), proc() {
             let _c = c;
             fail!()
-        }
+        });
         assert_eq!(p.recv_opt(), None);
     }
 
@@ -533,38 +533,38 @@ fn smoke_opts_fail() {
     #[test]
     fn yield_test() {
         let (p, c) = Chan::new();
-        do spawn_opts(TaskOpts::new()) {
-            10.times(task::deschedule);
+        spawn_opts(TaskOpts::new(), proc() {
+            for _ in range(0, 10) { task::deschedule(); }
             c.send(());
-        }
+        });
         p.recv();
     }
 
     #[test]
     fn spawn_children() {
         let (p, c) = Chan::new();
-        do spawn_opts(TaskOpts::new()) {
+        spawn_opts(TaskOpts::new(), proc() {
             let (p, c2) = Chan::new();
-            do spawn {
+            spawn(proc() {
                 let (p, c3) = Chan::new();
-                do spawn {
+                spawn(proc() {
                     c3.send(());
-                }
+                });
                 p.recv();
                 c2.send(());
-            }
+            });
             p.recv();
             c.send(());
-        }
+        });
         p.recv();
     }
 
     #[test]
     fn spawn_inherits() {
         let (p, c) = Chan::new();
-        do spawn_opts(TaskOpts::new()) {
+        spawn_opts(TaskOpts::new(), proc() {
             let c = c;
-            do spawn {
+            spawn(proc() {
                 let mut task: ~Task = Local::take();
                 match task.maybe_take_runtime::<GreenTask>() {
                     Some(ops) => {
@@ -574,8 +574,8 @@ fn spawn_inherits() {
                 }
                 Local::put(task);
                 c.send(());
-            }
-        }
+            });
+        });
         p.recv();
     }
 }
diff --git a/src/libnative/io/addrinfo.rs b/src/libnative/io/addrinfo.rs
new file mode 100644 (file)
index 0000000..5bdeaa1
--- /dev/null
@@ -0,0 +1,117 @@
+// 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 ai = std::io::net::addrinfo;
+use std::c_str::CString;
+use std::cast;
+use std::io::IoError;
+use std::libc;
+use std::libc::{c_char, c_int};
+use std::ptr::null;
+
+use super::net::sockaddr_to_addr;
+
+pub struct GetAddrInfoRequest;
+
+impl GetAddrInfoRequest {
+    pub fn run(host: Option<&str>, servname: Option<&str>,
+               hint: Option<ai::Hint>) -> Result<~[ai::Info], IoError> {
+        assert!(host.is_some() || servname.is_some());
+
+        let c_host = host.map_or(unsafe { CString::new(null(), true) }, |x| x.to_c_str());
+        let c_serv = servname.map_or(unsafe { CString::new(null(), true) }, |x| x.to_c_str());
+
+        let hint = hint.map(|hint| {
+            libc::addrinfo {
+                ai_flags: hint.flags as c_int,
+                ai_family: hint.family as c_int,
+                ai_socktype: 0,
+                ai_protocol: 0,
+                ai_addrlen: 0,
+                ai_canonname: null(),
+                ai_addr: null(),
+                ai_next: null()
+            }
+        });
+
+        let hint_ptr = hint.as_ref().map_or(null(), |x| x as *libc::addrinfo);
+        let res = null();
+
+        // Make the call
+        let s = unsafe {
+            let ch = if c_host.is_null() { null() } else { c_host.with_ref(|x| x) };
+            let cs = if c_serv.is_null() { null() } else { c_serv.with_ref(|x| x) };
+            getaddrinfo(ch, cs, hint_ptr, &res)
+        };
+
+        // Error?
+        if s != 0 {
+            return Err(get_error(s));
+        }
+
+        // Collect all the results we found
+        let mut addrs = ~[];
+        let mut rp = res;
+        while rp.is_not_null() {
+            unsafe {
+                let addr = match sockaddr_to_addr(cast::transmute((*rp).ai_addr),
+                                                  (*rp).ai_addrlen as uint) {
+                    Ok(a) => a,
+                    Err(e) => return Err(e)
+                };
+                addrs.push(ai::Info {
+                    address: addr,
+                    family: (*rp).ai_family as uint,
+                    socktype: None,
+                    protocol: None,
+                    flags: (*rp).ai_flags as uint
+                });
+
+                rp = (*rp).ai_next;
+            }
+        }
+
+        unsafe { freeaddrinfo(res); }
+
+        Ok(addrs)
+    }
+}
+
+extern "system" {
+    fn getaddrinfo(node: *c_char, service: *c_char,
+                   hints: *libc::addrinfo, res: **libc::addrinfo) -> c_int;
+    fn freeaddrinfo(res: *libc::addrinfo);
+    #[cfg(not(windows))]
+    fn gai_strerror(errcode: c_int) -> *c_char;
+    #[cfg(windows)]
+    fn WSAGetLastError() -> c_int;
+}
+
+#[cfg(windows)]
+fn get_error(_: c_int) -> IoError {
+    use super::translate_error;
+
+    unsafe {
+        translate_error(WSAGetLastError() as i32, true)
+    }
+}
+
+#[cfg(not(windows))]
+fn get_error(s: c_int) -> IoError {
+    use std::io;
+    use std::str::raw::from_c_str;
+
+    let err_str = unsafe { from_c_str(gai_strerror(s)) };
+    IoError {
+        kind: io::OtherIoError,
+        desc: "unable to resolve host",
+        detail: Some(err_str),
+    }
+}
index af06533d44bd1cb1844fa3809e405657be4acc14..acab7ce3a91b4763b8615236ed0fabcf005fd6f1 100644 (file)
@@ -118,7 +118,10 @@ fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
 
 impl io::Writer for FileDesc {
     fn write(&mut self, buf: &[u8]) {
-        self.inner_write(buf);
+        match self.inner_write(buf) {
+            Ok(()) => {}
+            Err(e) => { io::io_error::cond.raise(e); }
+        }
     }
 }
 
@@ -276,7 +279,7 @@ fn truncate(&mut self, offset: i64) -> Result<(), IoError> {
                 _ => Ok(())
             }
         };
-        self.seek(orig_pos as i64, io::SeekSet);
+        let _ = self.seek(orig_pos as i64, io::SeekSet);
         return ret;
     }
     #[cfg(unix)]
@@ -383,12 +386,10 @@ fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
     }
 
     fn pread(&mut self, buf: &mut [u8], offset: u64) -> Result<int, IoError> {
-        self.flush();
-        self.fd.pread(buf, offset)
+        self.flush().and_then(|()| self.fd.pread(buf, offset))
     }
     fn pwrite(&mut self, buf: &[u8], offset: u64) -> Result<(), IoError> {
-        self.flush();
-        self.fd.pwrite(buf, offset)
+        self.flush().and_then(|()| self.fd.pwrite(buf, offset))
     }
     fn seek(&mut self, pos: i64, style: io::SeekStyle) -> Result<u64, IoError> {
         let whence = match style {
@@ -412,16 +413,13 @@ fn tell(&self) -> Result<u64, IoError> {
         }
     }
     fn fsync(&mut self) -> Result<(), IoError> {
-        self.flush();
-        self.fd.fsync()
+        self.flush().and_then(|()| self.fd.fsync())
     }
     fn datasync(&mut self) -> Result<(), IoError> {
-        self.flush();
-        self.fd.fsync()
+        self.flush().and_then(|()| self.fd.fsync())
     }
     fn truncate(&mut self, offset: i64) -> Result<(), IoError> {
-        self.flush();
-        self.fd.truncate(offset)
+        self.flush().and_then(|()| self.fd.truncate(offset))
     }
 }
 
@@ -674,7 +672,7 @@ fn os_chown(p: &CString, uid: int, gid: int) -> c_int {
 pub fn readlink(p: &CString) -> IoResult<Path> {
     return os_readlink(p);
 
-    // XXX: I have a feeling that this reads intermediate symlinks as well.
+    // FIXME: I have a feeling that this reads intermediate symlinks as well.
     #[cfg(windows)]
     fn os_readlink(p: &CString) -> IoResult<Path> {
         let handle = unsafe {
@@ -709,7 +707,7 @@ fn os_readlink(p: &CString) -> IoResult<Path> {
         let p = p.with_ref(|p| p);
         let mut len = unsafe { libc::pathconf(p, libc::_PC_NAME_MAX) };
         if len == -1 {
-            len = 1024; // XXX: read PATH_MAX from C ffi?
+            len = 1024; // FIXME: read PATH_MAX from C ffi?
         }
         let mut buf = vec::with_capacity::<u8>(len as uint);
         match retry(|| unsafe {
@@ -877,7 +875,7 @@ fn os_stat(p: &CString) -> IoResult<io::FileStat> {
 pub fn lstat(p: &CString) -> IoResult<io::FileStat> {
     return os_lstat(p);
 
-    // XXX: windows implementation is missing
+    // FIXME: windows implementation is missing
     #[cfg(windows)]
     fn os_lstat(_p: &CString) -> IoResult<io::FileStat> {
         Err(super::unimpl())
index f3aca7820a50582124436b685acd3836853f62ae..c94554f510e461da104e01615413f838cfdfb7a1 100644 (file)
 
 use std::c_str::CString;
 use std::comm::SharedChan;
+use std::io;
+use std::io::IoError;
+use std::io::net::ip::SocketAddr;
+use std::io::process::ProcessConfig;
+use std::io::signal::Signum;
 use std::libc::c_int;
 use std::libc;
 use std::os;
 use std::rt::rtio::{RtioTcpStream, RtioTcpListener, RtioUdpSocket,
                     RtioUnixListener, RtioPipe, RtioFileStream, RtioProcess,
                     RtioSignal, RtioTTY, CloseBehavior, RtioTimer};
-use std::io;
-use std::io::IoError;
-use std::io::net::ip::SocketAddr;
-use std::io::process::ProcessConfig;
-use std::io::signal::Signum;
 use ai = std::io::net::addrinfo;
 
 // Local re-exports
 pub use self::process::Process;
 
 // Native I/O implementations
+pub mod addrinfo;
 pub mod file;
-pub mod process;
 pub mod net;
+pub mod process;
 
 #[cfg(target_os = "macos")]
 #[cfg(target_os = "freebsd")]
+#[cfg(target_os = "android")]
 #[path = "timer_other.rs"]
 pub mod timer;
 
 #[cfg(target_os = "linux")]
-#[cfg(target_os = "android")]
 #[path = "timer_timerfd.rs"]
 pub mod timer;
 
@@ -62,7 +63,7 @@
 
 mod timer_helper;
 
-type IoResult<T> = Result<T, IoError>;
+pub type IoResult<T> = Result<T, IoError>;
 
 fn unimpl() -> IoError {
     IoError {
@@ -96,7 +97,7 @@ fn get_err(errno: i32) -> (io::IoErrorKind, &'static str) {
 
     #[cfg(not(windows))]
     fn get_err(errno: i32) -> (io::IoErrorKind, &'static str) {
-        // XXX: this should probably be a bit more descriptive...
+        // FIXME: this should probably be a bit more descriptive...
         match errno {
             libc::EOF => (io::EndOfFile, "end of file"),
             libc::ECONNREFUSED => (io::ConnectionRefused, "connection refused"),
@@ -202,9 +203,9 @@ fn unix_bind(&mut self, _path: &CString) -> IoResult<~RtioUnixListener> {
     fn unix_connect(&mut self, _path: &CString) -> IoResult<~RtioPipe> {
         Err(unimpl())
     }
-    fn get_host_addresses(&mut self, _host: Option<&str>, _servname: Option<&str>,
-                          _hint: Option<ai::Hint>) -> IoResult<~[ai::Info]> {
-        Err(unimpl())
+    fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
+                          hint: Option<ai::Hint>) -> IoResult<~[ai::Info]> {
+        addrinfo::GetAddrInfoRequest::run(host, servname, hint)
     }
 
     // filesystem operations
index adcd21f0ac4c5d85b6e5797d00d75569881e1fcc..2f4bec22755f6621d0d26902b09eb727a6cccd59 100644 (file)
@@ -134,8 +134,8 @@ fn sockname(fd: sock_t,
     return sockaddr_to_addr(&storage, len as uint);
 }
 
-fn sockaddr_to_addr(storage: &libc::sockaddr_storage,
-                    len: uint) -> IoResult<ip::SocketAddr> {
+pub fn sockaddr_to_addr(storage: &libc::sockaddr_storage,
+                        len: uint) -> IoResult<ip::SocketAddr> {
     match storage.ss_family as libc::c_int {
         libc::AF_INET => {
             assert!(len as uint >= mem::size_of::<libc::sockaddr_in>());
@@ -348,6 +348,17 @@ pub fn bind(addr: ip::SocketAddr) -> IoResult<TcpListener> {
                 let (addr, len) = addr_to_sockaddr(addr);
                 let addrp = &addr as *libc::sockaddr_storage;
                 let ret = TcpListener { fd: fd };
+                // On platforms with Berkeley-derived sockets, this allows
+                // to quickly rebind a socket, without needing to wait for
+                // the OS to clean up the previous one.
+                if cfg!(unix) {
+                    match setsockopt(fd, libc::SOL_SOCKET,
+                                     libc::SO_REUSEADDR,
+                                     1 as libc::c_int) {
+                        Err(n) => { return Err(n); },
+                        Ok(..) => { }
+                    }
+                }
                 match libc::bind(fd, addrp as *libc::sockaddr,
                                  len as libc::socklen_t) {
                     -1 => Err(super::last_error()),
index ee4ee29505575d74007c63cd1ee7db2b40bbd999..13dd4298777c617db5bdf5cd1451cd49b55dd433 100644 (file)
@@ -486,7 +486,7 @@ unsafe fn set_cloexec(fd: c_int) {
                 (errno <<  8) as u8,
                 (errno <<  0) as u8,
             ];
-            output.inner_write(bytes);
+            assert!(output.inner_write(bytes).is_ok());
             intrinsics::abort();
         })
     }
index 3c20d073f2913306532ebbb5ecea2ac393dfa015..74759b467d4a797557932eb89fa39f4417139c79 100644 (file)
@@ -46,10 +46,10 @@ pub fn boot(helper: fn(imp::signal, Port<Req>)) {
             let (receive, send) = imp::new();
             HELPER_SIGNAL = send;
 
-            do task::spawn {
+            task::spawn(proc() {
                 bookkeeping::decrement();
                 helper(receive, msgp);
-            }
+            });
 
             rt::at_exit(proc() { shutdown() });
         })
@@ -101,7 +101,7 @@ pub fn new() -> (signal, signal) {
     }
 
     pub fn signal(fd: libc::c_int) {
-        FileDesc::new(fd, false).inner_write([0]);
+        FileDesc::new(fd, false).inner_write([0]).unwrap();
     }
 
     pub fn close(fd: libc::c_int) {
index 24ffd7a4147782a42e8265b31fde2d6bcc68c6d0..bc005f2fe8dd3542b40ee033f900a20c16817b22 100644 (file)
@@ -187,7 +187,7 @@ fn signal(active: &mut ~[~Inner], dead: &mut HashMap<uint, ~Inner>) {
 
                 // drain the file descriptor
                 let mut buf = [0];
-                fd.inner_read(buf);
+                fd.inner_read(buf).unwrap();
             }
 
             -1 if os::errno() == libc::EINTR as int => {}
@@ -301,6 +301,7 @@ pub fn gettimeofday(timeval: *mut libc::timeval,
     }
 }
 
+#[cfg(target_os = "android")]
 #[cfg(target_os = "freebsd")]
 mod imp {
     use std::libc;
index 0556b0c2599c0284c7937f7a648b65b577db0df4..1888b8578a0920952f35f1589b2933724f1e3b7f 100644 (file)
@@ -98,15 +98,15 @@ fn del(efd: libc::c_int, fd: libc::c_int) {
             if fd == input {
                 let mut buf = [0, ..1];
                 // drain the input file descriptor of its input
-                FileDesc::new(fd, false).inner_read(buf);
+                FileDesc::new(fd, false).inner_read(buf).unwrap();
                 incoming = true;
             } else {
                 let mut bits = [0, ..8];
                 // drain the timerfd of how many times its fired
                 //
-                // XXX: should this perform a send() this number of
+                // FIXME: should this perform a send() this number of
                 //      times?
-                FileDesc::new(fd, false).inner_read(bits);
+                FileDesc::new(fd, false).inner_read(bits).unwrap();
                 let remove = {
                     match map.find(&fd).expect("fd unregistered") {
                         &(ref c, oneshot) => !c.try_send(()) || oneshot
index d2f68c4ef681dd0b56ad9690921b6494135b7029..3742517970118a7bf0ccde00a1293fb42c352a4a 100644 (file)
@@ -272,19 +272,19 @@ mod tests {
     #[test]
     fn smoke() {
         let (p, c) = Chan::new();
-        do spawn {
+        spawn(proc() {
             c.send(());
-        }
+        });
         p.recv();
     }
 
     #[test]
     fn smoke_fail() {
         let (p, c) = Chan::<()>::new();
-        do spawn {
+        spawn(proc() {
             let _c = c;
             fail!()
-        }
+        });
         assert_eq!(p.recv_opt(), None);
     }
 
@@ -311,38 +311,38 @@ fn smoke_opts_fail() {
     #[test]
     fn yield_test() {
         let (p, c) = Chan::new();
-        do spawn {
-            10.times(task::deschedule);
+        spawn(proc() {
+            for _ in range(0, 10) { task::deschedule(); }
             c.send(());
-        }
+        });
         p.recv();
     }
 
     #[test]
     fn spawn_children() {
         let (p, c) = Chan::new();
-        do spawn {
+        spawn(proc() {
             let (p, c2) = Chan::new();
-            do spawn {
+            spawn(proc() {
                 let (p, c3) = Chan::new();
-                do spawn {
+                spawn(proc() {
                     c3.send(());
-                }
+                });
                 p.recv();
                 c2.send(());
-            }
+            });
             p.recv();
             c.send(());
-        }
+        });
         p.recv();
     }
 
     #[test]
     fn spawn_inherits() {
         let (p, c) = Chan::new();
-        do spawn {
+        spawn(proc() {
             let c = c;
-            do spawn {
+            spawn(proc() {
                 let mut task: ~Task = Local::take();
                 match task.maybe_take_runtime::<Ops>() {
                     Some(ops) => {
@@ -352,8 +352,8 @@ fn spawn_inherits() {
                 }
                 Local::put(task);
                 c.send(());
-            }
-        }
+            });
+        });
         p.recv();
     }
 }
index 8f639a5e499f1d2f2440c0d95da1faec67969734..83a17bd3231a2442285a5035f95036950934858f 100644 (file)
 
 pub static tydesc_field_size: uint = 0u;
 pub static tydesc_field_align: uint = 1u;
-pub static tydesc_field_take_glue: uint = 2u;
-pub static tydesc_field_drop_glue: uint = 3u;
-pub static tydesc_field_visit_glue: uint = 4u;
-pub static tydesc_field_name_offset: uint = 5u;
-pub static n_tydesc_fields: uint = 6u;
+pub static tydesc_field_drop_glue: uint = 2u;
+pub static tydesc_field_visit_glue: uint = 3u;
+pub static tydesc_field_name_offset: uint = 4u;
+pub static n_tydesc_fields: uint = 5u;
 
 // The two halves of a closure: code and environment.
 pub static fn_field_code: uint = 0u;
index 63c4d9f4a2976ee270e7cdcdd50934fb41bb9d3e..3a6b9f399aa64c2245a438958d8b2abdf2c3dbf2 100644 (file)
@@ -128,6 +128,9 @@ pub fn run_passes(sess: Session,
             };
             let use_softfp = sess.opts.debugging_opts & session::USE_SOFTFP != 0;
 
+            // FIXME: #11906: Omitting frame pointers breaks retrieving the value of a parameter.
+            let no_fp_elim = sess.opts.debuginfo;
+
             let tm = sess.targ_cfg.target_strs.target_triple.with_c_str(|T| {
                 sess.opts.target_cpu.with_c_str(|CPU| {
                     sess.opts.target_feature.with_c_str(|Features| {
@@ -137,7 +140,8 @@ pub fn run_passes(sess: Session,
                             lib::llvm::RelocPIC,
                             OptLevel,
                             true,
-                            use_softfp
+                            use_softfp,
+                            no_fp_elim
                         )
                     })
                 })
@@ -1089,8 +1093,10 @@ fn link_args(sess: Session,
             args.push(~"-dynamiclib");
             args.push(~"-Wl,-dylib");
             // FIXME (#9639): This needs to handle non-utf8 paths
-            args.push(~"-Wl,-install_name,@rpath/" +
-                      out_filename.filename_str().unwrap());
+            if !sess.opts.no_rpath {
+                args.push(~"-Wl,-install_name,@rpath/" +
+                          out_filename.filename_str().unwrap());
+            }
         } else {
             args.push(~"-shared")
         }
@@ -1108,7 +1114,9 @@ fn link_args(sess: Session,
     // FIXME (#2397): At some point we want to rpath our guesses as to
     // where extern libraries might live, based on the
     // addl_lib_search_paths
-    args.push_all(rpath::get_rpath_flags(sess, out_filename));
+    if !sess.opts.no_rpath {
+        args.push_all(rpath::get_rpath_flags(sess, out_filename));
+    }
 
     // Finally add all the linker arguments provided on the command line along
     // with any #[link_args] attributes found inside the crate
index 301a49d8aec66babfc3468c4f873a489dea1f28b..211d60f7e2d538be7795c8646f643f33e44a774e 100644 (file)
@@ -176,6 +176,9 @@ pub fn phase_2_configure_and_expand(sess: Session,
     time(time_passes, "gated feature checking", (), |_|
          front::feature_gate::check_crate(sess, &crate));
 
+    crate = time(time_passes, "crate injection", crate, |crate|
+                 front::std_inject::maybe_inject_crates_ref(sess, crate));
+
     // strip before expansion to allow macros to depend on
     // configuration variables e.g/ in
     //
@@ -183,10 +186,6 @@ pub fn phase_2_configure_and_expand(sess: Session,
     //   mod bar { macro_rules! baz!(() => {{}}) }
     //
     // baz! should not use this definition unless foo is enabled.
-    crate = time(time_passes, "std macros injection", crate, |crate|
-                 syntax::ext::expand::inject_std_macros(sess.parse_sess,
-                                                        cfg.clone(),
-                                                        crate));
 
     crate = time(time_passes, "configuration 1", crate, |crate|
                  front::config::strip_unconfigured_items(crate));
@@ -207,8 +206,8 @@ pub fn phase_2_configure_and_expand(sess: Session,
     crate = time(time_passes, "maybe building test harness", crate, |crate|
                  front::test::modify_for_testing(sess, crate));
 
-    crate = time(time_passes, "std injection", crate, |crate|
-                 front::std_inject::maybe_inject_libstd_ref(sess, crate));
+    crate = time(time_passes, "prelude injection", crate, |crate|
+                 front::std_inject::maybe_inject_prelude(sess, crate));
 
     time(time_passes, "assinging node ids and indexing ast", crate, |crate|
          front::assign_node_ids_and_map::assign_node_ids_and_map(sess, crate))
@@ -717,14 +716,16 @@ pub fn build_session_options(binary: ~str,
                              demitter: @diagnostic::Emitter)
                              -> @session::Options {
     let mut outputs = ~[];
+    if matches.opt_present("lib") {
+        outputs.push(session::default_lib_output());
+    }
     if matches.opt_present("rlib") {
         outputs.push(session::OutputRlib)
     }
     if matches.opt_present("staticlib") {
         outputs.push(session::OutputStaticlib)
     }
-    // dynamic libraries are the "compiler blesssed" default library
-    if matches.opt_present("dylib") || matches.opt_present("lib") {
+    if matches.opt_present("dylib") {
         outputs.push(session::OutputDylib)
     }
     if matches.opt_present("bin") {
@@ -734,6 +735,7 @@ pub fn build_session_options(binary: ~str,
     let parse_only = matches.opt_present("parse-only");
     let no_trans = matches.opt_present("no-trans");
     let no_analysis = matches.opt_present("no-analysis");
+    let no_rpath = matches.opt_present("no-rpath");
 
     let lint_levels = [lint::allow, lint::warn,
                        lint::deny, lint::forbid];
@@ -888,6 +890,7 @@ pub fn build_session_options(binary: ~str,
         parse_only: parse_only,
         no_trans: no_trans,
         no_analysis: no_analysis,
+        no_rpath: no_rpath,
         debugging_opts: debugging_opts,
         android_cross_path: android_cross_path,
         write_dependency_info: write_dependency_info,
@@ -896,35 +899,48 @@ pub fn build_session_options(binary: ~str,
     return sopts;
 }
 
-pub fn build_session(sopts: @session::Options, demitter: @diagnostic::Emitter)
+pub fn build_session(sopts: @session::Options,
+                     local_crate_source_file: Option<Path>,
+                     demitter: @diagnostic::Emitter)
                      -> Session {
     let codemap = @codemap::CodeMap::new();
     let diagnostic_handler =
         diagnostic::mk_handler(Some(demitter));
     let span_diagnostic_handler =
         diagnostic::mk_span_handler(diagnostic_handler, codemap);
-    build_session_(sopts, codemap, demitter, span_diagnostic_handler)
+
+    build_session_(sopts, local_crate_source_file, codemap, demitter, span_diagnostic_handler)
 }
 
 pub fn build_session_(sopts: @session::Options,
-                      cm: @codemap::CodeMap,
+                      local_crate_source_file: Option<Path>,
+                      codemap: @codemap::CodeMap,
                       demitter: @diagnostic::Emitter,
                       span_diagnostic_handler: @diagnostic::SpanHandler)
                       -> Session {
     let target_cfg = build_target_config(sopts, demitter);
-    let p_s = parse::new_parse_sess_special_handler(span_diagnostic_handler,
-                                                    cm);
+    let p_s = parse::new_parse_sess_special_handler(span_diagnostic_handler, codemap);
     let cstore = @CStore::new(token::get_ident_interner());
     let filesearch = @filesearch::FileSearch::new(
         &sopts.maybe_sysroot,
         sopts.target_triple,
         sopts.addl_lib_search_paths);
+
+    // Make the path absolute, if necessary
+    let local_crate_source_file = local_crate_source_file.map(|path|
+        if path.is_absolute() {
+            path.clone()
+        } else {
+            os::getcwd().join(path.clone())
+        }
+    );
+
     @Session_ {
         targ_cfg: target_cfg,
         opts: sopts,
         cstore: cstore,
         parse_sess: p_s,
-        codemap: cm,
+        codemap: codemap,
         // For a library crate, this is always none
         entry_fn: RefCell::new(None),
         entry_type: Cell::new(None),
@@ -932,6 +948,7 @@ pub fn build_session_(sopts: @session::Options,
         span_diagnostic: span_diagnostic_handler,
         filesearch: filesearch,
         building_library: Cell::new(false),
+        local_crate_source_file: local_crate_source_file,
         working_dir: os::getcwd(),
         lints: RefCell::new(HashMap::new()),
         node_id: Cell::new(1),
@@ -995,6 +1012,7 @@ pub fn optgroups() -> ~[getopts::groups::OptGroup] {
                         \"list\" will list all of the available passes", "NAMES"),
   optopt("", "llvm-args", "A list of arguments to pass to llvm, comma \
                            separated", "ARGS"),
+  optflag("", "no-rpath", "Disables setting the rpath in libs/exes"),
   optopt( "",  "out-dir",
                         "Write output to compiler-chosen filename
                           in <dir>", "DIR"),
@@ -1162,13 +1180,8 @@ fn test_switch_implies_cfg_test() {
               Ok(m) => m,
               Err(f) => fail!("test_switch_implies_cfg_test: {}", f.to_err_msg())
             };
-        let sessopts = build_session_options(
-            ~"rustc",
-            matches,
-            @diagnostic::DefaultEmitter as @diagnostic::Emitter);
-        let sess = build_session(sessopts,
-                                 @diagnostic::DefaultEmitter as
-                                    @diagnostic::Emitter);
+        let sessopts = build_session_options(~"rustc", matches, @diagnostic::DefaultEmitter);
+        let sess = build_session(sessopts, None, @diagnostic::DefaultEmitter);
         let cfg = build_configuration(sess);
         assert!((attr::contains_name(cfg, "test")));
     }
@@ -1185,13 +1198,8 @@ fn test_switch_implies_cfg_test_unless_cfg_test() {
                        f.to_err_msg());
               }
             };
-        let sessopts = build_session_options(
-            ~"rustc",
-            matches,
-            @diagnostic::DefaultEmitter as @diagnostic::Emitter);
-        let sess = build_session(sessopts,
-                                 @diagnostic::DefaultEmitter as
-                                    @diagnostic::Emitter);
+        let sessopts = build_session_options(~"rustc", matches, @diagnostic::DefaultEmitter);
+        let sess = build_session(sessopts, None, @diagnostic::DefaultEmitter);
         let cfg = build_configuration(sess);
         let mut test_items = cfg.iter().filter(|m| "test" == m.name());
         assert!(test_items.next().is_some());
index 42b716e8cdfc3d5218deeed6d703017ba0fa2705..5cda81836a44b6f6c80d1acc359834e0a1ed7592 100644 (file)
@@ -170,6 +170,7 @@ pub struct Options {
     parse_only: bool,
     no_trans: bool,
     no_analysis: bool,
+    no_rpath: bool,
     debugging_opts: u64,
     android_cross_path: Option<~str>,
     /// Whether to write dependency files. It's (enabled, optional filename).
@@ -210,6 +211,9 @@ pub struct Session_ {
     macro_registrar_fn: RefCell<Option<ast::DefId>>,
     filesearch: @filesearch::FileSearch,
     building_library: Cell<bool>,
+    // The name of the root source file of the crate, in the local file system. The path is always
+    // expected to be absolute. `None` means that there is no source file.
+    local_crate_source_file: Option<Path>,
     working_dir: Path,
     lints: RefCell<HashMap<ast::NodeId,
                            ~[(lint::Lint, codemap::Span, ~str)]>>,
@@ -391,6 +395,7 @@ pub fn basic_options() -> @Options {
         parse_only: false,
         no_trans: false,
         no_analysis: false,
+        no_rpath: false,
         debugging_opts: 0,
         android_cross_path: None,
         write_dependency_info: (false, None),
@@ -417,6 +422,10 @@ pub fn building_library(options: &Options, crate: &ast::Crate) -> bool {
     }
 }
 
+pub fn default_lib_output() -> OutputStyle {
+    OutputRlib
+}
+
 pub fn collect_outputs(session: &Session,
                        attrs: &[ast::Attribute]) -> ~[OutputStyle] {
     // If we're generating a test executable, then ignore all other output
@@ -430,7 +439,7 @@ pub fn collect_outputs(session: &Session,
             match a.value_str() {
                 Some(n) if "rlib" == n => Some(OutputRlib),
                 Some(n) if "dylib" == n => Some(OutputDylib),
-                Some(n) if "lib" == n => Some(OutputDylib),
+                Some(n) if "lib" == n => Some(default_lib_output()),
                 Some(n) if "staticlib" == n => Some(OutputStaticlib),
                 Some(n) if "bin" == n => Some(OutputExecutable),
                 Some(_) => {
index a0a9800926ebc829e018cac3a37cdad70de32c1d..bfb27594108545cdf4b07d0512036e6f0dbf864c 100644 (file)
@@ -46,6 +46,9 @@
     ("phase", Active),
     ("macro_registrar", Active),
     ("log_syntax", Active),
+    ("trace_macros", Active),
+    ("simd", Active),
+    ("default_type_params", Active),
 
     // These are used to test this portion of the compiler, they don't actually
     // mean anything
@@ -170,6 +173,13 @@ fn visit_item(&mut self, i: &ast::Item, _:()) {
                 }
             }
 
+            ast::ItemStruct(..) => {
+                if attr::contains_name(i.attrs, "simd") {
+                    self.gate_feature("simd", i.span,
+                                      "SIMD types are experimental and possibly buggy");
+                }
+            }
+
             _ => {}
         }
 
@@ -193,6 +203,10 @@ fn visit_mac(&mut self, macro: &ast::Mac, _: ()) {
             self.gate_feature("log_syntax", path.span, "`log_syntax!` is not \
                 stable enough for use and is subject to change");
         }
+        else if path.segments.last().unwrap().identifier == self.sess.ident_of("trace_macros") {
+            self.gate_feature("trace_macros", path.span, "`trace_macros` is not \
+                stable enough for use and is subject to change");
+        }
     }
 
     fn visit_ty(&mut self, t: &ast::Ty, _: ()) {
@@ -221,6 +235,20 @@ fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
         }
         visit::walk_expr(self, e, ());
     }
+
+    fn visit_generics(&mut self, generics: &ast::Generics, _: ()) {
+        for type_parameter in generics.ty_params.iter() {
+            match type_parameter.default {
+                Some(ty) => {
+                    self.gate_feature("default_type_params", ty.span,
+                                      "default type parameters are \
+                                       experimental and possibly buggy");
+                }
+                None => {}
+            }
+        }
+        visit::walk_generics(self, generics, ());
+    }
 }
 
 pub fn check_crate(sess: Session, crate: &ast::Crate) {
index 6fa54061e344027396f38085357047044d9ed4d0..71a82536aee0c54cf0ac4edf5538be62218987cc 100644 (file)
 
 pub static VERSION: &'static str = "0.10-pre";
 
-pub fn maybe_inject_libstd_ref(sess: Session, crate: ast::Crate)
+pub fn maybe_inject_crates_ref(sess: Session, crate: ast::Crate)
                                -> ast::Crate {
     if use_std(&crate) {
-        inject_libstd_ref(sess, crate)
+        inject_crates_ref(sess, crate)
+    } else {
+        crate
+    }
+}
+
+pub fn maybe_inject_prelude(sess: Session, crate: ast::Crate) -> ast::Crate {
+    if use_std(&crate) {
+        inject_prelude(sess, crate)
     } else {
         crate
     }
@@ -44,13 +52,6 @@ fn no_prelude(attrs: &[ast::Attribute]) -> bool {
     attr::contains_name(attrs, "no_implicit_prelude")
 }
 
-fn spanned<T>(x: T) -> codemap::Spanned<T> {
-    codemap::Spanned {
-        node: x,
-        span: DUMMY_SP,
-    }
-}
-
 struct StandardLibraryInjector {
     sess: Session,
 }
@@ -71,7 +72,11 @@ fn fold_crate(&mut self, crate: ast::Crate) -> ast::Crate {
             node: ast::ViewItemExternMod(self.sess.ident_of("std"),
                                          with_version("std"),
                                          ast::DUMMY_NODE_ID),
-            attrs: ~[],
+            attrs: ~[
+                attr::mk_attr(attr::mk_list_item(@"phase",
+                                                 ~[attr::mk_word_item(@"syntax"),
+                                                   attr::mk_word_item(@"link")]))
+            ],
             vis: ast::Inherited,
             span: DUMMY_SP
         }];
@@ -96,22 +101,43 @@ fn fold_crate(&mut self, crate: ast::Crate) -> ast::Crate {
         }
 
         vis.push_all(crate.module.view_items);
-        let mut new_module = ast::Mod {
+        let new_module = ast::Mod {
             view_items: vis,
             ..crate.module.clone()
         };
 
-        if !no_prelude(crate.attrs) {
-            // only add `use std::prelude::*;` if there wasn't a
-            // `#[no_implicit_prelude];` at the crate level.
-            new_module = self.fold_mod(&new_module);
-        }
-
         ast::Crate {
             module: new_module,
             ..crate
         }
     }
+}
+
+fn inject_crates_ref(sess: Session, crate: ast::Crate) -> ast::Crate {
+    let mut fold = StandardLibraryInjector {
+        sess: sess,
+    };
+    fold.fold_crate(crate)
+}
+
+struct PreludeInjector {
+    sess: Session,
+}
+
+
+impl fold::Folder for PreludeInjector {
+    fn fold_crate(&mut self, crate: ast::Crate) -> ast::Crate {
+        if !no_prelude(crate.attrs) {
+            // only add `use std::prelude::*;` if there wasn't a
+            // `#[no_implicit_prelude];` at the crate level.
+            ast::Crate {
+                module: self.fold_mod(&crate.module),
+                ..crate
+            }
+        } else {
+            crate
+        }
+    }
 
     fn fold_item(&mut self, item: @ast::Item) -> SmallVector<@ast::Item> {
         if !no_prelude(item.attrs) {
@@ -142,7 +168,7 @@ fn fold_mod(&mut self, module: &ast::Mod) -> ast::Mod {
             ],
         };
 
-        let vp = @spanned(ast::ViewPathGlob(prelude_path, ast::DUMMY_NODE_ID));
+        let vp = @codemap::dummy_spanned(ast::ViewPathGlob(prelude_path, ast::DUMMY_NODE_ID));
         let vi2 = ast::ViewItem {
             node: ast::ViewItemUse(~[vp]),
             attrs: ~[],
@@ -161,8 +187,8 @@ fn fold_mod(&mut self, module: &ast::Mod) -> ast::Mod {
     }
 }
 
-fn inject_libstd_ref(sess: Session, crate: ast::Crate) -> ast::Crate {
-    let mut fold = StandardLibraryInjector {
+fn inject_prelude(sess: Session, crate: ast::Crate) -> ast::Crate {
+    let mut fold = PreludeInjector {
         sess: sess,
     };
     fold.fold_crate(crate)
index f7ee736f144de60bc042287af91252e6421ae6c1..c840faecb559bc3b0cd122c5631731427a4a52a1 100644 (file)
@@ -30,6 +30,8 @@
 #[feature(macro_rules, globs, struct_variant, managed_boxes)];
 
 extern mod extra;
+extern mod flate;
+extern mod arena;
 extern mod syntax;
 
 use back::link;
@@ -229,22 +231,22 @@ pub fn run_compiler(args: &[~str], demitter: @diagnostic::Emitter) {
         version(binary);
         return;
     }
-    let input = match matches.free.len() {
+    let (input, input_file_path) = match matches.free.len() {
       0u => d::early_error(demitter, "no input filename given"),
       1u => {
         let ifile = matches.free[0].as_slice();
         if "-" == ifile {
             let src = str::from_utf8_owned(io::stdin().read_to_end()).unwrap();
-            d::StrInput(src.to_managed())
+            (d::StrInput(src.to_managed()), None)
         } else {
-            d::FileInput(Path::new(ifile))
+            (d::FileInput(Path::new(ifile)), Some(Path::new(ifile)))
         }
       }
       _ => d::early_error(demitter, "multiple input filenames provided")
     };
 
     let sopts = d::build_session_options(binary, matches, demitter);
-    let sess = d::build_session(sopts, demitter);
+    let sess = d::build_session(sopts, input_file_path, demitter);
     let odir = matches.opt_str("out-dir").map(|o| Path::new(o));
     let ofile = matches.opt_str("o").map(|o| Path::new(o));
     let cfg = d::build_configuration(sess);
@@ -330,7 +332,7 @@ fn parse_crate_attrs(sess: session::Session,
 /// The diagnostic emitter yielded to the procedure should be used for reporting
 /// errors of the compiler.
 pub fn monitor(f: proc(@diagnostic::Emitter)) {
-    // XXX: This is a hack for newsched since it doesn't support split stacks.
+    // FIXME: This is a hack for newsched since it doesn't support split stacks.
     // rustc needs a lot of stack! When optimizations are disabled, it needs
     // even *more* stack than usual as well.
     #[cfg(rtopt)]
@@ -341,7 +343,7 @@ pub fn monitor(f: proc(@diagnostic::Emitter)) {
     let mut task_builder = task::task();
     task_builder.name("rustc");
 
-    // XXX: Hacks on hacks. If the env is trying to override the stack size
+    // FIXME: Hacks on hacks. If the env is trying to override the stack size
     // then *don't* set it explicitly.
     if os::getenv("RUST_MIN_STACK").is_none() {
         task_builder.opts.stack_size = Some(STACK_SIZE);
index 3693b00951bcc84bacdfea7f51fe9b91c4d0fc0f..0e5abd64b8ae5f5341bf521c27c58fb0b93fd26e 100644 (file)
@@ -1493,6 +1493,11 @@ pub fn LLVMInlineAsm(Ty: TypeRef,
                              Dialect: c_uint)
                              -> ValueRef;
 
+        pub static LLVMRustDebugMetadataVersion: u32;
+
+        pub fn LLVMRustAddModuleFlag(M: ModuleRef,
+                                     name: *c_char,
+                                     value: u32);
 
         pub fn LLVMDIBuilderCreate(M: ModuleRef) -> DIBuilderRef;
 
@@ -1728,7 +1733,8 @@ pub fn LLVMRustCreateTargetMachine(Triple: *c_char,
                                            Reloc: RelocMode,
                                            Level: CodeGenOptLevel,
                                            EnableSegstk: bool,
-                                           UseSoftFP: bool) -> TargetMachineRef;
+                                           UseSoftFP: bool,
+                                           NoFramePointerElim: bool) -> TargetMachineRef;
         pub fn LLVMRustDisposeTargetMachine(T: TargetMachineRef);
         pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef,
                                          PM: PassManagerRef,
@@ -1762,6 +1768,8 @@ pub fn LLVMRustRunRestrictionPass(M: ModuleRef,
         pub fn LLVMRustArchiveReadSection(AR: ArchiveRef, name: *c_char,
                                           out_len: *mut size_t) -> *c_char;
         pub fn LLVMRustDestroyArchive(AR: ArchiveRef);
+
+        pub fn LLVMRustSetDLLExportStorageClass(V: ValueRef);
     }
 }
 
index 09531e80ae59cf1d038f609195102ce8aa1c2800..e8cfa97c0e1c881bc1fe0e3a1ae2d2119feb0f12 100644 (file)
@@ -176,24 +176,23 @@ pub fn from_uint(value : uint) -> Option<astencode_tag> {
 
 pub static tag_item_method_tps: uint = 0x7b;
 pub static tag_item_method_fty: uint = 0x7c;
-pub static tag_item_method_transformed_self_ty: uint = 0x7d;
 
-pub static tag_mod_child: uint = 0x7e;
-pub static tag_misc_info: uint = 0x7f;
-pub static tag_misc_info_crate_items: uint = 0x80;
+pub static tag_mod_child: uint = 0x7d;
+pub static tag_misc_info: uint = 0x7e;
+pub static tag_misc_info_crate_items: uint = 0x7f;
 
-pub static tag_item_method_provided_source: uint = 0x81;
-pub static tag_item_impl_vtables: uint = 0x82;
+pub static tag_item_method_provided_source: uint = 0x80;
+pub static tag_item_impl_vtables: uint = 0x81;
 
-pub static tag_impls: uint = 0x83;
-pub static tag_impls_impl: uint = 0x84;
+pub static tag_impls: uint = 0x82;
+pub static tag_impls_impl: uint = 0x83;
 
-pub static tag_items_data_item_inherent_impl: uint = 0x85;
-pub static tag_items_data_item_extension_impl: uint = 0x86;
+pub static tag_items_data_item_inherent_impl: uint = 0x84;
+pub static tag_items_data_item_extension_impl: uint = 0x85;
 
-pub static tag_path_elem_pretty_name: uint = 0x87;
-pub static tag_path_elem_pretty_name_ident: uint = 0x88;
-pub static tag_path_elem_pretty_name_extra: uint = 0x89;
+pub static tag_path_elem_pretty_name: uint = 0x86;
+pub static tag_path_elem_pretty_name_ident: uint = 0x87;
+pub static tag_path_elem_pretty_name_extra: uint = 0x88;
 
 pub static tag_region_param_def: uint = 0x100;
 pub static tag_region_param_def_ident: uint = 0x101;
index a7e5082bcbbf6b875e502f90abec7ea78eaa58f2..11fab9cced7f7ac240ac1fcc967fd65c0e1b6daa 100644 (file)
@@ -227,16 +227,6 @@ fn doc_method_fty(doc: ebml::Doc, tcx: ty::ctxt, cdata: Cmd) -> ty::BareFnTy {
                           |_, did| translate_def_id(cdata, did))
 }
 
-fn doc_transformed_self_ty(doc: ebml::Doc,
-                           tcx: ty::ctxt,
-                           cdata: Cmd) -> Option<ty::t>
-{
-    reader::maybe_get_doc(doc, tag_item_method_transformed_self_ty).map(|tp| {
-        parse_ty_data(tp.data, cdata.cnum, tp.start, tcx,
-                      |_, did| translate_def_id(cdata, did))
-    })
-}
-
 pub fn item_type(_item_id: ast::DefId, item: ebml::Doc,
                  tcx: ty::ctxt, cdata: Cmd) -> ty::t {
     doc_type(item, tcx, cdata)
@@ -781,9 +771,9 @@ fn get_mutability(ch: u8) -> ast::Mutability {
     let explicit_self_kind = string[0];
     match explicit_self_kind as char {
         's' => ast::SelfStatic,
-        'v' => ast::SelfValue(get_mutability(string[1])),
+        'v' => ast::SelfValue,
         '@' => ast::SelfBox,
-        '~' => ast::SelfUniq(get_mutability(string[1])),
+        '~' => ast::SelfUniq,
         // FIXME(#4846) expl. region
         '&' => ast::SelfRegion(None, get_mutability(string[1])),
         _ => fail!("unknown self type code: `{}`", explicit_self_kind as char)
@@ -847,7 +837,6 @@ pub fn get_method(intr: @IdentInterner, cdata: Cmd, id: ast::NodeId,
     let type_param_defs = item_ty_param_defs(method_doc, tcx, cdata,
                                              tag_item_method_tps);
     let rp_defs = item_region_param_defs(method_doc, tcx, cdata);
-    let transformed_self_ty = doc_transformed_self_ty(method_doc, tcx, cdata);
     let fty = doc_method_fty(method_doc, tcx, cdata);
     let vis = item_visibility(method_doc);
     let explicit_self = get_explicit_self(method_doc);
@@ -859,7 +848,6 @@ pub fn get_method(intr: @IdentInterner, cdata: Cmd, id: ast::NodeId,
             type_param_defs: type_param_defs,
             region_param_defs: rp_defs,
         },
-        transformed_self_ty,
         fty,
         explicit_self,
         vis,
index 114b74b02de068bf4c68928f5ccaa673b8cc5beb..ac3ee78fb8642948012a120252604453f576a90f 100644 (file)
@@ -261,16 +261,6 @@ fn encode_type(ecx: &EncodeContext,
     ebml_w.end_tag();
 }
 
-fn encode_transformed_self_ty(ecx: &EncodeContext,
-                              ebml_w: &mut writer::Encoder,
-                              opt_typ: Option<ty::t>) {
-    for &typ in opt_typ.iter() {
-        ebml_w.start_tag(tag_item_method_transformed_self_ty);
-        write_type(ecx, ebml_w, typ);
-        ebml_w.end_tag();
-    }
-}
-
 fn encode_method_fty(ecx: &EncodeContext,
                      ebml_w: &mut writer::Encoder,
                      typ: &ty::BareFnTy) {
@@ -679,23 +669,13 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::Explic
 
     // Encode the base self type.
     match explicit_self {
-        SelfStatic => {
-            ebml_w.writer.write(&[ 's' as u8 ]);
-        }
-        SelfValue(m) => {
-            ebml_w.writer.write(&[ 'v' as u8 ]);
-            encode_mutability(ebml_w, m);
-        }
+        SelfStatic => ebml_w.writer.write(&[ 's' as u8 ]),
+        SelfValue  => ebml_w.writer.write(&[ 'v' as u8 ]),
+        SelfBox    => ebml_w.writer.write(&[ '@' as u8 ]),
+        SelfUniq   => ebml_w.writer.write(&[ '~' as u8 ]),
         SelfRegion(_, m) => {
             // FIXME(#4846) encode custom lifetime
-            ebml_w.writer.write(&[ '&' as u8 ]);
-            encode_mutability(ebml_w, m);
-        }
-        SelfBox => {
-            ebml_w.writer.write(&[ '@' as u8 ]);
-        }
-        SelfUniq(m) => {
-            ebml_w.writer.write(&[ '~' as u8 ]);
+            ebml_w.writer.write(&['&' as u8]);
             encode_mutability(ebml_w, m);
         }
     }
@@ -786,6 +766,8 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext,
     ebml_w.start_tag(tag_items_data_item);
     encode_def_id(ebml_w, local_def(ctor_id));
     encode_family(ebml_w, 'f');
+    encode_bounds_and_type(ebml_w, ecx,
+                           &lookup_item_type(ecx.tcx, local_def(ctor_id)));
     encode_name(ecx, ebml_w, name);
     encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, ctor_id));
     encode_path(ecx, ebml_w, path, ast_map::PathName(name));
@@ -807,7 +789,6 @@ fn encode_method_ty_fields(ecx: &EncodeContext,
     encode_ty_type_param_defs(ebml_w, ecx,
                               method_ty.generics.type_param_defs,
                               tag_item_method_tps);
-    encode_transformed_self_ty(ecx, ebml_w, method_ty.transformed_self_ty);
     encode_method_fty(ecx, ebml_w, &method_ty.fty);
     encode_visibility(ebml_w, method_ty.vis);
     encode_explicit_self(ebml_w, method_ty.explicit_self);
@@ -1275,7 +1256,7 @@ fn add_to_index(item: &Item, ebml_w: &writer::Encoder,
                     // If this is a static method, we've already encoded
                     // this.
                     if method_ty.explicit_self != SelfStatic {
-                        // XXX: I feel like there is something funny going on.
+                        // FIXME: I feel like there is something funny going on.
                         let tpt = ty::lookup_item_type(tcx, method_def_id);
                         encode_bounds_and_type(ebml_w, ecx, &tpt);
                     }
index f8e7a28d27708117066d7c43f7c2c26dd99ff7a2..fd8c620dc4e961518899871864149bdfaced16c0 100644 (file)
@@ -160,8 +160,24 @@ fn make_rustpkg_target_lib_path(dir: &Path,
 }
 
 pub fn get_or_default_sysroot() -> Path {
-    match os::self_exe_path() {
-      option::Some(p) => { let mut p = p; p.pop(); p }
+    // Follow symlinks.  If the resolved path is relative, make it absolute.
+    fn canonicalize(path: Option<Path>) -> Option<Path> {
+        path.and_then(|mut path|
+            match io::io_error::cond.trap(|_| ()).inside(|| fs::readlink(&path)) {
+                Some(canon) => {
+                    if canon.is_absolute() {
+                        Some(canon)
+                    } else {
+                        path.pop();
+                        Some(path.join(canon))
+                    }
+                },
+                None => Some(path),
+            })
+    }
+
+    match canonicalize(os::self_exe_name()) {
+      option::Some(p) => { let mut p = p; p.pop(); p.pop(); p }
       option::None => fail!("can't determine value for sysroot")
     }
 }
index 72f2e1baddd7bdd7adb4a2d742382c8b49404358..046184bef58bb3e7e788587ed88525809f31d120 100644 (file)
@@ -33,7 +33,7 @@
 use std::ptr;
 use std::str;
 use std::vec;
-use extra::flate;
+use flate;
 
 pub enum Os {
     OsMacos,
@@ -187,7 +187,7 @@ fn add_existing_rlib(&self, libs: &mut [Library],
         for lib in libs.mut_iter() {
             match lib.dylib {
                 Some(ref p) if p.filename_str() == Some(file.as_slice()) => {
-                    assert!(lib.rlib.is_none()); // XXX: legit compiler error
+                    assert!(lib.rlib.is_none()); // FIXME: legit compiler error
                     lib.rlib = Some(path.clone());
                     return true;
                 }
@@ -207,7 +207,7 @@ fn add_existing_dylib(&self, libs: &mut [Library],
         for lib in libs.mut_iter() {
             match lib.rlib {
                 Some(ref p) if p.filename_str() == Some(file.as_slice()) => {
-                    assert!(lib.dylib.is_none()); // XXX: legit compiler error
+                    assert!(lib.dylib.is_none()); // FIXME: legit compiler error
                     lib.dylib = Some(path.clone());
                     return true;
                 }
index 4f19d461c854c7216d0f42fc67a8d4407e0f6199..c986016206047e15f67f1846c9e6c0ce652e8806 100644 (file)
@@ -374,10 +374,6 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
         return ty::mk_bare_fn(st.tcx, parse_bare_fn_ty(st, |x,y| conv(x,y)));
       }
       'Y' => return ty::mk_type(st.tcx),
-      'C' => {
-        let sigil = parse_sigil(st);
-        return ty::mk_opaque_closure_ptr(st.tcx, sigil);
-      }
       '#' => {
         let pos = parse_hex(st);
         assert_eq!(next(st), ':');
@@ -577,9 +573,12 @@ pub fn parse_type_param_def_data(data: &[u8], start: uint,
 }
 
 fn parse_type_param_def(st: &mut PState, conv: conv_did) -> ty::TypeParameterDef {
-    ty::TypeParameterDef {ident: parse_ident(st, ':'),
-                          def_id: parse_def(st, NominalType, |x,y| conv(x,y)),
-                          bounds: @parse_bounds(st, |x,y| conv(x,y))}
+    ty::TypeParameterDef {
+        ident: parse_ident(st, ':'),
+        def_id: parse_def(st, NominalType, |x,y| conv(x,y)),
+        bounds: @parse_bounds(st, |x,y| conv(x,y)),
+        default: parse_opt(st, |st| parse_ty(st, |x,y| conv(x,y)))
+    }
 }
 
 fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds {
index 965aab31f142682272e137bdd637d64aa3ac8146..9da19d666673f1ab3ba2f8258421da0b047288df 100644 (file)
@@ -327,10 +327,6 @@ fn enc_sty(w: &mut MemWriter, cx: @ctxt, st: &ty::sty) {
             mywrite!(w, "s{}|", (cx.ds)(did));
         }
         ty::ty_type => mywrite!(w, "Y"),
-        ty::ty_opaque_closure_ptr(p) => {
-            mywrite!(w, "C&");
-            enc_sigil(w, p);
-        }
         ty::ty_struct(def, ref substs) => {
             mywrite!(w, "a[{}|", (cx.ds)(def));
             enc_substs(w, cx, substs);
@@ -425,4 +421,5 @@ fn enc_bounds(w: &mut MemWriter, cx: @ctxt, bs: &ty::ParamBounds) {
 pub fn enc_type_param_def(w: &mut MemWriter, cx: @ctxt, v: &ty::TypeParameterDef) {
     mywrite!(w, "{}:{}|", cx.tcx.sess.str_of(v.ident), (cx.ds)(v.def_id));
     enc_bounds(w, cx, v.bounds);
+    enc_opt(w, v.default, |w, t| enc_ty(w, cx, t));
 }
index 5cc522a6e44974ae23a177de410487cada7475ac..a601b624c1979f6f6185350b94219380641bceb5 100644 (file)
@@ -435,7 +435,6 @@ fn tr(&self, xcx: @ExtendedDecodeContext) -> ast::Def {
             ast::DefMethod(did0.tr(xcx), did1.map(|did1| did1.tr(xcx)))
           }
           ast::DefSelfTy(nid) => { ast::DefSelfTy(xcx.tr_id(nid)) }
-          ast::DefSelf(nid, m) => { ast::DefSelf(xcx.tr_id(nid), m) }
           ast::DefMod(did) => { ast::DefMod(did.tr(xcx)) }
           ast::DefForeignMod(did) => { ast::DefForeignMod(did.tr(xcx)) }
           ast::DefStatic(did, m) => { ast::DefStatic(did.tr(xcx), m) }
@@ -579,16 +578,8 @@ fn read_method_map_entry(&mut self, xcx: @ExtendedDecodeContext)
                              -> method_map_entry;
 }
 
-fn encode_method_map_entry(ecx: &e::EncodeContext,
-                           ebml_w: &mut writer::Encoder,
-                           mme: method_map_entry) {
+fn encode_method_map_entry(ebml_w: &mut writer::Encoder, mme: method_map_entry) {
     ebml_w.emit_struct("method_map_entry", 3, |ebml_w| {
-        ebml_w.emit_struct_field("self_ty", 0u, |ebml_w| {
-            ebml_w.emit_ty(ecx, mme.self_ty);
-        });
-        ebml_w.emit_struct_field("explicit_self", 2u, |ebml_w| {
-            mme.explicit_self.encode(ebml_w);
-        });
         ebml_w.emit_struct_field("origin", 1u, |ebml_w| {
             mme.origin.encode(ebml_w);
         });
@@ -600,15 +591,6 @@ fn read_method_map_entry(&mut self, xcx: @ExtendedDecodeContext)
                              -> method_map_entry {
         self.read_struct("method_map_entry", 3, |this| {
             method_map_entry {
-                self_ty: this.read_struct_field("self_ty", 0u, |this| {
-                    this.read_ty(xcx)
-                }),
-                explicit_self: this.read_struct_field("explicit_self",
-                                                      2,
-                                                      |this| {
-                    let explicit_self: ast::ExplicitSelf_ = Decodable::decode(this);
-                    explicit_self
-                }),
                 origin: this.read_struct_field("origin", 1, |this| {
                     let method_origin: method_origin =
                         Decodable::decode(this);
@@ -913,7 +895,7 @@ fn visit_id(&self, id: ast::NodeId) {
         // it is mutable. But I believe it's harmless since we generate
         // balanced EBML.
         //
-        // XXX(pcwalton): Don't copy this way.
+        // FIXME(pcwalton): Don't copy this way.
         let mut new_ebml_w = unsafe {
             self.new_ebml_w.unsafe_clone()
         };
@@ -1043,7 +1025,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
             ebml_w.tag(c::tag_table_method_map, |ebml_w| {
                 ebml_w.id(id);
                 ebml_w.tag(c::tag_table_val, |ebml_w| {
-                    encode_method_map_entry(ecx, ebml_w, *mme)
+                    encode_method_map_entry(ebml_w, *mme)
                 })
             })
         }
index 0fd92079489ae152565dc4958742777192cf1e93..59310d722e426441f3f5a3ae93acc72b463cec61 100644 (file)
@@ -371,9 +371,7 @@ fn mark_variable_as_used_mut(this: &CheckLoanCtxt,
                 debug!("mark_writes_through_upvars_as_used_mut(cmt={})",
                        cmt.repr(this.tcx()));
                 match cmt.cat {
-                    mc::cat_local(id) |
-                    mc::cat_arg(id) |
-                    mc::cat_self(id) => {
+                    mc::cat_local(id) | mc::cat_arg(id) => {
                         let mut used_mut_nodes = this.tcx()
                                                      .used_mut_nodes
                                                      .borrow_mut();
@@ -459,7 +457,6 @@ fn check_for_aliasability_violation(this: &CheckLoanCtxt,
                     mc::cat_rvalue(..) |
                     mc::cat_local(..) |
                     mc::cat_arg(_) |
-                    mc::cat_self(..) |
                     mc::cat_deref(_, _, mc::unsafe_ptr(..)) |
                     mc::cat_static_item(..) |
                     mc::cat_deref(_, _, mc::gc_ptr) |
@@ -790,7 +787,6 @@ fn check_loans_in_expr<'a>(this: &mut CheckLoanCtxt<'a>,
 
     let method_map = this.bccx.method_map.borrow();
     match expr.node {
-      ast::ExprSelf |
       ast::ExprPath(..) => {
           if !this.move_data.is_assignee(expr.id) {
               let cmt = this.bccx.cat_expr_unadjusted(expr);
@@ -808,32 +804,24 @@ fn check_loans_in_expr<'a>(this: &mut CheckLoanCtxt<'a>,
       ast::ExprCall(f, ref args, _) => {
         this.check_call(expr, Some(f), f.id, f.span, *args);
       }
-      ast::ExprMethodCall(callee_id, _, _, _, ref args, _) => {
+      ast::ExprMethodCall(callee_id, _, _, ref args, _) => {
         this.check_call(expr, None, callee_id, expr.span, *args);
       }
       ast::ExprIndex(callee_id, _, rval) |
       ast::ExprBinary(callee_id, _, _, rval)
       if method_map.get().contains_key(&expr.id) => {
-        this.check_call(expr,
-                        None,
-                        callee_id,
-                        expr.span,
-                        [rval]);
+        this.check_call(expr, None, callee_id, expr.span, [rval]);
       }
       ast::ExprUnary(callee_id, _, _) | ast::ExprIndex(callee_id, _, _)
       if method_map.get().contains_key(&expr.id) => {
-        this.check_call(expr,
-                        None,
-                        callee_id,
-                        expr.span,
-                        []);
+        this.check_call(expr, None, callee_id, expr.span, []);
       }
       ast::ExprInlineAsm(ref ia) => {
           for &(_, out) in ia.outputs.iter() {
               this.check_assignment(out);
           }
       }
-      _ => { }
+      _ => {}
     }
 }
 
index 9ba8e00dc8ecbbbd9221148ffd81f2e9bc80b701..78350a993b483c205c72d31db9794d7445f60581 100644 (file)
@@ -133,8 +133,7 @@ fn check_is_legal_to_move_from(bccx: &BorrowckCtxt,
 
         mc::cat_rvalue(..) |
         mc::cat_local(..) |
-        mc::cat_arg(..) |
-        mc::cat_self(..) => {
+        mc::cat_arg(..) => {
             true
         }
 
index 9a4869fb6d1d02ce80b957254594e9aed1435d72..4c2f0986d9cc21e5ff7180ed618929d053a6a468 100644 (file)
@@ -76,7 +76,6 @@ fn check(&self, cmt: mc::cmt, discr_scope: Option<ast::NodeId>) -> R {
             mc::cat_copied_upvar(..) |                  // L-Local
             mc::cat_local(..) |                         // L-Local
             mc::cat_arg(..) |                           // L-Local
-            mc::cat_self(..) |                          // L-Local
             mc::cat_deref(_, _, mc::region_ptr(..)) |   // L-Deref-Borrowed
             mc::cat_deref(_, _, mc::unsafe_ptr(..)) => {
                 let scope = self.scope(cmt);
@@ -261,7 +260,6 @@ fn is_moved(&self, cmt: mc::cmt) -> bool {
 
         match cmt.guarantor().cat {
             mc::cat_local(id) |
-            mc::cat_self(id) |
             mc::cat_arg(id) => {
                 let moved_variables_set = self.bccx
                                               .moved_variables_set
@@ -303,8 +301,7 @@ fn scope(&self, cmt: mc::cmt) -> ty::Region {
                 ty::ReStatic
             }
             mc::cat_local(local_id) |
-            mc::cat_arg(local_id) |
-            mc::cat_self(local_id) => {
+            mc::cat_arg(local_id) => {
                 ty::ReScope(self.bccx.tcx.region_maps.var_scope(local_id))
             }
             mc::cat_deref(_, _, mc::unsafe_ptr(..)) => {
index e45ea77b49e1dfcb6d3794974dd68fa3f34a5903..0ae1fefa2a077a380032eae92364f64ce34dccff 100644 (file)
@@ -416,7 +416,7 @@ pub fn guarantee_adjustments(&mut self,
             }
 
             ty::AutoObject(..) => {
-                // XXX: Handle @Trait to &Trait casts here?
+                // FIXME: Handle @Trait to &Trait casts here?
             }
         }
     }
index 50b437e95d5d16f5e94064a99b6fb9f6bd556bf7..22e64064c9ce56ec46200ac3dae42888104c3bdd 100644 (file)
@@ -74,8 +74,7 @@ fn restrict(&self,
             }
 
             mc::cat_local(local_id) |
-            mc::cat_arg(local_id) |
-            mc::cat_self(local_id) => {
+            mc::cat_arg(local_id) => {
                 // R-Variable
                 let lp = @LpVar(local_id);
                 SafeIf(lp, ~[Restriction {loan_path: lp,
index f1cccab12399dc5cc52b42e40f9d019ddde0be72..90c9a61b18b170266a3aa69286a8546070bce9fd 100644 (file)
@@ -25,6 +25,7 @@
 use std::result::{Result};
 use syntax::ast;
 use syntax::ast_map;
+use syntax::ast_util;
 use syntax::codemap::Span;
 use syntax::parse::token;
 use syntax::visit;
@@ -50,7 +51,7 @@ macro_rules! if_ok(
 
 pub struct LoanDataFlowOperator;
 
-/// XXX(pcwalton): Should just be #[deriving(Clone)], but that doesn't work
+/// FIXME(pcwalton): Should just be #[deriving(Clone)], but that doesn't work
 /// yet on unit structs.
 impl Clone for LoanDataFlowOperator {
     fn clone(&self) -> LoanDataFlowOperator {
@@ -294,9 +295,7 @@ pub fn opt_loan_path(cmt: mc::cmt) -> Option<@LoanPath> {
             None
         }
 
-        mc::cat_local(id) |
-        mc::cat_arg(id) |
-        mc::cat_self(id) => {
+        mc::cat_local(id) | mc::cat_arg(id) => {
             Some(@LpVar(id))
         }
 
@@ -771,8 +770,18 @@ pub fn append_loan_path_to_str(&self,
         match *loan_path {
             LpVar(id) => {
                 match self.tcx.items.find(id) {
-                    Some(ast_map::NodeLocal(ref ident, _)) => {
-                        out.push_str(token::ident_to_str(ident));
+                    Some(ast_map::NodeLocal(pat)) => {
+                        match pat.node {
+                            ast::PatIdent(_, ref path, _) => {
+                                let ident = ast_util::path_to_ident(path);
+                                out.push_str(token::ident_to_str(&ident));
+                            }
+                            _ => {
+                                self.tcx.sess.bug(
+                                    format!("Loan path LpVar({:?}) maps to {:?}, not local",
+                                        id, pat));
+                            }
+                        }
                     }
                     r => {
                         self.tcx.sess.bug(
index 53cf5646cfb54fceca2986b3ab20ab16fd917fcc..ca9bce19ab8a610d0989493e741ba70f2a9fe6cd 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -80,7 +80,7 @@ fn clone(&self) -> MovePathIndex {
 }
 
 static InvalidMovePathIndex: MovePathIndex =
-    MovePathIndex(uint::max_value);
+    MovePathIndex(uint::MAX);
 
 /// Index into `MoveData.moves`, used like a pointer
 #[deriving(Eq)]
@@ -93,7 +93,7 @@ fn get(&self) -> uint {
 }
 
 static InvalidMoveIndex: MoveIndex =
-    MoveIndex(uint::max_value);
+    MoveIndex(uint::MAX);
 
 pub struct MovePath {
     /// Loan path corresponding to this move path
@@ -148,7 +148,7 @@ pub struct Assignment {
 
 pub struct MoveDataFlowOperator;
 
-/// XXX(pcwalton): Should just be #[deriving(Clone)], but that doesn't work
+/// FIXME(pcwalton): Should just be #[deriving(Clone)], but that doesn't work
 /// yet on unit structs.
 impl Clone for MoveDataFlowOperator {
     fn clone(&self) -> MoveDataFlowOperator {
@@ -160,7 +160,7 @@ fn clone(&self) -> MoveDataFlowOperator {
 
 pub struct AssignDataFlowOperator;
 
-/// XXX(pcwalton): Should just be #[deriving(Clone)], but that doesn't work
+/// FIXME(pcwalton): Should just be #[deriving(Clone)], but that doesn't work
 /// yet on unit structs.
 impl Clone for AssignDataFlowOperator {
     fn clone(&self) -> AssignDataFlowOperator {
index dc0b700da522a7d7b9a772e7b18622bb0e862427..eb9c434ca28497192744ba58383873e14fa39f2c 100644 (file)
@@ -355,8 +355,8 @@ fn expr(&mut self, expr: @ast::Expr, pred: CFGIndex) -> CFGIndex {
                 self.call(expr, pred, func, *args)
             }
 
-            ast::ExprMethodCall(_, rcvr, _, _, ref args, _) => {
-                self.call(expr, pred, rcvr, *args)
+            ast::ExprMethodCall(_, _, _, ref args, _) => {
+                self.call(expr, pred, args[0], args.slice_from(1))
             }
 
             ast::ExprIndex(_, l, r) |
@@ -398,7 +398,6 @@ fn expr(&mut self, expr: @ast::Expr, pred: CFGIndex) -> CFGIndex {
             }
 
             ast::ExprAddrOf(_, e) |
-            ast::ExprDoBody(e) |
             ast::ExprCast(e, _) |
             ast::ExprUnary(_, _, e) |
             ast::ExprParen(e) |
@@ -410,7 +409,6 @@ fn expr(&mut self, expr: @ast::Expr, pred: CFGIndex) -> CFGIndex {
             ast::ExprLogLevel |
             ast::ExprMac(..) |
             ast::ExprInlineAsm(..) |
-            ast::ExprSelf |
             ast::ExprFnBlock(..) |
             ast::ExprProc(..) |
             ast::ExprLit(..) |
index 835f53a50ac795288ff6e9755c6f5f87c6446647..a957b8c7ef5f23ec67c3ca8b7042dee2b7bbf655 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -42,7 +42,7 @@ pub struct DataFlowContext<O> {
     priv bits_per_id: uint,
 
     /// number of words we will use to store bits_per_id.
-    /// equal to bits_per_id/uint::bits rounded up.
+    /// equal to bits_per_id/uint::BITS rounded up.
     priv words_per_id: uint,
 
     // mapping from node to bitset index.
@@ -129,7 +129,7 @@ pub fn new(tcx: ty::ctxt,
                oper: O,
                id_range: IdRange,
                bits_per_id: uint) -> DataFlowContext<O> {
-        let words_per_id = (bits_per_id + uint::bits - 1) / uint::bits;
+        let words_per_id = (bits_per_id + uint::BITS - 1) / uint::BITS;
 
         debug!("DataFlowContext::new(id_range={:?}, bits_per_id={:?}, words_per_id={:?})",
                id_range, bits_per_id, words_per_id);
@@ -213,12 +213,12 @@ fn compute_id_range(&mut self, id: ast::NodeId) -> (uint, uint) {
             len
         });
         if expanded {
-            let entry = if self.oper.initial_value() { uint::max_value } else {0};
-            self.words_per_id.times(|| {
+            let entry = if self.oper.initial_value() { uint::MAX } else {0};
+            for _ in range(0, self.words_per_id) {
                 self.gens.push(0);
                 self.kills.push(0);
                 self.on_entry.push(entry);
-            })
+            }
         }
         let start = *n * self.words_per_id;
         let end = start + self.words_per_id;
@@ -291,13 +291,13 @@ fn each_bit(&self, words: &[uint], f: |uint| -> bool) -> bool {
 
         for (word_index, &word) in words.iter().enumerate() {
             if word != 0 {
-                let base_index = word_index * uint::bits;
-                for offset in range(0u, uint::bits) {
+                let base_index = word_index * uint::BITS;
+                for offset in range(0u, uint::BITS) {
                     let bit = 1 << offset;
                     if (word & bit) != 0 {
                         // NB: we round up the total number of bits
                         // that we store in any given bit set so that
-                        // it is an even multiple of uint::bits.  This
+                        // it is an even multiple of uint::BITS.  This
                         // means that there may be some stray bits at
                         // the end that do not correspond to any
                         // actual value.  So before we callback, check
@@ -668,24 +668,21 @@ fn walk_expr(&mut self,
             }
 
             ast::ExprCall(f, ref args, _) => {
-                self.walk_call(f.id, expr.id,
-                               f, *args, in_out, loop_scopes);
+                self.walk_expr(f, in_out, loop_scopes);
+                self.walk_call(f.id, expr.id, *args, in_out, loop_scopes);
             }
 
-            ast::ExprMethodCall(callee_id, rcvr, _, _, ref args, _) => {
-                self.walk_call(callee_id, expr.id,
-                               rcvr, *args, in_out, loop_scopes);
+            ast::ExprMethodCall(callee_id, _, _, ref args, _) => {
+                self.walk_call(callee_id, expr.id, *args, in_out, loop_scopes);
             }
 
             ast::ExprIndex(callee_id, l, r) |
             ast::ExprBinary(callee_id, _, l, r) if self.is_method_call(expr) => {
-                self.walk_call(callee_id, expr.id,
-                               l, [r], in_out, loop_scopes);
+                self.walk_call(callee_id, expr.id, [l, r], in_out, loop_scopes);
             }
 
             ast::ExprUnary(callee_id, _, e) if self.is_method_call(expr) => {
-                self.walk_call(callee_id, expr.id,
-                               e, [], in_out, loop_scopes);
+                self.walk_call(callee_id, expr.id, [e], in_out, loop_scopes);
             }
 
             ast::ExprTup(ref exprs) => {
@@ -706,12 +703,9 @@ fn walk_expr(&mut self,
 
             ast::ExprLogLevel |
             ast::ExprLit(..) |
-            ast::ExprPath(..) |
-            ast::ExprSelf => {
-            }
+            ast::ExprPath(..) => {}
 
             ast::ExprAddrOf(_, e) |
-            ast::ExprDoBody(e) |
             ast::ExprCast(e, _) |
             ast::ExprUnary(_, _, e) |
             ast::ExprParen(e) |
@@ -813,11 +807,9 @@ fn walk_opt_expr(&mut self,
     fn walk_call(&mut self,
                  _callee_id: ast::NodeId,
                  call_id: ast::NodeId,
-                 arg0: &ast::Expr,
                  args: &[@ast::Expr],
                  in_out: &mut [uint],
                  loop_scopes: &mut ~[LoopScope]) {
-        self.walk_expr(arg0, in_out, loop_scopes);
         self.walk_exprs(args, in_out, loop_scopes);
 
         // FIXME(#6268) nested method calls
@@ -908,7 +900,7 @@ fn is_method_call(&self, expr: &ast::Expr) -> bool {
     }
 
     fn reset(&mut self, bits: &mut [uint]) {
-        let e = if self.dfcx.oper.initial_value() {uint::max_value} else {0};
+        let e = if self.dfcx.oper.initial_value() {uint::MAX} else {0};
         for b in bits.mut_iter() { *b = e; }
     }
 
@@ -959,7 +951,7 @@ fn bits_to_str(words: &[uint]) -> ~str {
 
     for &word in words.iter() {
         let mut v = word;
-        for _ in range(0u, uint::bytes) {
+        for _ in range(0u, uint::BYTES) {
             result.push_char(sep);
             result.push_str(format!("{:02x}", v & 0xFF));
             v >>= 8;
@@ -997,8 +989,8 @@ fn bitwise(out_vec: &mut [uint], in_vec: &[uint], op: |uint, uint| -> uint)
 fn set_bit(words: &mut [uint], bit: uint) -> bool {
     debug!("set_bit: words={} bit={}",
            mut_bits_to_str(words), bit_str(bit));
-    let word = bit / uint::bits;
-    let bit_in_word = bit % uint::bits;
+    let word = bit / uint::BITS;
+    let bit_in_word = bit % uint::BITS;
     let bit_mask = 1 << bit_in_word;
     debug!("word={} bit_in_word={} bit_mask={}", word, bit_in_word, word);
     let oldv = words[word];
index e291d2595a0b2cde584098833cbdeb12605d5463..36dd46388c6243691db329282c292b62c270607f 100644 (file)
@@ -120,7 +120,7 @@ fn visit_block(&mut self, block: &ast::Block, _:()) {
 
     fn visit_expr(&mut self, expr: &ast::Expr, _:()) {
         match expr.node {
-            ast::ExprMethodCall(callee_id, _, _, _, _, _) => {
+            ast::ExprMethodCall(callee_id, _, _, _, _) => {
                 let base_type = ty::node_id_to_type(self.tcx, callee_id);
                 debug!("effect: method call case, base type is {}",
                        ppaux::ty_to_str(self.tcx, base_type));
index 4ee8eb4108d1643801a774d2c527cf94dc55a114..635fbf7eea81662007f59469dae7a86a0b832dd2 100644 (file)
@@ -48,7 +48,7 @@ fn visit_expr(&mut self, expr: &ast::Expr, depth: int) {
             ast::ExprFnBlock(..) | ast::ExprProc(..) => {
                 visit::walk_expr(self, expr, depth + 1)
             }
-            ast::ExprPath(..) | ast::ExprSelf => {
+            ast::ExprPath(..) => {
                 let mut i = 0;
                 let def_map = self.def_map.borrow();
                 match def_map.get().find(&expr.id) {
index 3b998f4379d33e89bc8464fdfb79d4b7070c4e41..a83e1f601249304aef224dcc19818cc944df8635 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -56,11 +56,11 @@ pub struct Edge<E> {
 
 #[deriving(Eq)]
 pub struct NodeIndex(uint);
-pub static InvalidNodeIndex: NodeIndex = NodeIndex(uint::max_value);
+pub static InvalidNodeIndex: NodeIndex = NodeIndex(uint::MAX);
 
 #[deriving(Eq)]
 pub struct EdgeIndex(uint);
-pub static InvalidEdgeIndex: EdgeIndex = EdgeIndex(uint::max_value);
+pub static InvalidEdgeIndex: EdgeIndex = EdgeIndex(uint::MAX);
 
 // Use a private field here to guarantee no more instances are created:
 pub struct Direction { priv repr: uint }
index fde3e4809c39abb2d9c30b491fb74d0d182032f9..880074256c02b2086d898044190d7e00a6d567bd 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -184,9 +184,6 @@ fn check_for_uniq(cx: &Context, fv: &freevar_entry, bounds: ty::BuiltinBounds) {
         let id = ast_util::def_id_of_def(fv.def).node;
         let var_t = ty::node_id_to_type(cx.tcx, id);
 
-        // check that only immutable variables are implicitly copied in
-        check_imm_free_var(cx, fv.def, fv.span);
-
         check_freevar_bounds(cx, fv.span, var_t, bounds, None);
     }
 
@@ -447,24 +444,6 @@ pub fn check_trait_cast_bounds(cx: &Context, sp: Span, ty: ty::t,
     });
 }
 
-fn check_imm_free_var(cx: &Context, def: Def, sp: Span) {
-    match def {
-        DefLocal(_, BindByValue(MutMutable)) => {
-            cx.tcx.sess.span_err(
-                sp,
-                "mutable variables cannot be implicitly captured");
-        }
-        DefLocal(..) | DefArg(..) => { /* ok */ }
-        DefUpvar(_, def1, _, _) => { check_imm_free_var(cx, *def1, sp); }
-        DefBinding(..) | DefSelf(..) => { /*ok*/ }
-        _ => {
-            cx.tcx.sess.span_bug(
-                sp,
-                format!("unknown def for free variable: {:?}", def));
-        }
-    }
-}
-
 fn check_copy(cx: &Context, ty: ty::t, sp: Span, reason: &str) {
     debug!("type_contents({})={}",
            ty_to_str(cx.tcx, ty),
index 7e6db24a4a319138a685e0eedbd3e39571378f6b..89d5ca740120ede60bb51689eefaee90798a7c23 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -86,6 +86,7 @@ pub enum Lint {
     AttributeUsage,
     UnknownFeatures,
     UnknownCrateType,
+    DefaultTypeParamUsage,
 
     ManagedHeapMemory,
     OwnedHeapMemory,
@@ -105,6 +106,9 @@ pub enum Lint {
     Experimental,
     Unstable,
 
+    UnusedMustUse,
+    UnusedResult,
+
     Warnings,
 }
 
@@ -356,10 +360,32 @@ enum LintSource {
         desc: "unknown features found in crate-level #[feature] directives",
         default: deny,
     }),
-     ("unknown_crate_type",
+
+    ("unknown_crate_type",
+    LintSpec {
+        lint: UnknownCrateType,
+        desc: "unknown crate type found in #[crate_type] directive",
+        default: deny,
+    }),
+
+    ("unused_must_use",
+    LintSpec {
+        lint: UnusedMustUse,
+        desc: "unused result of an type flagged as #[must_use]",
+        default: warn,
+    }),
+
+    ("unused_result",
+    LintSpec {
+        lint: UnusedResult,
+        desc: "unused result of an expression in a statement",
+        default: allow,
+    }),
+
+     ("default_type_param_usage",
      LintSpec {
-         lint: UnknownCrateType,
-         desc: "unknown crate type found in #[crate_type] directive",
+         lint: DefaultTypeParamUsage,
+         desc: "prevents explicitly setting a type parameter with a default",
          default: deny,
      }),
 ];
@@ -523,10 +549,10 @@ fn with_lint_attrs(&mut self,
 
         // rollback
         self.is_doc_hidden = old_is_doc_hidden;
-        pushed.times(|| {
+        for _ in range(0, pushed) {
             let (lint, lvl, src) = self.lint_stack.pop().unwrap();
             self.set_level(lint, lvl, src);
-        })
+        }
     }
 
     fn visit_ids(&self, f: |&mut ast_util::IdVisitor<Context>|) {
@@ -724,21 +750,21 @@ fn rev_binop(binop: ast::BinOp) -> ast::BinOp {
     // warnings are consistent between 32- and 64-bit platforms
     fn int_ty_range(int_ty: ast::IntTy) -> (i64, i64) {
         match int_ty {
-            ast::TyI =>    (i64::min_value,        i64::max_value),
-            ast::TyI8 =>   (i8::min_value  as i64, i8::max_value  as i64),
-            ast::TyI16 =>  (i16::min_value as i64, i16::max_value as i64),
-            ast::TyI32 =>  (i32::min_value as i64, i32::max_value as i64),
-            ast::TyI64 =>  (i64::min_value,        i64::max_value)
+            ast::TyI =>    (i64::MIN,        i64::MAX),
+            ast::TyI8 =>   (i8::MIN  as i64, i8::MAX  as i64),
+            ast::TyI16 =>  (i16::MIN as i64, i16::MAX as i64),
+            ast::TyI32 =>  (i32::MIN as i64, i32::MAX as i64),
+            ast::TyI64 =>  (i64::MIN,        i64::MAX)
         }
     }
 
     fn uint_ty_range(uint_ty: ast::UintTy) -> (u64, u64) {
         match uint_ty {
-            ast::TyU =>   (u64::min_value,         u64::max_value),
-            ast::TyU8 =>  (u8::min_value   as u64, u8::max_value   as u64),
-            ast::TyU16 => (u16::min_value  as u64, u16::max_value  as u64),
-            ast::TyU32 => (u32::min_value  as u64, u32::max_value  as u64),
-            ast::TyU64 => (u64::min_value,         u64::max_value)
+            ast::TyU =>   (u64::MIN,         u64::MAX),
+            ast::TyU8 =>  (u8::MIN   as u64, u8::MAX   as u64),
+            ast::TyU16 => (u16::MIN  as u64, u16::MAX  as u64),
+            ast::TyU32 => (u32::MIN  as u64, u32::MAX  as u64),
+            ast::TyU64 => (u64::MIN,         u64::MAX)
         }
     }
 
@@ -934,7 +960,7 @@ fn check_heap_item(cx: &Context, it: &ast::Item) {
     "crate_map", "cfg", "doc", "export_name", "link_section", "no_freeze",
     "no_mangle", "no_send", "static_assert", "unsafe_no_drop_flag", "packed",
     "simd", "repr", "deriving", "unsafe_destructor", "link", "phase",
-    "macro_export",
+    "macro_export", "must_use",
 
     //mod-level
     "path", "link_name", "link_args", "nolink", "macro_escape", "no_implicit_prelude",
@@ -1016,6 +1042,54 @@ fn check_path_statement(cx: &Context, s: &ast::Stmt) {
     }
 }
 
+fn check_unused_result(cx: &Context, s: &ast::Stmt) {
+    let expr = match s.node {
+        ast::StmtSemi(expr, _) => expr,
+        _ => return
+    };
+    let t = ty::expr_ty(cx.tcx, expr);
+    match ty::get(t).sty {
+        ty::ty_nil | ty::ty_bot | ty::ty_bool => return,
+        _ => {}
+    }
+    match expr.node {
+        ast::ExprRet(..) => return,
+        _ => {}
+    }
+
+    let t = ty::expr_ty(cx.tcx, expr);
+    let mut warned = false;
+    match ty::get(t).sty {
+        ty::ty_struct(did, _) |
+        ty::ty_enum(did, _) => {
+            if ast_util::is_local(did) {
+                match cx.tcx.items.get(did.node) {
+                    ast_map::NodeItem(it, _) => {
+                        if attr::contains_name(it.attrs, "must_use") {
+                            cx.span_lint(UnusedMustUse, s.span,
+                                         "unused result which must be used");
+                            warned = true;
+                        }
+                    }
+                    _ => {}
+                }
+            } else {
+                csearch::get_item_attrs(cx.tcx.sess.cstore, did, |attrs| {
+                    if attr::contains_name(attrs, "must_use") {
+                        cx.span_lint(UnusedMustUse, s.span,
+                                     "unused result which must be used");
+                        warned = true;
+                    }
+                });
+            }
+        }
+        _ => {}
+    }
+    if !warned {
+        cx.span_lint(UnusedResult, s.span, "unused result");
+    }
+}
+
 fn check_item_non_camel_case_types(cx: &Context, it: &ast::Item) {
     fn is_camel_case(cx: ty::ctxt, ident: ast::Ident) -> bool {
         let ident = cx.sess.str_of(ident);
@@ -1478,6 +1552,7 @@ fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
 
     fn visit_stmt(&mut self, s: &ast::Stmt, _: ()) {
         check_path_statement(self, s);
+        check_unused_result(self, s);
 
         visit::walk_stmt(self, s, ());
     }
index d8bf115eb42b298f0c7b0166ba702fae29e86201..6a1fa488121bb58ffff60a3ce3934f22de3c6b8c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -215,11 +215,11 @@ fn to_str(&self) -> ~str { format!("v({})", self.get()) }
 
 impl LiveNode {
     pub fn is_valid(&self) -> bool {
-        self.get() != uint::max_value
+        self.get() != uint::MAX
     }
 }
 
-fn invalid_node() -> LiveNode { LiveNode(uint::max_value) }
+fn invalid_node() -> LiveNode { LiveNode(uint::MAX) }
 
 struct CaptureInfo {
     ln: LiveNode,
@@ -405,20 +405,6 @@ fn visit_fn(v: &mut LivenessVisitor,
         })
     };
 
-    // Add `this`, whether explicit or implicit.
-    match *fk {
-        visit::FkMethod(_, _, method) => {
-            match method.explicit_self.node {
-                SelfValue(_) | SelfRegion(..) | SelfBox | SelfUniq(_) => {
-                    fn_maps.add_variable(Arg(method.self_id,
-                                             special_idents::self_));
-                }
-                SelfStatic => {}
-            }
-        }
-        visit::FkItemFn(..) | visit::FkFnBlock(..) => {}
-    }
-
     // gather up the various local variables, significant expressions,
     // and so forth:
     visit::walk_fn(v, fk, decl, body, sp, id, fn_maps);
@@ -493,7 +479,7 @@ fn visit_arm(v: &mut LivenessVisitor, arm: &Arm, this: @IrMaps) {
 fn visit_expr(v: &mut LivenessVisitor, expr: &Expr, this: @IrMaps) {
     match expr.node {
       // live nodes required for uses or definitions of variables:
-      ExprPath(_) | ExprSelf => {
+      ExprPath(_) => {
         let def_map = this.tcx.def_map.borrow();
         let def = def_map.get().get_copy(&expr.id);
         debug!("expr {}: path that leads to {:?}", expr.id, def);
@@ -552,7 +538,7 @@ fn visit_expr(v: &mut LivenessVisitor, expr: &Expr, this: @IrMaps) {
       ExprIndex(..) | ExprField(..) | ExprVstore(..) | ExprVec(..) |
       ExprCall(..) | ExprMethodCall(..) | ExprTup(..) | ExprLogLevel |
       ExprBinary(..) | ExprAddrOf(..) |
-      ExprDoBody(..) | ExprCast(..) | ExprUnary(..) | ExprBreak(_) |
+      ExprCast(..) | ExprUnary(..) | ExprBreak(_) |
       ExprAgain(_) | ExprLit(_) | ExprRet(..) | ExprBlock(..) |
       ExprAssign(..) | ExprAssignOp(..) | ExprMac(..) |
       ExprStruct(..) | ExprRepeat(..) | ExprParen(..) |
@@ -1050,7 +1036,7 @@ pub fn propagate_through_expr(&self, expr: @Expr, succ: LiveNode)
         match expr.node {
           // Interesting cases with control flow or which gen/kill
 
-          ExprPath(_) | ExprSelf => {
+          ExprPath(_) => {
               self.access_path(expr, succ, ACC_READ | ACC_USE)
           }
 
@@ -1229,14 +1215,13 @@ pub fn propagate_through_expr(&self, expr: @Expr, succ: LiveNode)
             self.propagate_through_expr(f, succ)
           }
 
-          ExprMethodCall(callee_id, rcvr, _, _, ref args, _) => {
+          ExprMethodCall(callee_id, _, _, 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::ty_fn_ret(ty::node_id_to_type(self.tcx, callee_id));
             let succ = if ty::type_is_bot(t_ret) {self.s.exit_ln}
                        else {succ};
-            let succ = self.propagate_through_exprs(*args, succ);
-            self.propagate_through_expr(rcvr, succ)
+            self.propagate_through_exprs(*args, succ)
           }
 
           ExprTup(ref exprs) => {
@@ -1260,7 +1245,6 @@ pub fn propagate_through_expr(&self, expr: @Expr, succ: LiveNode)
           }
 
           ExprAddrOf(_, e) |
-          ExprDoBody(e) |
           ExprCast(e, _) |
           ExprUnary(_, _, e) |
           ExprParen(e) => {
@@ -1544,12 +1528,12 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
       ExprCall(..) | ExprMethodCall(..) | ExprIf(..) | ExprMatch(..) |
       ExprWhile(..) | ExprLoop(..) | ExprIndex(..) | ExprField(..) |
       ExprVstore(..) | ExprVec(..) | ExprTup(..) | ExprLogLevel |
-      ExprBinary(..) | ExprDoBody(..) |
+      ExprBinary(..) |
       ExprCast(..) | ExprUnary(..) | ExprRet(..) | ExprBreak(..) |
       ExprAgain(..) | ExprLit(_) | ExprBlock(..) |
       ExprMac(..) | ExprAddrOf(..) | ExprStruct(..) | ExprRepeat(..) |
       ExprParen(..) | ExprFnBlock(..) | ExprProc(..) | ExprPath(..) |
-      ExprSelf(..) | ExprBox(..) => {
+      ExprBox(..) => {
         visit::walk_expr(this, expr, ());
       }
       ExprForLoop(..) => fail!("non-desugared expr_for_loop")
@@ -1694,9 +1678,13 @@ pub fn warn_about_unused_args(&self, decl: &FnDecl, entry_ln: LiveNode) {
         for arg in decl.inputs.iter() {
             pat_util::pat_bindings(self.tcx.def_map,
                                    arg.pat,
-                                   |_bm, p_id, sp, _n| {
+                                   |_bm, p_id, sp, path| {
                 let var = self.variable(p_id, sp);
-                self.warn_about_unused(sp, p_id, entry_ln, var);
+                // Ignore unused self.
+                let ident = ast_util::path_to_ident(path);
+                if ident.name != special_idents::self_.name {
+                    self.warn_about_unused(sp, p_id, entry_ln, var);
+                }
             })
         }
     }
index 70d4f63a16449942ce484033f1b95c347df2f00e..ce1840283b2e4e3691c7f373dbeee6cc70159b8d 100644 (file)
@@ -70,7 +70,6 @@ pub enum categorization {
     cat_interior(cmt, InteriorKind),   // something interior: field, tuple, etc
     cat_downcast(cmt),                 // selects a particular enum variant (..)
     cat_discr(cmt, ast::NodeId),       // match discriminant (see preserve())
-    cat_self(ast::NodeId),             // explicit `self`
 
     // (..) downcast is only required if the enum has more than one variant
 }
@@ -357,7 +356,7 @@ pub fn cat_expr(&self, expr: &ast::Expr) -> cmt {
                         // Convert a bare fn to a closure by adding NULL env.
                         // Result is an rvalue.
                         let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
-                        self.cat_rvalue_node(expr, expr_ty)
+                        self.cat_rvalue_node(expr.id(), expr.span(), expr_ty)
                     }
 
                     ty::AutoDerefRef(ty::AutoDerefRef {
@@ -366,7 +365,7 @@ pub fn cat_expr(&self, expr: &ast::Expr) -> cmt {
                         // Equivalent to &*expr or something similar.
                         // Result is an rvalue.
                         let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
-                        self.cat_rvalue_node(expr, expr_ty)
+                        self.cat_rvalue_node(expr.id(), expr.span(), expr_ty)
                     }
 
                     ty::AutoDerefRef(ty::AutoDerefRef {
@@ -399,7 +398,7 @@ pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> cmt {
           ast::ExprUnary(_, ast::UnDeref, e_base) => {
             let method_map = self.method_map.borrow();
             if method_map.get().contains_key(&expr.id) {
-                return self.cat_rvalue_node(expr, expr_ty);
+                return self.cat_rvalue_node(expr.id(), expr.span(), expr_ty);
             }
 
             let base_cmt = self.cat_expr(e_base);
@@ -419,14 +418,14 @@ pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> cmt {
           ast::ExprIndex(_, base, _) => {
             let method_map = self.method_map.borrow();
             if method_map.get().contains_key(&expr.id) {
-                return self.cat_rvalue_node(expr, expr_ty);
+                return self.cat_rvalue_node(expr.id(), expr.span(), expr_ty);
             }
 
             let base_cmt = self.cat_expr(base);
             self.cat_index(expr, base_cmt, 0)
           }
 
-          ast::ExprPath(_) | ast::ExprSelf => {
+          ast::ExprPath(_) => {
             let def_map = self.tcx.def_map.borrow();
             let def = def_map.get().get_copy(&expr.id);
             self.cat_def(expr.id, expr.span, expr_ty, def)
@@ -437,7 +436,7 @@ pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> cmt {
           ast::ExprAddrOf(..) | ast::ExprCall(..) |
           ast::ExprAssign(..) | ast::ExprAssignOp(..) |
           ast::ExprFnBlock(..) | ast::ExprProc(..) | ast::ExprRet(..) |
-          ast::ExprDoBody(..) | ast::ExprUnary(..) |
+          ast::ExprUnary(..) |
           ast::ExprMethodCall(..) | ast::ExprCast(..) | ast::ExprVstore(..) |
           ast::ExprVec(..) | ast::ExprTup(..) | ast::ExprIf(..) |
           ast::ExprLogLevel | ast::ExprBinary(..) | ast::ExprWhile(..) |
@@ -445,7 +444,7 @@ pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> cmt {
           ast::ExprLit(..) | ast::ExprBreak(..) | ast::ExprMac(..) |
           ast::ExprAgain(..) | ast::ExprStruct(..) | ast::ExprRepeat(..) |
           ast::ExprInlineAsm(..) | ast::ExprBox(..) => {
-            return self.cat_rvalue_node(expr, expr_ty);
+            return self.cat_rvalue_node(expr.id(), expr.span(), expr_ty);
           }
 
           ast::ExprForLoop(..) => fail!("non-desugared expr_for_loop")
@@ -458,13 +457,18 @@ pub fn cat_def(&self,
                    expr_ty: ty::t,
                    def: ast::Def)
                    -> cmt {
+        debug!("cat_def: id={} expr={}",
+               id, ty_to_str(self.tcx, expr_ty));
+
+
         match def {
+          ast::DefStruct(..) | ast::DefVariant(..) => {
+                self.cat_rvalue_node(id, span, expr_ty)
+          }
           ast::DefFn(..) | ast::DefStaticMethod(..) | ast::DefMod(_) |
           ast::DefForeignMod(_) | ast::DefStatic(_, false) |
-          ast::DefUse(_) | ast::DefVariant(..) |
-          ast::DefTrait(_) | ast::DefTy(_) | ast::DefPrimTy(_) |
-          ast::DefTyParam(..) | ast::DefStruct(..) |
-          ast::DefTyParamBinder(..) | ast::DefRegion(_) |
+          ast::DefUse(_) | ast::DefTrait(_) | ast::DefTy(_) | ast::DefPrimTy(_) |
+          ast::DefTyParam(..) | ast::DefTyParamBinder(..) | ast::DefRegion(_) |
           ast::DefLabel(_) | ast::DefSelfTy(..) | ast::DefMethod(..) => {
               @cmt_ {
                   id:id,
@@ -503,16 +507,6 @@ pub fn cat_def(&self,
             }
           }
 
-          ast::DefSelf(self_id, mutbl) => {
-            @cmt_ {
-                id:id,
-                span:span,
-                cat:cat_self(self_id),
-                mutbl: if mutbl { McDeclared } else { McImmutable },
-                ty:expr_ty
-            }
-          }
-
           ast::DefUpvar(upvar_id, inner, fn_node_id, _) => {
               let ty = ty::node_id_to_type(self.tcx, fn_node_id);
               match ty::get(ty).sty {
@@ -582,16 +576,13 @@ pub fn cat_def(&self,
         }
     }
 
-    pub fn cat_rvalue_node<N:ast_node>(&self,
-                                       node: &N,
-                                       expr_ty: ty::t) -> cmt {
-        match self.tcx.region_maps.temporary_scope(node.id()) {
+    pub fn cat_rvalue_node(&self, id: ast::NodeId, span: Span, expr_ty: ty::t) -> cmt {
+        match self.tcx.region_maps.temporary_scope(id) {
             Some(scope) => {
-                self.cat_rvalue(node.id(), node.span(),
-                                ty::ReScope(scope), expr_ty)
+                self.cat_rvalue(id, span, ty::ReScope(scope), expr_ty)
             }
             None => {
-                self.cat_rvalue(node.id(), node.span(), ty::ReStatic, expr_ty)
+                self.cat_rvalue(id, span, ty::ReStatic, expr_ty)
             }
         }
     }
@@ -997,7 +988,7 @@ pub fn cat_pattern(&self,
               }
               for &slice_pat in slice.iter() {
                   let slice_ty = self.pat_ty(slice_pat);
-                  let slice_cmt = self.cat_rvalue_node(pat, slice_ty);
+                  let slice_cmt = self.cat_rvalue_node(pat.id(), pat.span(), slice_ty);
                   self.cat_pattern(slice_cmt, slice_pat, |x,y| op(x,y));
               }
               for &after_pat in after.iter() {
@@ -1032,9 +1023,6 @@ pub fn cmt_to_str(&self, cmt: cmt) -> ~str {
           cat_local(_) => {
               ~"local variable"
           }
-          cat_self(_) => {
-              ~"self value"
-          }
           cat_arg(..) => {
               ~"argument"
           }
@@ -1129,7 +1117,6 @@ pub fn guarantor(@self) -> cmt {
             cat_static_item |
             cat_copied_upvar(..) |
             cat_local(..) |
-            cat_self(..) |
             cat_arg(..) |
             cat_deref(_, _, unsafe_ptr(..)) |
             cat_deref(_, _, gc_ptr) |
@@ -1165,7 +1152,6 @@ pub fn freely_aliasable(&self) -> Option<AliasableReason> {
             cat_rvalue(..) |
             cat_local(..) |
             cat_arg(_) |
-            cat_self(..) |
             cat_deref(_, _, unsafe_ptr(..)) | // of course it is aliasable, but...
             cat_deref(_, _, region_ptr(MutMutable, _)) => {
                 None
@@ -1212,7 +1198,6 @@ fn repr(&self, tcx: ty::ctxt) -> ~str {
             cat_rvalue(..) |
             cat_copied_upvar(..) |
             cat_local(..) |
-            cat_self(..) |
             cat_arg(..) => {
                 format!("{:?}", *self)
             }
index e0146694881b7d5d04e61e201b390a1f327d85c9..b0171eafeb3fa1c041c9a0ed0f41f9493d93e88a 100644 (file)
@@ -227,10 +227,9 @@ pub fn compute_moves(tcx: ty::ctxt,
 
 pub fn moved_variable_node_id_from_def(def: Def) -> Option<NodeId> {
     match def {
-      DefBinding(nid, _) |
-      DefArg(nid, _) |
-      DefLocal(nid, _) |
-      DefSelf(nid, _) => Some(nid),
+        DefBinding(nid, _) |
+        DefArg(nid, _) |
+        DefLocal(nid, _) => Some(nid),
 
       _ => None
     }
@@ -344,7 +343,7 @@ pub fn use_expr(&mut self,
         debug!("comp_mode = {:?}", comp_mode);
 
         match expr.node {
-            ExprPath(..) | ExprSelf => {
+            ExprPath(..) => {
                 match comp_mode {
                     Move => {
                         let def_map = self.tcx.def_map.borrow();
@@ -413,10 +412,7 @@ pub fn use_expr(&mut self,
                 self.use_fn_args(callee.id, *args);
             }
 
-            ExprMethodCall(callee_id, rcvr, _, _, ref args, _) => { // callee.m(args)
-                // Implicit self is equivalent to & mode, but every
-                // other kind should be + mode.
-                self.use_receiver(rcvr);
+            ExprMethodCall(callee_id, _, _, ref args, _) => { // callee.m(args)
                 self.use_fn_args(callee_id, *args);
             }
 
@@ -574,10 +570,6 @@ fn has_dtor(tcx: ty::ctxt, ty: ty::t) -> bool {
                 self.consume_expr(count);
             }
 
-            ExprDoBody(base) => {
-                self.use_expr(base, comp_mode);
-            }
-
             ExprFnBlock(ref decl, body) |
             ExprProc(ref decl, body) => {
                 for a in decl.inputs.iter() {
@@ -620,7 +612,7 @@ pub fn use_overloaded_operator(&mut self,
             return false;
         }
 
-        self.use_receiver(receiver_expr);
+        self.use_fn_arg(receiver_expr);
 
         // for overloaded operatrs, we are always passing in a
         // reference, so it's always read mode:
@@ -675,11 +667,6 @@ pub fn use_pat(&mut self, pat: @Pat) {
         })
     }
 
-    pub fn use_receiver(&mut self,
-                        receiver_expr: @Expr) {
-        self.use_fn_arg(receiver_expr);
-    }
-
     pub fn use_fn_args(&mut self,
                        _: NodeId,
                        arg_exprs: &[@Expr]) {
index 3d5267cd9285cce528250e63c097eb6e288cb9c9..2562c34b54b00e4661de9362727a93abbce3400c 100644 (file)
@@ -15,6 +15,7 @@
 use std::hashmap::{HashSet, HashMap};
 use std::util;
 
+use metadata::csearch;
 use middle::resolve;
 use middle::ty;
 use middle::typeck::{method_map, method_origin, method_param};
@@ -123,22 +124,7 @@ fn visit_struct_def(&mut self, s: &ast::StructDef, i: ast::Ident,
         // While we have the id of the struct definition, go ahead and parent
         // all the fields.
         for field in s.fields.iter() {
-            let vis = match field.node.kind {
-                ast::NamedField(_, vis) => vis,
-                ast::UnnamedField => continue
-            };
-
-            // Private fields are scoped to this module, so parent them directly
-            // to the module instead of the struct. This is similar to the case
-            // of private enum variants.
-            if vis == ast::Private {
-                self.parents.insert(field.node.id, self.curparent);
-
-            // Otherwise public fields are scoped to the visibility of the
-            // struct itself
-            } else {
-                self.parents.insert(field.node.id, n);
-            }
+            self.parents.insert(field.node.id, self.curparent);
         }
         visit::walk_struct_def(self, s, i, g, n, ())
     }
@@ -338,7 +324,7 @@ fn visit_mod(&mut self, m: &ast::Mod, _sp: Span, id: ast::NodeId, _: ()) {
             let exp_map2 = self.exp_map2.borrow();
             assert!(exp_map2.get().contains_key(&id), "wut {:?}", id);
             for export in exp_map2.get().get(&id).iter() {
-                if is_local(export.def_id) && export.reexport {
+                if is_local(export.def_id) {
                     self.reexports.insert(export.def_id.node);
                 }
             }
@@ -558,12 +544,48 @@ fn ensure_public(&self, span: Span, to_check: ast::DefId,
 
     // Checks that a field is in scope.
     // FIXME #6993: change type (and name) from Ident to Name
-    fn check_field(&mut self, span: Span, id: ast::DefId, ident: ast::Ident) {
+    fn check_field(&mut self, span: Span, id: ast::DefId, ident: ast::Ident,
+                   enum_id: Option<ast::DefId>) {
         let fields = ty::lookup_struct_fields(self.tcx, id);
+        let struct_vis = if is_local(id) {
+            match self.tcx.items.get(id.node) {
+                ast_map::NodeItem(ref it, _) => it.vis,
+                ast_map::NodeVariant(ref v, ref it, _) => {
+                    if v.node.vis == ast::Inherited {it.vis} else {v.node.vis}
+                }
+                _ => {
+                    self.tcx.sess.span_bug(span,
+                                           format!("not an item or variant def"));
+                }
+            }
+        } else {
+            let cstore = self.tcx.sess.cstore;
+            match enum_id {
+                Some(enum_id) => {
+                    let v = csearch::get_enum_variants(self.tcx, enum_id);
+                    match v.iter().find(|v| v.id == id) {
+                        Some(variant) => {
+                            if variant.vis == ast::Inherited {
+                                csearch::get_item_visibility(cstore, enum_id)
+                            } else {
+                                variant.vis
+                            }
+                        }
+                        None => {
+                            self.tcx.sess.span_bug(span, "no xcrate variant");
+                        }
+                    }
+                }
+                None => csearch::get_item_visibility(cstore, id)
+            }
+        };
+
         for field in fields.iter() {
             if field.name != ident.name { continue; }
-            // public fields are public everywhere
-            if field.vis != ast::Private { break }
+            // public structs have public fields by default, and private structs
+            // have private fields by default.
+            if struct_vis == ast::Public && field.vis != ast::Private { break }
+            if struct_vis != ast::Public && field.vis == ast::Public { break }
             if !is_local(field.id) ||
                !self.private_accessible(field.id.node) {
                 self.tcx.sess.span_err(span, format!("field `{}` is private",
@@ -661,14 +683,14 @@ fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
                 let t = ty::type_autoderef(ty::expr_ty(self.tcx, base));
                 match ty::get(t).sty {
                     ty::ty_struct(id, _) => {
-                        self.check_field(expr.span, id, ident);
+                        self.check_field(expr.span, id, ident, None);
                     }
                     _ => {}
                 }
             }
-            ast::ExprMethodCall(_, base, ident, _, _, _) => {
+            ast::ExprMethodCall(_, ident, _, ref args, _) => {
                 // see above
-                let t = ty::type_autoderef(ty::expr_ty(self.tcx, base));
+                let t = ty::type_autoderef(ty::expr_ty(self.tcx, args[0]));
                 match ty::get(t).sty {
                     ty::ty_enum(_, _) | ty::ty_struct(_, _) => {
                         let method_map = self.method_map.borrow();
@@ -690,16 +712,18 @@ fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
                 match ty::get(ty::expr_ty(self.tcx, expr)).sty {
                     ty::ty_struct(id, _) => {
                         for field in (*fields).iter() {
-                            self.check_field(expr.span, id, field.ident.node);
+                            self.check_field(expr.span, id, field.ident.node,
+                                             None);
                         }
                     }
                     ty::ty_enum(_, _) => {
                         let def_map = self.tcx.def_map.borrow();
                         match def_map.get().get_copy(&expr.id) {
-                            ast::DefVariant(_, variant_id, _) => {
+                            ast::DefVariant(enum_id, variant_id, _) => {
                                 for field in fields.iter() {
                                     self.check_field(expr.span, variant_id,
-                                                     field.ident.node);
+                                                     field.ident.node,
+                                                     Some(enum_id));
                                 }
                             }
                             _ => self.tcx.sess.span_bug(expr.span,
@@ -763,16 +787,17 @@ fn visit_pat(&mut self, pattern: &ast::Pat, _: ()) {
                 match ty::get(ty::pat_ty(self.tcx, pattern)).sty {
                     ty::ty_struct(id, _) => {
                         for field in fields.iter() {
-                            self.check_field(pattern.span, id, field.ident);
+                            self.check_field(pattern.span, id, field.ident,
+                                             None);
                         }
                     }
                     ty::ty_enum(_, _) => {
                         let def_map = self.tcx.def_map.borrow();
                         match def_map.get().find(&pattern.id) {
-                            Some(&ast::DefVariant(_, variant_id, _)) => {
+                            Some(&ast::DefVariant(enum_id, variant_id, _)) => {
                                 for field in fields.iter() {
                                     self.check_field(pattern.span, variant_id,
-                                                     field.ident);
+                                                     field.ident, Some(enum_id));
                                 }
                             }
                             _ => self.tcx.sess.span_bug(pattern.span,
@@ -888,15 +913,22 @@ fn check_sane_privacy(&self, item: &ast::Item) {
                 }
             }
         };
-        let check_struct = |def: &@ast::StructDef| {
+        let check_struct = |def: &@ast::StructDef,
+                            vis: ast::Visibility,
+                            parent_vis: Option<ast::Visibility>| {
+            let public_def = match vis {
+                ast::Public => true,
+                ast::Inherited | ast::Private => parent_vis == Some(ast::Public),
+            };
             for f in def.fields.iter() {
                match f.node.kind {
-                    ast::NamedField(_, ast::Public) => {
+                    ast::NamedField(_, ast::Public) if public_def => {
                         tcx.sess.span_err(f.span, "unnecessary `pub` \
                                                    visibility");
                     }
-                    ast::NamedField(_, ast::Private) => {
-                        // Fields should really be private by default...
+                    ast::NamedField(_, ast::Private) if !public_def => {
+                        tcx.sess.span_err(f.span, "unnecessary `priv` \
+                                                   visibility");
                     }
                     ast::NamedField(..) | ast::UnnamedField => {}
                 }
@@ -951,13 +983,15 @@ fn check_sane_privacy(&self, item: &ast::Item) {
                     }
 
                     match v.node.kind {
-                        ast::StructVariantKind(ref s) => check_struct(s),
+                        ast::StructVariantKind(ref s) => {
+                            check_struct(s, v.node.vis, Some(item.vis));
+                        }
                         ast::TupleVariantKind(..) => {}
                     }
                 }
             }
 
-            ast::ItemStruct(ref def, _) => check_struct(def),
+            ast::ItemStruct(ref def, _) => check_struct(def, item.vis, None),
 
             ast::ItemTrait(_, _, ref methods) => {
                 for m in methods.iter() {
index 66d706e3621c10b53d45140e8b10e7bbbd600cff..071371c6b616c53607c68cfebe5c0eba06008b02 100644 (file)
@@ -404,7 +404,7 @@ fn propagate_node(&self, node: &ast_map::Node,
 
     // Step 3: Mark all destructors as reachable.
     //
-    // XXX(pcwalton): This is a conservative overapproximation, but fixing
+    // FIXME(pcwalton): This is a conservative overapproximation, but fixing
     // this properly would result in the necessity of computing *type*
     // reachability, which might result in a compile time loss.
     fn mark_destructors_reachable(&self) {
index c202684c7abff850b8bda193579a63158132bd70..9c11b89bb7e7ddcbfb7eb67bbfca34b2c93b5502 100644 (file)
@@ -172,7 +172,14 @@ pub fn temporary_scope(&self, expr_id: ast::NodeId) -> Option<ast::NodeId> {
         }
 
         // else, locate the innermost terminating scope
-        let mut id = self.encl_scope(expr_id);
+        // if there's one. Static items, for instance, won't
+        // have an enclusing scope, hence no scope will be
+        // returned.
+        let mut id = match self.opt_encl_scope(expr_id) {
+            Some(i) => i,
+            None => { return None; }
+        };
+
         let terminating_scopes = self.terminating_scopes.borrow();
         while !terminating_scopes.get().contains(&id) {
             match self.opt_encl_scope(id) {
@@ -820,12 +827,6 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor,
     // The arguments and `self` are parented to the body of the fn.
     let decl_cx = Context {parent: Some(body.id),
                            var_parent: Some(body.id)};
-    match *fk {
-        visit::FkMethod(_, _, method) => {
-            visitor.region_maps.record_var_scope(method.self_id, body.id);
-        }
-        _ => {}
-    }
     visit::walk_fn_decl(visitor, decl, decl_cx);
 
     // The body of the fn itself is either a root scope (top-level fn)
index 082c755b8321e37646db0aad730375388e500c7c..e235e914689e8f6b6bfe485b4b504f50cc1bbce7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -55,14 +55,13 @@ struct binding_info {
 pub struct Export2 {
     name: @str,        // The name of the target.
     def_id: DefId,     // The definition of the target.
-    reexport: bool,     // Whether this is a reexport.
 }
 
 // This set contains all exported definitions from external crates. The set does
 // not contain any entries from local crates.
 pub type ExternalExports = HashSet<DefId>;
 
-// XXX: dox
+// FIXME: dox
 pub type LastPrivateMap = HashMap<NodeId, LastPrivate>;
 
 pub enum LastPrivate {
@@ -131,11 +130,6 @@ enum NameDefinition {
     ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
 }
 
-enum SelfBinding {
-    NoSelfBinding,
-    HasSelfBinding(NodeId, ExplicitSelf)
-}
-
 impl Visitor<()> for Resolver {
     fn visit_item(&mut self, item: &Item, _: ()) {
         self.resolve_item(item);
@@ -259,12 +253,6 @@ enum ModulePrefixResult {
     PrefixFound(@Module, uint)
 }
 
-#[deriving(Eq)]
-enum AllowCapturingSelfFlag {
-    AllowCapturingSelf,         //< The "self" definition can be captured.
-    DontAllowCapturingSelf,     //< The "self" definition cannot be captured.
-}
-
 #[deriving(Eq)]
 enum NameSearchType {
     /// We're doing a name search in order to resolve a `use` directive.
@@ -295,7 +283,6 @@ enum DuplicateCheckingMode {
 /// One local scope.
 struct Rib {
     bindings: RefCell<HashMap<Name, DefLike>>,
-    self_binding: RefCell<Option<DefLike>>,
     kind: RibKind,
 }
 
@@ -303,7 +290,6 @@ impl Rib {
     fn new(kind: RibKind) -> Rib {
         Rib {
             bindings: RefCell::new(HashMap::new()),
-            self_binding: RefCell::new(None),
             kind: kind
         }
     }
@@ -1412,7 +1398,7 @@ fn build_reduced_graph_for_variant(&mut self,
                                        parent: ReducedGraphParent,
                                        parent_public: bool) {
         let ident = variant.node.name;
-        // XXX: this is unfortunate to have to do this privacy calculation
+        // FIXME: this is unfortunate to have to do this privacy calculation
         //      here. This should be living in middle::privacy, but it's
         //      necessary to keep around in some form becaues of glob imports...
         let is_public = parent_public && variant.node.vis != ast::Private;
@@ -1747,8 +1733,8 @@ trait method '{}'",
                       ignoring {:?}", def);
               // Ignored; handled elsewhere.
           }
-          DefSelf(..) | DefArg(..) | DefLocal(..) |
-          DefPrimTy(..) | DefTyParam(..) | DefBinding(..) |
+          DefArg(..) | DefLocal(..) | DefPrimTy(..) |
+          DefTyParam(..) | DefBinding(..) |
           DefUse(..) | DefUpvar(..) | DefRegion(..) |
           DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
             fail!("didn't expect `{:?}`", def);
@@ -3364,22 +3350,19 @@ fn add_exports_of_namebindings(&mut self,
                                    exports2: &mut ~[Export2],
                                    name: Name,
                                    namebindings: @NameBindings,
-                                   ns: Namespace,
-                                   reexport: bool) {
+                                   ns: Namespace) {
         match namebindings.def_for_namespace(ns) {
             Some(d) => {
-                debug!("(computing exports) YES: {} '{}' => {:?}",
-                       if reexport { ~"reexport" } else { ~"export"},
+                debug!("(computing exports) YES: export '{}' => {:?}",
                        interner_get(name),
                        def_id_of_def(d));
                 exports2.push(Export2 {
-                    reexport: reexport,
                     name: interner_get(name),
                     def_id: def_id_of_def(d)
                 });
             }
             d_opt => {
-                debug!("(computing reexports) NO: {:?}", d_opt);
+                debug!("(computing exports) NO: {:?}", d_opt);
             }
         }
     }
@@ -3396,13 +3379,12 @@ fn add_exports_for_module(&mut self,
             for &ns in xs.iter() {
                 match importresolution.target_for_namespace(ns) {
                     Some(target) => {
-                        debug!("(computing exports) maybe reexport '{}'",
+                        debug!("(computing exports) maybe export '{}'",
                                interner_get(*name));
                         self.add_exports_of_namebindings(exports2,
                                                          *name,
                                                          target.bindings,
-                                                         ns,
-                                                         true)
+                                                         ns)
                     }
                     _ => ()
                 }
@@ -3474,8 +3456,7 @@ fn upvarify(&mut self,
                     ribs: &mut ~[@Rib],
                     rib_index: uint,
                     def_like: DefLike,
-                    span: Span,
-                    allow_capturing_self: AllowCapturingSelfFlag)
+                    span: Span)
                     -> Option<DefLike> {
         let mut def;
         let is_ty_param;
@@ -3490,11 +3471,6 @@ fn upvarify(&mut self,
                 def = d;
                 is_ty_param = true;
             }
-            DlDef(d @ DefSelf(..))
-                    if allow_capturing_self == DontAllowCapturingSelf => {
-                def = d;
-                is_ty_param = false;
-            }
             _ => {
                 return Some(def_like);
             }
@@ -3594,8 +3570,7 @@ fn upvarify(&mut self,
     fn search_ribs(&mut self,
                        ribs: &mut ~[@Rib],
                        name: Name,
-                       span: Span,
-                       allow_capturing_self: AllowCapturingSelfFlag)
+                       span: Span)
                        -> Option<DefLike> {
         // FIXME #4950: This should not use a while loop.
         // FIXME #4950: Try caching?
@@ -3609,8 +3584,7 @@ fn search_ribs(&mut self,
             };
             match binding_opt {
                 Some(def_like) => {
-                    return self.upvarify(ribs, i, def_like, span,
-                                         allow_capturing_self);
+                    return self.upvarify(ribs, i, def_like, span);
                 }
                 None => {
                     // Continue.
@@ -3791,8 +3765,7 @@ fn resolve_item(&mut self, item: &Item) {
                                          item.id,
                                          0,
                                          OpaqueFunctionRibKind),
-                                      block,
-                                      NoSelfBinding);
+                                      block);
             }
 
             ItemStatic(..) => {
@@ -3888,11 +3861,10 @@ fn with_constant_rib(&mut self, f: |&mut Resolver|) {
     }
 
     fn resolve_function(&mut self,
-                            rib_kind: RibKind,
-                            optional_declaration: Option<P<FnDecl>>,
-                            type_parameters: TypeParameters,
-                            block: P<Block>,
-                            self_binding: SelfBinding) {
+                        rib_kind: RibKind,
+                        optional_declaration: Option<P<FnDecl>>,
+                        type_parameters: TypeParameters,
+                        block: P<Block>) {
         // Create a value rib for the function.
         let function_value_rib = @Rib::new(rib_kind);
         {
@@ -3919,21 +3891,6 @@ fn resolve_function(&mut self,
                 }
             }
 
-            // Add self to the rib, if necessary.
-            match self_binding {
-                NoSelfBinding => {
-                    // Nothing to do.
-                }
-                HasSelfBinding(self_node_id, explicit_self) => {
-                    let mutable = match explicit_self.node {
-                        SelfUniq(m) | SelfValue(m) if m == MutMutable => true,
-                        _ => false
-                    };
-                    let def_like = DlDef(DefSelf(self_node_id, mutable));
-                    function_value_rib.self_binding.set(Some(def_like));
-                }
-            }
-
             // Add each argument to the rib.
             match optional_declaration {
                 None => {
@@ -3974,6 +3931,10 @@ fn resolve_type_parameters(&mut self,
             for bound in type_parameter.bounds.iter() {
                 self.resolve_type_parameter_bound(type_parameter.id, bound);
             }
+            match type_parameter.default {
+                Some(ty) => self.resolve_type(ty),
+                None => {}
+            }
         }
     }
 
@@ -4055,26 +4016,17 @@ fn resolve_struct(&mut self,
     // Does this really need to take a RibKind or is it always going
     // to be NormalRibKind?
     fn resolve_method(&mut self,
-                          rib_kind: RibKind,
-                          method: @Method,
-                          outer_type_parameter_count: uint) {
+                      rib_kind: RibKind,
+                      method: @Method,
+                      outer_type_parameter_count: uint) {
         let method_generics = &method.generics;
         let type_parameters =
             HasTypeParameters(method_generics,
                               method.id,
                               outer_type_parameter_count,
                               rib_kind);
-        // we only have self ty if it is a non static method
-        let self_binding = match method.explicit_self.node {
-            SelfStatic => NoSelfBinding,
-            _ => HasSelfBinding(method.self_id, method.explicit_self)
-        };
 
-        self.resolve_function(rib_kind,
-                              Some(method.decl),
-                              type_parameters,
-                              method.body,
-                              self_binding);
+        self.resolve_function(rib_kind, Some(method.decl), type_parameters, method.body);
     }
 
     fn resolve_implementation(&mut self,
@@ -4140,9 +4092,7 @@ fn resolve_implementation(&mut self,
                                              method.id,
                                              outer_type_parameter_count,
                                              NormalRibKind),
-                                          method.body,
-                                          HasSelfBinding(method.self_id),
-                                          visitor);
+                                          method.body);
 */
             }
 
@@ -4979,16 +4929,14 @@ fn resolve_identifier_in_local_ribs(&mut self,
                 let mut value_ribs = self.value_ribs.borrow_mut();
                 search_result = self.search_ribs(value_ribs.get(),
                                                  renamed,
-                                                 span,
-                                                 DontAllowCapturingSelf);
+                                                 span);
             }
             TypeNS => {
                 let name = ident.name;
                 let mut type_ribs = self.type_ribs.borrow_mut();
                 search_result = self.search_ribs(type_ribs.get(),
                                                  name,
-                                                 span,
-                                                 AllowCapturingSelf);
+                                                 span);
             }
         }
 
@@ -5006,46 +4954,6 @@ fn resolve_identifier_in_local_ribs(&mut self,
         }
     }
 
-    fn resolve_self_value_in_local_ribs(&mut self, span: Span)
-                                            -> Option<Def> {
-        // FIXME #4950: This should not use a while loop.
-        let mut i = {
-            let value_ribs = self.value_ribs.borrow();
-            value_ribs.get().len()
-        };
-        while i != 0 {
-            i -= 1;
-            let self_binding_opt = {
-                let value_ribs = self.value_ribs.borrow();
-                value_ribs.get()[i].self_binding.get()
-            };
-            match self_binding_opt {
-                Some(def_like) => {
-                    let mut value_ribs = self.value_ribs.borrow_mut();
-                    match self.upvarify(value_ribs.get(),
-                                        i,
-                                        def_like,
-                                        span,
-                                        DontAllowCapturingSelf) {
-                        Some(DlDef(def)) => return Some(def),
-                        _ => {
-                            if self.session.has_errors() {
-                                // May happen inside a nested fn item, cf #6642.
-                                return None;
-                            } else {
-                                self.session.span_bug(span,
-                                        "self wasn't mapped to a def?!")
-                            }
-                        }
-                    }
-                }
-                None => {}
-            }
-        }
-
-        None
-    }
-
     fn resolve_item_by_identifier_in_lexical_scope(&mut self,
                                                    ident: Ident,
                                                    namespace: Namespace)
@@ -5117,7 +5025,7 @@ fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
             let bindings = value_ribs.get()[j].bindings.borrow();
             for (&k, _) in bindings.get().iter() {
                 maybes.push(interner_get(k));
-                values.push(uint::max_value);
+                values.push(uint::MAX);
             }
         }
 
@@ -5131,7 +5039,7 @@ fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
         }
 
         if values.len() > 0 &&
-            values[smallest] != uint::max_value &&
+            values[smallest] != uint::MAX &&
             values[smallest] < name.len() + 2 &&
             values[smallest] <= max_distance &&
             name != maybes[smallest] {
@@ -5229,10 +5137,8 @@ fn resolve_expr(&mut self, expr: &Expr) {
             ExprFnBlock(fn_decl, block) |
             ExprProc(fn_decl, block) => {
                 self.resolve_function(FunctionRibKind(expr.id, block.id),
-                                      Some(fn_decl),
-                                      NoTypeParameters,
-                                      block,
-                                      NoSelfBinding);
+                                      Some(fn_decl), NoTypeParameters,
+                                      block);
             }
 
             ExprStruct(ref path, _, _) => {
@@ -5279,15 +5185,14 @@ fn resolve_expr(&mut self, expr: &Expr) {
 
             ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
                 let mut label_ribs = self.label_ribs.borrow_mut();
-                match self.search_ribs(label_ribs.get(), label, expr.span,
-                                       DontAllowCapturingSelf) {
+                match self.search_ribs(label_ribs.get(), label, expr.span) {
                     None =>
                         self.resolve_error(expr.span,
                                               format!("use of undeclared label \
                                                    `{}`",
                                                    interner_get(label))),
                     Some(DlDef(def @ DefLabel(_))) => {
-                        // XXX: is AllPublic correct?
+                        // FIXME: is AllPublic correct?
                         self.record_def(expr.id, (def, AllPublic))
                     }
                     Some(_) => {
@@ -5298,17 +5203,6 @@ fn resolve_expr(&mut self, expr: &Expr) {
                 }
             }
 
-            ExprSelf => {
-                match self.resolve_self_value_in_local_ribs(expr.span) {
-                    None => {
-                        self.resolve_error(expr.span,
-                                              "`self` is not allowed in \
-                                               this context")
-                    }
-                    Some(def) => self.record_def(expr.id, (def, AllPublic)),
-                }
-            }
-
             _ => {
                 visit::walk_expr(self, expr, ());
             }
@@ -5325,7 +5219,7 @@ fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
                 let traits = self.search_for_traits_containing_method(ident);
                 self.trait_map.insert(expr.id, @RefCell::new(traits));
             }
-            ExprMethodCall(_, _, ident, _, _, _) => {
+            ExprMethodCall(_, ident, _, _, _) => {
                 debug!("(recording candidate traits for expr) recording \
                         traits for {}",
                        expr.id);
index 89442d0cc848b9580df4d408dc656b06bad9943a..067082992c6fc87554ee60162b78ba4d8438f211 100644 (file)
@@ -164,7 +164,8 @@ fn subst(&self, tcx: ty::ctxt, substs: &ty::substs) -> ty::TypeParameterDef {
         ty::TypeParameterDef {
             ident: self.ident,
             def_id: self.def_id,
-            bounds: self.bounds.subst(tcx, substs)
+            bounds: self.bounds.subst(tcx, substs),
+            default: self.default.map(|x| x.subst(tcx, substs))
         }
     }
 }
index 5bd8eb6386fcff4d055f44f7cf84c096270fa5ae..2fabc44d0e4b208f8bc950c4503c983b7247c188 100644 (file)
@@ -337,8 +337,8 @@ fn trans_opt<'a>(bcx: &'a Block<'a>, o: &Opt) -> opt_result<'a> {
             return adt::trans_case(bcx, repr, disr_val);
         }
         range(l1, l2) => {
-            let (l1, _) = consts::const_expr(ccx, l1);
-            let (l2, _) = consts::const_expr(ccx, l2);
+            let (l1, _) = consts::const_expr(ccx, l1, true);
+            let (l2, _) = consts::const_expr(ccx, l2, true);
             return range_result(rslt(bcx, l1), rslt(bcx, l2));
         }
         vec_len(n, vec_len_eq, _) => {
@@ -399,13 +399,17 @@ struct BindingInfo {
 
 type BindingsMap = HashMap<Ident, BindingInfo>;
 
-#[deriving(Clone)]
 struct ArmData<'a,'b> {
     bodycx: &'b Block<'b>,
     arm: &'a ast::Arm,
     bindings_map: @BindingsMap
 }
 
+// FIXME #11820: method resolution is unreliable with &
+impl<'a,'b> Clone for ArmData<'a, 'b> {
+    fn clone(&self) -> ArmData<'a, 'b> { *self }
+}
+
 /**
  * Info about Match.
  * If all `pats` are matched then arm `data` will be executed.
@@ -643,7 +647,7 @@ fn enter_opt<'r,'b>(
             }
             ast::PatEnum(_, ref subpats) => {
                 if opt_eq(tcx, &variant_opt(bcx, p.id), opt) {
-                    // XXX: Must we clone?
+                    // FIXME: Must we clone?
                     match *subpats {
                         None => Some(vec::from_elem(variant_size, dummy)),
                         _ => (*subpats).clone(),
@@ -2227,5 +2231,3 @@ fn bind_irrefutable_pat<'a>(
     }
     return bcx;
 }
-
-
index 7b194690b2f23efbbc85c2fc0aeba98512f79197..9f28385aa5ca6900793a4badad2340353c50b2a3 100644 (file)
@@ -805,7 +805,7 @@ fn padding(size: u64) -> ValueRef {
     C_undef(Type::array(&Type::i8(), size))
 }
 
-// XXX this utility routine should be somewhere more general
+// FIXME this utility routine should be somewhere more general
 #[inline]
 fn roundup(x: u64, a: u64) -> u64 { ((x + (a - 1)) / a) * a }
 
index 5b246daa6c5b54ef30a17c06017a1cac9b28f127..d39369c7a5f47288090bc9870cdf7e7f9a83369d 100644 (file)
@@ -30,7 +30,7 @@
 use driver::session::Session;
 use driver::driver::{CrateAnalysis, CrateTranslation};
 use lib::llvm::{ModuleRef, ValueRef, BasicBlockRef};
-use lib::llvm::{llvm, True};
+use lib::llvm::{llvm, True, Vector};
 use lib;
 use metadata::common::LinkMeta;
 use metadata::{csearch, encoder};
@@ -68,7 +68,7 @@
 use util::ppaux::{Repr, ty_to_str};
 use util::sha2::Sha256;
 
-use extra::arena::TypedArena;
+use arena::TypedArena;
 use extra::time;
 use std::c_str::ToCStr;
 use std::cell::{Cell, RefCell};
@@ -240,7 +240,7 @@ fn get_extern_rust_fn(ccx: &CrateContext, inputs: &[ty::t], output: ty::t,
         }
     }
 
-    let f = decl_rust_fn(ccx, None, inputs, output, name);
+    let f = decl_rust_fn(ccx, false, inputs, output, name);
     csearch::get_item_attrs(ccx.tcx.cstore, did, |meta_items| {
         set_llvm_fn_attrs(meta_items.iter().map(|&x| attr::mk_attr(x)).to_owned_vec(), f)
     });
@@ -250,16 +250,15 @@ fn get_extern_rust_fn(ccx: &CrateContext, inputs: &[ty::t], output: ty::t,
     f
 }
 
-fn decl_rust_fn(ccx: &CrateContext,
-                self_ty: Option<ty::t>,
-                inputs: &[ty::t],
-                output: ty::t,
-                name: &str) -> ValueRef {
-    let llfty = type_of_rust_fn(ccx, self_ty, inputs, output);
+pub fn decl_rust_fn(ccx: &CrateContext, has_env: bool,
+                    inputs: &[ty::t], output: ty::t,
+                    name: &str) -> ValueRef {
+    let llfty = type_of_rust_fn(ccx, has_env, inputs, output);
     let llfn = decl_cdecl_fn(ccx.llmod, name, llfty, output);
 
     let uses_outptr = type_of::return_uses_outptr(ccx, output);
-    let offset = if uses_outptr { 2 } else { 1 };
+    let offset = if uses_outptr { 1 } else { 0 };
+    let offset = if has_env { offset + 1 } else { offset };
 
     for (i, &arg_ty) in inputs.iter().enumerate() {
         let llarg = unsafe { llvm::LLVMGetParam(llfn, (offset + i) as c_uint) };
@@ -292,10 +291,10 @@ fn decl_rust_fn(ccx: &CrateContext,
     llfn
 }
 
-pub fn decl_internal_rust_fn(ccx: &CrateContext,
-                             self_ty: Option<ty::t>, inputs: &[ty::t],
-                             output: ty::t, name: &str) -> ValueRef {
-    let llfn = decl_rust_fn(ccx, self_ty, inputs, output, name);
+pub fn decl_internal_rust_fn(ccx: &CrateContext, has_env: bool,
+                             inputs: &[ty::t], output: ty::t,
+                             name: &str) -> ValueRef {
+    let llfn = decl_rust_fn(ccx, has_env, inputs, output, name);
     lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
     llfn
 }
@@ -318,14 +317,10 @@ pub fn get_extern_const(externs: &mut ExternMap, llmod: ModuleRef,
 // Returns a pointer to the body for the box. The box may be an opaque
 // box. The result will be casted to the type of body_t, if it is statically
 // known.
-//
-// The runtime equivalent is box_body() in "rust_internal.h".
-pub fn opaque_box_body(bcx: &Block, body_t: ty::t, boxptr: ValueRef)
-                       -> ValueRef {
-    let _icx = push_ctxt("opaque_box_body");
+pub fn at_box_body(bcx: &Block, body_t: ty::t, boxptr: ValueRef) -> ValueRef {
+    let _icx = push_ctxt("at_box_body");
     let ccx = bcx.ccx();
-    let ty = type_of(ccx, body_t);
-    let ty = Type::smart_ptr(ccx, &ty);
+    let ty = Type::at_box(ccx, type_of(ccx, body_t));
     let boxptr = PointerCast(bcx, boxptr, ty.ptr_to());
     GEPi(bcx, boxptr, [0u, abi::box_field_body])
 }
@@ -381,7 +376,7 @@ fn require_alloc_fn(bcx: &Block, t: ty::t, it: LangItem) -> ast::DefId {
 
         // Get the tydesc for the body:
         let static_ti = get_tydesc(ccx, t);
-        glue::lazily_emit_all_tydesc_glue(ccx, static_ti);
+        glue::lazily_emit_tydesc_glue(ccx, abi::tydesc_field_drop_glue, static_ti);
 
         // Allocate space:
         let tydesc = PointerCast(bcx, static_ti.tydesc, Type::i8p());
@@ -782,9 +777,6 @@ fn iter_variant<'r,
                       let variant_cx =
                           fcx.new_temp_block(~"enum-iter-variant-" +
                                              variant.disr_val.to_str());
-                      let variant_cx =
-                          iter_variant(variant_cx, repr, av, *variant,
-                                       substs.tps, |x,y,z| f(x,y,z));
                       match adt::trans_case(cx, repr, variant.disr_val) {
                           _match::single_result(r) => {
                               AddCase(llswitch, r.val, variant_cx.llbb)
@@ -792,6 +784,9 @@ fn iter_variant<'r,
                           _ => ccx.sess.unimpl("value from adt::trans_case \
                                                 in iter_structural_ty")
                       }
+                      let variant_cx =
+                          iter_variant(variant_cx, repr, av, *variant,
+                                       substs.tps, |x,y,z| f(x,y,z));
                       Br(variant_cx, next_cx.llbb);
                   }
                   cx = next_cx;
@@ -832,8 +827,10 @@ pub fn cast_shift_rhs(op: ast::BinOp,
     // Shifts may have any size int on the rhs
     unsafe {
         if ast_util::is_shift_binop(op) {
-            let rhs_llty = val_ty(rhs);
-            let lhs_llty = val_ty(lhs);
+            let mut rhs_llty = val_ty(rhs);
+            let mut lhs_llty = val_ty(lhs);
+            if rhs_llty.kind() == Vector { rhs_llty = rhs_llty.element_type() }
+            if lhs_llty.kind() == Vector { lhs_llty = lhs_llty.element_type() }
             let rhs_sz = llvm::LLVMGetIntTypeWidth(rhs_llty.to_ref());
             let lhs_sz = llvm::LLVMGetIntTypeWidth(lhs_llty.to_ref());
             if lhs_sz < rhs_sz {
@@ -882,10 +879,6 @@ pub fn fail_if_zero<'a>(
     })
 }
 
-pub fn null_env_ptr(ccx: &CrateContext) -> ValueRef {
-    C_null(Type::opaque_box(ccx).ptr_to())
-}
-
 pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> ValueRef {
     let name = csearch::get_symbol(ccx.sess.cstore, did);
     match ty::get(t).sty {
@@ -898,7 +891,7 @@ pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> Val
                 Some(..) | None => {
                     let c = foreign::llvm_calling_convention(ccx, fn_ty.abis);
                     let cconv = c.unwrap_or(lib::llvm::CCallConv);
-                    let llty = type_of_fn_from_ty(ccx, None, t);
+                    let llty = type_of_fn_from_ty(ccx, t);
                     let mut externs = ccx.externs.borrow_mut();
                     get_extern_fn(externs.get(), ccx.llmod, name,
                                   cconv, llty, fn_ty.sig.output)
@@ -1241,6 +1234,7 @@ pub fn new_fn_ctxt_detailed(ccx: @CrateContext,
                             path: ast_map::Path,
                             llfndecl: ValueRef,
                             id: ast::NodeId,
+                            has_env: bool,
                             output_type: ty::t,
                             param_substs: Option<@param_substs>,
                             sp: Option<Span>)
@@ -1263,33 +1257,33 @@ pub fn new_fn_ctxt_detailed(ccx: @CrateContext,
     let uses_outptr = type_of::return_uses_outptr(ccx, substd_output_type);
     let debug_context = debuginfo::create_function_debug_context(ccx, id, param_substs, llfndecl);
 
-    let fcx = FunctionContext {
-          llfn: llfndecl,
-          llenv: unsafe {
-              Cell::new(llvm::LLVMGetUndef(Type::i8p().to_ref()))
-          },
-          llretptr: Cell::new(None),
-          entry_bcx: RefCell::new(None),
-          alloca_insert_pt: Cell::new(None),
-          llreturn: Cell::new(None),
-          llself: Cell::new(None),
-          personality: Cell::new(None),
-          caller_expects_out_pointer: uses_outptr,
-          llargs: RefCell::new(HashMap::new()),
-          lllocals: RefCell::new(HashMap::new()),
-          llupvars: RefCell::new(HashMap::new()),
-          id: id,
-          param_substs: param_substs,
-          span: sp,
-          path: path,
-          block_arena: TypedArena::new(),
-          ccx: ccx,
-          debug_context: debug_context,
-          scopes: RefCell::new(~[])
+    let mut fcx = FunctionContext {
+        llfn: llfndecl,
+        llenv: None,
+        llretptr: Cell::new(None),
+        entry_bcx: RefCell::new(None),
+        alloca_insert_pt: Cell::new(None),
+        llreturn: Cell::new(None),
+        personality: Cell::new(None),
+        caller_expects_out_pointer: uses_outptr,
+        llargs: RefCell::new(HashMap::new()),
+        lllocals: RefCell::new(HashMap::new()),
+        llupvars: RefCell::new(HashMap::new()),
+        id: id,
+        param_substs: param_substs,
+        span: sp,
+        path: path,
+        block_arena: TypedArena::new(),
+        ccx: ccx,
+        debug_context: debug_context,
+        scopes: RefCell::new(~[])
     };
-    fcx.llenv.set(unsafe {
-          llvm::LLVMGetParam(llfndecl, fcx.env_arg_pos() as c_uint)
-    });
+
+    if has_env {
+        fcx.llenv = Some(unsafe {
+            llvm::LLVMGetParam(fcx.llfn, fcx.env_arg_pos() as c_uint)
+        });
+    }
 
     fcx
 }
@@ -1301,14 +1295,16 @@ pub fn init_function<'a>(
                      skip_retptr: bool,
                      output_type: ty::t,
                      param_substs: Option<@param_substs>) {
-    unsafe {
-        let entry_bcx = fcx.new_temp_block("entry-block");
-        Load(entry_bcx, C_null(Type::i8p()));
+    let entry_bcx = fcx.new_temp_block("entry-block");
 
-        fcx.entry_bcx.set(Some(entry_bcx));
-        fcx.alloca_insert_pt.set(Some(
-                llvm::LLVMGetFirstInstruction(entry_bcx.llbb)));
-    }
+    fcx.entry_bcx.set(Some(entry_bcx));
+
+    // Use a dummy instruction as the insertion point for all allocas.
+    // This is later removed in FunctionContext::cleanup.
+    fcx.alloca_insert_pt.set(Some(unsafe {
+        Load(entry_bcx, C_null(Type::i8p()));
+        llvm::LLVMGetFirstInstruction(entry_bcx.llbb)
+    }));
 
     let substd_output_type = match param_substs {
         None => output_type,
@@ -1327,8 +1323,7 @@ pub fn init_function<'a>(
             // Otherwise, we normally allocate the llretptr, unless we
             // have been instructed to skip it for immediate return
             // values.
-            fcx.llretptr.set(Some(make_return_pointer(fcx,
-                                                      substd_output_type)));
+            fcx.llretptr.set(Some(make_return_pointer(fcx, substd_output_type)));
         }
     }
 }
@@ -1336,12 +1331,13 @@ pub fn init_function<'a>(
 pub fn new_fn_ctxt(ccx: @CrateContext,
                    path: ast_map::Path,
                    llfndecl: ValueRef,
+                   has_env: bool,
                    output_type: ty::t,
                    sp: Option<Span>)
                    -> FunctionContext {
     // FIXME(#11385): Do not call `init_function` here; it will typecheck
     // but segfault.
-    new_fn_ctxt_detailed(ccx, path, llfndecl, -1, output_type, None, sp)
+    new_fn_ctxt_detailed(ccx, path, llfndecl, -1, has_env, output_type, None, sp)
 }
 
 // NB: must keep 4 fns in sync:
@@ -1363,35 +1359,28 @@ fn arg_kind(cx: &FunctionContext, t: ty::t) -> datum::Rvalue {
 type RvalueDatum = datum::Datum<datum::Rvalue>;
 type LvalueDatum = datum::Datum<datum::Lvalue>;
 
-// create_datums_for_fn_args: creates rvalue datums for `self` and each of the
+// create_datums_for_fn_args: creates rvalue datums for each of the
 // incoming function arguments. These will later be stored into
 // appropriate lvalue datums.
-fn create_datums_for_fn_args(cx: &FunctionContext,
-                             self_arg: Option<ty::t>,
-                             arg_tys: &[ty::t])
-                             -> (Option<RvalueDatum>, ~[RvalueDatum]) {
+pub fn create_datums_for_fn_args(fcx: &FunctionContext,
+                                 arg_tys: &[ty::t])
+                                 -> ~[RvalueDatum] {
     let _icx = push_ctxt("create_datums_for_fn_args");
 
-    let self_datum = self_arg.map(
-        |t| datum::Datum(cx.llenv.get(), t, arg_kind(cx, t)));
-
     // Return an array wrapping the ValueRefs that we get from
     // llvm::LLVMGetParam for each argument into datums.
-    let arg_datums = arg_tys.iter().enumerate().map(|(i, &arg_ty)| {
-            let llarg = unsafe {
-                llvm::LLVMGetParam(cx.llfn, cx.arg_pos(i) as c_uint)
-            };
-            datum::Datum(llarg, arg_ty, arg_kind(cx, arg_ty))
-        }).collect();
-
-    (self_datum, arg_datums)
+    arg_tys.iter().enumerate().map(|(i, &arg_ty)| {
+        let llarg = unsafe {
+            llvm::LLVMGetParam(fcx.llfn, fcx.arg_pos(i) as c_uint)
+        };
+        datum::Datum(llarg, arg_ty, arg_kind(fcx, arg_ty))
+    }).collect()
 }
 
 fn copy_args_to_allocas<'a>(fcx: &FunctionContext<'a>,
                             arg_scope: cleanup::CustomScopeIndex,
                             bcx: &'a Block<'a>,
                             args: &[ast::Arg],
-                            self_datum: Option<RvalueDatum>,
                             arg_datums: ~[RvalueDatum])
                             -> &'a Block<'a> {
     debug!("copy_args_to_allocas");
@@ -1400,18 +1389,6 @@ fn copy_args_to_allocas<'a>(fcx: &FunctionContext<'a>,
     let mut bcx = bcx;
 
     let arg_scope_id = cleanup::CustomScope(arg_scope);
-    match self_datum {
-        Some(slf_rv) => {
-            let slf = unpack_datum!(
-                bcx, slf_rv.to_lvalue_datum_in_scope(bcx, "__self",
-                                                     arg_scope_id));
-            fcx.llself.set(Some(slf));
-            if fcx.ccx.sess.opts.extra_debuginfo {
-                debuginfo::create_self_argument_metadata(bcx, slf.ty, slf.val);
-            }
-        }
-        _ => {}
-    }
 
     for (i, arg_datum) in arg_datums.move_iter().enumerate() {
         // For certain mode/type combinations, the raw llarg values are passed
@@ -1429,7 +1406,7 @@ fn copy_args_to_allocas<'a>(fcx: &FunctionContext<'a>,
         }
     }
 
-    return bcx;
+    bcx
 }
 
 // Ties up the llstaticallocas -> llloadenv -> lltop edges,
@@ -1483,17 +1460,16 @@ pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block) {
 // trans_closure: Builds an LLVM function out of a source function.
 // If the function closes over its environment a closure will be
 // returned.
-pub fn trans_closure(ccx: @CrateContext,
-                     path: ast_map::Path,
-                     decl: &ast::FnDecl,
-                     body: &ast::Block,
-                     llfndecl: ValueRef,
-                     self_arg: Option<ty::t>,
-                     param_substs: Option<@param_substs>,
-                     id: ast::NodeId,
-                     _attributes: &[ast::Attribute],
-                     output_type: ty::t,
-                     maybe_load_env: |&FunctionContext|) {
+pub fn trans_closure<'a>(ccx: @CrateContext,
+                         path: ast_map::Path,
+                         decl: &ast::FnDecl,
+                         body: &ast::Block,
+                         llfndecl: ValueRef,
+                         param_substs: Option<@param_substs>,
+                         id: ast::NodeId,
+                         _attributes: &[ast::Attribute],
+                         output_type: ty::t,
+                         maybe_load_env: |&'a Block<'a>| -> &'a Block<'a>) {
     ccx.stats.n_closures.set(ccx.stats.n_closures.get() + 1);
 
     let _icx = push_ctxt("trans_closure");
@@ -1502,13 +1478,13 @@ pub fn trans_closure(ccx: @CrateContext,
     debug!("trans_closure(..., param_substs={})",
            param_substs.repr(ccx.tcx));
 
-    let fcx = new_fn_ctxt_detailed(ccx,
-                                   path,
-                                   llfndecl,
-                                   id,
-                                   output_type,
-                                   param_substs,
-                                   Some(body.span));
+    let has_env = match ty::get(ty::node_id_to_type(ccx.tcx, id)).sty {
+        ty::ty_closure(_) => true,
+        _ => false
+    };
+
+    let fcx = new_fn_ctxt_detailed(ccx, path, llfndecl, id, has_env, output_type,
+                                   param_substs, Some(body.span));
     init_function(&fcx, false, output_type, param_substs);
 
     // cleanup scope for the incoming arguments
@@ -1522,13 +1498,11 @@ pub fn trans_closure(ccx: @CrateContext,
 
     // Set up arguments to the function.
     let arg_tys = ty::ty_fn_args(node_id_type(bcx, id));
-    let (self_datum, arg_datums) =
-        create_datums_for_fn_args(&fcx, self_arg, arg_tys);
+    let arg_datums = create_datums_for_fn_args(&fcx, arg_tys);
 
-    bcx = copy_args_to_allocas(&fcx, arg_scope, bcx,
-                               decl.inputs, self_datum, arg_datums);
+    bcx = copy_args_to_allocas(&fcx, arg_scope, bcx, decl.inputs, arg_datums);
 
-    maybe_load_env(&fcx);
+    bcx = maybe_load_env(bcx);
 
     // Up until here, IR instructions for this function have explicitly not been annotated with
     // source code location, so we don't step into call setup code. From here on, source location
@@ -1578,28 +1552,16 @@ pub fn trans_fn(ccx: @CrateContext,
                 decl: &ast::FnDecl,
                 body: &ast::Block,
                 llfndecl: ValueRef,
-                self_arg: Option<ty::t>,
                 param_substs: Option<@param_substs>,
                 id: ast::NodeId,
                 attrs: &[ast::Attribute]) {
     let the_path_str = path_str(ccx.sess, path);
     let _s = StatRecorder::new(ccx, the_path_str);
-    debug!("trans_fn(self_arg={:?}, param_substs={})",
-           self_arg,
-           param_substs.repr(ccx.tcx));
+    debug!("trans_fn(param_substs={})", param_substs.repr(ccx.tcx));
     let _icx = push_ctxt("trans_fn");
     let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, id));
-    trans_closure(ccx,
-                  path.clone(),
-                  decl,
-                  body,
-                  llfndecl,
-                  self_arg,
-                  param_substs,
-                  id,
-                  attrs,
-                  output_type,
-                  |_fcx| { });
+    trans_closure(ccx, path.clone(), decl, body, llfndecl,
+                  param_substs, id, attrs, output_type, |bcx| bcx);
 }
 
 pub fn trans_enum_variant(ccx: @CrateContext,
@@ -1664,18 +1626,13 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: @CrateContext,
                  ty_to_str(ccx.tcx, ctor_ty)))
     };
 
-    let fcx = new_fn_ctxt_detailed(ccx,
-                                   ~[],
-                                   llfndecl,
-                                   ctor_id,
-                                   result_ty,
-                                   param_substs,
-                                   None);
+    let fcx = new_fn_ctxt_detailed(ccx, ~[], llfndecl, ctor_id, false,
+                                   result_ty, param_substs, None);
     init_function(&fcx, false, result_ty, param_substs);
 
     let arg_tys = ty::ty_fn_args(ctor_ty);
 
-    let (_, arg_datums) = create_datums_for_fn_args(&fcx, None, arg_tys);
+    let arg_datums = create_datums_for_fn_args(&fcx, arg_tys);
 
     let bcx = fcx.entry_bcx.get().unwrap();
 
@@ -1750,16 +1707,9 @@ pub fn trans_item(ccx: @CrateContext, item: &ast::Item) {
                 llfndecl,
                 item.id);
         } else if !generics.is_type_parameterized() {
-            let llfndecl = get_item_val(ccx, item.id);
-            trans_fn(ccx,
-                     vec::append_one((*path).clone(), PathName(item.ident)),
-                     decl,
-                     body,
-                     llfndecl,
-                     None,
-                     None,
-                     item.id,
-                     item.attrs);
+            let path = vec::append_one((*path).clone(), PathName(item.ident));
+            let llfn = get_item_val(ccx, item.id);
+            trans_fn(ccx, path, decl, body, llfn, None, item.id, item.attrs);
         } else {
             // Be sure to travel more than just one layer deep to catch nested
             // items in blocks and such.
@@ -1874,8 +1824,7 @@ fn register_fn(ccx: @CrateContext,
                sp: Span,
                sym: ~str,
                node_id: ast::NodeId,
-               node_type: ty::t,
-               self_ty: Option<ty::t>)
+               node_type: ty::t)
                -> ValueRef {
     let f = match ty::get(node_type).sty {
         ty::ty_bare_fn(ref f) => {
@@ -1885,7 +1834,7 @@ fn register_fn(ccx: @CrateContext,
         _ => fail!("expected bare rust fn or an intrinsic")
     };
 
-    let llfn = decl_rust_fn(ccx, self_ty, f.sig.inputs, f.sig.output, sym);
+    let llfn = decl_rust_fn(ccx, false, f.sig.inputs, f.sig.output, sym);
     finish_register_fn(ccx, sp, sym, node_id, llfn);
     llfn
 }
@@ -1963,7 +1912,6 @@ fn create_entry_fn(ccx: @CrateContext,
                     });
 
                     ~[
-                        C_null(Type::opaque_box(ccx).ptr_to()),
                         opaque_rust_main,
                         llvm::LLVMGetParam(llfn, 0),
                         llvm::LLVMGetParam(llfn, 1)
@@ -1973,7 +1921,6 @@ fn create_entry_fn(ccx: @CrateContext,
             } else {
                 debug!("using user-defined start fn");
                 let args = ~[
-                    C_null(Type::opaque_box(ccx).ptr_to()),
                     llvm::LLVMGetParam(llfn, 0 as c_uint),
                     llvm::LLVMGetParam(llfn, 1 as c_uint)
                 ];
@@ -1990,18 +1937,6 @@ fn create_entry_fn(ccx: @CrateContext,
     }
 }
 
-pub fn fill_fn_pair(bcx: &Block,
-                    pair: ValueRef,
-                    llfn: ValueRef,
-                    llenvptr: ValueRef) {
-    let ccx = bcx.ccx();
-    let code_cell = GEPi(bcx, pair, [0u, abi::fn_field_code]);
-    Store(bcx, llfn, code_cell);
-    let env_cell = GEPi(bcx, pair, [0u, abi::fn_field_box]);
-    let llenvblobptr = PointerCast(bcx, llenvptr, Type::opaque_box(ccx).ptr_to());
-    Store(bcx, llenvblobptr, env_cell);
-}
-
 pub fn item_path(ccx: &CrateContext, id: &ast::NodeId) -> ast_map::Path {
     ty::item_path(ccx.tcx, ast_util::local_def(*id))
 }
@@ -2049,22 +1984,22 @@ pub fn get_item_val(ccx: @CrateContext, id: ast::NodeId) -> ValueRef {
                             // using the current crate's name/version
                             // information in the hash of the symbol
                             debug!("making {}", sym);
-                            let sym = {
+                            let (sym, is_local) = {
                                 let external_srcs = ccx.external_srcs
                                                        .borrow();
                                 match external_srcs.get().find(&i.id) {
                                     Some(&did) => {
                                         debug!("but found in other crate...");
-                                        csearch::get_symbol(ccx.sess.cstore,
-                                                            did)
+                                        (csearch::get_symbol(ccx.sess.cstore,
+                                                             did), false)
                                     }
-                                    None => sym
+                                    None => (sym, true)
                                 }
                             };
 
                             // We need the translated value here, because for enums the
                             // LLVM type is not fully determined by the Rust type.
-                            let (v, inlineable) = consts::const_expr(ccx, expr);
+                            let (v, inlineable) = consts::const_expr(ccx, expr, is_local);
                             {
                                 let mut const_values = ccx.const_values
                                                           .borrow_mut();
@@ -2142,7 +2077,7 @@ pub fn get_item_val(ccx: @CrateContext, id: ast::NodeId) -> ValueRef {
 
                         ast::ItemFn(_, purity, _, _, _) => {
                             let llfn = if purity != ast::ExternFn {
-                                register_fn(ccx, i.span, sym, i.id, ty, None)
+                                register_fn(ccx, i.span, sym, i.id, ty)
                             } else {
                                 foreign::register_rust_fn_with_foreign_abi(ccx,
                                                                            i.span,
@@ -2246,7 +2181,7 @@ pub fn get_item_val(ccx: @CrateContext, id: ast::NodeId) -> ValueRef {
 
                             llfn = match enm.node {
                                 ast::ItemEnum(_, _) => {
-                                    register_fn(ccx, (*v).span, sym, id, ty, None)
+                                    register_fn(ccx, (*v).span, sym, id, ty)
                                 }
                                 _ => fail!("NodeVariant, shouldn't happen")
                             };
@@ -2271,7 +2206,7 @@ pub fn get_item_val(ccx: @CrateContext, id: ast::NodeId) -> ValueRef {
                             let sym = exported_name(ccx, (*struct_path).clone(), ty,
                                                     struct_item.attrs);
                             let llfn = register_fn(ccx, struct_item.span,
-                                                   sym, ctor_id, ty, None);
+                                                   sym, ctor_id, ty);
                             set_inline_hint(llfn);
                             llfn
                         }
@@ -2312,11 +2247,7 @@ fn register_method(ccx: @CrateContext,
 
     let sym = exported_name(ccx, path, mty, m.attrs);
 
-    let self_ty = match m.explicit_self.node {
-        ast::SelfStatic => None,
-        _ => Some(ty::node_id_to_type(ccx.tcx, m.self_id))
-    };
-    let llfn = register_fn(ccx, m.span, sym, id, mty, self_ty);
+    let llfn = register_fn(ccx, m.span, sym, id, mty);
     set_llvm_fn_attrs(m.attrs, llfn);
     llfn
 }
@@ -2594,12 +2525,12 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
             llvm::LLVMAddGlobal(llmod, maptype.to_ref(), buf)
         }
     });
+    lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage);
+
     // On windows we'd like to export the toplevel cratemap
     // such that we can find it from libstd.
     if targ_cfg.os == OsWin32 && is_top {
-        lib::llvm::SetLinkage(map, lib::llvm::DLLExportLinkage);
-    } else {
-        lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage);
+        unsafe { llvm::LLVMRustSetDLLExportStorageClass(map) }
     }
 
     return (sym_name, map);
@@ -2683,7 +2614,7 @@ pub fn crate_ctxt_to_encode_parms<'r>(cx: &'r CrateContext, ie: encoder::encode_
 }
 
 pub fn write_metadata(cx: &CrateContext, crate: &ast::Crate) -> ~[u8] {
-    use extra::flate;
+    use flate;
 
     if !cx.sess.building_library.get() {
         return ~[]
@@ -2741,7 +2672,7 @@ pub fn trans_crate(sess: session::Session,
     let link_meta = link::build_link_meta(sess, crate.attrs, output,
                                           &mut symbol_hasher);
 
-    // Append ".rc" to crate name as LLVM module identifier.
+    // Append ".rs" to crate name as LLVM module identifier.
     //
     // LLVM code generator emits a ".file filename" directive
     // for ELF backends. Value of the "filename" is set as the
@@ -2749,7 +2680,7 @@ pub fn trans_crate(sess: session::Session,
     // crashes if the module identifer is same as other symbols
     // such as a function name in the module.
     // 1. http://llvm.org/bugs/show_bug.cgi?id=11479
-    let llmod_id = link_meta.crateid.name.clone() + ".rc";
+    let llmod_id = link_meta.crateid.name.clone() + ".rs";
 
     let ccx = @CrateContext::new(sess,
                                      llmod_id,
index c4beb935ffecfc96512fe3454f809a99aa00bb38..71b25b79feb4af5fd0e99b819b9d960636913bff 100644 (file)
@@ -797,6 +797,11 @@ pub fn inline_asm_call(&self, asm: *c_char, cons: *c_char,
     pub fn call(&self, llfn: ValueRef, args: &[ValueRef],
                 attributes: &[(uint, lib::llvm::Attribute)]) -> ValueRef {
         self.count_insn("call");
+
+        debug!("Call {} with args ({})",
+               self.ccx.tn.val_to_str(llfn),
+               args.map(|&v| self.ccx.tn.val_to_str(v)).connect(", "));
+
         unsafe {
             let v = llvm::LLVMBuildCall(self.llbuilder, llfn, args.as_ptr(),
                                         args.len() as c_uint, noname());
index 229a1b3662defea610468d6cdfd6c67b0ed63a78..e10c7af7f313d0c168ab8d981400a9a56af341eb 100644 (file)
 use syntax::abi::AbiSet;
 use syntax::ast_map;
 
-// Represents a (possibly monomorphized) top-level fn item or method
-// item.  Note that this is just the fn-ptr and is not a Rust closure
-// value (which is a pair).
-pub struct FnData {
-    llfn: ValueRef,
-}
-
 pub struct MethodData {
     llfn: ValueRef,
     llself: ValueRef,
@@ -66,8 +59,13 @@ pub struct MethodData {
 
 pub enum CalleeData {
     Closure(Datum<Lvalue>),
-    Fn(FnData),
-    Method(MethodData)
+
+    // Represents a (possibly monomorphized) top-level fn item or method
+    // item. Note that this is just the fn-ptr and is not a Rust closure
+    // value (which is a pair).
+    Fn(/* llfn */ ValueRef),
+
+    TraitMethod(MethodData)
 }
 
 pub struct Callee<'a> {
@@ -95,7 +93,7 @@ fn datum_callee<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {
         match ty::get(datum.ty).sty {
             ty::ty_bare_fn(..) => {
                 let llval = datum.to_llscalarish(bcx);
-                return Callee {bcx: bcx, data: Fn(FnData {llfn: llval})};
+                return Callee {bcx: bcx, data: Fn(llval)};
             }
             ty::ty_closure(..) => {
                 let datum = unpack_datum!(
@@ -111,8 +109,8 @@ fn datum_callee<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {
         }
     }
 
-    fn fn_callee<'a>(bcx: &'a Block<'a>, fd: FnData) -> Callee<'a> {
-        return Callee {bcx: bcx, data: Fn(fd)};
+    fn fn_callee<'a>(bcx: &'a Block<'a>, llfn: ValueRef) -> Callee<'a> {
+        return Callee {bcx: bcx, data: Fn(llfn)};
     }
 
     fn trans_def<'a>(bcx: &'a Block<'a>, def: ast::Def, ref_expr: &ast::Expr)
@@ -143,8 +141,7 @@ fn trans_def<'a>(bcx: &'a Block<'a>, def: ast::Def, ref_expr: &ast::Expr)
             ast::DefArg(..) |
             ast::DefLocal(..) |
             ast::DefBinding(..) |
-            ast::DefUpvar(..) |
-            ast::DefSelf(..) => {
+            ast::DefUpvar(..) => {
                 datum_callee(bcx, ref_expr)
             }
             ast::DefMod(..) | ast::DefForeignMod(..) | ast::DefTrait(..) |
@@ -171,7 +168,7 @@ pub fn trans_fn_ref_to_callee<'a>(
 }
 
 pub fn trans_fn_ref(bcx: &Block, def_id: ast::DefId, ref_id: ast::NodeId)
-                    -> FnData {
+                    -> ValueRef {
     /*!
      *
      * Translates a reference (with id `ref_id`) to the fn/method
@@ -248,7 +245,7 @@ pub fn trans_fn_ref_with_vtables(
         ref_id: ast::NodeId,  // node id of use of fn; may be zero if N/A
         type_params: &[ty::t], // values for fn's ty params
         vtables: Option<typeck::vtable_res>) // vtables for the call
-     -> FnData {
+     -> ValueRef {
     /*!
      * Translates a reference to a fn/method item, monomorphizing and
      * inlining as it goes.
@@ -399,9 +396,9 @@ pub fn trans_fn_ref_with_vtables(
             let ref_ty = common::node_id_type(bcx, ref_id);
 
             val = PointerCast(
-                bcx, val, type_of::type_of_fn_from_ty(ccx, None, ref_ty).ptr_to());
+                bcx, val, type_of::type_of_fn_from_ty(ccx, ref_ty).ptr_to());
         }
-        return FnData {llfn: val};
+        return val;
     }
 
     // Find the actual function pointer.
@@ -438,13 +435,13 @@ pub fn trans_fn_ref_with_vtables(
     // This can occur on either a crate-local or crate-external
     // reference. It also occurs when testing libcore and in some
     // other weird situations. Annoying.
-    let llty = type_of::type_of_fn_from_ty(ccx, None, fn_tpt.ty);
+    let llty = type_of::type_of_fn_from_ty(ccx, fn_tpt.ty);
     let llptrty = llty.ptr_to();
     if val_ty(val) != llptrty {
         val = BitCast(bcx, val, llptrty);
     }
 
-    return FnData {llfn: val};
+    val
 }
 
 // ______________________________________________________________________
@@ -465,8 +462,7 @@ pub fn trans_call<'a>(
                      node_id_type(in_cx, id),
                      |cx, _| trans(cx, f),
                      args,
-                     Some(dest),
-                     DontAutorefArg).bcx
+                     Some(dest)).bcx
 }
 
 pub fn trans_method_call<'a>(
@@ -478,9 +474,7 @@ pub fn trans_method_call<'a>(
                          dest: expr::Dest)
                          -> &'a Block<'a> {
     let _icx = push_ctxt("trans_method_call");
-    debug!("trans_method_call(call_ex={}, rcvr={})",
-           call_ex.repr(in_cx.tcx()),
-           rcvr.repr(in_cx.tcx()));
+    debug!("trans_method_call(call_ex={})", call_ex.repr(in_cx.tcx()));
     trans_call_inner(
         in_cx,
         Some(common::expr_info(call_ex)),
@@ -509,8 +503,7 @@ pub fn trans_method_call<'a>(
             }
         },
         args,
-        Some(dest),
-        DontAutorefArg).bcx
+        Some(dest)).bcx
 }
 
 pub fn trans_lang_call<'a>(
@@ -537,8 +530,7 @@ pub fn trans_lang_call<'a>(
                                                                     None)
                              },
                              ArgVals(args),
-                             dest,
-                             DontAutorefArg)
+                             dest)
 }
 
 pub fn trans_lang_call_with_type_params<'a>(
@@ -569,20 +561,20 @@ pub fn trans_lang_call_with_type_params<'a>(
 
             let new_llval;
             match callee.data {
-                Fn(fn_data) => {
+                Fn(llfn) => {
                     let substituted = ty::subst_tps(callee.bcx.tcx(),
                                                     type_params,
                                                     None,
                                                     fty);
                     let llfnty = type_of::type_of(callee.bcx.ccx(),
                                                       substituted);
-                    new_llval = PointerCast(callee.bcx, fn_data.llfn, llfnty);
+                    new_llval = PointerCast(callee.bcx, llfn, llfnty);
                 }
                 _ => fail!()
             }
-            Callee { bcx: callee.bcx, data: Fn(FnData { llfn: new_llval }) }
+            Callee { bcx: callee.bcx, data: Fn(new_llval) }
         },
-        ArgVals(args), Some(dest), DontAutorefArg).bcx;
+        ArgVals(args), Some(dest)).bcx;
 }
 
 pub fn trans_call_inner<'a>(
@@ -594,8 +586,7 @@ pub fn trans_call_inner<'a>(
                                      arg_cleanup_scope: cleanup::ScopeId|
                                      -> Callee<'a>,
                         args: CallArgs,
-                        dest: Option<expr::Dest>,
-                        autoref_arg: AutorefArg)
+                        dest: Option<expr::Dest>)
                         -> Result<'a> {
     /*!
      * This behemoth of a function translates function calls.
@@ -627,25 +618,22 @@ pub fn trans_call_inner<'a>(
     let callee = get_callee(bcx, cleanup::CustomScope(arg_cleanup_scope));
     let mut bcx = callee.bcx;
 
-    let (llfn, llenv) = unsafe {
-        match callee.data {
-            Fn(d) => {
-                (d.llfn, llvm::LLVMGetUndef(Type::opaque_box(ccx).ptr_to().to_ref()))
-            }
-            Method(d) => {
-                // Weird but true: we pass self in the *environment* slot!
-                (d.llfn, d.llself)
-            }
-            Closure(d) => {
-                // Closures are represented as (llfn, llclosure) pair:
-                // load the requisite values out.
-                let pair = d.to_llref();
-                let llfn = GEPi(bcx, pair, [0u, abi::fn_field_code]);
-                let llfn = Load(bcx, llfn);
-                let llenv = GEPi(bcx, pair, [0u, abi::fn_field_box]);
-                let llenv = Load(bcx, llenv);
-                (llfn, llenv)
-            }
+    let (llfn, llenv, llself) = match callee.data {
+        Fn(llfn) => {
+            (llfn, None, None)
+        }
+        TraitMethod(d) => {
+            (d.llfn, None, Some(d.llself))
+        }
+        Closure(d) => {
+            // Closures are represented as (llfn, llclosure) pair:
+            // load the requisite values out.
+            let pair = d.to_llref();
+            let llfn = GEPi(bcx, pair, [0u, abi::fn_field_code]);
+            let llfn = Load(bcx, llfn);
+            let llenv = GEPi(bcx, pair, [0u, abi::fn_field_box]);
+            let llenv = Load(bcx, llenv);
+            (llfn, Some(llenv), None)
         }
     };
 
@@ -694,13 +682,17 @@ pub fn trans_call_inner<'a>(
             llargs.push(opt_llretslot.unwrap());
         }
 
-        // Push the environment.
-        llargs.push(llenv);
+        // Push the environment (or a trait object's self).
+        match (llenv, llself) {
+            (Some(llenv), None) => llargs.push(llenv),
+            (None, Some(llself)) => llargs.push(llself),
+            _ => {}
+        }
 
         // Push the arguments.
-        bcx = trans_args(bcx, args, callee_ty,
-                         autoref_arg, &mut llargs,
-                         cleanup::CustomScope(arg_cleanup_scope));
+        bcx = trans_args(bcx, args, callee_ty, &mut llargs,
+                         cleanup::CustomScope(arg_cleanup_scope),
+                         llself.is_some());
 
         fcx.pop_custom_cleanup_scope(arg_cleanup_scope);
 
@@ -718,11 +710,10 @@ pub fn trans_call_inner<'a>(
         match ty::get(ret_ty).sty {
             // `~` pointer return values never alias because ownership
             // is transferred
-            ty::ty_uniq(..) |
-                ty::ty_vec(_, ty::vstore_uniq) => {
+            ty::ty_uniq(..) | ty::ty_vec(_, ty::vstore_uniq) => {
                 attrs.push((0, NoAliasAttribute));
             }
-            _ => ()
+            _ => {}
         }
 
         // Invoke the actual rust fn and update bcx/llresult.
@@ -748,13 +739,12 @@ pub fn trans_call_inner<'a>(
         assert!(dest.is_some());
 
         let mut llargs = ~[];
-        bcx = trans_args(bcx, args, callee_ty,
-                         autoref_arg, &mut llargs,
-                         cleanup::CustomScope(arg_cleanup_scope));
+        bcx = trans_args(bcx, args, callee_ty, &mut llargs,
+                         cleanup::CustomScope(arg_cleanup_scope), false);
         fcx.pop_custom_cleanup_scope(arg_cleanup_scope);
         let arg_tys = match args {
             ArgExprs(a) => a.iter().map(|x| expr_ty(bcx, *x)).collect(),
-            ArgVals(_) => fail!("expected arg exprs.")
+            _ => fail!("expected arg exprs.")
         };
         bcx = foreign::trans_native_call(bcx, callee_ty,
                                          llfn, opt_llretslot.unwrap(), llargs, arg_tys);
@@ -782,18 +772,18 @@ pub fn trans_call_inner<'a>(
 
 pub enum CallArgs<'a> {
     ArgExprs(&'a [@ast::Expr]),
+    // HACK used only by trans_overloaded_op.
+    ArgAutorefSecond(&'a ast::Expr, Option<&'a ast::Expr>),
     ArgVals(&'a [ValueRef])
 }
 
-pub fn trans_args<'a>(
-                  cx: &'a Block<'a>,
+fn trans_args<'a>(cx: &'a Block<'a>,
                   args: CallArgs,
                   fn_ty: ty::t,
-                  autoref_arg: AutorefArg,
                   llargs: &mut ~[ValueRef],
-                  arg_cleanup_scope: cleanup::ScopeId)
-                  -> &'a Block<'a>
-{
+                  arg_cleanup_scope: cleanup::ScopeId,
+                  ignore_self: bool)
+                  -> &'a Block<'a> {
     let _icx = push_ctxt("trans_args");
     let arg_tys = ty::ty_fn_args(fn_ty);
     let variadic = ty::fn_is_variadic(fn_ty);
@@ -804,28 +794,50 @@ pub fn trans_args<'a>(
     // This will be needed if this is a generic call, because the callee has
     // to cast her view of the arguments to the caller's view.
     match args {
-      ArgExprs(arg_exprs) => {
-        let num_formal_args = arg_tys.len();
-        for (i, arg_expr) in arg_exprs.iter().enumerate() {
-            let arg_ty = if i >= num_formal_args {
-                assert!(variadic);
-                expr_ty_adjusted(cx, *arg_expr)
-            } else {
-                arg_tys[i]
-            };
-            let arg_val = unpack_result!(bcx, {
-                trans_arg_expr(bcx,
-                               arg_ty,
-                               *arg_expr,
+        ArgExprs(arg_exprs) => {
+            let num_formal_args = arg_tys.len();
+            for (i, arg_expr) in arg_exprs.iter().enumerate() {
+                if i == 0 && ignore_self {
+                    continue;
+                }
+                let arg_ty = if i >= num_formal_args {
+                    assert!(variadic);
+                    expr_ty_adjusted(cx, *arg_expr)
+                } else {
+                    arg_tys[i]
+                };
+                llargs.push(unpack_result!(bcx, {
+                    trans_arg_expr(bcx, arg_ty, *arg_expr,
+                                   arg_cleanup_scope,
+                                   DontAutorefArg)
+                }));
+            }
+        }
+        ArgAutorefSecond(arg_expr, arg2) => {
+            assert!(!variadic);
+
+            llargs.push(unpack_result!(bcx, {
+                trans_arg_expr(bcx, arg_tys[0], arg_expr,
                                arg_cleanup_scope,
-                               autoref_arg)
-            });
-            llargs.push(arg_val);
+                               DontAutorefArg)
+            }));
+
+            match arg2 {
+                Some(arg2_expr) => {
+                    assert_eq!(arg_tys.len(), 2);
+
+                    llargs.push(unpack_result!(bcx, {
+                        trans_arg_expr(bcx, arg_tys[1], arg2_expr,
+                                       arg_cleanup_scope,
+                                       DoAutorefArg)
+                    }));
+                }
+                None => assert_eq!(arg_tys.len(), 1)
+            }
+        }
+        ArgVals(vs) => {
+            llargs.push_all(vs);
         }
-      }
-      ArgVals(vs) => {
-        llargs.push_all(vs);
-      }
     }
 
     bcx
index 020b840e5b2ef01d3e7e50eb2a0c45d75d2922ba..6e92ea9f11e51b3607263e829302faea69f59944 100644 (file)
@@ -680,7 +680,7 @@ fn get_or_create_landing_pad(&self) -> BasicBlockRef {
 
         // The exception handling personality function.
         let def_id = common::langcall(pad_bcx, None, "", EhPersonalityLangItem);
-        let llpersonality = callee::trans_fn_ref(pad_bcx, def_id, 0).llfn;
+        let llpersonality = callee::trans_fn_ref(pad_bcx, def_id, 0);
 
         // The only landing pad clause will be 'cleanup'
         let llretval = build::LandingPad(pad_bcx, llretty, llpersonality, 1u);
index 58f7171452e7df6178419d3cb026d73dd908a917..5a8039f9c4d65b12f250138bcd7f8c5dd1bb0c60 100644 (file)
 
 
 use back::abi;
-use back::link::{mangle_internal_name_by_path_and_seq};
+use back::link::mangle_internal_name_by_path_and_seq;
 use lib::llvm::ValueRef;
 use middle::moves;
 use middle::trans::base::*;
 use middle::trans::build::*;
 use middle::trans::common::*;
-use middle::trans::datum::{Datum, Lvalue};
+use middle::trans::datum::{Datum, DatumBlock, Expr, Lvalue, rvalue_scratch_datum};
 use middle::trans::debuginfo;
 use middle::trans::expr;
-use middle::trans::glue;
 use middle::trans::type_of::*;
+use middle::trans::type_::Type;
 use middle::ty;
+use util::ppaux::Repr;
 use util::ppaux::ty_to_str;
 
 use std::vec;
@@ -69,9 +70,9 @@
 // closure".
 //
 // Typically an opaque closure suffices because we only manipulate it
-// by ptr.  The routine Type::opaque_box().ptr_to() returns an
-// appropriate type for such an opaque closure; it allows access to
-// the box fields, but not the closure_data itself.
+// by ptr.  The routine Type::at_box().ptr_to() returns an appropriate
+// type for such an opaque closure; it allows access to the box fields,
+// but not the closure_data itself.
 //
 // But sometimes, such as when cloning or freeing a closure, we need
 // to know the full information.  That is where the type descriptor
@@ -244,8 +245,7 @@ pub fn store_environment<'a>(
 
 // Given a context and a list of upvars, build a closure. This just
 // collects the upvars and packages them up for store_environment.
-pub fn build_closure<'a>(
-                     bcx0: &'a Block<'a>,
+fn build_closure<'a>(bcx0: &'a Block<'a>,
                      cap_vars: &[moves::CaptureVar],
                      sigil: ast::Sigil)
                      -> ClosureResult<'a> {
@@ -282,25 +282,22 @@ pub fn build_closure<'a>(
 // Given an enclosing block context, a new function context, a closure type,
 // and a list of upvars, generate code to load and populate the environment
 // with the upvars and type descriptors.
-pub fn load_environment(fcx: &FunctionContext,
-                        cdata_ty: ty::t,
+fn load_environment<'a>(bcx: &'a Block<'a>, cdata_ty: ty::t,
                         cap_vars: &[moves::CaptureVar],
-                        sigil: ast::Sigil) {
+                        sigil: ast::Sigil) -> &'a Block<'a> {
     let _icx = push_ctxt("closure::load_environment");
 
     // Don't bother to create the block if there's nothing to load
     if cap_vars.len() == 0 {
-        return;
+        return bcx;
     }
 
-    let bcx = fcx.entry_bcx.get().unwrap();
-
     // Load a pointer to the closure data, skipping over the box header:
-    let llcdata = opaque_box_body(bcx, cdata_ty, fcx.llenv.get());
+    let llcdata = at_box_body(bcx, cdata_ty, bcx.fcx.llenv.unwrap());
 
     // Store the pointer to closure data in an alloca for debug info because that's what the
     // llvm.dbg.declare intrinsic expects
-    let env_pointer_alloca = if fcx.ccx.sess.opts.extra_debuginfo {
+    let env_pointer_alloca = if bcx.ccx().sess.opts.extra_debuginfo {
         let alloc = alloc_ty(bcx, ty::mk_mut_ptr(bcx.tcx(), cdata_ty), "__debuginfo_env_ptr");
         Store(bcx, llcdata, alloc);
         Some(alloc)
@@ -319,7 +316,7 @@ pub fn load_environment(fcx: &FunctionContext,
         let def_id = ast_util::def_id_of_def(cap_var.def);
 
         {
-            let mut llupvars = fcx.llupvars.borrow_mut();
+            let mut llupvars = bcx.fcx.llupvars.borrow_mut();
             llupvars.get().insert(def_id.node, upvarptr);
         }
 
@@ -336,6 +333,14 @@ pub fn load_environment(fcx: &FunctionContext,
 
         i += 1u;
     }
+
+    bcx
+}
+
+fn fill_fn_pair(bcx: &Block, pair: ValueRef, llfn: ValueRef, llenvptr: ValueRef) {
+    Store(bcx, llfn, GEPi(bcx, pair, [0u, abi::fn_field_code]));
+    let llenvptr = PointerCast(bcx, llenvptr, Type::i8p());
+    Store(bcx, llenvptr, GEPi(bcx, pair, [0u, abi::fn_field_box]));
 }
 
 pub fn trans_expr_fn<'a>(
@@ -384,119 +389,123 @@ pub fn trans_expr_fn<'a>(
 
     let sub_path = vec::append_one(bcx.fcx.path.clone(),
                                    PathName(special_idents::anon));
-    // XXX: Bad copy.
+    // FIXME: Bad copy.
     let s = mangle_internal_name_by_path_and_seq(ccx,
                                                  sub_path.clone(),
                                                  "expr_fn");
-    let llfn = decl_internal_rust_fn(ccx, None, f.sig.inputs, f.sig.output, s);
+    let llfn = decl_internal_rust_fn(ccx, true, f.sig.inputs, f.sig.output, s);
 
     // set an inline hint for all closures
     set_inline_hint(llfn);
 
-    let Result {bcx: bcx, val: closure} = match sigil {
-        ast::BorrowedSigil | ast::ManagedSigil | ast::OwnedSigil => {
-            let cap_vars = {
-                let capture_map = ccx.maps.capture_map.borrow();
-                capture_map.get().get_copy(&user_id)
-            };
-            let ClosureResult {llbox, cdata_ty, bcx}
-                = build_closure(bcx, cap_vars, sigil);
-            trans_closure(ccx,
-                          sub_path,
-                          decl,
-                          body,
-                          llfn,
-                          None,
-                          bcx.fcx.param_substs,
-                          user_id,
-                          [],
-                          ty::ty_fn_ret(fty),
-                          |fcx| load_environment(fcx, cdata_ty, cap_vars, sigil));
-            rslt(bcx, llbox)
-        }
+    let cap_vars = {
+        let capture_map = ccx.maps.capture_map.borrow();
+        capture_map.get().get_copy(&user_id)
     };
-    fill_fn_pair(bcx, dest_addr, llfn, closure);
-
-    return bcx;
+    let ClosureResult {llbox, cdata_ty, bcx} = build_closure(bcx, cap_vars, sigil);
+    trans_closure(ccx, sub_path, decl, body, llfn,
+                    bcx.fcx.param_substs, user_id,
+                    [], ty::ty_fn_ret(fty),
+                    |bcx| load_environment(bcx, cdata_ty, cap_vars, sigil));
+    fill_fn_pair(bcx, dest_addr, llfn, llbox);
+
+    bcx
 }
 
-pub fn make_closure_glue<'a>(
-                         cx: &'a Block<'a>,
-                         v: ValueRef,
-                         t: ty::t,
-                         glue_fn: |&'a Block<'a>, v: ValueRef, t: ty::t|
-                                   -> &'a Block<'a>)
-                         -> &'a Block<'a> {
-    let _icx = push_ctxt("closure::make_closure_glue");
-    let bcx = cx;
-    let tcx = cx.tcx();
-
-    let sigil = ty::ty_closure_sigil(t);
-    match sigil {
-        ast::BorrowedSigil => bcx,
-        ast::OwnedSigil | ast::ManagedSigil => {
-            let box_cell_v = GEPi(cx, v, [0u, abi::fn_field_box]);
-            let box_ptr_v = Load(cx, box_cell_v);
-            with_cond(cx, IsNotNull(cx, box_ptr_v), |bcx| {
-                let closure_ty = ty::mk_opaque_closure_ptr(tcx, sigil);
-                glue_fn(bcx, box_cell_v, closure_ty)
-            })
+pub fn get_wrapper_for_bare_fn(ccx: @CrateContext,
+                               closure_ty: ty::t,
+                               def: ast::Def,
+                               fn_ptr: ValueRef,
+                               is_local: bool) -> ValueRef {
+
+    let def_id = match def {
+        ast::DefFn(did, _) | ast::DefStaticMethod(did, _, _) |
+        ast::DefVariant(_, did, _) | ast::DefStruct(did) => did,
+        _ => {
+            ccx.sess.bug(format!("get_wrapper_for_bare_fn: \
+                                  expected a statically resolved fn, got {:?}",
+                                  def));
         }
-    }
-}
+    };
 
-pub fn make_opaque_cbox_drop_glue<'a>(
-                                  bcx: &'a Block<'a>,
-                                  sigil: ast::Sigil,
-                                  cboxptr: ValueRef)    // opaque closure ptr
-                                  -> &'a Block<'a> {
-    let _icx = push_ctxt("closure::make_opaque_cbox_drop_glue");
-    match sigil {
-        ast::BorrowedSigil => bcx,
-        ast::ManagedSigil => {
-            bcx.tcx().sess.bug("trying to trans drop glue of @fn")
-        }
-        ast::OwnedSigil => {
-            glue::make_free_glue(
-                bcx, cboxptr,
-                ty::mk_opaque_closure_ptr(bcx.tcx(), sigil))
+    {
+        let cache = ccx.closure_bare_wrapper_cache.borrow();
+        match cache.get().find(&fn_ptr) {
+            Some(&llval) => return llval,
+            None => {}
         }
     }
-}
 
-/// `cbox` is a pointer to a pointer to an opaque closure.
-pub fn make_opaque_cbox_free_glue<'a>(
-                                  bcx: &'a Block<'a>,
-                                  sigil: ast::Sigil,
-                                  cbox: ValueRef)
-                                  -> &'a Block<'a> {
-    let _icx = push_ctxt("closure::make_opaque_cbox_free_glue");
-    match sigil {
-        ast::BorrowedSigil => {
-            return bcx;
+    let tcx = ccx.tcx;
+
+    debug!("get_wrapper_for_bare_fn(closure_ty={})", closure_ty.repr(tcx));
+
+    let f = match ty::get(closure_ty).sty {
+        ty::ty_closure(ref f) => f,
+        _ => {
+            ccx.sess.bug(format!("get_wrapper_for_bare_fn: \
+                                  expected a closure ty, got {}",
+                                  closure_ty.repr(tcx)));
         }
-        ast::ManagedSigil | ast::OwnedSigil => {
-            /* hard cases: fallthrough to code below */
+    };
+
+    let path = ty::item_path(tcx, def_id);
+    let name = mangle_internal_name_by_path_and_seq(ccx, path, "as_closure");
+    let llfn = if is_local {
+        decl_internal_rust_fn(ccx, true, f.sig.inputs, f.sig.output, name)
+    } else {
+        decl_rust_fn(ccx, true, f.sig.inputs, f.sig.output, name)
+    };
+
+    {
+        let mut cache = ccx.closure_bare_wrapper_cache.borrow_mut();
+        cache.get().insert(fn_ptr, llfn);
+    }
+
+    // This is only used by statics inlined from a different crate.
+    if !is_local {
+        // Don't regenerate the wrapper, just reuse the original one.
+        return llfn;
+    }
+
+    let _icx = push_ctxt("closure::get_wrapper_for_bare_fn");
+
+    let fcx = new_fn_ctxt(ccx, ~[], llfn, true, f.sig.output, None);
+    init_function(&fcx, true, f.sig.output, None);
+    let bcx = fcx.entry_bcx.get().unwrap();
+
+    let args = create_datums_for_fn_args(&fcx, ty::ty_fn_args(closure_ty));
+    let mut llargs = ~[];
+    match fcx.llretptr.get() {
+        Some(llretptr) => {
+            llargs.push(llretptr);
         }
+        None => {}
     }
+    llargs.extend(&mut args.iter().map(|arg| arg.val));
 
-    let ccx = bcx.ccx();
-    with_cond(bcx, IsNotNull(bcx, cbox), |bcx| {
-        // Load the type descr found in the cbox
-        let lltydescty = ccx.tydesc_type.ptr_to();
-        let cbox = Load(bcx, cbox);
-        let tydescptr = GEPi(bcx, cbox, [0u, abi::box_field_tydesc]);
-        let tydesc = Load(bcx, tydescptr);
-        let tydesc = PointerCast(bcx, tydesc, lltydescty);
-
-        // Drop the tuple data then free the descriptor
-        let cdata = GEPi(bcx, cbox, [0u, abi::box_field_body]);
-        glue::call_tydesc_glue_full(bcx, cdata, tydesc,
-                                    abi::tydesc_field_drop_glue, None);
-
-        // Free the ty descr (if necc) and the box itself
-        glue::trans_exchange_free(bcx, cbox);
-
-        bcx
-    })
+    let retval = Call(bcx, fn_ptr, llargs, []);
+    if type_is_zero_size(ccx, f.sig.output) || fcx.llretptr.get().is_some() {
+        RetVoid(bcx);
+    } else {
+        Ret(bcx, retval);
+    }
+
+    // HACK(eddyb) finish_fn cannot be used here, we returned directly.
+    debuginfo::clear_source_location(&fcx);
+    fcx.cleanup();
+
+    llfn
+}
+
+pub fn make_closure_from_bare_fn<'a>(bcx: &'a Block<'a>,
+                                     closure_ty: ty::t,
+                                     def: ast::Def,
+                                     fn_ptr: ValueRef)
+                                     -> DatumBlock<'a, Expr>  {
+    let scratch = rvalue_scratch_datum(bcx, closure_ty, "__adjust");
+    let wrapper = get_wrapper_for_bare_fn(bcx.ccx(), closure_ty, def, fn_ptr, true);
+    fill_fn_pair(bcx, scratch.val, wrapper, C_null(Type::i8p()));
+
+    DatumBlock(bcx, scratch.to_expr_datum())
 }
index e466e4da38d72f779eb5c0f00c681d8dde0667fa..18a6727dee06966eb20af3f50a8410ab32858625 100644 (file)
@@ -31,7 +31,7 @@
 use util::ppaux::Repr;
 
 
-use extra::arena::TypedArena;
+use arena::TypedArena;
 use std::c_str::ToCStr;
 use std::cast::transmute;
 use std::cast;
@@ -114,7 +114,6 @@ pub struct tydesc_info {
     size: ValueRef,
     align: ValueRef,
     name: ValueRef,
-    take_glue: Cell<Option<ValueRef>>,
     drop_glue: Cell<Option<ValueRef>>,
     visit_glue: Cell<Option<ValueRef>>,
 }
@@ -230,9 +229,8 @@ pub struct FunctionContext<'a> {
     // section of the executable we're generating.
     llfn: ValueRef,
 
-    // The implicit environment argument that arrives in the function we're
-    // creating.
-    llenv: Cell<ValueRef>,
+    // The environment argument in a closure.
+    llenv: Option<ValueRef>,
 
     // The place to store the return value. If the return type is immediate,
     // this is an alloca in the function. Otherwise, it's the hidden first
@@ -250,14 +248,6 @@ pub struct FunctionContext<'a> {
     alloca_insert_pt: Cell<Option<ValueRef>>,
     llreturn: Cell<Option<BasicBlockRef>>,
 
-    // The 'self' value currently in use in this function, if there
-    // is one.
-    //
-    // NB: This is the type of the self *variable*, not the self *type*. The
-    // self type is set only for default methods, while the self variable is
-    // set for all methods.
-    llself: Cell<Option<LvalueDatum>>,
-
     // The a value alloca'd for calls to upcalls.rust_personality. Used when
     // outputting the resume instruction.
     personality: Cell<Option<ValueRef>>,
@@ -305,10 +295,11 @@ pub struct FunctionContext<'a> {
 
 impl<'a> FunctionContext<'a> {
     pub fn arg_pos(&self, arg: uint) -> uint {
-        if self.caller_expects_out_pointer {
-            arg + 2u
+        let arg = self.env_arg_pos() + arg;
+        if self.llenv.is_some() {
+            arg + 1
         } else {
-            arg + 1u
+            arg
         }
     }
 
index d70f2ab7d99b9175d279fb2585c1a4e8690d13a8..79aa536a0dbdc47dc69bdc24170caece3f666df9 100644 (file)
@@ -19,6 +19,7 @@
 use middle::trans::adt;
 use middle::trans::base;
 use middle::trans::base::push_ctxt;
+use middle::trans::closure;
 use middle::trans::common::*;
 use middle::trans::consts;
 use middle::trans::expr;
@@ -85,11 +86,12 @@ pub fn const_ptrcast(cx: &CrateContext, a: ValueRef, t: Type) -> ValueRef {
     }
 }
 
-fn const_vec(cx: @CrateContext, e: &ast::Expr, es: &[@ast::Expr]) -> (ValueRef, Type, bool) {
+fn const_vec(cx: @CrateContext, e: &ast::Expr,
+             es: &[@ast::Expr], is_local: bool) -> (ValueRef, Type, bool) {
     let vec_ty = ty::expr_ty(cx.tcx, e);
     let unit_ty = ty::sequence_element_type(cx.tcx, vec_ty);
     let llunitty = type_of::type_of(cx, unit_ty);
-    let (vs, inlineable) = vec::unzip(es.iter().map(|e| const_expr(cx, *e)));
+    let (vs, inlineable) = vec::unzip(es.iter().map(|e| const_expr(cx, *e, is_local)));
     // If the vector contains enums, an LLVM array won't work.
     let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
         C_struct(vs, false)
@@ -187,11 +189,12 @@ pub fn get_const_val(cx: @CrateContext,
      !non_inlineable_statics.get().contains(&def_id.node))
 }
 
-pub fn const_expr(cx: @CrateContext, e: &ast::Expr) -> (ValueRef, bool) {
-    let (llconst, inlineable) = const_expr_unadjusted(cx, e);
+pub fn const_expr(cx: @CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef, bool) {
+    let (llconst, inlineable) = const_expr_unadjusted(cx, e, is_local);
     let mut llconst = llconst;
     let mut inlineable = inlineable;
     let ety = ty::expr_ty(cx.tcx, e);
+    let ety_adjusted = ty::expr_ty_adjusted(cx.tcx, e);
     let adjustment = {
         let adjustments = cx.tcx.adjustments.borrow();
         adjustments.get().find_copy(&e.id)
@@ -201,10 +204,13 @@ pub fn const_expr(cx: @CrateContext, e: &ast::Expr) -> (ValueRef, bool) {
         Some(adj) => {
             match *adj {
                 ty::AutoAddEnv(ty::ReStatic, ast::BorrowedSigil) => {
-                    llconst = C_struct([
-                        llconst,
-                        C_null(Type::opaque_box(cx).ptr_to())
-                    ], false)
+                    let def = ty::resolve_expr(cx.tcx, e);
+                    let wrapper = closure::get_wrapper_for_bare_fn(cx,
+                                                                   ety_adjusted,
+                                                                   def,
+                                                                   llconst,
+                                                                   is_local);
+                    llconst = C_struct([wrapper, C_null(Type::i8p())], false)
                 }
                 ty::AutoAddEnv(ref r, ref s) => {
                     cx.sess
@@ -223,12 +229,12 @@ pub fn const_expr(cx: @CrateContext, e: &ast::Expr) -> (ValueRef, bool) {
                 ty::AutoDerefRef(ref adj) => {
                     let mut ty = ety;
                     let mut maybe_ptr = None;
-                    adj.autoderefs.times(|| {
+                    for _ in range(0, adj.autoderefs) {
                         let (dv, dt) = const_deref(cx, llconst, ty, false);
                         maybe_ptr = Some(llconst);
                         llconst = dv;
                         ty = dt;
-                    });
+                    }
 
                     match adj.autoref {
                         None => { }
@@ -277,13 +283,12 @@ pub fn const_expr(cx: @CrateContext, e: &ast::Expr) -> (ValueRef, bool) {
         }
     }
 
-    let ety_adjusted = ty::expr_ty_adjusted(cx.tcx, e);
     let llty = type_of::sizing_type_of(cx, ety_adjusted);
     let csize = machine::llsize_of_alloc(cx, val_ty(llconst));
     let tsize = machine::llsize_of_alloc(cx, llty);
     if csize != tsize {
         unsafe {
-            // XXX these values could use some context
+            // FIXME these values could use some context
             llvm::LLVMDumpValue(llconst);
             llvm::LLVMDumpValue(C_undef(llty));
         }
@@ -296,22 +301,21 @@ pub fn const_expr(cx: @CrateContext, e: &ast::Expr) -> (ValueRef, bool) {
 
 // the bool returned is whether this expression can be inlined into other crates
 // if it's assigned to a static.
-fn const_expr_unadjusted(cx: @CrateContext,
-                         e: &ast::Expr) -> (ValueRef, bool) {
-    fn map_list(cx: @CrateContext,
-                exprs: &[@ast::Expr]) -> (~[ValueRef], bool) {
-        exprs.iter().map(|&e| const_expr(cx, e))
+fn const_expr_unadjusted(cx: @CrateContext, e: &ast::Expr,
+                         is_local: bool) -> (ValueRef, bool) {
+    let map_list = |exprs: &[@ast::Expr]| {
+        exprs.iter().map(|&e| const_expr(cx, e, is_local))
              .fold((~[], true), |(L, all_inlineable), (val, inlineable)| {
-                    (vec::append_one(L, val), all_inlineable && inlineable)
+                (vec::append_one(L, val), all_inlineable && inlineable)
              })
-    }
+    };
     unsafe {
         let _icx = push_ctxt("const_expr");
         return match e.node {
           ast::ExprLit(lit) => (consts::const_lit(cx, e, *lit), true),
           ast::ExprBinary(_, b, e1, e2) => {
-            let (te1, _) = const_expr(cx, e1);
-            let (te2, _) = const_expr(cx, e2);
+            let (te1, _) = const_expr(cx, e1, is_local);
+            let (te2, _) = const_expr(cx, e2, is_local);
 
             let te2 = base::cast_shift_const_rhs(b, te1, te2);
 
@@ -392,7 +396,7 @@ fn map_list(cx: @CrateContext,
             }, true)
           },
           ast::ExprUnary(_, u, e) => {
-            let (te, _) = const_expr(cx, e);
+            let (te, _) = const_expr(cx, e, is_local);
             let ty = ty::expr_ty(cx.tcx, e);
             let is_float = ty::type_is_fp(ty);
             return (match u {
@@ -421,7 +425,7 @@ fn map_list(cx: @CrateContext,
           ast::ExprField(base, field, _) => {
               let bt = ty::expr_ty_adjusted(cx.tcx, base);
               let brepr = adt::represent_type(cx, bt);
-              let (bv, inlineable) = const_expr(cx, base);
+              let (bv, inlineable) = const_expr(cx, base, is_local);
               expr::with_field_tys(cx.tcx, bt, None, |discr, field_tys| {
                   let ix = ty::field_idx_strict(cx.tcx, field.name, field_tys);
                   (adt::const_get_field(cx, brepr, bv, discr, ix), inlineable)
@@ -430,7 +434,7 @@ fn map_list(cx: @CrateContext,
 
           ast::ExprIndex(_, base, index) => {
               let bt = ty::expr_ty_adjusted(cx.tcx, base);
-              let (bv, inlineable) = const_expr(cx, base);
+              let (bv, inlineable) = const_expr(cx, base, is_local);
               let iv = match const_eval::eval_const_expr(cx.tcx, index) {
                   const_eval::const_int(i) => i as u64,
                   const_eval::const_uint(u) => u,
@@ -471,7 +475,7 @@ fn map_list(cx: @CrateContext,
             let ety = ty::expr_ty(cx.tcx, e);
             let llty = type_of::type_of(cx, ety);
             let basety = ty::expr_ty(cx.tcx, base);
-            let (v, inlineable) = const_expr(cx, base);
+            let (v, inlineable) = const_expr(cx, base, is_local);
             return (match (expr::cast_type_kind(basety),
                            expr::cast_type_kind(ety)) {
 
@@ -522,13 +526,13 @@ fn map_list(cx: @CrateContext,
             }, inlineable)
           }
           ast::ExprAddrOf(ast::MutImmutable, sub) => {
-              let (e, _) = const_expr(cx, sub);
+              let (e, _) = const_expr(cx, sub, is_local);
               (const_addr_of(cx, e), false)
           }
           ast::ExprTup(ref es) => {
               let ety = ty::expr_ty(cx.tcx, e);
               let repr = adt::represent_type(cx, ety);
-              let (vals, inlineable) = map_list(cx, *es);
+              let (vals, inlineable) = map_list(*es);
               (adt::trans_const(cx, repr, 0, vals), inlineable)
           }
           ast::ExprStruct(_, ref fs, ref base_opt) => {
@@ -537,7 +541,7 @@ fn map_list(cx: @CrateContext,
               let tcx = cx.tcx;
 
               let base_val = match *base_opt {
-                Some(base) => Some(const_expr(cx, base)),
+                Some(base) => Some(const_expr(cx, base, is_local)),
                 None => None
               };
 
@@ -545,7 +549,7 @@ fn map_list(cx: @CrateContext,
                   let cs = field_tys.iter().enumerate()
                       .map(|(ix, &field_ty)| {
                       match fs.iter().find(|f| field_ty.ident.name == f.ident.node.name) {
-                          Some(f) => const_expr(cx, (*f).expr),
+                          Some(f) => const_expr(cx, (*f).expr, is_local),
                           None => {
                               match base_val {
                                 Some((bv, inlineable)) => {
@@ -563,19 +567,19 @@ fn map_list(cx: @CrateContext,
               })
           }
           ast::ExprVec(ref es, ast::MutImmutable) => {
-            let (v, _, inlineable) = const_vec(cx, e, *es);
+            let (v, _, inlineable) = const_vec(cx, e, *es, is_local);
             (v, inlineable)
           }
           ast::ExprVstore(sub, ast::ExprVstoreSlice) => {
             match sub.node {
               ast::ExprLit(ref lit) => {
                 match lit.node {
-                    ast::LitStr(..) => { const_expr(cx, sub) }
+                    ast::LitStr(..) => { const_expr(cx, sub, is_local) }
                     _ => { cx.sess.span_bug(e.span, "bad const-slice lit") }
                 }
               }
               ast::ExprVec(ref es, ast::MutImmutable) => {
-                let (cv, llunitty, _) = const_vec(cx, e, *es);
+                let (cv, llunitty, _) = const_vec(cx, e, *es, is_local);
                 let llty = val_ty(cv);
                 let gv = "const".with_c_str(|name| {
                     llvm::LLVMAddGlobal(cx.llmod, llty.to_ref(), name)
@@ -598,7 +602,7 @@ fn map_list(cx: @CrateContext,
                 const_eval::const_uint(i) => i as uint,
                 _ => cx.sess.span_bug(count.span, "count must be integral const expression.")
             };
-            let vs = vec::from_elem(n, const_expr(cx, elem).first());
+            let vs = vec::from_elem(n, const_expr(cx, elem, is_local).first());
             let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
                 C_struct(vs, false)
             } else {
@@ -656,7 +660,7 @@ fn map_list(cx: @CrateContext,
                   Some(ast::DefStruct(_)) => {
                       let ety = ty::expr_ty(cx.tcx, e);
                       let repr = adt::represent_type(cx, ety);
-                      let (arg_vals, inlineable) = map_list(cx, *args);
+                      let (arg_vals, inlineable) = map_list(*args);
                       (adt::trans_const(cx, repr, 0, arg_vals), inlineable)
                   }
                   Some(ast::DefVariant(enum_did, variant_did, _)) => {
@@ -665,14 +669,14 @@ fn map_list(cx: @CrateContext,
                       let vinfo = ty::enum_variant_with_id(cx.tcx,
                                                            enum_did,
                                                            variant_did);
-                      let (arg_vals, inlineable) = map_list(cx, *args);
+                      let (arg_vals, inlineable) = map_list(*args);
                       (adt::trans_const(cx, repr, vinfo.disr_val, arg_vals),
                        inlineable)
                   }
                   _ => cx.sess.span_bug(e.span, "expected a struct or variant def")
               }
           }
-          ast::ExprParen(e) => { const_expr(cx, e) }
+          ast::ExprParen(e) => { const_expr(cx, e, is_local) }
           _ => cx.sess.span_bug(e.span,
                   "bad constant expression type in consts::const_expr")
         };
index 527308be0fffa8230fcd43e268318deff638c71e..8503ce9066bc3d07a2c52009e9bd4594d0966e83 100644 (file)
@@ -91,6 +91,9 @@ pub struct CrateContext {
 
      impl_method_cache: RefCell<HashMap<(ast::DefId, ast::Name), ast::DefId>>,
 
+     // Cache of closure wrappers for bare fn's.
+     closure_bare_wrapper_cache: RefCell<HashMap<ValueRef, ValueRef>>,
+
      module_data: RefCell<HashMap<~str, ValueRef>>,
      lltypes: RefCell<HashMap<ty::t, Type>>,
      llsizingtypes: RefCell<HashMap<ty::t, Type>>,
@@ -165,7 +168,7 @@ pub fn new(sess: session::Session,
 
             let (crate_map_name, crate_map) = decl_crate_map(sess, link_meta.clone(), llmod);
             let dbg_cx = if sess.opts.debuginfo {
-                Some(debuginfo::CrateDebugContext::new(llmod, name.to_owned()))
+                Some(debuginfo::CrateDebugContext::new(llmod))
             } else {
                 None
             };
@@ -201,6 +204,7 @@ pub fn new(sess: session::Session,
                   const_values: RefCell::new(HashMap::new()),
                   extern_const_values: RefCell::new(HashMap::new()),
                   impl_method_cache: RefCell::new(HashMap::new()),
+                  closure_bare_wrapper_cache: RefCell::new(HashMap::new()),
                   module_data: RefCell::new(HashMap::new()),
                   lltypes: RefCell::new(HashMap::new()),
                   llsizingtypes: RefCell::new(HashMap::new()),
index ec47dbacb39c0eb85ebaa91fa16b2ea46f7b5b2c..8c8c6829e49fd6f5a46b71460ad4ac5f69934c5c 100644 (file)
@@ -309,7 +309,7 @@ pub fn trans_ret<'a>(bcx: &'a Block<'a>,
         Some(x) => {
             bcx = expr::trans_into(bcx, x, dest);
         }
-        _ => ()
+        _ => {}
     }
     let cleanup_llbb = fcx.return_exit_block();
     Br(bcx, cleanup_llbb);
index 467501449b8d5c8b8488c44c4a5440eb1cba0a17..4888c2ce4d5dc920f8ce9c251b59501ce1311092 100644 (file)
@@ -491,7 +491,7 @@ pub fn to_rvalue_datum<'a>(self,
                     }
                     ByValue => {
                         let v = load(bcx, l.val, l.ty);
-                        l.kind.post_store(bcx, l.val, l.ty);
+                        bcx = l.kind.post_store(bcx, l.val, l.ty);
                         DatumBlock(bcx, Datum(v, l.ty, Rvalue(ByValue)))
                     }
                 }
index 4c5ed91e5f74750f1b94f37494778cae715548eb..36cc6f3afd16e40b419c8e9e824e99cad59c373c 100644 (file)
@@ -130,8 +130,6 @@ struct List {
 use lib::llvm::{ModuleRef, ContextRef, ValueRef};
 use lib::llvm::debuginfo::*;
 use middle::trans::adt;
-use middle::trans::base;
-use middle::trans::build;
 use middle::trans::common::*;
 use middle::trans::datum::{Datum, Lvalue};
 use middle::trans::machine;
@@ -142,7 +140,7 @@ struct List {
 use middle::pat_util;
 use util::ppaux;
 
-use std::c_str::ToCStr;
+use std::c_str::{CString, ToCStr};
 use std::cell::{Cell, RefCell};
 use std::hashmap::HashMap;
 use std::hashmap::HashSet;
@@ -151,7 +149,7 @@ struct List {
 use std::sync::atomics;
 use std::vec;
 use syntax::codemap::{Span, Pos};
-use syntax::{ast, codemap, ast_util, ast_map, opt_vec};
+use syntax::{abi, ast, codemap, ast_util, ast_map, opt_vec};
 use syntax::parse::token;
 use syntax::parse::token::special_idents;
 
@@ -173,7 +171,6 @@ struct List {
 
 /// A context object for maintaining all state needed by the debuginfo module.
 pub struct CrateDebugContext {
-    priv crate_file: ~str,
     priv llcontext: ContextRef,
     priv builder: DIBuilderRef,
     priv current_debug_location: Cell<DebugLocation>,
@@ -186,13 +183,12 @@ pub struct CrateDebugContext {
 }
 
 impl CrateDebugContext {
-    pub fn new(llmod: ModuleRef, crate: ~str) -> CrateDebugContext {
+    pub fn new(llmod: ModuleRef) -> CrateDebugContext {
         debug!("CrateDebugContext::new");
         let builder = unsafe { llvm::LLVMDIBuilderCreate(llmod) };
         // DIBuilder inherits context from the module, so we'd better use the same one
         let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) };
         return CrateDebugContext {
-            crate_file: crate,
             llcontext: llcontext,
             builder: builder,
             current_debug_location: Cell::new(UnknownLocation),
@@ -265,6 +261,20 @@ pub fn finalize(cx: @CrateContext) {
     unsafe {
         llvm::LLVMDIBuilderFinalize(DIB(cx));
         llvm::LLVMDIBuilderDispose(DIB(cx));
+        // Debuginfo generation in LLVM by default uses a higher
+        // version of dwarf than OS X currently understands. We can
+        // instruct LLVM to emit an older version of dwarf, however,
+        // for OS X to understand. For more info see #11352
+        // This can be overridden using --llvm-opts -dwarf-version,N.
+        if cx.sess.targ_cfg.os == abi::OsMacos {
+            "Dwarf Version".with_c_str(
+                |s| llvm::LLVMRustAddModuleFlag(cx.llmod, s, 2));
+        }
+
+        // Prevent bitcode readers from deleting the debug info.
+        "Debug Info Version".with_c_str(
+            |s| llvm::LLVMRustAddModuleFlag(cx.llmod, s,
+                                            llvm::LLVMRustDebugMetadataVersion));
     };
 }
 
@@ -328,8 +338,7 @@ pub fn create_captured_var_metadata(bcx: &Block,
         None => {
             cx.sess.span_bug(span, "debuginfo::create_captured_var_metadata() - NodeId not found");
         }
-        Some(ast_map::NodeLocal(ident, _)) => ident,
-        Some(ast_map::NodeArg(pat)) => {
+        Some(ast_map::NodeLocal(pat)) | Some(ast_map::NodeArg(pat)) => {
             match pat.node {
                 ast::PatIdent(_, ref path, _) => {
                     ast_util::path_to_ident(path)
@@ -410,83 +419,6 @@ pub fn create_match_binding_metadata(bcx: &Block,
                   span);
 }
 
-/// Creates debug information for the self argument of a method.
-///
-/// Adds the created metadata nodes directly to the crate's IR.
-pub fn create_self_argument_metadata(bcx: &Block,
-                                     type_of_self: ty::t,
-                                     llptr: ValueRef) {
-    if fn_should_be_ignored(bcx.fcx) {
-        return;
-    }
-
-    // Extract the span of the self argument from the method's AST
-    let fnitem = bcx.ccx().tcx.items.get(bcx.fcx.id);
-    let span = match fnitem {
-        ast_map::NodeMethod(method, _, _) => {
-            method.explicit_self.span
-        }
-        ast_map::NodeTraitMethod(trait_method, _, _) => {
-            match *trait_method {
-                ast::Provided(method) => method.explicit_self.span,
-                _ => {
-                    bcx.ccx()
-                       .sess
-                       .bug(format!("create_self_argument_metadata: \
-                                     unexpected sort of node: {:?}",
-                                     fnitem))
-                }
-            }
-        }
-        _ => bcx.ccx().sess.bug(
-                format!("create_self_argument_metadata: unexpected sort of node: {:?}", fnitem))
-    };
-
-    let scope_metadata = bcx.fcx.debug_context.get_ref(bcx.ccx(), span).fn_metadata;
-
-    let argument_index = {
-        let counter = &bcx.fcx.debug_context.get_ref(bcx.ccx(), span).argument_counter;
-        let argument_index = counter.get();
-        counter.set(argument_index + 1);
-        argument_index
-    };
-
-    let address_operations = &[unsafe { llvm::LLVMDIBuilderCreateOpDeref(Type::i64().to_ref()) }];
-
-    // The self argument comes in one of two forms:
-    // (1) For `&self`, `~self`, and `@self` it is an alloca containing a pointer to the data. That
-    //     is the `{&~@}self` pointer is contained by value in the alloca, and `type_of_self` will
-    //     be `{&~@}Self`
-    // (2) For by-value `self`, `llptr` will not be an alloca, but a pointer to the self-value. That
-    //     is by-value `self` is always implicitly passed by reference (sic!). So we have a couple
-    //     of problems here:
-    //     (a) There is no alloca to give to `llvm.dbg.declare` and
-    //     (b) `type_of_self` is `Self`, but `llptr` is of type `*Self`
-    //     In order to solve this problem, the else branch below creates a helper alloca which
-    //     contains a copy of `llptr`. We then describe the `self` parameter by pointing
-    //     `llvm.dbg.declare` to this helper alloca and tell it that the pointer there needs to be
-    //     dereferenced once to get to the actual data (similar to non-immediate by-value args).
-    let variable_access = if unsafe { llvm::LLVMIsAAllocaInst(llptr) } != ptr::null() {
-        DirectVariable { alloca: llptr }
-    } else {
-        // Create a helper alloca that allows us to track the self-argument properly. The alloca
-        // contains a pointer to the self-value.
-        let ptr_type = ty::mk_mut_ptr(bcx.tcx(), type_of_self);
-        let helper_alloca = base::alloc_ty(bcx, ptr_type, "__self");
-        build::Store(bcx, llptr, helper_alloca);
-
-        IndirectVariable { alloca: helper_alloca, address_operations: address_operations }
-    };
-
-    declare_local(bcx,
-                  special_idents::self_,
-                  type_of_self,
-                  scope_metadata,
-                  variable_access,
-                  ArgumentVariable(argument_index),
-                  span);
-}
-
 /// Creates debug information for the given function argument.
 ///
 /// Adds the created metadata nodes directly to the crate's IR.
@@ -929,26 +861,49 @@ fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray {
     };
 }
 
-fn compile_unit_metadata(cx: @CrateContext) {
-    let dcx = debug_context(cx);
-    let crate_name: &str = dcx.crate_file;
-
-    debug!("compile_unit_metadata: {:?}", crate_name);
+fn compile_unit_metadata(cx: &CrateContext) {
+    let work_dir = &cx.sess.working_dir;
+    let compile_unit_name = match cx.sess.local_crate_source_file {
+        None => fallback_path(cx),
+        Some(ref abs_path) => {
+            if abs_path.is_relative() {
+                cx.sess.warn("debuginfo: Invalid path to crate's local root source file!");
+                fallback_path(cx)
+            } else {
+                match abs_path.path_relative_from(work_dir) {
+                    Some(ref p) if p.is_relative() => {
+                            // prepend "./" if necessary
+                            let dotdot = bytes!("..");
+                            let prefix = &[dotdot[0], ::std::path::SEP_BYTE];
+                            let mut path_bytes = p.as_vec().to_owned();
+
+                            if path_bytes.slice_to(2) != prefix &&
+                               path_bytes.slice_to(2) != dotdot {
+                                path_bytes.insert(0, prefix[0]);
+                                path_bytes.insert(1, prefix[1]);
+                            }
+
+                            path_bytes.to_c_str()
+                        }
+                    _ => fallback_path(cx)
+                }
+            }
+        }
+    };
 
-    // FIXME (#9639): This needs to handle non-utf8 paths
-    let work_dir = cx.sess.working_dir.as_str().unwrap();
+    debug!("compile_unit_metadata: {:?}", compile_unit_name);
     let producer = format!("rustc version {}", env!("CFG_VERSION"));
 
-    crate_name.with_c_str(|crate_name| {
-        work_dir.with_c_str(|work_dir| {
+    compile_unit_name.with_ref(|compile_unit_name| {
+        work_dir.as_vec().with_c_str(|work_dir| {
             producer.with_c_str(|producer| {
                 "".with_c_str(|flags| {
                     "".with_c_str(|split_name| {
                         unsafe {
                             llvm::LLVMDIBuilderCreateCompileUnit(
-                                dcx.builder,
+                                debug_context(cx).builder,
                                 DW_LANG_RUST,
-                                crate_name,
+                                compile_unit_name,
                                 work_dir,
                                 producer,
                                 cx.sess.opts.optimize != session::No,
@@ -961,6 +916,10 @@ fn compile_unit_metadata(cx: @CrateContext) {
             })
         })
     });
+
+    fn fallback_path(cx: &CrateContext) -> CString {
+        cx.link_meta.crateid.name.to_c_str()
+    }
 }
 
 fn declare_local(bcx: &Block,
@@ -1687,7 +1646,7 @@ fn set_members_of_composite_type(cx: &CrateContext,
         .map(|(i, member_description)| {
             let (member_size, member_align) = size_and_align_of(cx, member_description.llvm_type);
             let member_offset = match member_description.offset {
-                FixedMemberOffset { bytes } => bytes,
+                FixedMemberOffset { bytes } => bytes as u64,
                 ComputedMemberOffset => machine::llelement_offset(cx, composite_llvm_type, i)
             };
 
@@ -1768,7 +1727,7 @@ fn boxed_type_metadata(cx: &CrateContext,
         None                    => ~"BoxedType"
     };
 
-    let box_llvm_type = Type::smart_ptr(cx, &content_llvm_type);
+    let box_llvm_type = Type::at_box(cx, content_llvm_type);
     let member_llvm_types = box_llvm_type.field_types();
     assert!(box_layout_is_correct(cx, member_llvm_types, content_llvm_type));
 
@@ -1856,7 +1815,7 @@ fn fixed_vec_metadata(cx: &CrateContext,
     return unsafe {
         llvm::LLVMDIBuilderCreateArrayType(
             DIB(cx),
-            bytes_to_bits(element_type_size * len),
+            bytes_to_bits(element_type_size * (len as u64)),
             bytes_to_bits(element_type_align),
             element_type_metadata,
             subscripts)
@@ -2041,7 +2000,8 @@ fn trait_metadata(cx: &CrateContext,
                ppaux::mutability_to_str(mutability) +
                token::ident_to_str(&ident);
     // Add type and region parameters
-    let name = ppaux::parameterized(cx.tcx, name, &substs.regions, substs.tps);
+    let name = ppaux::parameterized(cx.tcx, name, &substs.regions,
+                                    substs.tps, def_id, true);
 
     let (containing_scope, definition_span) =
         get_namespace_and_span_for_item(cx, def_id, usage_site_span);
@@ -2251,11 +2211,11 @@ fn span_start(cx: &CrateContext, span: Span) -> codemap::Loc {
     cx.sess.codemap.lookup_char_pos(span.lo)
 }
 
-fn size_and_align_of(cx: &CrateContext, llvm_type: Type) -> (uint, uint) {
+fn size_and_align_of(cx: &CrateContext, llvm_type: Type) -> (u64, u64) {
     (machine::llsize_of_alloc(cx, llvm_type), machine::llalign_of_min(cx, llvm_type))
 }
 
-fn bytes_to_bits(bytes: uint) -> c_ulonglong {
+fn bytes_to_bits(bytes: u64) -> c_ulonglong {
     (bytes * 8) as c_ulonglong
 }
 
@@ -2584,11 +2544,10 @@ fn walk_expr(cx: &CrateContext,
 
         match exp.node {
             ast::ExprLogLevel |
-            ast::ExprSelf     |
             ast::ExprLit(_)   |
             ast::ExprBreak(_) |
             ast::ExprAgain(_) |
-            ast::ExprPath(_)  => (),
+            ast::ExprPath(_)  => {}
 
             ast::ExprVstore(sub_exp, _)   |
             ast::ExprCast(sub_exp, _)     |
@@ -2697,21 +2656,6 @@ fn walk_expr(cx: &CrateContext,
                 })
             }
 
-            // ast::expr_loop_body(inner_exp) |
-            ast::ExprDoBody(inner_exp)   => {
-                let inner_expr_is_expr_fn_block = match *inner_exp {
-                    ast::Expr { node: ast::ExprFnBlock(..), .. } => true,
-                    _ => false
-                };
-
-                if !inner_expr_is_expr_fn_block {
-                    cx.sess.span_bug(inner_exp.span, "debuginfo: Inner expression was expected \
-                                                      to be an ast::expr_fn_block.");
-                }
-
-                walk_expr(cx, inner_exp, scope_stack, scope_map);
-            }
-
             ast::ExprCall(fn_exp, ref args, _) => {
                 walk_expr(cx, fn_exp, scope_stack, scope_map);
 
@@ -2720,9 +2664,8 @@ fn walk_expr(cx: &CrateContext,
                 }
             }
 
-            ast::ExprMethodCall(node_id, receiver_exp, _, _, ref args, _) => {
+            ast::ExprMethodCall(node_id, _, _, ref args, _) => {
                 scope_map.insert(node_id, scope_stack.last().unwrap().scope_metadata);
-                walk_expr(cx, receiver_exp, scope_stack, scope_map);
 
                 for arg_exp in args.iter() {
                     walk_expr(cx, *arg_exp, scope_stack, scope_map);
index 36fc927b64c4546ba91468b8e82acab05d648404..d0a01f56b530c4ac084e726925fcd3accc42d019 100644 (file)
@@ -42,7 +42,6 @@
 use middle::trans::base::*;
 use middle::trans::base;
 use middle::trans::build::*;
-use middle::trans::callee::DoAutorefArg;
 use middle::trans::callee;
 use middle::trans::cleanup;
 use middle::trans::cleanup::CleanupMethods;
@@ -316,16 +315,10 @@ fn add_env<'a>(bcx: &'a Block<'a>,
         // code and keep it DRY that accommodates that use case at the
         // moment.
 
-        let tcx = bcx.tcx();
         let closure_ty = expr_ty_adjusted(bcx, expr);
-        debug!("add_env(closure_ty={})", closure_ty.repr(tcx));
-        let scratch = rvalue_scratch_datum(bcx, closure_ty, "__adjust");
-        let llfn = GEPi(bcx, scratch.val, [0u, abi::fn_field_code]);
-        let llval = datum.to_llscalarish(bcx);
-        Store(bcx, llval, llfn);
-        let llenv = GEPi(bcx, scratch.val, [0u, abi::fn_field_box]);
-        Store(bcx, base::null_env_ptr(bcx.ccx()), llenv);
-        DatumBlock(bcx, scratch.to_expr_datum())
+        let fn_ptr = datum.to_llscalarish(bcx);
+        let def = ty::resolve_expr(bcx.tcx(), expr);
+        closure::make_closure_from_bare_fn(bcx, closure_ty, def, fn_ptr)
     }
 
     fn auto_slice_and_ref<'a>(
@@ -517,7 +510,7 @@ fn trans_datum_unadjusted<'a>(bcx: &'a Block<'a>,
         ast::ExprParen(e) => {
             trans(bcx, e)
         }
-        ast::ExprPath(_) | ast::ExprSelf => {
+        ast::ExprPath(_) => {
             trans_def(bcx, expr, bcx.def(expr.id))
         }
         ast::ExprField(base, ident, _) => {
@@ -669,7 +662,8 @@ fn trans_def<'a>(bcx: &'a Block<'a>,
 
     let _icx = push_ctxt("trans_def_lvalue");
     match def {
-        ast::DefFn(..) | ast::DefStaticMethod(..) => {
+        ast::DefFn(..) | ast::DefStaticMethod(..) |
+        ast::DefStruct(_) | ast::DefVariant(..) => {
             trans_def_fn_unadjusted(bcx, ref_expr, def)
         }
         ast::DefStatic(did, _) => {
@@ -817,34 +811,33 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
 
     match expr.node {
         ast::ExprParen(e) => {
-            return trans_into(bcx, e, dest);
+            trans_into(bcx, e, dest)
         }
-        ast::ExprPath(_) | ast::ExprSelf => {
-            return trans_def_dps_unadjusted(bcx, expr,
-                                            bcx.def(expr.id), dest);
+        ast::ExprPath(_) => {
+            trans_def_dps_unadjusted(bcx, expr, bcx.def(expr.id), dest)
         }
         ast::ExprIf(cond, thn, els) => {
-            return controlflow::trans_if(bcx, expr.id, cond, thn, els, dest);
+            controlflow::trans_if(bcx, expr.id, cond, thn, els, dest)
         }
         ast::ExprMatch(discr, ref arms) => {
-            return _match::trans_match(bcx, expr, discr, *arms, dest);
+            _match::trans_match(bcx, expr, discr, *arms, dest)
         }
         ast::ExprBlock(blk) => {
             controlflow::trans_block(bcx, blk, dest)
         }
         ast::ExprStruct(_, ref fields, base) => {
-            return trans_rec_or_struct(bcx, (*fields), base, expr.span, expr.id, dest);
+            trans_rec_or_struct(bcx, (*fields), base, expr.span, expr.id, dest)
         }
         ast::ExprTup(ref args) => {
             let repr = adt::represent_type(bcx.ccx(), expr_ty(bcx, expr));
             let numbered_fields: ~[(uint, @ast::Expr)] =
                 args.iter().enumerate().map(|(i, arg)| (i, *arg)).collect();
-            return trans_adt(bcx, repr, 0, numbered_fields, None, dest);
+            trans_adt(bcx, repr, 0, numbered_fields, None, dest)
         }
         ast::ExprLit(lit) => {
             match lit.node {
                 ast::LitStr(s, _) => {
-                    return tvec::trans_lit_str(bcx, expr, s, dest);
+                    tvec::trans_lit_str(bcx, expr, s, dest)
                 }
                 _ => {
                     bcx.tcx()
@@ -859,10 +852,10 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
         ast::ExprVstore(contents, ast::ExprVstoreMutSlice) => {
             fcx.push_ast_cleanup_scope(contents.id);
             bcx = tvec::trans_slice_vstore(bcx, expr, contents, dest);
-            return fcx.pop_and_trans_ast_cleanup_scope(bcx, contents.id);
+            fcx.pop_and_trans_ast_cleanup_scope(bcx, contents.id)
         }
         ast::ExprVec(..) | ast::ExprRepeat(..) => {
-            return tvec::trans_fixed_vstore(bcx, expr, expr, dest);
+            tvec::trans_fixed_vstore(bcx, expr, expr, dest)
         }
         ast::ExprFnBlock(decl, body) |
         ast::ExprProc(decl, body) => {
@@ -871,60 +864,38 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
             debug!("translating block function {} with type {}",
                    expr_to_str(expr, tcx.sess.intr()),
                    expr_ty.repr(tcx));
-            return closure::trans_expr_fn(bcx, sigil, decl, body,
-                                          expr.id, expr.id, dest);
-        }
-        ast::ExprDoBody(blk) => {
-            return trans_into(bcx, blk, dest);
+            closure::trans_expr_fn(bcx, sigil, decl, body,
+                                   expr.id, expr.id, dest)
         }
         ast::ExprCall(f, ref args, _) => {
-            return callee::trans_call(
-                bcx, expr, f, callee::ArgExprs(*args), expr.id, dest);
+            callee::trans_call(bcx, expr, f,
+                               callee::ArgExprs(*args), expr.id, dest)
         }
-        ast::ExprMethodCall(callee_id, rcvr, _, _, ref args, _) => {
-            return callee::trans_method_call(bcx,
-                                             expr,
-                                             callee_id,
-                                             rcvr,
-                                             callee::ArgExprs(*args),
-                                             dest);
+        ast::ExprMethodCall(callee_id, _, _, ref args, _) => {
+            callee::trans_method_call(bcx, expr, callee_id, args[0],
+                                      callee::ArgExprs(*args), dest)
         }
         ast::ExprBinary(callee_id, _, lhs, rhs) => {
             // if not overloaded, would be RvalueDatumExpr
-            return trans_overloaded_op(bcx,
-                                       expr,
-                                       callee_id,
-                                       lhs,
-                                       ~[rhs],
-                                       expr_ty(bcx, expr),
-                                       dest);
+            trans_overloaded_op(bcx, expr, callee_id, lhs,
+                                Some(&*rhs), expr_ty(bcx, expr), dest)
         }
         ast::ExprUnary(callee_id, _, subexpr) => {
             // if not overloaded, would be RvalueDatumExpr
-            return trans_overloaded_op(bcx,
-                                       expr,
-                                       callee_id,
-                                       subexpr,
-                                       ~[],
-                                       expr_ty(bcx, expr),
-                                       dest);
+            trans_overloaded_op(bcx, expr, callee_id, subexpr,
+                                None, expr_ty(bcx, expr), dest)
         }
         ast::ExprIndex(callee_id, base, idx) => {
             // if not overloaded, would be RvalueDatumExpr
-            return trans_overloaded_op(bcx,
-                                       expr,
-                                       callee_id,
-                                       base,
-                                       ~[idx],
-                                       expr_ty(bcx, expr),
-                                       dest);
+            trans_overloaded_op(bcx, expr, callee_id, base,
+                                Some(&*idx), expr_ty(bcx, expr), dest)
         }
         ast::ExprCast(val, _) => {
             // DPS output mode means this is a trait cast:
             match ty::get(node_id_type(bcx, expr.id)).sty {
                 ty::ty_trait(..) => {
                     let datum = unpack_datum!(bcx, trans(bcx, val));
-                    return meth::trans_trait_cast(bcx, datum, expr.id, dest);
+                    meth::trans_trait_cast(bcx, datum, expr.id, dest)
                 }
                 _ => {
                     bcx.tcx().sess.span_bug(expr.span,
@@ -933,12 +904,12 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
             }
         }
         ast::ExprAssignOp(callee_id, op, dst, src) => {
-            return trans_assign_op(bcx, expr, callee_id, op, dst, src);
+            trans_assign_op(bcx, expr, callee_id, op, dst, src)
         }
         ast::ExprBox(_, contents) => {
             // Special case for `Gc<T>` for now. The other case, for unique
             // pointers, is handled in `trans_rvalue_datum_unadjusted`.
-            return trans_gc(bcx, expr, contents, dest)
+            trans_gc(bcx, expr, contents, dest)
         }
         _ => {
             bcx.tcx().sess.span_bug(
@@ -968,8 +939,8 @@ fn trans_def_dps_unadjusted<'a>(
             let variant_info = ty::enum_variant_with_id(ccx.tcx, tid, vid);
             if variant_info.args.len() > 0u {
                 // N-ary variant.
-                let fn_data = callee::trans_fn_ref(bcx, vid, ref_expr.id);
-                Store(bcx, fn_data.llfn, lldest);
+                let llfn = callee::trans_fn_ref(bcx, vid, ref_expr.id);
+                Store(bcx, llfn, lldest);
                 return bcx;
             } else {
                 // Nullary variant.
@@ -980,20 +951,16 @@ fn trans_def_dps_unadjusted<'a>(
                 return bcx;
             }
         }
-        ast::DefStruct(def_id) => {
+        ast::DefStruct(_) => {
             let ty = expr_ty(bcx, ref_expr);
             match ty::get(ty).sty {
                 ty::ty_struct(did, _) if ty::has_dtor(ccx.tcx, did) => {
                     let repr = adt::represent_type(ccx, ty);
                     adt::trans_start_init(bcx, repr, lldest, 0);
                 }
-                ty::ty_bare_fn(..) => {
-                    let fn_data = callee::trans_fn_ref(bcx, def_id, ref_expr.id);
-                    Store(bcx, fn_data.llfn, lldest);
-                }
-                _ => ()
+                _ => {}
             }
-            return bcx;
+            bcx
         }
         _ => {
             bcx.tcx().sess.span_bug(ref_expr.span, format!(
@@ -1009,16 +976,15 @@ fn trans_def_fn_unadjusted<'a>(bcx: &'a Block<'a>,
 {
     let _icx = push_ctxt("trans_def_datum_unadjusted");
 
-    let fn_data = match def {
+    let llfn = match def {
         ast::DefFn(did, _) |
+        ast::DefStruct(did) | ast::DefVariant(_, did, _) |
         ast::DefStaticMethod(did, ast::FromImpl(_), _) => {
             callee::trans_fn_ref(bcx, did, ref_expr.id)
         }
         ast::DefStaticMethod(impl_did, ast::FromTrait(trait_did), _) => {
-            meth::trans_static_method_callee(bcx,
-                                             impl_did,
-                                             trait_did,
-                                             ref_expr.id)
+            meth::trans_static_method_callee(bcx, impl_did,
+                                             trait_did, ref_expr.id)
         }
         _ => {
             bcx.tcx().sess.span_bug(ref_expr.span, format!(
@@ -1029,7 +995,7 @@ fn trans_def_fn_unadjusted<'a>(bcx: &'a Block<'a>,
     };
 
     let fn_ty = expr_ty(bcx, ref_expr);
-    DatumBlock(bcx, Datum(fn_data.llfn, fn_ty, RvalueExpr(Rvalue(ByValue))))
+    DatumBlock(bcx, Datum(llfn, fn_ty, RvalueExpr(Rvalue(ByValue))))
 }
 
 pub fn trans_local_var<'a>(bcx: &'a Block<'a>,
@@ -1063,21 +1029,6 @@ pub fn trans_local_var<'a>(bcx: &'a Block<'a>,
             let lllocals = bcx.fcx.lllocals.borrow();
             take_local(bcx, lllocals.get(), nid)
         }
-        ast::DefSelf(nid, _) => {
-            let self_info = match bcx.fcx.llself.get() {
-                Some(self_info) => self_info,
-                None => {
-                    bcx.sess().bug(format!(
-                        "trans_local_var: reference to self \
-                         out of context with id {:?}", nid));
-                }
-            };
-
-            debug!("def_self() reference, self_info.ty={}",
-                   self_info.ty.repr(bcx.tcx()));
-
-            self_info
-        }
         _ => {
             bcx.sess().unimpl(format!(
                 "unsupported def type in trans_local_var: {:?}", def));
@@ -1630,12 +1581,12 @@ fn trans_binary<'a>(
     }
 }
 
-fn trans_overloaded_op<'a>(
+fn trans_overloaded_op<'a, 'b>(
                        bcx: &'a Block<'a>,
                        expr: &ast::Expr,
                        callee_id: ast::NodeId,
-                       rcvr: &ast::Expr,
-                       args: ~[@ast::Expr],
+                       rcvr: &'b ast::Expr,
+                       arg: Option<&'b ast::Expr>,
                        ret_ty: ty::t,
                        dest: Dest)
                        -> &'a Block<'a> {
@@ -1655,9 +1606,8 @@ fn trans_overloaded_op<'a>(
                                                           origin,
                                                           arg_cleanup_scope)
                              },
-                             callee::ArgExprs(args),
-                             Some(dest),
-                             DoAutorefArg).bcx
+                             callee::ArgAutorefSecond(rcvr, arg),
+                             Some(dest)).bcx
 }
 
 fn int_cast(bcx: &Block,
index 2526d8e3fea27655410b3a47adb9ed67908361be..d9a34e1da7d51cac8185f03da0d9fbc991f95bef 100644 (file)
@@ -341,7 +341,7 @@ pub fn trans_native_call<'a>(
             let llalign = cmp::min(llforeign_align, llrust_align);
             debug!("llrust_size={:?}", llrust_size);
             base::call_memcpy(bcx, llretptr_i8, llscratch_i8,
-                              C_uint(ccx, llrust_size), llalign as u32);
+                              C_uint(ccx, llrust_size as uint), llalign as u32);
         }
     }
 
@@ -480,18 +480,10 @@ fn build_rust_fn(ccx: @CrateContext,
                id,
                t.repr(tcx));
 
-        let llfndecl = base::decl_internal_rust_fn(ccx, None, f.sig.inputs, f.sig.output, ps);
-        base::set_llvm_fn_attrs(attrs, llfndecl);
-        base::trans_fn(ccx,
-                       (*path).clone(),
-                       decl,
-                       body,
-                       llfndecl,
-                       None,
-                       None,
-                       id,
-                       []);
-        return llfndecl;
+        let llfn = base::decl_internal_rust_fn(ccx, false, f.sig.inputs, f.sig.output, ps);
+        base::set_llvm_fn_attrs(attrs, llfn);
+        base::trans_fn(ccx, (*path).clone(), decl, body, llfn, None, id, []);
+        llfn
     }
 
     unsafe fn build_wrap_fn(ccx: @CrateContext,
@@ -597,11 +589,6 @@ unsafe fn build_wrap_fn(ccx: @CrateContext,
             return_alloca = None;
         };
 
-        // Push an (null) env pointer
-        let env_pointer = base::null_env_ptr(ccx);
-        debug!("env pointer={}", ccx.tn.val_to_str(env_pointer));
-        llrust_args.push(env_pointer);
-
         // Build up the arguments to the call to the rust function.
         // Careful to adapt for cases where the native convention uses
         // a pointer and Rust does not or vice versa.
index ae03d48dbf0dc3d0d86e2ea5b97b150756a63af4..ab77d105e5feaf85c51a8d04dfa7131f3d582278 100644 (file)
@@ -23,7 +23,6 @@
 use middle::trans::callee;
 use middle::trans::cleanup;
 use middle::trans::cleanup::CleanupMethods;
-use middle::trans::closure;
 use middle::trans::common::*;
 use middle::trans::build::*;
 use middle::trans::expr;
@@ -59,14 +58,24 @@ pub fn trans_exchange_free<'a>(cx: &'a Block<'a>, v: ValueRef)
         Some(expr::Ignore)).bcx
 }
 
-pub fn take_ty<'a>(cx: &'a Block<'a>, v: ValueRef, t: ty::t)
+pub fn take_ty<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
                -> &'a Block<'a> {
     // NB: v is an *alias* of type t here, not a direct value.
     let _icx = push_ctxt("take_ty");
-    if ty::type_needs_drop(cx.tcx(), t) {
-        return call_tydesc_glue(cx, v, t, abi::tydesc_field_take_glue);
+    match ty::get(t).sty {
+        ty::ty_box(_) |
+        ty::ty_vec(_, ty::vstore_box) | ty::ty_str(ty::vstore_box) => {
+            incr_refcnt_of_boxed(bcx, v)
+        }
+        ty::ty_trait(_, _, ty::BoxTraitStore, _, _) => {
+            incr_refcnt_of_boxed(bcx, GEPi(bcx, v, [0u, abi::trt_field_box]))
+        }
+        _ if ty::type_is_structural(t)
+          && ty::type_needs_drop(bcx.tcx(), t) => {
+            iter_structural_ty(bcx, v, t, take_ty)
+        }
+        _ => bcx
     }
-    return cx;
 }
 
 pub fn drop_ty<'a>(cx: &'a Block<'a>, v: ValueRef, t: ty::t)
@@ -89,30 +98,15 @@ pub fn drop_ty_immediate<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
 
 pub fn lazily_emit_all_tydesc_glue(ccx: @CrateContext,
                                    static_ti: @tydesc_info) {
-    lazily_emit_tydesc_glue(ccx, abi::tydesc_field_take_glue, static_ti);
     lazily_emit_tydesc_glue(ccx, abi::tydesc_field_drop_glue, static_ti);
     lazily_emit_tydesc_glue(ccx, abi::tydesc_field_visit_glue, static_ti);
 }
 
 fn simplified_glue_type(tcx: ty::ctxt, field: uint, t: ty::t) -> ty::t {
-    if (field == abi::tydesc_field_take_glue || field == abi::tydesc_field_drop_glue)
-        && !ty::type_needs_drop(tcx, t) {
-        return ty::mk_nil();
-    }
-
-    if field == abi::tydesc_field_take_glue {
-        match ty::get(t).sty {
-            ty::ty_str(ty::vstore_uniq) |  ty::ty_vec(_, ty::vstore_uniq) |
-            ty::ty_unboxed_vec(..) | ty::ty_uniq(..) => return ty::mk_nil(),
-            _ => {}
-        }
-    }
-
-    if field == abi::tydesc_field_take_glue && ty::type_is_boxed(t) {
-        return ty::mk_box(tcx, ty::mk_nil());
-    }
-
     if field == abi::tydesc_field_drop_glue {
+        if !ty::type_needs_drop(tcx, t) {
+            return ty::mk_nil();
+        }
         match ty::get(t).sty {
             ty::ty_box(typ)
                 if !ty::type_needs_drop(tcx, typ) =>
@@ -137,7 +131,7 @@ fn simplified_glue_type(tcx: ty::ctxt, field: uint, t: ty::t) -> ty::t {
     t
 }
 
-fn lazily_emit_tydesc_glue(ccx: @CrateContext, field: uint, ti: @tydesc_info) {
+pub fn lazily_emit_tydesc_glue(ccx: @CrateContext, field: uint, ti: @tydesc_info) {
     let _icx = push_ctxt("lazily_emit_tydesc_glue");
 
     let simpl = simplified_glue_type(ccx.tcx, field, ti.ty);
@@ -146,9 +140,7 @@ fn lazily_emit_tydesc_glue(ccx: @CrateContext, field: uint, ti: @tydesc_info) {
         let simpl_ti = get_tydesc(ccx, simpl);
         lazily_emit_tydesc_glue(ccx, field, simpl_ti);
 
-        if field == abi::tydesc_field_take_glue {
-            ti.take_glue.set(simpl_ti.take_glue.get());
-        } else if field == abi::tydesc_field_drop_glue {
+        if field == abi::tydesc_field_drop_glue {
             ti.drop_glue.set(simpl_ti.drop_glue.get());
         } else if field == abi::tydesc_field_visit_glue {
             ti.visit_glue.set(simpl_ti.visit_glue.get());
@@ -159,20 +151,7 @@ fn lazily_emit_tydesc_glue(ccx: @CrateContext, field: uint, ti: @tydesc_info) {
 
     let llfnty = Type::glue_fn(type_of(ccx, ti.ty).ptr_to());
 
-    if field == abi::tydesc_field_take_glue {
-        match ti.take_glue.get() {
-          Some(_) => (),
-          None => {
-            debug!("+++ lazily_emit_tydesc_glue TAKE {}",
-                   ppaux::ty_to_str(ccx.tcx, ti.ty));
-            let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, "take");
-            ti.take_glue.set(Some(glue_fn));
-            make_generic_glue(ccx, ti.ty, glue_fn, make_take_glue, "take");
-            debug!("--- lazily_emit_tydesc_glue TAKE {}",
-                   ppaux::ty_to_str(ccx.tcx, ti.ty));
-          }
-        }
-    } else if field == abi::tydesc_field_drop_glue {
+    if field == abi::tydesc_field_drop_glue {
         match ti.drop_glue.get() {
           Some(_) => (),
           None => {
@@ -202,11 +181,8 @@ fn lazily_emit_tydesc_glue(ccx: @CrateContext, field: uint, ti: @tydesc_info) {
 }
 
 // See [Note-arg-mode]
-pub fn call_tydesc_glue_full(bcx: &Block,
-                             v: ValueRef,
-                             tydesc: ValueRef,
-                             field: uint,
-                             static_ti: Option<@tydesc_info>) {
+pub fn call_tydesc_glue_full(bcx: &Block, v: ValueRef, tydesc: ValueRef,
+                             field: uint, static_ti: Option<@tydesc_info>) {
     let _icx = push_ctxt("call_tydesc_glue_full");
     let ccx = bcx.ccx();
     // NB: Don't short-circuit even if this block is unreachable because
@@ -214,25 +190,23 @@ pub fn call_tydesc_glue_full(bcx: &Block,
     if bcx.unreachable.get() && !ccx.sess.no_landing_pads() { return; }
 
     let static_glue_fn = match static_ti {
-      None => None,
-      Some(sti) => {
-        lazily_emit_tydesc_glue(ccx, field, sti);
-        if field == abi::tydesc_field_take_glue {
-            sti.take_glue.get()
-        } else if field == abi::tydesc_field_drop_glue {
-            sti.drop_glue.get()
-        } else if field == abi::tydesc_field_visit_glue {
-            sti.visit_glue.get()
-        } else {
-            None
+        None => None,
+        Some(sti) => {
+            lazily_emit_tydesc_glue(ccx, field, sti);
+            if field == abi::tydesc_field_drop_glue {
+                sti.drop_glue.get()
+            } else if field == abi::tydesc_field_visit_glue {
+                sti.visit_glue.get()
+            } else {
+                None
+            }
         }
-      }
     };
 
     // When static type info is available, avoid casting parameter unless the
     // glue is using a simplified type, because the function already has the
     // right type. Otherwise cast to generic pointer.
-    let llrawptr = if static_ti.is_none() || static_glue_fn.is_none() {
+    let llrawptr = if static_glue_fn.is_none() {
         PointerCast(bcx, v, Type::i8p())
     } else {
         let ty = static_ti.unwrap().ty;
@@ -246,16 +220,16 @@ pub fn call_tydesc_glue_full(bcx: &Block,
 
     let llfn = {
         match static_glue_fn {
-          None => {
-            // Select out the glue function to call from the tydesc
-            let llfnptr = GEPi(bcx, tydesc, [0u, field]);
-            Load(bcx, llfnptr)
-          }
-          Some(sgf) => sgf
+            None => {
+                // Select out the glue function to call from the tydesc
+                let llfnptr = GEPi(bcx, tydesc, [0u, field]);
+                Load(bcx, llfnptr)
+            }
+            Some(sgf) => sgf
         }
     };
 
-    Call(bcx, llfn, [C_null(Type::nil().ptr_to()), llrawptr], []);
+    Call(bcx, llfn, [llrawptr], []);
 }
 
 // See [Note-arg-mode]
@@ -283,43 +257,7 @@ fn make_visit_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
     bcx
 }
 
-pub fn make_free_glue<'a>(bcx: &'a Block<'a>,
-                          v: ValueRef,
-                          t: ty::t)
-                          -> &'a Block<'a> {
-    // NB: v0 is an *alias* of type t here, not a direct value.
-    let _icx = push_ctxt("make_free_glue");
-    match ty::get(t).sty {
-      ty::ty_box(body_ty) => {
-        let v = Load(bcx, v);
-        let body = GEPi(bcx, v, [0u, abi::box_field_body]);
-        let bcx = drop_ty(bcx, body, body_ty);
-        trans_free(bcx, v)
-      }
-      ty::ty_uniq(content_ty) => {
-        let llbox = Load(bcx, v);
-        let not_null = IsNotNull(bcx, llbox);
-        with_cond(bcx, not_null, |bcx| {
-                    let bcx = drop_ty(bcx, llbox, content_ty);
-                    trans_exchange_free(bcx, llbox)
-                })
-      }
-      ty::ty_vec(_, ty::vstore_uniq) | ty::ty_str(ty::vstore_uniq) |
-      ty::ty_vec(_, ty::vstore_box) | ty::ty_str(ty::vstore_box) => {
-        make_free_glue(bcx, v, tvec::expand_boxed_vec_ty(bcx.tcx(), t))
-      }
-      ty::ty_closure(_) => {
-        closure::make_closure_glue(bcx, v, t, make_free_glue)
-      }
-      ty::ty_opaque_closure_ptr(ck) => {
-        closure::make_opaque_cbox_free_glue(bcx, ck, v)
-      }
-      _ => bcx
-    }
-}
-
-pub fn trans_struct_drop_flag<'a>(
-                              bcx: &'a Block<'a>,
+fn trans_struct_drop_flag<'a>(bcx: &'a Block<'a>,
                               t: ty::t,
                               v0: ValueRef,
                               dtor_did: ast::DefId,
@@ -333,8 +271,7 @@ pub fn trans_struct_drop_flag<'a>(
     })
 }
 
-pub fn trans_struct_drop<'a>(
-                         bcx: &'a Block<'a>,
+fn trans_struct_drop<'a>(bcx: &'a Block<'a>,
                          t: ty::t,
                          v0: ValueRef,
                          dtor_did: ast::DefId,
@@ -380,72 +317,91 @@ pub fn trans_struct_drop<'a>(
     bcx.fcx.pop_and_trans_custom_cleanup_scope(bcx, field_scope)
 }
 
-pub fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t)
-                      -> &'a Block<'a> {
+fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'a> {
     // NB: v0 is an *alias* of type t here, not a direct value.
     let _icx = push_ctxt("make_drop_glue");
     let ccx = bcx.ccx();
     match ty::get(t).sty {
-      ty::ty_box(_) |
-      ty::ty_str(ty::vstore_box) | ty::ty_vec(_, ty::vstore_box) => {
-        decr_refcnt_maybe_free(bcx, v0, Some(t))
-      }
-      ty::ty_uniq(_) |
-      ty::ty_vec(_, ty::vstore_uniq) | ty::ty_str(ty::vstore_uniq) => {
-        make_free_glue(bcx, v0, t)
-      }
-      ty::ty_unboxed_vec(_) => {
-        tvec::make_drop_glue_unboxed(bcx, v0, t)
-      }
-      ty::ty_struct(did, ref substs) => {
-        let tcx = bcx.tcx();
-        match ty::ty_dtor(tcx, did) {
-          ty::TraitDtor(dtor, true) => {
-            trans_struct_drop_flag(bcx, t, v0, dtor, did, substs)
-          }
-          ty::TraitDtor(dtor, false) => {
-            trans_struct_drop(bcx, t, v0, dtor, did, substs)
-          }
-          ty::NoDtor => {
-            // No dtor? Just the default case
-            iter_structural_ty(bcx, v0, t, drop_ty)
-          }
+        ty::ty_box(body_ty) => {
+            decr_refcnt_maybe_free(bcx, v0, Some(body_ty))
+        }
+        ty::ty_str(ty::vstore_box) | ty::ty_vec(_, ty::vstore_box) => {
+            let unit_ty = ty::sequence_element_type(ccx.tcx, t);
+            let unboxed_vec_ty = ty::mk_mut_unboxed_vec(ccx.tcx, unit_ty);
+            decr_refcnt_maybe_free(bcx, v0, Some(unboxed_vec_ty))
+        }
+        ty::ty_uniq(content_ty) => {
+            let llbox = Load(bcx, v0);
+            let not_null = IsNotNull(bcx, llbox);
+            with_cond(bcx, not_null, |bcx| {
+                let bcx = drop_ty(bcx, llbox, content_ty);
+                trans_exchange_free(bcx, llbox)
+            })
+        }
+        ty::ty_vec(_, ty::vstore_uniq) | ty::ty_str(ty::vstore_uniq) => {
+            make_drop_glue(bcx, v0, tvec::expand_boxed_vec_ty(bcx.tcx(), t))
+        }
+        ty::ty_unboxed_vec(_) => {
+            tvec::make_drop_glue_unboxed(bcx, v0, t)
+        }
+        ty::ty_struct(did, ref substs) => {
+            let tcx = bcx.tcx();
+            match ty::ty_dtor(tcx, did) {
+                ty::TraitDtor(dtor, true) => {
+                    trans_struct_drop_flag(bcx, t, v0, dtor, did, substs)
+                }
+                ty::TraitDtor(dtor, false) => {
+                    trans_struct_drop(bcx, t, v0, dtor, did, substs)
+                }
+                ty::NoDtor => {
+                    // No dtor? Just the default case
+                    iter_structural_ty(bcx, v0, t, drop_ty)
+                }
+            }
+        }
+        ty::ty_trait(_, _, ty::BoxTraitStore, _, _) => {
+            let llbox_ptr = GEPi(bcx, v0, [0u, abi::trt_field_box]);
+            decr_refcnt_maybe_free(bcx, llbox_ptr, None)
+        }
+        ty::ty_trait(_, _, ty::UniqTraitStore, _, _) => {
+            let lluniquevalue = GEPi(bcx, v0, [0, abi::trt_field_box]);
+            // Only drop the value when it is non-null
+            with_cond(bcx, IsNotNull(bcx, Load(bcx, lluniquevalue)), |bcx| {
+                let lldtor_ptr = Load(bcx, GEPi(bcx, v0, [0, abi::trt_field_vtable]));
+                let lldtor = Load(bcx, lldtor_ptr);
+                Call(bcx, lldtor, [PointerCast(bcx, lluniquevalue, Type::i8p())], []);
+                bcx
+            })
+        }
+        ty::ty_closure(ref f) if f.sigil == ast::OwnedSigil => {
+            let box_cell_v = GEPi(bcx, v0, [0u, abi::fn_field_box]);
+            let env = Load(bcx, box_cell_v);
+            let env_ptr_ty = Type::at_box(ccx, Type::i8()).ptr_to();
+            let env = PointerCast(bcx, env, env_ptr_ty);
+            with_cond(bcx, IsNotNull(bcx, env), |bcx| {
+                // Load the type descr found in the env
+                let lltydescty = ccx.tydesc_type.ptr_to();
+                let tydescptr = GEPi(bcx, env, [0u, abi::box_field_tydesc]);
+                let tydesc = Load(bcx, tydescptr);
+                let tydesc = PointerCast(bcx, tydesc, lltydescty);
+
+                // Drop the tuple data then free the descriptor
+                let cdata = GEPi(bcx, env, [0u, abi::box_field_body]);
+                call_tydesc_glue_full(bcx, cdata, tydesc,
+                                      abi::tydesc_field_drop_glue, None);
+
+                // Free the ty descr (if necc) and the env itself
+                trans_exchange_free(bcx, env)
+            })
+        }
+        _ => {
+            if ty::type_needs_drop(ccx.tcx, t) &&
+                ty::type_is_structural(t) {
+                iter_structural_ty(bcx, v0, t, drop_ty)
+            } else {
+                bcx
+            }
         }
-      }
-      ty::ty_closure(_) => {
-        closure::make_closure_glue(bcx, v0, t, drop_ty)
-      }
-      ty::ty_trait(_, _, ty::BoxTraitStore, _, _) => {
-          let llbox_ptr = GEPi(bcx, v0, [0u, abi::trt_field_box]);
-          decr_refcnt_maybe_free(bcx, llbox_ptr, None)
-      }
-      ty::ty_trait(_, _, ty::UniqTraitStore, _, _) => {
-          let lluniquevalue = GEPi(bcx, v0, [0, abi::trt_field_box]);
-          // Only drop the value when it is non-null
-          with_cond(bcx, IsNotNull(bcx, Load(bcx, lluniquevalue)), |bcx| {
-              let llvtable = Load(bcx, GEPi(bcx, v0, [0, abi::trt_field_vtable]));
-
-              // Cast the vtable to a pointer to a pointer to a tydesc.
-              let llvtable = PointerCast(bcx, llvtable,
-                                         ccx.tydesc_type.ptr_to().ptr_to());
-              let lltydesc = Load(bcx, llvtable);
-              call_tydesc_glue_full(bcx,
-                                    lluniquevalue,
-                                    lltydesc,
-                                    abi::tydesc_field_drop_glue,
-                                    None);
-              bcx
-          })
-      }
-      ty::ty_opaque_closure_ptr(ck) => {
-        closure::make_opaque_cbox_drop_glue(bcx, ck, v0)
-      }
-      _ => {
-        if ty::type_needs_drop(ccx.tcx, t) &&
-            ty::type_is_structural(t) {
-            iter_structural_ty(bcx, v0, t, drop_ty)
-        } else { bcx }
-      }
     }
 }
 
@@ -468,71 +424,34 @@ fn decr_refcnt_maybe_free<'a>(bcx: &'a Block<'a>, box_ptr_ptr: ValueRef,
     Store(decr_bcx, rc, rc_ptr);
     CondBr(decr_bcx, IsNull(decr_bcx, rc), free_bcx.llbb, next_bcx.llbb);
 
+    let v = Load(free_bcx, box_ptr_ptr);
+    let body = GEPi(free_bcx, v, [0u, abi::box_field_body]);
     let free_bcx = match t {
-        Some(t) => make_free_glue(free_bcx, box_ptr_ptr, t),
+        Some(t) => drop_ty(free_bcx, body, t),
         None => {
-            let v = Load(free_bcx, box_ptr_ptr);
-            let td = Load(free_bcx, GEPi(free_bcx, v, [0u, abi::box_field_tydesc]));
-            let valptr = GEPi(free_bcx, v, [0u, abi::box_field_body]);
             // Generate code that, dynamically, indexes into the
             // tydesc and calls the drop glue that got set dynamically
-            call_tydesc_glue_full(free_bcx, valptr, td, abi::tydesc_field_drop_glue, None);
-            trans_free(free_bcx, v)
+            let td = Load(free_bcx, GEPi(free_bcx, v, [0u, abi::box_field_tydesc]));
+            call_tydesc_glue_full(free_bcx, body, td, abi::tydesc_field_drop_glue, None);
+            free_bcx
         }
     };
+    let free_bcx = trans_free(free_bcx, v);
     Br(free_bcx, next_bcx.llbb);
 
     next_bcx
 }
 
-fn make_take_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t) -> &'a Block<'a> {
-    let _icx = push_ctxt("make_take_glue");
-    // NB: v is a *pointer* to type t here, not a direct value.
-    match ty::get(t).sty {
-      ty::ty_box(_) |
-      ty::ty_vec(_, ty::vstore_box) | ty::ty_str(ty::vstore_box) => {
-        incr_refcnt_of_boxed(bcx, Load(bcx, v)); bcx
-      }
-      ty::ty_vec(_, ty::vstore_slice(_))
-      | ty::ty_str(ty::vstore_slice(_)) => {
-        bcx
-      }
-      ty::ty_closure(_) => bcx,
-      ty::ty_trait(_, _, ty::BoxTraitStore, _, _) => {
-        let llbox = Load(bcx, GEPi(bcx, v, [0u, abi::trt_field_box]));
-        incr_refcnt_of_boxed(bcx, llbox);
-        bcx
-      }
-      ty::ty_trait(_, _, ty::UniqTraitStore, _, _) => {
-          let lluniquevalue = GEPi(bcx, v, [0, abi::trt_field_box]);
-          let llvtable = Load(bcx, GEPi(bcx, v, [0, abi::trt_field_vtable]));
-
-          // Cast the vtable to a pointer to a pointer to a tydesc.
-          let llvtable = PointerCast(bcx, llvtable,
-                                     bcx.ccx().tydesc_type.ptr_to().ptr_to());
-          let lltydesc = Load(bcx, llvtable);
-          call_tydesc_glue_full(bcx,
-                                lluniquevalue,
-                                lltydesc,
-                                abi::tydesc_field_take_glue,
-                                None);
-          bcx
-      }
-      ty::ty_opaque_closure_ptr(_) => bcx,
-      _ if ty::type_is_structural(t) => {
-        iter_structural_ty(bcx, v, t, take_ty)
-      }
-      _ => bcx
-    }
-}
-
-fn incr_refcnt_of_boxed(cx: &Block, box_ptr: ValueRef) {
+fn incr_refcnt_of_boxed<'a>(bcx: &'a Block<'a>,
+                            box_ptr_ptr: ValueRef) -> &'a Block<'a> {
     let _icx = push_ctxt("incr_refcnt_of_boxed");
-    let ccx = cx.ccx();
-    let rc_ptr = GEPi(cx, box_ptr, [0u, abi::box_field_refcnt]);
-    let rc = Load(cx, rc_ptr);
-    let rc = Add(cx, rc, C_int(ccx, 1));
-    Store(cx, rc, rc_ptr);
+    let ccx = bcx.ccx();
+    let box_ptr = Load(bcx, box_ptr_ptr);
+    let rc_ptr = GEPi(bcx, box_ptr, [0u, abi::box_field_refcnt]);
+    let rc = Load(bcx, rc_ptr);
+    let rc = Add(bcx, rc, C_int(ccx, 1));
+    Store(bcx, rc, rc_ptr);
+    bcx
 }
 
 
@@ -568,7 +487,6 @@ pub fn declare_tydesc(ccx: &CrateContext, t: ty::t) -> @tydesc_info {
         size: llsize,
         align: llalign,
         name: ty_name,
-        take_glue: Cell::new(None),
         drop_glue: Cell::new(None),
         visit_glue: Cell::new(None),
     };
@@ -595,7 +513,7 @@ fn make_generic_glue(ccx: @CrateContext, t: ty::t, llfn: ValueRef,
     let glue_name = format!("glue {} {}", name, ty_to_short_str(ccx.tcx, t));
     let _s = StatRecorder::new(ccx, glue_name);
 
-    let fcx = new_fn_ctxt(ccx, ~[], llfn, ty::mk_nil(), None);
+    let fcx = new_fn_ctxt(ccx, ~[], llfn, false, ty::mk_nil(), None);
     init_function(&fcx, false, ty::mk_nil(), None);
 
     lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
@@ -630,21 +548,6 @@ pub fn emit_tydescs(ccx: &CrateContext) {
         // before being put into the tydesc because we only have a singleton
         // tydesc type. Then we'll recast each function to its real type when
         // calling it.
-        let take_glue =
-            match ti.take_glue.get() {
-              None => {
-                  ccx.stats.n_null_glues.set(ccx.stats.n_null_glues.get() +
-                                             1);
-                  C_null(glue_fn_ty)
-              }
-              Some(v) => {
-                unsafe {
-                    ccx.stats.n_real_glues.set(ccx.stats.n_real_glues.get() +
-                                               1);
-                    llvm::LLVMConstPointerCast(v, glue_fn_ty.to_ref())
-                }
-              }
-            };
         let drop_glue =
             match ti.drop_glue.get() {
               None => {
@@ -679,7 +582,6 @@ pub fn emit_tydescs(ccx: &CrateContext) {
         let tydesc = C_named_struct(ccx.tydesc_type,
                                     [ti.size, // size
                                      ti.align, // align
-                                     take_glue, // take_glue
                                      drop_glue, // drop_glue
                                      visit_glue, // visit_glue
                                      ti.name]); // name
index 98e3593a9f15f6f01d984a99010f9771b3f040ff..3a0b97813df50b19b135f925fe24a7fc690cdbbd 100644 (file)
@@ -14,7 +14,6 @@
 use middle::trans::base::{push_ctxt, trans_item, get_item_val, trans_fn};
 use middle::trans::common::*;
 use middle::ty;
-use util::ppaux::ty_to_str;
 
 use std::vec;
 use syntax::ast;
@@ -160,25 +159,7 @@ pub fn maybe_instantiate_inline(ccx: @CrateContext, fn_id: ast::DefId)
               let llfn = get_item_val(ccx, mth.id);
               let path = vec::append_one(
                   ty::item_path(ccx.tcx, impl_did), PathName(mth.ident));
-              let self_kind = match mth.explicit_self.node {
-                  ast::SelfStatic => None,
-                  _ => {
-                      let self_ty = ty::node_id_to_type(ccx.tcx,
-                                                        mth.self_id);
-                      debug!("calling inline trans_fn with self_ty {}",
-                             ty_to_str(ccx.tcx, self_ty));
-                      Some(self_ty)
-                  }
-              };
-              trans_fn(ccx,
-                       path,
-                       mth.decl,
-                       mth.body,
-                       llfn,
-                       self_kind,
-                       None,
-                       mth.id,
-                       []);
+              trans_fn(ccx, path, mth.decl, mth.body, llfn, None, mth.id, []);
           }
           local_def(mth.id)
         }
index 675052856304dc73c8b1bba3ef43d38e50118add..25c4ff04ce57907151f2004d89985862739499a9 100644 (file)
@@ -153,13 +153,8 @@ fn count_zeros_intrinsic(bcx: &Block, name: &'static str) {
 
     let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, item.id));
 
-    let fcx = new_fn_ctxt_detailed(ccx,
-                                   path,
-                                   decl,
-                                   item.id,
-                                   output_type,
-                                   Some(substs),
-                                   Some(item.span));
+    let fcx = new_fn_ctxt_detailed(ccx, path, decl, item.id, false, output_type,
+                                   Some(substs), Some(item.span));
     init_function(&fcx, true, output_type, Some(substs));
 
     set_always_inline(fcx.llfn);
@@ -252,7 +247,7 @@ fn count_zeros_intrinsic(bcx: &Block, name: &'static str) {
         "size_of" => {
             let tp_ty = substs.tys[0];
             let lltp_ty = type_of::type_of(ccx, tp_ty);
-            Ret(bcx, C_uint(ccx, machine::llsize_of_real(ccx, lltp_ty)));
+            Ret(bcx, C_uint(ccx, machine::llsize_of_real(ccx, lltp_ty) as uint));
         }
         "move_val_init" => {
             // Create a datum reflecting the value being moved.
@@ -271,12 +266,12 @@ fn count_zeros_intrinsic(bcx: &Block, name: &'static str) {
         "min_align_of" => {
             let tp_ty = substs.tys[0];
             let lltp_ty = type_of::type_of(ccx, tp_ty);
-            Ret(bcx, C_uint(ccx, machine::llalign_of_min(ccx, lltp_ty)));
+            Ret(bcx, C_uint(ccx, machine::llalign_of_min(ccx, lltp_ty) as uint));
         }
         "pref_align_of"=> {
             let tp_ty = substs.tys[0];
             let lltp_ty = type_of::type_of(ccx, tp_ty);
-            Ret(bcx, C_uint(ccx, machine::llalign_of_pref(ccx, lltp_ty)));
+            Ret(bcx, C_uint(ccx, machine::llalign_of_pref(ccx, lltp_ty) as uint));
         }
         "get_tydesc" => {
             let tp_ty = substs.tys[0];
@@ -342,7 +337,7 @@ fn count_zeros_intrinsic(bcx: &Block, name: &'static str) {
                         _ => fail!("transmute has non-expr arg"),
                     }
                 };
-                let pluralize = |n| if 1u == n { "" } else { "s" };
+                let pluralize = |n| if 1 == n { "" } else { "s" };
                 ccx.sess.span_fatal(sp,
                                     format!("transmute called on types with \
                                           different sizes: {} ({} bit{}) to \
@@ -417,10 +412,10 @@ fn count_zeros_intrinsic(bcx: &Block, name: &'static str) {
             RetVoid(bcx);
         }
         "morestack_addr" => {
-            // XXX This is a hack to grab the address of this particular
+            // FIXME This is a hack to grab the address of this particular
             // native function. There should be a general in-language
             // way to do this
-            let llfty = type_of_rust_fn(bcx.ccx(), None, [], ty::mk_nil());
+            let llfty = type_of_rust_fn(bcx.ccx(), false, [], ty::mk_nil());
             let morestack_addr = decl_cdecl_fn(bcx.ccx().llmod, "__morestack",
                                                llfty, ty::mk_nil());
             let morestack_addr = PointerCast(bcx, morestack_addr,
index 0bf0a522a655f3c39b81392466e14292848aa4f6..7a7e3a9b759132fa18c0097c2e45fd5fa41dda96 100644 (file)
 // compute sizeof / alignof
 
 // Returns the number of bytes clobbered by a Store to this type.
-pub fn llsize_of_store(cx: &CrateContext, ty: Type) -> uint {
+pub fn llsize_of_store(cx: &CrateContext, ty: Type) -> u64 {
     unsafe {
-        return llvm::LLVMStoreSizeOfType(cx.td.lltd, ty.to_ref()) as uint;
+        return llvm::LLVMStoreSizeOfType(cx.td.lltd, ty.to_ref()) as u64;
     }
 }
 
 // Returns the number of bytes between successive elements of type T in an
 // array of T. This is the "ABI" size. It includes any ABI-mandated padding.
-pub fn llsize_of_alloc(cx: &CrateContext, ty: Type) -> uint {
+pub fn llsize_of_alloc(cx: &CrateContext, ty: Type) -> u64 {
     unsafe {
-        return llvm::LLVMABISizeOfType(cx.td.lltd, ty.to_ref()) as uint;
+        return llvm::LLVMABISizeOfType(cx.td.lltd, ty.to_ref()) as u64;
     }
 }
 
@@ -43,12 +43,12 @@ pub fn llsize_of_alloc(cx: &CrateContext, ty: Type) -> uint {
 // that LLVM *does* distinguish between e.g. a 1-bit value and an 8-bit value
 // at the codegen level! In general you should prefer `llbitsize_of_real`
 // below.
-pub fn llsize_of_real(cx: &CrateContext, ty: Type) -> uint {
+pub fn llsize_of_real(cx: &CrateContext, ty: Type) -> u64 {
     unsafe {
-        let nbits = llvm::LLVMSizeOfTypeInBits(cx.td.lltd, ty.to_ref()) as uint;
-        if nbits & 7u != 0u {
+        let nbits = llvm::LLVMSizeOfTypeInBits(cx.td.lltd, ty.to_ref()) as u64;
+        if nbits & 7 != 0 {
             // Not an even number of bytes, spills into "next" byte.
-            1u + (nbits >> 3)
+            1 + (nbits >> 3)
         } else {
             nbits >> 3
         }
@@ -56,9 +56,9 @@ pub fn llsize_of_real(cx: &CrateContext, ty: Type) -> uint {
 }
 
 /// Returns the "real" size of the type in bits.
-pub fn llbitsize_of_real(cx: &CrateContext, ty: Type) -> uint {
+pub fn llbitsize_of_real(cx: &CrateContext, ty: Type) -> u64 {
     unsafe {
-        llvm::LLVMSizeOfTypeInBits(cx.td.lltd, ty.to_ref()) as uint
+        llvm::LLVMSizeOfTypeInBits(cx.td.lltd, ty.to_ref()) as u64
     }
 }
 
@@ -71,7 +71,7 @@ pub fn llsize_of(cx: &CrateContext, ty: Type) -> ValueRef {
     // there's no need for that contrivance.  The instruction
     // selection DAG generator would flatten that GEP(1) node into a
     // constant of the type's alloc size, so let's save it some work.
-    return C_uint(cx, llsize_of_alloc(cx, ty));
+    return C_uint(cx, llsize_of_alloc(cx, ty) as uint);
 }
 
 // Returns the "default" size of t (see above), or 1 if the size would
@@ -89,18 +89,18 @@ pub fn nonzero_llsize_of(cx: &CrateContext, ty: Type) -> ValueRef {
 // The preferred alignment may be larger than the alignment used when
 // packing the type into structs. This will be used for things like
 // allocations inside a stack frame, which LLVM has a free hand in.
-pub fn llalign_of_pref(cx: &CrateContext, ty: Type) -> uint {
+pub fn llalign_of_pref(cx: &CrateContext, ty: Type) -> u64 {
     unsafe {
-        return llvm::LLVMPreferredAlignmentOfType(cx.td.lltd, ty.to_ref()) as uint;
+        return llvm::LLVMPreferredAlignmentOfType(cx.td.lltd, ty.to_ref()) as u64;
     }
 }
 
 // Returns the minimum alignment of a type required by the platform.
 // This is the alignment that will be used for struct fields, arrays,
 // and similar ABI-mandated things.
-pub fn llalign_of_min(cx: &CrateContext, ty: Type) -> uint {
+pub fn llalign_of_min(cx: &CrateContext, ty: Type) -> u64 {
     unsafe {
-        return llvm::LLVMABIAlignmentOfType(cx.td.lltd, ty.to_ref()) as uint;
+        return llvm::LLVMABIAlignmentOfType(cx.td.lltd, ty.to_ref()) as u64;
     }
 }
 
@@ -114,8 +114,8 @@ pub fn llalign_of(cx: &CrateContext, ty: Type) -> ValueRef {
     }
 }
 
-pub fn llelement_offset(cx: &CrateContext, struct_ty: Type, element: uint) -> uint {
+pub fn llelement_offset(cx: &CrateContext, struct_ty: Type, element: uint) -> u64 {
     unsafe {
-        return llvm::LLVMOffsetOfElement(cx.td.lltd, struct_ty.to_ref(), element as u32) as uint;
+        return llvm::LLVMOffsetOfElement(cx.td.lltd, struct_ty.to_ref(), element as u32) as u64;
     }
 }
index 3badfc38df6c767655c085355b5f9ba6c95f6749..09bfa36ddc172445e3003ad3c3cec425b8ff35a5 100644 (file)
@@ -51,7 +51,7 @@ pub fn trans_impl(ccx: @CrateContext,
                   methods: &[@ast::Method],
                   generics: &ast::Generics,
                   id: ast::NodeId) {
-    let _icx = push_ctxt("impl::trans_impl");
+    let _icx = push_ctxt("meth::trans_impl");
     let tcx = ccx.tcx;
 
     debug!("trans_impl(path={}, name={}, id={:?})",
@@ -73,11 +73,8 @@ pub fn trans_impl(ccx: @CrateContext,
             let path = vec::append_one(sub_path.clone(),
                                        PathName(method.ident));
 
-            trans_method(ccx,
-                         path,
-                         *method,
-                         None,
-                         |_| llfn);
+            trans_fn(ccx, path, method.decl, method.body,
+                     llfn, None, method.id, []);
         } else {
             let mut v = TransItemVisitor{ ccx: ccx };
             visit::walk_method_helper(&mut v, *method, ());
@@ -91,49 +88,15 @@ pub fn trans_impl(ccx: @CrateContext,
 /// * `path`: the path to the method
 /// * `method`: the AST node for the method
 /// * `param_substs`: if this is a generic method, the current values for
-///   type parameters and so forth, else none
-/// * `llfn`: a closure returning the LLVM ValueRef for the method
-/// * `impl_id`: the node ID of the impl this method is inside
+///   type parameters and so forth, else None
+/// * `llfn`: the LLVM ValueRef for the method
 ///
-/// XXX(pcwalton) Can we take `path` by reference?
-pub fn trans_method(ccx: @CrateContext,
-                    path: Path,
-                    method: &ast::Method,
+/// FIXME(pcwalton) Can we take `path` by reference?
+pub fn trans_method(ccx: @CrateContext, path: Path, method: &ast::Method,
                     param_substs: Option<@param_substs>,
-                    llfn_with_self: |Option<ty::t>| -> ValueRef) -> ValueRef {
-    // figure out how self is being passed
-    let self_ty = match method.explicit_self.node {
-      ast::SelfStatic => None,
-      _ => {
-        // determine the (monomorphized) type that `self` maps to for
-        // this method
-        let self_ty = ty::node_id_to_type(ccx.tcx, method.self_id);
-        let self_ty = match param_substs {
-            None => self_ty,
-            Some(param_substs) => {
-                ty::subst_tps(ccx.tcx,
-                              param_substs.tys,
-                              param_substs.self_ty,
-                              self_ty)
-            }
-        };
-        debug!("calling trans_fn with self_ty {}", self_ty.repr(ccx.tcx));
-        Some(self_ty)
-      }
-    };
-
-    let llfn = llfn_with_self(self_ty);
-
-    // generate the actual code
-    trans_fn(ccx,
-             path,
-             method.decl,
-             method.body,
-             llfn,
-             self_ty,
-             param_substs,
-             method.id,
-             []);
+                    llfn: ValueRef) -> ValueRef {
+    trans_fn(ccx, path, method.decl, method.body,
+             llfn, param_substs, method.id, []);
     llfn
 }
 
@@ -144,31 +107,17 @@ pub fn trans_method_callee<'a>(
                            mentry: typeck::method_map_entry,
                            arg_cleanup_scope: cleanup::ScopeId)
                            -> Callee<'a> {
-    let _icx = push_ctxt("impl::trans_method_callee");
+    let _icx = push_ctxt("meth::trans_method_callee");
 
-    debug!("trans_method_callee(callee_id={:?}, this={}, mentry={})",
+    debug!("trans_method_callee(callee_id={:?}, mentry={})",
            callee_id,
-           bcx.expr_to_str(this),
            mentry.repr(bcx.tcx()));
 
     match mentry.origin {
         typeck::method_static(did) => {
-            let self_ty = monomorphize_type(bcx, mentry.self_ty);
-            let Result {bcx, val} = trans_arg_expr(bcx, self_ty, this,
-                                                   arg_cleanup_scope,
-                                                   DontAutorefArg);
-            // HACK should not need the pointer cast, eventually trans_fn_ref
-            // should return a function type with the right type for self.
-            let callee_fn = callee::trans_fn_ref(bcx, did, callee_id);
-            let fn_ty = node_id_type(bcx, callee_id);
-            let llfn_ty = type_of_fn_from_ty(bcx.ccx(), Some(self_ty), fn_ty).ptr_to();
-            let llfn_val = PointerCast(bcx, callee_fn.llfn, llfn_ty);
             Callee {
                 bcx: bcx,
-                data: Method(MethodData {
-                    llfn: llfn_val,
-                    llself: val,
-                })
+                data: Fn(callee::trans_fn_ref(bcx, did, callee_id))
             }
         }
         typeck::method_param(typeck::method_param {
@@ -184,9 +133,8 @@ pub fn trans_method_callee<'a>(
                         trait_id);
 
                     let vtbl = find_vtable(bcx.tcx(), substs, p, b);
-                    trans_monomorphized_callee(bcx, callee_id, this, mentry,
-                                               trait_id, off, vtbl,
-                                               arg_cleanup_scope)
+                    trans_monomorphized_callee(bcx, callee_id,
+                                               trait_id, off, vtbl)
                 }
                 // how to get rid of this?
                 None => fail!("trans_method_callee: missing param_substs")
@@ -207,8 +155,8 @@ pub fn trans_static_method_callee(bcx: &Block,
                                   method_id: ast::DefId,
                                   trait_id: ast::DefId,
                                   callee_id: ast::NodeId)
-                                  -> FnData {
-    let _icx = push_ctxt("impl::trans_static_method_callee");
+                                  -> ValueRef {
+    let _icx = push_ctxt("meth::trans_static_method_callee");
     let ccx = bcx.ccx();
 
     debug!("trans_static_method_callee(method_id={:?}, trait_id={}, \
@@ -271,16 +219,13 @@ pub fn trans_static_method_callee(bcx: &Block,
                     bcx, mth_id, callee_id,
                     *rcvr_substs, rcvr_origins);
 
-            let FnData {llfn: lval} =
-                trans_fn_ref_with_vtables(bcx,
-                                          mth_id,
-                                          callee_id,
-                                          callee_substs,
-                                          Some(callee_origins));
+            let llfn = trans_fn_ref_with_vtables(bcx, mth_id, callee_id,
+                                                 callee_substs,
+                                                 Some(callee_origins));
 
             let callee_ty = node_id_type(bcx, callee_id);
-            let llty = type_of_fn_from_ty(ccx, None, callee_ty).ptr_to();
-            FnData {llfn: PointerCast(bcx, lval, llty)}
+            let llty = type_of_fn_from_ty(ccx, callee_ty).ptr_to();
+            PointerCast(bcx, llfn, llty)
         }
         _ => {
             fail!("vtable_param left in monomorphized \
@@ -312,29 +257,19 @@ pub fn method_with_name(ccx: &CrateContext,
     meth.def_id
 }
 
-pub fn trans_monomorphized_callee<'a>(
-                                  bcx: &'a Block<'a>,
+fn trans_monomorphized_callee<'a>(bcx: &'a Block<'a>,
                                   callee_id: ast::NodeId,
-                                  base: &ast::Expr,
-                                  mentry: typeck::method_map_entry,
                                   trait_id: ast::DefId,
                                   n_method: uint,
-                                  vtbl: typeck::vtable_origin,
-                                  arg_cleanup_scope: cleanup::ScopeId)
+                                  vtbl: typeck::vtable_origin)
                                   -> Callee<'a> {
-    let _icx = push_ctxt("impl::trans_monomorphized_callee");
+    let _icx = push_ctxt("meth::trans_monomorphized_callee");
     return match vtbl {
       typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => {
           let ccx = bcx.ccx();
           let mname = ty::trait_method(ccx.tcx, trait_id, n_method).ident;
           let mth_id = method_with_name(bcx.ccx(), impl_did, mname.name);
 
-          // obtain the `self` value:
-          let self_ty = monomorphize_type(bcx, mentry.self_ty);
-          let Result {bcx, val} = trans_arg_expr(bcx, self_ty, base,
-                                                 arg_cleanup_scope,
-                                                 DontAutorefArg);
-
           // create a concatenated set of substitutions which includes
           // those from the impl and those from the method:
           let (callee_substs, callee_origins) =
@@ -343,26 +278,13 @@ pub fn trans_monomorphized_callee<'a>(
                   *rcvr_substs, rcvr_origins);
 
           // translate the function
-          let callee = trans_fn_ref_with_vtables(bcx,
-                                                 mth_id,
-                                                 callee_id,
-                                                 callee_substs,
-                                                 Some(callee_origins));
+          let llfn = trans_fn_ref_with_vtables(bcx,
+                                               mth_id,
+                                               callee_id,
+                                               callee_substs,
+                                               Some(callee_origins));
 
-          // create a llvalue that represents the fn ptr
-          // HACK should not need the pointer cast (add self in trans_fn_ref_with_vtables).
-          let fn_ty = node_id_type(bcx, callee_id);
-          let llfn_ty = type_of_fn_from_ty(ccx, Some(self_ty), fn_ty).ptr_to();
-          let llfn_val = PointerCast(bcx, callee.llfn, llfn_ty);
-
-          // combine the self environment with the rest
-          Callee {
-              bcx: bcx,
-              data: Method(MethodData {
-                  llfn: llfn_val,
-                  llself: val,
-              })
-          }
+          Callee { bcx: bcx, data: Fn(llfn) }
       }
       typeck::vtable_param(..) => {
           fail!("vtable_param left in monomorphized function's vtable substs");
@@ -420,8 +342,7 @@ pub fn combine_impl_and_methods_tps(bcx: &Block,
     return (ty_substs, vtables);
 }
 
-pub fn trans_trait_callee<'a>(
-                          bcx: &'a Block<'a>,
+fn trans_trait_callee<'a>(bcx: &'a Block<'a>,
                           callee_id: ast::NodeId,
                           n_method: uint,
                           self_expr: &ast::Expr,
@@ -436,7 +357,7 @@ pub fn trans_trait_callee<'a>(
      * pair.
      */
 
-    let _icx = push_ctxt("impl::trans_trait_callee");
+    let _icx = push_ctxt("meth::trans_trait_callee");
     let mut bcx = bcx;
 
     // Translate self_datum and take ownership of the value by
@@ -469,18 +390,26 @@ pub fn trans_trait_callee_from_llval<'a>(bcx: &'a Block<'a>,
      * a by-ref pointer to the object pair.
      */
 
-    let _icx = push_ctxt("impl::trans_trait_callee");
+    let _icx = push_ctxt("meth::trans_trait_callee");
     let ccx = bcx.ccx();
 
     // Load the data pointer from the object.
     debug!("(translating trait callee) loading second index from pair");
     let llboxptr = GEPi(bcx, llpair, [0u, abi::trt_field_box]);
     let llbox = Load(bcx, llboxptr);
-    let llself = PointerCast(bcx, llbox, Type::opaque_box(ccx).ptr_to());
+    let llself = PointerCast(bcx, llbox, Type::i8p());
 
     // Load the function from the vtable and cast it to the expected type.
     debug!("(translating trait callee) loading method");
-    let llcallee_ty = type_of_fn_from_ty(ccx, None, callee_ty);
+    // Replace the self type (&Self or ~Self) with an opaque pointer.
+    let llcallee_ty = match ty::get(callee_ty).sty {
+        ty::ty_bare_fn(ref f) if f.abis.is_rust() => {
+            type_of_rust_fn(ccx, true, f.sig.inputs.slice_from(1), f.sig.output)
+        }
+        _ => {
+            ccx.sess.bug("meth::trans_trait_callee given non-bare-rust-fn");
+        }
+    };
     let llvtable = Load(bcx,
                         PointerCast(bcx,
                                     GEPi(bcx, llpair,
@@ -491,7 +420,7 @@ pub fn trans_trait_callee_from_llval<'a>(bcx: &'a Block<'a>,
 
     return Callee {
         bcx: bcx,
-        data: Method(MethodData {
+        data: TraitMethod(MethodData {
             llfn: mptr,
             llself: llself,
         })
@@ -528,7 +457,7 @@ pub fn get_vtable(bcx: &Block,
                   origins: typeck::vtable_param_res)
                   -> ValueRef {
     let ccx = bcx.ccx();
-    let _icx = push_ctxt("impl::get_vtable");
+    let _icx = push_ctxt("meth::get_vtable");
 
     // Check the cache.
     let hash_id = (self_ty, vtable_id(ccx, &origins[0]));
@@ -552,7 +481,7 @@ pub fn get_vtable(bcx: &Block,
 
     // Generate a type descriptor for the vtable.
     let tydesc = get_tydesc(ccx, self_ty);
-    glue::lazily_emit_all_tydesc_glue(ccx, tydesc);
+    glue::lazily_emit_tydesc_glue(ccx, abi::tydesc_field_drop_glue, tydesc);
 
     let vtable = make_vtable(ccx, tydesc, methods);
 
@@ -567,9 +496,9 @@ pub fn make_vtable(ccx: &CrateContext,
                    ptrs: &[ValueRef])
                    -> ValueRef {
     unsafe {
-        let _icx = push_ctxt("impl::make_vtable");
+        let _icx = push_ctxt("meth::make_vtable");
 
-        let mut components = ~[ tydesc.tydesc ];
+        let mut components = ~[tydesc.drop_glue.get().unwrap()];
         for &ptr in ptrs.iter() {
             components.push(ptr)
         }
@@ -618,8 +547,7 @@ fn emit_vtable_methods(bcx: &Block,
                    tcx.sess.str_of(ident));
             C_null(Type::nil().ptr_to())
         } else {
-            trans_fn_ref_with_vtables(bcx, m_id, 0,
-                                      substs, Some(vtables)).llfn
+            trans_fn_ref_with_vtables(bcx, m_id, 0, substs, Some(vtables))
         }
     })
 }
@@ -637,7 +565,7 @@ pub fn trans_trait_cast<'a>(bcx: &'a Block<'a>,
      */
 
     let mut bcx = bcx;
-    let _icx = push_ctxt("impl::trans_cast");
+    let _icx = push_ctxt("meth::trans_cast");
 
     let lldest = match dest {
         Ignore => {
index 5e3e323639422c5cc3c0bc45008183a39a17faab..678d23c0e1931348f04b372fc424be25efb9f60f 100644 (file)
@@ -213,8 +213,10 @@ pub fn monomorphic_fn(ccx: @CrateContext,
     let s = mangle_exported_name(ccx, pt.clone(), mono_ty);
     debug!("monomorphize_fn mangled to {}", s);
 
-    let mk_lldecl = |self_ty| {
-        let lldecl = decl_internal_rust_fn(ccx, self_ty, f.sig.inputs, f.sig.output, s);
+    let mk_lldecl = || {
+        let lldecl = decl_internal_rust_fn(ccx, false,
+                                           f.sig.inputs,
+                                           f.sig.output, s);
         let mut monomorphized = ccx.monomorphized.borrow_mut();
         monomorphized.get().insert(hash_id, lldecl);
         lldecl
@@ -227,17 +229,9 @@ pub fn monomorphic_fn(ccx: @CrateContext,
                 node: ast::ItemFn(decl, _, _, _, body),
                 ..
             } => {
-                let d = mk_lldecl(None);
+                let d = mk_lldecl();
                 set_llvm_fn_attrs(i.attrs, d);
-                trans_fn(ccx,
-                         pt,
-                         decl,
-                         body,
-                         d,
-                         None,
-                         Some(psubsts),
-                         fn_id.node,
-                         []);
+                trans_fn(ccx, pt, decl, body, d, Some(psubsts), fn_id.node, []);
                 d
             }
             _ => {
@@ -246,7 +240,7 @@ pub fn monomorphic_fn(ccx: @CrateContext,
           }
       }
       ast_map::NodeForeignItem(i, _, _, _) => {
-          let d = mk_lldecl(None);
+          let d = mk_lldecl();
           intrinsic::trans_intrinsic(ccx, d, i, pt, psubsts, i.attrs,
                                      ref_id);
           d
@@ -254,7 +248,7 @@ pub fn monomorphic_fn(ccx: @CrateContext,
       ast_map::NodeVariant(v, enum_item, _) => {
         let tvs = ty::enum_variants(ccx.tcx, local_def(enum_item.id));
         let this_tv = *tvs.iter().find(|tv| { tv.id.node == fn_id.node}).unwrap();
-        let d = mk_lldecl(None);
+        let d = mk_lldecl();
         set_inline_hint(d);
         match v.node.kind {
             ast::TupleVariantKind(ref args) => {
@@ -272,24 +266,19 @@ pub fn monomorphic_fn(ccx: @CrateContext,
         d
       }
       ast_map::NodeMethod(mth, _, _) => {
-        meth::trans_method(ccx, pt, mth, Some(psubsts), |self_ty| {
-            let d = mk_lldecl(self_ty);
-            set_llvm_fn_attrs(mth.attrs, d);
-            d
-        })
+        let d = mk_lldecl();
+        set_llvm_fn_attrs(mth.attrs, d);
+        trans_fn(ccx, pt, mth.decl, mth.body, d, Some(psubsts), mth.id, []);
+        d
       }
       ast_map::NodeTraitMethod(method, _, pt) => {
           match *method {
               ast::Provided(mth) => {
-                meth::trans_method(ccx,
-                                   (*pt).clone(),
-                                   mth,
-                                   Some(psubsts),
-                                   |self_ty| {
-                    let d = mk_lldecl(self_ty);
-                    set_llvm_fn_attrs(mth.attrs, d);
-                    d
-                })
+                  let d = mk_lldecl();
+                  set_llvm_fn_attrs(mth.attrs, d);
+                  trans_fn(ccx, (*pt).clone(), mth.decl, mth.body,
+                           d, Some(psubsts), mth.id, []);
+                  d
               }
               _ => {
                 ccx.tcx.sess.bug(format!("Can't monomorphize a {:?}",
@@ -298,7 +287,7 @@ pub fn monomorphic_fn(ccx: @CrateContext,
           }
       }
       ast_map::NodeStructCtor(struct_def, _, _) => {
-        let d = mk_lldecl(None);
+        let d = mk_lldecl();
         set_inline_hint(d);
         base::trans_tuple_struct(ccx,
                                  struct_def.fields,
index c13bb139da759482736df9793ddd8504307734d5..cbfd83309a4a0f3902741317a383990ea3e0a92b 100644 (file)
@@ -13,7 +13,7 @@
 use middle::trans::adt;
 use middle::trans::base::*;
 use middle::trans::build::*;
-use middle::trans::callee::{ArgVals, DontAutorefArg};
+use middle::trans::callee::ArgVals;
 use middle::trans::callee;
 use middle::trans::common::*;
 use middle::trans::datum::*;
@@ -73,8 +73,8 @@ pub fn c_size_and_align(&mut self, t: ty::t) -> ~[ValueRef] {
         let tr = type_of(self.bcx.ccx(), t);
         let s = machine::llsize_of_real(self.bcx.ccx(), tr);
         let a = machine::llalign_of_min(self.bcx.ccx(), tr);
-        return ~[self.c_uint(s),
-             self.c_uint(a)];
+        return ~[self.c_uint(s as uint),
+             self.c_uint(a as uint)];
     }
 
     pub fn c_tydesc(&mut self, t: ty::t) -> ValueRef {
@@ -111,7 +111,7 @@ pub fn visit(&mut self, ty_name: &str, args: &[ValueRef]) {
                                                          mth_ty,
                                                          mth_idx,
                                                          v),
-            ArgVals(args), None, DontAutorefArg));
+            ArgVals(args), None));
         let result = bool_to_i1(bcx, result);
         let next_bcx = fcx.new_temp_block("next");
         CondBr(bcx, result, next_bcx.llbb, self.final_bcx.llbb);
@@ -292,12 +292,10 @@ pub fn visit_ty(&mut self, t: ty::t) {
                                                                sub_path,
                                                                "get_disr");
 
-                let llfdecl = decl_internal_rust_fn(ccx, None, [opaqueptrty], ty::mk_u64(), sym);
-                let fcx = new_fn_ctxt(ccx,
-                                      ~[],
-                                      llfdecl,
-                                      ty::mk_u64(),
-                                      None);
+                let llfdecl = decl_internal_rust_fn(ccx, false,
+                                                    [opaqueptrty],
+                                                    ty::mk_u64(), sym);
+                let fcx = new_fn_ctxt(ccx, ~[], llfdecl, false, ty::mk_u64(), None);
                 init_function(&fcx, false, ty::mk_u64(), None);
 
                 let arg = unsafe {
@@ -358,12 +356,7 @@ pub fn visit_ty(&mut self, t: ty::t) {
               self.visit("param", extra)
           }
           ty::ty_self(..) => self.leaf("self"),
-          ty::ty_type => self.leaf("type"),
-          ty::ty_opaque_closure_ptr(ck) => {
-              let ckval = ast_sigil_constant(ck);
-              let extra = ~[self.c_uint(ckval)];
-              self.visit("closure_ptr", extra)
-          }
+          ty::ty_type => self.leaf("type")
         }
     }
 
index 5a5a028c38000f29870a06a300d75e058b6b6152..5754a9ba88b99d67ad4a8e50f2990462dbb574f0 100644 (file)
@@ -164,7 +164,7 @@ pub struct VecTypes {
     unit_ty: ty::t,
     llunit_ty: Type,
     llunit_size: ValueRef,
-    llunit_alloc_size: uint
+    llunit_alloc_size: u64
 }
 
 impl VecTypes {
index 833a7848ad316a0f16cc11e34d9eb43ce58ba819..39a99ef995012f9d9cceb7ef24cb4f484ac982f5 100644 (file)
@@ -160,10 +160,6 @@ pub fn variadic_func(args: &[Type], ret: &Type) -> Type {
                                    args.len() as c_uint, True))
     }
 
-    pub fn func_pair(cx: &CrateContext, fn_ty: &Type) -> Type {
-        Type::struct_([fn_ty.ptr_to(), Type::opaque_cbox_ptr(cx)], false)
-    }
-
     pub fn ptr(ty: Type) -> Type {
         ty!(llvm::LLVMPointerType(ty.to_ref(), 0 as c_uint))
     }
@@ -184,7 +180,7 @@ pub fn empty_struct() -> Type {
     }
 
     pub fn vtable() -> Type {
-        Type::array(&Type::i8().ptr_to(), 1)
+        Type::array(&Type::i8p().ptr_to(), 1)
     }
 
     pub fn generic_glue_fn(cx: &CrateContext) -> Type {
@@ -200,8 +196,7 @@ pub fn generic_glue_fn(cx: &CrateContext) -> Type {
     }
 
     pub fn glue_fn(t: Type) -> Type {
-        Type::func([ Type::nil().ptr_to(), t ],
-            &Type::void())
+        Type::func([t], &Type::void())
     }
 
     pub fn tydesc(arch: Architecture) -> Type {
@@ -213,11 +208,9 @@ pub fn tydesc(arch: Architecture) -> Type {
         // Must mirror:
         //
         // std::unstable::intrinsics::TyDesc
-        // type_desc in rt
 
         let elems = [int_ty,     // size
                      int_ty,     // align
-                     glue_fn_ty, // take
                      glue_fn_ty, // drop
                      glue_fn_ty, // visit
                      Type::struct_([Type::i8p(), Type::int(arch)], false)]; // name
@@ -244,42 +237,22 @@ pub fn opaque_vec(arch: Architecture) -> Type {
         Type::vec(arch, &Type::i8())
     }
 
-    #[inline]
-    pub fn box_header_fields(ctx: &CrateContext) -> ~[Type] {
-        ~[
+    // The box pointed to by @T.
+    pub fn at_box(ctx: &CrateContext, ty: Type) -> Type {
+        Type::struct_([
             ctx.int_type, ctx.tydesc_type.ptr_to(),
-            Type::i8().ptr_to(), Type::i8().ptr_to()
-        ]
-    }
-
-    pub fn box_header(ctx: &CrateContext) -> Type {
-        Type::struct_(Type::box_header_fields(ctx), false)
-    }
-
-    pub fn smart_ptr(ctx: &CrateContext, ty: &Type) -> Type {
-        Type::struct_(Type::box_header_fields(ctx) + &[*ty], false)
-    }
-
-    pub fn opaque() -> Type {
-        Type::i8()
-    }
-
-    pub fn opaque_box(ctx: &CrateContext) -> Type {
-        Type::smart_ptr(ctx, &Type::opaque())
-    }
-
-    pub fn opaque_cbox_ptr(cx: &CrateContext) -> Type {
-        Type::opaque_box(cx).ptr_to()
+            Type::i8p(), Type::i8p(), ty
+        ], false)
     }
 
     pub fn opaque_trait(ctx: &CrateContext, store: ty::TraitStore) -> Type {
-        let tydesc_ptr = ctx.tydesc_type.ptr_to();
+        let vtable = Type::glue_fn(Type::i8p()).ptr_to().ptr_to();
         let box_ty = match store {
-            ty::BoxTraitStore => Type::opaque_box(ctx),
+            ty::BoxTraitStore => Type::at_box(ctx, Type::i8()),
             ty::UniqTraitStore => Type::i8(),
             ty::RegionTraitStore(..) => Type::i8()
         };
-        Type::struct_([tydesc_ptr, box_ty.ptr_to()], false)
+        Type::struct_([vtable, box_ty.ptr_to()], false)
     }
 
     pub fn kind(&self) -> TypeKind {
index 4db89fbeccec7497d20f810f66edf8a4efeb6a8c..86456187d1ad1bdfb78ff45a714c7d01f32a1d18 100644 (file)
@@ -38,15 +38,8 @@ pub fn type_of_explicit_arg(ccx: &CrateContext, arg_ty: ty::t) -> Type {
     }
 }
 
-pub fn type_of_explicit_args(ccx: &CrateContext,
-                             inputs: &[ty::t]) -> ~[Type] {
-    inputs.map(|&arg_ty| type_of_explicit_arg(ccx, arg_ty))
-}
-
-pub fn type_of_rust_fn(cx: &CrateContext,
-                       self_ty: Option<ty::t>,
-                       inputs: &[ty::t],
-                       output: ty::t) -> Type {
+pub fn type_of_rust_fn(cx: &CrateContext, has_env: bool,
+                       inputs: &[ty::t], output: ty::t) -> Type {
     let mut atys: ~[Type] = ~[];
 
     // Arg 0: Output pointer.
@@ -58,14 +51,13 @@ pub fn type_of_rust_fn(cx: &CrateContext,
     }
 
     // Arg 1: Environment
-    let env = match self_ty {
-        Some(t) => type_of_explicit_arg(cx, t),
-        None => Type::opaque_box(cx).ptr_to()
-    };
-    atys.push(env);
+    if has_env {
+        atys.push(Type::i8p());
+    }
 
     // ... then explicit args.
-    atys.push_all(type_of_explicit_args(cx, inputs));
+    let mut input_tys = inputs.iter().map(|&arg_ty| type_of_explicit_arg(cx, arg_ty));
+    atys.extend(&mut input_tys);
 
     // Use the output as the actual return value if it's immediate.
     if use_out_pointer || return_type_is_void(cx, output) {
@@ -76,14 +68,14 @@ pub fn type_of_rust_fn(cx: &CrateContext,
 }
 
 // Given a function type and a count of ty params, construct an llvm type
-pub fn type_of_fn_from_ty(cx: &CrateContext, self_ty: Option<ty::t>, fty: ty::t) -> Type {
-    return match ty::get(fty).sty {
+pub fn type_of_fn_from_ty(cx: &CrateContext, fty: ty::t) -> Type {
+    match ty::get(fty).sty {
         ty::ty_closure(ref f) => {
-            type_of_rust_fn(cx, None, f.sig.inputs, f.sig.output)
+            type_of_rust_fn(cx, true, f.sig.inputs, f.sig.output)
         }
         ty::ty_bare_fn(ref f) => {
             if f.abis.is_rust() || f.abis.is_intrinsic() {
-                type_of_rust_fn(cx, self_ty, f.sig.inputs, f.sig.output)
+                type_of_rust_fn(cx, false, f.sig.inputs, f.sig.output)
             } else {
                 foreign::lltype_for_foreign_fn(cx, fty)
             }
@@ -91,7 +83,7 @@ pub fn type_of_fn_from_ty(cx: &CrateContext, self_ty: Option<ty::t>, fty: ty::t)
         _ => {
             cx.sess.bug("type_of_fn_from_ty given non-closure, non-bare-fn")
         }
-    };
+    }
 }
 
 // A "sizing type" is an LLVM type, the size and alignment of which are
@@ -130,8 +122,7 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
         ty::ty_uniq(..) |
         ty::ty_ptr(..) |
         ty::ty_rptr(..) |
-        ty::ty_type |
-        ty::ty_opaque_closure_ptr(..) => Type::i8p(),
+        ty::ty_type => Type::i8p(),
 
         ty::ty_str(ty::vstore_slice(..)) |
         ty::ty_vec(_, ty::vstore_slice(..)) => {
@@ -231,18 +222,14 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
         adt::incomplete_type_of(cx, repr, name)
       }
       ty::ty_str(ty::vstore_box) => {
-        Type::smart_ptr(cx,
-                        &Type::vec(cx.sess.targ_cfg.arch,
-                                   &Type::i8())).ptr_to()
+          Type::at_box(cx, Type::vec(cx.sess.targ_cfg.arch, &Type::i8())).ptr_to()
       }
       ty::ty_vec(ref mt, ty::vstore_box) => {
           let e_ty = type_of(cx, mt.ty);
-          let v_ty = Type::vec(cx.sess.targ_cfg.arch, &e_ty);
-          Type::smart_ptr(cx, &v_ty).ptr_to()
+          Type::at_box(cx, Type::vec(cx.sess.targ_cfg.arch, &e_ty)).ptr_to()
       }
       ty::ty_box(typ) => {
-          let ty = type_of(cx, typ);
-          Type::smart_ptr(cx, &ty).ptr_to()
+          Type::at_box(cx, type_of(cx, typ)).ptr_to()
       }
       ty::ty_uniq(typ) => {
           type_of(cx, typ).ptr_to()
@@ -278,11 +265,11 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
       }
 
       ty::ty_bare_fn(_) => {
-          type_of_fn_from_ty(cx, None, t).ptr_to()
+          type_of_fn_from_ty(cx, t).ptr_to()
       }
       ty::ty_closure(_) => {
-          let ty = type_of_fn_from_ty(cx, None, t);
-          Type::func_pair(cx, &ty)
+          let fn_ty = type_of_fn_from_ty(cx, t).ptr_to();
+          Type::struct_([fn_ty, Type::i8p()], false)
       }
       ty::ty_trait(_, _, store, _, _) => Type::opaque_trait(cx, store),
       ty::ty_type => cx.tydesc_type.ptr_to(),
@@ -290,7 +277,6 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
           let repr = adt::represent_type(cx, t);
           adt::type_of(cx, repr)
       }
-      ty::ty_opaque_closure_ptr(_) => Type::opaque_box(cx).ptr_to(),
       ty::ty_struct(did, ref substs) => {
           if ty::type_is_simd(cx.tcx, t) {
               let et = ty::simd_type(cx.tcx, t);
@@ -344,7 +330,8 @@ pub fn llvm_type_name(cx: &CrateContext,
         an_enum => { "enum" }
     };
     let tstr = ppaux::parameterized(cx.tcx, ty::item_path_str(cx.tcx, did),
-                                    &ty::NonerasedRegions(opt_vec::Empty), tps);
+                                    &ty::NonerasedRegions(opt_vec::Empty),
+                                    tps, did, false);
     if did.crate == 0 {
         format!("{}.{}", name, tstr)
     } else {
index 01fb18d73c26a5efa6ae110653e34b2847b19c91..3b5dd67366c5de54bcd9853dfbed190d835cc77a 100644 (file)
@@ -73,7 +73,6 @@ pub enum MethodContainer {
 pub struct Method {
     ident: ast::Ident,
     generics: ty::Generics,
-    transformed_self_ty: Option<ty::t>,
     fty: BareFnTy,
     explicit_self: ast::ExplicitSelf_,
     vis: ast::Visibility,
@@ -87,7 +86,6 @@ pub struct Method {
 impl Method {
     pub fn new(ident: ast::Ident,
                generics: ty::Generics,
-               transformed_self_ty: Option<ty::t>,
                fty: BareFnTy,
                explicit_self: ast::ExplicitSelf_,
                vis: ast::Visibility,
@@ -95,17 +93,9 @@ pub fn new(ident: ast::Ident,
                container: MethodContainer,
                provided_source: Option<ast::DefId>)
                -> Method {
-        // Check the invariants.
-        if explicit_self == ast::SelfStatic {
-            assert!(transformed_self_ty.is_none());
-        } else {
-            assert!(transformed_self_ty.is_some());
-        }
-
        Method {
             ident: ident,
             generics: generics,
-            transformed_self_ty: transformed_self_ty,
             fty: fty,
             explicit_self: explicit_self,
             vis: vis,
@@ -257,7 +247,7 @@ pub enum AutoRef {
 /// The data structure to keep track of all the information that typechecker
 /// generates so that so that it can be reused and doesn't have to be redone
 /// later on.
-struct ctxt_ {
+pub struct ctxt_ {
     diag: @syntax::diagnostic::SpanHandler,
     interner: RefCell<HashMap<intern_key, ~t_box_>>,
     next_id: Cell<uint>,
@@ -650,7 +640,6 @@ pub enum sty {
 
     // "Fake" types, used for trans purposes
     ty_type, // type_desc*
-    ty_opaque_closure_ptr(Sigil), // ptr to env for || and proc
     ty_unboxed_vec(mt),
 }
 
@@ -866,7 +855,8 @@ fn to_str(&self) -> ~str {
 pub struct TypeParameterDef {
     ident: ast::Ident,
     def_id: ast::DefId,
-    bounds: @ParamBounds
+    bounds: @ParamBounds,
+    default: Option<ty::t>
 }
 
 #[deriving(Encodable, Decodable, Clone)]
@@ -1068,7 +1058,7 @@ fn sflags(substs: &substs) -> uint {
         flags |= get(mt.ty).flags;
       }
       &ty_nil | &ty_bool | &ty_char | &ty_int(_) | &ty_float(_) | &ty_uint(_) |
-      &ty_str(_) | &ty_type | &ty_opaque_closure_ptr(_) => {}
+      &ty_str(_) | &ty_type => {}
       // 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
@@ -1333,10 +1323,6 @@ pub fn mk_param(cx: ctxt, n: uint, k: DefId) -> t {
 
 pub fn mk_type(cx: ctxt) -> t { mk_t(cx, ty_type) }
 
-pub fn mk_opaque_closure_ptr(cx: ctxt, sigil: ast::Sigil) -> t {
-    mk_t(cx, ty_opaque_closure_ptr(sigil))
-}
-
 pub fn walk_ty(ty: t, f: |t|) {
     maybe_walk_ty(ty, |t| { f(t); true });
 }
@@ -1346,27 +1332,27 @@ 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_type | ty_self(_) |
-      ty_opaque_closure_ptr(_) | ty_infer(_) | ty_param(_) | ty_err => {}
-      ty_box(ty) | ty_uniq(ty) => maybe_walk_ty(ty, f),
-      ty_vec(ref tm, _) | ty_unboxed_vec(ref tm) | ty_ptr(ref tm) |
-      ty_rptr(_, ref tm) => {
-        maybe_walk_ty(tm.ty, f);
-      }
-      ty_enum(_, ref substs) | ty_struct(_, ref substs) |
-      ty_trait(_, ref substs, _, _, _) => {
-        for subty in (*substs).tps.iter() { maybe_walk_ty(*subty, |x| f(x)); }
-      }
-      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);
-      }
-      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);
-      }
+        ty_nil | ty_bot | ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) |
+        ty_str(_) | ty_type | ty_self(_) |
+        ty_infer(_) | ty_param(_) | ty_err => {}
+        ty_box(ty) | ty_uniq(ty) => maybe_walk_ty(ty, f),
+        ty_vec(ref tm, _) | ty_unboxed_vec(ref tm) | ty_ptr(ref tm) |
+        ty_rptr(_, ref tm) => {
+            maybe_walk_ty(tm.ty, f);
+        }
+        ty_enum(_, ref substs) | ty_struct(_, ref substs) |
+        ty_trait(_, ref substs, _, _, _) => {
+            for subty in (*substs).tps.iter() { maybe_walk_ty(*subty, |x| f(x)); }
+        }
+        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);
+        }
+        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);
+        }
     }
 }
 
@@ -1608,11 +1594,8 @@ pub fn type_is_vec(ty: t) -> bool {
 
 pub fn type_is_unique(ty: t) -> bool {
     match get(ty).sty {
-        ty_uniq(_) |
-        ty_vec(_, vstore_uniq) |
-        ty_str(vstore_uniq) |
-        ty_opaque_closure_ptr(ast::OwnedSigil) => true,
-        _ => return false
+        ty_uniq(_) | ty_vec(_, vstore_uniq) | ty_str(vstore_uniq) => true,
+        _ => false
     }
 }
 
@@ -2118,13 +2101,6 @@ fn tc_ty(cx: ctxt,
                 TC::All
             }
             ty_unboxed_vec(mt) => TC::InteriorUnsized | tc_mt(cx, mt, cache),
-            ty_opaque_closure_ptr(sigil) => {
-                match sigil {
-                    ast::BorrowedSigil => TC::ReachesBorrowed,
-                    ast::ManagedSigil => TC::Managed,
-                    ast::OwnedSigil => TC::OwnsOwned,
-                }
-            }
 
             ty_type => TC::None,
 
@@ -2308,7 +2284,6 @@ fn subtypes_require(cx: ctxt, seen: &mut ~[DefId],
             ty_param(_) |
             ty_self(_) |
             ty_type |
-            ty_opaque_closure_ptr(_) |
             ty_vec(_, _) |
             ty_unboxed_vec(_) => {
                 false
@@ -2374,53 +2349,104 @@ fn subtypes_require(cx: ctxt, seen: &mut ~[DefId],
     !subtypes_require(cx, &mut seen, r_ty, r_ty)
 }
 
-pub fn type_structurally_contains(cx: ctxt, ty: t, test: |x: &sty| -> bool)
-                                  -> bool {
-    let sty = &get(ty).sty;
-    debug!("type_structurally_contains: {}",
-           ::util::ppaux::ty_to_str(cx, ty));
-    if test(sty) { return true; }
-    match *sty {
-      ty_enum(did, ref substs) => {
-        for variant in (*enum_variants(cx, did)).iter() {
-            for aty in variant.args.iter() {
-                let sty = subst(cx, substs, *aty);
-                if type_structurally_contains(cx, sty, |x| test(x)) { return true; }
+/// Describes whether a type is representable. For types that are not
+/// representable, 'SelfRecursive' and 'ContainsRecursive' are used to
+/// distinguish between types that are recursive with themselves and types that
+/// contain a different recursive type. These cases can therefore be treated
+/// differently when reporting errors.
+#[deriving(Eq)]
+pub enum Representability {
+    Representable,
+    SelfRecursive,
+    ContainsRecursive,
+}
+
+/// Check whether a type is representable. This means it cannot contain unboxed
+/// structural recursion. This check is needed for structs and enums.
+pub fn is_type_representable(cx: ctxt, ty: t) -> Representability {
+
+    // Iterate until something non-representable is found
+    fn find_nonrepresentable<It: Iterator<t>>(cx: ctxt, seen: &mut ~[DefId],
+                                              mut iter: It) -> Representability {
+        for ty in iter {
+            let r = type_structurally_recursive(cx, seen, ty);
+            if r != Representable {
+                 return r
             }
         }
-        return false;
-      }
-      ty_struct(did, ref substs) => {
-        let r = lookup_struct_fields(cx, did);
-        for field in r.iter() {
-            let ft = lookup_field_type(cx, did, field.id, substs);
-            if type_structurally_contains(cx, ft, |x| test(x)) { return true; }
+        Representable
+    }
+
+    // Does the type `ty` directly (without indirection through a pointer)
+    // contain any types on stack `seen`?
+    fn type_structurally_recursive(cx: ctxt, seen: &mut ~[DefId],
+                                   ty: t) -> Representability {
+        debug!("type_structurally_recursive: {}",
+               ::util::ppaux::ty_to_str(cx, ty));
+
+        // Compare current type to previously seen types
+        match get(ty).sty {
+            ty_struct(did, _) |
+            ty_enum(did, _) => {
+                for (i, &seen_did) in seen.iter().enumerate() {
+                    if did == seen_did {
+                        return if i == 0 { SelfRecursive }
+                               else { ContainsRecursive }
+                    }
+                }
+            }
+            _ => (),
         }
-        return false;
-      }
 
-      ty_tup(ref ts) => {
-        for tt in ts.iter() {
-            if type_structurally_contains(cx, *tt, |x| test(x)) { return true; }
+        // Check inner types
+        match get(ty).sty {
+            // Tuples
+            ty_tup(ref ts) => {
+                find_nonrepresentable(cx, seen, ts.iter().map(|t| *t))
+            }
+            // Fixed-length vectors.
+            // FIXME(#11924) Behavior undecided for zero-length vectors.
+            ty_vec(mt, vstore_fixed(_)) => {
+                type_structurally_recursive(cx, seen, mt.ty)
+            }
+
+            // Push struct and enum def-ids onto `seen` before recursing.
+            ty_struct(did, ref substs) => {
+                seen.push(did);
+                let fields = struct_fields(cx, did, substs);
+                let r = find_nonrepresentable(cx, seen,
+                                              fields.iter().map(|f| f.mt.ty));
+                seen.pop();
+                r
+            }
+            ty_enum(did, ref substs) => {
+                seen.push(did);
+                let vs = enum_variants(cx, did);
+
+                let mut r = Representable;
+                for variant in vs.iter() {
+                    let iter = variant.args.iter().map(|aty| subst(cx, substs, *aty));
+                    r = find_nonrepresentable(cx, seen, iter);
+
+                    if r != Representable { break }
+                }
+
+                seen.pop();
+                r
+            }
+
+            _ => Representable,
         }
-        return false;
-      }
-      ty_vec(ref mt, vstore_fixed(_)) => {
-        return type_structurally_contains(cx, mt.ty, test);
-      }
-      _ => return false
     }
-}
 
-pub fn type_structurally_contains_uniques(cx: ctxt, ty: t) -> bool {
-    return type_structurally_contains(cx, ty, |sty| {
-        match *sty {
-          ty_uniq(_) |
-          ty_vec(_, vstore_uniq) |
-          ty_str(vstore_uniq) => true,
-          _ => false,
-        }
-    });
+    debug!("is_type_representable: {}",
+           ::util::ppaux::ty_to_str(cx, ty));
+
+    // To avoid a stack overflow when checking an enum variant or struct that
+    // contains a different, structurally recursive type, maintain a stack
+    // of seen types and check recursion for each of them (issues #3008, #3779).
+    let mut seen: ~[DefId] = ~[];
+    type_structurally_recursive(cx, &mut seen, ty)
 }
 
 pub fn type_is_trait(ty: t) -> bool {
@@ -2494,7 +2520,7 @@ pub fn type_is_pod(cx: ctxt, ty: t) -> bool {
       ty_enum(did, ref substs) => {
         let variants = enum_variants(cx, did);
         for variant in (*variants).iter() {
-            // XXX(pcwalton): This is an inefficient way to do this. Don't
+            // FIXME(pcwalton): This is an inefficient way to do this. Don't
             // synthesize a tuple!
             //
             // Perform any type parameter substitutions.
@@ -2511,7 +2537,6 @@ pub fn type_is_pod(cx: ctxt, ty: t) -> bool {
         result = type_is_pod(cx, mt.ty);
       }
       ty_param(_) => result = false,
-      ty_opaque_closure_ptr(_) => result = true,
       ty_struct(did, ref substs) => {
         let fields = lookup_struct_fields(cx, did);
         result = fields.iter().all(|f| {
@@ -2655,7 +2680,7 @@ pub fn node_id_to_type(cx: ctxt, id: ast::NodeId) -> t {
     }
 }
 
-// XXX(pcwalton): Makes a copy, bleh. Probably better to not do that.
+// FIXME(pcwalton): Makes a copy, bleh. Probably better to not do that.
 pub fn node_id_to_type_params(cx: ctxt, id: ast::NodeId) -> ~[t] {
     let node_type_substs = cx.node_type_substs.borrow();
     match node_type_substs.get().find(&id) {
@@ -3139,22 +3164,37 @@ pub fn expr_kind(tcx: ctxt,
     }
 
     match expr.node {
-        ast::ExprPath(..) | ast::ExprSelf => {
+        ast::ExprPath(..) => {
             match resolve_expr(tcx, expr) {
-                ast::DefVariant(..) | ast::DefStruct(..) => RvalueDpsExpr,
+                ast::DefVariant(tid, vid, _) => {
+                    let variant_info = enum_variant_with_id(tcx, tid, vid);
+                    if variant_info.args.len() > 0u {
+                        // N-ary variant.
+                        RvalueDatumExpr
+                    } else {
+                        // Nullary variant.
+                        RvalueDpsExpr
+                    }
+                }
+
+                ast::DefStruct(_) => {
+                    match get(expr_ty(tcx, expr)).sty {
+                        ty_bare_fn(..) => RvalueDatumExpr,
+                        _ => RvalueDpsExpr
+                    }
+                }
 
                 // Fn pointers are just scalar values.
                 ast::DefFn(..) | ast::DefStaticMethod(..) => RvalueDatumExpr,
 
                 // Note: there is actually a good case to be made that
-                // def_args, particularly those of immediate type, ought to
+                // DefArg's, particularly those of immediate type, ought to
                 // considered rvalues.
                 ast::DefStatic(..) |
                 ast::DefBinding(..) |
                 ast::DefUpvar(..) |
                 ast::DefArg(..) |
-                ast::DefLocal(..) |
-                ast::DefSelf(..) => LvalueExpr,
+                ast::DefLocal(..) => LvalueExpr,
 
                 def => {
                     tcx.sess.span_bug(expr.span, format!(
@@ -3178,7 +3218,6 @@ pub fn expr_kind(tcx: ctxt,
         ast::ExprMatch(..) |
         ast::ExprFnBlock(..) |
         ast::ExprProc(..) |
-        ast::ExprDoBody(..) |
         ast::ExprBlock(..) |
         ast::ExprRepeat(..) |
         ast::ExprVstore(_, ast::ExprVstoreSlice) |
@@ -3343,30 +3382,29 @@ fn vars_in_type(ty: t) -> ~[TyVid] {
 
 pub fn ty_sort_str(cx: ctxt, t: t) -> ~str {
     match get(t).sty {
-      ty_nil | ty_bot | ty_bool | ty_char | ty_int(_) |
-      ty_uint(_) | ty_float(_) | ty_str(_) |
-      ty_type | ty_opaque_closure_ptr(_) => {
-        ::util::ppaux::ty_to_str(cx, t)
-      }
-
-      ty_enum(id, _) => format!("enum {}", item_path_str(cx, id)),
-      ty_box(_) => ~"@-ptr",
-      ty_uniq(_) => ~"~-ptr",
-      ty_vec(_, _) => ~"vector",
-      ty_unboxed_vec(_) => ~"unboxed vector",
-      ty_ptr(_) => ~"*-ptr",
-      ty_rptr(_, _) => ~"&-ptr",
-      ty_bare_fn(_) => ~"extern fn",
-      ty_closure(_) => ~"fn",
-      ty_trait(id, _, _, _, _) => format!("trait {}", item_path_str(cx, id)),
-      ty_struct(id, _) => format!("struct {}", item_path_str(cx, id)),
-      ty_tup(_) => ~"tuple",
-      ty_infer(TyVar(_)) => ~"inferred type",
-      ty_infer(IntVar(_)) => ~"integral variable",
-      ty_infer(FloatVar(_)) => ~"floating-point variable",
-      ty_param(_) => ~"type parameter",
-      ty_self(_) => ~"self",
-      ty_err => ~"type error"
+        ty_nil | ty_bot | ty_bool | ty_char | ty_int(_) |
+        ty_uint(_) | ty_float(_) | ty_str(_) | ty_type => {
+            ::util::ppaux::ty_to_str(cx, t)
+        }
+
+        ty_enum(id, _) => format!("enum {}", item_path_str(cx, id)),
+        ty_box(_) => ~"@-ptr",
+        ty_uniq(_) => ~"~-ptr",
+        ty_vec(_, _) => ~"vector",
+        ty_unboxed_vec(_) => ~"unboxed vector",
+        ty_ptr(_) => ~"*-ptr",
+        ty_rptr(_, _) => ~"&-ptr",
+        ty_bare_fn(_) => ~"extern fn",
+        ty_closure(_) => ~"fn",
+        ty_trait(id, _, _, _, _) => format!("trait {}", item_path_str(cx, id)),
+        ty_struct(id, _) => format!("struct {}", item_path_str(cx, id)),
+        ty_tup(_) => ~"tuple",
+        ty_infer(TyVar(_)) => ~"inferred type",
+        ty_infer(IntVar(_)) => ~"integral variable",
+        ty_infer(FloatVar(_)) => ~"floating-point variable",
+        ty_param(_) => ~"type parameter",
+        ty_self(_) => ~"self",
+        ty_err => ~"type error"
     }
 }
 
@@ -4912,12 +4950,8 @@ fn iter<T: IterBytes>(hash: &mut SipState, t: &T) {
             ty_infer(_) => unreachable!(),
             ty_err => hash.input([23]),
             ty_type => hash.input([24]),
-            ty_opaque_closure_ptr(s) => {
-                hash.input([25]);
-                iter(&mut hash, &s);
-            }
             ty_unboxed_vec(m) => {
-                hash.input([26]);
+                hash.input([25]);
                 mt(&mut hash, m);
             }
         }
index 28ba566c0a4ab5063594303b8a2a03ea3d69e8e3..e322792c996802f273f72a8c6a76338e9b3a043f 100644 (file)
@@ -189,7 +189,6 @@ pub fn super_fold_sty<T:TypeFolder>(this: &mut T,
         ty::ty_nil | ty::ty_bot | ty::ty_bool | ty::ty_char |
         ty::ty_int(_) | ty::ty_uint(_) |
         ty::ty_float(_) | ty::ty_type |
-        ty::ty_opaque_closure_ptr(_) |
         ty::ty_err | ty::ty_infer(_) |
         ty::ty_param(..) | ty::ty_self(_) => {
             (*sty).clone()
index 2e25ac941a66dda43031b72dc07eb7c6864b7a67..144ce99198f4ae4286284b4f656996498379cccb 100644 (file)
@@ -51,6 +51,7 @@
 
 
 use middle::const_eval;
+use middle::lint;
 use middle::ty::{substs};
 use middle::ty::{ty_param_substs_and_ty};
 use middle::ty;
@@ -195,21 +196,43 @@ fn ast_path_substs<AC:AstConv,RS:RegionScope>(
     };
 
     // Convert the type parameters supplied by the user.
-    let supplied_type_parameter_count =
-        path.segments.iter().flat_map(|s| s.types.iter()).len();
-    if decl_generics.type_param_defs.len() != supplied_type_parameter_count {
-        this.tcx().sess.span_fatal(
-            path.span,
-            format!("wrong number of type arguments: expected {} but found {}",
-                 decl_generics.type_param_defs.len(),
-                 supplied_type_parameter_count));
+    let supplied_ty_param_count = path.segments.iter().flat_map(|s| s.types.iter()).len();
+    let formal_ty_param_count = decl_generics.type_param_defs.len();
+    let required_ty_param_count = decl_generics.type_param_defs.iter()
+                                               .take_while(|x| x.default.is_none())
+                                               .len();
+    if supplied_ty_param_count < required_ty_param_count {
+        let expected = if required_ty_param_count < formal_ty_param_count {
+            "expected at least"
+        } else {
+            "expected"
+        };
+        this.tcx().sess.span_fatal(path.span,
+            format!("wrong number of type arguments: {} {} but found {}",
+                expected, required_ty_param_count, supplied_ty_param_count));
+    } else if supplied_ty_param_count > formal_ty_param_count {
+        let expected = if required_ty_param_count < formal_ty_param_count {
+            "expected at most"
+        } else {
+            "expected"
+        };
+        this.tcx().sess.span_fatal(path.span,
+            format!("wrong number of type arguments: {} {} but found {}",
+                expected, formal_ty_param_count, supplied_ty_param_count));
     }
-    let tps = path.segments
-                  .iter()
-                  .flat_map(|s| s.types.iter())
-                  .map(|&a_t| ast_ty_to_ty(this, rscope, a_t))
-                  .collect();
 
+    if supplied_ty_param_count > required_ty_param_count {
+        let id = path.segments.iter().flat_map(|s| s.types.iter())
+                              .nth(required_ty_param_count).unwrap().id;
+        this.tcx().sess.add_lint(lint::DefaultTypeParamUsage, id, path.span,
+                                 ~"provided type arguments with defaults");
+    }
+
+    let defaults = decl_generics.type_param_defs.slice_from(supplied_ty_param_count)
+                                .iter().map(|&x| x.default.unwrap());
+    let tps = path.segments.iter().flat_map(|s| s.types.iter())
+                            .map(|&a_t| ast_ty_to_ty(this, rscope, a_t))
+                            .chain(defaults).collect();
     substs {
         regions: ty::NonerasedRegions(regions),
         self_ty: self_ty,
@@ -589,13 +612,8 @@ fn check_path_args(tcx: ty::ctxt,
     return typ;
 }
 
-pub fn ty_of_arg<AC:AstConv,
-                 RS:RegionScope>(
-                 this: &AC,
-                 rscope: &RS,
-                 a: &ast::Arg,
-                 expected_ty: Option<ty::t>)
-                 -> ty::t {
+pub fn ty_of_arg<AC: AstConv, RS: RegionScope>(this: &AC, rscope: &RS, a: &ast::Arg,
+                                               expected_ty: Option<ty::t>) -> ty::t {
     match a.ty.node {
         ast::TyInfer if expected_ty.is_some() => expected_ty.unwrap(),
         ast::TyInfer => this.ty_infer(a.ty.span),
@@ -614,77 +632,38 @@ pub fn ty_of_method<AC:AstConv>(
     purity: ast::Purity,
     untransformed_self_ty: ty::t,
     explicit_self: ast::ExplicitSelf,
-    decl: &ast::FnDecl) -> (Option<ty::t>, ty::BareFnTy)
-{
-    let self_info = SelfInfo {
+    decl: &ast::FnDecl) -> ty::BareFnTy {
+    ty_of_method_or_bare_fn(this, id, purity, AbiSet::Rust(), Some(SelfInfo {
         untransformed_self_ty: untransformed_self_ty,
         explicit_self: explicit_self
-    };
-    let (a, b) = ty_of_method_or_bare_fn(
-        this, id, purity, AbiSet::Rust(), Some(&self_info), decl);
-    (a.unwrap(), b)
+    }), decl)
 }
 
-pub fn ty_of_bare_fn<AC:AstConv>(
-    this: &AC,
-    id: ast::NodeId,
-    purity: ast::Purity,
-    abi: AbiSet,
-    decl: &ast::FnDecl) -> ty::BareFnTy
-{
-    let (_, b) = ty_of_method_or_bare_fn(this, id, purity,
-                                         abi, None, decl);
-    b
+pub fn ty_of_bare_fn<AC:AstConv>(this: &AC, id: ast::NodeId,
+                                 purity: ast::Purity, abi: AbiSet,
+                                 decl: &ast::FnDecl) -> ty::BareFnTy {
+    ty_of_method_or_bare_fn(this, id, purity, abi, None, decl)
 }
 
-fn ty_of_method_or_bare_fn<AC:AstConv>(
-    this: &AC,
-    id: ast::NodeId,
-    purity: ast::Purity,
-    abi: AbiSet,
-    opt_self_info: Option<&SelfInfo>,
-    decl: &ast::FnDecl) -> (Option<Option<ty::t>>, ty::BareFnTy)
-{
+fn ty_of_method_or_bare_fn<AC:AstConv>(this: &AC, id: ast::NodeId,
+                                       purity: ast::Purity, abi: AbiSet,
+                                       opt_self_info: Option<SelfInfo>,
+                                       decl: &ast::FnDecl) -> ty::BareFnTy {
     debug!("ty_of_method_or_bare_fn");
 
     // new region names that appear inside of the fn decl are bound to
     // that function type
     let rb = rscope::BindingRscope::new(id);
 
-    let opt_transformed_self_ty = opt_self_info.map(|self_info| {
-        transform_self_ty(this, &rb, self_info)
-    });
-
-    let input_tys = decl.inputs.map(|a| ty_of_arg(this, &rb, a, None));
-
-    let output_ty = match decl.output.node {
-        ast::TyInfer => this.ty_infer(decl.output.span),
-        _ => ast_ty_to_ty(this, &rb, decl.output)
-    };
-
-    return (opt_transformed_self_ty,
-            ty::BareFnTy {
-                purity: purity,
-                abis: abi,
-                sig: ty::FnSig {binder_id: id,
-                                inputs: input_tys,
-                                output: output_ty,
-                                variadic: decl.variadic}
-            });
-
-    fn transform_self_ty<AC:AstConv,RS:RegionScope>(
-        this: &AC,
-        rscope: &RS,
-        self_info: &SelfInfo) -> Option<ty::t>
-    {
+    let self_ty = opt_self_info.and_then(|self_info| {
         match self_info.explicit_self.node {
             ast::SelfStatic => None,
-            ast::SelfValue(_) => {
+            ast::SelfValue => {
                 Some(self_info.untransformed_self_ty)
             }
             ast::SelfRegion(ref lifetime, mutability) => {
                 let region =
-                    opt_ast_region_to_region(this, rscope,
+                    opt_ast_region_to_region(this, &rb,
                                              self_info.explicit_self.span,
                                              lifetime);
                 Some(ty::mk_rptr(this.tcx(), region,
@@ -694,11 +673,37 @@ fn transform_self_ty<AC:AstConv,RS:RegionScope>(
             ast::SelfBox => {
                 Some(ty::mk_box(this.tcx(), self_info.untransformed_self_ty))
             }
-            ast::SelfUniq(_) => {
+            ast::SelfUniq => {
                 Some(ty::mk_uniq(this.tcx(), self_info.untransformed_self_ty))
             }
         }
-    }
+    });
+
+    // HACK(eddyb) replace the fake self type in the AST with the actual type.
+    let input_tys = if self_ty.is_some() {
+        decl.inputs.slice_from(1)
+    } else {
+        decl.inputs.as_slice()
+    };
+    let input_tys = input_tys.iter().map(|a| ty_of_arg(this, &rb, a, None));
+
+    let self_and_input_tys = self_ty.move_iter().chain(input_tys).collect();
+
+    let output_ty = match decl.output.node {
+        ast::TyInfer => this.ty_infer(decl.output.span),
+        _ => ast_ty_to_ty(this, &rb, decl.output)
+    };
+
+    return ty::BareFnTy {
+        purity: purity,
+        abis: abi,
+        sig: ty::FnSig {
+            binder_id: id,
+            inputs: self_and_input_tys,
+            output: output_ty,
+            variadic: decl.variadic
+        }
+    };
 }
 
 pub fn ty_of_closure<AC:AstConv,RS:RegionScope>(
index 293442417d2bee96f4a77fd092f0dc98dbb879fc..398b4cca015b4e0bbb9f6ecb4a2505475edf23ae 100644 (file)
@@ -80,6 +80,7 @@ trait `ToStr` imported, and I call `to_str()` on a value of type `T`,
 */
 
 
+use middle::subst::Subst;
 use middle::resolve;
 use middle::ty::*;
 use middle::ty;
@@ -422,19 +423,16 @@ fn push_inherent_candidates_from_object(&self,
             |new_trait_ref, m, method_num, _bound_num| {
             let vtable_index =
                 self.get_method_index(new_trait_ref, trait_ref, method_num);
+            let mut m = (*m).clone();
             // We need to fix up the transformed self type.
-            let transformed_self_ty =
+            m.fty.sig.inputs[0] =
                 self.construct_transformed_self_ty_for_object(
-                    did, &rcvr_substs, m);
-            let m = @Method {
-                transformed_self_ty: Some(transformed_self_ty),
-                .. (*m).clone()
-            };
+                    did, &rcvr_substs, &m);
 
             Candidate {
                 rcvr_match_condition: RcvrMatchesIfObject(did),
                 rcvr_substs: new_trait_ref.substs.clone(),
-                method_ty: m,
+                method_ty: @m,
                 origin: method_object(method_object {
                         trait_id: new_trait_ref.def_id,
                         object_trait_id: did,
@@ -790,8 +788,7 @@ fn search_for_autoptrd_method(&self, self_ty: ty::t, autoderefs: uint)
 
             ty_err => None,
 
-            ty_opaque_closure_ptr(_) | ty_unboxed_vec(_) |
-            ty_type | ty_infer(TyVar(_)) => {
+            ty_unboxed_vec(_) | ty_type | ty_infer(TyVar(_)) => {
                 self.bug(format!("Unexpected type: {}",
                               self.ty_to_str(self_ty)));
             }
@@ -861,7 +858,7 @@ fn consider_candidates(&self,
                            rcvr_ty: ty::t,
                            candidates: &mut ~[Candidate])
                            -> Option<method_map_entry> {
-        // XXX(pcwalton): Do we need to clone here?
+        // FIXME(pcwalton): Do we need to clone here?
         let relevant_candidates: ~[Candidate] =
             candidates.iter().map(|c| (*c).clone()).
                 filter(|c| self.is_relevant(rcvr_ty, c)).collect();
@@ -932,32 +929,25 @@ fn merge_candidates(&self, candidates: &[Candidate]) -> ~[Candidate] {
 
     fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
                              -> method_map_entry {
+        // This method performs two sets of substitutions, one after the other:
+        // 1. Substitute values for any type/lifetime parameters from the impl and
+        //    method declaration into the method type. This is the function type
+        //    before it is called; it may still include late bound region variables.
+        // 2. Instantiate any late bound lifetime parameters in the method itself
+        //    with fresh region variables.
+
         let tcx = self.tcx();
-        let fty = ty::mk_bare_fn(tcx, candidate.method_ty.fty.clone());
 
-        debug!("confirm_candidate(expr={}, candidate={}, fty={})",
+        debug!("confirm_candidate(expr={}, candidate={})",
                self.expr.repr(tcx),
-               self.cand_to_str(candidate),
-               self.ty_to_str(fty));
+               self.cand_to_str(candidate));
 
-        self.enforce_object_limitations(fty, candidate);
+        self.enforce_object_limitations(candidate);
         self.enforce_drop_trait_limitations(candidate);
 
         // static methods should never have gotten this far:
         assert!(candidate.method_ty.explicit_self != SelfStatic);
 
-        let transformed_self_ty = match candidate.origin {
-            method_object(..) => {
-                // For annoying reasons, we've already handled the
-                // substitution for object calls.
-                candidate.method_ty.transformed_self_ty.unwrap()
-            }
-            _ => {
-                ty::subst(tcx, &candidate.rcvr_substs,
-                          candidate.method_ty.transformed_self_ty.unwrap())
-            }
-        };
-
         // Determine the values for the type parameters of the method.
         // If they were not explicitly supplied, just construct fresh
         // type variables.
@@ -990,29 +980,41 @@ fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
             self_ty: candidate.rcvr_substs.self_ty,
         };
 
+        let ref bare_fn_ty = candidate.method_ty.fty;
+
         // Compute the method type with type parameters substituted
         debug!("fty={} all_substs={}",
-               self.ty_to_str(fty),
+               bare_fn_ty.repr(tcx),
                ty::substs_to_str(tcx, &all_substs));
-        let fty = ty::subst(tcx, &all_substs, fty);
-        debug!("after subst, fty={}", self.ty_to_str(fty));
 
-        // Replace any bound regions that appear in the function
-        // signature with region variables
-        let bare_fn_ty = match ty::get(fty).sty {
-            ty::ty_bare_fn(ref f) => f,
-            ref s => {
-                tcx.sess.span_bug(
-                    self.expr.span,
-                    format!("Invoking method with non-bare-fn ty: {:?}", s));
+        let fn_sig = &bare_fn_ty.sig;
+        let inputs = match candidate.origin {
+            method_object(..) => {
+                // For annoying reasons, we've already handled the
+                // substitution of self for object calls.
+                let args = fn_sig.inputs.slice_from(1).iter().map(|t| {
+                    t.subst(tcx, &all_substs)
+                });
+                Some(fn_sig.inputs[0]).move_iter().chain(args).collect()
             }
+            _ => fn_sig.inputs.subst(tcx, &all_substs)
         };
-        let (_, opt_transformed_self_ty, fn_sig) =
-            replace_bound_regions_in_fn_sig(
-                tcx, Some(transformed_self_ty), &bare_fn_ty.sig,
-                |br| self.fcx.infcx().next_region_var(
-                    infer::BoundRegionInFnCall(self.expr.span, br)));
-        let transformed_self_ty = opt_transformed_self_ty.unwrap();
+        let fn_sig = ty::FnSig {
+            binder_id: fn_sig.binder_id,
+            inputs: inputs,
+            output: fn_sig.output.subst(tcx, &all_substs),
+            variadic: fn_sig.variadic
+        };
+
+        debug!("after subst, fty={}", fn_sig.repr(tcx));
+
+        // Replace any bound regions that appear in the function
+        // signature with region variables
+        let (_, fn_sig) = replace_bound_regions_in_fn_sig( tcx, &fn_sig, |br| {
+            self.fcx.infcx().next_region_var(
+                infer::BoundRegionInFnCall(self.expr.span, br))
+        });
+        let transformed_self_ty = fn_sig.inputs[0];
         let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
             sig: fn_sig,
             purity: bare_fn_ty.purity,
@@ -1027,7 +1029,7 @@ fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
         // should never fail.
         match self.fcx.mk_subty(false, infer::Misc(self.self_expr.span),
                                 rcvr_ty, transformed_self_ty) {
-            result::Ok(_) => (),
+            result::Ok(_) => {}
             result::Err(_) => {
                 self.bug(format!("{} was a subtype of {} but now is not?",
                               self.ty_to_str(rcvr_ty),
@@ -1038,9 +1040,7 @@ fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
         self.fcx.write_ty(self.callee_id, fty);
         self.fcx.write_substs(self.callee_id, all_substs);
         method_map_entry {
-            self_ty: transformed_self_ty,
-            explicit_self: candidate.method_ty.explicit_self,
-            origin: candidate.origin,
+            origin: candidate.origin
         }
     }
 
@@ -1064,7 +1064,7 @@ fn construct_transformed_self_ty_for_object(
          * result to be `&'a Foo`. Assuming that `u_method` is being
          * called, we want the result to be `~Foo`. Of course,
          * this transformation has already been done as part of
-         * `method_ty.transformed_self_ty`, but there the type
+         * `method_ty.fty.sig.inputs[0]`, but there the type
          * is expressed in terms of `Self` (i.e., `&'a Self`, `~Self`).
          * Because objects are not standalone types, we can't just substitute
          * `s/Self/Foo/`, so we must instead perform this kind of hokey
@@ -1078,12 +1078,11 @@ fn construct_transformed_self_ty_for_object(
             ast::SelfStatic => {
                 self.bug(~"static method for object type receiver");
             }
-            ast::SelfValue(_) => {
+            ast::SelfValue => {
                 ty::mk_err() // error reported in `enforce_object_limitations()`
             }
-            ast::SelfRegion(..) | ast::SelfBox | ast::SelfUniq(..) => {
-                let transformed_self_ty =
-                    method_ty.transformed_self_ty.clone().unwrap();
+            ast::SelfRegion(..) | ast::SelfBox | ast::SelfUniq => {
+                let transformed_self_ty = method_ty.fty.sig.inputs[0];
                 match ty::get(transformed_self_ty).sty {
                     ty::ty_rptr(r, mt) => { // must be SelfRegion
                         ty::mk_trait(self.tcx(), trait_def_id,
@@ -1110,10 +1109,7 @@ fn construct_transformed_self_ty_for_object(
         }
     }
 
-    fn enforce_object_limitations(&self,
-                                  method_fty: ty::t,
-                                  candidate: &Candidate)
-    {
+    fn enforce_object_limitations(&self, candidate: &Candidate) {
         /*!
          * There are some limitations to calling functions through an
          * object, because (a) the self type is not known
@@ -1137,21 +1133,38 @@ fn enforce_object_limitations(&self,
                      through an object");
             }
 
-            ast::SelfValue(_) => { // reason (a) above
+            ast::SelfValue => { // reason (a) above
                 self.tcx().sess.span_err(
                     self.expr.span,
                     "cannot call a method with a by-value receiver \
                      through an object");
             }
 
-            ast::SelfRegion(..) | ast::SelfBox | ast::SelfUniq(..) => {}
+            ast::SelfRegion(..) | ast::SelfBox | ast::SelfUniq => {}
         }
 
-        if ty::type_has_self(method_fty) { // reason (a) above
-            self.tcx().sess.span_err(
-                self.expr.span,
-                "cannot call a method whose type contains a \
-                 self-type through an object");
+        // reason (a) above
+        let check_for_self_ty = |ty| {
+            if ty::type_has_self(ty) {
+                self.tcx().sess.span_err(
+                    self.expr.span,
+                    "cannot call a method whose type contains a \
+                     self-type through an object");
+                true
+            } else {
+                false
+            }
+        };
+        let ref sig = candidate.method_ty.fty.sig;
+        let mut found_self_ty = false;
+        for &input_ty in sig.inputs.iter() {
+            if check_for_self_ty(input_ty) {
+                found_self_ty = true;
+                break;
+            }
+        }
+        if !found_self_ty {
+            check_for_self_ty(sig.output);
         }
 
         if candidate.method_ty.generics.has_type_params() { // reason (b) above
@@ -1169,7 +1182,7 @@ fn enforce_drop_trait_limitations(&self, candidate: &Candidate) {
                 let destructors = self.tcx().destructors.borrow();
                 bad = destructors.get().contains(&method_id);
             }
-            // XXX: does this properly enforce this on everything now
+            // FIXME: does this properly enforce this on everything now
             // that self has been merged in? -sully
             method_param(method_param { trait_id: trait_id, .. }) |
             method_object(method_object { trait_id: trait_id, .. }) => {
@@ -1198,7 +1211,7 @@ fn is_relevant(&self, rcvr_ty: ty::t, candidate: &Candidate) -> bool {
                 false
             }
 
-            SelfValue(_) => {
+            SelfValue => {
                 rcvr_matches_ty(self.fcx, rcvr_ty, candidate)
             }
 
@@ -1234,7 +1247,7 @@ fn is_relevant(&self, rcvr_ty: ty::t, candidate: &Candidate) -> bool {
                 }
             }
 
-            SelfUniq(_) => {
+            SelfUniq => {
                 debug!("(is relevant?) explicit self is a unique pointer");
                 match ty::get(rcvr_ty).sty {
                     ty::ty_uniq(typ) => {
index 86d347fdac0d2d0f43d9917c38d29f42aae500e9..5e6e3c95692940c58df925863eee5f055a6f4e2a 100644 (file)
@@ -81,6 +81,7 @@
 use middle::lang_items::{ExchangeHeapLangItem, GcLangItem};
 use middle::lang_items::{ManagedHeapLangItem};
 use middle::lint::UnreachableCode;
+use middle::lint;
 use middle::pat_util::pat_id_map;
 use middle::pat_util;
 use middle::subst::Subst;
 pub mod demand;
 pub mod method;
 
-pub struct SelfInfo {
-    self_ty: ty::t,
-    self_id: ast::NodeId,
-    span: Span
-}
-
 /// Fields that are part of a `FnCtxt` which are inherited by
 /// closures defined within the function.  For example:
 ///
 ///     fn foo() {
-///         do bar() { ... }
+///         bar(proc() { ... })
 ///     }
 ///
 /// Here, the function `foo()` and the closure passed to
@@ -320,23 +315,21 @@ pub fn check_item_types(ccx: @CrateCtxt, crate: &ast::Crate) {
     visit::walk_crate(&mut visit, crate, ());
 }
 
-pub fn check_bare_fn(ccx: @CrateCtxt,
-                     decl: &ast::FnDecl,
-                     body: &ast::Block,
-                     id: ast::NodeId,
-                     self_info: Option<SelfInfo>,
-                     fty: ty::t,
-                     param_env: ty::ParameterEnvironment) {
+fn check_bare_fn(ccx: @CrateCtxt,
+                 decl: &ast::FnDecl,
+                 body: &ast::Block,
+                 id: ast::NodeId,
+                 fty: ty::t,
+                 param_env: ty::ParameterEnvironment) {
     match ty::get(fty).sty {
         ty::ty_bare_fn(ref fn_ty) => {
             let fcx =
-                check_fn(ccx, self_info, fn_ty.purity,
-                         &fn_ty.sig, decl, id, body, Vanilla,
-                         @Inherited::new(ccx.tcx, param_env));
+                check_fn(ccx, fn_ty.purity, &fn_ty.sig, decl, id, body,
+                         Vanilla, @Inherited::new(ccx.tcx, param_env));
 
             vtable::resolve_in_block(fcx, body);
             regionck::regionck_fn(fcx, body);
-            writeback::resolve_type_vars_in_fn(fcx, decl, body, self_info);
+            writeback::resolve_type_vars_in_fn(fcx, decl, body);
         }
         _ => ccx.tcx.sess.impossible_case(body.span,
                                  "check_bare_fn: function type expected")
@@ -419,15 +412,14 @@ fn visit_item(&mut self, _: &ast::Item, _: ()) { }
 
 }
 
-pub fn check_fn(ccx: @CrateCtxt,
-                opt_self_info: Option<SelfInfo>,
-                purity: ast::Purity,
-                fn_sig: &ty::FnSig,
-                decl: &ast::FnDecl,
-                id: ast::NodeId,
-                body: &ast::Block,
-                fn_kind: FnKind,
-                inherited: @Inherited) -> @FnCtxt
+fn check_fn(ccx: @CrateCtxt,
+            purity: ast::Purity,
+            fn_sig: &ty::FnSig,
+            decl: &ast::FnDecl,
+            id: ast::NodeId,
+            body: &ast::Block,
+            fn_kind: FnKind,
+            inherited: @Inherited) -> @FnCtxt
 {
     /*!
      * Helper used by check_bare_fn and check_expr_fn.  Does the
@@ -442,99 +434,44 @@ pub fn check_fn(ccx: @CrateCtxt,
     let tcx = ccx.tcx;
     let err_count_on_creation = tcx.sess.err_count();
 
-    // First, we have to replace any bound regions in the fn and self
-    // types with free ones.  The free region references will be bound
-    // the node_id of the body block.
-    let (opt_self_info, fn_sig) = {
-        let opt_self_ty = opt_self_info.map(|i| i.self_ty);
-        let (_, opt_self_ty, fn_sig) =
-            replace_bound_regions_in_fn_sig(
-                tcx, opt_self_ty, fn_sig,
-                |br| ty::ReFree(ty::FreeRegion {scope_id: body.id,
-                                                 bound_region: br}));
-        let opt_self_info =
-            opt_self_info.map(
-                |si| SelfInfo {self_ty: opt_self_ty.unwrap(), .. si});
-        (opt_self_info, fn_sig)
-    };
+    // First, we have to replace any bound regions in the fn type with free ones.
+    // The free region references will be bound the node_id of the body block.
+    let (_, fn_sig) = replace_bound_regions_in_fn_sig(tcx, fn_sig, |br| {
+        ty::ReFree(ty::FreeRegion {scope_id: body.id, bound_region: br})
+    });
 
-    relate_free_regions(tcx, opt_self_info.map(|s| s.self_ty), &fn_sig);
+    relate_free_regions(tcx, &fn_sig);
 
-    let arg_tys = fn_sig.inputs.map(|a| *a);
+    let arg_tys = fn_sig.inputs.as_slice();
     let ret_ty = fn_sig.output;
 
-    debug!("check_fn(arg_tys={:?}, ret_ty={:?}, opt_self_ty={:?})",
+    debug!("check_fn(arg_tys={:?}, ret_ty={:?})",
            arg_tys.map(|&a| ppaux::ty_to_str(tcx, a)),
-           ppaux::ty_to_str(tcx, ret_ty),
-           opt_self_info.map(|si| ppaux::ty_to_str(tcx, si.self_ty)));
+           ppaux::ty_to_str(tcx, ret_ty));
 
     // Create the function context.  This is either derived from scratch or,
     // in the case of function expressions, based on the outer context.
-    let fcx: @FnCtxt = {
-        @FnCtxt {
-            err_count_on_creation: err_count_on_creation,
-            ret_ty: ret_ty,
-            ps: RefCell::new(PurityState::function(purity, id)),
-            region_lb: Cell::new(body.id),
-            fn_kind: fn_kind,
-            inh: inherited,
-            ccx: ccx
-        }
+    let fcx = @FnCtxt {
+        err_count_on_creation: err_count_on_creation,
+        ret_ty: ret_ty,
+        ps: RefCell::new(PurityState::function(purity, id)),
+        region_lb: Cell::new(body.id),
+        fn_kind: fn_kind,
+        inh: inherited,
+        ccx: ccx
     };
 
-    gather_locals(fcx, decl, body, arg_tys, opt_self_info);
-    check_block_with_expected(fcx, body, Some(ret_ty));
-
-    // We unify the tail expr's type with the
-    // function result type, if there is a tail expr.
-    match body.expr {
-      Some(tail_expr) => {
-        let tail_expr_ty = fcx.expr_ty(tail_expr);
-        // Special case: we print a special error if there appears
-        // to be do-block/for-loop confusion
-        demand::suptype_with_fn(fcx, tail_expr.span, false,
-            fcx.ret_ty, tail_expr_ty,
-            |sp, e, a, s| {
-                fcx.report_mismatched_return_types(sp, e, a, s) });
-      }
-      None => ()
-    }
-
-    for self_info in opt_self_info.iter() {
-        fcx.write_ty(self_info.self_id, self_info.self_ty);
-    }
-    for (input, arg) in decl.inputs.iter().zip(arg_tys.iter()) {
-        fcx.write_ty(input.id, *arg);
-    }
-
-    return fcx;
-
-    fn gather_locals(fcx: @FnCtxt,
-                     decl: &ast::FnDecl,
-                     body: &ast::Block,
-                     arg_tys: &[ty::t],
-                     opt_self_info: Option<SelfInfo>) {
-        let tcx = fcx.ccx.tcx;
+    {
 
         let mut visit = GatherLocalsVisitor { fcx: fcx, tcx: tcx, };
-
-        // Add the self parameter
-        for self_info in opt_self_info.iter() {
-            visit.assign(self_info.self_id, Some(self_info.self_ty));
-            let locals = fcx.inh.locals.borrow();
-            debug!("self is assigned to {}",
-                   fcx.infcx().ty_to_str(
-                       locals.get().get_copy(&self_info.self_id)));
-        }
-
         // Add formal parameters.
         for (arg_ty, input) in arg_tys.iter().zip(decl.inputs.iter()) {
             // Create type variables for each argument.
             pat_util::pat_bindings(tcx.def_map,
                                    input.pat,
                                    |_bm, pat_id, _sp, _path| {
-                visit.assign(pat_id, None);
-            });
+                                       visit.assign(pat_id, None);
+                                   });
 
             // Check the pattern.
             let pcx = pat_ctxt {
@@ -546,6 +483,29 @@ fn gather_locals(fcx: @FnCtxt,
 
         visit.visit_block(body, ());
     }
+
+    check_block_with_expected(fcx, body, Some(ret_ty));
+
+    // We unify the tail expr's type with the
+    // function result type, if there is a tail expr.
+    match body.expr {
+        Some(tail_expr) => {
+            // Special case: we print a special error if there appears
+            // to be do-block/for-loop confusion
+            demand::suptype_with_fn(fcx, tail_expr.span, false,
+                fcx.ret_ty, fcx.expr_ty(tail_expr),
+                |sp, e, a, s| {
+                    fcx.report_mismatched_return_types(sp, e, a, s);
+                });
+        }
+        None => {}
+    }
+
+    for (input, arg) in decl.inputs.iter().zip(arg_tys.iter()) {
+        fcx.write_ty(input.id, *arg);
+    }
+
+    fcx
 }
 
 pub fn check_no_duplicate_fields(tcx: ty::ctxt,
@@ -572,7 +532,10 @@ pub fn check_no_duplicate_fields(tcx: ty::ctxt,
 pub fn check_struct(ccx: @CrateCtxt, id: ast::NodeId, span: Span) {
     let tcx = ccx.tcx;
 
-    // Check that the class is instantiable
+    // Check that the struct is representable
+    check_representable(tcx, span, id, "struct");
+
+    // Check that the struct is instantiable
     check_instantiable(tcx, span, id);
 
     if ty::lookup_simd(tcx, local_def(id)) {
@@ -606,7 +569,7 @@ pub fn check_item(ccx: @CrateCtxt, it: &ast::Item) {
                 [],
                 body.id);
 
-        check_bare_fn(ccx, decl, body, it.id, None, fn_tpt.ty, param_env);
+        check_bare_fn(ccx, decl, body, it.id, fn_tpt.ty, param_env);
       }
       ast::ItemImpl(_, ref opt_trait_ref, _, ref ms) => {
         debug!("ItemImpl {} with id {}", ccx.tcx.sess.str_of(it.ident), it.id);
@@ -716,23 +679,11 @@ fn check_method_body(ccx: @CrateCtxt,
             item_generics.region_param_defs,
             method.body.id);
 
-    // Compute the self type and fty from point of view of inside fn
-    let opt_self_info = method_ty.transformed_self_ty.map(|ty| {
-        SelfInfo {self_ty: ty.subst(ccx.tcx, &param_env.free_substs),
-                  self_id: method.self_id,
-                  span: method.explicit_self.span}
-    });
+    // Compute the fty from point of view of inside fn
     let fty = ty::node_id_to_type(ccx.tcx, method.id);
     let fty = fty.subst(ccx.tcx, &param_env.free_substs);
 
-    check_bare_fn(
-        ccx,
-        method.decl,
-        method.body,
-        method.id,
-        opt_self_info,
-        fty,
-        param_env);
+    check_bare_fn(ccx, method.decl, method.body, method.id, fty, param_env);
 }
 
 fn check_impl_methods_against_trait(ccx: @CrateCtxt,
@@ -815,13 +766,13 @@ fn check_impl_methods_against_trait(ccx: @CrateCtxt,
  * - trait_m: the method in the trait
  * - trait_substs: the substitutions used on the type of the trait
  */
-pub fn compare_impl_method(tcx: ty::ctxt,
-                           impl_generics: &ty::Generics,
-                           impl_m: @ty::Method,
-                           impl_m_span: Span,
-                           impl_m_body_id: ast::NodeId,
-                           trait_m: &ty::Method,
-                           trait_substs: &ty::substs) {
+fn compare_impl_method(tcx: ty::ctxt,
+                       impl_generics: &ty::Generics,
+                       impl_m: @ty::Method,
+                       impl_m_span: Span,
+                       impl_m_body_id: ast::NodeId,
+                       trait_m: &ty::Method,
+                       trait_substs: &ty::substs) {
     debug!("compare_impl_method()");
     let infcx = infer::new_infer_ctxt(tcx);
 
@@ -953,52 +904,10 @@ pub fn compare_impl_method(tcx: ty::ctxt,
         regions: ty::NonerasedRegions(dummy_impl_regions),
         self_ty: None };
 
-    // We are going to create a synthetic fn type that includes
-    // both the method's self argument and its normal arguments.
-    // So a method like `fn(&self, a: uint)` would be converted
-    // into a function `fn(self: &T, a: uint)`.
-    let mut trait_fn_args = ~[];
-    let mut impl_fn_args = ~[];
-
-    // For both the trait and the impl, create an argument to
-    // represent the self argument (unless this is a static method).
-    // This argument will have the *transformed* self type.
-    for &t in trait_m.transformed_self_ty.iter() {
-        trait_fn_args.push(t);
-    }
-    for &t in impl_m.transformed_self_ty.iter() {
-        impl_fn_args.push(t);
-    }
-
-    // Add in the normal arguments.
-    trait_fn_args.push_all(trait_m.fty.sig.inputs);
-    impl_fn_args.push_all(impl_m.fty.sig.inputs);
-
-    // Create a bare fn type for trait/impl that includes self argument
-    let trait_fty =
-        ty::mk_bare_fn(tcx,
-                       ty::BareFnTy {
-                            purity: trait_m.fty.purity,
-                            abis: trait_m.fty.abis,
-                            sig: ty::FnSig {
-                                binder_id: trait_m.fty.sig.binder_id,
-                                inputs: trait_fn_args,
-                                output: trait_m.fty.sig.output,
-                                variadic: false
-                            }
-                        });
-    let impl_fty =
-        ty::mk_bare_fn(tcx,
-                       ty::BareFnTy {
-                            purity: impl_m.fty.purity,
-                            abis: impl_m.fty.abis,
-                            sig: ty::FnSig {
-                                binder_id: impl_m.fty.sig.binder_id,
-                                inputs: impl_fn_args,
-                                output: impl_m.fty.sig.output,
-                                variadic: false
-                            }
-                        });
+    // Create a bare fn type for trait/impl
+    // It'd be nice to refactor so as to provide the bare fn types instead.
+    let trait_fty = ty::mk_bare_fn(tcx, trait_m.fty.clone());
+    let impl_fty = ty::mk_bare_fn(tcx, impl_m.fty.clone());
 
     // Perform substitutions so that the trait/impl methods are expressed
     // in terms of the same set of type/region parameters:
@@ -1592,32 +1501,55 @@ fn check_type_parameter_positions_in_path(function_context: @FnCtxt,
             // Make sure the number of type parameters supplied on the trait
             // or implementation segment equals the number of type parameters
             // on the trait or implementation definition.
-            let trait_type_parameter_count = generics.type_param_defs.len();
-            let supplied_type_parameter_count = trait_segment.types.len();
-            if trait_type_parameter_count != supplied_type_parameter_count {
-                let trait_count_suffix = if trait_type_parameter_count == 1 {
+            let formal_ty_param_count = generics.type_param_defs.len();
+            let required_ty_param_count = generics.type_param_defs.iter()
+                                                  .take_while(|x| x.default.is_none())
+                                                  .len();
+            let supplied_ty_param_count = trait_segment.types.len();
+            if supplied_ty_param_count < required_ty_param_count {
+                let trait_count_suffix = if required_ty_param_count == 1 {
                     ""
                 } else {
                     "s"
                 };
-                let supplied_count_suffix =
-                    if supplied_type_parameter_count == 1 {
-                        ""
-                    } else {
-                        "s"
-                    };
-                function_context.tcx()
-                                .sess
-                                .span_err(path.span,
-                                          format!("the {} referenced by this \
-                                                path has {} type \
-                                                parameter{}, but {} type \
-                                                parameter{} were supplied",
-                                               name,
-                                               trait_type_parameter_count,
-                                               trait_count_suffix,
-                                               supplied_type_parameter_count,
-                                               supplied_count_suffix))
+                let supplied_count_suffix = if supplied_ty_param_count == 1 {
+                    ""
+                } else {
+                    "s"
+                };
+                let needs = if required_ty_param_count < generics.type_param_defs.len() {
+                    "needs at least"
+                } else {
+                    "needs"
+                };
+                function_context.tcx().sess.span_err(path.span,
+                    format!("the {} referenced by this path {} {} type \
+                            parameter{}, but {} type parameter{} were supplied",
+                            name, needs,
+                            required_ty_param_count, trait_count_suffix,
+                            supplied_ty_param_count, supplied_count_suffix))
+            } else if supplied_ty_param_count > formal_ty_param_count {
+                let trait_count_suffix = if formal_ty_param_count == 1 {
+                    ""
+                } else {
+                    "s"
+                };
+                let supplied_count_suffix = if supplied_ty_param_count == 1 {
+                    ""
+                } else {
+                    "s"
+                };
+                let needs = if required_ty_param_count < generics.type_param_defs.len() {
+                    "needs at most"
+                } else {
+                    "needs"
+                };
+                function_context.tcx().sess.span_err(path.span,
+                    format!("the {} referenced by this path {} {} type \
+                            parameter{}, but {} type parameter{} were supplied",
+                            name, needs,
+                            formal_ty_param_count, trait_count_suffix,
+                            supplied_ty_param_count, supplied_count_suffix))
             }
         }
         _ => {
@@ -1669,6 +1601,8 @@ fn check_method_argument_types(
         sugar: ast::CallSugar,
         deref_args: DerefArgs) -> ty::t
     {
+        // HACK(eddyb) ignore provided self (it has special typeck rules).
+        let args = args.slice_from(1);
         if ty::type_is_error(method_fn_ty) {
             let err_inputs = err_args(args.len());
             check_argument_types(fcx, sp, err_inputs, callee_expr,
@@ -1677,8 +1611,10 @@ fn check_method_argument_types(
         } else {
             match ty::get(method_fn_ty).sty {
                 ty::ty_bare_fn(ref fty) => {
-                    check_argument_types(fcx, sp, fty.sig.inputs, callee_expr,
-                                         args, sugar, deref_args, fty.sig.variadic);
+                    // HACK(eddyb) ignore self in the definition (see above).
+                    check_argument_types(fcx, sp, fty.sig.inputs.slice_from(1),
+                                         callee_expr, args, sugar, deref_args,
+                                         fty.sig.variadic);
                     fty.sig.output
                 }
                 _ => {
@@ -1731,8 +1667,6 @@ fn check_argument_types(fcx: @FnCtxt,
         } else {
             let suffix = match sugar {
                 ast::NoSugar => "",
-                ast::DoSugar => " (including the closure passed by \
-                                 the `do` keyword)",
                 ast::ForSugar => " (including the closure passed by \
                                   the `for` keyword)"
             };
@@ -1781,8 +1715,7 @@ fn check_argument_types(fcx: @FnCtxt,
             for (i, arg) in args.iter().take(t).enumerate() {
                 let is_block = match arg.node {
                     ast::ExprFnBlock(..) |
-                    ast::ExprProc(..) |
-                    ast::ExprDoBody(..) => true,
+                    ast::ExprProc(..) => true,
                     _ => false
                 };
 
@@ -1923,13 +1856,10 @@ fn check_call(fcx: @FnCtxt,
 
         // Replace any bound regions that appear in the function
         // signature with region variables
-        let (_, _, fn_sig) =
-            replace_bound_regions_in_fn_sig(fcx.tcx(),
-                                            None,
-                                            fn_sig,
-                                            |br| fcx.infcx()
-                                                    .next_region_var(
-                    infer::BoundRegionInFnCall(call_expr.span, br)));
+        let (_, fn_sig) = replace_bound_regions_in_fn_sig(fcx.tcx(), fn_sig, |br| {
+            fcx.infcx()
+               .next_region_var(infer::BoundRegionInFnCall(call_expr.span, br))
+        });
 
         // Call the generic checker.
         check_argument_types(fcx, call_expr.span, fn_sig.inputs, f,
@@ -1942,11 +1872,11 @@ fn check_call(fcx: @FnCtxt,
     fn check_method_call(fcx: @FnCtxt,
                          callee_id: ast::NodeId,
                          expr: &ast::Expr,
-                         rcvr: &ast::Expr,
                          method_name: ast::Ident,
                          args: &[@ast::Expr],
                          tps: &[ast::P<ast::Ty>],
                          sugar: ast::CallSugar) {
+        let rcvr = args[0];
         check_expr(fcx, rcvr);
 
         // no need to check for bot/err -- callee does that
@@ -2042,7 +1972,6 @@ fn check_then_else(fcx: @FnCtxt,
     fn lookup_op_method(fcx: @FnCtxt,
                         callee_id: ast::NodeId,
                         op_ex: &ast::Expr,
-                        self_ex: &ast::Expr,
                         self_t: ty::t,
                         opname: ast::Name,
                         args: &[@ast::Expr],
@@ -2052,7 +1981,7 @@ fn lookup_op_method(fcx: @FnCtxt,
                         _expected_result: Option<ty::t>
                        )
                      -> ty::t {
-        match method::lookup(fcx, op_ex, self_ex,
+        match method::lookup(fcx, op_ex, args[0],
                              callee_id, opname, self_t, [],
                              deref_args, CheckTraitsOnly, autoderef_receiver) {
             Some(ref origin) => {
@@ -2084,7 +2013,7 @@ fn check_binop(fcx: @FnCtxt,
                    callee_id: ast::NodeId,
                    expr: &ast::Expr,
                    op: ast::BinOp,
-                   lhs: &ast::Expr,
+                   lhs: @ast::Expr,
                    rhs: @ast::Expr,
                    // Used only in the error case
                    expected_result: Option<ty::t>,
@@ -2172,7 +2101,7 @@ fn check_binop(fcx: @FnCtxt,
     fn check_user_binop(fcx: @FnCtxt,
                         callee_id: ast::NodeId,
                         ex: &ast::Expr,
-                        lhs_expr: &ast::Expr,
+                        lhs_expr: @ast::Expr,
                         lhs_resolved_t: ty::t,
                         op: ast::BinOp,
                         rhs: @ast::Expr,
@@ -2187,10 +2116,10 @@ fn check_user_binop(fcx: @FnCtxt,
                              ast_util::binop_to_str(op), actual)},
                             lhs_resolved_t, None)
                 };
-                return lookup_op_method(fcx, callee_id, ex, lhs_expr, lhs_resolved_t,
-                                       token::intern(*name),
-                                       &[rhs], DoDerefArgs, DontAutoderefReceiver, if_op_unbound,
-                                       expected_result);
+                return lookup_op_method(fcx, callee_id, ex, lhs_resolved_t,
+                                        token::intern(*name), [lhs_expr, rhs],
+                                        DoDerefArgs,DontAutoderefReceiver,
+                                        if_op_unbound, expected_result);
             }
             None => ()
         };
@@ -2216,14 +2145,13 @@ fn check_user_unop(fcx: @FnCtxt,
                        op_str: &str,
                        mname: &str,
                        ex: &ast::Expr,
-                       rhs_expr: &ast::Expr,
+                       rhs_expr: @ast::Expr,
                        rhs_t: ty::t,
                        expected_t: Option<ty::t>)
                     -> ty::t {
        lookup_op_method(
-            fcx, callee_id, ex, rhs_expr, rhs_t,
-            token::intern(mname), &[],
-            DoDerefArgs, DontAutoderefReceiver,
+            fcx, callee_id, ex, rhs_t, token::intern(mname),
+            [rhs_expr], DoDerefArgs, DontAutoderefReceiver,
             || {
                 fcx.type_error_message(ex.span, |actual| {
                     format!("cannot apply unary operator `{}` to type `{}`",
@@ -2280,9 +2208,9 @@ fn check_expr_fn(fcx: @FnCtxt,
              expected_bounds) = {
             match expected_sty {
                 Some(ty::ty_closure(ref cenv)) => {
-                    let (_, _, sig) =
+                    let (_, sig) =
                         replace_bound_regions_in_fn_sig(
-                            tcx, None, &cenv.sig,
+                            tcx, &cenv.sig,
                             |_| fcx.inh.infcx.fresh_bound_region(expr.id));
                     (Some(sig), cenv.purity, cenv.sigil,
                      cenv.onceness, cenv.bounds)
@@ -2352,7 +2280,7 @@ fn check_expr_fn(fcx: @FnCtxt,
                                            (purity, expr.id),
                                            sigil);
 
-        check_fn(fcx.ccx, None, inherited_purity, &fty_sig,
+        check_fn(fcx.ccx, inherited_purity, &fty_sig,
                  decl, id, body, fn_kind, fcx.inh);
     }
 
@@ -2691,7 +2619,7 @@ fn check_struct_enum_variant(fcx: @FnCtxt,
           let mut checked = false;
           match place.node {
               ast::ExprPath(ref path) => {
-                  // XXX(pcwalton): For now we hardcode the two permissible
+                  // FIXME(pcwalton): For now we hardcode the two permissible
                   // places: the exchange heap and the managed heap.
                   let definition = lookup_def(fcx, path.span, place.id);
                   let def_id = ast_util::def_id_of_def(definition);
@@ -2916,12 +2844,6 @@ fn check_struct_enum_variant(fcx: @FnCtxt,
         let tpt = ty_param_bounds_and_ty_for_def(fcx, expr.span, defn);
         instantiate_path(fcx, pth, tpt, defn, expr.span, expr.id);
       }
-      ast::ExprSelf => {
-        let definition = lookup_def(fcx, expr.span, id);
-        let ty_param_bounds_and_ty =
-            ty_param_bounds_and_ty_for_def(fcx, expr.span, definition);
-        fcx.write_ty(id, ty_param_bounds_and_ty.ty);
-      }
       ast::ExprInlineAsm(ref ia) => {
           for &(_, input) in ia.inputs.iter() {
               check_expr(fcx, input);
@@ -3030,44 +2952,6 @@ fn check_struct_enum_variant(fcx: @FnCtxt,
                       Vanilla,
                       expected);
       }
-      ast::ExprDoBody(b) => {
-        let expected_sty = unpack_expected(fcx,
-                                           expected,
-                                           |x| Some((*x).clone()));
-        let inner_ty = match expected_sty {
-            Some(ty::ty_closure(ref closure_ty))
-                    if closure_ty.sigil == ast::OwnedSigil => {
-                expected.unwrap()
-            }
-            _ => match expected {
-                Some(expected_t) => {
-                    fcx.type_error_message(expr.span, |actual| {
-                        format!("last argument in `do` call \
-                              has non-procedure type: {}",
-                             actual)
-                    }, expected_t, None);
-                    let err_ty = ty::mk_err();
-                    fcx.write_ty(id, err_ty);
-                    err_ty
-                }
-                None => {
-                    fcx.tcx().sess.impossible_case(
-                        expr.span,
-                        "do body must have expected type")
-                }
-            }
-        };
-        match b.node {
-          ast::ExprFnBlock(decl, body) => {
-            check_expr_fn(fcx, b, None,
-                          decl, body, DoBlock, Some(inner_ty));
-            demand::suptype(fcx, b.span, inner_ty, fcx.expr_ty(b));
-          }
-          // argh
-          _ => fail!("expected fn ty")
-        }
-        fcx.write_ty(expr.id, fcx.node_ty(b.id));
-      }
       ast::ExprBlock(b) => {
         check_block_with_expected(fcx, b, expected);
         fcx.write_ty(id, fcx.node_ty(b.id));
@@ -3088,18 +2972,16 @@ fn check_struct_enum_variant(fcx: @FnCtxt,
               fcx.write_bot(id);
           }
       }
-      ast::ExprMethodCall(callee_id, rcvr, ident, ref tps, ref args, sugar) => {
-        check_method_call(fcx, callee_id, expr, rcvr, ident, *args, *tps, sugar);
-        let f_ty = fcx.expr_ty(rcvr);
+      ast::ExprMethodCall(callee_id, ident, ref tps, ref args, sugar) => {
+        check_method_call(fcx, callee_id, expr, ident, *args, *tps, sugar);
         let arg_tys = args.map(|a| fcx.expr_ty(*a));
         let (args_bot, args_err) = arg_tys.iter().fold((false, false),
              |(rest_bot, rest_err), a| {
               (rest_bot || ty::type_is_bot(*a),
                rest_err || ty::type_is_error(*a))});
-        if ty::type_is_error(f_ty) || args_err {
+        if args_err {
             fcx.write_error(id);
-        }
-        else if ty::type_is_bot(f_ty) || args_bot {
+        } else if args_bot {
             fcx.write_bot(id);
         }
       }
@@ -3327,10 +3209,9 @@ fn types_compatible(fcx: @FnCtxt, sp: Span,
                       let ret_ty = lookup_op_method(fcx,
                                                     callee_id,
                                                     expr,
-                                                    base,
                                                     resolved,
                                                     index_ident.name,
-                                                    &[idx],
+                                                    [base, idx],
                                                     DoDerefArgs,
                                                     AutoderefReceiver,
                                                     error_message,
@@ -3556,6 +3437,33 @@ pub fn check_const_with_ty(fcx: @FnCtxt,
     writeback::resolve_type_vars_in_expr(fcx, e);
 }
 
+/// Checks whether a type can be represented in memory. In particular, it
+/// identifies types that contain themselves without indirection through a
+/// pointer, which would mean their size is unbounded. This is different from
+/// the question of whether a type can be instantiated. See the definition of
+/// `check_instantiable`.
+pub fn check_representable(tcx: ty::ctxt,
+                           sp: Span,
+                           item_id: ast::NodeId,
+                           designation: &str) {
+    let rty = ty::node_id_to_type(tcx, item_id);
+
+    // Check that it is possible to represent this type. This call identifies
+    // (1) types that contain themselves and (2) types that contain a different
+    // recursive type. It is only necessary to throw an error on those that
+    // contain themselves. For case 2, there must be an inner type that will be
+    // caught by case 1.
+    match ty::is_type_representable(tcx, rty) {
+      ty::SelfRecursive => {
+        tcx.sess.span_err(
+          sp, format!("illegal recursive {} type; \
+                       wrap the inner value in a box to make it representable",
+                      designation));
+      }
+      ty::Representable | ty::ContainsRecursive => (),
+    }
+}
+
 /// Checks whether a type can be created without an instance of itself.
 /// This is similar but different from the question of whether a type
 /// can be represented.  For example, the following type:
@@ -3711,7 +3619,6 @@ fn do_check(ccx: @CrateCtxt,
         return variants;
     }
 
-    let rty = ty::node_id_to_type(ccx.tcx, id);
     let hint = ty::lookup_repr_hint(ccx.tcx, ast::DefId { crate: ast::LOCAL_CRATE, node: id });
     if hint != attr::ReprAny && vs.len() <= 1 {
         ccx.tcx.sess.span_err(sp, format!("unsupported representation for {}variant enum",
@@ -3726,22 +3633,8 @@ fn do_check(ccx: @CrateCtxt,
         enum_var_cache.get().insert(local_def(id), @variants);
     }
 
-    // Check that it is possible to represent this enum:
-    let mut outer = true;
-    let did = local_def(id);
-    if ty::type_structurally_contains(ccx.tcx, rty, |sty| {
-        match *sty {
-          ty::ty_enum(id, _) if id == did => {
-            if outer { outer = false; false }
-            else { true }
-          }
-          _ => false
-        }
-    }) {
-        ccx.tcx.sess.span_err(sp,
-                              "illegal recursive enum type; \
-                               wrap the inner value in a box to make it representable");
-    }
+    // Check that it is possible to represent this enum.
+    check_representable(ccx.tcx, sp, id, "enum");
 
     // Check that it is possible to instantiate this enum:
     //
@@ -3760,7 +3653,7 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: @FnCtxt,
                                       defn: ast::Def)
                                    -> ty_param_bounds_and_ty {
     match defn {
-      ast::DefArg(nid, _) | ast::DefLocal(nid, _) | ast::DefSelf(nid, _) |
+      ast::DefArg(nid, _) | ast::DefLocal(nid, _) |
       ast::DefBinding(nid, _) => {
           let typ = fcx.local_ty(sp, nid);
           return no_params(typ);
@@ -3814,6 +3707,9 @@ pub fn instantiate_path(fcx: @FnCtxt,
     debug!(">>> instantiate_path");
 
     let ty_param_count = tpt.generics.type_param_defs.len();
+    let ty_param_req = tpt.generics.type_param_defs.iter()
+                                                   .take_while(|x| x.default.is_none())
+                                                   .len();
     let mut ty_substs_len = 0;
     for segment in pth.segments.iter() {
         ty_substs_len += segment.types.len()
@@ -3851,13 +3747,13 @@ pub fn instantiate_path(fcx: @FnCtxt,
     // Here we calculate the "user type parameter count", which is the number
     // of type parameters actually manifest in the AST. This will differ from
     // the internal type parameter count when there are self types involved.
-    let (user_type_parameter_count, self_parameter_index) = match def {
+    let (user_ty_param_count, user_ty_param_req, self_parameter_index) = match def {
         ast::DefStaticMethod(_, provenance @ ast::FromTrait(_), _) => {
             let generics = generics_of_static_method_container(fcx.ccx.tcx,
                                                                provenance);
-            (ty_param_count - 1, Some(generics.type_param_defs.len()))
+            (ty_param_count - 1, ty_param_req - 1, Some(generics.type_param_defs.len()))
         }
-        _ => (ty_param_count, None),
+        _ => (ty_param_count, ty_param_req, None),
     };
 
     // determine values for type parameters, using the values given by
@@ -3868,27 +3764,55 @@ pub fn instantiate_path(fcx: @FnCtxt,
         fcx.ccx.tcx.sess.span_err
             (span, "this item does not take type parameters");
         fcx.infcx().next_ty_vars(ty_param_count)
-    } else if ty_substs_len > user_type_parameter_count {
+    } else if ty_substs_len > user_ty_param_count {
+        let expected = if user_ty_param_req < user_ty_param_count {
+            "expected at most"
+        } else {
+            "expected"
+        };
         fcx.ccx.tcx.sess.span_err
             (span,
-             format!("too many type parameters provided: expected {}, found {}",
-                  user_type_parameter_count, ty_substs_len));
+             format!("too many type parameters provided: {} {}, found {}",
+                  expected, user_ty_param_count, ty_substs_len));
         fcx.infcx().next_ty_vars(ty_param_count)
-    } else if ty_substs_len < user_type_parameter_count {
+    } else if ty_substs_len < user_ty_param_req {
+        let expected = if user_ty_param_req < user_ty_param_count {
+            "expected at least"
+        } else {
+            "expected"
+        };
         fcx.ccx.tcx.sess.span_err
             (span,
-             format!("not enough type parameters provided: expected {}, found {}",
-                  user_type_parameter_count, ty_substs_len));
+             format!("not enough type parameters provided: {} {}, found {}",
+                  expected, user_ty_param_req, ty_substs_len));
         fcx.infcx().next_ty_vars(ty_param_count)
     } else {
+        if ty_substs_len > user_ty_param_req {
+            fcx.tcx().sess.add_lint(lint::DefaultTypeParamUsage, node_id, pth.span,
+                                    ~"provided type arguments with defaults");
+        }
+
         // Build up the list of type parameters, inserting the self parameter
         // at the appropriate position.
         let mut result = ~[];
         let mut pushed = false;
-        for (i, &ast_type) in pth.segments
-                                .iter()
-                                .flat_map(|segment| segment.types.iter())
-                                .enumerate() {
+        let defaults = tpt.generics.type_param_defs.iter()
+                          .enumerate().filter_map(|(i, x)| {
+            match self_parameter_index {
+                Some(index) if index == i => None,
+                _ => Some(x.default)
+            }
+        }).skip(ty_substs_len).map(|x| match x {
+            Some(default) => default,
+            None => {
+                fcx.tcx().sess.span_bug(span,
+                    "missing default for a not explicitely provided type param")
+            }
+        });
+        for (i, ty) in pth.segments.iter()
+                                   .flat_map(|segment| segment.types.iter())
+                                   .map(|&ast_type| fcx.to_ty(ast_type))
+                                   .chain(defaults).enumerate() {
             match self_parameter_index {
                 Some(index) if index == i => {
                     result.push(fcx.infcx().next_ty_vars(1)[0]);
@@ -3896,7 +3820,7 @@ pub fn instantiate_path(fcx: @FnCtxt,
                 }
                 _ => {}
             }
-            result.push(fcx.to_ty(ast_type))
+            result.push(ty)
         }
 
         // If the self parameter goes at the end, insert it there.
index b21f2c7463055b35da9ae09a30b668b4b451a467..f134fb3b6ae85d842d87d54ef10500a26aada8f2 100644 (file)
@@ -41,7 +41,7 @@
 use util::ppaux::{ty_to_str, region_to_str, Repr};
 
 use syntax::ast::{ManagedSigil, OwnedSigil, BorrowedSigil};
-use syntax::ast::{DefArg, DefBinding, DefLocal, DefSelf, DefUpvar};
+use syntax::ast::{DefArg, DefBinding, DefLocal, DefUpvar};
 use syntax::ast;
 use syntax::codemap::Span;
 use syntax::visit;
@@ -64,7 +64,7 @@ fn region_of_def(fcx: @FnCtxt, def: ast::Def) -> ty::Region {
     let tcx = fcx.tcx();
     match def {
         DefLocal(node_id, _) | DefArg(node_id, _) |
-        DefSelf(node_id, _) | DefBinding(node_id, _) => {
+        DefBinding(node_id, _) => {
             tcx.region_maps.var_region(node_id)
         }
         DefUpvar(_, subdef, closure_id, body_id) => {
@@ -316,8 +316,9 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
             visit::walk_expr(rcx, expr, ());
         }
 
-        ast::ExprMethodCall(callee_id, arg0, _, _, ref args, _) => {
-            constrain_call(rcx, callee_id, expr, Some(arg0), *args, false);
+        ast::ExprMethodCall(callee_id, _, _, ref args, _) => {
+            constrain_call(rcx, callee_id, expr, Some(args[0]),
+                           args.slice_from(1), false);
 
             visit::walk_expr(rcx, expr, ());
         }
@@ -1012,12 +1013,10 @@ fn guarantor(rcx: &mut Rcx, expr: &ast::Expr) -> Option<ty::Region> {
                 guarantor(rcx, e)
             }
 
-            ast::ExprPath(..) | ast::ExprSelf => {
-                // Either a variable or constant and hence resides
-                // in constant memory or on the stack frame.  Either way,
-                // not guaranteed by a region pointer.
-                None
-            }
+            // Either a variable or constant and hence resides
+            // in constant memory or on the stack frame.  Either way,
+            // not guaranteed by a region pointer.
+            ast::ExprPath(..) => None,
 
             // All of these expressions are rvalues and hence their
             // value is not guaranteed by a region pointer.
@@ -1046,7 +1045,6 @@ fn guarantor(rcx: &mut Rcx, expr: &ast::Expr) -> Option<ty::Region> {
             ast::ExprMatch(..) |
             ast::ExprFnBlock(..) |
             ast::ExprProc(..) |
-            ast::ExprDoBody(..) |
             ast::ExprBlock(..) |
             ast::ExprRepeat(..) |
             ast::ExprVec(..) => {
index daf5bdd9ea3158c5a3468edaadd6282b4c5bcd62..0b04db882340a9c80858d33d4b609eb23ce0802b 100644 (file)
 
 pub fn replace_bound_regions_in_fn_sig(
         tcx: ty::ctxt,
-        opt_self_ty: Option<ty::t>,
         fn_sig: &ty::FnSig,
         mapf: |ty::BoundRegion| -> ty::Region)
-        -> (HashMap<ty::BoundRegion,ty::Region>, Option<ty::t>, ty::FnSig) {
-    debug!("replace_bound_regions_in_fn_sig(self_ty={}, fn_sig={})",
-            opt_self_ty.repr(tcx),
-            fn_sig.repr(tcx));
+        -> (HashMap<ty::BoundRegion,ty::Region>, ty::FnSig) {
+    debug!("replace_bound_regions_in_fn_sig({})", fn_sig.repr(tcx));
 
     let mut map = HashMap::new();
-    let (fn_sig, opt_self_ty) = {
+    let fn_sig = {
         let mut f = ty_fold::RegionFolder::regions(tcx, |r| {
-                debug!("region r={}", r.to_str());
-                match r {
+            debug!("region r={}", r.to_str());
+            match r {
                 ty::ReLateBound(s, br) if s == fn_sig.binder_id => {
                     *map.find_or_insert_with(br, |_| mapf(br))
                 }
                 _ => r
-            }});
-        (ty_fold::super_fold_sig(&mut f, fn_sig),
-         ty_fold::fold_opt_ty(&mut f, opt_self_ty))
+            }
+        });
+        ty_fold::super_fold_sig(&mut f, fn_sig)
     };
     debug!("resulting map: {}", map.to_str());
-    (map, opt_self_ty, fn_sig)
+    (map, fn_sig)
 }
 
 pub fn relate_nested_regions(tcx: ty::ctxt,
@@ -135,11 +132,7 @@ fn relate(&mut self, r_sub: ty::Region) {
     }
 }
 
-pub fn relate_free_regions(
-    tcx: ty::ctxt,
-    self_ty: Option<ty::t>,
-    fn_sig: &ty::FnSig)
-{
+pub fn relate_free_regions(tcx: ty::ctxt, fn_sig: &ty::FnSig) {
     /*!
      * This function populates the region map's `free_region_map`.
      * It walks over the transformed self type and argument types
@@ -158,9 +151,6 @@ pub fn relate_free_regions(
     for arg in fn_sig.inputs.iter() {
         all_tys.push(*arg);
     }
-    for &t in self_ty.iter() {
-        all_tys.push(t);
-    }
 
     for &t in all_tys.iter() {
         debug!("relate_free_regions(t={})", ppaux::ty_to_str(tcx, t));
index 8f85c185adbcce59a7210dba1e74b952ba798dd1..0a231be5d459b60343a4bd3e11f8b5d12ec18e2e 100644 (file)
@@ -330,7 +330,7 @@ fn search_for_vtable(vcx: &VtableContext,
     ty::populate_implementations_for_trait_if_necessary(tcx,
                                                         trait_ref.def_id);
 
-    // XXX: this is a bad way to do this, since we do
+    // FIXME: this is a bad way to do this, since we do
     // pointless allocations.
     let impls = {
         let trait_impls = tcx.trait_impls.borrow();
@@ -371,7 +371,7 @@ fn search_for_vtable(vcx: &VtableContext,
         // we're trying to cast to some_trait.  If not, then we try
         // the next impl.
         //
-        // XXX: document a bit more what this means
+        // FIXME: document a bit more what this means
         //
         // FIXME(#5781) this should be mk_eqty not mk_subty
         let ty::ty_param_substs_and_ty {
@@ -712,7 +712,7 @@ fn mutability_allowed(a_mutbl: ast::Mutability,
       ast::ExprUnary(callee_id, _, _) |
       ast::ExprAssignOp(callee_id, _, _, _) |
       ast::ExprIndex(callee_id, _, _) |
-      ast::ExprMethodCall(callee_id, _, _, _, _, _) => {
+      ast::ExprMethodCall(callee_id, _, _, _, _) => {
         match ty::method_call_type_param_defs(cx.tcx, fcx.inh.method_map, ex.id) {
           Some(type_param_defs) => {
             debug!("vtable resolution on parameter bounds for method call {}",
index 2237c2f43e1934790ebc150901b755ccc7d8344b..48b1acd3f9b37546725c0d4a7850cbfd204cc6c6 100644 (file)
 use middle::pat_util;
 use middle::ty;
 use middle::typeck::astconv::AstConv;
-use middle::typeck::check::{FnCtxt, SelfInfo};
+use middle::typeck::check::FnCtxt;
 use middle::typeck::infer::{force_all, resolve_all, resolve_region};
 use middle::typeck::infer::resolve_type;
 use middle::typeck::infer;
 use middle::typeck::{vtable_res, vtable_origin};
 use middle::typeck::{vtable_static, vtable_param};
-use middle::typeck::method_map_entry;
 use middle::typeck::write_substs_to_tcx;
 use middle::typeck::write_ty_to_tcx;
 use util::ppaux;
@@ -62,7 +61,7 @@ fn resolve_type_vars_in_types(fcx: @FnCtxt, sp: Span, tys: &[ty::t])
     })
 }
 
-fn resolve_method_map_entry(fcx: @FnCtxt, sp: Span, id: ast::NodeId) {
+fn resolve_method_map_entry(fcx: @FnCtxt, id: ast::NodeId) {
     // Resolve any method map entry
     let method_map_entry_opt = {
         let method_map = fcx.inh.method_map.borrow();
@@ -71,18 +70,9 @@ fn resolve_method_map_entry(fcx: @FnCtxt, sp: Span, id: ast::NodeId) {
     match method_map_entry_opt {
         None => {}
         Some(mme) => {
-            {
-                let r = resolve_type_vars_in_type(fcx, sp, mme.self_ty);
-                for t in r.iter() {
-                    let method_map = fcx.ccx.method_map;
-                    let new_entry = method_map_entry { self_ty: *t, ..mme };
-                    debug!("writeback::resolve_method_map_entry(id={:?}, \
-                            new_entry={:?})",
-                           id, new_entry);
-                    let mut method_map = method_map.borrow_mut();
-                    method_map.get().insert(id, new_entry);
-                }
-            }
+            debug!("writeback::resolve_method_map_entry(id={:?}, entry={:?})", id, mme);
+            let mut method_map = fcx.ccx.method_map.borrow_mut();
+            method_map.get().insert(id, mme);
         }
     }
 }
@@ -148,19 +138,33 @@ fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId)
                                          resolve_all | force_all) {
                         Err(e) => {
                             // This should not, I think, happen:
-                            fcx.ccx.tcx.sess.span_err(
+                            tcx.sess.span_err(
                                 sp,
                                 format!("cannot resolve bound for closure: \
                                          {}",
                                         infer::fixup_err_to_str(e)));
                         }
                         Ok(r1) => {
+                            // FIXME(eddyb) #2190 Allow only statically resolved
+                            // bare functions to coerce to a closure to avoid
+                            // constructing (slower) indirect call wrappers.
+                            {
+                                let def_map = tcx.def_map.borrow();
+                                match def_map.get().find(&id) {
+                                    Some(&ast::DefFn(..)) |
+                                    Some(&ast::DefStaticMethod(..)) |
+                                    Some(&ast::DefVariant(..)) |
+                                    Some(&ast::DefStruct(_)) => {}
+                                    _ => tcx.sess.span_err(sp,
+                                            "cannot coerce non-statically resolved bare fn")
+                                }
+                            }
+
                             let resolved_adj = @ty::AutoAddEnv(r1, s);
                             debug!("Adjustments for node {}: {:?}",
                                    id,
                                    resolved_adj);
-                            let mut adjustments = fcx.tcx()
-                                                     .adjustments
+                            let mut adjustments = tcx.adjustments
                                                      .borrow_mut();
                             adjustments.get().insert(id, resolved_adj);
                         }
@@ -175,7 +179,7 @@ fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId)
                             Ok(r1) => r1,
                             Err(e) => {
                                 // This should not, I think, happen.
-                                fcx.ccx.tcx.sess.span_err(
+                                tcx.sess.span_err(
                                     sp,
                                     format!("cannot resolve scope of borrow: \
                                              {}",
@@ -195,13 +199,13 @@ fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId)
                         autoref: resolved_autoref,
                     });
                     debug!("Adjustments for node {}: {:?}", id, resolved_adj);
-                    let mut adjustments = fcx.tcx().adjustments.borrow_mut();
+                    let mut adjustments = tcx.adjustments.borrow_mut();
                     adjustments.get().insert(id, resolved_adj);
                 }
 
                 ty::AutoObject(..) => {
                     debug!("Adjustments for node {}: {:?}", id, adjustment);
-                    let mut adjustments = fcx.tcx().adjustments.borrow_mut();
+                    let mut adjustments = tcx.adjustments.borrow_mut();
                     adjustments.get().insert(id, adjustment);
                 }
             }
@@ -273,11 +277,11 @@ fn visit_expr(e: &ast::Expr, wbcx: &mut WbCtxt) {
 
     resolve_type_vars_for_node(wbcx, e.span, e.id);
 
-    resolve_method_map_entry(wbcx.fcx, e.span, e.id);
+    resolve_method_map_entry(wbcx.fcx, e.id);
     {
         let r = e.get_callee_id();
         for callee_id in r.iter() {
-            resolve_method_map_entry(wbcx.fcx, e.span, *callee_id);
+            resolve_method_map_entry(wbcx.fcx, *callee_id);
         }
     }
 
@@ -303,7 +307,7 @@ fn visit_expr(e: &ast::Expr, wbcx: &mut WbCtxt) {
             maybe_resolve_type_vars_for_node(wbcx, e.span, callee_id);
         }
 
-        ast::ExprMethodCall(callee_id, _, _, _, _, _) => {
+        ast::ExprMethodCall(callee_id, _, _, _, _) => {
             // We must always have written in a callee ID type for these.
             resolve_type_vars_for_node(wbcx, e.span, callee_id);
         }
@@ -381,18 +385,11 @@ pub fn resolve_type_vars_in_expr(fcx: @FnCtxt, e: &ast::Expr) -> bool {
     return wbcx.success;
 }
 
-pub fn resolve_type_vars_in_fn(fcx: @FnCtxt,
-                               decl: &ast::FnDecl,
-                               blk: &ast::Block,
-                               self_info: Option<SelfInfo>) -> bool {
+pub fn resolve_type_vars_in_fn(fcx: @FnCtxt, decl: &ast::FnDecl,
+                               blk: &ast::Block) -> bool {
     let mut wbcx = WbCtxt { fcx: fcx, success: true };
     let wbcx = &mut wbcx;
     wbcx.visit_block(blk, ());
-    for self_info in self_info.iter() {
-        resolve_type_vars_for_node(wbcx,
-                                   self_info.span,
-                                   self_info.self_id);
-    }
     for arg in decl.inputs.iter() {
         wbcx.visit_pat(arg.pat, ());
         // Privacy needs the type for the whole pattern, not just each binding
index 89c24cf4116758eace2e3a23cd690d3ad0fa27af..0dcb3c7329ba5259af18a991f3b9406eb4aa0014 100644 (file)
@@ -24,8 +24,7 @@
 use middle::ty::{ty_param, ty_param_bounds_and_ty, ty_ptr};
 use middle::ty::{ty_rptr, ty_self, ty_struct, ty_trait, ty_tup};
 use middle::ty::{ty_type, ty_uint, ty_uniq, ty_bare_fn, ty_closure};
-use middle::ty::{ty_opaque_closure_ptr, ty_unboxed_vec};
-use middle::ty::{type_is_ty_var};
+use middle::ty::{ty_unboxed_vec, type_is_ty_var};
 use middle::subst::Subst;
 use middle::ty;
 use middle::ty::{Impl, Method};
@@ -84,7 +83,7 @@ pub fn get_base_type(inference_context: @InferCtxt,
         ty_nil | ty_bot | 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_self(..) | ty_type |
-        ty_opaque_closure_ptr(..) | ty_unboxed_vec(..) | ty_err | ty_box(_) |
+        ty_unboxed_vec(..) | ty_err | ty_box(_) |
         ty_uniq(_) | ty_ptr(_) | ty_rptr(_, _) => {
             debug!("(getting base type) no base type; found {:?}",
                    get(original_type).sty);
@@ -309,7 +308,7 @@ pub fn check_implementation(&self,
                 // Nothing to do.
             }
             Some(base_type_def_id) => {
-                // XXX: Gather up default methods?
+                // FIXME: Gather up default methods?
                 if associated_traits.len() == 0 {
                     self.add_inherent_impl(base_type_def_id, implementation);
                 }
@@ -820,9 +819,6 @@ fn subst_receiver_types_in_method_ty(tcx: ty::ctxt,
         // method types *can* appear in the generic bounds
         method.generics.subst(tcx, &combined_substs),
 
-        // method tps cannot appear in the self_ty, so use `substs` from trait ref
-        method.transformed_self_ty.subst(tcx, &trait_ref.substs),
-
         // method types *can* appear in the fty
         method.fty.subst(tcx, &combined_substs),
 
index 474335caa7bb80b67735ee052ba7fe785c674dd9..1077454039deff35131a7eacc3263134706917f2 100644 (file)
@@ -345,7 +345,8 @@ fn make_static_method_ty(ccx: &CrateCtxt,
             bounds: @ty::ParamBounds {
                 builtin_bounds: ty::EmptyBuiltinBounds(),
                 trait_bounds: ~[self_trait_ref]
-            }
+            },
+            default: None
         });
 
         // add in the type parameters from the method
@@ -380,15 +381,13 @@ fn ty_method_of_trait_method(this: &CrateCtxt,
                                  m_decl: &ast::FnDecl) -> ty::Method
     {
         let trait_self_ty = ty::mk_self(this.tcx, local_def(trait_id));
-        let (transformed_self_ty, fty) =
-            astconv::ty_of_method(this, *m_id, *m_purity,
-                                  trait_self_ty, *m_explicit_self, m_decl);
+        let fty = astconv::ty_of_method(this, *m_id, *m_purity, trait_self_ty,
+                                        *m_explicit_self, m_decl);
         let num_trait_type_params = trait_generics.type_param_defs.len();
         ty::Method::new(
             *m_ident,
             // FIXME(#5121) -- distinguish early vs late lifetime params
             ty_generics(this, m_generics, num_trait_type_params),
-            transformed_self_ty,
             fty,
             m_explicit_self.node,
             // assume public, because this is only invoked on trait methods
@@ -512,10 +511,9 @@ fn ty_of_method(ccx: &CrateCtxt,
                     rcvr_generics: &ast::Generics,
                     rcvr_visibility: ast::Visibility) -> ty::Method
     {
-        let (transformed_self_ty, fty) =
-            astconv::ty_of_method(ccx, m.id, m.purity,
-                                  untransformed_rcvr_ty,
-                                  m.explicit_self, m.decl);
+        let fty = astconv::ty_of_method(ccx, m.id, m.purity,
+                                        untransformed_rcvr_ty,
+                                        m.explicit_self, m.decl);
 
         // if the method specifies a visibility, use that, otherwise
         // inherit the visibility from the impl (so `foo` in `pub impl
@@ -528,7 +526,6 @@ fn ty_of_method(ccx: &CrateCtxt,
             m.ident,
             // FIXME(#5121) -- distinguish early vs late lifetime params
             ty_generics(ccx, &m.generics, num_rcvr_type_params),
-            transformed_self_ty,
             fty,
             m.explicit_self.node,
             method_vis,
@@ -956,10 +953,12 @@ pub fn ty_generics(ccx: &CrateCtxt,
                     let param_ty = ty::param_ty {idx: base_index + offset,
                                                  def_id: local_def(param.id)};
                     let bounds = @compute_bounds(ccx, param_ty, &param.bounds);
+                    let default = param.default.map(|x| ast_ty_to_ty(ccx, &ExplicitRscope, x));
                     let def = ty::TypeParameterDef {
                         ident: param.ident,
                         def_id: local_def(param.id),
-                        bounds: bounds
+                        bounds: bounds,
+                        default: default
                     };
                     debug!("def for param: {}", def.repr(ccx.tcx));
 
index d3931d277dd8f073906b0bd484f7651917b943b1..6a4de959c2bb93bf113c29d7a58cf105af28c4b2 100644 (file)
@@ -385,48 +385,37 @@ pub fn coerce_borrowed_fn(&self,
         })))
     }
 
-    pub fn coerce_from_bare_fn(&self,
-                               a: ty::t,
-                               fn_ty_a: &ty::BareFnTy,
-                               b: ty::t)
-                               -> CoerceResult {
-        self.unpack_actual_value(b, |sty_b| {
-            self.coerce_from_bare_fn_post_unpack(a, fn_ty_a, b, sty_b)
-        })
-    }
-
-    pub fn coerce_from_bare_fn_post_unpack(&self,
-                                           a: ty::t,
-                                           fn_ty_a: &ty::BareFnTy,
-                                           b: ty::t,
-                                           sty_b: &ty::sty)
-                                           -> CoerceResult {
+    fn coerce_from_bare_fn(&self, a: ty::t, fn_ty_a: &ty::BareFnTy, b: ty::t)
+                           -> CoerceResult {
         /*!
          *
          * Attempts to coerce from a bare Rust function (`extern
-         * "rust" fn`) into a closure.
+         * "Rust" fn`) into a closure or a `proc`.
          */
 
-        debug!("coerce_from_bare_fn(a={}, b={})",
-               a.inf_str(self.get_ref().infcx), b.inf_str(self.get_ref().infcx));
+        self.unpack_actual_value(b, |sty_b| {
 
-        if !fn_ty_a.abis.is_rust() || fn_ty_a.purity != ast::ImpureFn {
-            return self.subtype(a, b);
-        }
+            debug!("coerce_from_bare_fn(a={}, b={})",
+                   a.inf_str(self.get_ref().infcx), b.inf_str(self.get_ref().infcx));
 
-        let fn_ty_b = match *sty_b {
-            ty::ty_closure(ref f) => (*f).clone(),
-            _ => return self.subtype(a, b),
-        };
+            if !fn_ty_a.abis.is_rust() || fn_ty_a.purity != ast::ImpureFn {
+                return self.subtype(a, b);
+            }
 
-        let adj = @ty::AutoAddEnv(fn_ty_b.region, fn_ty_b.sigil);
-        let a_closure = ty::mk_closure(self.get_ref().infcx.tcx,
-                                       ty::ClosureTy {
-                                            sig: fn_ty_a.sig.clone(),
-                                            ..fn_ty_b
-                                       });
-        if_ok!(self.subtype(a_closure, b));
-        Ok(Some(adj))
+            let fn_ty_b = match *sty_b {
+                ty::ty_closure(ref f) => (*f).clone(),
+                _ => return self.subtype(a, b)
+            };
+
+            let adj = @ty::AutoAddEnv(fn_ty_b.region, fn_ty_b.sigil);
+            let a_closure = ty::mk_closure(self.get_ref().infcx.tcx,
+                                           ty::ClosureTy {
+                                                sig: fn_ty_a.sig.clone(),
+                                                ..fn_ty_b
+                                           });
+            if_ok!(self.subtype(a_closure, b));
+            Ok(Some(adj))
+        })
     }
 
     pub fn coerce_unsafe_ptr(&self,
index 68fb4b1e579a6d5204398055fd8cd9d5dd8e5b49..812b7ffd97d60dccf9fbd106bed48792a6ce5945 100644 (file)
@@ -25,7 +25,7 @@
 use middle::ty;
 use middle::ty_fold;
 use middle::ty_fold::TypeFolder;
-use middle::typeck::check::regionmanip::{replace_bound_regions_in_fn_sig};
+use middle::typeck::check::regionmanip::replace_bound_regions_in_fn_sig;
 use middle::typeck::infer::coercion::Coerce;
 use middle::typeck::infer::combine::{Combine, CombineFields, eq_tys};
 use middle::typeck::infer::region_inference::{RegionVarBindings};
@@ -809,8 +809,8 @@ pub fn replace_bound_regions_with_fresh_regions(&self,
                                                     -> (ty::FnSig,
                                                         HashMap<ty::BoundRegion,
                                                                 ty::Region>) {
-        let (map, _, fn_sig) =
-            replace_bound_regions_in_fn_sig(self.tcx, None, fsig, |br| {
+        let (map, fn_sig) =
+            replace_bound_regions_in_fn_sig(self.tcx, fsig, |br| {
                 let rvar = self.next_region_var(
                     BoundRegionInFnType(trace.origin.span(), br));
                 debug!("Bound region {} maps to {:?}",
index 536bbd0b20da031b1e62cfe45bf276832ce7abd6..54998e06f8e4566d22ff0e179f1efafb40065963 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -1010,7 +1010,7 @@ fn extract_values_and_collect_conflicts(
         // idea is to report errors that derive from independent
         // regions of the graph, but not those that derive from
         // overlapping locations.
-        let mut dup_vec = vec::from_elem(self.num_vars(), uint::max_value);
+        let mut dup_vec = vec::from_elem(self.num_vars(), uint::MAX);
 
         let mut opt_graph = None;
 
@@ -1238,7 +1238,7 @@ struct WalkState {
             let classification = var_data[node_idx.to_uint()].classification;
 
             // check whether we've visited this node on some previous walk
-            if dup_vec[node_idx.to_uint()] == uint::max_value {
+            if dup_vec[node_idx.to_uint()] == uint::MAX {
                 dup_vec[node_idx.to_uint()] = orig_node_idx.to_uint();
             } else if dup_vec[node_idx.to_uint()] != orig_node_idx.to_uint() {
                 state.dup_found = true;
index 6e370a85096c20ac27812d56276be15618ff1e94..19abbecaa8a72929756416f7a5979d851a34c58b 100644 (file)
@@ -171,8 +171,8 @@ fn fn_sigs(&self, a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig> {
 
         // Second, we instantiate each bound region in the supertype with a
         // fresh concrete region.
-        let (skol_map, _, b_sig) = {
-            replace_bound_regions_in_fn_sig(self.get_ref().infcx.tcx, None, b, |br| {
+        let (skol_map, b_sig) = {
+            replace_bound_regions_in_fn_sig(self.get_ref().infcx.tcx, b, |br| {
                 let skol = self.get_ref().infcx.region_vars.new_skolemized(br);
                 debug!("Bound region {} skolemized to {:?}",
                        bound_region_to_str(self.get_ref().infcx.tcx, "", false, br),
index dc8e090596d0cea18d4516fb1b82d53cdf18b2de..6ac4c5ff395ce3790d1085be2ebe2aa181638c3b 100644 (file)
@@ -52,7 +52,7 @@ fn setup_env(test_name: &str, source_string: &str) -> Env {
     let matches = getopts(~[~"-Z", ~"verbose"], optgroups()).get();
     let diag = diagnostic::collect(messages);
     let sessopts = build_session_options(~"rustc", &matches, diag);
-    let sess = build_session(sessopts, diag);
+    let sess = build_session(sessopts, None, diag);
     let cfg = build_configuration(sess, ~"whatever", str_input(~""));
     let dm = HashMap();
     let amap = HashMap();
index da3a2eebfeb1beeaf428d54bdf85ee753fccac7e..8837a978f439ac35ac57a00a2f1d6b56a55e0d16 100644 (file)
@@ -144,13 +144,6 @@ pub struct method_object {
 
 #[deriving(Clone)]
 pub struct method_map_entry {
-    // the type of the self parameter, which is not reflected in the fn type
-    // (FIXME #3446)
-    self_ty: ty::t,
-
-    // the type of explicit self on the method
-    explicit_self: ast::ExplicitSelf_,
-
     // method details being invoked
     origin: method_origin,
 }
@@ -264,10 +257,10 @@ pub fn write_tpt_to_tcx(tcx: ty::ctxt,
 pub fn lookup_def_tcx(tcx: ty::ctxt, sp: Span, id: ast::NodeId) -> ast::Def {
     let def_map = tcx.def_map.borrow();
     match def_map.get().find(&id) {
-      Some(&x) => x,
-      _ => {
-        tcx.sess.span_fatal(sp, "internal error looking up a definition")
-      }
+        Some(&x) => x,
+        _ => {
+            tcx.sess.span_fatal(sp, "internal error looking up a definition")
+        }
     }
 }
 
index 7740645030d221681eba8e18cf0d925bf869e40d..dc57ad747ebd762a1ed9c082b2c5dc566e86cca8 100644 (file)
@@ -193,8 +193,8 @@ enum OptionalMap<C> { Some(|C| -> C), None }
 */
 
 use std::hashmap::HashMap;
-use extra::arena;
-use extra::arena::Arena;
+use arena;
+use arena::Arena;
 use middle::ty;
 use std::vec;
 use syntax::ast;
@@ -472,22 +472,6 @@ fn visit_item(&mut self, item: &ast::Item, _: ()) {
             ast::ItemTrait(..) => {
                 let methods = ty::trait_methods(tcx, did);
                 for method in methods.iter() {
-                    match method.transformed_self_ty {
-                        Some(self_ty) => {
-                            // The implicit self parameter is basically
-                            // equivalent to a normal parameter declared
-                            // like:
-                            //
-                            //     self : self_ty
-                            //
-                            // where self_ty is `&Self` or `&mut Self`
-                            // or whatever.
-                            self.add_constraints_from_ty(
-                                self_ty, self.contravariant);
-                        }
-                        None => {}
-                    }
-
                     self.add_constraints_from_sig(
                         &method.fty.sig, self.covariant);
                 }
@@ -691,8 +675,8 @@ fn add_constraints_from_ty(&mut self,
                 self.add_constraints_from_sig(sig, variance);
             }
 
-            ty::ty_infer(..) | ty::ty_err | ty::ty_type |
-            ty::ty_opaque_closure_ptr(..) | ty::ty_unboxed_vec(..) => {
+            ty::ty_infer(..) | ty::ty_err |
+            ty::ty_type | ty::ty_unboxed_vec(..) => {
                 self.tcx().sess.bug(
                     format!("Unexpected type encountered in \
                             variance inference: {}",
index dc35ab7e885ee222c8466cacc33cbd7d320d8fb1..f391239df330402bd2cfb37e6cb323e19e54f241 100644 (file)
                  ReEmpty};
 use middle::ty::{ty_bool, ty_char, ty_bot, ty_box, ty_struct, ty_enum};
 use middle::ty::{ty_err, ty_str, ty_vec, ty_float, ty_bare_fn, ty_closure};
-use middle::ty::{ty_nil, ty_opaque_closure_ptr, ty_param};
-use middle::ty::{ty_ptr, ty_rptr, ty_self, ty_tup, ty_type, ty_uniq};
-use middle::ty::{ty_trait, ty_int};
-use middle::ty::{ty_uint, ty_unboxed_vec, ty_infer};
+use middle::ty::{ty_nil, ty_param, ty_ptr, ty_rptr, ty_self, ty_tup, ty_type};
+use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_unboxed_vec, ty_infer};
 use middle::ty;
 use middle::typeck;
 use syntax::abi::AbiSet;
@@ -487,12 +485,13 @@ fn push_sig_to_str(cx: ctxt,
       ty_enum(did, ref substs) | ty_struct(did, ref substs) => {
         let path = ty::item_path(cx, did);
         let base = ast_map::path_to_str(path, cx.sess.intr());
-        parameterized(cx, base, &substs.regions, substs.tps)
+        parameterized(cx, base, &substs.regions, substs.tps, did, false)
       }
       ty_trait(did, ref substs, s, mutbl, ref bounds) => {
         let path = ty::item_path(cx, did);
         let base = ast_map::path_to_str(path, cx.sess.intr());
-        let ty = parameterized(cx, base, &substs.regions, substs.tps);
+        let ty = parameterized(cx, base, &substs.regions,
+                               substs.tps, did, true);
         let bound_sep = if bounds.is_empty() { "" } else { ":" };
         let bound_str = bounds.repr(cx);
         format!("{}{}{}{}{}", trait_store_to_str(cx, s), mutability_to_str(mutbl), ty,
@@ -501,17 +500,16 @@ fn push_sig_to_str(cx: ctxt,
       ty_vec(ref mt, vs) => {
         vstore_ty_to_str(cx, mt, vs)
       }
-      ty_str(vs) => format!("{}{}", vstore_to_str(cx, vs), "str"),
-      ty_opaque_closure_ptr(ast::BorrowedSigil) => ~"&closure",
-      ty_opaque_closure_ptr(ast::ManagedSigil) => ~"@closure",
-      ty_opaque_closure_ptr(ast::OwnedSigil) => ~"~closure",
+      ty_str(vs) => format!("{}{}", vstore_to_str(cx, vs), "str")
     }
 }
 
 pub fn parameterized(cx: ctxt,
                      base: &str,
                      regions: &ty::RegionSubsts,
-                     tps: &[ty::t]) -> ~str {
+                     tps: &[ty::t],
+                     did: ast::DefId,
+                     is_trait: bool) -> ~str {
 
     let mut strs = ~[];
     match *regions {
@@ -523,7 +521,20 @@ pub fn parameterized(cx: ctxt,
         }
     }
 
-    for t in tps.iter() {
+    let generics = if is_trait {
+        ty::lookup_trait_def(cx, did).generics
+    } else {
+        ty::lookup_item_type(cx, did).generics
+    };
+    let ty_params = generics.type_param_defs.iter();
+    let num_defaults = ty_params.zip(tps.iter()).rev().take_while(|&(def, &actual)| {
+        match def.default {
+            Some(default) => default == actual,
+            None => false
+        }
+    }).len();
+
+    for t in tps.slice_to(tps.len() - num_defaults).iter() {
         strs.push(ty_to_str(cx, *t))
     }
 
@@ -800,11 +811,10 @@ fn repr(&self, _: ctxt) -> ~str {
 
 impl Repr for ty::Method {
     fn repr(&self, tcx: ctxt) -> ~str {
-        format!("method(ident: {}, generics: {}, transformed_self_ty: {}, \
-                fty: {}, explicit_self: {}, vis: {}, def_id: {})",
+        format!("method(ident: {}, generics: {}, fty: {}, \
+                explicit_self: {}, vis: {}, def_id: {})",
                 self.ident.repr(tcx),
                 self.generics.repr(tcx),
-                self.transformed_self_ty.repr(tcx),
                 self.fty.repr(tcx),
                 self.explicit_self.repr(tcx),
                 self.vis.repr(tcx),
@@ -847,12 +857,7 @@ fn repr(&self, tcx: ctxt) -> ~str {
 
 impl Repr for typeck::method_map_entry {
     fn repr(&self, tcx: ctxt) -> ~str {
-        format!("method_map_entry \\{self_arg: {}, \
-              explicit_self: {}, \
-              origin: {}\\}",
-             self.self_ty.repr(tcx),
-             self.explicit_self.repr(tcx),
-             self.origin.repr(tcx))
+        format!("method_map_entry \\{origin: {}\\}", self.origin.repr(tcx))
     }
 }
 
@@ -980,9 +985,11 @@ fn user_string(&self, tcx: ctxt) -> ~str {
         if tcx.sess.verbose() && self.substs.self_ty.is_some() {
             let mut all_tps = self.substs.tps.clone();
             for &t in self.substs.self_ty.iter() { all_tps.push(t); }
-            parameterized(tcx, base, &self.substs.regions, all_tps)
+            parameterized(tcx, base, &self.substs.regions,
+                          all_tps, self.def_id, true)
         } else {
-            parameterized(tcx, base, &self.substs.regions, self.substs.tps)
+            parameterized(tcx, base, &self.substs.regions,
+                          self.substs.tps, self.def_id, true)
         }
     }
 }
index ee2f7638be988734fa9f26ee967d0bdf139eb5aa..b0695bc0128eb02d95b181c860381cd12d98eee1 100644 (file)
@@ -38,11 +38,11 @@ fn read_u32v_be(dst: &mut[u32], input: &[u8]) {
     unsafe {
         let mut x: *mut i32 = transmute(dst.unsafe_mut_ref(0));
         let mut y: *i32 = transmute(input.unsafe_ref(0));
-        dst.len().times(|| {
+        for _ in range(0, dst.len()) {
             *x = to_be32(*y);
             x = x.offset(1);
             y = y.offset(1);
-        });
+        }
     }
 }
 
@@ -109,8 +109,8 @@ trait FixedBuffer {
 
 /// A FixedBuffer of 64 bytes useful for implementing Sha256 which has a 64 byte blocksize.
 struct FixedBuffer64 {
-    priv buffer: [u8, ..64],
-    priv buffer_idx: uint,
+    buffer: [u8, ..64],
+    buffer_idx: uint,
 }
 
 impl FixedBuffer64 {
index e48c0800506f90bd9cf359efb03efb1dfdc4d290..e86122fb7d1e670fd5bfe0517aae14ddf38cd276 100644 (file)
@@ -330,6 +330,16 @@ pub struct Method {
 
 impl Clean<Item> for ast::Method {
     fn clean(&self) -> Item {
+        let inputs = match self.explicit_self.node {
+            ast::SelfStatic => self.decl.inputs.as_slice(),
+            _ => self.decl.inputs.slice_from(1)
+        };
+        let decl = FnDecl {
+            inputs: inputs.iter().map(|x| x.clean()).collect(),
+            output: (self.decl.output.clean()),
+            cf: self.decl.cf.clean(),
+            attrs: ~[]
+        };
         Item {
             name: Some(self.ident.clean()),
             attrs: self.attrs.clean(),
@@ -340,7 +350,7 @@ fn clean(&self) -> Item {
                 generics: self.generics.clean(),
                 self_: self.explicit_self.clean(),
                 purity: self.purity.clone(),
-                decl: self.decl.clean(),
+                decl: decl,
             }),
         }
     }
@@ -356,6 +366,16 @@ pub struct TyMethod {
 
 impl Clean<Item> for ast::TypeMethod {
     fn clean(&self) -> Item {
+        let inputs = match self.explicit_self.node {
+            ast::SelfStatic => self.decl.inputs.as_slice(),
+            _ => self.decl.inputs.slice_from(1)
+        };
+        let decl = FnDecl {
+            inputs: inputs.iter().map(|x| x.clean()).collect(),
+            output: (self.decl.output.clean()),
+            cf: self.decl.cf.clean(),
+            attrs: ~[]
+        };
         Item {
             name: Some(self.ident.clean()),
             attrs: self.attrs.clean(),
@@ -364,7 +384,7 @@ fn clean(&self) -> Item {
             visibility: None,
             inner: TyMethodItem(TyMethod {
                 purity: self.purity.clone(),
-                decl: self.decl.clean(),
+                decl: decl,
                 self_: self.explicit_self.clean(),
                 generics: self.generics.clean(),
             }),
@@ -385,8 +405,8 @@ impl Clean<SelfTy> for ast::ExplicitSelf {
     fn clean(&self) -> SelfTy {
         match self.node {
             ast::SelfStatic => SelfStatic,
-            ast::SelfValue(_) => SelfValue,
-            ast::SelfUniq(_) => SelfOwned,
+            ast::SelfValue => SelfValue,
+            ast::SelfUniq => SelfOwned,
             ast::SelfRegion(lt, mt) => SelfBorrowed(lt.clean(), mt.clean()),
             ast::SelfBox => SelfManaged,
         }
@@ -1178,7 +1198,7 @@ fn resolve_type(path: Path, tpbs: Option<~[TyParamBound]>,
 
     let (def_id, kind) = match *d {
         ast::DefFn(i, _) => (i, TypeFunction),
-        ast::DefSelf(i, _) | ast::DefSelfTy(i) => return Self(i),
+        ast::DefSelfTy(i) => return Self(i),
         ast::DefTy(i) => (i, TypeEnum),
         ast::DefTrait(i) => {
             debug!("saw DefTrait in def_to_id");
index 8501a01d34bcf140073fddf7cf357497801b6942..e4260e367a879d592d4cea21f04a7711c23876be 100644 (file)
@@ -64,9 +64,9 @@ fn get_ast_and_resolve(cpath: &Path,
         syntax::diagnostic::mk_span_handler(diagnostic_handler, parsesess.cm);
 
     let sess = driver::driver::build_session_(sessopts,
+                                              Some(cpath.clone()),
                                               parsesess.cm,
-                                              @diagnostic::DefaultEmitter as
-                                                @diagnostic::Emitter,
+                                              @diagnostic::DefaultEmitter,
                                               span_diagnostic_handler);
 
     let mut cfg = build_configuration(sess);
index 9b1caaa152ce3b341542ebcc1fe13379392eb445..11a8ca0dd45a2552108cba5cac3c782e7b17fda5 100644 (file)
@@ -323,7 +323,7 @@ fn fmt(g: &clean::Type, f: &mut fmt::Formatter) {
                        },
                        arrow = match decl.decl.output { clean::Unit => "no", _ => "yes" },
                        ret = decl.decl.output);
-                // XXX: where are bounds and lifetimes printed?!
+                // FIXME: where are bounds and lifetimes printed?!
             }
             clean::BareFunction(ref decl) => {
                 write!(f.buf, "{}{}fn{}{}",
@@ -481,7 +481,7 @@ fn fmt(v: &clean::ViewPath, f: &mut fmt::Formatter) {
 impl fmt::Default for clean::ImportSource {
     fn fmt(v: &clean::ImportSource, f: &mut fmt::Formatter) {
         match v.did {
-            // XXX: shouldn't be restricted to just local imports
+            // FIXME: shouldn't be restricted to just local imports
             Some(did) if ast_util::is_local(did) => {
                 resolved_path(f.buf, did.node, &v.path, true);
             }
@@ -498,7 +498,7 @@ fn fmt(v: &clean::ImportSource, f: &mut fmt::Formatter) {
 impl fmt::Default for clean::ViewListIdent {
     fn fmt(v: &clean::ViewListIdent, f: &mut fmt::Formatter) {
         match v.source {
-            // XXX: shouldn't be limited to just local imports
+            // FIXME: shouldn't be limited to just local imports
             Some(did) if ast_util::is_local(did) => {
                 let path = clean::Path {
                     global: false,
index 5d0728c8cdf77c6ff4ac6df1216a8f53d1ab6830..d53adb78a30866b440286a14088d0794aa43b73e 100644 (file)
@@ -16,7 +16,9 @@
 //! functionality through a unit-struct, `Markdown`, which has an implementation
 //! of `fmt::Default`. Example usage:
 //!
-//! ```rust
+//! ```rust,ignore
+//! use rustdoc::html::markdown::Markdown;
+//!
 //! let s = "My *markdown* _text_";
 //! let html = format!("{}", Markdown(s));
 //! // ... something using html
index b0a56cb402b5ffe57a100c22333148f6c9217fae..90ed4a4c744c5ab7593ad72b9c0368307acd0ef9 100644 (file)
@@ -682,7 +682,7 @@ fn recurse<T>(&mut self, s: ~str, f: |&mut Context| -> T) -> T {
     ///
     /// This currently isn't parallelized, but it'd be pretty easy to add
     /// parallelization to this function.
-    fn crate(mut self, mut crate: clean::Crate, cache: Cache) {
+    fn crate(self, mut crate: clean::Crate, cache: Cache) {
         let mut item = match crate.module.take() {
             Some(i) => i,
             None => return
index b2500a1bc68a26acc20dc1e3a296840cff1b0add..6dbf56681bd0c5dc4a8921285c1165a0abb958c2 100644 (file)
 
     $('.js-only').removeClass('js-only');
 
+    function getQueryStringParams() {
+        var params = {};
+        window.location.search.substring(1).split("&").
+            map(function(s) {
+                var pair = s.split("=");
+                params[decodeURIComponent(pair[0])] =
+                    typeof pair[1] === "undefined" ? null : decodeURIComponent(pair[1]);
+            });
+        return params;
+    }
+
+    function browserSupportsHistoryApi() {
+        return window.history && typeof window.history.pushState === "function";
+    }
+
     function resizeShortBlocks() {
         if (resizeTimeout) {
             clearTimeout(resizeTimeout);
     });
 
     function initSearch(searchIndex) {
-        var currentResults, index;
+        var currentResults, index, params = getQueryStringParams();
 
-        // clear cached values from the search bar
-        $(".search-input")[0].value = '';
+        // Populate search bar with query string search term when provided.
+        $(".search-input")[0].value = params.search || '';
 
         /**
          * Executes the query and builds an index of results
                 results = [],
                 maxResults = 200,
                 resultIndex;
+            var params = getQueryStringParams();
 
             query = getQuery();
             if (e) {
                 return;
             }
 
+            // Because searching is incremental by character, only the most recent search query
+            // is added to the browser history.
+            if (browserSupportsHistoryApi()) {
+                if (!history.state && !params.search) {
+                    history.pushState(query, "", "?search=" + encodeURIComponent(query.query));
+                } else {
+                    history.replaceState(query, "", "?search=" + encodeURIComponent(query.query));
+                }
+            }
+
             resultIndex = execQuery(query, 20000, index);
             len = resultIndex.length;
             for (i = 0; i < len; i += 1) {
                 clearTimeout(keyUpTimeout);
                 keyUpTimeout = setTimeout(search, 100);
             });
+            // Push and pop states are used to add search results to the browser history.
+            if (browserSupportsHistoryApi()) {
+                $(window).on('popstate', function(e) {
+                    var params = getQueryStringParams();
+                    // When browsing back from search results the main page visibility must be reset.
+                    if (!params.search) {
+                        $('#main.content').removeClass('hidden');
+                        $('#search.content').addClass('hidden');
+                    }
+                    // When browsing forward to search results the previous search will be repeated,
+                    // so the currentResults are cleared to ensure the search is successful.
+                    currentResults = null;
+                    // Synchronize search bar with query string state and perform the search.
+                    $('.search-input').val(params.search);
+                    // Some browsers fire 'onpopstate' for every page load (Chrome), while others fire the
+                    // event only when actually popping a state (Firefox), which is why search() is called
+                    // both here and at the end of the startSearch() function.
+                    search();
+                });
+            }
+            search();
         }
 
         index = buildIndex(searchIndex);
index 393be290506e127582f5ca899f6c33019f9dd1f2..f7a484e3d3e00262c6072a406250a679c3a2fde7 100644 (file)
@@ -211,10 +211,10 @@ fn rust_input(cratefile: &str, matches: &getopts::Matches) -> Output {
     let cfgs = matches.opt_strs("cfg");
     let cr = Path::new(cratefile);
     info!("starting to run rustc");
-    let (crate, analysis) = do std::task::try {
+    let (crate, analysis) = std::task::try(proc() {
         let cr = cr;
         core::run_core(libs.move_iter().collect(), cfgs, &cr)
-    }.unwrap();
+    }).unwrap();
     info!("finished with rustc");
     local_data::set(analysiskey, analysis);
 
@@ -301,7 +301,7 @@ fn json_input(input: &str) -> Result<Output, ~str> {
                 }
                 None => return Err(~"malformed json"),
             };
-            // XXX: this should read from the "plugins" field, but currently
+            // FIXME: this should read from the "plugins" field, but currently
             //      Json doesn't implement decodable...
             let plugin_output = ~[];
             Ok((crate, plugin_output))
index cd3d3ecddfec22da4f31fe4eac1e894c37462c8d..53b42baf402a74302b3d3d09f201c92e05a131e6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -231,7 +231,7 @@ pub fn unindent(s: &str) -> ~str {
     let lines = s.lines_any().collect::<~[&str]>();
     let mut saw_first_line = false;
     let mut saw_second_line = false;
-    let min_indent = lines.iter().fold(uint::max_value, |min_indent, line| {
+    let min_indent = lines.iter().fold(uint::MAX, |min_indent, line| {
 
         // After we see the first non-whitespace line, look at
         // the line we have. If it is not whitespace, and therefore
@@ -243,7 +243,7 @@ pub fn unindent(s: &str) -> ~str {
             !line.is_whitespace();
 
         let min_indent = if ignore_previous_indents {
-            uint::max_value
+            uint::MAX
         } else {
             min_indent
         };
index 4d8df829a944869b67122a3626e69f137e323352..9271af9d575eafba3314308df06091931a7c5344 100644 (file)
@@ -34,7 +34,8 @@
 
 pub fn run(input: &str, matches: &getopts::Matches) -> int {
     let parsesess = parse::new_parse_sess(None);
-    let input = driver::FileInput(Path::new(input));
+    let input_path = Path::new(input);
+    let input = driver::FileInput(input_path.clone());
     let libs = matches.opt_strs("L").map(|s| Path::new(s.as_slice()));
     let libs = @RefCell::new(libs.move_iter().collect());
 
@@ -52,9 +53,9 @@ pub fn run(input: &str, matches: &getopts::Matches) -> int {
         diagnostic::mk_span_handler(diagnostic_handler, parsesess.cm);
 
     let sess = driver::build_session_(sessopts,
+                                      Some(input_path),
                                       parsesess.cm,
-                                      @diagnostic::DefaultEmitter as
-                                            @diagnostic::Emitter,
+                                      @diagnostic::DefaultEmitter,
                                       span_diagnostic_handler);
 
     let cfg = driver::build_configuration(sess);
@@ -113,9 +114,9 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>) {
         diagnostic::mk_span_handler(diagnostic_handler, parsesess.cm);
 
     let sess = driver::build_session_(sessopts,
+                                      None,
                                       parsesess.cm,
-                                      @diagnostic::DefaultEmitter as
-                                            @diagnostic::Emitter,
+                                      @diagnostic::DefaultEmitter,
                                       span_diagnostic_handler);
 
     let outdir = TempDir::new("rustdoctest").expect("rustdoc needs a tempdir");
index e5e494e9b5f0c115c84bae81a0cca088a3bee052..b43ffec2783cafb3d5e37613be81e0db69501fa4 100644 (file)
@@ -114,8 +114,8 @@ fn parse<'a>(sysroot: Path,
         };
         let input = driver::FileInput(script.clone());
         let sess = driver::build_session(options,
-                                         @diagnostic::DefaultEmitter as
-                                            @diagnostic::Emitter);
+                                         Some(script.clone()),
+                                         @diagnostic::DefaultEmitter);
         let cfg = driver::build_configuration(sess);
         let crate = driver::phase_1_parse_input(sess, cfg.clone(), &input);
         let loader = &mut Loader::new(sess);
@@ -799,14 +799,14 @@ pub fn main_args(args: &[~str]) -> int {
     debug!("Will store workcache in {}", ws.display());
 
     // Wrap the rest in task::try in case of a condition failure in a task
-    let result = do task::try {
+    let result = task::try(proc() {
         BuildContext {
             context: context,
             sysroot: sysroot.clone(), // Currently, only tests override this
             workcache_context: api::default_context(sysroot.clone(),
                                                     default_workspace()).workcache_context
         }.run(command, args.clone())
-    };
+    });
     // FIXME #9262: This is using the same error code for all errors,
     // and at least one test case succeeds if rustpkg returns COPY_FAILED_CODE,
     // when actually, it might set the exit code for that even if a different
index 5ac62c5284e080f3713149d5f98552efab7997df..6b4f1c1ae1abc60c40fdd3e908369095d36ada3b 100644 (file)
@@ -78,8 +78,8 @@ fn prefixes(p: &Path) -> Prefixes {
 }
 
 struct Prefixes {
-    priv components: ~[~str],
-    priv remaining: ~[~str]
+    components: ~[~str],
+    remaining: ~[~str]
 }
 
 impl Iterator<(Path, Path)> for Prefixes {
@@ -459,7 +459,7 @@ fn build_crates(&self,
                                                subcfgs,
                                                opt,
                                                what);
-                    // XXX: result is an Option<Path>. The following code did not take that
+                    // FIXME: result is an Option<Path>. The following code did not take that
                     // into account. I'm not sure if the workcache really likes seeing the
                     // output as "Some(\"path\")". But I don't know what to do about it.
                     // FIXME (#9639): This needs to handle non-utf8 paths
index 909b25fe7563b2151e49f4bc974ac46c39181c6c..255172e0988a67a20864b146dca0c0c126c3651c 100644 (file)
@@ -51,11 +51,11 @@ fn read_u32v_be(dst: &mut[u32], input: &[u8]) {
     unsafe {
         let mut x: *mut i32 = transmute(dst.unsafe_mut_ref(0));
         let mut y: *i32 = transmute(input.unsafe_ref(0));
-        dst.len().times(|| {
+        for _ in range(0, dst.len()) {
             *x = to_be32(*y);
             x = x.offset(1);
             y = y.offset(1);
-        })
+        }
     }
 }
 
index bf8ec1e738cabc2538ef7f4702169681ef427bc7..091399c3fb7de274659d9b6e2b740cd35d7fde64 100644 (file)
@@ -353,7 +353,7 @@ fn lib_exists(repo: &Path, crate_id: &CrateId) -> bool {
     debug!("assert_lib_exists: checking whether {:?} exists", lib);
     lib.is_some() && {
         let libname = lib.get_ref();
-        libname.exists() && is_rwx(libname)
+        libname.exists()
     }
 }
 
@@ -437,7 +437,7 @@ fn built_library_exists(repo: &Path, short_name: &str) -> bool {
     let lib = built_library_in_workspace(&crate_id, repo);
     lib.is_some() && {
         let libname = lib.get_ref();
-        libname.exists() && is_rwx(libname)
+        libname.exists()
     }
 }
 
@@ -607,13 +607,13 @@ fn test_install_invalid() {
     let ctxt = fake_ctxt(sysroot, &temp_workspace);
 
     // Uses task::try because of #9001
-    let result = do task::try {
+    let result = task::try(proc() {
         let pkg_src = PkgSrc::new(temp_workspace.clone(),
                                   temp_workspace.clone(),
                                   false,
                                   crateid.clone());
         ctxt.install(pkg_src, &WhatToBuild::new(MaybeCustom, Everything));
-    };
+    });
     assert!(result.unwrap_err()
             .to_str().contains("supplied path for package dir does not exist"));
 }
@@ -634,7 +634,6 @@ fn test_install_valid_external() {
     let lib = installed_library_in_workspace(&temp_pkg_id, temp_workspace);
     debug!("lib = {:?}", lib);
     assert!(lib.as_ref().map_or(false, |l| l.exists()));
-    assert!(lib.as_ref().map_or(false, |l| is_rwx(l)));
 
     // And that the test and bench executables aren't installed
     assert!(!target_test_in_workspace(&temp_pkg_id, temp_workspace).exists());
@@ -758,7 +757,8 @@ fn test_package_request_version() {
         Some(p) => {
             debug!("installed: {}", p.display());
             let suffix = format!("0.3{}", os::consts::DLL_SUFFIX);
-            p.as_vec().ends_with(suffix.as_bytes())
+            p.as_vec().ends_with(suffix.as_bytes()) ||
+                p.as_vec().ends_with(bytes!("0.3.rlib"))
         }
         None    => false
     });
@@ -1770,11 +1770,8 @@ fn test_linker_build() {
     let matches = getopts([], optgroups());
     let options = build_session_options(~"rustpkg",
                                         matches.as_ref().unwrap(),
-                                        @diagnostic::DefaultEmitter as
-                                            @diagnostic::Emitter);
-    let sess = build_session(options,
-                             @diagnostic::DefaultEmitter as
-                                @diagnostic::Emitter);
+                                        @diagnostic::DefaultEmitter);
+    let sess = build_session(options, None, @diagnostic::DefaultEmitter);
     let test_sys = test_sysroot();
     // FIXME (#9639): This needs to handle non-utf8 paths
     let cc = get_cc_prog(sess);
@@ -2163,7 +2160,6 @@ fn test_installed_read_only() {
         built_library_in_workspace(&temp_pkg_id,
                                    &ws).expect("test_install_git: built lib should exist");
     assert!(built_lib.exists());
-    assert!(is_rwx(&built_lib));
 
     // Make sure sources are (a) under "build" and (b) read-only
     let temp_dir = format!("{}-{}", temp_pkg_id.path, temp_pkg_id.version_or_default());
index b6dba40ebd46aed7600e3d4b7053116c8ec355cb..dcc39ae0e92b43d9fe7ec20e138b05710f657969 100644 (file)
@@ -50,7 +50,7 @@ pub fn main() {
         prep.declare_input("file",
                            foo_c_name.as_str().unwrap().to_owned(),
                            digest_file_with_date(&foo_c_name));
-        let out_path = do prep.exec |exec| {
+        let out_path = prep.exec(|exec| {
             let out_path = api::build_library_in_workspace(exec,
                                                            &mut sub_cx.clone(),
                                                            "cdep",
@@ -60,7 +60,7 @@ pub fn main() {
                                                            "foo");
             let out_p = Path::new(out_path.unwrap());
             out_p.as_str().unwrap().to_owned()
-        };
+        });
         out_path
     });
     let out_lib_path = Path::new(out_lib_path);
@@ -68,14 +68,14 @@ pub fn main() {
     context.add_library_path(out_lib_path.dir_path());
 
     let context_clone = context.clone();
-    let task_res = do task::try {
+    let task_res = task::try(proc() {
         let mut cc = context_clone.clone();
         api::install_pkg(&mut cc,
                          os::getcwd(),
                          ~"cdep",
                          None,
                          ~[(~"binary", out_lib_path.clone()), (~"file", foo_c_name.clone())]);
-    };
+    });
 
     if task_res.is_err() {
         os::set_exit_status(COPY_FAILED_CODE);
index 57fcf564c5db2e24c07ac93cbad06d12aab79bb9..1f8962fbd3af085545e2bc94e2baaa930b4a0feb 100644 (file)
@@ -264,6 +264,7 @@ pub fn compile_input(context: &BuildContext,
     debug!("About to build session...");
 
     let sess = driver::build_session(options,
+                                     Some(in_file.clone()),
                                      @diagnostic::DefaultEmitter as
                                         @diagnostic::Emitter);
 
index aa4dda786e3c65ad1b02e69339e4d45590dcc26c..2740671c00d60489abb90b402fce4ddafa5ea4f8 100644 (file)
@@ -10,6 +10,7 @@
 
 use ai = std::io::net::addrinfo;
 use std::cast;
+use std::libc;
 use std::libc::c_int;
 use std::ptr::null;
 use std::rt::task::BlockedTask;
@@ -19,7 +20,7 @@
 use uvll;
 
 struct Addrinfo {
-    handle: *uvll::addrinfo,
+    handle: *libc::addrinfo,
 }
 
 struct Ctx {
@@ -62,7 +63,7 @@ pub fn run(loop_: &Loop, node: Option<&str>, service: Option<&str>,
             let socktype = 0;
             let protocol = 0;
 
-            uvll::addrinfo {
+            libc::addrinfo {
                 ai_flags: flags,
                 ai_family: hint.family as c_int,
                 ai_socktype: socktype,
@@ -73,7 +74,7 @@ pub fn run(loop_: &Loop, node: Option<&str>, service: Option<&str>,
                 ai_next: null(),
             }
         });
-        let hint_ptr = hint.as_ref().map_or(null(), |x| x as *uvll::addrinfo);
+        let hint_ptr = hint.as_ref().map_or(null(), |x| x as *libc::addrinfo);
         let mut req = Request::new(uvll::UV_GETADDRINFO);
 
         return match unsafe {
@@ -100,7 +101,7 @@ pub fn run(loop_: &Loop, node: Option<&str>, service: Option<&str>,
 
         extern fn getaddrinfo_cb(req: *uvll::uv_getaddrinfo_t,
                                  status: c_int,
-                                 res: *uvll::addrinfo) {
+                                 res: *libc::addrinfo) {
             let req = Request::wrap(req);
             assert!(status != uvll::ECANCELED);
             let cx: &mut Ctx = unsafe { req.get_data() };
@@ -182,39 +183,3 @@ pub fn accum_addrinfo(addr: &Addrinfo) -> ~[ai::Info] {
         return addrs;
     }
 }
-
-// cannot give tcp/ip permission without help of apk
-#[cfg(test, not(target_os="android"))]
-mod test {
-    use std::io::net::ip::{SocketAddr, Ipv4Addr};
-    use super::super::local_loop;
-    use super::GetAddrInfoRequest;
-
-    #[test]
-    fn getaddrinfo_test() {
-        let loop_ = &mut local_loop().loop_;
-        match GetAddrInfoRequest::run(loop_, Some("localhost"), None, None) {
-            Ok(infos) => {
-                let mut found_local = false;
-                let local_addr = &SocketAddr {
-                    ip: Ipv4Addr(127, 0, 0, 1),
-                    port: 0
-                };
-                for addr in infos.iter() {
-                    found_local = found_local || addr.address == *local_addr;
-                }
-                assert!(found_local);
-            }
-            Err(e) => fail!("{:?}", e),
-        }
-    }
-
-    #[test]
-    fn issue_10663() {
-        let loop_ = &mut local_loop().loop_;
-        // Something should happen here, but this certainly shouldn't cause
-        // everything to die. The actual outcome we don't care too much about.
-        GetAddrInfoRequest::run(loop_, Some("irc.n0v4.com"), None,
-                                None);
-    }
-}
index 5085dd64b6759cdd4e7472e399a5669f5f1669da..5dc50beb8506176648245916c9260aa21d63121c 100644 (file)
@@ -152,10 +152,10 @@ fn call(&mut self) {
         let watcher = AsyncWatcher::new(&mut local_loop().loop_,
                                         cb as ~Callback);
 
-        let thread = do Thread::start {
+        let thread = Thread::start(proc() {
             let mut watcher = watcher;
             watcher.fire();
-        };
+        });
 
         assert_eq!(port.recv(), 1);
         thread.join();
index 8f7ced93fb0c6a7defbc7fa3e19a65d3a99dd90c..31afa7b5c7c80edf626bd6614fa101b4fcc50411 100644 (file)
@@ -389,7 +389,7 @@ fn drop(&mut self) {
                 }
             }
             rtio::CloseSynchronously => {
-                execute_nop(|req, cb| unsafe {
+                let _ = execute_nop(|req, cb| unsafe {
                     uvll::uv_fs_close(self.loop_.handle, req, self.fd, cb)
                 });
             }
index 16534b7b38babbdbaf1a42d0f61a49e47a800ac6..8d3e71312cd9510be048e73c654541fd65b0962a 100644 (file)
@@ -126,7 +126,7 @@ fn fire_homing_missile(&mut self) -> HomingMissile {
 /// task back to its appropriate home (if applicable). The field is used to
 /// assert that we are where we think we are.
 struct HomingMissile {
-    priv io_home: uint,
+    io_home: uint,
 }
 
 impl HomingMissile {
@@ -170,14 +170,14 @@ fn test_homing_closes_correctly() {
             event_loop_factory: None,
         });
 
-        do pool.spawn(TaskOpts::new()) {
+        pool.spawn(TaskOpts::new(), proc() {
             let listener = UdpWatcher::bind(local_loop(), next_test_ip4());
             chan.send(listener.unwrap());
-        }
+        });
 
-        let task = do pool.task(TaskOpts::new()) {
+        let task = pool.task(TaskOpts::new(), proc() {
             port.recv();
-        };
+        });
         pool.spawn_sched().send(sched::TaskFromFriend(task));
 
         pool.shutdown();
@@ -191,20 +191,20 @@ fn test_homing_read() {
             event_loop_factory: None,
         });
 
-        do pool.spawn(TaskOpts::new()) {
+        pool.spawn(TaskOpts::new(), proc() {
             let addr1 = next_test_ip4();
             let addr2 = next_test_ip4();
             let listener = UdpWatcher::bind(local_loop(), addr2);
             chan.send((listener.unwrap(), addr1));
             let mut listener = UdpWatcher::bind(local_loop(), addr1).unwrap();
             listener.sendto([1, 2, 3, 4], addr2);
-        }
+        });
 
-        let task = do pool.task(TaskOpts::new()) {
+        let task = pool.task(TaskOpts::new(), proc() {
             let (mut watcher, addr) = port.recv();
             let mut buf = [0, ..10];
             assert_eq!(watcher.recvfrom(buf).unwrap(), (4, addr));
-        };
+        });
         pool.spawn_sched().send(sched::TaskFromFriend(task));
 
         pool.shutdown();
index 36305c26682afc39c6a9906e6b7f1e398204b0f0..0b889e17a445ea2eb3f62a2c8195f111c6cb7cb1 100644 (file)
@@ -259,7 +259,7 @@ fn drop(&mut self) {
     }
 }
 
-/// XXX: Loop(*handle) is buggy with destructors. Normal structs
+/// FIXME: Loop(*handle) is buggy with destructors. Normal structs
 /// with dtors may not be destructured, but tuple structs can,
 /// but the results are not correct.
 pub struct Loop {
@@ -284,7 +284,7 @@ pub fn close(&mut self) {
     }
 }
 
-// XXX: Need to define the error constants like EOF so they can be
+// FIXME: Need to define the error constants like EOF so they can be
 // compared to the UvError type
 
 pub struct UvError(c_int);
@@ -349,7 +349,7 @@ pub fn uv_error_to_io_error(uverr: UvError) -> IoError {
             uvll::EADDRNOTAVAIL => io::ConnectionRefused,
             err => {
                 uvdebug!("uverr.code {}", err as int);
-                // XXX: Need to map remaining uv error types
+                // FIXME: Need to map remaining uv error types
                 io::OtherIoError
             }
         };
@@ -433,10 +433,10 @@ fn test_slice_to_uv_buf() {
 
     #[test]
     fn loop_smoke_test() {
-        do run_in_bare_thread {
+        run_in_bare_thread(proc() {
             let mut loop_ = Loop::new();
             loop_.run();
             loop_.close();
-        }
+        });
     }
 }
index 004a014463514a20e0ec0e9685489f2b2607a503..8919ecfa97ef40308ee5928829f61c60920991ee 100644 (file)
@@ -338,12 +338,12 @@ fn socket_name(&mut self) -> Result<ip::SocketAddr, IoError> {
 }
 
 impl rtio::RtioTcpListener for TcpListener {
-    fn listen(mut ~self) -> Result<~rtio::RtioTcpAcceptor, IoError> {
+    fn listen(~self) -> Result<~rtio::RtioTcpAcceptor, IoError> {
         // create the acceptor object from ourselves
         let mut acceptor = ~TcpAcceptor { listener: self };
 
         let _m = acceptor.fire_homing_missile();
-        // XXX: the 128 backlog should be configurable
+        // FIXME: the 128 backlog should be configurable
         match unsafe { uvll::uv_listen(acceptor.listener.handle, 128, listen_cb) } {
             0 => Ok(acceptor as ~rtio::RtioTcpAcceptor),
             n => Err(uv_error_to_io_error(UvError(n))),
@@ -692,7 +692,7 @@ fn listen_ip4() {
         let (port, chan) = Chan::new();
         let addr = next_test_ip4();
 
-        do spawn {
+        spawn(proc() {
             let w = match TcpListener::bind(local_loop(), addr) {
                 Ok(w) => w, Err(e) => fail!("{:?}", e)
             };
@@ -712,7 +712,7 @@ fn listen_ip4() {
                 }
                 Err(e) => fail!("{:?}", e)
             }
-        }
+        });
 
         port.recv();
         let mut w = match TcpWatcher::connect(local_loop(), addr) {
@@ -728,7 +728,7 @@ fn listen_ip6() {
         let (port, chan) = Chan::new();
         let addr = next_test_ip6();
 
-        do spawn {
+        spawn(proc() {
             let w = match TcpListener::bind(local_loop(), addr) {
                 Ok(w) => w, Err(e) => fail!("{:?}", e)
             };
@@ -748,7 +748,7 @@ fn listen_ip6() {
                 }
                 Err(e) => fail!("{:?}", e)
             }
-        }
+        });
 
         port.recv();
         let mut w = match TcpWatcher::connect(local_loop(), addr) {
@@ -765,7 +765,7 @@ fn udp_recv_ip4() {
         let client = next_test_ip4();
         let server = next_test_ip4();
 
-        do spawn {
+        spawn(proc() {
             match UdpWatcher::bind(local_loop(), server) {
                 Ok(mut w) => {
                     chan.send(());
@@ -780,7 +780,7 @@ fn udp_recv_ip4() {
                 }
                 Err(e) => fail!("{:?}", e)
             }
-        }
+        });
 
         port.recv();
         let mut w = match UdpWatcher::bind(local_loop(), client) {
@@ -797,7 +797,7 @@ fn udp_recv_ip6() {
         let client = next_test_ip6();
         let server = next_test_ip6();
 
-        do spawn {
+        spawn(proc() {
             match UdpWatcher::bind(local_loop(), server) {
                 Ok(mut w) => {
                     chan.send(());
@@ -812,7 +812,7 @@ fn udp_recv_ip6() {
                 }
                 Err(e) => fail!("{:?}", e)
             }
-        }
+        });
 
         port.recv();
         let mut w = match UdpWatcher::bind(local_loop(), client) {
@@ -829,7 +829,7 @@ fn test_read_read_read() {
         static MAX: uint = 5000;
         let (port, chan) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             let listener = TcpListener::bind(local_loop(), addr).unwrap();
             let mut acceptor = listener.listen().unwrap();
             chan.send(());
@@ -841,7 +841,7 @@ fn test_read_read_read() {
                 uvdebug!("wrote bytes");
                 total_bytes_written += buf.len();
             }
-        }
+        });
 
         port.recv();
         let mut stream = TcpWatcher::connect(local_loop(), addr).unwrap();
@@ -864,12 +864,12 @@ fn test_udp_twice() {
         let client_addr = next_test_ip4();
         let (port, chan) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             let mut client = UdpWatcher::bind(local_loop(), client_addr).unwrap();
             port.recv();
             assert!(client.sendto([1], server_addr).is_ok());
             assert!(client.sendto([2], server_addr).is_ok());
-        }
+        });
 
         let mut server = UdpWatcher::bind(local_loop(), server_addr).unwrap();
         chan.send(());
@@ -896,7 +896,7 @@ fn test_udp_many_read() {
         let (p1, c1) = Chan::new();
         let (p2, c2) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             let l = local_loop();
             let mut server_out = UdpWatcher::bind(l, server_out_addr).unwrap();
             let mut server_in = UdpWatcher::bind(l, server_in_addr).unwrap();
@@ -918,7 +918,7 @@ fn test_udp_many_read() {
                 assert_eq!(src, client_out_addr);
             }
             assert!(total_bytes_sent >= MAX);
-        }
+        });
 
         let l = local_loop();
         let mut client_out = UdpWatcher::bind(l, client_out_addr).unwrap();
@@ -950,7 +950,7 @@ fn test_read_and_block() {
         let addr = next_test_ip4();
         let (port, chan) = Chan::<Port<()>>::new();
 
-        do spawn {
+        spawn(proc() {
             let port2 = port.recv();
             let mut stream = TcpWatcher::connect(local_loop(), addr).unwrap();
             stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
@@ -959,7 +959,7 @@ fn test_read_and_block() {
             stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
             stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
             port2.recv();
-        }
+        });
 
         let listener = TcpListener::bind(local_loop(), addr).unwrap();
         let mut acceptor = listener.listen().unwrap();
@@ -992,7 +992,7 @@ fn test_read_and_block() {
     fn test_simple_tcp_server_and_client_on_diff_threads() {
         let addr = next_test_ip4();
 
-        do spawn {
+        spawn(proc() {
             let listener = TcpListener::bind(local_loop(), addr).unwrap();
             let mut acceptor = listener.listen().unwrap();
             let mut stream = acceptor.accept().unwrap();
@@ -1002,7 +1002,7 @@ fn test_simple_tcp_server_and_client_on_diff_threads() {
             for i in range(0u, nread) {
                 assert_eq!(buf[i], i as u8);
             }
-        }
+        });
 
         let mut stream = TcpWatcher::connect(local_loop(), addr);
         while stream.is_err() {
@@ -1024,12 +1024,12 @@ fn tcp_stream_fail_cleanup() {
         let (port, chan) = Chan::new();
         let addr = next_test_ip4();
 
-        do spawn {
+        spawn(proc() {
             let w = TcpListener::bind(local_loop(), addr).unwrap();
             let mut w = w.listen().unwrap();
             chan.send(());
             w.accept();
-        }
+        });
         port.recv();
         let _w = TcpWatcher::connect(local_loop(), addr).unwrap();
         fail!();
@@ -1050,10 +1050,10 @@ fn udp_fail_other_task() {
         // force the handle to be created on a different scheduler, failure in
         // the original task will force a homing operation back to this
         // scheduler.
-        do spawn {
+        spawn(proc() {
             let w = UdpWatcher::bind(local_loop(), addr).unwrap();
             chan.send(w);
-        }
+        });
 
         let _w = port.recv();
         fail!();
index ff4481e8b97f45b588239b294f56a47590c0e595..cfe86d739abcf935c95fec374b3994e9fadd3003 100644 (file)
@@ -174,12 +174,12 @@ pub fn bind(io: &mut UvIoFactory, name: &CString)
 }
 
 impl RtioUnixListener for PipeListener {
-    fn listen(mut ~self) -> Result<~RtioUnixAcceptor, IoError> {
+    fn listen(~self) -> Result<~RtioUnixAcceptor, IoError> {
         // create the acceptor object from ourselves
         let mut acceptor = ~PipeAcceptor { listener: self };
 
         let _m = acceptor.fire_homing_missile();
-        // XXX: the 128 backlog should be configurable
+        // FIXME: the 128 backlog should be configurable
         match unsafe { uvll::uv_listen(acceptor.listener.pipe, 128, listen_cb) } {
             0 => Ok(acceptor as ~RtioUnixAcceptor),
             n => Err(uv_error_to_io_error(UvError(n))),
@@ -278,7 +278,7 @@ fn connect() {
         let path2 = path.clone();
         let (port, chan) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             let p = PipeListener::bind(local_loop(), &path2.to_c_str()).unwrap();
             let mut p = p.listen().unwrap();
             chan.send(());
@@ -287,7 +287,7 @@ fn connect() {
             assert!(client.read(buf).unwrap() == 1);
             assert_eq!(buf[0], 1);
             assert!(client.write([2]).is_ok());
-        }
+        });
         port.recv();
         let mut c = PipeWatcher::connect(local_loop(), &path.to_c_str()).unwrap();
         assert!(c.write([1]).is_ok());
@@ -302,12 +302,12 @@ fn connect_fail() {
         let path2 = path.clone();
         let (port, chan) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             let p = PipeListener::bind(local_loop(), &path2.to_c_str()).unwrap();
             let mut p = p.listen().unwrap();
             chan.send(());
             p.accept();
-        }
+        });
         port.recv();
         let _c = PipeWatcher::connect(local_loop(), &path.to_c_str()).unwrap();
         fail!()
index 6772c6d19361447a63b574a432c37281164792ed..8cb0c1f0a52d70c8b7fe54f9908d3c32f7131420 100644 (file)
@@ -85,9 +85,9 @@ fn closing_channel_during_drop_doesnt_kill_everything() {
         let _signal = SignalWatcher::new(local_loop(), signal::Interrupt,
                                          chan);
 
-        do spawn {
+        spawn(proc() {
             port.try_recv();
-        }
+        });
 
         // when we drop the SignalWatcher we're going to destroy the channel,
         // which must wake up the task on the other end
index 73173fc677e8f786c782afc3388e0fd7b6132d76..262952f8890cb7be7ad314ce8fca68bce0489ef7 100644 (file)
@@ -157,7 +157,7 @@ pub fn write(&mut self, buf: &[u8]) -> Result<(), UvError> {
     };
     // Stop reading so that no read callbacks are
     // triggered before the user calls `read` again.
-    // XXX: Is there a performance impact to calling
+    // FIXME: Is there a performance impact to calling
     // stop here?
     unsafe { assert_eq!(uvll::uv_read_stop(handle), 0); }
     rcx.result = nread;
index 4a0ad44d311476212545183411d6d9dc4e945c00..aeda1a45175eacdad0c943db86ebf3898f3ae12e 100644 (file)
@@ -245,9 +245,9 @@ fn closing_channel_during_drop_doesnt_kill_everything() {
         let mut timer = TimerWatcher::new(local_loop());
         let timer_port = timer.period(1000);
 
-        do spawn {
+        spawn(proc() {
             timer_port.recv_opt();
-        }
+        });
 
         // when we drop the TimerWatcher we're going to destroy the channel,
         // which must wake up the task on the other end
@@ -259,9 +259,9 @@ fn reset_doesnt_switch_tasks() {
         let mut timer = TimerWatcher::new(local_loop());
         let timer_port = timer.period(1000);
 
-        do spawn {
+        spawn(proc() {
             timer_port.recv_opt();
-        }
+        });
 
         timer.oneshot(1);
     }
@@ -271,9 +271,9 @@ fn reset_doesnt_switch_tasks2() {
         let mut timer = TimerWatcher::new(local_loop());
         let timer_port = timer.period(1000);
 
-        do spawn {
+        spawn(proc() {
             timer_port.recv_opt();
-        }
+        });
 
         timer.sleep(1);
     }
index dbf129d0b699c81ee7f6785b0498b2f9f6503838..e0bff059b0c91344305c64535150427b2538cc07 100644 (file)
@@ -111,16 +111,16 @@ pub fn new_loop() -> ~rtio::EventLoop {
 #[test]
 fn test_callback_run_once() {
     use std::rt::rtio::EventLoop;
-    do run_in_bare_thread {
+    run_in_bare_thread(proc() {
         let mut event_loop = UvEventLoop::new();
         let mut count = 0;
         let count_ptr: *mut int = &mut count;
-        do event_loop.callback {
+        event_loop.callback(proc() {
             unsafe { *count_ptr += 1 }
-        }
+        });
         event_loop.run();
         assert_eq!(count, 1);
-    }
+    });
 }
 
 pub struct UvIoFactory {
index 0a6e23e995640d443f1fc0d59f1e4f3812680b65..c5ff5c60b80c934083afce4dbb5bd052f80aa66d 100644 (file)
@@ -30,7 +30,7 @@
 #[allow(non_camel_case_types)]; // C types
 
 use std::libc::{size_t, c_int, c_uint, c_void, c_char, c_double};
-use std::libc::{ssize_t, sockaddr, free};
+use std::libc::{ssize_t, sockaddr, free, addrinfo};
 use std::libc;
 use std::rt::global_heap::malloc_raw;
 
@@ -249,45 +249,6 @@ pub fn is_dir(&self) -> bool {
                                       signum: c_int);
 pub type uv_fs_cb = extern "C" fn(req: *uv_fs_t);
 
-// XXX: This is a standard C type. Could probably be defined in libc
-#[cfg(target_os = "android")]
-#[cfg(target_os = "linux")]
-pub struct addrinfo {
-    ai_flags: c_int,
-    ai_family: c_int,
-    ai_socktype: c_int,
-    ai_protocol: c_int,
-    ai_addrlen: libc::socklen_t,
-    ai_addr: *sockaddr,
-    ai_canonname: *char,
-    ai_next: *addrinfo
-}
-
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "freebsd")]
-pub struct addrinfo {
-    ai_flags: c_int,
-    ai_family: c_int,
-    ai_socktype: c_int,
-    ai_protocol: c_int,
-    ai_addrlen: libc::socklen_t,
-    ai_canonname: *char,
-    ai_addr: *sockaddr,
-    ai_next: *addrinfo
-}
-
-#[cfg(windows)]
-pub struct addrinfo {
-    ai_flags: c_int,
-    ai_family: c_int,
-    ai_socktype: c_int,
-    ai_protocol: c_int,
-    ai_addrlen: size_t,
-    ai_canonname: *char,
-    ai_addr: *sockaddr,
-    ai_next: *addrinfo
-}
-
 #[cfg(unix)] pub type uv_uid_t = libc::types::os::arch::posix88::uid_t;
 #[cfg(unix)] pub type uv_gid_t = libc::types::os::arch::posix88::gid_t;
 #[cfg(windows)] pub type uv_uid_t = libc::c_uchar;
@@ -400,7 +361,7 @@ fn request_sanity_check() {
     }
 }
 
-// XXX Event loops ignore SIGPIPE by default.
+// FIXME Event loops ignore SIGPIPE by default.
 pub unsafe fn loop_new() -> *c_void {
     return rust_uv_loop_new();
 }
diff --git a/src/libstd/borrow.rs b/src/libstd/borrow.rs
deleted file mode 100644 (file)
index 66df433..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Utilities for references
-
-#[cfg(not(test))]
-use prelude::*;
-
-/// Cast a region pointer - &T - to a uint.
-#[inline]
-pub fn to_uint<T>(thing: &T) -> uint {
-    thing as *T as uint
-}
-
-/// Determine if two borrowed pointers point to the same thing.
-#[inline]
-pub fn ref_eq<'a, 'b, T>(thing: &'a T, other: &'b T) -> bool {
-    (thing as *T) == (other as *T)
-}
-
-// Equality for region pointers
-#[cfg(not(test))]
-impl<'a, T: Eq> Eq for &'a T {
-    #[inline]
-    fn eq(&self, other: & &'a T) -> bool {
-        *(*self) == *(*other)
-    }
-    #[inline]
-    fn ne(&self, other: & &'a T) -> bool {
-        *(*self) != *(*other)
-    }
-}
-
-// Comparison for region pointers
-#[cfg(not(test))]
-impl<'a, T: Ord> Ord for &'a T {
-    #[inline]
-    fn lt(&self, other: & &'a T) -> bool {
-        *(*self) < *(*other)
-    }
-    #[inline]
-    fn le(&self, other: & &'a T) -> bool {
-        *(*self) <= *(*other)
-    }
-    #[inline]
-    fn ge(&self, other: & &'a T) -> bool {
-        *(*self) >= *(*other)
-    }
-    #[inline]
-    fn gt(&self, other: & &'a T) -> bool {
-        *(*self) > *(*other)
-    }
-}
-
-#[cfg(not(test))]
-impl<'a, T: TotalOrd> TotalOrd for &'a T {
-    #[inline]
-    fn cmp(&self, other: & &'a T) -> Ordering { (**self).cmp(*other) }
-}
-
-#[cfg(not(test))]
-impl<'a, T: TotalEq> TotalEq for &'a T {
-    #[inline]
-    fn equals(&self, other: & &'a T) -> bool { (**self).equals(*other) }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::ref_eq;
-
-    #[test]
-    fn test_ref_eq() {
-        let x = 1;
-        let y = 1;
-
-        assert!(ref_eq(&x, &x));
-        assert!(!ref_eq(&x, &y));
-    }
-}
index 22e93e5819442bbadd7786b3cef9e91c8f0c2889..6e6aa9ad3faaf48f7b43e1ce1705e2d29f650214 100644 (file)
@@ -72,7 +72,7 @@
 use ptr;
 use str::StrSlice;
 use str;
-use vec::{CopyableVector, ImmutableVector, MutableVector};
+use vec::{CloneableVector, ImmutableVector, MutableVector};
 use vec;
 use unstable::intrinsics;
 
index 40c4ad842fffeb8104b335120384b92ab9910551..82c1ed7440c502f0b4e949844f939c1c1685af6f 100644 (file)
@@ -55,7 +55,7 @@ unsafe fn each_live_alloc(read_next_before: bool,
 
 #[cfg(unix)]
 fn debug_mem() -> bool {
-    // XXX: Need to port the environment struct to newsched
+    // FIXME: Need to port the environment struct to newsched
     false
 }
 
index 26d67daf7c147337e3ae247ac25e023dac42a705..7f8f74f1b641a7d42d64cd6c843ad88729d6b512 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
 //! ```rust,should_fail
 //! // Create a simple streaming channel
 //! let (port, chan) = Chan::new();
-//! do spawn {
+//! spawn(proc() {
 //!     chan.send(10);
-//! }
+//! })
 //! assert_eq!(port.recv(), 10);
 //!
 //! // Create a shared channel which can be sent along from many tasks
 //! let (port, chan) = SharedChan::new();
 //! for i in range(0, 10) {
 //!     let chan = chan.clone();
-//!     do spawn {
+//!     spawn(proc() {
 //!         chan.send(i);
-//!     }
+//!     })
 //! }
 //!
 //! for _ in range(0, 10) {
 use spsc = sync::spsc_queue;
 use mpsc = sync::mpsc_queue;
 
-pub use self::select::Select;
+pub use self::select::{Select, Handle};
 
 macro_rules! test (
     { fn $name:ident() $b:block $($a:attr)*} => (
@@ -264,7 +264,7 @@ fn f() $b
             $($a)* #[test] fn native() {
                 use native;
                 let (p, c) = Chan::new();
-                do native::task::spawn { c.send(f()) }
+                native::task::spawn(proc() { c.send(f()) });
                 p.recv();
             }
         }
@@ -367,7 +367,7 @@ struct Packet {
 // All implementations -- the fun part
 ///////////////////////////////////////////////////////////////////////////////
 
-static DISCONNECTED: int = int::min_value;
+static DISCONNECTED: int = int::MIN;
 static RESCHED_FREQ: int = 200;
 
 impl Packet {
@@ -962,9 +962,9 @@ pub fn stress_factor() -> uint {
 
     test!(fn smoke_threads() {
         let (p, c) = Chan::new();
-        do spawn {
+        spawn(proc() {
             c.send(1);
-        }
+        });
         assert_eq!(p.recv(), 1);
     })
 
@@ -990,18 +990,18 @@ pub fn stress_factor() -> uint {
 
     test!(fn port_gone_concurrent() {
         let (p, c) = Chan::new();
-        do spawn {
+        spawn(proc() {
             p.recv();
-        }
+        });
         loop { c.send(1) }
     } #[should_fail])
 
     test!(fn port_gone_concurrent_shared() {
         let (p, c) = SharedChan::new();
         let c1 = c.clone();
-        do spawn {
+        spawn(proc() {
             p.recv();
-        }
+        });
         loop {
             c.send(1);
             c1.send(1);
@@ -1024,18 +1024,18 @@ pub fn stress_factor() -> uint {
 
     test!(fn chan_gone_concurrent() {
         let (p, c) = Chan::new();
-        do spawn {
+        spawn(proc() {
             c.send(1);
             c.send(1);
-        }
+        });
         loop { p.recv(); }
     } #[should_fail])
 
     test!(fn stress() {
         let (p, c) = Chan::new();
-        do spawn {
+        spawn(proc() {
             for _ in range(0, 10000) { c.send(1); }
-        }
+        });
         for _ in range(0, 10000) {
             assert_eq!(p.recv(), 1);
         }
@@ -1047,7 +1047,7 @@ pub fn stress_factor() -> uint {
         let (p, c) = SharedChan::<int>::new();
         let (p1, c1) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             for _ in range(0, AMT * NTHREADS) {
                 assert_eq!(p.recv(), 1);
             }
@@ -1056,13 +1056,13 @@ pub fn stress_factor() -> uint {
                 _ => {}
             }
             c1.send(());
-        }
+        });
 
         for _ in range(0, NTHREADS) {
             let c = c.clone();
-            do spawn {
+            spawn(proc() {
                 for _ in range(0, AMT) { c.send(1); }
-            }
+            });
         }
         p1.recv();
     })
@@ -1073,20 +1073,20 @@ fn send_from_outside_runtime() {
         let (p1, c1) = Chan::new();
         let (port, chan) = SharedChan::new();
         let chan2 = chan.clone();
-        do spawn {
+        spawn(proc() {
             c1.send(());
             for _ in range(0, 40) {
                 assert_eq!(p.recv(), 1);
             }
             chan2.send(());
-        }
+        });
         p1.recv();
-        do native::task::spawn {
+        native::task::spawn(proc() {
             for _ in range(0, 40) {
                 c.send(1);
             }
             chan.send(());
-        }
+        });
         port.recv();
         port.recv();
     }
@@ -1095,12 +1095,12 @@ fn send_from_outside_runtime() {
     fn recv_from_outside_runtime() {
         let (p, c) = Chan::<int>::new();
         let (dp, dc) = Chan::new();
-        do native::task::spawn {
+        native::task::spawn(proc() {
             for _ in range(0, 40) {
                 assert_eq!(p.recv(), 1);
             }
             dc.send(());
-        };
+        });
         for _ in range(0, 40) {
             c.send(1);
         }
@@ -1113,16 +1113,16 @@ fn no_runtime() {
         let (p2, c2) = Chan::<int>::new();
         let (port, chan) = SharedChan::new();
         let chan2 = chan.clone();
-        do native::task::spawn {
+        native::task::spawn(proc() {
             assert_eq!(p1.recv(), 1);
             c2.send(2);
             chan2.send(());
-        }
-        do native::task::spawn {
+        });
+        native::task::spawn(proc() {
             c1.send(1);
             assert_eq!(p2.recv(), 2);
             chan.send(());
-        }
+        });
         port.recv();
         port.recv();
     }
@@ -1148,11 +1148,11 @@ fn no_runtime() {
 
     test!(fn oneshot_single_thread_recv_chan_close() {
         // Receiving on a closed chan will fail
-        let res = do task::try {
+        let res = task::try(proc() {
             let (port, chan) = Chan::<~int>::new();
             { let _c = chan; }
             port.recv();
-        };
+        });
         // What is our res?
         assert!(res.is_err());
     })
@@ -1208,79 +1208,79 @@ fn no_runtime() {
 
     test!(fn oneshot_multi_task_recv_then_send() {
         let (port, chan) = Chan::<~int>::new();
-        do spawn {
+        spawn(proc() {
             assert!(port.recv() == ~10);
-        }
+        });
 
         chan.send(~10);
     })
 
     test!(fn oneshot_multi_task_recv_then_close() {
         let (port, chan) = Chan::<~int>::new();
-        do spawn {
+        spawn(proc() {
             let _chan = chan;
-        }
-        let res = do task::try {
+        });
+        let res = task::try(proc() {
             assert!(port.recv() == ~10);
-        };
+        });
         assert!(res.is_err());
     })
 
     test!(fn oneshot_multi_thread_close_stress() {
-        stress_factor().times(|| {
+        for _ in range(0, stress_factor()) {
             let (port, chan) = Chan::<int>::new();
-            do spawn {
+            spawn(proc() {
                 let _p = port;
-            }
+            });
             let _chan = chan;
-        })
+        }
     })
 
     test!(fn oneshot_multi_thread_send_close_stress() {
-        stress_factor().times(|| {
+        for _ in range(0, stress_factor()) {
             let (port, chan) = Chan::<int>::new();
-            do spawn {
+            spawn(proc() {
                 let _p = port;
-            }
-            do task::try {
+            });
+            task::try(proc() {
                 chan.send(1);
-            };
-        })
+            });
+        }
     })
 
     test!(fn oneshot_multi_thread_recv_close_stress() {
-        stress_factor().times(|| {
+        for _ in range(0, stress_factor()) {
             let (port, chan) = Chan::<int>::new();
-            do spawn {
+            spawn(proc() {
                 let port = port;
-                let res = do task::try {
+                let res = task::try(proc() {
                     port.recv();
-                };
+                });
                 assert!(res.is_err());
-            };
-            do spawn {
+            });
+            spawn(proc() {
                 let chan = chan;
-                do spawn {
+                spawn(proc() {
                     let _chan = chan;
-                }
-            };
-        })
+                });
+            });
+        }
     })
 
     test!(fn oneshot_multi_thread_send_recv_stress() {
-        stress_factor().times(|| {
+        for _ in range(0, stress_factor()) {
             let (port, chan) = Chan::<~int>::new();
-            do spawn {
+            spawn(proc() {
                 chan.send(~10);
-            }
-            do spawn {
+            });
+            spawn(proc() {
                 assert!(port.recv() == ~10);
-            }
-        })
+            });
+        }
     })
 
     test!(fn stream_send_recv_stress() {
-        stress_factor().times(|| {
+        for _ in range(0, stress_factor()) {
             let (port, chan) = Chan::<~int>::new();
 
             send(chan, 0);
@@ -1289,56 +1289,56 @@ fn no_runtime() {
             fn send(chan: Chan<~int>, i: int) {
                 if i == 10 { return }
 
-                do spawn {
+                spawn(proc() {
                     chan.send(~i);
                     send(chan, i + 1);
-                }
+                });
             }
 
             fn recv(port: Port<~int>, i: int) {
                 if i == 10 { return }
 
-                do spawn {
+                spawn(proc() {
                     assert!(port.recv() == ~i);
                     recv(port, i + 1);
-                };
+                });
             }
-        })
+        }
     })
 
     test!(fn recv_a_lot() {
         // Regression test that we don't run out of stack in scheduler context
         let (port, chan) = Chan::new();
-        10000.times(|| { chan.send(()) });
-        10000.times(|| { port.recv() });
+        for _ in range(0, 10000) { chan.send(()); }
+        for _ in range(0, 10000) { port.recv(); }
     })
 
     test!(fn shared_chan_stress() {
         let (port, chan) = SharedChan::new();
         let total = stress_factor() + 100;
-        total.times(|| {
+        for _ in range(0, total) {
             let chan_clone = chan.clone();
-            do spawn {
+            spawn(proc() {
                 chan_clone.send(());
-            }
-        });
+            });
+        }
 
-        total.times(|| {
+        for _ in range(0, total) {
             port.recv();
-        });
+        }
     })
 
     test!(fn test_nested_recv_iter() {
         let (port, chan) = Chan::<int>::new();
         let (total_port, total_chan) = Chan::<int>::new();
 
-        do spawn {
+        spawn(proc() {
             let mut acc = 0;
             for x in port.iter() {
                 acc += x;
             }
             total_chan.send(acc);
-        }
+        });
 
         chan.send(3);
         chan.send(1);
@@ -1351,7 +1351,7 @@ fn recv(port: Port<~int>, i: int) {
         let (port, chan) = Chan::<int>::new();
         let (count_port, count_chan) = Chan::<int>::new();
 
-        do spawn {
+        spawn(proc() {
             let mut count = 0;
             for x in port.iter() {
                 if count >= 3 {
@@ -1361,7 +1361,7 @@ fn recv(port: Port<~int>, i: int) {
                 }
             }
             count_chan.send(count);
-        }
+        });
 
         chan.send(2);
         chan.send(2);
@@ -1375,14 +1375,14 @@ fn recv(port: Port<~int>, i: int) {
         let (p, c) = Chan::<int>::new();
         let (p1, c1) = Chan::<()>::new();
         let (p2, c2) = Chan::<()>::new();
-        do spawn {
+        spawn(proc() {
             p1.recv();
             c.send(1);
             c2.send(());
             p1.recv();
             drop(c);
             c2.send(());
-        }
+        });
 
         assert_eq!(p.try_recv(), Empty);
         c1.send(());
index 6a10ac56a4ef446b4a9d0cbaaedcdfc468beee38..a0db70117aa2bf6ddb4262afbfbd2de37aba228d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -89,12 +89,13 @@ pub struct Select {
 /// This handle is used to keep the port in the set as well as interact with the
 /// underlying port.
 pub struct Handle<'port, T> {
+    /// A unique ID for this Handle.
     id: uint,
     priv selector: &'port Select,
     priv port: &'port mut Port<T>,
 }
 
-struct Packets { priv cur: *mut Packet }
+struct Packets { cur: *mut Packet }
 
 impl Select {
     /// Creates a new selection structure. This set is initially empty and
@@ -182,7 +183,7 @@ pub fn wait(&self) -> uint {
             assert!(amt > 0);
 
             let mut ready_index = amt;
-            let mut ready_id = uint::max_value;
+            let mut ready_id = uint::MAX;
             let mut iter = self.iter().enumerate();
 
             // Acquire a number of blocking contexts, and block on each one
@@ -199,11 +200,14 @@ pub fn wait(&self) -> uint {
                 if (*packet).decrement() {
                     Ok(())
                 } else {
+                    // Empty to_wake first to avoid tripping an assertion in
+                    // abort_selection in the disconnected case.
+                    let task = (*packet).to_wake.take_unwrap();
                     (*packet).abort_selection(false);
                     (*packet).selecting.store(false, SeqCst);
                     ready_index = i;
                     ready_id = (*packet).selection_id;
-                    Err((*packet).to_wake.take_unwrap())
+                    Err(task)
                 }
             });
 
@@ -242,7 +246,7 @@ pub fn wait(&self) -> uint {
                 assert!(!(*packet).selecting.load(Relaxed));
             }
 
-            assert!(ready_id != uint::max_value);
+            assert!(ready_id != uint::MAX);
             return ready_id;
         }
     }
@@ -374,12 +378,12 @@ mod test {
         let (mut p2, _c2) = Chan::<int>::new();
         let (p3, c3) = Chan::<int>::new();
 
-        do spawn {
-            20.times(task::deschedule);
+        spawn(proc() {
+            for _ in range(0, 20) { task::deschedule(); }
             c1.send(1);
             p3.recv();
-            20.times(task::deschedule);
-        }
+            for _ in range(0, 20) { task::deschedule(); }
+        });
 
         select! (
             a = p1.recv() => { assert_eq!(a, 1); },
@@ -397,12 +401,12 @@ mod test {
         let (mut p2, c2) = Chan::<int>::new();
         let (p3, c3) = Chan::<()>::new();
 
-        do spawn {
-            20.times(task::deschedule);
+        spawn(proc() {
+            for _ in range(0, 20) { task::deschedule(); }
             c1.send(1);
             c2.send(2);
             p3.recv();
-        }
+        });
 
         select! (
             a = p1.recv() => { assert_eq!(a, 1); },
@@ -423,7 +427,7 @@ mod test {
         let (mut p2, c2) = Chan::<int>::new();
         let (p3, c3) = Chan::<()>::new();
 
-        do spawn {
+        spawn(proc() {
             for i in range(0, AMT) {
                 if i % 2 == 0 {
                     c1.send(i);
@@ -432,7 +436,7 @@ mod test {
                 }
                 p3.recv();
             }
-        }
+        });
 
         for i in range(0, AMT) {
             select! (
index 5b2a792a05b1099c06d64a51cd0ef969977eb6a8..111eb70eb204a2cadb3fd629fabbaf06c8d04587 100644 (file)
@@ -780,7 +780,7 @@ fn execute(&mut self, method: &rt::Method, arg: Argument) {
                         rt::Keyword(parse::One) => value == 1,
                         rt::Keyword(parse::Two) => value == 2,
 
-                        // XXX: Few/Many should have a user-specified boundary
+                        // FIXME: Few/Many should have a user-specified boundary
                         //      One possible option would be in the function
                         //      pointer of the 'arg: Argument' struct.
                         rt::Keyword(parse::Few) => value < 8,
@@ -1085,7 +1085,7 @@ fn fmt(c: &$signed, f: &mut Formatter) {
 macro_rules! floating(($ty:ident) => {
     impl Float for $ty {
         fn fmt(f: &$ty, fmt: &mut Formatter) {
-            // XXX: this shouldn't perform an allocation
+            // FIXME: this shouldn't perform an allocation
             let s = match fmt.precision {
                 Some(i) => ::$ty::to_str_exact(f.abs(), i),
                 None => ::$ty::to_str_digits(f.abs(), 6)
@@ -1096,7 +1096,7 @@ fn fmt(f: &$ty, fmt: &mut Formatter) {
 
     impl LowerExp for $ty {
         fn fmt(f: &$ty, fmt: &mut Formatter) {
-            // XXX: this shouldn't perform an allocation
+            // FIXME: this shouldn't perform an allocation
             let s = match fmt.precision {
                 Some(i) => ::$ty::to_str_exp_exact(f.abs(), i, false),
                 None => ::$ty::to_str_exp_digits(f.abs(), 6, false)
@@ -1107,7 +1107,7 @@ fn fmt(f: &$ty, fmt: &mut Formatter) {
 
     impl UpperExp for $ty {
         fn fmt(f: &$ty, fmt: &mut Formatter) {
-            // XXX: this shouldn't perform an allocation
+            // FIXME: this shouldn't perform an allocation
             let s = match fmt.precision {
                 Some(i) => ::$ty::to_str_exp_exact(f.abs(), i, true),
                 None => ::$ty::to_str_exp_digits(f.abs(), 6, true)
index 745273a1d74be3064559d44f578b0589a9ea86c7..64e42c5480f28bfdf86eaf50624a954d40c916bc 100644 (file)
@@ -230,7 +230,7 @@ pub fn get_ref<'a>(&'a self) -> &'a W { self.inner.get_ref() }
     /// Unwraps this buffer, returning the underlying writer.
     ///
     /// The internal buffer is flushed before returning the writer.
-    pub fn unwrap(mut self) -> W { self.inner.unwrap() }
+    pub fn unwrap(self) -> W { self.inner.unwrap() }
 }
 
 impl<W: Writer> Writer for LineBufferedWriter<W> {
index e15b9a861ca1bfd7a0cbd160c253aa073019f152..1eaa752d2a31a7e02aa5382a70b007db7ec9f757 100644 (file)
@@ -15,7 +15,7 @@
 use io;
 use option::{None, Option, Some};
 use super::{Reader, Writer};
-use vec::{bytes, CopyableVector, MutableVector, ImmutableVector};
+use vec::{bytes, CloneableVector, MutableVector, ImmutableVector};
 
 /// Allows reading from a port.
 ///
@@ -120,13 +120,13 @@ mod test {
     #[test]
     fn test_port_reader() {
         let (port, chan) = Chan::new();
-        do task::spawn {
+        task::spawn(proc() {
           chan.send(~[1u8, 2u8]);
           chan.send(~[]);
           chan.send(~[3u8, 4u8]);
           chan.send(~[5u8, 6u8]);
           chan.send(~[7u8, 8u8]);
-        }
+        });
 
         let mut reader = PortReader::new(port);
         let mut buf = ~[0u8, ..3];
@@ -172,7 +172,7 @@ fn test_chan_writer() {
         writer.write_be_u32(42);
 
         let wanted = ~[0u8, 0u8, 0u8, 42u8];
-        let got = do task::try { port.recv() }.unwrap();
+        let got = task::try(proc() { port.recv() }).unwrap();
         assert_eq!(wanted, got);
 
         let mut err = None;
index e58fcc16182363dcdd8f6bc19f4280d0e7df861d..26e0a0d09adb9d43659812a5f9e86e62cc23ea87 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -10,8 +10,8 @@
 
 //! Utility mixins that apply to all Readers and Writers
 
-// XXX: Not sure how this should be structured
-// XXX: Iteration should probably be considered separately
+// FIXME: Not sure how this should be structured
+// FIXME: Iteration should probably be considered separately
 
 use container::Container;
 use iter::Iterator;
@@ -401,7 +401,7 @@ fn read_to_end_error() {
 
     #[test]
     fn test_read_write_le_mem() {
-        let uints = [0, 1, 2, 42, 10_123, 100_123_456, ::u64::max_value];
+        let uints = [0, 1, 2, 42, 10_123, 100_123_456, ::u64::MAX];
 
         let mut writer = MemWriter::new();
         for i in uints.iter() {
@@ -417,7 +417,7 @@ fn test_read_write_le_mem() {
 
     #[test]
     fn test_read_write_be() {
-        let uints = [0, 1, 2, 42, 10_123, 100_123_456, ::u64::max_value];
+        let uints = [0, 1, 2, 42, 10_123, 100_123_456, ::u64::MAX];
 
         let mut writer = MemWriter::new();
         for i in uints.iter() {
@@ -432,7 +432,7 @@ fn test_read_write_be() {
 
     #[test]
     fn test_read_be_int_n() {
-        let ints = [::i32::min_value, -123456, -42, -5, 0, 1, ::i32::max_value];
+        let ints = [::i32::MIN, -123456, -42, -5, 0, 1, ::i32::MAX];
 
         let mut writer = MemWriter::new();
         for i in ints.iter() {
index cb98ff21105bba7eb386c7413bf255f482cd3044..8904101dd05ed1ec6b02e4310bc2822a950f3278 100644 (file)
@@ -175,7 +175,7 @@ pub fn path<'a>(&'a self) -> &'a Path {
     ///
     /// This function will raise on the `io_error` condition on failure.
     pub fn fsync(&mut self) {
-        self.fd.fsync().map_err(|e| io_error::cond.raise(e));
+        let _ = self.fd.fsync().map_err(|e| io_error::cond.raise(e));
     }
 
     /// This function is similar to `fsync`, except that it may not synchronize
@@ -187,7 +187,7 @@ pub fn fsync(&mut self) {
     ///
     /// This function will raise on the `io_error` condition on failure.
     pub fn datasync(&mut self) {
-        self.fd.datasync().map_err(|e| io_error::cond.raise(e));
+        let _ = self.fd.datasync().map_err(|e| io_error::cond.raise(e));
     }
 
     /// Either truncates or extends the underlying file, updating the size of
@@ -203,7 +203,7 @@ pub fn datasync(&mut self) {
     ///
     /// On error, this function will raise on the `io_error` condition.
     pub fn truncate(&mut self, size: i64) {
-        self.fd.truncate(size).map_err(|e| io_error::cond.raise(e));
+        let _ = self.fd.truncate(size).map_err(|e| io_error::cond.raise(e));
     }
 
     /// Tests whether this stream has reached EOF.
index 6c380be343c889b585894904d2c42a88b8640401..c185951fecac855562aec0c1c693693f010c226a 100644 (file)
@@ -17,7 +17,7 @@
 use super::{Reader, Writer, Seek, Buffer, IoError, SeekStyle, io_error,
             OtherIoError};
 use vec;
-use vec::{Vector, ImmutableVector, MutableVector, OwnedCopyableVector};
+use vec::{Vector, ImmutableVector, MutableVector, OwnedCloneableVector};
 
 /// Writes to an owned, growable byte vector
 ///
index 30827983360692f3029be5f6ddcbc55c8f5b26bd..cadcbdd51f57b2af5d5687159fed0a6ac67c238b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -84,7 +84,7 @@
     ```
 
 * Make an simple HTTP request
-  XXX This needs more improvement: TcpStream constructor taking &str,
+  FIXME This needs more improvement: TcpStream constructor taking &str,
   `write_str` and `write_line` methods.
 
     ```rust,should_fail
 * Connect based on URL? Requires thinking about where the URL type lives
   and how to make protocol handlers extensible, e.g. the "tcp" protocol
   yields a `TcpStream`.
-  XXX this is not implemented now.
+  FIXME this is not implemented now.
 
     ```rust
     // connect("tcp://localhost:8080");
 # ::std::io::fs::unlink(&Path::new("diary.txt"));
 ```
 
-XXX: Need better condition handling syntax
+FIXME: Need better condition handling syntax
 
 In this case the condition handler will have the opportunity to
 inspect the IoError raised by either the call to `new` or the call to
 In particular code written to ignore errors and expect conditions to be unhandled
 will start passing around null or zero objects when wrapped in a condition handler.
 
-* XXX: How should we use condition handlers that return values?
-* XXX: Should EOF raise default conditions when EOF is not an error?
+* FIXME: How should we use condition handlers that return values?
+* FIXME: Should EOF raise default conditions when EOF is not an error?
 
 # Issues with i/o scheduler affinity, work stealing, task pinning
 
 * Async I/O. We'll probably want it eventually
 
 
-# XXX Questions and issues
+# FIXME Questions and issues
 
 * Should default constructors take `Path` or `&str`? `Path` makes simple cases verbose.
   Overloading would be nice.
 use to_str::ToStr;
 use uint;
 use unstable::finally::Finally;
-use vec::{OwnedVector, MutableVector, ImmutableVector, OwnedCopyableVector};
+use vec::{OwnedVector, MutableVector, ImmutableVector, OwnedCloneableVector};
 use vec;
 
 // Reexports
 
 /// The type passed to I/O condition handlers to indicate error
 ///
-/// # XXX
+/// # FIXME
 ///
 /// Is something like this sufficient? It's kind of archaic
 pub struct IoError {
@@ -446,7 +446,7 @@ fn to_str(&self) -> ~str {
     }
 }
 
-// XXX: Can't put doc comments on macros
+// FIXME: Can't put doc comments on macros
 // Raised by `I/O` operations on error.
 condition! {
     pub io_error: IoError -> ();
@@ -491,9 +491,9 @@ pub trait Reader {
     /// Raises the `io_error` condition on error. If the condition
     /// is handled then no guarantee is made about the number of bytes
     /// read and the contents of `buf`. If the condition is handled
-    /// returns `None` (XXX see below).
+    /// returns `None` (FIXME see below).
     ///
-    /// # XXX
+    /// # FIXME
     ///
     /// * Should raise_default error on eof?
     /// * If the condition is handled it should still return the bytes read,
@@ -680,28 +680,28 @@ fn read_be_int_n(&mut self, nbytes: uint) -> i64 {
     ///
     /// The number of bytes returned is system-dependant.
     fn read_le_uint(&mut self) -> uint {
-        self.read_le_uint_n(uint::bytes) as uint
+        self.read_le_uint_n(uint::BYTES) as uint
     }
 
     /// Reads a little-endian integer.
     ///
     /// The number of bytes returned is system-dependant.
     fn read_le_int(&mut self) -> int {
-        self.read_le_int_n(int::bytes) as int
+        self.read_le_int_n(int::BYTES) as int
     }
 
     /// Reads a big-endian unsigned integer.
     ///
     /// The number of bytes returned is system-dependant.
     fn read_be_uint(&mut self) -> uint {
-        self.read_be_uint_n(uint::bytes) as uint
+        self.read_be_uint_n(uint::BYTES) as uint
     }
 
     /// Reads a big-endian integer.
     ///
     /// The number of bytes returned is system-dependant.
     fn read_be_int(&mut self) -> int {
-        self.read_be_int_n(int::bytes) as int
+        self.read_be_int_n(int::BYTES) as int
     }
 
     /// Reads a big-endian `u64`.
@@ -915,22 +915,22 @@ fn write_uint(&mut self, n: uint) {
 
     /// Write a little-endian uint (number of bytes depends on system).
     fn write_le_uint(&mut self, n: uint) {
-        extensions::u64_to_le_bytes(n as u64, uint::bytes, |v| self.write(v))
+        extensions::u64_to_le_bytes(n as u64, uint::BYTES, |v| self.write(v))
     }
 
     /// Write a little-endian int (number of bytes depends on system).
     fn write_le_int(&mut self, n: int) {
-        extensions::u64_to_le_bytes(n as u64, int::bytes, |v| self.write(v))
+        extensions::u64_to_le_bytes(n as u64, int::BYTES, |v| self.write(v))
     }
 
     /// Write a big-endian uint (number of bytes depends on system).
     fn write_be_uint(&mut self, n: uint) {
-        extensions::u64_to_be_bytes(n as u64, uint::bytes, |v| self.write(v))
+        extensions::u64_to_be_bytes(n as u64, uint::BYTES, |v| self.write(v))
     }
 
     /// Write a big-endian int (number of bytes depends on system).
     fn write_be_int(&mut self, n: int) {
-        extensions::u64_to_be_bytes(n as u64, int::bytes, |v| self.write(v))
+        extensions::u64_to_be_bytes(n as u64, int::BYTES, |v| self.write(v))
     }
 
     /// Write a big-endian u64 (8 bytes).
@@ -1218,7 +1218,7 @@ pub enum SeekStyle {
     SeekCur,
 }
 
-/// # XXX
+/// # FIXME
 /// * Are `u64` and `i64` the right choices?
 pub trait Seek {
     /// Return position of file cursor in the stream
@@ -1228,7 +1228,7 @@ pub trait Seek {
     ///
     /// A successful seek clears the EOF indicator.
     ///
-    /// # XXX
+    /// # FIXME
     ///
     /// * What is the behavior when seeking past the end of a stream?
     fn seek(&mut self, pos: i64, style: SeekStyle);
@@ -1268,7 +1268,7 @@ fn incoming<'r>(&'r mut self) -> IncomingConnections<'r, Self> {
 /// The Some contains another Option representing whether the connection attempt was succesful.
 /// A successful connection will be wrapped in Some.
 /// A failed connection is represented as a None and raises a condition.
-struct IncomingConnections<'a, A> {
+pub struct IncomingConnections<'a, A> {
     priv inc: &'a mut A,
 }
 
index fe29a112262283596d6cca7bacc69a9e15f50f57..a1650c9a3a33cf6e5c6e810745d9c6de03a796ea 100644 (file)
@@ -91,22 +91,22 @@ pub fn get_host_addresses(host: &str) -> Option<~[IpAddr]> {
 ///
 /// On failure, this will raise on the `io_error` condition.
 ///
-/// XXX: this is not public because the `Hint` structure is not ready for public
+/// FIXME: this is not public because the `Hint` structure is not ready for public
 ///      consumption just yet.
 fn lookup(hostname: Option<&str>, servname: Option<&str>, hint: Option<Hint>)
           -> Option<~[Info]> {
     LocalIo::maybe_raise(|io| io.get_host_addresses(hostname, servname, hint))
 }
 
-#[cfg(test)]
+// Ignored on android since we cannot give tcp/ip
+// permission without help of apk
+#[cfg(test, not(target_os = "android"))]
 mod test {
     use io::net::ip::Ipv4Addr;
     use prelude::*;
     use super::*;
 
-    #[test]
-    #[ignore(cfg(target_os="android"))] // cannot give tcp/ip permission without help of apk
-    fn dns_smoke_test() {
+    iotest!(fn dns_smoke_test() {
         let ipaddrs = get_host_addresses("localhost").unwrap();
         let mut found_local = false;
         let local_addr = &Ipv4Addr(127, 0, 0, 1);
@@ -114,5 +114,11 @@ fn dns_smoke_test() {
             found_local = found_local || addr == local_addr;
         }
         assert!(found_local);
-    }
+    })
+
+    iotest!(fn issue_10663() {
+        // Something should happen here, but this certainly shouldn't cause
+        // everything to die. The actual outcome we don't care too much about.
+        get_host_addresses("example.com");
+    } #[ignore])
 }
index b901ea99cbe3cb58b0147c56931ec0252e74a9e6..fc608ce25a66801720da18fad8125a5ad368f3bc 100644 (file)
@@ -167,11 +167,11 @@ mod test {
         let addr = next_test_ip4();
         let (port, chan) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             port.recv();
             let mut stream = TcpStream::connect(addr);
             stream.write([99]);
-        }
+        });
 
         let mut acceptor = TcpListener::bind(addr).listen();
         chan.send(());
@@ -185,11 +185,11 @@ mod test {
         let addr = next_test_ip6();
         let (port, chan) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             port.recv();
             let mut stream = TcpStream::connect(addr);
             stream.write([99]);
-        }
+        });
 
         let mut acceptor = TcpListener::bind(addr).listen();
         chan.send(());
@@ -203,11 +203,11 @@ mod test {
         let addr = next_test_ip4();
         let (port, chan) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             port.recv();
             let _stream = TcpStream::connect(addr);
             // Close
-        }
+        });
 
         let mut acceptor = TcpListener::bind(addr).listen();
         chan.send(());
@@ -221,11 +221,11 @@ mod test {
         let addr = next_test_ip6();
         let (port, chan) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             port.recv();
             let _stream = TcpStream::connect(addr);
             // Close
-        }
+        });
 
         let mut acceptor = TcpListener::bind(addr).listen();
         chan.send(());
@@ -239,11 +239,11 @@ mod test {
         let addr = next_test_ip4();
         let (port, chan) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             port.recv();
             let _stream = TcpStream::connect(addr);
             // Close
-        }
+        });
 
         let mut acceptor = TcpListener::bind(addr).listen();
         chan.send(());
@@ -267,11 +267,11 @@ mod test {
         let addr = next_test_ip6();
         let (port, chan) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             port.recv();
             let _stream = TcpStream::connect(addr);
             // Close
-        }
+        });
 
         let mut acceptor = TcpListener::bind(addr).listen();
         chan.send(());
@@ -295,11 +295,11 @@ mod test {
         let addr = next_test_ip4();
         let (port, chan) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             port.recv();
             let _stream = TcpStream::connect(addr);
             // Close
-        }
+        });
 
         let mut acceptor = TcpListener::bind(addr).listen();
         chan.send(());
@@ -326,11 +326,11 @@ mod test {
         let addr = next_test_ip6();
         let (port, chan) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             port.recv();
             let _stream = TcpStream::connect(addr);
             // Close
-        }
+        });
 
         let mut acceptor = TcpListener::bind(addr).listen();
         chan.send(());
@@ -355,16 +355,16 @@ mod test {
 
     iotest!(fn multiple_connect_serial_ip4() {
         let addr = next_test_ip4();
-        let max = 10;
+        let max = 10u;
         let (port, chan) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             port.recv();
-            max.times(|| {
+            for _ in range(0, max) {
                 let mut stream = TcpStream::connect(addr);
                 stream.write([99]);
-            });
-        }
+            }
+        });
 
         let mut acceptor = TcpListener::bind(addr).listen();
         chan.send(());
@@ -377,16 +377,16 @@ mod test {
 
     iotest!(fn multiple_connect_serial_ip6() {
         let addr = next_test_ip6();
-        let max = 10;
+        let max = 10u;
         let (port, chan) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             port.recv();
-            max.times(|| {
+            for _ in range(0, max) {
                 let mut stream = TcpStream::connect(addr);
                 stream.write([99]);
-            });
-        }
+            }
+        });
 
         let mut acceptor = TcpListener::bind(addr).listen();
         chan.send(());
@@ -402,20 +402,20 @@ mod test {
         static MAX: int = 10;
         let (port, chan) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             let mut acceptor = TcpListener::bind(addr).listen();
             chan.send(());
             for (i, stream) in acceptor.incoming().enumerate().take(MAX as uint) {
                 // Start another task to handle the connection
-                do spawn {
+                spawn(proc() {
                     let mut stream = stream;
                     let mut buf = [0];
                     stream.read(buf);
                     assert!(buf[0] == i as u8);
                     debug!("read");
-                }
+                });
             }
-        }
+        });
 
         port.recv();
         connect(0, addr);
@@ -423,14 +423,14 @@ mod test {
         fn connect(i: int, addr: SocketAddr) {
             if i == MAX { return }
 
-            do spawn {
+            spawn(proc() {
                 debug!("connecting");
                 let mut stream = TcpStream::connect(addr);
                 // Connect again before writing
                 connect(i + 1, addr);
                 debug!("writing");
                 stream.write([i as u8]);
-            }
+            });
         }
     })
 
@@ -439,20 +439,20 @@ fn connect(i: int, addr: SocketAddr) {
         static MAX: int = 10;
         let (port, chan) = Chan::<()>::new();
 
-        do spawn {
+        spawn(proc() {
             let mut acceptor = TcpListener::bind(addr).listen();
             chan.send(());
             for (i, stream) in acceptor.incoming().enumerate().take(MAX as uint) {
                 // Start another task to handle the connection
-                do spawn {
+                spawn(proc() {
                     let mut stream = stream;
                     let mut buf = [0];
                     stream.read(buf);
                     assert!(buf[0] == i as u8);
                     debug!("read");
-                }
+                });
             }
-        }
+        });
 
         port.recv();
         connect(0, addr);
@@ -460,14 +460,14 @@ fn connect(i: int, addr: SocketAddr) {
         fn connect(i: int, addr: SocketAddr) {
             if i == MAX { return }
 
-            do spawn {
+            spawn(proc() {
                 debug!("connecting");
                 let mut stream = TcpStream::connect(addr);
                 // Connect again before writing
                 connect(i + 1, addr);
                 debug!("writing");
                 stream.write([i as u8]);
-            }
+            });
         }
     })
 
@@ -476,20 +476,20 @@ fn connect(i: int, addr: SocketAddr) {
         static MAX: int = 10;
         let (port, chan) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             let mut acceptor = TcpListener::bind(addr).listen();
             chan.send(());
             for stream in acceptor.incoming().take(MAX as uint) {
                 // Start another task to handle the connection
-                do spawn {
+                spawn(proc() {
                     let mut stream = stream;
                     let mut buf = [0];
                     stream.read(buf);
                     assert!(buf[0] == 99);
                     debug!("read");
-                }
+                });
             }
-        }
+        });
 
         port.recv();
         connect(0, addr);
@@ -497,14 +497,14 @@ fn connect(i: int, addr: SocketAddr) {
         fn connect(i: int, addr: SocketAddr) {
             if i == MAX { return }
 
-            do spawn {
+            spawn(proc() {
                 debug!("connecting");
                 let mut stream = TcpStream::connect(addr);
                 // Connect again before writing
                 connect(i + 1, addr);
                 debug!("writing");
                 stream.write([99]);
-            }
+            });
         }
     })
 
@@ -513,20 +513,20 @@ fn connect(i: int, addr: SocketAddr) {
         static MAX: int = 10;
         let (port, chan) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             let mut acceptor = TcpListener::bind(addr).listen();
             chan.send(());
             for stream in acceptor.incoming().take(MAX as uint) {
                 // Start another task to handle the connection
-                do spawn {
+                spawn(proc() {
                     let mut stream = stream;
                     let mut buf = [0];
                     stream.read(buf);
                     assert!(buf[0] == 99);
                     debug!("read");
-                }
+                });
             }
-        }
+        });
 
         port.recv();
         connect(0, addr);
@@ -534,14 +534,14 @@ fn connect(i: int, addr: SocketAddr) {
         fn connect(i: int, addr: SocketAddr) {
             if i == MAX { return }
 
-            do spawn {
+            spawn(proc() {
                 debug!("connecting");
                 let mut stream = TcpStream::connect(addr);
                 // Connect again before writing
                 connect(i + 1, addr);
                 debug!("writing");
                 stream.write([99]);
-            }
+            });
         }
     })
 
@@ -558,11 +558,11 @@ pub fn socket_name(addr: SocketAddr) {
     pub fn peer_name(addr: SocketAddr) {
         let (port, chan) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             let mut acceptor = TcpListener::bind(addr).listen();
             chan.send(());
             acceptor.accept();
-        }
+        });
 
         port.recv();
         let stream = TcpStream::connect(addr);
@@ -584,7 +584,7 @@ pub fn peer_name(addr: SocketAddr) {
     })
 
     iotest!(fn socket_and_peer_name_ip6() {
-        // XXX: peer name is not consistent
+        // FIXME: peer name is not consistent
         //peer_name(next_test_ip6());
         socket_name(next_test_ip6());
     })
@@ -592,7 +592,7 @@ pub fn peer_name(addr: SocketAddr) {
     iotest!(fn partial_read() {
         let addr = next_test_ip4();
         let (p, c) = Chan::new();
-        do spawn {
+        spawn(proc() {
             let mut srv = TcpListener::bind(addr).listen();
             c.send(());
             let mut cl = srv.accept().unwrap();
@@ -600,7 +600,7 @@ pub fn peer_name(addr: SocketAddr) {
             let mut b = [0];
             cl.read(b);
             c.send(());
-        }
+        });
 
         p.recv();
         let mut c = TcpStream::connect(addr).unwrap();
@@ -609,4 +609,44 @@ pub fn peer_name(addr: SocketAddr) {
         c.write([1]);
         p.recv();
     })
+
+    iotest!(fn double_bind() {
+        let mut called = false;
+        io_error::cond.trap(|e| {
+            assert!(e.kind == ConnectionRefused || e.kind == OtherIoError);
+            called = true;
+        }).inside(|| {
+            let addr = next_test_ip4();
+            let listener = TcpListener::bind(addr).unwrap().listen();
+            assert!(listener.is_some());
+            let listener2 = TcpListener::bind(addr).and_then(|l|
+                                                    l.listen());
+            assert!(listener2.is_none());
+        });
+        assert!(called);
+    })
+
+    iotest!(fn fast_rebind() {
+        let addr = next_test_ip4();
+        let (port, chan) = Chan::new();
+
+        spawn(proc() {
+            port.recv();
+            let stream = TcpStream::connect(addr);
+            // Close
+            port.recv();
+        });
+
+        {
+            let mut acceptor = TcpListener::bind(addr).listen();
+            chan.send(());
+            {
+                let stream = acceptor.accept();
+                // Close client
+                chan.send(());
+            }
+            // Close listener
+        }
+        let listener = TcpListener::bind(addr);
+    })
 }
index 952ca7f730ed71dd1d1796189f81c527589da086..1cf30d469f7aa81d76982ea75a3a34bca0f6f4d8 100644 (file)
@@ -119,7 +119,7 @@ mod test {
         let (port, chan) = Chan::new();
         let (port2, chan2) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             match UdpSocket::bind(client_ip) {
                 Some(ref mut client) => {
                     port.recv();
@@ -128,7 +128,7 @@ mod test {
                 None => fail!()
             }
             chan2.send(());
-        }
+        });
 
         match UdpSocket::bind(server_ip) {
             Some(ref mut server) => {
@@ -153,7 +153,7 @@ mod test {
         let client_ip = next_test_ip6();
         let (port, chan) = Chan::<()>::new();
 
-        do spawn {
+        spawn(proc() {
             match UdpSocket::bind(client_ip) {
                 Some(ref mut client) => {
                     port.recv();
@@ -161,7 +161,7 @@ mod test {
                 }
                 None => fail!()
             }
-        }
+        });
 
         match UdpSocket::bind(server_ip) {
             Some(ref mut server) => {
@@ -186,7 +186,7 @@ mod test {
         let (port, chan) = Chan::new();
         let (port2, chan2) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             match UdpSocket::bind(client_ip) {
                 Some(client) => {
                     let client = ~client;
@@ -197,7 +197,7 @@ mod test {
                 None => fail!()
             }
             chan2.send(());
-        }
+        });
 
         match UdpSocket::bind(server_ip) {
             Some(server) => {
@@ -224,7 +224,7 @@ mod test {
         let (port, chan) = Chan::new();
         let (port2, chan2) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             match UdpSocket::bind(client_ip) {
                 Some(client) => {
                     let client = ~client;
@@ -235,7 +235,7 @@ mod test {
                 None => fail!()
             }
             chan2.send(());
-        }
+        });
 
         match UdpSocket::bind(server_ip) {
             Some(server) => {
index 232ca6705973298cc92539f37d329f329140af1d..d470e9bfda108d2cb2ab3ab17301c7881e1648d1 100644 (file)
@@ -147,10 +147,10 @@ fn smalltest(server: proc(UnixStream), client: proc(UnixStream)) {
         let path2 = path1.clone();
         let (port, chan) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             port.recv();
             client(UnixStream::connect(&path2).unwrap());
-        }
+        });
 
         let mut acceptor = UnixListener::bind(&path1).listen();
         chan.send(());
@@ -232,22 +232,22 @@ fn accept_lots() {
         let path2 = path1.clone();
         let (port, chan) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             port.recv();
-            times.times(|| {
+            for _ in range(0, times) {
                 let mut stream = UnixStream::connect(&path2);
                 stream.write([100]);
-            })
-        }
+            }
+        });
 
         let mut acceptor = UnixListener::bind(&path1).listen();
         chan.send(());
-        times.times(|| {
+        for _ in range(0, times) {
             let mut client = acceptor.accept();
             let mut buf = [0];
             client.read(buf);
             assert_eq!(buf[0], 100);
-        })
+        }
     }
 
     #[test]
index 799adff37e37f911d7c365ce510a06141ad26e6f..9919d333f41b4c80bda9726565c1d76ae53c7986 100644 (file)
@@ -89,11 +89,11 @@ mod test {
         let out = PipeStream::open(out);
         let mut input = PipeStream::open(input);
         let (p, c) = Chan::new();
-        do spawn {
+        spawn(proc() {
             let mut out = out;
             out.write([10]);
             p.recv(); // don't close the pipe until the other read has finished
-        }
+        });
 
         let mut buf = [0, ..10];
         input.read(buf);
index 0f05254b034896dc99a9efda17064e09ffa1b73a..5575e289b59a7a096a4acfc66ca1aece6cb66cdc 100644 (file)
@@ -65,14 +65,14 @@ pub enum Signum {
 /// let mut listener = Listener::new();
 /// listener.register(Interrupt);
 ///
-/// do spawn {
+/// spawn({
 ///     loop {
 ///         match listener.port.recv() {
 ///             Interrupt => println!("Got Interrupt'ed"),
 ///             _ => (),
 ///         }
 ///     }
-/// }
+/// });
 ///
 /// ```
 pub struct Listener {
index f3f071ab78bff6482c9c24afe1dd611f304e1600..d9fa2a4fc336bc63b65d0e3cc55c19e68560e473 100644 (file)
@@ -372,10 +372,10 @@ mod tests {
 
         let (p, c) = Chan::new();
         let (mut r, w) = (PortReader::new(p), ChanWriter::new(c));
-        do spawn {
+        spawn(proc() {
             set_stdout(~w as ~Writer);
             println!("hello!");
-        }
+        });
         assert_eq!(r.read_to_str(), ~"hello!\n");
     })
 
@@ -384,10 +384,10 @@ mod tests {
 
         let (p, c) = Chan::new();
         let (mut r, w) = (PortReader::new(p), ChanWriter::new(c));
-        do spawn {
+        spawn(proc() {
             set_stderr(~w as ~Writer);
             fail!("my special message");
-        }
+        });
         let s = r.read_to_str();
         assert!(s.contains("my special message"));
     })
index d81de989df7d849cad657b7225a0480e03ec20d3..6ac73e7f61e712c78a810bd16968562313786cd6 100644 (file)
@@ -45,7 +45,7 @@ fn f() $b
             $($a)* #[test] fn native() {
                 use native;
                 let (p, c) = Chan::new();
-                do native::task::spawn { c.send(f()) }
+                native::task::spawn(proc() { c.send(f()) });
                 p.recv();
             }
         }
index 4bf89a1d5596cb641df9048ac6a3f374e538e1fc..24eaf6adf3f3ead681439b736b3dbf66c4be7fa6 100644 (file)
@@ -204,9 +204,9 @@ mod test {
         let mut timer = Timer::new().unwrap();
         let timer_port = timer.periodic(1000);
 
-        do spawn {
+        spawn(proc() {
             timer_port.recv_opt();
-        }
+        });
 
         // when we drop the TimerWatcher we're going to destroy the channel,
         // which must wake up the task on the other end
@@ -217,9 +217,9 @@ mod test {
         let mut timer = Timer::new().unwrap();
         let timer_port = timer.periodic(1000);
 
-        do spawn {
+        spawn(proc() {
             timer_port.recv_opt();
-        }
+        });
 
         timer.oneshot(1);
     })
@@ -229,9 +229,9 @@ mod test {
         let mut timer = Timer::new().unwrap();
         let timer_port = timer.periodic(1000);
 
-        do spawn {
+        spawn(proc() {
             timer_port.recv_opt();
-        }
+        });
 
         timer.sleep(1);
     })
index a65da91437313b9b334712157539e35351a97744..5a38b7cb2e19686eaf0c7cccea4884197a55c249 100644 (file)
@@ -681,7 +681,7 @@ pub trait DoubleEndedIterator<A>: Iterator<A> {
     /// of the original iterator.
     ///
     /// Note: Random access with flipped indices still only applies to the first
-    /// `uint::max_value` elements of the original iterator.
+    /// `uint::MAX` elements of the original iterator.
     #[inline]
     fn rev(self) -> Rev<Self> {
         Rev{iter: self}
@@ -713,7 +713,7 @@ fn reverse_(&mut self) {
 ///
 /// A `RandomAccessIterator` should be either infinite or a `DoubleEndedIterator`.
 pub trait RandomAccessIterator<A>: Iterator<A> {
-    /// Return the number of indexable elements. At most `std::uint::max_value`
+    /// Return the number of indexable elements. At most `std::uint::MAX`
     /// elements are indexable, even if the iterator represents a longer range.
     fn indexable(&self) -> uint;
 
@@ -952,7 +952,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
         match self.orig.size_hint() {
             sz @ (0, Some(0)) => sz,
             (0, _) => (0, None),
-            _ => (uint::max_value, None)
+            _ => (uint::MAX, None)
         }
     }
 }
@@ -961,7 +961,7 @@ impl<A, T: Clone + RandomAccessIterator<A>> RandomAccessIterator<A> for Cycle<T>
     #[inline]
     fn indexable(&self) -> uint {
         if self.orig.indexable() > 0 {
-            uint::max_value
+            uint::MAX
         } else {
             0
         }
@@ -1366,7 +1366,7 @@ pub fn peek(&'a mut self) -> Option<&'a A> {
     /// Check whether peekable iterator is empty or not.
     #[inline]
     pub fn is_empty(&mut self) -> bool {
-        self.peek().is_some()
+        self.peek().is_none()
     }
 }
 
@@ -1823,7 +1823,7 @@ fn next(&mut self) -> Option<A> {
 
     #[inline]
     fn size_hint(&self) -> (uint, Option<uint>) {
-        (uint::max_value, None) // Too bad we can't specify an infinite lower bound
+        (uint::MAX, None) // Too bad we can't specify an infinite lower bound
     }
 }
 
@@ -2049,7 +2049,7 @@ impl<A: Clone> Iterator<A> for Repeat<A> {
     #[inline]
     fn next(&mut self) -> Option<A> { self.idx(0) }
     #[inline]
-    fn size_hint(&self) -> (uint, Option<uint>) { (uint::max_value, None) }
+    fn size_hint(&self) -> (uint, Option<uint>) { (uint::MAX, None) }
 }
 
 impl<A: Clone> DoubleEndedIterator<A> for Repeat<A> {
@@ -2059,7 +2059,7 @@ fn next_back(&mut self) -> Option<A> { self.idx(0) }
 
 impl<A: Clone> RandomAccessIterator<A> for Repeat<A> {
     #[inline]
-    fn indexable(&self) -> uint { uint::max_value }
+    fn indexable(&self) -> uint { uint::MAX }
     #[inline]
     fn idx(&self, _: uint) -> Option<A> { Some(self.element.clone()) }
 }
@@ -2417,7 +2417,7 @@ fn count(st: &mut uint) -> Option<uint> {
     fn test_cycle() {
         let cycle_len = 3;
         let it = count(0u, 1).take(cycle_len).cycle();
-        assert_eq!(it.size_hint(), (uint::max_value, None));
+        assert_eq!(it.size_hint(), (uint::MAX, None));
         for (i, x) in it.take(100).enumerate() {
             assert_eq!(i % cycle_len, x);
         }
@@ -2489,19 +2489,19 @@ fn test_iterator_size_hint() {
         let v2 = &[10, 11, 12];
         let vi = v.iter();
 
-        assert_eq!(c.size_hint(), (uint::max_value, None));
+        assert_eq!(c.size_hint(), (uint::MAX, None));
         assert_eq!(vi.size_hint(), (10, Some(10)));
 
         assert_eq!(c.take(5).size_hint(), (5, Some(5)));
         assert_eq!(c.skip(5).size_hint().second(), None);
         assert_eq!(c.take_while(|_| false).size_hint(), (0, None));
         assert_eq!(c.skip_while(|_| false).size_hint(), (0, None));
-        assert_eq!(c.enumerate().size_hint(), (uint::max_value, None));
-        assert_eq!(c.chain(vi.map(|&i| i)).size_hint(), (uint::max_value, None));
+        assert_eq!(c.enumerate().size_hint(), (uint::MAX, None));
+        assert_eq!(c.chain(vi.map(|&i| i)).size_hint(), (uint::MAX, None));
         assert_eq!(c.zip(vi).size_hint(), (10, Some(10)));
         assert_eq!(c.scan(0, |_,_| Some(0)).size_hint(), (0, None));
         assert_eq!(c.filter(|_| false).size_hint(), (0, None));
-        assert_eq!(c.map(|_| 0).size_hint(), (uint::max_value, None));
+        assert_eq!(c.map(|_| 0).size_hint(), (uint::MAX, None));
         assert_eq!(c.filter_map(|_| Some(0)).size_hint(), (0, None));
 
         assert_eq!(vi.take(5).size_hint(), (5, Some(5)));
@@ -2894,7 +2894,7 @@ fn one() -> Foo {
 
         assert_eq!(range(0i, 100).size_hint(), (100, Some(100)));
         // this test is only meaningful when sizeof uint < sizeof u64
-        assert_eq!(range(uint::max_value - 1, uint::max_value).size_hint(), (1, Some(1)));
+        assert_eq!(range(uint::MAX - 1, uint::MAX).size_hint(), (1, Some(1)));
         assert_eq!(range(-10i, -1).size_hint(), (9, Some(9)));
         assert_eq!(range(Foo, Foo).size_hint(), (0, None));
     }
@@ -2936,6 +2936,7 @@ fn test_reverse() {
         assert_eq!(ys, [5, 4, 3, 2, 1]);
     }
 
+    #[test]
     fn test_peekable_is_empty() {
         let a = [1];
         let mut it = a.iter().peekable();
index 7e53a0071bd1cc01f6ee06e61032765f80509ced..d7a7011319ae9afbd9f4d044b8f771dde7c73b1c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://static.rust-lang.org/doc/master")];
 
-#[feature(macro_rules, globs, asm, managed_boxes, thread_local, link_args)];
+#[feature(macro_rules, globs, asm, managed_boxes, thread_local, link_args, simd)];
 
 // Don't link to std. We are std.
 #[no_std];
 
 #[deny(non_camel_case_types)];
 #[deny(missing_doc)];
+#[allow(unknown_features)];
 
 // When testing libstd, bring in libuv as the I/O backend so tests can print
 // things and all of the std::io tests have an I/O interface to run on top
@@ -76,6 +77,8 @@
 #[cfg(test)] pub use ops = realstd::ops;
 #[cfg(test)] pub use cmp = realstd::cmp;
 
+mod macros;
+
 mod rtdeps;
 
 /* The Prelude. */
 pub mod ptr;
 pub mod owned;
 pub mod managed;
-pub mod borrow;
+mod reference;
 pub mod rc;
 pub mod gc;
 
@@ -220,7 +223,6 @@ mod std {
     pub use kinds;
     pub use local_data;
     pub use logging;
-    pub use logging;
     pub use option;
     pub use os;
     pub use rt;
index 6f2d64ff668215c105c10f0ab3b074bed4b31db0..dccadf2e00b70c0ea9328cc0618dc90e3e3ab685 100644 (file)
@@ -267,7 +267,7 @@ pub struct timespec {
                 pub enum timezone {}
             }
             pub mod bsd44 {
-                use libc::types::os::arch::c95::c_uint;
+                use libc::types::os::arch::c95::{c_char, c_int, c_uint};
 
                 pub type socklen_t = u32;
                 pub type sa_family_t = u16;
@@ -309,6 +309,16 @@ pub struct ip6_mreq {
                     ipv6mr_multiaddr: in6_addr,
                     ipv6mr_interface: c_uint,
                 }
+                pub struct addrinfo {
+                    ai_flags: c_int,
+                    ai_family: c_int,
+                    ai_socktype: c_int,
+                    ai_protocol: c_int,
+                    ai_addrlen: socklen_t,
+                    ai_addr: *sockaddr,
+                    ai_canonname: *c_char,
+                    ai_next: *addrinfo
+                }
             }
         }
 
@@ -624,7 +634,7 @@ pub struct timespec {
                 pub enum timezone {}
             }
             pub mod bsd44 {
-                use libc::types::os::arch::c95::c_uint;
+                use libc::types::os::arch::c95::{c_char, c_int, c_uint};
 
                 pub type socklen_t = u32;
                 pub type sa_family_t = u8;
@@ -671,6 +681,16 @@ pub struct ip6_mreq {
                     ipv6mr_multiaddr: in6_addr,
                     ipv6mr_interface: c_uint,
                 }
+                pub struct addrinfo {
+                    ai_flags: c_int,
+                    ai_family: c_int,
+                    ai_socktype: c_int,
+                    ai_protocol: c_int,
+                    ai_addrlen: socklen_t,
+                    ai_canonname: *c_char,
+                    ai_addr: *sockaddr,
+                    ai_next: *addrinfo
+                }
             }
         }
 
@@ -811,7 +831,7 @@ pub enum timezone {}
             }
 
             pub mod bsd44 {
-                use libc::types::os::arch::c95::{c_int, c_uint};
+                use libc::types::os::arch::c95::{c_char, c_int, c_uint, size_t};
 
                 pub type SOCKET = c_uint;
                 pub type socklen_t = c_int;
@@ -854,6 +874,16 @@ pub struct ip6_mreq {
                     ipv6mr_multiaddr: in6_addr,
                     ipv6mr_interface: c_uint,
                 }
+                pub struct addrinfo {
+                    ai_flags: c_int,
+                    ai_family: c_int,
+                    ai_socktype: c_int,
+                    ai_protocol: c_int,
+                    ai_addrlen: size_t,
+                    ai_canonname: *c_char,
+                    ai_addr: *sockaddr,
+                    ai_next: *addrinfo
+                }
             }
         }
 
@@ -1121,7 +1151,7 @@ pub enum timezone {}
             }
 
             pub mod bsd44 {
-                use libc::types::os::arch::c95::{c_int, c_uint};
+                use libc::types::os::arch::c95::{c_char, c_int, c_uint};
 
                 pub type socklen_t = c_int;
                 pub type sa_family_t = u8;
@@ -1168,6 +1198,16 @@ pub struct ip6_mreq {
                     ipv6mr_multiaddr: in6_addr,
                     ipv6mr_interface: c_uint,
                 }
+                pub struct addrinfo {
+                    ai_flags: c_int,
+                    ai_family: c_int,
+                    ai_socktype: c_int,
+                    ai_protocol: c_int,
+                    ai_addrlen: socklen_t,
+                    ai_canonname: *c_char,
+                    ai_addr: *sockaddr,
+                    ai_next: *addrinfo
+                }
             }
         }
 
@@ -1507,6 +1547,7 @@ pub mod bsd44 {
             pub static SOL_SOCKET: c_int = 0xffff;
             pub static SO_KEEPALIVE: c_int = 8;
             pub static SO_BROADCAST: c_int = 32;
+            pub static SO_REUSEADDR: c_int = 4;
         }
         pub mod extra {
             use libc::types::os::arch::c95::c_int;
@@ -2226,6 +2267,7 @@ pub mod bsd44 {
             pub static SOL_SOCKET: c_int = 1;
             pub static SO_KEEPALIVE: c_int = 9;
             pub static SO_BROADCAST: c_int = 6;
+            pub static SO_REUSEADDR: c_int = 2;
         }
         #[cfg(target_arch = "x86")]
         #[cfg(target_arch = "x86_64")]
@@ -2667,6 +2709,7 @@ pub mod bsd44 {
             pub static SOL_SOCKET: c_int = 0xffff;
             pub static SO_KEEPALIVE: c_int = 0x0008;
             pub static SO_BROADCAST: c_int = 0x0020;
+            pub static SO_REUSEADDR: c_int = 0x0004;
         }
         pub mod extra {
             use libc::types::os::arch::c95::c_int;
@@ -2823,6 +2866,7 @@ pub mod posix88 {
             pub static MAP_PRIVATE : c_int = 0x0002;
             pub static MAP_FIXED : c_int = 0x0010;
             pub static MAP_ANON : c_int = 0x1000;
+            pub static MAP_STACK : c_int = 0;
 
             pub static MAP_FAILED : *c_void = -1 as *c_void;
 
@@ -3042,6 +3086,7 @@ pub mod bsd44 {
             pub static SOL_SOCKET: c_int = 0xffff;
             pub static SO_KEEPALIVE: c_int = 0x0008;
             pub static SO_BROADCAST: c_int = 0x0020;
+            pub static SO_REUSEADDR: c_int = 0x0004;
         }
         pub mod extra {
             use libc::types::os::arch::c95::c_int;
index 7406fe8ee408d3ed4615e656b89cc6c880aead02..719cf2450c5054c964ff8ac4f79c7931f978302e 100644 (file)
@@ -355,14 +355,14 @@ mod tests {
     fn test_tls_multitask() {
         static my_key: Key<~str> = &Key;
         set(my_key, ~"parent data");
-        do task::spawn {
+        task::spawn(proc() {
             // TLS shouldn't carry over.
             assert!(get(my_key, |k| k.map(|k| (*k).clone())).is_none());
             set(my_key, ~"child data");
             assert!(get(my_key, |k| k.map(|k| (*k).clone())).unwrap() ==
                     ~"child data");
             // should be cleaned up for us
-        }
+        });
         // Must work multiple times
         assert!(get(my_key, |k| k.map(|k| (*k).clone())).unwrap() == ~"parent data");
         assert!(get(my_key, |k| k.map(|k| (*k).clone())).unwrap() == ~"parent data");
@@ -414,9 +414,9 @@ fn test_tls_crust_automorestack_memorial_bug() {
         // subsequent upcall (esp. for logging, think vsnprintf) would run on
         // a stack smaller than 1 MB.
         static my_key: Key<~str> = &Key;
-        do task::spawn {
+        task::spawn(proc() {
             set(my_key, ~"hax");
-        }
+        });
     }
 
     #[test]
@@ -424,11 +424,11 @@ fn test_tls_multiple_types() {
         static str_key: Key<~str> = &Key;
         static box_key: Key<@()> = &Key;
         static int_key: Key<int> = &Key;
-        do task::spawn {
+        task::spawn(proc() {
             set(str_key, ~"string data");
             set(box_key, @());
             set(int_key, 42);
-        }
+        });
     }
 
     #[test]
@@ -437,7 +437,7 @@ fn test_tls_overwrite_multiple_types() {
         static str_key: Key<~str> = &Key;
         static box_key: Key<@()> = &Key;
         static int_key: Key<int> = &Key;
-        do task::spawn {
+        task::spawn(proc() {
             set(str_key, ~"string data");
             set(str_key, ~"string data 2");
             set(box_key, @());
@@ -447,7 +447,7 @@ fn test_tls_overwrite_multiple_types() {
             // with the crazy polymorphic transmute rather than the provided
             // finaliser.
             set(int_key, 31337);
-        }
+        });
     }
 
     #[test]
@@ -458,13 +458,13 @@ fn test_tls_cleanup_on_failure() {
         static int_key: Key<int> = &Key;
         set(str_key, ~"parent data");
         set(box_key, @());
-        do task::spawn {
+        task::spawn(proc() {
             // spawn_linked
             set(str_key, ~"string data");
             set(box_key, @());
             set(int_key, 42);
             fail!();
-        }
+        });
         // Not quite nondeterministic.
         set(int_key, 31337);
         fail!();
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
new file mode 100644 (file)
index 0000000..4032b63
--- /dev/null
@@ -0,0 +1,199 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+#[macro_escape];
+
+#[macro_export]
+macro_rules! log(
+    ($lvl:expr, $($arg:tt)+) => ({
+        let lvl = $lvl;
+        if lvl <= __log_level() {
+            format_args!(|args| {
+                ::std::logging::log(lvl, args)
+            }, $($arg)+)
+        }
+    })
+)
+#[macro_export]
+macro_rules! error( ($($arg:tt)*) => (log!(1u32, $($arg)*)) )
+#[macro_export]
+macro_rules! warn ( ($($arg:tt)*) => (log!(2u32, $($arg)*)) )
+#[macro_export]
+macro_rules! info ( ($($arg:tt)*) => (log!(3u32, $($arg)*)) )
+#[macro_export]
+macro_rules! debug( ($($arg:tt)*) => (
+    if cfg!(not(ndebug)) { log!(4u32, $($arg)*) }
+))
+
+#[macro_export]
+macro_rules! log_enabled(
+    ($lvl:expr) => ( {
+        let lvl = $lvl;
+        lvl <= __log_level() && (lvl != 4 || cfg!(not(ndebug)))
+    } )
+)
+
+#[macro_export]
+macro_rules! fail(
+    () => (
+        fail!("explicit failure")
+    );
+    ($msg:expr) => (
+        ::std::rt::begin_unwind($msg, file!(), line!())
+    );
+    ($fmt:expr, $($arg:tt)*) => (
+        {
+            // a closure can't have return type !, so we need a full
+            // function to pass to format_args!, *and* we need the
+            // file and line numbers right here; so an inner bare fn
+            // is our only choice.
+            #[inline]
+            fn run_fmt(fmt: &::std::fmt::Arguments) -> ! {
+                ::std::rt::begin_unwind_fmt(fmt, file!(), line!())
+            }
+            format_args!(run_fmt, $fmt, $($arg)*)
+        }
+        )
+)
+
+#[macro_export]
+macro_rules! assert(
+    ($cond:expr) => {
+        if !$cond {
+            fail!("assertion failed: {:s}", stringify!($cond))
+        }
+    };
+    ($cond:expr, $msg:expr) => {
+        if !$cond {
+            fail!($msg)
+        }
+    };
+    ($cond:expr, $( $arg:expr ),+) => {
+        if !$cond {
+            fail!( $($arg),+ )
+        }
+    }
+)
+
+#[macro_export]
+macro_rules! assert_eq (
+    ($given:expr , $expected:expr) => (
+        {
+            let given_val = &($given);
+            let expected_val = &($expected);
+            // check both directions of equality....
+            if !((*given_val == *expected_val) &&
+                 (*expected_val == *given_val)) {
+                fail!("assertion failed: `(left == right) && (right == left)` \
+                       (left: `{:?}`, right: `{:?}`)", *given_val, *expected_val)
+            }
+        }
+    )
+)
+
+/// A utility macro for indicating unreachable code. It will fail if
+/// executed. This is occasionally useful to put after loops that never
+/// terminate normally, but instead directly return from a function.
+///
+/// # Example
+///
+/// ```rust
+/// fn choose_weighted_item(v: &[Item]) -> Item {
+///     assert!(!v.is_empty());
+///     let mut so_far = 0u;
+///     for item in v.iter() {
+///         so_far += item.weight;
+///         if so_far > 100 {
+///             return item;
+///         }
+///     }
+///     // The above loop always returns, so we must hint to the
+///     // type checker that it isn't possible to get down here
+///     unreachable!();
+/// }
+/// ```
+#[macro_export]
+macro_rules! unreachable (() => (
+    fail!("internal error: entered unreachable code");
+))
+
+#[macro_export]
+macro_rules! condition (
+
+    { pub $c:ident: $input:ty -> $out:ty; } => {
+
+        pub mod $c {
+            #[allow(unused_imports)];
+            #[allow(non_uppercase_statics)];
+            #[allow(missing_doc)];
+
+            use super::*;
+
+            local_data_key!(key: @::std::condition::Handler<$input, $out>)
+
+            pub static cond :
+                ::std::condition::Condition<$input,$out> =
+                ::std::condition::Condition {
+                    name: stringify!($c),
+                    key: key
+                };
+        }
+    };
+
+    { $c:ident: $input:ty -> $out:ty; } => {
+
+        mod $c {
+            #[allow(unused_imports)];
+            #[allow(non_uppercase_statics)];
+            #[allow(dead_code)];
+
+            use super::*;
+
+            local_data_key!(key: @::std::condition::Handler<$input, $out>)
+
+            pub static cond :
+                ::std::condition::Condition<$input,$out> =
+                ::std::condition::Condition {
+                    name: stringify!($c),
+                    key: key
+                };
+        }
+    }
+)
+
+#[macro_export]
+macro_rules! format(($($arg:tt)*) => (
+    format_args!(::std::fmt::format, $($arg)*)
+))
+#[macro_export]
+macro_rules! write(($dst:expr, $($arg:tt)*) => (
+    format_args!(|args| { ::std::fmt::write($dst, args) }, $($arg)*)
+))
+#[macro_export]
+macro_rules! writeln(($dst:expr, $($arg:tt)*) => (
+    format_args!(|args| { ::std::fmt::writeln($dst, args) }, $($arg)*)
+))
+#[macro_export]
+macro_rules! print (
+    ($($arg:tt)*) => (format_args!(::std::io::stdio::print_args, $($arg)*))
+)
+#[macro_export]
+macro_rules! println (
+    ($($arg:tt)*) => (format_args!(::std::io::stdio::println_args, $($arg)*))
+)
+
+#[macro_export]
+macro_rules! local_data_key (
+    ($name:ident: $ty:ty) => (
+        static $name: ::std::local_data::Key<$ty> = &::std::local_data::Key;
+    );
+    (pub $name:ident: $ty:ty) => (
+        pub static $name: ::std::local_data::Key<$ty> = &::std::local_data::Key;
+    )
+)
index dbc7c67d97b9eaa9d3d538b70dce4d0b92f2891a..96e182adb82e1e8b19f24ef8f74aa742f7500564 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -123,7 +123,7 @@ fn checked_mul(&self, v: &int) -> Option<int> {
 
 #[test]
 fn test_overflows() {
-    assert!((::int::max_value > 0));
-    assert!((::int::min_value <= 0));
-    assert!((::int::min_value + ::int::max_value + 1 == 0));
+    assert!((::int::MAX > 0));
+    assert!((::int::MIN <= 0));
+    assert!((::int::MIN + ::int::MAX + 1 == 0));
 }
index 7102a8997584e0991198436498648a09a33acbde..ca65ade40699c874336df9f3ba587924aa1568ed 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -15,23 +15,23 @@ macro_rules! int_module (($T:ty, $bits:expr) => (
 
 // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
 // calling the `mem::size_of` function.
-pub static bits : uint = $bits;
+pub static BITS : uint = $bits;
 // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
 // calling the `mem::size_of` function.
-pub static bytes : uint = ($bits / 8);
+pub static BYTES : uint = ($bits / 8);
 
 // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
 // calling the `Bounded::min_value` function.
-pub static min_value: $T = (-1 as $T) << (bits - 1);
-// FIXME(#9837): Compute min_value like this so the high bits that shouldn't exist are 0.
+pub static MIN: $T = (-1 as $T) << (BITS - 1);
+// FIXME(#9837): Compute MIN like this so the high bits that shouldn't exist are 0.
 // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
 // calling the `Bounded::max_value` function.
-pub static max_value: $T = !min_value;
+pub static MAX: $T = !MIN;
 
 impl CheckedDiv for $T {
     #[inline]
     fn checked_div(&self, v: &$T) -> Option<$T> {
-        if *v == 0 || (*self == min_value && *v == -1) {
+        if *v == 0 || (*self == MIN && *v == -1) {
             None
         } else {
             Some(self / *v)
@@ -361,10 +361,10 @@ fn not(&self) -> $T { !*self }
 
 impl Bounded for $T {
     #[inline]
-    fn min_value() -> $T { min_value }
+    fn min_value() -> $T { MIN }
 
     #[inline]
-    fn max_value() -> $T { max_value }
+    fn max_value() -> $T { MAX }
 }
 
 impl Int for $T {}
@@ -757,7 +757,7 @@ fn test_int_from_str_overflow() {
     fn test_signed_checked_div() {
         assert_eq!(10i.checked_div(&2), Some(5));
         assert_eq!(5i.checked_div(&0), None);
-        assert_eq!(int::min_value.checked_div(&-1), None);
+        assert_eq!(int::MIN.checked_div(&-1), None);
     }
 }
 
index 34dd313d4421f12a6a6d453c434ffa0e67c8f1f9..28f0cfbce1512294992ccc3df7bf5b2ab60b8885 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -139,18 +139,6 @@ pub trait Signed: Num
 
 pub trait Unsigned: Num {}
 
-/// Times trait
-///
-/// ```rust
-/// let ten = 10u;
-/// let mut accum = 0;
-/// ten.times(|| { accum += 1; })
-/// ```
-///
-pub trait Times {
-    fn times(&self, it: ||);
-}
-
 pub trait Integer: Num
                  + Orderable
                  + Div<Self,Self>
@@ -1159,25 +1147,25 @@ macro_rules! test_cast_20(
 
     #[test]
     fn test_cast_range_int_min() {
-        assert_eq!(int::min_value.to_int(),  Some(int::min_value as int));
-        assert_eq!(int::min_value.to_i8(),   None);
-        assert_eq!(int::min_value.to_i16(),  None);
-        // int::min_value.to_i32() is word-size specific
-        assert_eq!(int::min_value.to_i64(),  Some(int::min_value as i64));
-        assert_eq!(int::min_value.to_uint(), None);
-        assert_eq!(int::min_value.to_u8(),   None);
-        assert_eq!(int::min_value.to_u16(),  None);
-        assert_eq!(int::min_value.to_u32(),  None);
-        assert_eq!(int::min_value.to_u64(),  None);
+        assert_eq!(int::MIN.to_int(),  Some(int::MIN as int));
+        assert_eq!(int::MIN.to_i8(),   None);
+        assert_eq!(int::MIN.to_i16(),  None);
+        // int::MIN.to_i32() is word-size specific
+        assert_eq!(int::MIN.to_i64(),  Some(int::MIN as i64));
+        assert_eq!(int::MIN.to_uint(), None);
+        assert_eq!(int::MIN.to_u8(),   None);
+        assert_eq!(int::MIN.to_u16(),  None);
+        assert_eq!(int::MIN.to_u32(),  None);
+        assert_eq!(int::MIN.to_u64(),  None);
 
         #[cfg(target_word_size = "32")]
         fn check_word_size() {
-            assert_eq!(int::min_value.to_i32(), Some(int::min_value as i32));
+            assert_eq!(int::MIN.to_i32(), Some(int::MIN as i32));
         }
 
         #[cfg(target_word_size = "64")]
         fn check_word_size() {
-            assert_eq!(int::min_value.to_i32(), None);
+            assert_eq!(int::MIN.to_i32(), None);
         }
 
         check_word_size();
@@ -1185,67 +1173,67 @@ fn check_word_size() {
 
     #[test]
     fn test_cast_range_i8_min() {
-        assert_eq!(i8::min_value.to_int(),  Some(i8::min_value as int));
-        assert_eq!(i8::min_value.to_i8(),   Some(i8::min_value as i8));
-        assert_eq!(i8::min_value.to_i16(),  Some(i8::min_value as i16));
-        assert_eq!(i8::min_value.to_i32(),  Some(i8::min_value as i32));
-        assert_eq!(i8::min_value.to_i64(),  Some(i8::min_value as i64));
-        assert_eq!(i8::min_value.to_uint(), None);
-        assert_eq!(i8::min_value.to_u8(),   None);
-        assert_eq!(i8::min_value.to_u16(),  None);
-        assert_eq!(i8::min_value.to_u32(),  None);
-        assert_eq!(i8::min_value.to_u64(),  None);
+        assert_eq!(i8::MIN.to_int(),  Some(i8::MIN as int));
+        assert_eq!(i8::MIN.to_i8(),   Some(i8::MIN as i8));
+        assert_eq!(i8::MIN.to_i16(),  Some(i8::MIN as i16));
+        assert_eq!(i8::MIN.to_i32(),  Some(i8::MIN as i32));
+        assert_eq!(i8::MIN.to_i64(),  Some(i8::MIN as i64));
+        assert_eq!(i8::MIN.to_uint(), None);
+        assert_eq!(i8::MIN.to_u8(),   None);
+        assert_eq!(i8::MIN.to_u16(),  None);
+        assert_eq!(i8::MIN.to_u32(),  None);
+        assert_eq!(i8::MIN.to_u64(),  None);
     }
 
     #[test]
     fn test_cast_range_i16_min() {
-        assert_eq!(i16::min_value.to_int(),  Some(i16::min_value as int));
-        assert_eq!(i16::min_value.to_i8(),   None);
-        assert_eq!(i16::min_value.to_i16(),  Some(i16::min_value as i16));
-        assert_eq!(i16::min_value.to_i32(),  Some(i16::min_value as i32));
-        assert_eq!(i16::min_value.to_i64(),  Some(i16::min_value as i64));
-        assert_eq!(i16::min_value.to_uint(), None);
-        assert_eq!(i16::min_value.to_u8(),   None);
-        assert_eq!(i16::min_value.to_u16(),  None);
-        assert_eq!(i16::min_value.to_u32(),  None);
-        assert_eq!(i16::min_value.to_u64(),  None);
+        assert_eq!(i16::MIN.to_int(),  Some(i16::MIN as int));
+        assert_eq!(i16::MIN.to_i8(),   None);
+        assert_eq!(i16::MIN.to_i16(),  Some(i16::MIN as i16));
+        assert_eq!(i16::MIN.to_i32(),  Some(i16::MIN as i32));
+        assert_eq!(i16::MIN.to_i64(),  Some(i16::MIN as i64));
+        assert_eq!(i16::MIN.to_uint(), None);
+        assert_eq!(i16::MIN.to_u8(),   None);
+        assert_eq!(i16::MIN.to_u16(),  None);
+        assert_eq!(i16::MIN.to_u32(),  None);
+        assert_eq!(i16::MIN.to_u64(),  None);
     }
 
     #[test]
     fn test_cast_range_i32_min() {
-        assert_eq!(i32::min_value.to_int(),  Some(i32::min_value as int));
-        assert_eq!(i32::min_value.to_i8(),   None);
-        assert_eq!(i32::min_value.to_i16(),  None);
-        assert_eq!(i32::min_value.to_i32(),  Some(i32::min_value as i32));
-        assert_eq!(i32::min_value.to_i64(),  Some(i32::min_value as i64));
-        assert_eq!(i32::min_value.to_uint(), None);
-        assert_eq!(i32::min_value.to_u8(),   None);
-        assert_eq!(i32::min_value.to_u16(),  None);
-        assert_eq!(i32::min_value.to_u32(),  None);
-        assert_eq!(i32::min_value.to_u64(),  None);
+        assert_eq!(i32::MIN.to_int(),  Some(i32::MIN as int));
+        assert_eq!(i32::MIN.to_i8(),   None);
+        assert_eq!(i32::MIN.to_i16(),  None);
+        assert_eq!(i32::MIN.to_i32(),  Some(i32::MIN as i32));
+        assert_eq!(i32::MIN.to_i64(),  Some(i32::MIN as i64));
+        assert_eq!(i32::MIN.to_uint(), None);
+        assert_eq!(i32::MIN.to_u8(),   None);
+        assert_eq!(i32::MIN.to_u16(),  None);
+        assert_eq!(i32::MIN.to_u32(),  None);
+        assert_eq!(i32::MIN.to_u64(),  None);
     }
 
     #[test]
     fn test_cast_range_i64_min() {
-        // i64::min_value.to_int() is word-size specific
-        assert_eq!(i64::min_value.to_i8(),   None);
-        assert_eq!(i64::min_value.to_i16(),  None);
-        assert_eq!(i64::min_value.to_i32(),  None);
-        assert_eq!(i64::min_value.to_i64(),  Some(i64::min_value as i64));
-        assert_eq!(i64::min_value.to_uint(), None);
-        assert_eq!(i64::min_value.to_u8(),   None);
-        assert_eq!(i64::min_value.to_u16(),  None);
-        assert_eq!(i64::min_value.to_u32(),  None);
-        assert_eq!(i64::min_value.to_u64(),  None);
+        // i64::MIN.to_int() is word-size specific
+        assert_eq!(i64::MIN.to_i8(),   None);
+        assert_eq!(i64::MIN.to_i16(),  None);
+        assert_eq!(i64::MIN.to_i32(),  None);
+        assert_eq!(i64::MIN.to_i64(),  Some(i64::MIN as i64));
+        assert_eq!(i64::MIN.to_uint(), None);
+        assert_eq!(i64::MIN.to_u8(),   None);
+        assert_eq!(i64::MIN.to_u16(),  None);
+        assert_eq!(i64::MIN.to_u32(),  None);
+        assert_eq!(i64::MIN.to_u64(),  None);
 
         #[cfg(target_word_size = "32")]
         fn check_word_size() {
-            assert_eq!(i64::min_value.to_int(), None);
+            assert_eq!(i64::MIN.to_int(), None);
         }
 
         #[cfg(target_word_size = "64")]
         fn check_word_size() {
-            assert_eq!(i64::min_value.to_int(), Some(i64::min_value as int));
+            assert_eq!(i64::MIN.to_int(), Some(i64::MIN as int));
         }
 
         check_word_size();
@@ -1253,26 +1241,26 @@ fn check_word_size() {
 
     #[test]
     fn test_cast_range_int_max() {
-        assert_eq!(int::max_value.to_int(),  Some(int::max_value as int));
-        assert_eq!(int::max_value.to_i8(),   None);
-        assert_eq!(int::max_value.to_i16(),  None);
-        // int::max_value.to_i32() is word-size specific
-        assert_eq!(int::max_value.to_i64(),  Some(int::max_value as i64));
-        assert_eq!(int::max_value.to_u8(),   None);
-        assert_eq!(int::max_value.to_u16(),  None);
-        // int::max_value.to_u32() is word-size specific
-        assert_eq!(int::max_value.to_u64(),  Some(int::max_value as u64));
+        assert_eq!(int::MAX.to_int(),  Some(int::MAX as int));
+        assert_eq!(int::MAX.to_i8(),   None);
+        assert_eq!(int::MAX.to_i16(),  None);
+        // int::MAX.to_i32() is word-size specific
+        assert_eq!(int::MAX.to_i64(),  Some(int::MAX as i64));
+        assert_eq!(int::MAX.to_u8(),   None);
+        assert_eq!(int::MAX.to_u16(),  None);
+        // int::MAX.to_u32() is word-size specific
+        assert_eq!(int::MAX.to_u64(),  Some(int::MAX as u64));
 
         #[cfg(target_word_size = "32")]
         fn check_word_size() {
-            assert_eq!(int::max_value.to_i32(), Some(int::max_value as i32));
-            assert_eq!(int::max_value.to_u32(), Some(int::max_value as u32));
+            assert_eq!(int::MAX.to_i32(), Some(int::MAX as i32));
+            assert_eq!(int::MAX.to_u32(), Some(int::MAX as u32));
         }
 
         #[cfg(target_word_size = "64")]
         fn check_word_size() {
-            assert_eq!(int::max_value.to_i32(), None);
-            assert_eq!(int::max_value.to_u32(), None);
+            assert_eq!(int::MAX.to_i32(), None);
+            assert_eq!(int::MAX.to_u32(), None);
         }
 
         check_word_size();
@@ -1280,69 +1268,69 @@ fn check_word_size() {
 
     #[test]
     fn test_cast_range_i8_max() {
-        assert_eq!(i8::max_value.to_int(),  Some(i8::max_value as int));
-        assert_eq!(i8::max_value.to_i8(),   Some(i8::max_value as i8));
-        assert_eq!(i8::max_value.to_i16(),  Some(i8::max_value as i16));
-        assert_eq!(i8::max_value.to_i32(),  Some(i8::max_value as i32));
-        assert_eq!(i8::max_value.to_i64(),  Some(i8::max_value as i64));
-        assert_eq!(i8::max_value.to_uint(), Some(i8::max_value as uint));
-        assert_eq!(i8::max_value.to_u8(),   Some(i8::max_value as u8));
-        assert_eq!(i8::max_value.to_u16(),  Some(i8::max_value as u16));
-        assert_eq!(i8::max_value.to_u32(),  Some(i8::max_value as u32));
-        assert_eq!(i8::max_value.to_u64(),  Some(i8::max_value as u64));
+        assert_eq!(i8::MAX.to_int(),  Some(i8::MAX as int));
+        assert_eq!(i8::MAX.to_i8(),   Some(i8::MAX as i8));
+        assert_eq!(i8::MAX.to_i16(),  Some(i8::MAX as i16));
+        assert_eq!(i8::MAX.to_i32(),  Some(i8::MAX as i32));
+        assert_eq!(i8::MAX.to_i64(),  Some(i8::MAX as i64));
+        assert_eq!(i8::MAX.to_uint(), Some(i8::MAX as uint));
+        assert_eq!(i8::MAX.to_u8(),   Some(i8::MAX as u8));
+        assert_eq!(i8::MAX.to_u16(),  Some(i8::MAX as u16));
+        assert_eq!(i8::MAX.to_u32(),  Some(i8::MAX as u32));
+        assert_eq!(i8::MAX.to_u64(),  Some(i8::MAX as u64));
     }
 
     #[test]
     fn test_cast_range_i16_max() {
-        assert_eq!(i16::max_value.to_int(),  Some(i16::max_value as int));
-        assert_eq!(i16::max_value.to_i8(),   None);
-        assert_eq!(i16::max_value.to_i16(),  Some(i16::max_value as i16));
-        assert_eq!(i16::max_value.to_i32(),  Some(i16::max_value as i32));
-        assert_eq!(i16::max_value.to_i64(),  Some(i16::max_value as i64));
-        assert_eq!(i16::max_value.to_uint(), Some(i16::max_value as uint));
-        assert_eq!(i16::max_value.to_u8(),   None);
-        assert_eq!(i16::max_value.to_u16(),  Some(i16::max_value as u16));
-        assert_eq!(i16::max_value.to_u32(),  Some(i16::max_value as u32));
-        assert_eq!(i16::max_value.to_u64(),  Some(i16::max_value as u64));
+        assert_eq!(i16::MAX.to_int(),  Some(i16::MAX as int));
+        assert_eq!(i16::MAX.to_i8(),   None);
+        assert_eq!(i16::MAX.to_i16(),  Some(i16::MAX as i16));
+        assert_eq!(i16::MAX.to_i32(),  Some(i16::MAX as i32));
+        assert_eq!(i16::MAX.to_i64(),  Some(i16::MAX as i64));
+        assert_eq!(i16::MAX.to_uint(), Some(i16::MAX as uint));
+        assert_eq!(i16::MAX.to_u8(),   None);
+        assert_eq!(i16::MAX.to_u16(),  Some(i16::MAX as u16));
+        assert_eq!(i16::MAX.to_u32(),  Some(i16::MAX as u32));
+        assert_eq!(i16::MAX.to_u64(),  Some(i16::MAX as u64));
     }
 
     #[test]
     fn test_cast_range_i32_max() {
-        assert_eq!(i32::max_value.to_int(),  Some(i32::max_value as int));
-        assert_eq!(i32::max_value.to_i8(),   None);
-        assert_eq!(i32::max_value.to_i16(),  None);
-        assert_eq!(i32::max_value.to_i32(),  Some(i32::max_value as i32));
-        assert_eq!(i32::max_value.to_i64(),  Some(i32::max_value as i64));
-        assert_eq!(i32::max_value.to_uint(), Some(i32::max_value as uint));
-        assert_eq!(i32::max_value.to_u8(),   None);
-        assert_eq!(i32::max_value.to_u16(),  None);
-        assert_eq!(i32::max_value.to_u32(),  Some(i32::max_value as u32));
-        assert_eq!(i32::max_value.to_u64(),  Some(i32::max_value as u64));
+        assert_eq!(i32::MAX.to_int(),  Some(i32::MAX as int));
+        assert_eq!(i32::MAX.to_i8(),   None);
+        assert_eq!(i32::MAX.to_i16(),  None);
+        assert_eq!(i32::MAX.to_i32(),  Some(i32::MAX as i32));
+        assert_eq!(i32::MAX.to_i64(),  Some(i32::MAX as i64));
+        assert_eq!(i32::MAX.to_uint(), Some(i32::MAX as uint));
+        assert_eq!(i32::MAX.to_u8(),   None);
+        assert_eq!(i32::MAX.to_u16(),  None);
+        assert_eq!(i32::MAX.to_u32(),  Some(i32::MAX as u32));
+        assert_eq!(i32::MAX.to_u64(),  Some(i32::MAX as u64));
     }
 
     #[test]
     fn test_cast_range_i64_max() {
-        // i64::max_value.to_int() is word-size specific
-        assert_eq!(i64::max_value.to_i8(),   None);
-        assert_eq!(i64::max_value.to_i16(),  None);
-        assert_eq!(i64::max_value.to_i32(),  None);
-        assert_eq!(i64::max_value.to_i64(),  Some(i64::max_value as i64));
-        // i64::max_value.to_uint() is word-size specific
-        assert_eq!(i64::max_value.to_u8(),   None);
-        assert_eq!(i64::max_value.to_u16(),  None);
-        assert_eq!(i64::max_value.to_u32(),  None);
-        assert_eq!(i64::max_value.to_u64(),  Some(i64::max_value as u64));
+        // i64::MAX.to_int() is word-size specific
+        assert_eq!(i64::MAX.to_i8(),   None);
+        assert_eq!(i64::MAX.to_i16(),  None);
+        assert_eq!(i64::MAX.to_i32(),  None);
+        assert_eq!(i64::MAX.to_i64(),  Some(i64::MAX as i64));
+        // i64::MAX.to_uint() is word-size specific
+        assert_eq!(i64::MAX.to_u8(),   None);
+        assert_eq!(i64::MAX.to_u16(),  None);
+        assert_eq!(i64::MAX.to_u32(),  None);
+        assert_eq!(i64::MAX.to_u64(),  Some(i64::MAX as u64));
 
         #[cfg(target_word_size = "32")]
         fn check_word_size() {
-            assert_eq!(i64::max_value.to_int(),  None);
-            assert_eq!(i64::max_value.to_uint(), None);
+            assert_eq!(i64::MAX.to_int(),  None);
+            assert_eq!(i64::MAX.to_uint(), None);
         }
 
         #[cfg(target_word_size = "64")]
         fn check_word_size() {
-            assert_eq!(i64::max_value.to_int(),  Some(i64::max_value as int));
-            assert_eq!(i64::max_value.to_uint(), Some(i64::max_value as uint));
+            assert_eq!(i64::MAX.to_int(),  Some(i64::MAX as int));
+            assert_eq!(i64::MAX.to_uint(), Some(i64::MAX as uint));
         }
 
         check_word_size();
@@ -1350,96 +1338,96 @@ fn check_word_size() {
 
     #[test]
     fn test_cast_range_uint_min() {
-        assert_eq!(uint::min_value.to_int(),  Some(uint::min_value as int));
-        assert_eq!(uint::min_value.to_i8(),   Some(uint::min_value as i8));
-        assert_eq!(uint::min_value.to_i16(),  Some(uint::min_value as i16));
-        assert_eq!(uint::min_value.to_i32(),  Some(uint::min_value as i32));
-        assert_eq!(uint::min_value.to_i64(),  Some(uint::min_value as i64));
-        assert_eq!(uint::min_value.to_uint(), Some(uint::min_value as uint));
-        assert_eq!(uint::min_value.to_u8(),   Some(uint::min_value as u8));
-        assert_eq!(uint::min_value.to_u16(),  Some(uint::min_value as u16));
-        assert_eq!(uint::min_value.to_u32(),  Some(uint::min_value as u32));
-        assert_eq!(uint::min_value.to_u64(),  Some(uint::min_value as u64));
+        assert_eq!(uint::MIN.to_int(),  Some(uint::MIN as int));
+        assert_eq!(uint::MIN.to_i8(),   Some(uint::MIN as i8));
+        assert_eq!(uint::MIN.to_i16(),  Some(uint::MIN as i16));
+        assert_eq!(uint::MIN.to_i32(),  Some(uint::MIN as i32));
+        assert_eq!(uint::MIN.to_i64(),  Some(uint::MIN as i64));
+        assert_eq!(uint::MIN.to_uint(), Some(uint::MIN as uint));
+        assert_eq!(uint::MIN.to_u8(),   Some(uint::MIN as u8));
+        assert_eq!(uint::MIN.to_u16(),  Some(uint::MIN as u16));
+        assert_eq!(uint::MIN.to_u32(),  Some(uint::MIN as u32));
+        assert_eq!(uint::MIN.to_u64(),  Some(uint::MIN as u64));
     }
 
     #[test]
     fn test_cast_range_u8_min() {
-        assert_eq!(u8::min_value.to_int(),  Some(u8::min_value as int));
-        assert_eq!(u8::min_value.to_i8(),   Some(u8::min_value as i8));
-        assert_eq!(u8::min_value.to_i16(),  Some(u8::min_value as i16));
-        assert_eq!(u8::min_value.to_i32(),  Some(u8::min_value as i32));
-        assert_eq!(u8::min_value.to_i64(),  Some(u8::min_value as i64));
-        assert_eq!(u8::min_value.to_uint(), Some(u8::min_value as uint));
-        assert_eq!(u8::min_value.to_u8(),   Some(u8::min_value as u8));
-        assert_eq!(u8::min_value.to_u16(),  Some(u8::min_value as u16));
-        assert_eq!(u8::min_value.to_u32(),  Some(u8::min_value as u32));
-        assert_eq!(u8::min_value.to_u64(),  Some(u8::min_value as u64));
+        assert_eq!(u8::MIN.to_int(),  Some(u8::MIN as int));
+        assert_eq!(u8::MIN.to_i8(),   Some(u8::MIN as i8));
+        assert_eq!(u8::MIN.to_i16(),  Some(u8::MIN as i16));
+        assert_eq!(u8::MIN.to_i32(),  Some(u8::MIN as i32));
+        assert_eq!(u8::MIN.to_i64(),  Some(u8::MIN as i64));
+        assert_eq!(u8::MIN.to_uint(), Some(u8::MIN as uint));
+        assert_eq!(u8::MIN.to_u8(),   Some(u8::MIN as u8));
+        assert_eq!(u8::MIN.to_u16(),  Some(u8::MIN as u16));
+        assert_eq!(u8::MIN.to_u32(),  Some(u8::MIN as u32));
+        assert_eq!(u8::MIN.to_u64(),  Some(u8::MIN as u64));
     }
 
     #[test]
     fn test_cast_range_u16_min() {
-        assert_eq!(u16::min_value.to_int(),  Some(u16::min_value as int));
-        assert_eq!(u16::min_value.to_i8(),   Some(u16::min_value as i8));
-        assert_eq!(u16::min_value.to_i16(),  Some(u16::min_value as i16));
-        assert_eq!(u16::min_value.to_i32(),  Some(u16::min_value as i32));
-        assert_eq!(u16::min_value.to_i64(),  Some(u16::min_value as i64));
-        assert_eq!(u16::min_value.to_uint(), Some(u16::min_value as uint));
-        assert_eq!(u16::min_value.to_u8(),   Some(u16::min_value as u8));
-        assert_eq!(u16::min_value.to_u16(),  Some(u16::min_value as u16));
-        assert_eq!(u16::min_value.to_u32(),  Some(u16::min_value as u32));
-        assert_eq!(u16::min_value.to_u64(),  Some(u16::min_value as u64));
+        assert_eq!(u16::MIN.to_int(),  Some(u16::MIN as int));
+        assert_eq!(u16::MIN.to_i8(),   Some(u16::MIN as i8));
+        assert_eq!(u16::MIN.to_i16(),  Some(u16::MIN as i16));
+        assert_eq!(u16::MIN.to_i32(),  Some(u16::MIN as i32));
+        assert_eq!(u16::MIN.to_i64(),  Some(u16::MIN as i64));
+        assert_eq!(u16::MIN.to_uint(), Some(u16::MIN as uint));
+        assert_eq!(u16::MIN.to_u8(),   Some(u16::MIN as u8));
+        assert_eq!(u16::MIN.to_u16(),  Some(u16::MIN as u16));
+        assert_eq!(u16::MIN.to_u32(),  Some(u16::MIN as u32));
+        assert_eq!(u16::MIN.to_u64(),  Some(u16::MIN as u64));
     }
 
     #[test]
     fn test_cast_range_u32_min() {
-        assert_eq!(u32::min_value.to_int(),  Some(u32::min_value as int));
-        assert_eq!(u32::min_value.to_i8(),   Some(u32::min_value as i8));
-        assert_eq!(u32::min_value.to_i16(),  Some(u32::min_value as i16));
-        assert_eq!(u32::min_value.to_i32(),  Some(u32::min_value as i32));
-        assert_eq!(u32::min_value.to_i64(),  Some(u32::min_value as i64));
-        assert_eq!(u32::min_value.to_uint(), Some(u32::min_value as uint));
-        assert_eq!(u32::min_value.to_u8(),   Some(u32::min_value as u8));
-        assert_eq!(u32::min_value.to_u16(),  Some(u32::min_value as u16));
-        assert_eq!(u32::min_value.to_u32(),  Some(u32::min_value as u32));
-        assert_eq!(u32::min_value.to_u64(),  Some(u32::min_value as u64));
+        assert_eq!(u32::MIN.to_int(),  Some(u32::MIN as int));
+        assert_eq!(u32::MIN.to_i8(),   Some(u32::MIN as i8));
+        assert_eq!(u32::MIN.to_i16(),  Some(u32::MIN as i16));
+        assert_eq!(u32::MIN.to_i32(),  Some(u32::MIN as i32));
+        assert_eq!(u32::MIN.to_i64(),  Some(u32::MIN as i64));
+        assert_eq!(u32::MIN.to_uint(), Some(u32::MIN as uint));
+        assert_eq!(u32::MIN.to_u8(),   Some(u32::MIN as u8));
+        assert_eq!(u32::MIN.to_u16(),  Some(u32::MIN as u16));
+        assert_eq!(u32::MIN.to_u32(),  Some(u32::MIN as u32));
+        assert_eq!(u32::MIN.to_u64(),  Some(u32::MIN as u64));
     }
 
     #[test]
     fn test_cast_range_u64_min() {
-        assert_eq!(u64::min_value.to_int(),  Some(u64::min_value as int));
-        assert_eq!(u64::min_value.to_i8(),   Some(u64::min_value as i8));
-        assert_eq!(u64::min_value.to_i16(),  Some(u64::min_value as i16));
-        assert_eq!(u64::min_value.to_i32(),  Some(u64::min_value as i32));
-        assert_eq!(u64::min_value.to_i64(),  Some(u64::min_value as i64));
-        assert_eq!(u64::min_value.to_uint(), Some(u64::min_value as uint));
-        assert_eq!(u64::min_value.to_u8(),   Some(u64::min_value as u8));
-        assert_eq!(u64::min_value.to_u16(),  Some(u64::min_value as u16));
-        assert_eq!(u64::min_value.to_u32(),  Some(u64::min_value as u32));
-        assert_eq!(u64::min_value.to_u64(),  Some(u64::min_value as u64));
+        assert_eq!(u64::MIN.to_int(),  Some(u64::MIN as int));
+        assert_eq!(u64::MIN.to_i8(),   Some(u64::MIN as i8));
+        assert_eq!(u64::MIN.to_i16(),  Some(u64::MIN as i16));
+        assert_eq!(u64::MIN.to_i32(),  Some(u64::MIN as i32));
+        assert_eq!(u64::MIN.to_i64(),  Some(u64::MIN as i64));
+        assert_eq!(u64::MIN.to_uint(), Some(u64::MIN as uint));
+        assert_eq!(u64::MIN.to_u8(),   Some(u64::MIN as u8));
+        assert_eq!(u64::MIN.to_u16(),  Some(u64::MIN as u16));
+        assert_eq!(u64::MIN.to_u32(),  Some(u64::MIN as u32));
+        assert_eq!(u64::MIN.to_u64(),  Some(u64::MIN as u64));
     }
 
     #[test]
     fn test_cast_range_uint_max() {
-        assert_eq!(uint::max_value.to_int(),  None);
-        assert_eq!(uint::max_value.to_i8(),   None);
-        assert_eq!(uint::max_value.to_i16(),  None);
-        assert_eq!(uint::max_value.to_i32(),  None);
-        // uint::max_value.to_i64() is word-size specific
-        assert_eq!(uint::max_value.to_u8(),   None);
-        assert_eq!(uint::max_value.to_u16(),  None);
-        // uint::max_value.to_u32() is word-size specific
-        assert_eq!(uint::max_value.to_u64(),  Some(uint::max_value as u64));
+        assert_eq!(uint::MAX.to_int(),  None);
+        assert_eq!(uint::MAX.to_i8(),   None);
+        assert_eq!(uint::MAX.to_i16(),  None);
+        assert_eq!(uint::MAX.to_i32(),  None);
+        // uint::MAX.to_i64() is word-size specific
+        assert_eq!(uint::MAX.to_u8(),   None);
+        assert_eq!(uint::MAX.to_u16(),  None);
+        // uint::MAX.to_u32() is word-size specific
+        assert_eq!(uint::MAX.to_u64(),  Some(uint::MAX as u64));
 
         #[cfg(target_word_size = "32")]
         fn check_word_size() {
-            assert_eq!(uint::max_value.to_u32(), Some(uint::max_value as u32));
-            assert_eq!(uint::max_value.to_i64(), Some(uint::max_value as i64));
+            assert_eq!(uint::MAX.to_u32(), Some(uint::MAX as u32));
+            assert_eq!(uint::MAX.to_i64(), Some(uint::MAX as i64));
         }
 
         #[cfg(target_word_size = "64")]
         fn check_word_size() {
-            assert_eq!(uint::max_value.to_u32(), None);
-            assert_eq!(uint::max_value.to_i64(), None);
+            assert_eq!(uint::MAX.to_u32(), None);
+            assert_eq!(uint::MAX.to_i64(), None);
         }
 
         check_word_size();
@@ -1447,53 +1435,53 @@ fn check_word_size() {
 
     #[test]
     fn test_cast_range_u8_max() {
-        assert_eq!(u8::max_value.to_int(),  Some(u8::max_value as int));
-        assert_eq!(u8::max_value.to_i8(),   None);
-        assert_eq!(u8::max_value.to_i16(),  Some(u8::max_value as i16));
-        assert_eq!(u8::max_value.to_i32(),  Some(u8::max_value as i32));
-        assert_eq!(u8::max_value.to_i64(),  Some(u8::max_value as i64));
-        assert_eq!(u8::max_value.to_uint(), Some(u8::max_value as uint));
-        assert_eq!(u8::max_value.to_u8(),   Some(u8::max_value as u8));
-        assert_eq!(u8::max_value.to_u16(),  Some(u8::max_value as u16));
-        assert_eq!(u8::max_value.to_u32(),  Some(u8::max_value as u32));
-        assert_eq!(u8::max_value.to_u64(),  Some(u8::max_value as u64));
+        assert_eq!(u8::MAX.to_int(),  Some(u8::MAX as int));
+        assert_eq!(u8::MAX.to_i8(),   None);
+        assert_eq!(u8::MAX.to_i16(),  Some(u8::MAX as i16));
+        assert_eq!(u8::MAX.to_i32(),  Some(u8::MAX as i32));
+        assert_eq!(u8::MAX.to_i64(),  Some(u8::MAX as i64));
+        assert_eq!(u8::MAX.to_uint(), Some(u8::MAX as uint));
+        assert_eq!(u8::MAX.to_u8(),   Some(u8::MAX as u8));
+        assert_eq!(u8::MAX.to_u16(),  Some(u8::MAX as u16));
+        assert_eq!(u8::MAX.to_u32(),  Some(u8::MAX as u32));
+        assert_eq!(u8::MAX.to_u64(),  Some(u8::MAX as u64));
     }
 
     #[test]
     fn test_cast_range_u16_max() {
-        assert_eq!(u16::max_value.to_int(),  Some(u16::max_value as int));
-        assert_eq!(u16::max_value.to_i8(),   None);
-        assert_eq!(u16::max_value.to_i16(),  None);
-        assert_eq!(u16::max_value.to_i32(),  Some(u16::max_value as i32));
-        assert_eq!(u16::max_value.to_i64(),  Some(u16::max_value as i64));
-        assert_eq!(u16::max_value.to_uint(), Some(u16::max_value as uint));
-        assert_eq!(u16::max_value.to_u8(),   None);
-        assert_eq!(u16::max_value.to_u16(),  Some(u16::max_value as u16));
-        assert_eq!(u16::max_value.to_u32(),  Some(u16::max_value as u32));
-        assert_eq!(u16::max_value.to_u64(),  Some(u16::max_value as u64));
+        assert_eq!(u16::MAX.to_int(),  Some(u16::MAX as int));
+        assert_eq!(u16::MAX.to_i8(),   None);
+        assert_eq!(u16::MAX.to_i16(),  None);
+        assert_eq!(u16::MAX.to_i32(),  Some(u16::MAX as i32));
+        assert_eq!(u16::MAX.to_i64(),  Some(u16::MAX as i64));
+        assert_eq!(u16::MAX.to_uint(), Some(u16::MAX as uint));
+        assert_eq!(u16::MAX.to_u8(),   None);
+        assert_eq!(u16::MAX.to_u16(),  Some(u16::MAX as u16));
+        assert_eq!(u16::MAX.to_u32(),  Some(u16::MAX as u32));
+        assert_eq!(u16::MAX.to_u64(),  Some(u16::MAX as u64));
     }
 
     #[test]
     fn test_cast_range_u32_max() {
-        // u32::max_value.to_int() is word-size specific
-        assert_eq!(u32::max_value.to_i8(),   None);
-        assert_eq!(u32::max_value.to_i16(),  None);
-        assert_eq!(u32::max_value.to_i32(),  None);
-        assert_eq!(u32::max_value.to_i64(),  Some(u32::max_value as i64));
-        assert_eq!(u32::max_value.to_uint(), Some(u32::max_value as uint));
-        assert_eq!(u32::max_value.to_u8(),   None);
-        assert_eq!(u32::max_value.to_u16(),  None);
-        assert_eq!(u32::max_value.to_u32(),  Some(u32::max_value as u32));
-        assert_eq!(u32::max_value.to_u64(),  Some(u32::max_value as u64));
+        // u32::MAX.to_int() is word-size specific
+        assert_eq!(u32::MAX.to_i8(),   None);
+        assert_eq!(u32::MAX.to_i16(),  None);
+        assert_eq!(u32::MAX.to_i32(),  None);
+        assert_eq!(u32::MAX.to_i64(),  Some(u32::MAX as i64));
+        assert_eq!(u32::MAX.to_uint(), Some(u32::MAX as uint));
+        assert_eq!(u32::MAX.to_u8(),   None);
+        assert_eq!(u32::MAX.to_u16(),  None);
+        assert_eq!(u32::MAX.to_u32(),  Some(u32::MAX as u32));
+        assert_eq!(u32::MAX.to_u64(),  Some(u32::MAX as u64));
 
         #[cfg(target_word_size = "32")]
         fn check_word_size() {
-            assert_eq!(u32::max_value.to_int(),  None);
+            assert_eq!(u32::MAX.to_int(),  None);
         }
 
         #[cfg(target_word_size = "64")]
         fn check_word_size() {
-            assert_eq!(u32::max_value.to_int(),  Some(u32::max_value as int));
+            assert_eq!(u32::MAX.to_int(),  Some(u32::MAX as int));
         }
 
         check_word_size();
@@ -1501,25 +1489,25 @@ fn check_word_size() {
 
     #[test]
     fn test_cast_range_u64_max() {
-        assert_eq!(u64::max_value.to_int(),  None);
-        assert_eq!(u64::max_value.to_i8(),   None);
-        assert_eq!(u64::max_value.to_i16(),  None);
-        assert_eq!(u64::max_value.to_i32(),  None);
-        assert_eq!(u64::max_value.to_i64(),  None);
-        // u64::max_value.to_uint() is word-size specific
-        assert_eq!(u64::max_value.to_u8(),   None);
-        assert_eq!(u64::max_value.to_u16(),  None);
-        assert_eq!(u64::max_value.to_u32(),  None);
-        assert_eq!(u64::max_value.to_u64(),  Some(u64::max_value as u64));
+        assert_eq!(u64::MAX.to_int(),  None);
+        assert_eq!(u64::MAX.to_i8(),   None);
+        assert_eq!(u64::MAX.to_i16(),  None);
+        assert_eq!(u64::MAX.to_i32(),  None);
+        assert_eq!(u64::MAX.to_i64(),  None);
+        // u64::MAX.to_uint() is word-size specific
+        assert_eq!(u64::MAX.to_u8(),   None);
+        assert_eq!(u64::MAX.to_u16(),  None);
+        assert_eq!(u64::MAX.to_u32(),  None);
+        assert_eq!(u64::MAX.to_u64(),  Some(u64::MAX as u64));
 
         #[cfg(target_word_size = "32")]
         fn check_word_size() {
-            assert_eq!(u64::max_value.to_uint(), None);
+            assert_eq!(u64::MAX.to_uint(), None);
         }
 
         #[cfg(target_word_size = "64")]
         fn check_word_size() {
-            assert_eq!(u64::max_value.to_uint(), Some(u64::max_value as uint));
+            assert_eq!(u64::MAX.to_uint(), Some(u64::MAX as uint));
         }
 
         check_word_size();
@@ -1527,55 +1515,55 @@ fn check_word_size() {
 
     #[test]
     fn test_saturating_add_uint() {
-        use uint::max_value;
+        use uint::MAX;
         assert_eq!(3u.saturating_add(5u), 8u);
-        assert_eq!(3u.saturating_add(max_value-1), max_value);
-        assert_eq!(max_value.saturating_add(max_value), max_value);
-        assert_eq!((max_value-2).saturating_add(1), max_value-1);
+        assert_eq!(3u.saturating_add(MAX-1), MAX);
+        assert_eq!(MAX.saturating_add(MAX), MAX);
+        assert_eq!((MAX-2).saturating_add(1), MAX-1);
     }
 
     #[test]
     fn test_saturating_sub_uint() {
-        use uint::max_value;
+        use uint::MAX;
         assert_eq!(5u.saturating_sub(3u), 2u);
         assert_eq!(3u.saturating_sub(5u), 0u);
         assert_eq!(0u.saturating_sub(1u), 0u);
-        assert_eq!((max_value-1).saturating_sub(max_value), 0);
+        assert_eq!((MAX-1).saturating_sub(MAX), 0);
     }
 
     #[test]
     fn test_saturating_add_int() {
-        use int::{min_value,max_value};
+        use int::{MIN,MAX};
         assert_eq!(3i.saturating_add(5i), 8i);
-        assert_eq!(3i.saturating_add(max_value-1), max_value);
-        assert_eq!(max_value.saturating_add(max_value), max_value);
-        assert_eq!((max_value-2).saturating_add(1), max_value-1);
+        assert_eq!(3i.saturating_add(MAX-1), MAX);
+        assert_eq!(MAX.saturating_add(MAX), MAX);
+        assert_eq!((MAX-2).saturating_add(1), MAX-1);
         assert_eq!(3i.saturating_add(-5i), -2i);
-        assert_eq!(min_value.saturating_add(-1i), min_value);
-        assert_eq!((-2i).saturating_add(-max_value), min_value);
+        assert_eq!(MIN.saturating_add(-1i), MIN);
+        assert_eq!((-2i).saturating_add(-MAX), MIN);
     }
 
     #[test]
     fn test_saturating_sub_int() {
-        use int::{min_value,max_value};
+        use int::{MIN,MAX};
         assert_eq!(3i.saturating_sub(5i), -2i);
-        assert_eq!(min_value.saturating_sub(1i), min_value);
-        assert_eq!((-2i).saturating_sub(max_value), min_value);
+        assert_eq!(MIN.saturating_sub(1i), MIN);
+        assert_eq!((-2i).saturating_sub(MAX), MIN);
         assert_eq!(3i.saturating_sub(-5i), 8i);
-        assert_eq!(3i.saturating_sub(-(max_value-1)), max_value);
-        assert_eq!(max_value.saturating_sub(-max_value), max_value);
-        assert_eq!((max_value-2).saturating_sub(-1), max_value-1);
+        assert_eq!(3i.saturating_sub(-(MAX-1)), MAX);
+        assert_eq!(MAX.saturating_sub(-MAX), MAX);
+        assert_eq!((MAX-2).saturating_sub(-1), MAX-1);
     }
 
     #[test]
     fn test_checked_add() {
-        let five_less = uint::max_value - 5;
-        assert_eq!(five_less.checked_add(&0), Some(uint::max_value - 5));
-        assert_eq!(five_less.checked_add(&1), Some(uint::max_value - 4));
-        assert_eq!(five_less.checked_add(&2), Some(uint::max_value - 3));
-        assert_eq!(five_less.checked_add(&3), Some(uint::max_value - 2));
-        assert_eq!(five_less.checked_add(&4), Some(uint::max_value - 1));
-        assert_eq!(five_less.checked_add(&5), Some(uint::max_value));
+        let five_less = uint::MAX - 5;
+        assert_eq!(five_less.checked_add(&0), Some(uint::MAX - 5));
+        assert_eq!(five_less.checked_add(&1), Some(uint::MAX - 4));
+        assert_eq!(five_less.checked_add(&2), Some(uint::MAX - 3));
+        assert_eq!(five_less.checked_add(&3), Some(uint::MAX - 2));
+        assert_eq!(five_less.checked_add(&4), Some(uint::MAX - 1));
+        assert_eq!(five_less.checked_add(&5), Some(uint::MAX));
         assert_eq!(five_less.checked_add(&6), None);
         assert_eq!(five_less.checked_add(&7), None);
     }
@@ -1594,7 +1582,7 @@ fn test_checked_sub() {
 
     #[test]
     fn test_checked_mul() {
-        let third = uint::max_value / 3;
+        let third = uint::MAX / 3;
         assert_eq!(third.checked_mul(&0), Some(0));
         assert_eq!(third.checked_mul(&1), Some(third));
         assert_eq!(third.checked_mul(&2), Some(third * 2));
index 30abe86866e220b526089c26588ff0a9919c625d..67f6d006b5787896ddfbe185460b7c18ff6bbc7c 100644 (file)
@@ -18,7 +18,7 @@
 use char;
 use str::{StrSlice};
 use str;
-use vec::{CopyableVector, ImmutableVector, MutableVector};
+use vec::{CloneableVector, ImmutableVector, MutableVector};
 use vec::OwnedVector;
 use num;
 use num::{NumCast, Zero, One, cast, Integer};
index d304f947542143c8f8e48a10019af03a60ee2673..89914571adaf81ca5bc9999443513e8a2fcf79e3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
 use num::{CheckedAdd, CheckedSub, CheckedMul};
 use num::{CheckedDiv, Zero, One, strconv};
 use num::{ToStrRadix, FromStrRadix};
-use num;
 use option::{Option, Some, None};
 use str;
 use unstable::intrinsics;
 
-uint_module!(uint, int, ::int::bits)
+uint_module!(uint, int, ::int::BITS)
 
 ///
 /// Divide two numbers, return the result, rounded up.
@@ -80,27 +79,6 @@ pub fn div_round(x: uint, y: uint) -> uint {
 ///
 pub fn div_floor(x: uint, y: uint) -> uint { return x / y; }
 
-impl num::Times for uint {
-    #[inline]
-    ///
-    /// A convenience form for basic repetition. Given a uint `x`,
-    /// `x.times(|| { ... })` executes the given block x times.
-    ///
-    /// Equivalent to `for uint::range(0, x) |_| { ... }`.
-    ///
-    /// Not defined on all integer types to permit unambiguous
-    /// use with integer literals of inferred integer-type as
-    /// the self-value (eg. `100.times(|| { ... })`).
-    ///
-    fn times(&self, it: ||) {
-        let mut i = *self;
-        while i > 0 {
-            it();
-            i -= 1;
-        }
-    }
-}
-
 /// Returns the smallest power of 2 greater than or equal to `n`
 #[inline]
 pub fn next_power_of_two(n: uint) -> uint {
@@ -234,9 +212,9 @@ fn test_next_power_of_two() {
 #[test]
 fn test_overflows() {
     use uint;
-    assert!((uint::max_value > 0u));
-    assert!((uint::min_value <= 0u));
-    assert!((uint::min_value + uint::max_value + 1u == 0u));
+    assert!((uint::MAX > 0u));
+    assert!((uint::MIN <= 0u));
+    assert!((uint::MIN + uint::MAX + 1u == 0u));
 }
 
 #[test]
@@ -245,12 +223,3 @@ fn test_div() {
     assert!((div_ceil(3u, 4u)  == 1u));
     assert!((div_round(3u, 4u) == 1u));
 }
-
-#[test]
-pub fn test_times() {
-    use num::Times;
-    let ten = 10 as uint;
-    let mut accum = 0;
-    ten.times(|| { accum += 1; });
-    assert!((accum == 10));
-}
index 1b822a491c6f38c7da87984be3646c752727bdc8..5b9767e68e8dafdf61d62c38df676417f82ba976 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
 
 macro_rules! uint_module (($T:ty, $T_SIGNED:ty, $bits:expr) => (
 
-pub static bits : uint = $bits;
-pub static bytes : uint = ($bits / 8);
+pub static BITS : uint = $bits;
+pub static BYTES : uint = ($bits / 8);
 
-pub static min_value: $T = 0 as $T;
-pub static max_value: $T = 0 as $T - 1 as $T;
+pub static MIN: $T = 0 as $T;
+pub static MAX: $T = 0 as $T - 1 as $T;
 
 impl CheckedDiv for $T {
     #[inline]
@@ -214,10 +214,10 @@ fn not(&self) -> $T { !*self }
 
 impl Bounded for $T {
     #[inline]
-    fn min_value() -> $T { min_value }
+    fn min_value() -> $T { MIN }
 
     #[inline]
-    fn max_value() -> $T { max_value }
+    fn max_value() -> $T { MAX }
 }
 
 impl Int for $T {}
@@ -398,7 +398,7 @@ fn test_bitwise() {
         assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(&(0b1010 as $T)));
         assert_eq!(0b1110 as $T, (0b0111 as $T).shl(&(1 as $T)));
         assert_eq!(0b0111 as $T, (0b1110 as $T).shr(&(1 as $T)));
-        assert_eq!(max_value - (0b1011 as $T), (0b1011 as $T).not());
+        assert_eq!(MAX - (0b1011 as $T), (0b1011 as $T).not());
     }
 
     #[test]
index 53fa41f9cfdc88d373130ffe7bc4e2d7605824f5..833f20210434b651eca55ad501941d933173873f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -441,7 +441,7 @@ impl<A> ExactSize<A> for Item<A> {}
 /// checking for overflow:
 ///
 ///     fn inc_conditionally(x: uint) -> Option<uint> {
-///         if x == uint::max_value { return None; }
+///         if x == uint::MAX { return None; }
 ///         else { return Some(x+1u); }
 ///     }
 ///     let v = [1u, 2, 3];
index 93762a3cdd5c7bf12b1b6faa07c3bc8e28462c09..457d58ae464050f85bd42253435df62836f919cd 100644 (file)
 #[cfg(target_os = "macos")]
 use iter::range;
 use libc;
-use libc::{c_char, c_void, c_int, size_t};
+use libc::{c_char, c_void, c_int};
 use option::{Some, None};
 use os;
 use prelude::*;
 use ptr;
 use str;
-use to_str;
+use fmt;
 use unstable::finally::Finally;
 use sync::atomics::{AtomicInt, INIT_ATOMIC_INT, SeqCst};
 
@@ -59,7 +59,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 size_t).is_null() {
+        if libc::getcwd(buf.as_mut_ptr(), buf.len() as libc::size_t).is_null() {
             fail!()
         }
         Path::new(CString::new(buf.as_ptr(), false))
@@ -337,9 +337,9 @@ pub fn dll_filename(base: &str) -> ~str {
     format!("{}{}{}", consts::DLL_PREFIX, base, consts::DLL_SUFFIX)
 }
 
-/// Optionally returns the filesystem path to the current executable which is
+/// Optionally returns the filesystem path of the current executable which is
 /// running. If any failure occurs, None is returned.
-pub fn self_exe_path() -> Option<Path> {
+pub fn self_exe_name() -> Option<Path> {
 
     #[cfg(target_os = "freebsd")]
     fn load_self() -> Option<~[u8]> {
@@ -350,14 +350,16 @@ fn load_self() -> Option<~[u8]> {
             let mib = ~[CTL_KERN as c_int,
                         KERN_PROC as c_int,
                         KERN_PROC_PATHNAME as c_int, -1 as c_int];
-            let mut sz: size_t = 0;
+            let mut sz: libc::size_t = 0;
             let err = sysctl(mib.as_ptr(), mib.len() as ::libc::c_uint,
-                             ptr::mut_null(), &mut sz, ptr::null(), 0u as size_t);
+                             ptr::mut_null(), &mut sz, ptr::null(),
+                             0u as libc::size_t);
             if err != 0 { return None; }
             if sz == 0 { return None; }
             let mut v: ~[u8] = vec::with_capacity(sz as uint);
             let err = sysctl(mib.as_ptr(), mib.len() as ::libc::c_uint,
-                             v.as_mut_ptr() as *mut c_void, &mut sz, ptr::null(), 0u as size_t);
+                             v.as_mut_ptr() as *mut c_void, &mut sz, ptr::null(),
+                             0u as libc::size_t);
             if err != 0 { return None; }
             if sz == 0 { return None; }
             v.set_len(sz as uint - 1); // chop off trailing NUL
@@ -402,7 +404,14 @@ fn load_self() -> Option<~[u8]> {
         }
     }
 
-    load_self().and_then(|path| Path::new_opt(path).map(|mut p| { p.pop(); p }))
+    load_self().and_then(Path::new_opt)
+}
+
+/// Optionally returns the filesystem path to the current executable which is
+/// running. Like self_exe_name() but without the binary's name.
+/// If any failure occurs, None is returned.
+pub fn self_exe_path() -> Option<Path> {
+    self_exe_name().map(|mut p| { p.pop(); p })
 }
 
 /**
@@ -586,12 +595,12 @@ fn strerror() -> ~str {
         #[cfg(target_os = "macos")]
         #[cfg(target_os = "android")]
         #[cfg(target_os = "freebsd")]
-        fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t)
+        fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: libc::size_t)
                       -> c_int {
             #[nolink]
             extern {
-                fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t)
-                              -> c_int;
+                fn strerror_r(errnum: c_int, buf: *mut c_char,
+                              buflen: libc::size_t) -> c_int;
             }
             unsafe {
                 strerror_r(errnum, buf, buflen)
@@ -602,12 +611,13 @@ fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t)
         // and requires macros to instead use the POSIX compliant variant.
         // So we just use __xpg_strerror_r which is always POSIX compliant
         #[cfg(target_os = "linux")]
-        fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t) -> c_int {
+        fn strerror_r(errnum: c_int, buf: *mut c_char,
+                      buflen: libc::size_t) -> c_int {
             #[nolink]
             extern {
                 fn __xpg_strerror_r(errnum: c_int,
                                     buf: *mut c_char,
-                                    buflen: size_t)
+                                    buflen: libc::size_t)
                                     -> c_int;
             }
             unsafe {
@@ -619,7 +629,7 @@ fn __xpg_strerror_r(errnum: c_int,
 
         let p = buf.as_mut_ptr();
         unsafe {
-            if strerror_r(errno() as c_int, p, buf.len() as size_t) < 0 {
+            if strerror_r(errno() as c_int, p, buf.len() as libc::size_t) < 0 {
                 fail!("strerror_r failure");
             }
 
@@ -822,13 +832,14 @@ pub fn page_size() -> uint {
     }
 }
 
-/// A memory mapped file or chunk of memory. This is a very system-specific interface to the OS's
-/// memory mapping facilities (`mmap` on POSIX, `VirtualAlloc`/`CreateFileMapping` on win32). It
-/// makes no attempt at abstracting platform differences, besides in error values returned. Consider
+/// A memory mapped file or chunk of memory. This is a very system-specific
+/// interface to the OS's memory mapping facilities (`mmap` on POSIX,
+/// `VirtualAlloc`/`CreateFileMapping` on win32). It makes no attempt at
+/// abstracting platform differences, besides in error values returned. Consider
 /// yourself warned.
 ///
-/// The memory map is released (unmapped) when the destructor is run, so don't let it leave scope by
-/// accident if you want it to stick around.
+/// The memory map is released (unmapped) when the destructor is run, so don't
+/// let it leave scope by accident if you want it to stick around.
 pub struct MemoryMap {
     /// Pointer to the memory created or modified by this map.
     data: *mut u8,
@@ -840,11 +851,12 @@ pub struct MemoryMap {
 
 /// Type of memory map
 pub enum MemoryMapKind {
-    /// Memory-mapped file. On Windows, the inner pointer is a handle to the mapping, and
-    /// corresponds to `CreateFileMapping`. Elsewhere, it is null.
+    /// Virtual memory map. Usually used to change the permissions of a given
+    /// chunk of memory.  Corresponds to `VirtualAlloc` on Windows.
     MapFile(*u8),
-    /// Virtual memory map. Usually used to change the permissions of a given chunk of memory.
-    /// Corresponds to `VirtualAlloc` on Windows.
+    /// Virtual memory map. Usually used to change the permissions of a given
+    /// chunk of memory, or for allocation. Corresponds to `VirtualAlloc` on
+    /// Windows.
     MapVirtual
 }
 
@@ -856,81 +868,119 @@ pub enum MapOption {
     MapWritable,
     /// The memory should be executable
     MapExecutable,
-    /// Create a map for a specific address range. Corresponds to `MAP_FIXED` on POSIX.
+    /// Create a map for a specific address range. Corresponds to `MAP_FIXED` on
+    /// POSIX.
     MapAddr(*u8),
     /// Create a memory mapping for a file with a given fd.
     MapFd(c_int),
-    /// When using `MapFd`, the start of the map is `uint` bytes from the start of the file.
-    MapOffset(uint)
+    /// When using `MapFd`, the start of the map is `uint` bytes from the start
+    /// of the file.
+    MapOffset(uint),
+    /// On POSIX, this can be used to specify the default flags passed to
+    /// `mmap`. By default it uses `MAP_PRIVATE` and, if not using `MapFd`,
+    /// `MAP_ANON`. This will override both of those. This is platform-specific
+    /// (the exact values used) and ignored on Windows.
+    MapNonStandardFlags(c_int),
 }
 
 /// Possible errors when creating a map.
 pub enum MapError {
     /// ## The following are POSIX-specific
     ///
-    /// fd was not open for reading or, if using `MapWritable`, was not open for writing.
+    /// fd was not open for reading or, if using `MapWritable`, was not open for
+    /// writing.
     ErrFdNotAvail,
     /// fd was not valid
     ErrInvalidFd,
-    /// Either the address given by `MapAddr` or offset given by `MapOffset` was not a multiple of
-    /// `MemoryMap::granularity` (unaligned to page size).
+    /// Either the address given by `MapAddr` or offset given by `MapOffset` was
+    /// not a multiple of `MemoryMap::granularity` (unaligned to page size).
     ErrUnaligned,
     /// With `MapFd`, the fd does not support mapping.
     ErrNoMapSupport,
-    /// If using `MapAddr`, the address + `min_len` was outside of the process's address space. If
-    /// using `MapFd`, the target of the fd didn't have enough resources to fulfill the request.
+    /// If using `MapAddr`, the address + `min_len` was outside of the process's
+    /// address space. If using `MapFd`, the target of the fd didn't have enough
+    /// resources to fulfill the request.
     ErrNoMem,
+    /// A zero-length map was requested. This is invalid according to
+    /// [POSIX](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mmap.html).
+    /// Not all platforms obey this, but this wrapper does.
+    ErrZeroLength,
     /// Unrecognized error. The inner value is the unrecognized errno.
     ErrUnknown(int),
     /// ## The following are win32-specific
     ///
-    /// Unsupported combination of protection flags (`MapReadable`/`MapWritable`/`MapExecutable`).
+    /// Unsupported combination of protection flags
+    /// (`MapReadable`/`MapWritable`/`MapExecutable`).
     ErrUnsupProt,
-    /// When using `MapFd`, `MapOffset` was given (Windows does not support this at all)
+    /// When using `MapFd`, `MapOffset` was given (Windows does not support this
+    /// at all)
     ErrUnsupOffset,
     /// When using `MapFd`, there was already a mapping to the file.
     ErrAlreadyExists,
-    /// Unrecognized error from `VirtualAlloc`. The inner value is the return value of GetLastError.
+    /// Unrecognized error from `VirtualAlloc`. The inner value is the return
+    /// value of GetLastError.
     ErrVirtualAlloc(uint),
-    /// Unrecognized error from `CreateFileMapping`. The inner value is the return value of
-    /// `GetLastError`.
+    /// Unrecognized error from `CreateFileMapping`. The inner value is the
+    /// return value of `GetLastError`.
     ErrCreateFileMappingW(uint),
-    /// Unrecognized error from `MapViewOfFile`. The inner value is the return value of
-    /// `GetLastError`.
+    /// Unrecognized error from `MapViewOfFile`. The inner value is the return
+    /// value of `GetLastError`.
     ErrMapViewOfFile(uint)
 }
 
-impl to_str::ToStr for MapError {
-    fn to_str(&self) -> ~str {
-        match *self {
-            ErrFdNotAvail => ~"fd not available for reading or writing",
-            ErrInvalidFd => ~"Invalid fd",
-            ErrUnaligned => ~"Unaligned address, invalid flags, \
-                              negative length or unaligned offset",
-            ErrNoMapSupport=> ~"File doesn't support mapping",
-            ErrNoMem => ~"Invalid address, or not enough available memory",
-            ErrUnknown(code) => format!("Unknown error={}", code),
-            ErrUnsupProt => ~"Protection mode unsupported",
-            ErrUnsupOffset => ~"Offset in virtual memory mode is unsupported",
-            ErrAlreadyExists => ~"File mapping for specified file already exists",
-            ErrVirtualAlloc(code) => format!("VirtualAlloc failure={}", code),
-            ErrCreateFileMappingW(code) => format!("CreateFileMappingW failure={}", code),
-            ErrMapViewOfFile(code) => format!("MapViewOfFile failure={}", code)
-        }
+impl fmt::Default for MapError {
+    fn fmt(val: &MapError, out: &mut fmt::Formatter) {
+        let str = match *val {
+            ErrFdNotAvail => "fd not available for reading or writing",
+            ErrInvalidFd => "Invalid fd",
+            ErrUnaligned => {
+                "Unaligned address, invalid flags, negative length or \
+                 unaligned offset"
+            }
+            ErrNoMapSupport=> "File doesn't support mapping",
+            ErrNoMem => "Invalid address, or not enough available memory",
+            ErrUnsupProt => "Protection mode unsupported",
+            ErrUnsupOffset => "Offset in virtual memory mode is unsupported",
+            ErrAlreadyExists => "File mapping for specified file already exists",
+            ErrZeroLength => "Zero-length mapping not allowed",
+            ErrUnknown(code) => {
+                write!(out.buf, "Unknown error = {}", code);
+                return
+            },
+            ErrVirtualAlloc(code) => {
+                write!(out.buf, "VirtualAlloc failure = {}", code);
+                return
+            },
+            ErrCreateFileMappingW(code) => {
+                format!("CreateFileMappingW failure = {}", code);
+                return
+            },
+            ErrMapViewOfFile(code) => {
+                write!(out.buf, "MapViewOfFile failure = {}", code);
+                return
+            }
+        };
+        write!(out.buf, "{}", str);
     }
 }
 
 #[cfg(unix)]
 impl MemoryMap {
-    /// Create a new mapping with the given `options`, at least `min_len` bytes long.
+    /// Create a new mapping with the given `options`, at least `min_len` bytes
+    /// long. `min_len` must be greater than zero; see the note on
+    /// `ErrZeroLength`.
     pub fn new(min_len: uint, options: &[MapOption]) -> Result<MemoryMap, MapError> {
         use libc::off_t;
 
+        if min_len == 0 {
+            return Err(ErrZeroLength)
+        }
         let mut addr: *u8 = ptr::null();
         let mut prot = 0;
         let mut flags = libc::MAP_PRIVATE;
         let mut fd = -1;
         let mut offset = 0;
+        let mut custom_flags = false;
         let len = round_up(min_len, page_size());
 
         for &o in options.iter() {
@@ -946,13 +996,15 @@ pub fn new(min_len: uint, options: &[MapOption]) -> Result<MemoryMap, MapError>
                     flags |= libc::MAP_FILE;
                     fd = fd_;
                 },
-                MapOffset(offset_) => { offset = offset_ as off_t; }
+                MapOffset(offset_) => { offset = offset_ as off_t; },
+                MapNonStandardFlags(f) => { custom_flags = true; flags = f },
             }
         }
-        if fd == -1 { flags |= libc::MAP_ANON; }
+        if fd == -1 && !custom_flags { flags |= libc::MAP_ANON; }
 
         let r = unsafe {
-            libc::mmap(addr as *c_void, len as size_t, prot, flags, fd, offset)
+            libc::mmap(addr as *c_void, len as libc::size_t, prot, flags, fd,
+                       offset)
         };
         if r.equiv(&libc::MAP_FAILED) {
             Err(match errno() as c_int {
@@ -976,7 +1028,8 @@ pub fn new(min_len: uint, options: &[MapOption]) -> Result<MemoryMap, MapError>
         }
     }
 
-    /// Granularity that the offset or address must be for `MapOffset` and `MapAddr` respectively.
+    /// Granularity that the offset or address must be for `MapOffset` and
+    /// `MapAddr` respectively.
     pub fn granularity() -> uint {
         page_size()
     }
@@ -986,6 +1039,8 @@ pub fn granularity() -> uint {
 impl Drop for MemoryMap {
     /// Unmap the mapping. Fails the task if `munmap` fails.
     fn drop(&mut self) {
+        if self.len == 0 { /* workaround for dummy_stack */ return; }
+
         unsafe {
             match libc::munmap(self.data as *c_void, self.len as libc::size_t) {
                 0 => (),
@@ -1020,7 +1075,11 @@ pub fn new(min_len: uint, options: &[MapOption]) -> Result<MemoryMap, MapError>
                 MapExecutable => { executable = true; }
                 MapAddr(addr_) => { lpAddress = addr_ as LPVOID; },
                 MapFd(fd_) => { fd = fd_; },
-                MapOffset(offset_) => { offset = offset_; }
+                MapOffset(offset_) => { offset = offset_; },
+                MapNonStandardFlags(f) => {
+                    info!("MemoryMap::new: MapNonStandardFlags used on \
+                           Windows: {}", f)
+                }
             }
         }
 
@@ -1106,18 +1165,18 @@ pub fn granularity() -> uint {
 
 #[cfg(windows)]
 impl Drop for MemoryMap {
-    /// Unmap the mapping. Fails the task if any of `VirtualFree`, `UnmapViewOfFile`, or
-    /// `CloseHandle` fail.
+    /// Unmap the mapping. Fails the task if any of `VirtualFree`,
+    /// `UnmapViewOfFile`, or `CloseHandle` fail.
     fn drop(&mut self) {
         use libc::types::os::arch::extra::{LPCVOID, HANDLE};
         use libc::consts::os::extra::FALSE;
+        if self.len == 0 { return }
 
         unsafe {
             match self.kind {
                 MapVirtual => {
-                    if libc::VirtualFree(self.data as *mut c_void,
-                                         self.len as size_t,
-                                         libc::MEM_RELEASE) == FALSE {
+                    if libc::VirtualFree(self.data as *mut c_void, 0,
+                                         libc::MEM_RELEASE) == 0 {
                         error!("VirtualFree failed: {}", errno());
                     }
                 },
@@ -1310,6 +1369,17 @@ fn test_getenv_big() {
         assert_eq!(getenv(n), option::Some(s));
     }
 
+    #[test]
+    fn test_self_exe_name() {
+        let path = os::self_exe_name();
+        assert!(path.is_some());
+        let path = path.unwrap();
+        debug!("{:?}", path.clone());
+
+        // Hard to test this function
+        assert!(path.is_absolute());
+    }
+
     #[test]
     fn test_self_exe_path() {
         let path = os::self_exe_path();
@@ -1411,7 +1481,7 @@ fn memory_map_rw() {
             os::MapWritable
         ]) {
             Ok(chunk) => chunk,
-            Err(msg) => fail!(msg.to_str())
+            Err(msg) => fail!("{}", msg)
         };
         assert!(chunk.len >= 16);
 
@@ -1461,7 +1531,7 @@ fn lseek_(fd: c_int, size: uint) {
             MapOffset(size / 2)
         ]) {
             Ok(chunk) => chunk,
-            Err(msg) => fail!(msg.to_str())
+            Err(msg) => fail!("{}", msg)
         };
         assert!(chunk.len > 0);
 
index 6464d6021ee53e3adf3b2f30822bf05ff9781b6d..11f23b22c51fa2889bd88939893ead0583c7b1be 100644 (file)
@@ -73,7 +73,7 @@
 use str::{OwnedStr, Str, StrSlice};
 use to_str::ToStr;
 use vec;
-use vec::{CopyableVector, OwnedCopyableVector, OwnedVector, Vector};
+use vec::{CloneableVector, OwnedCloneableVector, OwnedVector, Vector};
 use vec::{ImmutableEqVector, ImmutableVector};
 
 /// Typedef for POSIX file paths.
index e95bd2d8ca2f3ddfd7dcbcd3ae87e51f0b1a4f09..707ba18378a836324f18925749f87328621cf106 100644 (file)
@@ -21,8 +21,8 @@
 use str::Str;
 use to_bytes::IterBytes;
 use vec;
-use vec::{CopyableVector, RevSplits, Splits, Vector, VectorVector,
-          ImmutableEqVector, OwnedVector, ImmutableVector, OwnedCopyableVector};
+use vec::{CloneableVector, RevSplits, Splits, Vector, VectorVector,
+          ImmutableEqVector, OwnedVector, ImmutableVector, OwnedCloneableVector};
 use super::{BytesContainer, GenericPath, GenericPathUnsafe};
 
 /// Iterator that yields successive components of a Path as &[u8]
@@ -332,7 +332,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: Vector<u8>+CopyableVector<u8>>(v: V) -> ~[u8] {
+    fn normalize<V: Vector<u8>+CloneableVector<u8>>(v: V) -> ~[u8] {
         // borrowck is being very picky
         let val = {
             let is_abs = !v.as_slice().is_empty() && v.as_slice()[0] == SEP_BYTE;
@@ -569,11 +569,11 @@ fn test_null_byte_fail() {
         use task;
 
         macro_rules! t(
-            ($name:expr => $code:block) => (
+            ($name:expr => $code:expr) => (
                 {
                     let mut t = task::task();
                     t.name($name);
-                    let res = do t.try $code;
+                    let res = t.try(proc() $code);
                     assert!(res.is_err());
                 }
             )
index cc0705ee76fb4f4c91f4330f744ddcc188a9569c..a07471afc1a67f940fbebdb3ff8e05606c63bd9d 100644 (file)
@@ -1290,11 +1290,11 @@ fn test_null_byte_fail() {
         use task;
 
         macro_rules! t(
-            ($name:expr => $code:block) => (
+            ($name:expr => $code:expr) => (
                 {
                     let mut t = task::task();
                     t.name($name);
-                    let res = do t.try $code;
+                    let res = t.try(proc() $code);
                     assert!(res.is_err());
                 }
             )
index 2f5f3e8f4568d0b045d055cfe690921f4b20bd2a..b08d792822bfb4839dbddd412f8c1a6b822a80d4 100644 (file)
@@ -57,7 +57,6 @@
 pub use iter::{FromIterator, Extendable};
 pub use iter::{Iterator, DoubleEndedIterator, RandomAccessIterator, CloneableIterator};
 pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize};
-pub use num::Times;
 pub use num::{Integer, Real, Num, NumCast, CheckedAdd, CheckedSub, CheckedMul};
 pub use num::{Orderable, Signed, Unsigned, Round};
 pub use num::{Primitive, Int, Float, ToStrRadix, ToPrimitive, FromPrimitive};
 pub use str::{Str, StrVector, StrSlice, OwnedStr};
 pub use to_bytes::IterBytes;
 pub use to_str::{ToStr, IntoStr};
-pub use tuple::{CopyableTuple, ImmutableTuple};
+pub use tuple::{CloneableTuple, ImmutableTuple};
 pub use tuple::{ImmutableTuple1, ImmutableTuple2, ImmutableTuple3, ImmutableTuple4};
 pub use tuple::{ImmutableTuple5, ImmutableTuple6, ImmutableTuple7, ImmutableTuple8};
 pub use tuple::{ImmutableTuple9, ImmutableTuple10, ImmutableTuple11, ImmutableTuple12};
 pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4};
 pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8};
 pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12};
-pub use vec::{ImmutableEqVector, ImmutableTotalOrdVector, ImmutableCopyableVector};
-pub use vec::{OwnedVector, OwnedCopyableVector,OwnedEqVector};
+pub use vec::{ImmutableEqVector, ImmutableTotalOrdVector, ImmutableCloneableVector};
+pub use vec::{OwnedVector, OwnedCloneableVector,OwnedEqVector};
 pub use vec::{MutableVector, MutableTotalOrdVector};
-pub use vec::{Vector, VectorVector, CopyableVector, ImmutableVector};
+pub use vec::{Vector, VectorVector, CloneableVector, ImmutableVector};
 
 // Reexported runtime types
 pub use comm::{Port, Chan, SharedChan};
index a996233abe3dc7ee1eae44d32af85c0f035e745c..140323110df682e0c2efc1ef91c7c42d8b11b49f 100644 (file)
@@ -51,7 +51,7 @@ pub trait Sample<Support> {
 /// Since no state is recorded, each sample is (statistically)
 /// independent of all others, assuming the `Rng` used has this
 /// property.
-// XXX maybe having this separate is overkill (the only reason is to
+// FIXME maybe having this separate is overkill (the only reason is to
 // take &self rather than &mut self)? or maybe this should be the
 // trait called `Sample` and the other should be `DependentSample`.
 pub trait IndependentSample<Support>: Sample<Support> {
index 6fd2cde9dfbc6ae77f738bd9490a9e28517e85b8..9871207a91e6ad4dfa98507cacea28430e042c2e 100644 (file)
@@ -12,7 +12,6 @@
 
 use rand::{Rng, SeedableRng, OSRng};
 use iter::{Iterator, range, range_step, Repeat};
-use num::Times;
 use option::{None, Some};
 use vec::{raw, MutableVector, ImmutableVector};
 use mem;
@@ -95,7 +94,7 @@ macro_rules! mix(
             }}
         );
 
-        4.times(|| mix!());
+        for _ in range(0, 4) { mix!(); }
 
         if use_rsl {
             macro_rules! memloop (
index a8fd75c1beeedf1d60142b57b0e461c8dda34947..c359d79d27509e8204d4ce089d94432fadcd172a 100644 (file)
@@ -159,7 +159,7 @@ fn test_os_rng_tasks() {
         for _ in range(0, 20) {
             let (p, c) = Chan::new();
             chans.push(c);
-            do task::spawn {
+            task::spawn(proc() {
                 // wait until all the tasks are ready to go.
                 p.recv();
 
@@ -177,7 +177,7 @@ fn test_os_rng_tasks() {
                     r.fill_bytes(v);
                     task::deschedule();
                 }
-            }
+            })
         }
 
         // start all the tasks
index 1c90ef148fc08c17b918ab7f7f5f157fd4423d7c..8f4752b3c44c7e3f684e118fdda574b1b5193be3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -19,7 +19,7 @@
 impl Rand for int {
     #[inline]
     fn rand<R: Rng>(rng: &mut R) -> int {
-        if int::bits == 32 {
+        if int::BITS == 32 {
             rng.gen::<i32>() as int
         } else {
             rng.gen::<i64>() as int
@@ -58,7 +58,7 @@ fn rand<R: Rng>(rng: &mut R) -> i64 {
 impl Rand for uint {
     #[inline]
     fn rand<R: Rng>(rng: &mut R) -> uint {
-        if uint::bits == 32 {
+        if uint::BITS == 32 {
             rng.gen::<u32>() as uint
         } else {
             rng.gen::<u64>() as uint
diff --git a/src/libstd/reference.rs b/src/libstd/reference.rs
new file mode 100644 (file)
index 0000000..91f03f0
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Utilities for references
+
+#[cfg(not(test))]
+use prelude::*;
+
+// Equality for region pointers
+#[cfg(not(test))]
+impl<'a, T: Eq> Eq for &'a T {
+    #[inline]
+    fn eq(&self, other: & &'a T) -> bool {
+        *(*self) == *(*other)
+    }
+    #[inline]
+    fn ne(&self, other: & &'a T) -> bool {
+        *(*self) != *(*other)
+    }
+}
+
+// Comparison for region pointers
+#[cfg(not(test))]
+impl<'a, T: Ord> Ord for &'a T {
+    #[inline]
+    fn lt(&self, other: & &'a T) -> bool {
+        *(*self) < *(*other)
+    }
+    #[inline]
+    fn le(&self, other: & &'a T) -> bool {
+        *(*self) <= *(*other)
+    }
+    #[inline]
+    fn ge(&self, other: & &'a T) -> bool {
+        *(*self) >= *(*other)
+    }
+    #[inline]
+    fn gt(&self, other: & &'a T) -> bool {
+        *(*self) > *(*other)
+    }
+}
+
+#[cfg(not(test))]
+impl<'a, T: TotalOrd> TotalOrd for &'a T {
+    #[inline]
+    fn cmp(&self, other: & &'a T) -> Ordering { (**self).cmp(*other) }
+}
+
+#[cfg(not(test))]
+impl<'a, T: TotalEq> TotalEq for &'a T {
+    #[inline]
+    fn equals(&self, other: & &'a T) -> bool { (**self).equals(*other) }
+}
+
index c0af649f26cfe7395843f473b120248e2c0825d6..87655f5911fe700927684768f67575d0c3989c70 100644 (file)
@@ -451,13 +451,8 @@ fn visit_type(&mut self) -> bool {
         true
     }
 
-    fn visit_opaque_box(&mut self) -> bool {
-        self.align_to::<@u8>();
-        if ! self.inner.visit_opaque_box() { return false; }
-        self.bump_past::<@u8>();
-        true
-    }
-
+    // NOTE remove after next snapshot
+    #[cfg(stage0)]
     fn visit_closure_ptr(&mut self, ck: uint) -> bool {
         self.align_to::<proc()>();
         if ! self.inner.visit_closure_ptr(ck) {
index e3b34147c010a33e33413fa8d1dab0b3fde898a3..1ecc31ec2f4e9a5571924d20b7ac22291e27792e 100644 (file)
@@ -580,14 +580,8 @@ fn visit_param(&mut self, _i: uint) -> bool { true }
     fn visit_self(&mut self) -> bool { true }
     fn visit_type(&mut self) -> bool { true }
 
-    fn visit_opaque_box(&mut self) -> bool {
-        self.writer.write(['@' as u8]);
-        self.get::<&raw::Box<()>>(|this, b| {
-            let p = ptr::to_unsafe_ptr(&b.data) as *u8;
-            this.visit_ptr_inner(p, b.type_desc);
-        })
-    }
-
+    // NOTE remove after next snapshot
+    #[cfg(stage0)]
     fn visit_closure_ptr(&mut self, _ck: uint) -> bool { true }
 }
 
index 1a4e6d5bcfde95f4ea3b0b5d214d4f65119dfba2..c3618bad18ec4f8cb6af067e82b52f57df070adb 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -20,6 +20,7 @@
 
 /// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
 #[deriving(Clone, DeepClone, Eq, Ord, TotalEq, TotalOrd, ToStr)]
+#[must_use]
 pub enum Result<T, E> {
     /// Contains the success value
     Ok(T),
@@ -227,7 +228,7 @@ fn fmt(s: &Result<T, E>, f: &mut fmt::Formatter) {
 /// checking for overflow:
 ///
 ///     fn inc_conditionally(x: uint) -> Result<uint, &'static str> {
-///         if x == uint::max_value { return Err("overflow"); }
+///         if x == uint::MAX { return Err("overflow"); }
 ///         else { return Ok(x+1u); }
 ///     }
 ///     let v = [1u, 2, 3];
index 6ea12659e77f249b7767def0ea98db5e2a3014f5..8567f0e02516121ffceb1eab9ec48edb26008fb8 100644 (file)
@@ -108,7 +108,7 @@ fn do_iter_crate_map<'a>(
 
 /// Iterates recursively over `crate_map` and all child crate maps
 pub fn iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: |&ModEntry|) {
-    // XXX: use random numbers as keys from the OS-level RNG when there is a nice
+    // FIXME: use random numbers as keys from the OS-level RNG when there is a nice
     //        way to do this
     let mut v: HashSet<*CrateMap<'a>> = HashSet::with_capacity_and_keys(0, 0, 32);
     do_iter_crate_map(crate_map, f, &mut v);
index f3fa482b18cca468217bcaea08f99f618d71e92c..729e377e1af31797ad4fbae8418f6e7dc18fe5f4 100644 (file)
@@ -10,7 +10,7 @@
 
 //! Runtime environment settings
 
-use from_str::FromStr;
+use from_str::from_str;
 use option::{Some, None};
 use os;
 
 // They are expected to be initialized once then left alone.
 
 static mut MIN_STACK: uint = 2 * 1024 * 1024;
+/// This default corresponds to 20M of cache per scheduler (at the default size).
+static mut MAX_CACHED_STACKS: uint = 10;
 static mut DEBUG_BORROW: bool = false;
 static mut POISON_ON_FREE: bool = false;
 
 pub fn init() {
     unsafe {
         match os::getenv("RUST_MIN_STACK") {
-            Some(s) => match FromStr::from_str(s) {
+            Some(s) => match from_str(s) {
                 Some(i) => MIN_STACK = i,
                 None => ()
             },
             None => ()
         }
+        match os::getenv("RUST_MAX_CACHED_STACKS") {
+            Some(max) => MAX_CACHED_STACKS = from_str(max).expect("expected positive integer in \
+                                                                   RUST_MAX_CACHED_STACKS"),
+            None => ()
+        }
         match os::getenv("RUST_DEBUG_BORROW") {
             Some(_) => DEBUG_BORROW = true,
             None => ()
@@ -45,6 +52,10 @@ pub fn min_stack() -> uint {
     unsafe { MIN_STACK }
 }
 
+pub fn max_cached_stacks() -> uint {
+    unsafe { MAX_CACHED_STACKS }
+}
+
 pub fn debug_borrow() -> bool {
     unsafe { DEBUG_BORROW }
 }
index 37596b3501542c0deacbc2c66929d32cab0fdd3c..76a672b79cada5638095031819a2ab940f5151ab 100644 (file)
@@ -57,17 +57,17 @@ mod test {
 
     #[test]
     fn thread_local_task_smoke_test() {
-        do run_in_bare_thread {
+        run_in_bare_thread(proc() {
             let task = ~Task::new();
             Local::put(task);
             let task: ~Task = Local::take();
             cleanup_task(task);
-        }
+        });
     }
 
     #[test]
     fn thread_local_task_two_instances() {
-        do run_in_bare_thread {
+        run_in_bare_thread(proc() {
             let task = ~Task::new();
             Local::put(task);
             let task: ~Task = Local::take();
@@ -76,13 +76,12 @@ fn thread_local_task_two_instances() {
             Local::put(task);
             let task: ~Task = Local::take();
             cleanup_task(task);
-        }
-
+        });
     }
 
     #[test]
     fn borrow_smoke_test() {
-        do run_in_bare_thread {
+        run_in_bare_thread(proc() {
             let task = ~Task::new();
             Local::put(task);
 
@@ -91,12 +90,12 @@ fn borrow_smoke_test() {
             }
             let task: ~Task = Local::take();
             cleanup_task(task);
-        }
+        });
     }
 
     #[test]
     fn borrow_with_return() {
-        do run_in_bare_thread {
+        run_in_bare_thread(proc() {
             let task = ~Task::new();
             Local::put(task);
 
@@ -106,12 +105,12 @@ fn borrow_with_return() {
 
             let task: ~Task = Local::take();
             cleanup_task(task);
-        }
+        });
     }
 
     #[test]
     fn try_take() {
-        do run_in_bare_thread {
+        run_in_bare_thread(proc() {
             let task = ~Task::new();
             Local::put(task);
 
@@ -120,7 +119,7 @@ fn try_take() {
             assert!(u.is_none());
 
             cleanup_task(t);
-        }
+        });
     }
 
     fn cleanup_task(mut t: ~Task) {
index 36e3bf858e3efde618c28d6fe8134488437a4aaa..42a7e7867f94d321e90ded3e0b158e9dc568b6fa 100644 (file)
@@ -293,7 +293,7 @@ fn drop(&mut self) {
 
 #[inline]
 pub unsafe fn local_malloc(td: *u8, size: uint) -> *u8 {
-    // XXX: Unsafe borrow for speed. Lame.
+    // FIXME: Unsafe borrow for speed. Lame.
     let task: Option<*mut Task> = Local::try_unsafe_borrow();
     match task {
         Some(task) => {
@@ -306,7 +306,7 @@ pub unsafe fn local_malloc(td: *u8, size: uint) -> *u8 {
 // A little compatibility function
 #[inline]
 pub unsafe fn local_free(ptr: *u8) {
-    // XXX: Unsafe borrow for speed. Lame.
+    // FIXME: Unsafe borrow for speed. Lame.
     let task_ptr: Option<*mut Task> = Local::try_unsafe_borrow();
     match task_ptr {
         Some(task) => {
index 7aa966802f2f5ec8fa5a2202853f72e100951754..0e30f3e2efd0976990adc5cc32745dcc52335bde 100644 (file)
 Several modules in `core` are clients of `rt`:
 
 * `std::task` - The user-facing interface to the Rust task model.
-* `std::task::local_data` - The interface to local data.
+* `std::local_data` - The interface to local data.
 * `std::gc` - The garbage collector.
 * `std::unstable::lang` - Miscellaneous lang items, some of which rely on `std::rt`.
 * `std::condition` - Uses local data.
 * `std::cleanup` - Local heap destruction.
 * `std::io` - In the future `std::io` will use an `rt` implementation.
 * `std::logging`
-* `std::pipes`
 * `std::comm`
-* `std::stackwalk`
 
 */
 
-// XXX: this should not be here.
+// FIXME: this should not be here.
 #[allow(missing_doc)];
 
 use any::Any;
@@ -71,9 +69,9 @@
 pub use self::util::default_sched_threads;
 
 // Export unwinding facilities used by the failure macros
-pub use self::unwind::{begin_unwind, begin_unwind_raw};
+pub use self::unwind::{begin_unwind, begin_unwind_raw, begin_unwind_fmt};
 
-// XXX: these probably shouldn't be public...
+// FIXME: these probably shouldn't be public...
 #[doc(hidden)]
 pub mod shouldnt_be_public {
     pub use super::local_ptr::native::maybe_tls_key;
@@ -157,7 +155,7 @@ fn deschedule(~self, times: uint, cur_task: ~Task,
     /// The (low, high) edges of the current stack.
     fn stack_bounds(&self) -> (uint, uint); // (lo, hi)
 
-    // XXX: This is a serious code smell and this should not exist at all.
+    // FIXME: This is a serious code smell and this should not exist at all.
     fn wrap(~self) -> ~Any;
 }
 
@@ -167,7 +165,7 @@ fn deschedule(~self, times: uint, cur_task: ~Task,
 /// the crate's logging flags, registering GC
 /// metadata, and storing the process arguments.
 pub fn init(argc: int, argv: **u8) {
-    // XXX: Derefing these pointers is not safe.
+    // FIXME: Derefing these pointers is not safe.
     // Need to propagate the unsafety to `start`.
     unsafe {
         args::init(argc, argv);
index 6b3d50a76ac8fce9151b09259b296e37e8aec424..455a84b4ce3cf33079f791db864c386333cada37 100644 (file)
@@ -86,7 +86,7 @@ pub struct LocalIo<'a> {
 #[unsafe_destructor]
 impl<'a> Drop for LocalIo<'a> {
     fn drop(&mut self) {
-        // XXX(pcwalton): Do nothing here for now, but eventually we may want
+        // FIXME(pcwalton): Do nothing here for now, but eventually we may want
         // something. For now this serves to make `LocalIo` noncopyable.
     }
 }
@@ -143,7 +143,7 @@ pub fn new<'a>(io: &'a mut IoFactory) -> LocalIo<'a> {
     /// Returns the underlying I/O factory as a trait reference.
     #[inline]
     pub fn get<'a>(&'a mut self) -> &'a mut IoFactory {
-        // XXX(pcwalton): I think this is actually sound? Could borrow check
+        // FIXME(pcwalton): I think this is actually sound? Could borrow check
         // allow this safely?
         unsafe {
             cast::transmute_copy(&self.factory)
index e63208bcaec6fb0c9266e20714002ab3c2a1b4c4..7c43e64f17b15b6e6ed39cad779d0fe3c5a65944 100644 (file)
@@ -14,7 +14,6 @@
 //! to implement this.
 
 use any::AnyOwnExt;
-use borrow;
 use cast;
 use cleanup;
 use clone::Clone;
@@ -212,7 +211,7 @@ pub fn maybe_take_runtime<T: 'static>(&mut self) -> Option<~T> {
         // pretty sketchy and involves shuffling vtables of trait objects
         // around, but it gets the job done.
         //
-        // XXX: This function is a serious code smell and should be avoided at
+        // FIXME: This function is a serious code smell and should be avoided at
         //      all costs. I have yet to think of a method to avoid this
         //      function, and I would be saddened if more usage of the function
         //      crops up.
@@ -287,7 +286,7 @@ pub fn stack_bounds(&self) -> (uint, uint) {
 
 impl Drop for Task {
     fn drop(&mut self) {
-        rtdebug!("called drop for a task: {}", borrow::to_uint(self));
+        rtdebug!("called drop for a task: {}", self as *mut Task as uint);
         rtassert!(self.destroyed);
     }
 }
index b5262424c065c23761a0bbff7e85f88dd7796e54..83f5ca346a9369104c4e7b4455adcf44a11b5f6a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -43,7 +43,7 @@ pub struct Thread<T> {
 extern fn thread_start(main: *libc::c_void) -> imp::rust_thread_return {
     use unstable::stack;
     unsafe {
-        stack::record_stack_bounds(0, uint::max_value);
+        stack::record_stack_bounds(0, uint::MAX);
         let f: ~proc() = cast::transmute(main);
         (*f)();
         cast::transmute(0 as imp::rust_thread_return)
@@ -255,11 +255,11 @@ mod tests {
     use super::Thread;
 
     #[test]
-    fn smoke() { do Thread::start {}.join(); }
+    fn smoke() { Thread::start(proc (){}).join(); }
 
     #[test]
-    fn data() { assert_eq!(do Thread::start { 1 }.join(), 1); }
+    fn data() { assert_eq!(Thread::start(proc () { 1 }).join(), 1); }
 
     #[test]
-    fn detached() { do Thread::spawn {} }
+    fn detached() { Thread::spawn(proc () {}) }
 }
index 6f3aa4c4fd07ba70225bd2ede9e96f36b8629ee0..88c6b52ec236696f9a9f07ce329449fc2f421d99 100644 (file)
@@ -58,6 +58,7 @@
 use any::{Any, AnyRefExt};
 use c_str::CString;
 use cast;
+use fmt;
 use kinds::Send;
 use option::{Some, None, Option};
 use prelude::drop;
@@ -382,17 +383,47 @@ fn static_char_ptr(p: *u8) -> &'static str {
     begin_unwind(msg, file, line as uint)
 }
 
+/// 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 implact
+/// on (e.g.) the inlining of other functions as possible), by moving
+/// the actual formatting into this shared place.
+#[inline(never)] #[cold]
+pub fn begin_unwind_fmt(msg: &fmt::Arguments, file: &'static str, line: 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
+    // below).
+    begin_unwind_inner(~fmt::format(msg), file, line)
+}
+
 /// This is the entry point of unwinding for fail!() and assert!().
-#[inline(never)] #[cold] // this is the slow path, please never inline this
+#[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
 pub fn begin_unwind<M: Any + Send>(msg: M, file: &'static str, line: uint) -> ! {
-    // Note that this should be the only allocation performed in this block.
+    // 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
     // 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.
-    let msg = ~msg as ~Any;
 
+    // see below for why we do the `Any` coercion here.
+    begin_unwind_inner(~msg, file, line)
+}
+
+
+/// The core of the unwinding.
+///
+/// This is non-generic to avoid instantiation bloat in other crates
+/// (which makes compilation of small crates noticably slower). (Note:
+/// 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!()
+/// }` 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: ~Any, file: &'static str, line: uint) -> ! {
     let mut task;
     {
         let msg_s = match msg.as_ref::<&'static str>() {
index b482e2fb67fae080d5c831e828d6b21dfa4bb737..9c17c624987b5fb220df6d75208628545a70b8eb 100644 (file)
@@ -20,7 +20,7 @@
 use vec::ImmutableVector;
 
 // Indicates whether we should perform expensive sanity checks, including rtassert!
-// XXX: Once the runtime matures remove the `true` below to turn off rtassert, etc.
+// FIXME: Once the runtime matures remove the `true` below to turn off rtassert, etc.
 pub static ENFORCE_SANITY: bool = true || !cfg!(rtopt) || cfg!(rtdebug) || cfg!(rtassert);
 
 /// Get the number of cores available
index d0ca6efd2472b62ade7afcdd9dfc57a41c615777..ef2374f6095dad86aa0795864ea8dd6ed91b4b18 100644 (file)
@@ -223,22 +223,22 @@ pub fn finish_with_output(&mut self) -> ProcessOutput {
         let (p, ch) = SharedChan::new();
         let ch_clone = ch.clone();
 
-        do spawn {
+        spawn(proc() {
             let _guard = io::ignore_io_error();
             let mut error = error;
             match error {
                 Some(ref mut e) => ch.send((2, e.read_to_end())),
                 None => ch.send((2, ~[]))
             }
-        }
-        do spawn {
+        });
+        spawn(proc() {
             let _guard = io::ignore_io_error();
             let mut output = output;
             match output {
                 Some(ref mut e) => ch_clone.send((1, e.read_to_end())),
                 None => ch_clone.send((1, ~[]))
             }
-        }
+        });
 
         let status = self.finish();
 
@@ -414,9 +414,9 @@ fn test_pipes() {
         os::close(pipe_out.out as int);
         os::close(pipe_err.out as int);
 
-        do spawn {
+        spawn(proc() {
             writeclose(pipe_in.out, "test");
-        }
+        });
         let actual = readclose(pipe_out.input);
         readclose(pipe_err.input);
         process.finish();
index c8143442d6e37c735cafa8b27740893fd528d4ad..b6c9acd26723d0d46b2aef74be28e03590ff11f2 100644 (file)
@@ -119,7 +119,7 @@ impl Str for SendStr {
     fn as_slice<'r>(&'r self) -> &'r str {
         match *self {
             SendStrOwned(ref s) => s.as_slice(),
-            // XXX: Borrowchecker doesn't recognize lifetime as static unless prompted
+            // FIXME: Borrowchecker doesn't recognize lifetime as static unless prompted
             // SendStrStatic(s) => s.as_slice()
             SendStrStatic(s)    => {let tmp: &'static str = s; tmp}
         }
index 22c9ae606d37aeb7efb31323240703196368c1bd..9cc9799d0c017b2b9cba4f2c6248167ef0d2db93 100644 (file)
@@ -112,7 +112,7 @@ fn main() {
 use from_str::FromStr;
 use uint;
 use vec;
-use vec::{OwnedVector, OwnedCopyableVector, ImmutableVector, MutableVector};
+use vec::{OwnedVector, OwnedCloneableVector, ImmutableVector, MutableVector};
 use default::Default;
 use send_str::{SendStr, SendStrOwned};
 use unstable::raw::Repr;
@@ -594,7 +594,7 @@ fn next(&mut self) -> Option<&'a str> {
 // Helper functions used for Unicode normalization
 fn canonical_sort(comb: &mut [(char, u8)]) {
     use iter::range;
-    use tuple::CopyableTuple;
+    use tuple::CloneableTuple;
 
     let len = comb.len();
     for i in range(0, len) {
@@ -620,7 +620,7 @@ enum NormalizationForm {
 /// External iterator for a string's normalization's characters.
 /// Use with the `std::iter` module.
 #[deriving(Clone)]
-struct Normalizations<'a> {
+pub struct Normalizations<'a> {
     priv kind: NormalizationForm,
     priv iter: Chars<'a>,
     priv buffer: ~[(char, u8)],
index e740862fddfb407f3bd4277c38631a7413ab9a14..7feff127d691a029511e7af37995d1b7b6bfc761 100644 (file)
@@ -45,7 +45,7 @@
 // NB: the "buffer pool" strategy is not done for speed, but rather for
 //     correctness. For more info, see the comment on `swap_buffer`
 
-// XXX: all atomic operations in this module use a SeqCst ordering. That is
+// FIXME: all atomic operations in this module use a SeqCst ordering. That is
 //      probably overkill
 
 use cast;
@@ -425,7 +425,7 @@ fn stealpush() {
         static AMT: int = 100000;
         let mut pool = BufferPool::<int>::new();
         let (mut w, s) = pool.deque();
-        let t = do Thread::start {
+        let t = Thread::start(proc() {
             let mut s = s;
             let mut left = AMT;
             while left > 0 {
@@ -437,7 +437,7 @@ fn stealpush() {
                     Abort | Empty => {}
                 }
             }
-        };
+        });
 
         for _ in range(0, AMT) {
             w.push(1);
@@ -451,7 +451,7 @@ fn stealpush_large() {
         static AMT: int = 100000;
         let mut pool = BufferPool::<(int, int)>::new();
         let (mut w, s) = pool.deque();
-        let t = do Thread::start {
+        let t = Thread::start(proc() {
             let mut s = s;
             let mut left = AMT;
             while left > 0 {
@@ -461,7 +461,7 @@ fn stealpush_large() {
                     Abort | Empty => {}
                 }
             }
-        };
+        });
 
         for _ in range(0, AMT) {
             w.push((1, 10));
@@ -480,7 +480,7 @@ fn stampede(mut w: Worker<~int>, s: Stealer<~int>,
 
         let threads = range(0, nthreads).map(|_| {
             let s = s.clone();
-            do Thread::start {
+            Thread::start(proc() {
                 unsafe {
                     let mut s = s;
                     while (*unsafe_remaining).load(SeqCst) > 0 {
@@ -493,7 +493,7 @@ fn stampede(mut w: Worker<~int>, s: Stealer<~int>,
                         }
                     }
                 }
-            }
+            })
         }).to_owned_vec();
 
         while remaining.load(SeqCst) > 0 {
@@ -522,9 +522,9 @@ fn many_stampede() {
         let mut pool = BufferPool::<~int>::new();
         let threads = range(0, AMT).map(|_| {
             let (w, s) = pool.deque();
-            do Thread::start {
+            Thread::start(proc() {
                 stampede(w, s, 4, 10000);
-            }
+            })
         }).to_owned_vec();
 
         for thread in threads.move_iter() {
@@ -543,7 +543,7 @@ fn stress() {
 
         let threads = range(0, NTHREADS).map(|_| {
             let s = s.clone();
-            do Thread::start {
+            Thread::start(proc() {
                 unsafe {
                     let mut s = s;
                     loop {
@@ -555,7 +555,7 @@ fn stress() {
                         }
                     }
                 }
-            }
+            })
         }).to_owned_vec();
 
         let mut rng = rand::task_rng();
@@ -606,7 +606,7 @@ fn no_starvation() {
             let thread_box = unsafe {
                 *cast::transmute::<&~AtomicUint,**mut AtomicUint>(&unique_box)
             };
-            (do Thread::start {
+            (Thread::start(proc() {
                 unsafe {
                     let mut s = s;
                     loop {
@@ -620,7 +620,7 @@ fn no_starvation() {
                         }
                     }
                 }
-            }, unique_box)
+            }), unique_box)
         }));
 
         let mut rng = rand::task_rng();
index 18be85152d715a772cad9652623e80b464351ccd..bb0e96f96de2b8417583d4f9e7119b3d2237a42b 100644 (file)
@@ -177,13 +177,13 @@ fn test() {
         for _ in range(0, nthreads) {
             let q = q.clone();
             let chan = chan.clone();
-            do native::task::spawn {
+            native::task::spawn(proc() {
                 let mut q = q;
                 for i in range(0, nmsgs) {
                     assert!(q.push(i));
                 }
                 chan.send(());
-            }
+            });
         }
 
         let mut completion_ports = ~[];
@@ -191,7 +191,7 @@ fn test() {
             let (completion_port, completion_chan) = Chan::new();
             completion_ports.push(completion_port);
             let q = q.clone();
-            do native::task::spawn {
+            native::task::spawn(proc() {
                 let mut q = q;
                 let mut i = 0u;
                 loop {
@@ -204,7 +204,7 @@ fn test() {
                     }
                 }
                 completion_chan.send(i);
-            }
+            });
         }
 
         for completion_port in completion_ports.mut_iter() {
index a249d6ed2e8ce8cc65e93398db6a74fc4c251500..1ec8ac5d83e055abe2ef14330c39585b5e8dd903 100644 (file)
@@ -227,13 +227,13 @@ fn test() {
         for _ in range(0, nthreads) {
             let q = p.clone();
             let chan = chan.clone();
-            do native::task::spawn {
+            native::task::spawn(proc() {
                 let mut q = q;
                 for i in range(0, nmsgs) {
                     q.push(i);
                 }
                 chan.send(());
-            }
+            });
         }
 
         let mut i = 0u;
index 6f1b887c271569c2ca23a9d6209367768fc719c6..35a5846f11aba287fc843ca4b16034d24b50dcbd 100644 (file)
@@ -43,7 +43,7 @@
 
 // Node within the linked list queue of messages to send
 struct Node<T> {
-    // XXX: this could be an uninitialized T if we're careful enough, and
+    // FIXME: this could be an uninitialized T if we're careful enough, and
     //      that would reduce memory usage (and be a bit faster).
     //      is it worth it?
     value: Option<T>,           // nullable for re-use of nodes
@@ -225,7 +225,7 @@ unsafe fn pop(&mut self) -> Option<T> {
         if self.cache_bound == 0 {
             self.tail_prev.store(tail, Release);
         } else {
-            // XXX: this is dubious with overflow.
+            // FIXME: this is dubious with overflow.
             let additions = self.cache_additions.load(Relaxed);
             let subtractions = self.cache_subtractions.load(Relaxed);
             let size = additions - subtractions;
@@ -315,7 +315,7 @@ fn stress() {
         fn stress_bound(bound: uint) {
             let (c, mut p) = queue(bound, ());
             let (port, chan) = Chan::new();
-            do native::task::spawn {
+            native::task::spawn(proc() {
                 let mut c = c;
                 for _ in range(0, 100000) {
                     loop {
@@ -327,7 +327,7 @@ fn stress_bound(bound: uint) {
                     }
                 }
                 chan.send(());
-            }
+            });
             for _ in range(0, 100000) {
                 p.push(1);
             }
index 8ed4b70c0a28aa8a97075293c2bf375a79b1da60..c8b690830866e9a763a9ce99bf53682298babc2a 100644 (file)
@@ -45,9 +45,9 @@
  * # Example
  *
  * ```
- * do spawn {
+ * spawn(proc() {
  *     log(error, "Hello, World!");
- * }
+ * })
  * ```
  */
 
@@ -265,9 +265,9 @@ pub fn try<T:Send>(mut self, f: proc() -> T) -> Result<T, ~Any> {
 
         let result = self.future_result();
 
-        do self.spawn {
+        self.spawn(proc() {
             ch.send(f());
-        }
+        });
 
         match result.recv() {
             Ok(())     => Ok(po.recv()),
@@ -365,52 +365,52 @@ pub fn failing() -> bool {
 
 #[test]
 fn test_unnamed_task() {
-    do spawn {
+    spawn(proc() {
         with_task_name(|name| {
             assert!(name.is_none());
         })
-    }
+    })
 }
 
 #[test]
 fn test_owned_named_task() {
     let mut t = task();
     t.name(~"ada lovelace");
-    do t.spawn {
+    t.spawn(proc() {
         with_task_name(|name| {
             assert!(name.unwrap() == "ada lovelace");
         })
-    }
+    })
 }
 
 #[test]
 fn test_static_named_task() {
     let mut t = task();
     t.name("ada lovelace");
-    do t.spawn {
+    t.spawn(proc() {
         with_task_name(|name| {
             assert!(name.unwrap() == "ada lovelace");
         })
-    }
+    })
 }
 
 #[test]
 fn test_send_named_task() {
     let mut t = task();
     t.name("ada lovelace".into_send_str());
-    do t.spawn {
+    t.spawn(proc() {
         with_task_name(|name| {
             assert!(name.unwrap() == "ada lovelace");
         })
-    }
+    })
 }
 
 #[test]
 fn test_run_basic() {
     let (po, ch) = Chan::new();
-    do task().spawn {
+    task().spawn(proc() {
         ch.send(());
-    }
+    });
     po.recv();
 }
 
@@ -418,15 +418,15 @@ fn test_run_basic() {
 fn test_add_wrapper() {
     let (po, ch) = Chan::new();
     let mut b0 = task();
-    do b0.add_wrapper |body| {
+    b0.add_wrapper(proc(body) {
         let ch = ch;
         let result: proc() = proc() {
             body();
             ch.send(());
         };
         result
-    };
-    do b0.spawn { }
+    });
+    b0.spawn(proc() { });
     po.recv();
 }
 
@@ -434,14 +434,14 @@ fn test_add_wrapper() {
 fn test_future_result() {
     let mut builder = task();
     let result = builder.future_result();
-    do builder.spawn {}
+    builder.spawn(proc() {});
     assert!(result.recv().is_ok());
 
     let mut builder = task();
     let result = builder.future_result();
-    do builder.spawn {
+    builder.spawn(proc() {
         fail!();
-    }
+    });
     assert!(result.recv().is_err());
 }
 
@@ -454,9 +454,9 @@ fn test_back_to_the_future_result() {
 
 #[test]
 fn test_try_success() {
-    match do try {
+    match try(proc() {
         ~"Success!"
-    } {
+    }) {
         result::Ok(~"Success!") => (),
         _ => fail!()
     }
@@ -464,9 +464,9 @@ fn test_try_success() {
 
 #[test]
 fn test_try_fail() {
-    match do try {
+    match try(proc() {
         fail!()
-    } {
+    }) {
         result::Err(_) => (),
         result::Ok(()) => fail!()
     }
@@ -480,13 +480,13 @@ fn test_spawn_sched() {
 
     fn f(i: int, ch: SharedChan<()>) {
         let ch = ch.clone();
-        do spawn {
+        spawn(proc() {
             if i == 0 {
                 ch.send(());
             } else {
                 f(i - 1, ch);
             }
-        };
+        });
 
     }
     f(10, ch);
@@ -497,12 +497,12 @@ fn f(i: int, ch: SharedChan<()>) {
 fn test_spawn_sched_childs_on_default_sched() {
     let (po, ch) = Chan::new();
 
-    do spawn {
+    spawn(proc() {
         let ch = ch;
-        do spawn {
+        spawn(proc() {
             ch.send(());
-        };
-    };
+        });
+    });
 
     po.recv();
 }
@@ -514,10 +514,10 @@ fn avoid_copying_the_body(spawnfn: |v: proc()|) {
     let x = ~1;
     let x_in_parent = ptr::to_unsafe_ptr(&*x) as uint;
 
-    do spawnfn {
+    spawnfn(proc() {
         let x_in_child = ptr::to_unsafe_ptr(&*x) as uint;
         ch.send(x_in_child);
-    }
+    });
 
     let x_in_child = p.recv();
     assert_eq!(x_in_parent, x_in_child);
@@ -532,18 +532,18 @@ fn test_avoid_copying_the_body_spawn() {
 fn test_avoid_copying_the_body_task_spawn() {
     avoid_copying_the_body(|f| {
         let builder = task();
-        do builder.spawn || {
+        builder.spawn(proc() {
             f();
-        }
+        });
     })
 }
 
 #[test]
 fn test_avoid_copying_the_body_try() {
     avoid_copying_the_body(|f| {
-        do try || {
+        try(proc() {
             f()
-        };
+        });
     })
 }
 
@@ -575,9 +575,9 @@ fn test_simple_newsched_spawn() {
 
 #[test]
 fn test_try_fail_message_static_str() {
-    match do try {
+    match try(proc() {
         fail!("static string");
-    } {
+    }) {
         Err(e) => {
             type T = &'static str;
             assert!(e.is::<T>());
@@ -589,9 +589,9 @@ fn test_try_fail_message_static_str() {
 
 #[test]
 fn test_try_fail_message_owned_str() {
-    match do try {
+    match try(proc() {
         fail!(~"owned string");
-    } {
+    }) {
         Err(e) => {
             type T = ~str;
             assert!(e.is::<T>());
@@ -603,9 +603,9 @@ fn test_try_fail_message_owned_str() {
 
 #[test]
 fn test_try_fail_message_any() {
-    match do try {
+    match try(proc() {
         fail!(~413u16 as ~Any);
-    } {
+    }) {
         Err(e) => {
             type T = ~Any;
             assert!(e.is::<T>());
@@ -621,9 +621,9 @@ fn test_try_fail_message_any() {
 fn test_try_fail_message_unit_struct() {
     struct Juju;
 
-    match do try {
+    match try(proc() {
         fail!(Juju)
-    } {
+    }) {
         Err(ref e) if e.is::<Juju>() => {}
         Err(_) | Ok(()) => fail!()
     }
index 8b9b41f027c178176315462c6e8065b26bfe51eb..ef0930fabf1cd2605c20c00d27108475765d7301 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -21,7 +21,7 @@
 static SHIFT: uint = 4;
 static SIZE: uint = 1 << SHIFT;
 static MASK: uint = SIZE - 1;
-static NUM_CHUNKS: uint = uint::bits / SHIFT;
+static NUM_CHUNKS: uint = uint::BITS / SHIFT;
 
 enum Child<T> {
     Internal(~TrieNode<T>),
@@ -396,7 +396,7 @@ fn each_reverse<'a>(&'a self, f: |&uint, &'a T| -> bool) -> bool {
 // if this was done via a trait, the key could be generic
 #[inline]
 fn chunk(n: uint, idx: uint) -> uint {
-    let sh = uint::bits - (SHIFT * (idx + 1));
+    let sh = uint::BITS - (SHIFT * (idx + 1));
     (n >> sh) & MASK
 }
 
@@ -728,14 +728,14 @@ fn test_each_reverse() {
     fn test_each_reverse_break() {
         let mut m = TrieMap::new();
 
-        for x in range(uint::max_value - 10000, uint::max_value).rev() {
+        for x in range(uint::MAX - 10000, uint::MAX).rev() {
             m.insert(x, x / 2);
         }
 
-        let mut n = uint::max_value - 1;
+        let mut n = uint::MAX - 1;
         m.each_reverse(|k, v| {
-            if n == uint::max_value - 5000 { false } else {
-                assert!(n > uint::max_value - 5000);
+            if n == uint::MAX - 5000 { false } else {
+                assert!(n > uint::MAX - 5000);
 
                 assert_eq!(*k, n);
                 assert_eq!(*v, n / 2);
@@ -777,8 +777,8 @@ fn test_iteration() {
         let empty_map : TrieMap<uint> = TrieMap::new();
         assert_eq!(empty_map.iter().next(), None);
 
-        let first = uint::max_value - 10000;
-        let last = uint::max_value;
+        let first = uint::MAX - 10000;
+        let last = uint::MAX;
 
         let mut map = TrieMap::new();
         for x in range(first, last).rev() {
@@ -799,8 +799,8 @@ fn test_mut_iter() {
         let mut empty_map : TrieMap<uint> = TrieMap::new();
         assert!(empty_map.mut_iter().next().is_none());
 
-        let first = uint::max_value - 10000;
-        let last = uint::max_value;
+        let first = uint::MAX - 10000;
+        let last = uint::MAX;
 
         let mut map = TrieMap::new();
         for x in range(first, last).rev() {
@@ -1014,7 +1014,7 @@ mod test_set {
     #[test]
     fn test_sane_chunk() {
         let x = 1;
-        let y = 1 << (uint::bits - 1);
+        let y = 1 << (uint::BITS - 1);
 
         let mut trie = TrieSet::new();
 
index 8e278aeb2eab557630aa5b861403d3ba3e43bb02..33d23df242ce2dd61a9110f173429773eb8160a5 100644 (file)
@@ -17,7 +17,7 @@
 #[cfg(not(test))] use default::Default;
 
 /// Method extensions to pairs where both types satisfy the `Clone` bound
-pub trait CopyableTuple<T, U> {
+pub trait CloneableTuple<T, U> {
     /// Return the first element of self
     fn first(&self) -> T;
     /// Return the second element of self
@@ -26,7 +26,7 @@ pub trait CopyableTuple<T, U> {
     fn swap(&self) -> (U, T);
 }
 
-impl<T:Clone,U:Clone> CopyableTuple<T, U> for (T, U) {
+impl<T:Clone,U:Clone> CloneableTuple<T, U> for (T, U) {
     /// Return the first element of self
     #[inline]
     fn first(&self) -> T {
index 198df3090ee80fcc39bc2a2df19eaf5b58120e5a..067826f04dc8364f568ce76495bc859ba5a1979b 100644 (file)
@@ -57,6 +57,8 @@ pub struct TyDesc {
     align: uint,
 
     // Called on a copy of a value of type `T` *after* memcpy
+    // NOTE remove after next snapshot
+    #[cfg(stage0)]
     take_glue: GlueFn,
 
     // Called when a value of type `T` is no longer needed
@@ -164,7 +166,9 @@ fn visit_leave_fn(&mut self, purity: uint, proto: uint,
     fn visit_param(&mut self, i: uint) -> bool;
     fn visit_self(&mut self) -> bool;
     fn visit_type(&mut self) -> bool;
-    fn visit_opaque_box(&mut self) -> bool;
+
+    // NOTE remove after next snapshot
+    #[cfg(stage0)]
     fn visit_closure_ptr(&mut self, ck: uint) -> bool;
 }
 
index f4573785996c437e668ce3615349c0c68f15ecfb..87870ef033142c5b28998485babfaae2ab411907 100644 (file)
@@ -41,18 +41,18 @@ pub fn run_in_bare_thread(f: proc()) {
 #[test]
 fn test_run_in_bare_thread() {
     let i = 100;
-    do run_in_bare_thread {
+    run_in_bare_thread(proc() {
         assert_eq!(i, 100);
-    }
+    });
 }
 
 #[test]
 fn test_run_in_bare_thread_exchange() {
     // Does the exchange heap work without the runtime?
     let i = ~100;
-    do run_in_bare_thread {
+    run_in_bare_thread(proc() {
         assert!(i == ~100);
-    }
+    });
 }
 
 /// Dynamically inquire about whether we're running under V.
index 69c6204cc3236a5ba6c6a2f0044866c4035b5b50..39f0d7b5638bc366b5cef813ff2be6f8e9db9b6e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -389,9 +389,9 @@ pub fn doit(&mut self, f: ||) {
 
         let prev = self.cnt.fetch_add(1, atomics::SeqCst);
         if prev < 0 {
-            // Make sure we never overflow, we'll never have int::min_value
+            // Make sure we never overflow, we'll never have int::MIN
             // simultaneous calls to `doit` to make this value go back to 0
-            self.cnt.store(int::min_value, atomics::SeqCst);
+            self.cnt.store(int::MIN, atomics::SeqCst);
             return
         }
 
@@ -401,7 +401,7 @@ pub fn doit(&mut self, f: ||) {
         unsafe { self.mutex.lock() }
         if self.cnt.load(atomics::SeqCst) > 0 {
             f();
-            let prev = self.cnt.swap(int::min_value, atomics::SeqCst);
+            let prev = self.cnt.swap(int::MIN, atomics::SeqCst);
             self.lock_cnt.store(prev, atomics::SeqCst);
         }
         unsafe { self.mutex.unlock() }
@@ -439,7 +439,7 @@ fn stampede_once() {
         let (p, c) = SharedChan::new();
         for _ in range(0, 10) {
             let c = c.clone();
-            do spawn {
+            spawn(proc() {
                 for _ in range(0, 4) { task::deschedule() }
                 unsafe {
                     o.doit(|| {
@@ -449,7 +449,7 @@ fn stampede_once() {
                     assert!(run);
                 }
                 c.send(());
-            }
+            });
         }
 
         unsafe {
@@ -479,11 +479,11 @@ fn somke_cond() {
         static mut lock: Mutex = MUTEX_INIT;
         unsafe {
             lock.lock();
-            let t = do Thread::start {
+            let t = Thread::start(proc() {
                 lock.lock();
                 lock.signal();
                 lock.unlock();
-            };
+            });
             lock.wait();
             lock.unlock();
             t.join();
index a05f6e8af5a64108f8872d11dc88cc003744936c..1029e5fdbd3592f87e312ebb0e7f252eaf3ebeb5 100644 (file)
 
 #[allow(non_camel_case_types)];
 
+#[experimental]
 #[simd]
 pub struct i8x16(i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8);
 
+#[experimental]
 #[simd]
 pub struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16);
 
+#[experimental]
 #[simd]
 pub struct i32x4(i32, i32, i32, i32);
 
+#[experimental]
 #[simd]
 pub struct i64x2(i64, i64);
 
+#[experimental]
 #[simd]
 pub struct u8x16(u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8);
 
+#[experimental]
 #[simd]
 pub struct u16x8(u16, u16, u16, u16, u16, u16, u16, u16);
 
+#[experimental]
 #[simd]
 pub struct u32x4(u32, u32, u32, u32);
 
+#[experimental]
 #[simd]
 pub struct u64x2(u64, u64);
 
+#[experimental]
 #[simd]
 pub struct f32x4(f32, f32, f32, f32);
 
+#[experimental]
 #[simd]
 pub struct f64x2(f64, f64);
index 687efea939b52705e2f011174b0564d30a43a8c8..3b2c86c371217138a5cec130ebed2aeb007f8b28 100644 (file)
@@ -179,12 +179,12 @@ fn exclusive_new_arc() {
                 let (port, chan) = Chan::new();
                 futures.push(port);
 
-                do task::spawn {
+                task::spawn(proc() {
                     for _ in range(0u, count) {
                         total.with(|count| **count += 1);
                     }
                     chan.send(());
-                }
+                });
             };
 
             for f in futures.mut_iter() { f.recv() }
@@ -200,9 +200,9 @@ fn exclusive_new_poison() {
             // accesses will also fail.
             let x = Exclusive::new(1);
             let x2 = x.clone();
-            do task::try || {
+            task::try(proc() {
                 x2.with(|one| assert_eq!(*one, 2))
-            };
+            });
             x.with(|one| assert_eq!(*one, 1));
         }
     }
index 41cae372dbbe1f7761d9cf3146c72c23e05509f6..467bcf075f60cae573ad80b13aef6924dd54624c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -798,8 +798,8 @@ fn len(&self) -> uint {
     }
 }
 
-/// Extension methods for vector slices with copyable elements
-pub trait CopyableVector<T> {
+/// Extension methods for vector slices with cloneable elements
+pub trait CloneableVector<T> {
     /// Copy `self` into a new owned vector
     fn to_owned(&self) -> ~[T];
 
@@ -808,7 +808,7 @@ pub trait CopyableVector<T> {
 }
 
 /// Extension methods for vector slices
-impl<'a, T: Clone> CopyableVector<T> for &'a [T] {
+impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
     /// Returns a copy of `v`.
     #[inline]
     fn to_owned(&self) -> ~[T] {
@@ -824,7 +824,7 @@ fn into_owned(self) -> ~[T] { self.to_owned() }
 }
 
 /// Extension methods for owned vectors
-impl<T: Clone> CopyableVector<T> for ~[T] {
+impl<T: Clone> CloneableVector<T> for ~[T] {
     #[inline]
     fn to_owned(&self) -> ~[T] { self.clone() }
 
@@ -833,7 +833,7 @@ fn into_owned(self) -> ~[T] { self }
 }
 
 /// Extension methods for managed vectors
-impl<T: Clone> CopyableVector<T> for @[T] {
+impl<T: Clone> CloneableVector<T> for @[T] {
     #[inline]
     fn to_owned(&self) -> ~[T] { self.as_slice().to_owned() }
 
@@ -1072,7 +1072,7 @@ fn rev_iter(self) -> RevItems<'a, T> {
 
     #[inline]
     fn split(self, pred: 'a |&T| -> bool) -> Splits<'a, T> {
-        self.splitn(uint::max_value, pred)
+        self.splitn(uint::MAX, pred)
     }
 
     #[inline]
@@ -1087,7 +1087,7 @@ fn splitn(self, n: uint, pred: 'a |&T| -> bool) -> Splits<'a, T> {
 
     #[inline]
     fn rsplit(self, pred: 'a |&T| -> bool) -> RevSplits<'a, T> {
-        self.rsplitn(uint::max_value, pred)
+        self.rsplitn(uint::MAX, pred)
     }
 
     #[inline]
@@ -1261,7 +1261,7 @@ fn bsearch_elem(&self, x: &T) -> Option<uint> {
 }
 
 /// Extension methods for vectors containing `Clone` elements.
-pub trait ImmutableCopyableVector<T> {
+pub trait ImmutableCloneableVector<T> {
     /**
      * Partitions the vector into those that satisfies the predicate, and
      * those that do not.
@@ -1273,7 +1273,7 @@ pub trait ImmutableCopyableVector<T> {
     fn permutations(self) -> Permutations<T>;
 }
 
-impl<'a,T:Clone> ImmutableCopyableVector<T> for &'a [T] {
+impl<'a,T:Clone> ImmutableCloneableVector<T> for &'a [T] {
     #[inline]
     fn partitioned(&self, f: |&T| -> bool) -> (~[T], ~[T]) {
         let mut lefts  = ~[];
@@ -1698,7 +1698,7 @@ fn clear(&mut self) { self.truncate(0) }
 }
 
 /// Extension methods for owned vectors containing `Clone` elements.
-pub trait OwnedCopyableVector<T:Clone> {
+pub trait OwnedCloneableVector<T:Clone> {
     /// Iterates over the slice `rhs`, copies each element, and then appends it to
     /// the vector provided `v`. The `rhs` vector is traversed in-order.
     ///
@@ -1732,7 +1732,7 @@ pub trait OwnedCopyableVector<T:Clone> {
     fn grow_set(&mut self, index: uint, initval: &T, val: T);
 }
 
-impl<T:Clone> OwnedCopyableVector<T> for ~[T] {
+impl<T:Clone> OwnedCloneableVector<T> for ~[T] {
     #[inline]
     fn push_all(&mut self, rhs: &[T]) {
         let new_len = self.len() + rhs.len();
index 03b7f1891a16c51f447b683e4e63124847dd0876..40ae98791efbd0ab76b9e7e2d0abbfc264c90e24 100644 (file)
 
 // The Rust abstract syntax tree.
 
-use codemap::{Span, Spanned};
+use codemap::{Span, Spanned, DUMMY_SP};
 use abi::AbiSet;
+use ast_util;
 use opt_vec::OptVec;
-use parse::token::{interner_get, str_to_ident};
+use parse::token::{interner_get, str_to_ident, special_idents};
 
 use std::cell::RefCell;
 use std::hashmap::HashMap;
@@ -205,7 +206,8 @@ pub enum TyParamBound {
 pub struct TyParam {
     ident: Ident,
     id: NodeId,
-    bounds: OptVec<TyParamBound>
+    bounds: OptVec<TyParamBound>,
+    default: Option<P<Ty>>
 }
 
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
@@ -236,7 +238,6 @@ pub enum MethodProvenance {
 pub enum Def {
     DefFn(DefId, Purity),
     DefStaticMethod(/* method */ DefId, MethodProvenance, Purity),
-    DefSelf(NodeId, bool /* is_mutbl */),
     DefSelfTy(/* trait id */ NodeId),
     DefMod(DefId),
     DefForeignMod(DefId),
@@ -357,7 +358,7 @@ pub enum BindingMode {
 pub enum Pat_ {
     PatWild,
     PatWildMulti,
-    // A pat_ident may either be a new bound variable,
+    // A PatIdent may either be a new bound variable,
     // or a nullary enum (in which case the second field
     // is None).
     // In the nullary enum case, the parser can't determine
@@ -366,7 +367,7 @@ pub enum Pat_ {
     // set (of "pat_idents that refer to nullary enums")
     PatIdent(BindingMode, Path, Option<@Pat>),
     PatEnum(Path, Option<~[@Pat]>), /* "none" means a * pattern where
-                                       * we don't bind the fields to names */
+                                     * we don't bind the fields to names */
     PatStruct(Path, ~[FieldPat], bool),
     PatTup(~[@Pat]),
     PatUniq(@Pat),
@@ -374,7 +375,7 @@ pub enum Pat_ {
     PatLit(@Expr),
     PatRange(@Expr, @Expr),
     // [a, b, ..i, y, z] is represented as
-    // pat_vec(~[a, b], Some(i), ~[y, z])
+    // PatVec(~[a, b], Some(i), ~[y, z])
     PatVec(~[@Pat], Option<@Pat>, ~[@Pat])
 }
 
@@ -526,7 +527,7 @@ pub struct Expr {
 impl Expr {
     pub fn get_callee_id(&self) -> Option<NodeId> {
         match self.node {
-            ExprMethodCall(callee_id, _, _, _, _, _) |
+            ExprMethodCall(callee_id, _, _, _, _) |
             ExprIndex(callee_id, _, _) |
             ExprBinary(callee_id, _, _, _) |
             ExprAssignOp(callee_id, _, _, _) |
@@ -539,7 +540,6 @@ pub fn get_callee_id(&self) -> Option<NodeId> {
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum CallSugar {
     NoSugar,
-    DoSugar,
     ForSugar
 }
 
@@ -550,7 +550,7 @@ pub enum Expr_ {
     ExprBox(@Expr, @Expr),
     ExprVec(~[@Expr], Mutability),
     ExprCall(@Expr, ~[@Expr], CallSugar),
-    ExprMethodCall(NodeId, @Expr, Ident, ~[P<Ty>], ~[@Expr], CallSugar),
+    ExprMethodCall(NodeId, Ident, ~[P<Ty>], ~[@Expr], CallSugar),
     ExprTup(~[@Expr]),
     ExprBinary(NodeId, BinOp, @Expr, @Expr),
     ExprUnary(NodeId, UnOp, @Expr),
@@ -566,7 +566,6 @@ pub enum Expr_ {
     ExprMatch(@Expr, ~[Arm]),
     ExprFnBlock(P<FnDecl>, P<Block>),
     ExprProc(P<FnDecl>, P<Block>),
-    ExprDoBody(@Expr),
     ExprBlock(P<Block>),
 
     ExprAssign(@Expr, @Expr),
@@ -579,8 +578,6 @@ pub enum Expr_ {
     /// of a function call.
     ExprPath(Path),
 
-    /// The special identifier `self`.
-    ExprSelf,
     ExprAddrOf(Mutability, @Expr),
     ExprBreak(Option<Name>),
     ExprAgain(Option<Name>),
@@ -783,7 +780,7 @@ pub enum IntTy {
 
 impl ToStr for IntTy {
     fn to_str(&self) -> ~str {
-        ::ast_util::int_ty_to_str(*self)
+        ast_util::int_ty_to_str(*self)
     }
 }
 
@@ -798,7 +795,7 @@ pub enum UintTy {
 
 impl ToStr for UintTy {
     fn to_str(&self) -> ~str {
-        ::ast_util::uint_ty_to_str(*self)
+        ast_util::uint_ty_to_str(*self)
     }
 }
 
@@ -810,7 +807,7 @@ pub enum FloatTy {
 
 impl ToStr for FloatTy {
     fn to_str(&self) -> ~str {
-        ::ast_util::float_ty_to_str(*self)
+        ast_util::float_ty_to_str(*self)
     }
 }
 
@@ -886,7 +883,7 @@ pub enum Ty_ {
     TyTup(~[P<Ty>]),
     TyPath(Path, Option<OptVec<TyParamBound>>, NodeId), // for #7264; see above
     TyTypeof(@Expr),
-    // ty_infer means the type should be inferred instead of it having been
+    // TyInfer means the type should be inferred instead of it having been
     // specified. This should only appear at the "top level" of a type and not
     // nested in one.
     TyInfer,
@@ -917,6 +914,26 @@ pub struct Arg {
     id: NodeId,
 }
 
+impl Arg {
+    pub fn new_self(span: Span, mutability: Mutability) -> Arg {
+        let path = ast_util::ident_to_path(span, special_idents::self_);
+        Arg {
+            // HACK(eddyb) fake type for the self argument.
+            ty: P(Ty {
+                id: DUMMY_NODE_ID,
+                node: TyInfer,
+                span: DUMMY_SP,
+            }),
+            pat: @Pat {
+                id: DUMMY_NODE_ID,
+                node: PatIdent(BindByValue(mutability), path, None),
+                span: span
+            },
+            id: DUMMY_NODE_ID
+        }
+    }
+}
+
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct FnDecl {
     inputs: ~[Arg],
@@ -952,10 +969,10 @@ pub enum RetStyle {
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum ExplicitSelf_ {
     SelfStatic,                                // no self
-    SelfValue(Mutability),                     // `self`, `mut self`
+    SelfValue,                                 // `self`
     SelfRegion(Option<Lifetime>, Mutability),  // `&'lt self`, `&'lt mut self`
     SelfBox,                                   // `@self`
-    SelfUniq(Mutability)                       // `~self`, `mut ~self`
+    SelfUniq                                   // `~self`
 }
 
 pub type ExplicitSelf = Spanned<ExplicitSelf_>;
@@ -971,7 +988,6 @@ pub struct Method {
     body: P<Block>,
     id: NodeId,
     span: Span,
-    self_id: NodeId,
     vis: Visibility,
 }
 
index 0585f1abecc0c0aab585d1d5b4043883f1f16f42..bb66d620d2910392d5f6729264beb8672b3dd5ef 100644 (file)
@@ -17,7 +17,6 @@
 use fold::Folder;
 use fold;
 use parse::token::{get_ident_interner, IdentInterner};
-use parse::token::special_idents;
 use print::pprust;
 use util::small_vector::SmallVector;
 
@@ -86,7 +85,7 @@ pub fn path_elem_to_str(pe: PathElem, itr: @IdentInterner) -> ~str {
 /// from, even if it's hard to read (previously they would all just be
 /// listed as `__extensions__::method_name::hash`, with no indication
 /// of the type).
-// XXX: these dollar signs and the names in general are actually a
+// FIXME: these dollar signs and the names in general are actually a
 //      relic of $ being one of the very few valid symbol names on
 //      unix. These kinds of details shouldn't be exposed way up here
 //      in the ast.
@@ -163,10 +162,7 @@ pub enum Node {
     NodeExpr(@Expr),
     NodeStmt(@Stmt),
     NodeArg(@Pat),
-    // HACK(eddyb) should always be a pattern, but `self` is not, and thus it
-    // is identified only by an ident and no span is available. In all other
-    // cases, node_span will return the proper span (required by borrowck).
-    NodeLocal(Ident, Option<@Pat>),
+    NodeLocal(@Pat),
     NodeBlock(P<Block>),
 
     /// NodeStructCtor represents a tuple struct.
@@ -246,10 +242,6 @@ fn insert(&self, id: ast::NodeId, node: Node) {
         let mut map = self.map.map.borrow_mut();
         map.get().insert(id as uint, node);
     }
-
-    fn map_self(&self, m: @Method) {
-        self.insert(m.self_id, NodeLocal(special_idents::self_, None));
-    }
 }
 
 impl<F: FoldOps> Folder for Ctx<F> {
@@ -285,7 +277,6 @@ fn fold_item(&mut self, i: @Item) -> SmallVector<@Item> {
                 let impl_did = ast_util::local_def(i.id);
                 for &m in ms.iter() {
                     self.insert(m.id, NodeMethod(m, impl_did, p));
-                    self.map_self(m);
                 }
 
             }
@@ -332,7 +323,6 @@ fn fold_item(&mut self, i: @Item) -> SmallVector<@Item> {
                         }
                         Provided(m) => {
                             self.insert(m.id, NodeTraitMethod(@Provided(m), d_id, p));
-                            self.map_self(m);
                         }
                     }
                 }
@@ -348,9 +338,9 @@ fn fold_item(&mut self, i: @Item) -> SmallVector<@Item> {
     fn fold_pat(&mut self, pat: @Pat) -> @Pat {
         let pat = fold::noop_fold_pat(pat, self);
         match pat.node {
-            PatIdent(_, ref path, _) => {
+            PatIdent(..) => {
                 // Note: this is at least *potentially* a pattern...
-                self.insert(pat.id, NodeLocal(ast_util::path_to_ident(path), Some(pat)));
+                self.insert(pat.id, NodeLocal(pat));
             }
             _ => {}
         }
@@ -467,7 +457,6 @@ pub fn map_decoded_item<F: 'static + FoldOps>(diag: @SpanHandler,
                 NodeMethod(m, impl_did, @path)
             };
             cx.insert(m.id, entry);
-            cx.map_self(m);
         }
     }
 
@@ -525,8 +514,8 @@ pub fn node_id_to_str(map: Map, id: NodeId, itr: @IdentInterner) -> ~str {
       Some(NodeArg(pat)) => {
         format!("arg {} (id={})", pprust::pat_to_str(pat, itr), id)
       }
-      Some(NodeLocal(ident, _)) => {
-        format!("local (id={}, name={})", id, itr.get(ident.name))
+      Some(NodeLocal(pat)) => {
+        format!("local {} (id={})", pprust::pat_to_str(pat, itr), id)
       }
       Some(NodeBlock(block)) => {
         format!("block {} (id={})", pprust::block_to_str(block, itr), id)
@@ -559,11 +548,7 @@ pub fn node_span(items: Map, id: ast::NodeId) -> Span {
         Some(NodeVariant(variant, _, _)) => variant.span,
         Some(NodeExpr(expr)) => expr.span,
         Some(NodeStmt(stmt)) => stmt.span,
-        Some(NodeArg(pat)) => pat.span,
-        Some(NodeLocal(_, pat)) => match pat {
-            Some(pat) => pat.span,
-            None => fail!("node_span: cannot get span from NodeLocal (likely `self`)")
-        },
+        Some(NodeArg(pat)) | Some(NodeLocal(pat)) => pat.span,
         Some(NodeBlock(block)) => block.span,
         Some(NodeStructCtor(_, item, _)) => item.span,
         Some(NodeCalleeScope(expr)) => expr.span,
index 47ae146d19b31b87d4cc1f569391726a6994067f..405de5c5542d075dc334c536fd719f9d54a46eb9 100644 (file)
@@ -60,19 +60,19 @@ pub fn variant_def_ids(d: Def) -> Option<(DefId, DefId)> {
 
 pub fn def_id_of_def(d: Def) -> DefId {
     match d {
-      DefFn(id, _) | DefStaticMethod(id, _, _) | DefMod(id) |
-      DefForeignMod(id) | DefStatic(id, _) |
-      DefVariant(_, id, _) | DefTy(id) | DefTyParam(id, _) |
-      DefUse(id) | DefStruct(id) | DefTrait(id) | DefMethod(id, _) => {
-        id
-      }
-      DefArg(id, _) | DefLocal(id, _) | DefSelf(id, _) | DefSelfTy(id)
-      | DefUpvar(id, _, _, _) | DefBinding(id, _) | DefRegion(id)
-      | DefTyParamBinder(id) | DefLabel(id) => {
-        local_def(id)
-      }
+        DefFn(id, _) | DefStaticMethod(id, _, _) | DefMod(id) |
+        DefForeignMod(id) | DefStatic(id, _) |
+        DefVariant(_, id, _) | DefTy(id) | DefTyParam(id, _) |
+        DefUse(id) | DefStruct(id) | DefTrait(id) | DefMethod(id, _) => {
+            id
+        }
+        DefArg(id, _) | DefLocal(id, _) | DefSelfTy(id)
+        | DefUpvar(id, _, _, _) | DefBinding(id, _) | DefRegion(id)
+        | DefTyParamBinder(id) | DefLabel(id) => {
+            local_def(id)
+        }
 
-      DefPrimTy(_) => fail!()
+        DefPrimTy(_) => fail!()
     }
 }
 
@@ -292,16 +292,6 @@ pub fn struct_field_visibility(field: ast::StructField) -> Visibility {
     }
 }
 
-/* True if d is either a def_self, or a chain of def_upvars
- referring to a def_self */
-pub fn is_self(d: ast::Def) -> bool {
-  match d {
-    DefSelf(..)           => true,
-    DefUpvar(_, d, _, _) => is_self(*d),
-    _                     => false
-  }
-}
-
 /// Maps a binary operator to its precedence
 pub fn operator_prec(op: ast::BinOp) -> uint {
   match op {
@@ -340,8 +330,8 @@ pub struct IdRange {
 impl IdRange {
     pub fn max() -> IdRange {
         IdRange {
-            min: u32::max_value,
-            max: u32::min_value,
+            min: u32::MAX,
+            max: u32::MIN,
         }
     }
 
@@ -504,11 +494,8 @@ fn visit_fn(&mut self,
         self.operation.visit_id(node_id);
 
         match *function_kind {
-            visit::FkItemFn(_, generics, _, _) => {
-                self.visit_generics_helper(generics)
-            }
-            visit::FkMethod(_, generics, method) => {
-                self.operation.visit_id(method.self_id);
+            visit::FkItemFn(_, generics, _, _) |
+            visit::FkMethod(_, generics, _) => {
                 self.visit_generics_helper(generics)
             }
             visit::FkFnBlock => {}
index d81999c1e5fe1211a74fe0adf40211ef8461ab25..d4a412bbe9ff2d67437f8ed2f90312cd8fc60f43 100644 (file)
@@ -41,7 +41,7 @@ pub trait Pos {
 #[deriving(Eq,IterBytes, Ord)]
 pub struct CharPos(uint);
 
-// XXX: Lots of boilerplate in these impls, but so far my attempts to fix
+// FIXME: Lots of boilerplate in these impls, but so far my attempts to fix
 // have been unsuccessful
 
 impl Pos for BytePos {
index a9d3f6fea24107f88b79b1088896b99903cbd44d..fabc244e00af88aeafb69e1fe68d15a8befaf565 100644 (file)
@@ -14,6 +14,7 @@
 use std::cell::Cell;
 use std::io;
 use std::io::stdio::StdWriter;
+use std::iter::range;
 use std::local_data;
 use extra::term;
 
@@ -320,7 +321,7 @@ fn highlight_lines(cm: &codemap::CodeMap,
         // Skip is the number of characters we need to skip because they are
         // part of the 'filename:line ' part of the previous line.
         let skip = fm.name.len() + digits + 3u;
-        skip.times(|| s.push_char(' '));
+        for _ in range(0, skip) { s.push_char(' '); }
         let orig = fm.get_line(lines.lines[0] as int);
         for pos in range(0u, left-skip) {
             let curChar = (orig[pos] as char);
@@ -339,7 +340,7 @@ fn highlight_lines(cm: &codemap::CodeMap,
         if hi.col != lo.col {
             // the ^ already takes up one space
             let num_squigglies = hi.col.to_uint()-lo.col.to_uint()-1u;
-            num_squigglies.times(|| s.push_char('~'));
+            for _ in range(0, num_squigglies) { s.push_char('~'); }
         }
         print_maybe_styled(s + "\n", term::attr::ForegroundColor(lvl.color()));
     }
@@ -378,7 +379,7 @@ fn custom_highlight_lines(cm: &codemap::CodeMap,
     // Span seems to use half-opened interval, so subtract 1
     let skip = last_line_start.len() + hi.col.to_uint() - 1;
     let mut s = ~"";
-    skip.times(|| s.push_char(' '));
+    for _ in range(0, skip) { s.push_char(' '); }
     s.push_char('^');
     print_maybe_styled(s + "\n", term::attr::ForegroundColor(lvl.color()));
 }
index 2c817365390e16f390cd28e13e859403e7f8ce42..adf1eabf9d94d45401151bce758d7a060002f4e6 100644 (file)
@@ -38,91 +38,63 @@ pub struct MacroDef {
 pub type ItemDecorator =
     fn(&ExtCtxt, Span, @ast::MetaItem, ~[@ast::Item]) -> ~[@ast::Item];
 
-pub struct SyntaxExpanderTT {
-    expander: SyntaxExpanderTTExpander,
+pub struct BasicMacroExpander {
+    expander: MacroExpanderFn,
     span: Option<Span>
 }
 
-pub trait SyntaxExpanderTTTrait {
+pub trait MacroExpander {
     fn expand(&self,
               ecx: &mut ExtCtxt,
               span: Span,
-              token_tree: &[ast::TokenTree],
-              context: ast::SyntaxContext)
+              token_tree: &[ast::TokenTree])
               -> MacResult;
 }
 
-pub type SyntaxExpanderTTFunNoCtxt =
+pub type MacroExpanderFn =
     fn(ecx: &mut ExtCtxt, span: codemap::Span, token_tree: &[ast::TokenTree])
        -> MacResult;
 
-enum SyntaxExpanderTTExpander {
-    SyntaxExpanderTTExpanderWithoutContext(SyntaxExpanderTTFunNoCtxt),
-}
-
-impl SyntaxExpanderTTTrait for SyntaxExpanderTT {
+impl MacroExpander for BasicMacroExpander {
     fn expand(&self,
               ecx: &mut ExtCtxt,
               span: Span,
-              token_tree: &[ast::TokenTree],
-              _: ast::SyntaxContext)
+              token_tree: &[ast::TokenTree])
               -> MacResult {
-        match self.expander {
-            SyntaxExpanderTTExpanderWithoutContext(f) => {
-                f(ecx, span, token_tree)
-            }
-        }
+        (self.expander)(ecx, span, token_tree)
     }
 }
 
-enum SyntaxExpanderTTItemExpander {
-    SyntaxExpanderTTItemExpanderWithContext(SyntaxExpanderTTItemFun),
-    SyntaxExpanderTTItemExpanderWithoutContext(SyntaxExpanderTTItemFunNoCtxt),
-}
-
-pub struct SyntaxExpanderTTItem {
-    expander: SyntaxExpanderTTItemExpander,
+pub struct BasicIdentMacroExpander {
+    expander: IdentMacroExpanderFn,
     span: Option<Span>
 }
 
-pub trait SyntaxExpanderTTItemTrait {
+pub trait IdentMacroExpander {
     fn expand(&self,
               cx: &mut ExtCtxt,
               sp: Span,
               ident: ast::Ident,
-              token_tree: ~[ast::TokenTree],
-              context: ast::SyntaxContext)
+              token_tree: ~[ast::TokenTree])
               -> MacResult;
 }
 
-impl SyntaxExpanderTTItemTrait for SyntaxExpanderTTItem {
+impl IdentMacroExpander for BasicIdentMacroExpander {
     fn expand(&self,
               cx: &mut ExtCtxt,
               sp: Span,
               ident: ast::Ident,
-              token_tree: ~[ast::TokenTree],
-              context: ast::SyntaxContext)
+              token_tree: ~[ast::TokenTree])
               -> MacResult {
-        match self.expander {
-            SyntaxExpanderTTItemExpanderWithContext(fun) => {
-                fun(cx, sp, ident, token_tree, context)
-            }
-            SyntaxExpanderTTItemExpanderWithoutContext(fun) => {
-                fun(cx, sp, ident, token_tree)
-            }
-        }
+        (self.expander)(cx, sp, ident, token_tree)
     }
 }
 
-pub type SyntaxExpanderTTItemFun =
-    fn(&mut ExtCtxt, Span, ast::Ident, ~[ast::TokenTree], ast::SyntaxContext)
-       -> MacResult;
-
-pub type SyntaxExpanderTTItemFunNoCtxt =
+pub type IdentMacroExpanderFn =
     fn(&mut ExtCtxt, Span, ast::Ident, ~[ast::TokenTree]) -> MacResult;
 
 pub type MacroCrateRegistrationFun =
-    extern "Rust" fn(|ast::Name, SyntaxExtension|);
+    fn(|ast::Name, SyntaxExtension|);
 
 pub trait AnyMacro {
     fn make_expr(&self) -> @ast::Expr;
@@ -153,7 +125,7 @@ pub enum SyntaxExtension {
     ItemDecorator(ItemDecorator),
 
     // Token-tree expanders
-    NormalTT(~SyntaxExpanderTTTrait:'static, Option<Span>),
+    NormalTT(~MacroExpander:'static, Option<Span>),
 
     // An IdentTT is a macro that has an
     // identifier in between the name of the
@@ -163,7 +135,7 @@ pub enum SyntaxExtension {
 
     // perhaps macro_rules! will lose its odd special identifier argument,
     // and this can go away also
-    IdentTT(~SyntaxExpanderTTItemTrait:'static, Option<Span>),
+    IdentTT(~IdentMacroExpander:'static, Option<Span>),
 }
 
 pub struct BlockInfo {
@@ -192,102 +164,100 @@ pub fn new() -> BlockInfo {
 // AST nodes into full ASTs
 pub fn syntax_expander_table() -> SyntaxEnv {
     // utility function to simplify creating NormalTT syntax extensions
-    fn builtin_normal_tt_no_ctxt(f: SyntaxExpanderTTFunNoCtxt)
-                                 -> SyntaxExtension {
-        NormalTT(~SyntaxExpanderTT{
-            expander: SyntaxExpanderTTExpanderWithoutContext(f),
-            span: None,
-        },
-        None)
+    fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
+        NormalTT(~BasicMacroExpander {
+                expander: f,
+                span: None,
+            },
+            None)
     }
 
     let mut syntax_expanders = SyntaxEnv::new();
     syntax_expanders.insert(intern(&"macro_rules"),
-                            IdentTT(~SyntaxExpanderTTItem {
-                                expander: SyntaxExpanderTTItemExpanderWithContext(
-                                    ext::tt::macro_rules::add_new_extension),
+                            IdentTT(~BasicIdentMacroExpander {
+                                expander: ext::tt::macro_rules::add_new_extension,
                                 span: None,
                             },
                             None));
     syntax_expanders.insert(intern(&"fmt"),
-                            builtin_normal_tt_no_ctxt(
+                            builtin_normal_expander(
                                 ext::fmt::expand_syntax_ext));
     syntax_expanders.insert(intern(&"format_args"),
-                            builtin_normal_tt_no_ctxt(
+                            builtin_normal_expander(
                                 ext::format::expand_args));
     syntax_expanders.insert(intern(&"env"),
-                            builtin_normal_tt_no_ctxt(
+                            builtin_normal_expander(
                                     ext::env::expand_env));
     syntax_expanders.insert(intern(&"option_env"),
-                            builtin_normal_tt_no_ctxt(
+                            builtin_normal_expander(
                                     ext::env::expand_option_env));
     syntax_expanders.insert(intern("bytes"),
-                            builtin_normal_tt_no_ctxt(
+                            builtin_normal_expander(
                                     ext::bytes::expand_syntax_ext));
     syntax_expanders.insert(intern("concat_idents"),
-                            builtin_normal_tt_no_ctxt(
+                            builtin_normal_expander(
                                     ext::concat_idents::expand_syntax_ext));
     syntax_expanders.insert(intern("concat"),
-                            builtin_normal_tt_no_ctxt(
+                            builtin_normal_expander(
                                     ext::concat::expand_syntax_ext));
     syntax_expanders.insert(intern(&"log_syntax"),
-                            builtin_normal_tt_no_ctxt(
+                            builtin_normal_expander(
                                     ext::log_syntax::expand_syntax_ext));
     syntax_expanders.insert(intern(&"deriving"),
                             ItemDecorator(ext::deriving::expand_meta_deriving));
 
     // Quasi-quoting expanders
     syntax_expanders.insert(intern(&"quote_tokens"),
-                       builtin_normal_tt_no_ctxt(
+                       builtin_normal_expander(
                             ext::quote::expand_quote_tokens));
     syntax_expanders.insert(intern(&"quote_expr"),
-                       builtin_normal_tt_no_ctxt(
+                       builtin_normal_expander(
                             ext::quote::expand_quote_expr));
     syntax_expanders.insert(intern(&"quote_ty"),
-                       builtin_normal_tt_no_ctxt(
+                       builtin_normal_expander(
                             ext::quote::expand_quote_ty));
     syntax_expanders.insert(intern(&"quote_item"),
-                       builtin_normal_tt_no_ctxt(
+                       builtin_normal_expander(
                             ext::quote::expand_quote_item));
     syntax_expanders.insert(intern(&"quote_pat"),
-                       builtin_normal_tt_no_ctxt(
+                       builtin_normal_expander(
                             ext::quote::expand_quote_pat));
     syntax_expanders.insert(intern(&"quote_stmt"),
-                       builtin_normal_tt_no_ctxt(
+                       builtin_normal_expander(
                             ext::quote::expand_quote_stmt));
 
     syntax_expanders.insert(intern(&"line"),
-                            builtin_normal_tt_no_ctxt(
+                            builtin_normal_expander(
                                     ext::source_util::expand_line));
     syntax_expanders.insert(intern(&"col"),
-                            builtin_normal_tt_no_ctxt(
+                            builtin_normal_expander(
                                     ext::source_util::expand_col));
     syntax_expanders.insert(intern(&"file"),
-                            builtin_normal_tt_no_ctxt(
+                            builtin_normal_expander(
                                     ext::source_util::expand_file));
     syntax_expanders.insert(intern(&"stringify"),
-                            builtin_normal_tt_no_ctxt(
+                            builtin_normal_expander(
                                     ext::source_util::expand_stringify));
     syntax_expanders.insert(intern(&"include"),
-                            builtin_normal_tt_no_ctxt(
+                            builtin_normal_expander(
                                     ext::source_util::expand_include));
     syntax_expanders.insert(intern(&"include_str"),
-                            builtin_normal_tt_no_ctxt(
+                            builtin_normal_expander(
                                     ext::source_util::expand_include_str));
     syntax_expanders.insert(intern(&"include_bin"),
-                            builtin_normal_tt_no_ctxt(
+                            builtin_normal_expander(
                                     ext::source_util::expand_include_bin));
     syntax_expanders.insert(intern(&"module_path"),
-                            builtin_normal_tt_no_ctxt(
+                            builtin_normal_expander(
                                     ext::source_util::expand_mod));
     syntax_expanders.insert(intern(&"asm"),
-                            builtin_normal_tt_no_ctxt(
+                            builtin_normal_expander(
                                     ext::asm::expand_asm));
     syntax_expanders.insert(intern(&"cfg"),
-                            builtin_normal_tt_no_ctxt(
+                            builtin_normal_expander(
                                     ext::cfg::expand_cfg));
     syntax_expanders.insert(intern(&"trace_macros"),
-                            builtin_normal_tt_no_ctxt(
+                            builtin_normal_expander(
                                     ext::trace_macros::expand_trace_macros));
     syntax_expanders
 }
index 3c0d7aaf4f3a82a578870e060341d618ac206c66..9ad4f4f7fac2d4b7006c18d40a5fbbb160b24053 100644 (file)
@@ -18,6 +18,7 @@
 use fold::Folder;
 use opt_vec;
 use opt_vec::OptVec;
+use parse::token::special_idents;
 
 pub struct Field {
     ident: ast::Ident,
@@ -65,7 +66,10 @@ fn ty_rptr(&self, span: Span,
     fn ty_field_imm(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::TypeField;
     fn strip_bounds(&self, bounds: &Generics) -> Generics;
 
-    fn typaram(&self, id: ast::Ident, bounds: OptVec<ast::TyParamBound>) -> ast::TyParam;
+    fn typaram(&self,
+               id: ast::Ident,
+               bounds: OptVec<ast::TyParamBound>,
+               default: Option<P<ast::Ty>>) -> ast::TyParam;
 
     fn trait_ref(&self, path: ast::Path) -> ast::TraitRef;
     fn typarambound(&self, path: ast::Path) -> ast::TyParamBound;
@@ -179,7 +183,7 @@ fn item(&self, span: Span,
             name: Ident, attrs: ~[ast::Attribute], node: ast::Item_) -> @ast::Item;
 
     fn arg(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::Arg;
-    // XXX unused self
+    // FIXME unused self
     fn fn_decl(&self, inputs: ~[ast::Arg], output: P<ast::Ty>) -> P<ast::FnDecl>;
 
     fn item_fn_poly(&self,
@@ -353,8 +357,16 @@ fn ty_nil(&self) -> P<ast::Ty> {
         })
     }
 
-    fn typaram(&self, id: ast::Ident, bounds: OptVec<ast::TyParamBound>) -> ast::TyParam {
-        ast::TyParam { ident: id, id: ast::DUMMY_NODE_ID, bounds: bounds }
+    fn typaram(&self,
+               id: ast::Ident,
+               bounds: OptVec<ast::TyParamBound>,
+               default: Option<P<ast::Ty>>) -> ast::TyParam {
+        ast::TyParam {
+            ident: id,
+            id: ast::DUMMY_NODE_ID,
+            bounds: bounds,
+            default: default
+        }
     }
 
     // these are strange, and probably shouldn't be used outside of
@@ -478,7 +490,7 @@ fn expr_ident(&self, span: Span, id: ast::Ident) -> @ast::Expr {
         self.expr_path(self.path_ident(span, id))
     }
     fn expr_self(&self, span: Span) -> @ast::Expr {
-        self.expr(span, ast::ExprSelf)
+        self.expr_ident(span, special_idents::self_)
     }
 
     fn expr_binary(&self, sp: Span, op: ast::BinOp,
@@ -523,9 +535,9 @@ fn expr_call_global(&self, sp: Span, fn_path: ~[ast::Ident],
     fn expr_method_call(&self, span: Span,
                         expr: @ast::Expr,
                         ident: ast::Ident,
-                        args: ~[@ast::Expr]) -> @ast::Expr {
-        self.expr(span,
-                  ast::ExprMethodCall(ast::DUMMY_NODE_ID, expr, ident, ~[], args, ast::NoSugar))
+                        mut args: ~[@ast::Expr]) -> @ast::Expr {
+        args.unshift(expr);
+        self.expr(span, ast::ExprMethodCall(ast::DUMMY_NODE_ID, ident, ~[], args, ast::NoSugar))
     }
     fn expr_block(&self, b: P<ast::Block>) -> @ast::Expr {
         self.expr(b.span, ast::ExprBlock(b))
@@ -724,7 +736,7 @@ fn arg(&self, span: Span, ident: ast::Ident, ty: P<ast::Ty>) -> ast::Arg {
         }
     }
 
-    // XXX unused self
+    // FIXME unused self
     fn fn_decl(&self, inputs: ~[ast::Arg], output: P<ast::Ty>) -> P<ast::FnDecl> {
         P(ast::FnDecl {
             inputs: inputs,
@@ -736,7 +748,7 @@ fn fn_decl(&self, inputs: ~[ast::Arg], output: P<ast::Ty>) -> P<ast::FnDecl> {
 
     fn item(&self, span: Span,
             name: Ident, attrs: ~[ast::Attribute], node: ast::Item_) -> @ast::Item {
-        // XXX: Would be nice if our generated code didn't violate
+        // FIXME: Would be nice if our generated code didn't violate
         // Rust coding conventions
         @ast::Item { ident: name,
                     attrs: attrs,
index aa8dcc3981b909a6cb2152b677d2ce6ecfb7c569..567b89d3453f7e640f5201e499896c1d25a52429 100644 (file)
@@ -74,13 +74,13 @@ pub fn expand_deriving_deep_clone(cx: &ExtCtxt,
 
 fn cs_clone(
     name: &str,
-    cx: &ExtCtxt, span: Span,
+    cx: &ExtCtxt, trait_span: Span,
     substr: &Substructure) -> @Expr {
     let clone_ident = substr.method_ident;
     let ctor_ident;
     let all_fields;
-    let subcall = |field|
-        cx.expr_method_call(span, field, clone_ident, ~[]);
+    let subcall = |field: &FieldInfo|
+        cx.expr_method_call(field.span, field.self_, clone_ident, ~[]);
 
     match *substr.fields {
         Struct(ref af) => {
@@ -91,37 +91,37 @@ fn cs_clone(
             ctor_ident = variant.node.name;
             all_fields = af;
         },
-        EnumNonMatching(..) => cx.span_bug(span,
-                                          format!("Non-matching enum variants in `deriving({})`",
-                                               name)),
-        StaticEnum(..) | StaticStruct(..) => cx.span_bug(span,
-                                                       format!("Static method in `deriving({})`",
-                                                            name))
+        EnumNonMatching(..) => cx.span_bug(trait_span,
+                                           format!("Non-matching enum variants in `deriving({})`",
+                                                  name)),
+        StaticEnum(..) | StaticStruct(..) => cx.span_bug(trait_span,
+                                                         format!("Static method in `deriving({})`",
+                                                                 name))
     }
 
     match *all_fields {
         [FieldInfo { name: None, .. }, ..] => {
             // enum-like
-            let subcalls = all_fields.map(|field| subcall(field.self_));
-            cx.expr_call_ident(span, ctor_ident, subcalls)
+            let subcalls = all_fields.map(subcall);
+            cx.expr_call_ident(trait_span, ctor_ident, subcalls)
         },
         _ => {
             // struct-like
             let fields = all_fields.map(|field| {
                 let ident = match field.name {
                     Some(i) => i,
-                    None => cx.span_bug(span,
+                    None => cx.span_bug(trait_span,
                                         format!("unnamed field in normal struct in `deriving({})`",
-                                             name))
+                                                name))
                 };
-                cx.field_imm(span, ident, subcall(field.self_))
+                cx.field_imm(field.span, ident, subcall(field))
             });
 
             if fields.is_empty() {
                 // no fields, so construct like `None`
-                cx.expr_ident(span, ctor_ident)
+                cx.expr_ident(trait_span, ctor_ident)
             } else {
-                cx.expr_struct_ident(span, ctor_ident, fields)
+                cx.expr_struct_ident(trait_span, ctor_ident, fields)
             }
         }
     }
index 8a2b11b798cda5241994232cd3fdba0bca34060f..5a02d8eead85c9b847a13998a39d3fd1a4955e07 100644 (file)
@@ -78,14 +78,10 @@ fn cs_op(less: bool, equal: bool, cx: &ExtCtxt, span: Span, substr: &Substructur
                 _ => cx.span_bug(span, "Not exactly 2 arguments in `deriving(Ord)`")
             };
 
-            let cmp = cx.expr_binary(span, op,
-                                     cx.expr_deref(span, self_f),
-                                     cx.expr_deref(span, other_f));
+            let cmp = cx.expr_binary(span, op, self_f, other_f);
 
             let not_cmp = cx.expr_unary(span, ast::UnNot,
-                                        cx.expr_binary(span, op,
-                                                       cx.expr_deref(span, other_f),
-                                                       cx.expr_deref(span, self_f)));
+                                        cx.expr_binary(span, op, other_f, self_f));
 
             let and = cx.expr_binary(span, ast::BiAnd, not_cmp, subexpr);
             cx.expr_binary(span, ast::BiOr, cmp, and)
index 9272152e8d57838b057323125a78e4ef5ac90e88..a9268d85c91547e2c62a8ef6024fcb25c1a40558 100644 (file)
@@ -51,7 +51,7 @@ pub fn expand_deriving_decodable(cx: &ExtCtxt,
     trait_def.expand(mitem, in_items)
 }
 
-fn decodable_substructure(cx: &ExtCtxt, span: Span,
+fn decodable_substructure(cx: &ExtCtxt, trait_span: Span,
                           substr: &Substructure) -> @Expr {
     let decoder = substr.nonself_args[0];
     let recurse = ~[cx.ident_of("extra"),
@@ -60,9 +60,9 @@ fn decodable_substructure(cx: &ExtCtxt, span: Span,
                     cx.ident_of("decode")];
     // throw an underscore in front to suppress unused variable warnings
     let blkarg = cx.ident_of("_d");
-    let blkdecoder = cx.expr_ident(span, blkarg);
-    let calldecode = cx.expr_call_global(span, recurse, ~[blkdecoder]);
-    let lambdadecode = cx.lambda_expr_1(span, calldecode, blkarg);
+    let blkdecoder = cx.expr_ident(trait_span, blkarg);
+    let calldecode = cx.expr_call_global(trait_span, recurse, ~[blkdecoder]);
+    let lambdadecode = cx.lambda_expr_1(trait_span, calldecode, blkarg);
 
     return match *substr.fields {
         StaticStruct(_, ref summary) => {
@@ -73,7 +73,7 @@ fn decodable_substructure(cx: &ExtCtxt, span: Span,
             let read_struct_field = cx.ident_of("read_struct_field");
 
             let result = decode_static_fields(cx,
-                                              span,
+                                              trait_span,
                                               substr.type_ident,
                                               summary,
                                               |span, name, field| {
@@ -82,10 +82,10 @@ fn decodable_substructure(cx: &ExtCtxt, span: Span,
                                       cx.expr_uint(span, field),
                                       lambdadecode])
             });
-            cx.expr_method_call(span, decoder, cx.ident_of("read_struct"),
-                                ~[cx.expr_str(span, cx.str_of(substr.type_ident)),
-                                  cx.expr_uint(span, nfields),
-                                  cx.lambda_expr_1(span, result, blkarg)])
+            cx.expr_method_call(trait_span, decoder, cx.ident_of("read_struct"),
+                                ~[cx.expr_str(trait_span, cx.str_of(substr.type_ident)),
+                                  cx.expr_uint(trait_span, nfields),
+                                  cx.lambda_expr_1(trait_span, result, blkarg)])
         }
         StaticEnum(_, ref fields) => {
             let variant = cx.ident_of("i");
@@ -94,12 +94,11 @@ fn decodable_substructure(cx: &ExtCtxt, span: Span,
             let mut variants = ~[];
             let rvariant_arg = cx.ident_of("read_enum_variant_arg");
 
-            for (i, f) in fields.iter().enumerate() {
-                let (name, parts) = match *f { (i, ref p) => (i, p) };
-                variants.push(cx.expr_str(span, cx.str_of(name)));
+            for (i, &(name, v_span, ref parts)) in fields.iter().enumerate() {
+                variants.push(cx.expr_str(v_span, cx.str_of(name)));
 
                 let decoded = decode_static_fields(cx,
-                                                   span,
+                                                   v_span,
                                                    name,
                                                    parts,
                                                    |span, _, field| {
@@ -108,22 +107,22 @@ fn decodable_substructure(cx: &ExtCtxt, span: Span,
                                           lambdadecode])
                 });
 
-                arms.push(cx.arm(span,
-                                 ~[cx.pat_lit(span, cx.expr_uint(span, i))],
+                arms.push(cx.arm(v_span,
+                                 ~[cx.pat_lit(v_span, cx.expr_uint(v_span, i))],
                                  decoded));
             }
 
-            arms.push(cx.arm_unreachable(span));
+            arms.push(cx.arm_unreachable(trait_span));
 
-            let result = cx.expr_match(span, cx.expr_ident(span, variant), arms);
-            let lambda = cx.lambda_expr(span, ~[blkarg, variant], result);
-            let variant_vec = cx.expr_vec(span, variants);
-            let result = cx.expr_method_call(span, blkdecoder,
+            let result = cx.expr_match(trait_span, cx.expr_ident(trait_span, variant), arms);
+            let lambda = cx.lambda_expr(trait_span, ~[blkarg, variant], result);
+            let variant_vec = cx.expr_vec(trait_span, variants);
+            let result = cx.expr_method_call(trait_span, blkdecoder,
                                              cx.ident_of("read_enum_variant"),
                                              ~[variant_vec, lambda]);
-            cx.expr_method_call(span, decoder, cx.ident_of("read_enum"),
-                                ~[cx.expr_str(span, cx.str_of(substr.type_ident)),
-                                  cx.lambda_expr_1(span, result, blkarg)])
+            cx.expr_method_call(trait_span, decoder, cx.ident_of("read_enum"),
+                                ~[cx.expr_str(trait_span, cx.str_of(substr.type_ident)),
+                                  cx.lambda_expr_1(trait_span, result, blkarg)])
         }
         _ => cx.bug("expected StaticEnum or StaticStruct in deriving(Decodable)")
     };
@@ -133,7 +132,7 @@ fn decodable_substructure(cx: &ExtCtxt, span: Span,
 /// - `outer_pat_ident` is the name of this enum variant/struct
 /// - `getarg` should retrieve the `uint`-th field with name `@str`.
 fn decode_static_fields(cx: &ExtCtxt,
-                        outer_span: Span,
+                        trait_span: Span,
                         outer_pat_ident: Ident,
                         fields: &StaticFields,
                         getarg: |Span, @str, uint| -> @Expr)
@@ -141,13 +140,13 @@ fn decode_static_fields(cx: &ExtCtxt,
     match *fields {
         Unnamed(ref fields) => {
             if fields.is_empty() {
-                cx.expr_ident(outer_span, outer_pat_ident)
+                cx.expr_ident(trait_span, outer_pat_ident)
             } else {
                 let fields = fields.iter().enumerate().map(|(i, &span)| {
                     getarg(span, format!("_field{}", i).to_managed(), i)
                 }).collect();
 
-                cx.expr_call_ident(outer_span, outer_pat_ident, fields)
+                cx.expr_call_ident(trait_span, outer_pat_ident, fields)
             }
         }
         Named(ref fields) => {
@@ -155,7 +154,7 @@ fn decode_static_fields(cx: &ExtCtxt,
             let fields = fields.iter().enumerate().map(|(i, &(name, span))| {
                 cx.field_imm(span, name, getarg(span, cx.str_of(name), i))
             }).collect();
-            cx.expr_struct_ident(outer_span, outer_pat_ident, fields)
+            cx.expr_struct_ident(trait_span, outer_pat_ident, fields)
         }
     }
 }
index 088a221c965eb75f36c36edc1732c4b96d8413da..22f850d56090e845abc57488836a51dfe723f5ea 100644 (file)
@@ -41,7 +41,7 @@ pub fn expand_deriving_default(cx: &ExtCtxt,
     trait_def.expand(mitem, in_items)
 }
 
-fn default_substructure(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
+fn default_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr {
     let default_ident = ~[
         cx.ident_of("std"),
         cx.ident_of("default"),
@@ -55,25 +55,25 @@ fn default_substructure(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Exp
             match *summary {
                 Unnamed(ref fields) => {
                     if fields.is_empty() {
-                        cx.expr_ident(span, substr.type_ident)
+                        cx.expr_ident(trait_span, substr.type_ident)
                     } else {
                         let exprs = fields.map(|sp| default_call(*sp));
-                        cx.expr_call_ident(span, substr.type_ident, exprs)
+                        cx.expr_call_ident(trait_span, substr.type_ident, exprs)
                     }
                 }
                 Named(ref fields) => {
                     let default_fields = fields.map(|&(ident, span)| {
                         cx.field_imm(span, ident, default_call(span))
                     });
-                    cx.expr_struct_ident(span, substr.type_ident, default_fields)
+                    cx.expr_struct_ident(trait_span, substr.type_ident, default_fields)
                 }
             }
         }
         StaticEnum(..) => {
-            cx.span_err(span, "`Default` cannot be derived for enums, only structs");
+            cx.span_err(trait_span, "`Default` cannot be derived for enums, only structs");
             // let compilation continue
-            cx.expr_uint(span, 0)
+            cx.expr_uint(trait_span, 0)
         }
-        _ => cx.bug("Non-static method in `deriving(Default)`")
+        _ => cx.span_bug(trait_span, "Non-static method in `deriving(Default)`")
     };
 }
index 285bf86916e349c7b8e246db3d896e1f5214d564..9a8861f2e70e2daf3bc8a0a6671c6152361fd5a2 100644 (file)
@@ -113,24 +113,24 @@ pub fn expand_deriving_encodable(cx: &ExtCtxt,
     trait_def.expand(mitem, in_items)
 }
 
-fn encodable_substructure(cx: &ExtCtxt, span: Span,
+fn encodable_substructure(cx: &ExtCtxt, trait_span: Span,
                           substr: &Substructure) -> @Expr {
     let encoder = substr.nonself_args[0];
     // throw an underscore in front to suppress unused variable warnings
     let blkarg = cx.ident_of("_e");
-    let blkencoder = cx.expr_ident(span, blkarg);
+    let blkencoder = cx.expr_ident(trait_span, blkarg);
     let encode = cx.ident_of("encode");
 
     return match *substr.fields {
         Struct(ref fields) => {
             let emit_struct_field = cx.ident_of("emit_struct_field");
             let mut stmts = ~[];
-            for (i, f) in fields.iter().enumerate() {
-                let name = match f.name {
+            for (i, &FieldInfo { name, self_, span, .. }) in fields.iter().enumerate() {
+                let name = match name {
                     Some(id) => cx.str_of(id),
                     None => format!("_field{}", i).to_managed()
                 };
-                let enc = cx.expr_method_call(span, f.self_, encode, ~[blkencoder]);
+                let enc = cx.expr_method_call(span, self_, encode, ~[blkencoder]);
                 let lambda = cx.lambda_expr_1(span, enc, blkarg);
                 let call = cx.expr_method_call(span, blkencoder,
                                                emit_struct_field,
@@ -140,10 +140,10 @@ fn encodable_substructure(cx: &ExtCtxt, span: Span,
                 stmts.push(cx.stmt_expr(call));
             }
 
-            let blk = cx.lambda_stmts_1(span, stmts, blkarg);
-            cx.expr_method_call(span, encoder, cx.ident_of("emit_struct"),
-                                ~[cx.expr_str(span, cx.str_of(substr.type_ident)),
-                                  cx.expr_uint(span, fields.len()),
+            let blk = cx.lambda_stmts_1(trait_span, stmts, blkarg);
+            cx.expr_method_call(trait_span, encoder, cx.ident_of("emit_struct"),
+                                ~[cx.expr_str(trait_span, cx.str_of(substr.type_ident)),
+                                  cx.expr_uint(trait_span, fields.len()),
                                   blk])
         }
 
@@ -152,12 +152,12 @@ fn encodable_substructure(cx: &ExtCtxt, span: Span,
             // so we need to generate a unique local variable to take the
             // mutable loan out on, otherwise we get conflicts which don't
             // actually exist.
-            let me = cx.stmt_let(span, false, blkarg, encoder);
-            let encoder = cx.expr_ident(span, blkarg);
+            let me = cx.stmt_let(trait_span, false, blkarg, encoder);
+            let encoder = cx.expr_ident(trait_span, blkarg);
             let emit_variant_arg = cx.ident_of("emit_enum_variant_arg");
             let mut stmts = ~[];
-            for (i, f) in fields.iter().enumerate() {
-                let enc = cx.expr_method_call(span, f.self_, encode, ~[blkencoder]);
+            for (i, &FieldInfo { self_, span, .. }) in fields.iter().enumerate() {
+                let enc = cx.expr_method_call(span, self_, encode, ~[blkencoder]);
                 let lambda = cx.lambda_expr_1(span, enc, blkarg);
                 let call = cx.expr_method_call(span, blkencoder,
                                                emit_variant_arg,
@@ -166,21 +166,21 @@ fn encodable_substructure(cx: &ExtCtxt, span: Span,
                 stmts.push(cx.stmt_expr(call));
             }
 
-            let blk = cx.lambda_stmts_1(span, stmts, blkarg);
-            let name = cx.expr_str(span, cx.str_of(variant.node.name));
-            let call = cx.expr_method_call(span, blkencoder,
+            let blk = cx.lambda_stmts_1(trait_span, stmts, blkarg);
+            let name = cx.expr_str(trait_span, cx.str_of(variant.node.name));
+            let call = cx.expr_method_call(trait_span, blkencoder,
                                            cx.ident_of("emit_enum_variant"),
                                            ~[name,
-                                             cx.expr_uint(span, idx),
-                                             cx.expr_uint(span, fields.len()),
+                                             cx.expr_uint(trait_span, idx),
+                                             cx.expr_uint(trait_span, fields.len()),
                                              blk]);
-            let blk = cx.lambda_expr_1(span, call, blkarg);
-            let ret = cx.expr_method_call(span, encoder,
+            let blk = cx.lambda_expr_1(trait_span, call, blkarg);
+            let ret = cx.expr_method_call(trait_span, encoder,
                                           cx.ident_of("emit_enum"),
-                                          ~[cx.expr_str(span,
+                                          ~[cx.expr_str(trait_span,
                                             cx.str_of(substr.type_ident)),
                                             blk]);
-            cx.expr_block(cx.block(span, ~[me], Some(ret)))
+            cx.expr_block(cx.block(trait_span, ~[me], Some(ret)))
         }
 
         _ => cx.bug("expected Struct or EnumMatching in deriving(Encodable)")
index fe519a31efa6b3e656ec8af74eba4ffb8e7a3e0f..9ebb771f5da5bfe2646052d89f748e6f703e4655 100644 (file)
@@ -68,6 +68,7 @@ enum C {
     C0(int),
     C1 { x: int }
 }
+~~~
 
 The `int`s in `B` and `C0` don't have an identifier, so the
 `Option<ident>`s would be `None` for them.
@@ -168,8 +169,9 @@ fn eq(&self, other: &int) -> bool {
 
 StaticStruct(<ast::StructDef of B>, Unnamed(~[<span of x>]))
 
-StaticEnum(<ast::EnumDef of C>, ~[(<ident of C0>, Unnamed(~[<span of int>])),
-                                  (<ident of C1>, Named(~[(<ident of x>, <span of x>)]))])
+StaticEnum(<ast::EnumDef of C>, ~[(<ident of C0>, <span of C0>, Unnamed(~[<span of int>])),
+                                  (<ident of C1>, <span of C1>,
+                                   Named(~[(<ident of x>, <span of x>)]))])
 ~~~
 
 */
@@ -290,7 +292,7 @@ pub enum SubstructureFields<'a> {
     /// A static method where Self is a struct.
     StaticStruct(&'a ast::StructDef, StaticFields),
     /// A static method where Self is an enum.
-    StaticEnum(&'a ast::EnumDef, ~[(Ident, StaticFields)])
+    StaticEnum(&'a ast::EnumDef, ~[(Ident, Span, StaticFields)])
 }
 
 
@@ -373,7 +375,7 @@ fn create_derived_impl(&self,
             // require the current trait
             bounds.push(cx.typarambound(trait_path.clone()));
 
-            trait_generics.ty_params.push(cx.typaram(ty_param.ident, bounds));
+            trait_generics.ty_params.push(cx.typaram(ty_param.ident, bounds, None));
         }
 
         // Create the reference to the trait.
@@ -549,9 +551,14 @@ fn create_method(&self, trait_: &TraitDef,
         // create the generics that aren't for Self
         let fn_generics = self.generics.to_generics(trait_.cx, trait_.span, type_ident, generics);
 
+        let self_arg = match explicit_self.node {
+            ast::SelfStatic => None,
+            _ => Some(ast::Arg::new_self(trait_.span, ast::MutImmutable))
+        };
         let args = arg_types.move_iter().map(|(name, ty)| {
             trait_.cx.arg(trait_.span, name, ty)
-        }).collect();
+        });
+        let args = self_arg.move_iter().chain(args).collect();
 
         let ret_type = self.get_ret_ty(trait_, generics, type_ident);
 
@@ -576,7 +583,6 @@ fn create_method(&self, trait_: &TraitDef,
             body: body_block,
             id: ast::DUMMY_NODE_ID,
             span: trait_.span,
-            self_id: ast::DUMMY_NODE_ID,
             vis: ast::Inherited,
         }
     }
@@ -904,7 +910,7 @@ fn expand_static_enum_method_body(&self,
                     trait_.summarise_struct(struct_def)
                 }
             };
-            (ident, summary)
+            (ident, v.span, summary)
         });
         self.call_substructure_method(trait_, type_ident,
                                       self_args, nonself_args,
@@ -1007,7 +1013,8 @@ fn create_struct_pattern(&self,
             };
             let path = cx.path_ident(sp, cx.ident_of(format!("{}_{}", prefix, i)));
             paths.push(path.clone());
-            ident_expr.push((sp, opt_id, cx.expr_path(path)));
+            let val = cx.expr(sp, ast::ExprParen(cx.expr_deref(sp, cx.expr_path(path))));
+            ident_expr.push((sp, opt_id, val));
         }
 
         let subpats = self.create_subpatterns(paths, mutbl);
@@ -1051,7 +1058,8 @@ fn create_enum_variant_pattern(&self,
                     let path = cx.path_ident(sp, cx.ident_of(format!("{}_{}", prefix, i)));
 
                     paths.push(path.clone());
-                    ident_expr.push((sp, None, cx.expr_path(path)));
+                    let val = cx.expr(sp, ast::ExprParen(cx.expr_deref(sp, cx.expr_path(path))));
+                    ident_expr.push((sp, None, val));
                 }
 
                 let subpats = self.create_subpatterns(paths, mutbl);
@@ -1126,7 +1134,7 @@ pub fn cs_same_method(f: |&ExtCtxt, Span, ~[@Expr]| -> @Expr,
                 cx.expr_method_call(field.span,
                                     field.self_,
                                     substructure.method_ident,
-                                    field.other.clone())
+                                    field.other.map(|e| cx.expr_addr_of(field.span, *e)))
             });
 
             f(cx, trait_span, called)
index 2bf69e3467493077a50ff7055219979f5e767376..d82e1ef1842614de0f044ff8a1df86af12691aa7 100644 (file)
@@ -45,19 +45,20 @@ pub fn expand_deriving_iter_bytes(cx: &ExtCtxt,
     trait_def.expand(mitem, in_items)
 }
 
-fn iter_bytes_substructure(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
+fn iter_bytes_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr {
     let (lsb0, f)= match substr.nonself_args {
         [l, f] => (l, f),
-        _ => cx.span_bug(span, "Incorrect number of arguments in `deriving(IterBytes)`")
+        _ => cx.span_bug(trait_span, "Incorrect number of arguments in `deriving(IterBytes)`")
     };
     // Build the "explicitly borrowed" stack closure, "|_buf| f(_buf)".
     let blk_arg = cx.ident_of("_buf");
     let borrowed_f =
-        cx.lambda_expr_1(span, cx.expr_call(span, f, ~[cx.expr_ident(span, blk_arg)]),
+        cx.lambda_expr_1(trait_span,
+                         cx.expr_call(trait_span, f, ~[cx.expr_ident(trait_span, blk_arg)]),
                          blk_arg);
 
     let iter_bytes_ident = substr.method_ident;
-    let call_iterbytes = |thing_expr| {
+    let call_iterbytes = |span, thing_expr| {
         cx.expr_method_call(span,
                             thing_expr,
                             iter_bytes_ident,
@@ -74,25 +75,25 @@ fn iter_bytes_substructure(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @
             // iteration function.
             let discriminant = match variant.node.disr_expr {
                 Some(d)=> d,
-                None => cx.expr_uint(span, index)
+                None => cx.expr_uint(trait_span, index)
             };
 
-            exprs.push(call_iterbytes(discriminant));
+            exprs.push(call_iterbytes(trait_span, discriminant));
 
             fields = fs;
         }
-        _ => cx.span_bug(span, "Impossible substructure in `deriving(IterBytes)`")
+        _ => cx.span_bug(trait_span, "Impossible substructure in `deriving(IterBytes)`")
     }
 
-    for &FieldInfo { self_, .. } in fields.iter() {
-        exprs.push(call_iterbytes(self_));
+    for &FieldInfo { self_, span, .. } in fields.iter() {
+        exprs.push(call_iterbytes(span, self_));
     }
 
     if exprs.len() == 0 {
-        cx.span_bug(span, "#[deriving(IterBytes)] needs at least one field");
+        cx.span_bug(trait_span, "#[deriving(IterBytes)] needs at least one field");
     }
 
     exprs.slice(1, exprs.len()).iter().fold(exprs[0], |prev, me| {
-        cx.expr_binary(span, BiAnd, prev, *me)
+        cx.expr_binary(trait_span, BiAnd, prev, *me)
     })
 }
index f621ad854aa24f1ef1d530d916cbf71e0f0c7eab..a4e606f53c0c2215ca313185c2c082020f4c925d 100644 (file)
@@ -64,21 +64,22 @@ pub fn expand_deriving_from_primitive(cx: &ExtCtxt,
     trait_def.expand(mitem, in_items)
 }
 
-fn cs_from(name: &str, cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
+fn cs_from(name: &str, cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr {
     let n = match substr.nonself_args {
         [n] => n,
-        _ => cx.span_bug(span, "Incorrect number of arguments in `deriving(FromPrimitive)`")
+        _ => cx.span_bug(trait_span, "Incorrect number of arguments in `deriving(FromPrimitive)`")
     };
 
     match *substr.fields {
         StaticStruct(..) => {
-            cx.span_err(span, "`FromPrimitive` cannot be derived for structs");
-            return cx.expr_fail(span, @"");
+            cx.span_err(trait_span, "`FromPrimitive` cannot be derived for structs");
+            return cx.expr_fail(trait_span, @"");
         }
         StaticEnum(enum_def, _) => {
             if enum_def.variants.is_empty() {
-                cx.span_err(span, "`FromPrimitive` cannot be derived for enums with no variants");
-                return cx.expr_fail(span, @"");
+                cx.span_err(trait_span,
+                            "`FromPrimitive` cannot be derived for enums with no variants");
+                return cx.expr_fail(trait_span, @"");
             }
 
             let mut arms = ~[];
@@ -87,10 +88,12 @@ fn cs_from(name: &str, cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr
                 match variant.node.kind {
                     ast::TupleVariantKind(ref args) => {
                         if !args.is_empty() {
-                            cx.span_err(span, "`FromPrimitive` cannot be derived for \
-                                               enum variants with arguments");
-                            return cx.expr_fail(span, @"");
+                            cx.span_err(trait_span,
+                                        "`FromPrimitive` cannot be derived for \
+                                        enum variants with arguments");
+                            return cx.expr_fail(trait_span, @"");
                         }
+                        let span = variant.span;
 
                         // expr for `$n == $variant as $name`
                         let variant = cx.expr_ident(span, variant.node.name);
@@ -111,23 +114,24 @@ fn cs_from(name: &str, cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr
                         arms.push(arm);
                     }
                     ast::StructVariantKind(_) => {
-                        cx.span_err(span, "`FromPrimitive` cannot be derived for enums \
-                                           with struct variants");
-                        return cx.expr_fail(span, @"");
+                        cx.span_err(trait_span,
+                                    "`FromPrimitive` cannot be derived for enums \
+                                    with struct variants");
+                        return cx.expr_fail(trait_span, @"");
                     }
                 }
             }
 
             // arm for `_ => None`
             let arm = ast::Arm {
-                pats: ~[cx.pat_wild(span)],
+                pats: ~[cx.pat_wild(trait_span)],
                 guard: None,
-                body: cx.block_expr(cx.expr_none(span)),
+                body: cx.block_expr(cx.expr_none(trait_span)),
             };
             arms.push(arm);
 
-            cx.expr_match(span, n, arms)
+            cx.expr_match(trait_span, n, arms)
         }
-        _ => cx.bug("expected StaticEnum in deriving(FromPrimitive)")
+        _ => cx.span_bug(trait_span, "expected StaticEnum in deriving(FromPrimitive)")
     }
 }
index 29023dea6211fd80df02729479eb5cfe4b58c74b..a22822c2ddcc5cde3f560f93268cf0c875215f54 100644 (file)
@@ -50,7 +50,7 @@ pub fn expand_deriving_rand(cx: &ExtCtxt,
     trait_def.expand(mitem, in_items)
 }
 
-fn rand_substructure(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
+fn rand_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr {
     let rng = match substr.nonself_args {
         [rng] => ~[ rng ],
         _ => cx.bug("Incorrect number of arguments to `rand` in `deriving(Rand)`")
@@ -69,18 +69,18 @@ fn rand_substructure(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
 
     return match *substr.fields {
         StaticStruct(_, ref summary) => {
-            rand_thing(cx, span, substr.type_ident, summary, rand_call)
+            rand_thing(cx, trait_span, substr.type_ident, summary, rand_call)
         }
         StaticEnum(_, ref variants) => {
             if variants.is_empty() {
-                cx.span_err(span, "`Rand` cannot be derived for enums with no variants");
+                cx.span_err(trait_span, "`Rand` cannot be derived for enums with no variants");
                 // let compilation continue
-                return cx.expr_uint(span, 0);
+                return cx.expr_uint(trait_span, 0);
             }
 
-            let variant_count = cx.expr_uint(span, variants.len());
+            let variant_count = cx.expr_uint(trait_span, variants.len());
 
-            let rand_name = cx.path_all(span,
+            let rand_name = cx.path_all(trait_span,
                                         true,
                                         rand_ident.clone(),
                                         opt_vec::Empty,
@@ -88,52 +88,48 @@ fn rand_substructure(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
             let rand_name = cx.expr_path(rand_name);
 
             // ::std::rand::Rand::rand(rng)
-            let rv_call = cx.expr_call(span,
+            let rv_call = cx.expr_call(trait_span,
                                        rand_name,
                                        ~[ rng[0] ]);
 
             // need to specify the uint-ness of the random number
-            let uint_ty = cx.ty_ident(span, cx.ident_of("uint"));
+            let uint_ty = cx.ty_ident(trait_span, cx.ident_of("uint"));
             let value_ident = cx.ident_of("__value");
-            let let_statement = cx.stmt_let_typed(span,
+            let let_statement = cx.stmt_let_typed(trait_span,
                                                   false,
                                                   value_ident,
                                                   uint_ty,
                                                   rv_call);
 
             // rand() % variants.len()
-            let value_ref = cx.expr_ident(span, value_ident);
-            let rand_variant = cx.expr_binary(span,
+            let value_ref = cx.expr_ident(trait_span, value_ident);
+            let rand_variant = cx.expr_binary(trait_span,
                                               ast::BiRem,
                                               value_ref,
                                               variant_count);
 
-            let mut arms = variants.iter().enumerate().map(|(i, id_sum)| {
-                let i_expr = cx.expr_uint(span, i);
-                let pat = cx.pat_lit(span, i_expr);
+            let mut arms = variants.iter().enumerate().map(|(i, &(ident, v_span, ref summary))| {
+                let i_expr = cx.expr_uint(v_span, i);
+                let pat = cx.pat_lit(v_span, i_expr);
 
-                match *id_sum {
-                    (ident, ref summary) => {
-                        cx.arm(span,
-                               ~[ pat ],
-                               rand_thing(cx, span, ident, summary, |sp| rand_call(sp)))
-                    }
-                }
+                cx.arm(v_span,
+                       ~[ pat ],
+                       rand_thing(cx, v_span, ident, summary, |sp| rand_call(sp)))
             }).collect::<~[ast::Arm]>();
 
             // _ => {} at the end. Should never occur
-            arms.push(cx.arm_unreachable(span));
+            arms.push(cx.arm_unreachable(trait_span));
 
-            let match_expr = cx.expr_match(span, rand_variant, arms);
+            let match_expr = cx.expr_match(trait_span, rand_variant, arms);
 
-            let block = cx.block(span, ~[ let_statement ], Some(match_expr));
+            let block = cx.block(trait_span, ~[ let_statement ], Some(match_expr));
             cx.expr_block(block)
         }
         _ => cx.bug("Non-static method in `deriving(Rand)`")
     };
 
     fn rand_thing(cx: &ExtCtxt,
-                  span: Span,
+                  trait_span: Span,
                   ctor_ident: Ident,
                   summary: &StaticFields,
                   rand_call: |Span| -> @Expr)
@@ -141,17 +137,17 @@ fn rand_thing(cx: &ExtCtxt,
         match *summary {
             Unnamed(ref fields) => {
                 if fields.is_empty() {
-                    cx.expr_ident(span, ctor_ident)
+                    cx.expr_ident(trait_span, ctor_ident)
                 } else {
                     let exprs = fields.map(|span| rand_call(*span));
-                    cx.expr_call_ident(span, ctor_ident, exprs)
+                    cx.expr_call_ident(trait_span, ctor_ident, exprs)
                 }
             }
             Named(ref fields) => {
                 let rand_fields = fields.map(|&(ident, span)| {
                     cx.field_imm(span, ident, rand_call(span))
                 });
-                cx.expr_struct_ident(span, ctor_ident, rand_fields)
+                cx.expr_struct_ident(trait_span, ctor_ident, rand_fields)
             }
         }
     }
index c2b32b45ce45b2f4d6a0d5216cf187816ed5a3a7..893a1c68426579cbd73fc3ae687cd2da5f110d42 100644 (file)
@@ -196,7 +196,7 @@ fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str, bounds: &[Path],
             let path = b.to_path(cx, span, self_ident, self_generics);
             cx.typarambound(path)
         }));
-    cx.typaram(cx.ident_of(name), bounds)
+    cx.typaram(cx.ident_of(name), bounds, None)
 }
 
 fn mk_generics(lifetimes: ~[ast::Lifetime],  ty_params: ~[ast::TyParam]) -> Generics {
@@ -244,13 +244,13 @@ pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
     let self_path = cx.expr_self(span);
     match *self_ptr {
         None => {
-            (self_path, respan(span, ast::SelfValue(ast::MutImmutable)))
+            (self_path, respan(span, ast::SelfValue))
         }
         Some(ref ptr) => {
             let self_ty = respan(
                 span,
                 match *ptr {
-                    Send => ast::SelfUniq(ast::MutImmutable),
+                    Send => ast::SelfUniq,
                     Managed => ast::SelfBox,
                     Borrowed(ref lt, mutbl) => {
                         let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s)));
index 31020b4a56224dc2784b4cdc2805431789a5c842..dd99e8216200544f59d4158c71e5005cdd35a617 100644 (file)
@@ -57,7 +57,7 @@ pub fn expand_deriving_zero(cx: &ExtCtxt,
     trait_def.expand(mitem, in_items)
 }
 
-fn zero_substructure(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
+fn zero_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr {
     let zero_ident = ~[
         cx.ident_of("std"),
         cx.ident_of("num"),
@@ -71,24 +71,24 @@ fn zero_substructure(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
             match *summary {
                 Unnamed(ref fields) => {
                     if fields.is_empty() {
-                        cx.expr_ident(span, substr.type_ident)
+                        cx.expr_ident(trait_span, substr.type_ident)
                     } else {
                         let exprs = fields.map(|sp| zero_call(*sp));
-                        cx.expr_call_ident(span, substr.type_ident, exprs)
+                        cx.expr_call_ident(trait_span, substr.type_ident, exprs)
                     }
                 }
                 Named(ref fields) => {
                     let zero_fields = fields.map(|&(ident, span)| {
                         cx.field_imm(span, ident, zero_call(span))
                     });
-                    cx.expr_struct_ident(span, substr.type_ident, zero_fields)
+                    cx.expr_struct_ident(trait_span, substr.type_ident, zero_fields)
                 }
             }
         }
         StaticEnum(..) => {
-            cx.span_err(span, "`Zero` cannot be derived for enums, only structs");
+            cx.span_err(trait_span, "`Zero` cannot be derived for enums, only structs");
             // let compilation continue
-            cx.expr_uint(span, 0)
+            cx.expr_uint(trait_span, 0)
         }
         _ => cx.bug("Non-static method in `deriving(Zero)`")
     };
index 0534aa39848b84a7a37b427106fa8418db155b77..1ffff03a80f4a78444eea620184deefb9cb48671 100644 (file)
@@ -13,7 +13,7 @@
 use ast::{ItemMac, Mrk, Stmt, StmtDecl, StmtMac, StmtExpr, StmtSemi};
 use ast::{TokenTree};
 use ast;
-use ast_util::{mtwt_outer_mark, new_rename, new_mark};
+use ast_util::{new_rename, new_mark};
 use ext::build::AstBuilder;
 use attr;
 use attr::AttrMetaMethods;
@@ -22,7 +22,6 @@
 use ext::base::*;
 use fold::*;
 use parse;
-use parse::{parse_item_from_source_str};
 use parse::token;
 use parse::token::{fresh_mark, fresh_name, ident_to_str, intern};
 use visit;
@@ -45,7 +44,7 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
                 // for the other three macro invocation chunks of code
                 // in this file.
                 // Token-tree macros:
-                MacInvocTT(ref pth, ref tts, ctxt) => {
+                MacInvocTT(ref pth, ref tts, _) => {
                     if pth.segments.len() > 1u {
                         fld.cx.span_err(
                             pth.span,
@@ -78,7 +77,6 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
                             let fm = fresh_mark();
                             // mark before:
                             let marked_before = mark_tts(*tts,fm);
-                            let marked_ctxt = new_mark(fm, ctxt);
 
                             // The span that we pass to the expanders we want to
                             // be the root of the call stack. That's the most
@@ -88,8 +86,7 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
 
                             let expanded = match expandfun.expand(fld.cx,
                                                    mac_span.call_site,
-                                                   marked_before,
-                                                   marked_ctxt) {
+                                                   marked_before) {
                                 MRExpr(e) => e,
                                 MRAny(any_macro) => any_macro.make_expr(),
                                 _ => {
@@ -118,7 +115,7 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
 
                     // Keep going, outside-in.
                     //
-                    // XXX(pcwalton): Is it necessary to clone the
+                    // FIXME(pcwalton): Is it necessary to clone the
                     // node here?
                     let fully_expanded =
                         fld.fold_expr(marked_after).node.clone();
@@ -287,12 +284,12 @@ pub fn contains_macro_escape(attrs: &[ast::Attribute]) -> bool {
 // logic as for expression-position macro invocations.
 pub fn expand_item_mac(it: @ast::Item, fld: &mut MacroExpander)
                        -> SmallVector<@ast::Item> {
-    let (pth, tts, ctxt) = match it.node {
+    let (pth, tts) = match it.node {
         ItemMac(codemap::Spanned {
-            node: MacInvocTT(ref pth, ref tts, ctxt),
+            node: MacInvocTT(ref pth, ref tts, _),
             ..
         }) => {
-            (pth, (*tts).clone(), ctxt)
+            (pth, (*tts).clone())
         }
         _ => fld.cx.span_bug(it.span, "invalid item macro invocation")
     };
@@ -326,8 +323,7 @@ pub fn expand_item_mac(it: @ast::Item, fld: &mut MacroExpander)
             });
             // mark before expansion:
             let marked_before = mark_tts(tts,fm);
-            let marked_ctxt = new_mark(fm,ctxt);
-            expander.expand(fld.cx, it.span, marked_before, marked_ctxt)
+            expander.expand(fld.cx, it.span, marked_before)
         }
         Some(&IdentTT(ref expander, span)) => {
             if it.ident.name == parse::token::special_idents::invalid.name {
@@ -345,8 +341,7 @@ pub fn expand_item_mac(it: @ast::Item, fld: &mut MacroExpander)
             });
             // mark before expansion:
             let marked_tts = mark_tts(tts,fm);
-            let marked_ctxt = new_mark(fm,ctxt);
-            expander.expand(fld.cx, it.span, it.ident, marked_tts, marked_ctxt)
+            expander.expand(fld.cx, it.span, it.ident, marked_tts)
         }
         _ => {
             fld.cx.span_err(it.span, format!("{}! is not legal in item position", extnamestr));
@@ -465,11 +460,11 @@ fn load_extern_macros(crate: &ast::ViewItem, fld: &mut MacroExpander) {
 pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<@Stmt> {
     // why the copying here and not in expand_expr?
     // looks like classic changed-in-only-one-place
-    let (pth, tts, semi, ctxt) = match s.node {
+    let (pth, tts, semi) = match s.node {
         StmtMac(ref mac, semi) => {
             match mac.node {
-                MacInvocTT(ref pth, ref tts, ctxt) => {
-                    (pth, (*tts).clone(), semi, ctxt)
+                MacInvocTT(ref pth, ref tts, _) => {
+                    (pth, (*tts).clone(), semi)
                 }
             }
         }
@@ -499,7 +494,6 @@ pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<@Stmt> {
             let fm = fresh_mark();
             // mark before expansion:
             let marked_tts = mark_tts(tts,fm);
-            let marked_ctxt = new_mark(fm,ctxt);
 
             // See the comment in expand_expr for why we want the original span,
             // not the current mac.span.
@@ -507,8 +501,7 @@ pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<@Stmt> {
 
             let expanded = match expandfun.expand(fld.cx,
                                                   mac_span.call_site,
-                                                  marked_tts,
-                                                  marked_ctxt) {
+                                                  marked_tts) {
                 MRExpr(e) => {
                     @codemap::Spanned {
                         node: StmtExpr(e, ast::DUMMY_NODE_ID),
@@ -754,218 +747,6 @@ pub fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
     }
 }
 
-// FIXME (#2247): this is a moderately bad kludge to inject some macros into
-// the default compilation environment in that it injects strings, rather than
-// syntax elements.
-
-pub fn std_macros() -> @str {
-@r#"mod __std_macros {
-    #[macro_escape];
-    #[doc(hidden)];
-    #[allow(dead_code)];
-
-    macro_rules! ignore (($($x:tt)*) => (()))
-
-    macro_rules! log(
-        ($lvl:expr, $($arg:tt)+) => ({
-            let lvl = $lvl;
-            if lvl <= __log_level() {
-                format_args!(|args| {
-                    ::std::logging::log(lvl, args)
-                }, $($arg)+)
-            }
-        })
-    )
-    macro_rules! error( ($($arg:tt)*) => (log!(1u32, $($arg)*)) )
-    macro_rules! warn ( ($($arg:tt)*) => (log!(2u32, $($arg)*)) )
-    macro_rules! info ( ($($arg:tt)*) => (log!(3u32, $($arg)*)) )
-    macro_rules! debug( ($($arg:tt)*) => (
-        if cfg!(not(ndebug)) { log!(4u32, $($arg)*) }
-    ))
-
-    macro_rules! log_enabled(
-        ($lvl:expr) => ( {
-            let lvl = $lvl;
-            lvl <= __log_level() && (lvl != 4 || cfg!(not(ndebug)))
-        } )
-    )
-
-    macro_rules! fail(
-        () => (
-            fail!("explicit failure")
-        );
-        ($msg:expr) => (
-            ::std::rt::begin_unwind($msg, file!(), line!())
-        );
-        ($fmt:expr, $($arg:tt)*) => (
-            ::std::rt::begin_unwind(format!($fmt, $($arg)*), file!(), line!())
-        )
-    )
-
-    macro_rules! assert(
-        ($cond:expr) => {
-            if !$cond {
-                fail!("assertion failed: {:s}", stringify!($cond))
-            }
-        };
-        ($cond:expr, $msg:expr) => {
-            if !$cond {
-                fail!($msg)
-            }
-        };
-        ($cond:expr, $( $arg:expr ),+) => {
-            if !$cond {
-                fail!( $($arg),+ )
-            }
-        }
-    )
-
-    macro_rules! assert_eq (
-        ($given:expr , $expected:expr) => (
-            {
-                let given_val = &($given);
-                let expected_val = &($expected);
-                // check both directions of equality....
-                if !((*given_val == *expected_val) &&
-                     (*expected_val == *given_val)) {
-                    fail!("assertion failed: `(left == right) && (right == left)` \
-                           (left: `{:?}`, right: `{:?}`)", *given_val, *expected_val)
-                }
-            }
-        )
-    )
-
-    /// A utility macro for indicating unreachable code. It will fail if
-    /// executed. This is occasionally useful to put after loops that never
-    /// terminate normally, but instead directly return from a function.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// fn choose_weighted_item(v: &[Item]) -> Item {
-    ///     assert!(!v.is_empty());
-    ///     let mut so_far = 0u;
-    ///     for item in v.iter() {
-    ///         so_far += item.weight;
-    ///         if so_far > 100 {
-    ///             return item;
-    ///         }
-    ///     }
-    ///     // The above loop always returns, so we must hint to the
-    ///     // type checker that it isn't possible to get down here
-    ///     unreachable!();
-    /// }
-    /// ```
-    macro_rules! unreachable (() => (
-        fail!("internal error: entered unreachable code");
-    ))
-
-    macro_rules! condition (
-
-        { pub $c:ident: $input:ty -> $out:ty; } => {
-
-            pub mod $c {
-                #[allow(unused_imports)];
-                #[allow(non_uppercase_statics)];
-                #[allow(missing_doc)];
-
-                use super::*;
-
-                local_data_key!(key: @::std::condition::Handler<$input, $out>)
-
-                pub static cond :
-                    ::std::condition::Condition<$input,$out> =
-                    ::std::condition::Condition {
-                        name: stringify!($c),
-                        key: key
-                    };
-            }
-        };
-
-        { $c:ident: $input:ty -> $out:ty; } => {
-
-            mod $c {
-                #[allow(unused_imports)];
-                #[allow(non_uppercase_statics)];
-                #[allow(dead_code)];
-
-                use super::*;
-
-                local_data_key!(key: @::std::condition::Handler<$input, $out>)
-
-                pub static cond :
-                    ::std::condition::Condition<$input,$out> =
-                    ::std::condition::Condition {
-                        name: stringify!($c),
-                        key: key
-                    };
-            }
-        }
-    )
-
-    macro_rules! format(($($arg:tt)*) => (
-        format_args!(::std::fmt::format, $($arg)*)
-    ))
-    macro_rules! write(($dst:expr, $($arg:tt)*) => (
-        format_args!(|args| { ::std::fmt::write($dst, args) }, $($arg)*)
-    ))
-    macro_rules! writeln(($dst:expr, $($arg:tt)*) => (
-        format_args!(|args| { ::std::fmt::writeln($dst, args) }, $($arg)*)
-    ))
-    macro_rules! print (
-        ($($arg:tt)*) => (format_args!(::std::io::stdio::print_args, $($arg)*))
-    )
-    macro_rules! println (
-        ($($arg:tt)*) => (format_args!(::std::io::stdio::println_args, $($arg)*))
-    )
-
-    macro_rules! local_data_key (
-        ($name:ident: $ty:ty) => (
-            static $name: ::std::local_data::Key<$ty> = &::std::local_data::Key;
-        );
-        (pub $name:ident: $ty:ty) => (
-            pub static $name: ::std::local_data::Key<$ty> = &::std::local_data::Key;
-        )
-    )
-}"#
-}
-
-struct Injector {
-    sm: @ast::Item,
-}
-
-impl Folder for Injector {
-    fn fold_mod(&mut self, module: &ast::Mod) -> ast::Mod {
-        // Just inject the standard macros at the start of the first module
-        // in the crate: that is, at the start of the crate file itself.
-        let items = vec::append(~[ self.sm ], module.items);
-        ast::Mod {
-            items: items,
-            ..(*module).clone() // FIXME #2543: Bad copy.
-        }
-    }
-}
-
-// add a bunch of macros as though they were placed at the head of the
-// program (ick). This should run before cfg stripping.
-pub fn inject_std_macros(parse_sess: @parse::ParseSess,
-                         cfg: ast::CrateConfig,
-                         c: Crate)
-                         -> Crate {
-    let sm = match parse_item_from_source_str(@"<std-macros>",
-                                              std_macros(),
-                                              cfg.clone(),
-                                              parse_sess) {
-        Some(item) => item,
-        None => fail!("expected core macros to parse correctly")
-    };
-
-    let mut injector = Injector {
-        sm: sm,
-    };
-    injector.fold_crate(c)
-}
-
 pub struct MacroExpander<'a> {
     extsbox: SyntaxEnv,
     cx: &'a mut ExtCtxt<'a>,
@@ -1136,15 +917,6 @@ pub fn replace_ctxts(expr : @ast::Expr, ctxt : SyntaxContext) -> @ast::Expr {
     fun_to_ctxt_folder(@Repainter{ctxt:ctxt}).fold_expr(expr)
 }
 
-// take the mark from the given ctxt (that has a mark at the outside),
-// and apply it to everything in the token trees, thereby cancelling
-// that mark.
-pub fn mtwt_cancel_outer_mark(tts: &[ast::TokenTree], ctxt: ast::SyntaxContext)
-    -> ~[ast::TokenTree] {
-    let outer_mark = mtwt_outer_mark(ctxt);
-    mark_tts(tts,outer_mark)
-}
-
 fn original_span(cx: &ExtCtxt) -> @codemap::ExpnInfo {
     let mut relevant_info = cx.backtrace();
     let mut einfo = relevant_info.unwrap();
@@ -1231,20 +1003,6 @@ fn get_registrar_symbol(&mut self, _: ast::CrateNum) -> Option<~str> {
         }
     }
 
-    // make sure that fail! is present
-    #[test] fn fail_exists_test () {
-        let src = @"fn main() { fail!(\"something appropriately gloomy\");}";
-        let sess = parse::new_parse_sess(None);
-        let crate_ast = parse::parse_crate_from_source_str(
-            @"<test>",
-            src,
-            ~[],sess);
-        let crate_ast = inject_std_macros(sess, ~[], crate_ast);
-        // don't bother with striping, doesn't affect fail!.
-        let mut loader = ErrLoader;
-        expand_crate(sess,&mut loader,~[],crate_ast);
-    }
-
     // these following tests are quite fragile, in that they don't test what
     // *kind* of failure occurs.
 
@@ -1292,20 +1050,6 @@ fn get_registrar_symbol(&mut self, _: ast::CrateNum) -> Option<~str> {
         expand_crate(sess,&mut loader,~[],crate_ast);
     }
 
-    #[test] fn std_macros_must_parse () {
-        let src = super::std_macros();
-        let sess = parse::new_parse_sess(None);
-        let cfg = ~[];
-        let item_ast = parse::parse_item_from_source_str(
-            @"<test>",
-            src,
-            cfg,sess);
-        match item_ast {
-            Some(_) => (), // success
-            None => fail!("expected this to parse")
-        }
-    }
-
     #[test] fn test_contains_flatten (){
         let attr1 = make_dummy_attr (@"foo");
         let attr2 = make_dummy_attr (@"bar");
@@ -1331,28 +1075,6 @@ fn make_dummy_attr(s: @str) -> ast::Attribute {
         }
     }
 
-    #[test] fn cancel_outer_mark_test(){
-        let invalid_name = token::special_idents::invalid.name;
-        let ident_str = @"x";
-        let tts = string_to_tts(ident_str);
-        let fm = fresh_mark();
-        let marked_once = fold::fold_tts(tts,&mut new_mark_folder(fm));
-        assert_eq!(marked_once.len(),1);
-        let marked_once_ctxt =
-            match marked_once[0] {
-                ast::TTTok(_,token::IDENT(id,_)) => id.ctxt,
-                _ => fail!(format!("unexpected shape for marked tts: {:?}",marked_once[0]))
-            };
-        assert_eq!(mtwt_marksof(marked_once_ctxt,invalid_name),~[fm]);
-        let remarked = mtwt_cancel_outer_mark(marked_once,marked_once_ctxt);
-        assert_eq!(remarked.len(),1);
-        match remarked[0] {
-            ast::TTTok(_,token::IDENT(id,_)) =>
-            assert_eq!(mtwt_marksof(id.ctxt,invalid_name),~[]),
-            _ => fail!(format!("unexpected shape for marked tts: {:?}",remarked[0]))
-        }
-    }
-
     #[test]
     fn renaming () {
         let item_ast = string_to_crate(@"fn f() -> int { a }");
index 492852c6a79760a51c34ea21f68fb572305b4244..d5a30a7cf11866cf358d4cc775b3cb489f3c6def 100644 (file)
@@ -396,9 +396,9 @@ pub fn parse(sess: @ParseSess,
                 }
                 cur_eis.push(ei);
 
-                rust_parser.tokens_consumed.times(|| {
+                for _ in range(0, rust_parser.tokens_consumed) {
                     let _ = rdr.next_token();
-                });
+                }
             }
         }
 
index facbee135ed9fafe44a60962d2b6b15dae3d6cfe..aabd9c694f7c024bd5f063fa711837583d94d5fa 100644 (file)
@@ -13,7 +13,7 @@
 use ast;
 use codemap::{Span, Spanned, DUMMY_SP};
 use ext::base::{AnyMacro, ExtCtxt, MacResult, MRAny, MRDef, MacroDef};
-use ext::base::{NormalTT, SyntaxExpanderTTTrait};
+use ext::base::{NormalTT, MacroExpander};
 use ext::base;
 use ext::tt::macro_parser::{Success, Error, Failure};
 use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
@@ -87,18 +87,17 @@ fn make_stmt(&self) -> @ast::Stmt {
     }
 }
 
-struct MacroRulesSyntaxExpanderTTFun {
+struct MacroRulesMacroExpander {
     name: Ident,
     lhses: @~[@NamedMatch],
     rhses: @~[@NamedMatch],
 }
 
-impl SyntaxExpanderTTTrait for MacroRulesSyntaxExpanderTTFun {
+impl MacroExpander for MacroRulesMacroExpander {
     fn expand(&self,
               cx: &mut ExtCtxt,
               sp: Span,
-              arg: &[ast::TokenTree],
-              _: ast::SyntaxContext)
+              arg: &[ast::TokenTree])
               -> MacResult {
         generic_extension(cx, sp, self.name, arg, *self.lhses, *self.rhses)
     }
@@ -175,8 +174,7 @@ fn generic_extension(cx: &ExtCtxt,
 pub fn add_new_extension(cx: &mut ExtCtxt,
                          sp: Span,
                          name: Ident,
-                         arg: ~[ast::TokenTree],
-                         _: ast::SyntaxContext)
+                         arg: ~[ast::TokenTree])
                          -> base::MacResult {
     // these spans won't matter, anyways
     fn ms(m: Matcher_) -> Matcher {
@@ -224,7 +222,7 @@ fn ms(m: Matcher_) -> Matcher {
         _ => cx.span_bug(sp, "wrong-structured rhs")
     };
 
-    let exp = ~MacroRulesSyntaxExpanderTTFun {
+    let exp = ~MacroRulesMacroExpander {
         name: name,
         lhses: lhses,
         rhses: rhses,
index 20d544f52c90f8a035a89f5ad0a9e57064ec52a2..87a2f374c900517be9bcb1686f5182621f95a3f0 100644 (file)
@@ -173,7 +173,7 @@ fn lockstep_iter_size(t: &TokenTree, r: &TtReader) -> LockstepIterSize {
 // return the next token from the TtReader.
 // EFFECT: advances the reader's token field
 pub fn tt_next_token(r: &TtReader) -> TokenAndSpan {
-    // XXX(pcwalton): Bad copy?
+    // FIXME(pcwalton): Bad copy?
     let ret_val = TokenAndSpan {
         tok: r.cur_tok.get(),
         sp: r.cur_span.get(),
@@ -231,7 +231,7 @@ pub fn tt_next_token(r: &TtReader) -> TokenAndSpan {
     }
     loop { /* because it's easiest, this handles `TTDelim` not starting
     with a `TTTok`, even though it won't happen */
-        // XXX(pcwalton): Bad copy.
+        // FIXME(pcwalton): Bad copy.
         match r.stack.get().forest[r.stack.get().idx.get()].clone() {
           TTDelim(tts) => {
             r.stack.set(@TtFrame {
@@ -250,7 +250,7 @@ pub fn tt_next_token(r: &TtReader) -> TokenAndSpan {
             return ret_val;
           }
           TTSeq(sp, tts, sep, zerok) => {
-            // XXX(pcwalton): Bad copy.
+            // FIXME(pcwalton): Bad copy.
             let t = TTSeq(sp, tts, sep.clone(), zerok);
             match lockstep_iter_size(&t, r) {
               LisUnconstrained => {
@@ -306,7 +306,7 @@ pub fn tt_next_token(r: &TtReader) -> TokenAndSpan {
                 return ret_val;
               }
               MatchedNonterminal(ref other_whole_nt) => {
-                // XXX(pcwalton): Bad copy.
+                // FIXME(pcwalton): Bad copy.
                 r.cur_span.set(sp);
                 r.cur_tok.set(INTERPOLATED((*other_whole_nt).clone()));
                 r.stack.get().idx.set(r.stack.get().idx.get() + 1u);
index 7a86dd6e4ce72d70548f2e940c6afcd261307ac4..8dac13f1e31a9a307290c79f443271d8ded355d1 100644 (file)
@@ -306,9 +306,7 @@ fn fold_explicit_self(&mut self, es: &ExplicitSelf) -> ExplicitSelf {
 
     fn fold_explicit_self_(&mut self, es: &ExplicitSelf_) -> ExplicitSelf_ {
         match *es {
-            SelfStatic | SelfValue(_) | SelfUniq(_) | SelfBox => {
-                *es
-            }
+            SelfStatic | SelfValue | SelfUniq | SelfBox => *es,
             SelfRegion(ref lifetime, m) => {
                 SelfRegion(fold_opt_lifetime(lifetime, self), m)
             }
@@ -408,6 +406,7 @@ pub fn fold_ty_param<T: Folder>(tp: &TyParam, fld: &mut T) -> TyParam {
         ident: tp.ident,
         id: fld.new_id(tp.id),
         bounds: tp.bounds.map(|x| fold_ty_param_bound(x, fld)),
+        default: tp.default.map(|x| fld.fold_ty(x))
     }
 }
 
@@ -666,7 +665,6 @@ pub fn noop_fold_method<T: Folder>(m: &Method, folder: &mut T) -> @Method {
         body: folder.fold_block(m.body),
         id: folder.new_id(m.id),
         span: folder.new_span(m.span),
-        self_id: folder.new_id(m.self_id),
         vis: m.vis
     }
 }
@@ -737,10 +735,9 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
                      args.map(|&x| folder.fold_expr(x)),
                      blk)
         }
-        ExprMethodCall(callee_id, f, i, ref tps, ref args, blk) => {
+        ExprMethodCall(callee_id, i, ref tps, ref args, blk) => {
             ExprMethodCall(
                 folder.new_id(callee_id),
-                folder.fold_expr(f),
                 folder.fold_ident(i),
                 tps.map(|&x| folder.fold_ty(x)),
                 args.map(|&x| folder.fold_expr(x)),
@@ -756,7 +753,6 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
         ExprUnary(callee_id, binop, ohs) => {
             ExprUnary(folder.new_id(callee_id), binop, folder.fold_expr(ohs))
         }
-        ExprDoBody(f) => ExprDoBody(folder.fold_expr(f)),
         ExprLit(_) => e.node.clone(),
         ExprCast(expr, ty) => {
             ExprCast(folder.fold_expr(expr), folder.fold_ty(ty))
@@ -811,7 +807,6 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
                       folder.fold_expr(er))
         }
         ExprPath(ref pth) => ExprPath(folder.fold_path(pth)),
-        ExprSelf => ExprSelf,
         ExprLogLevel => ExprLogLevel,
         ExprBreak(opt_ident) => ExprBreak(opt_ident),
         ExprAgain(opt_ident) => ExprAgain(opt_ident),
index 1204cbc2eeae7c578f1474e982b30d73faf4947c..accf5e735404504f01ee4104e65e9e1fc4763dc0 100644 (file)
@@ -29,10 +29,8 @@ pub fn expr_requires_semi_to_be_stmt(e: @ast::Expr) -> bool {
       | ast::ExprWhile(..)
       | ast::ExprLoop(..)
       | ast::ExprForLoop(..)
-      | ast::ExprCall(_, _, ast::DoSugar)
       | ast::ExprCall(_, _, ast::ForSugar)
-      | ast::ExprMethodCall(_, _, _, _, _, ast::DoSugar)
-      | ast::ExprMethodCall(_, _, _, _, _, ast::ForSugar) => false,
+      | ast::ExprMethodCall(_, _, _, _, ast::ForSugar) => false,
       _ => true
     }
 }
index 22ece367b8028962c23072669696b330952b3c00..aa5e4e01ae0a050aeecd023493aa9770448972fe 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -78,7 +78,7 @@ fn vertical_trim(lines: ~[~str]) -> ~[~str] {
 
     /// remove a "[ \t]*\*" block from each line, if possible
     fn horizontal_trim(lines: ~[~str]) -> ~[~str] {
-        let mut i = uint::max_value;
+        let mut i = uint::MAX;
         let mut can_trim = true;
         let mut first = true;
         for line in lines.iter() {
index f753861892ffc359f16822e023d26bf54589817f..2521bb515f769ba418ec3734a3c5bd2f91654a97 100644 (file)
@@ -123,7 +123,7 @@ fn fatal(@self, m: ~str) -> ! {
     }
     fn span_diag(@self) -> @SpanHandler { self.span_diagnostic }
     fn peek(@self) -> TokenAndSpan {
-        // XXX(pcwalton): Bad copy!
+        // FIXME(pcwalton): Bad copy!
         TokenAndSpan {
             tok: self.peek_tok.get(),
             sp: self.peek_span.get(),
index 557e7e04ebfc59fdb992e4aece6c5dc3a4a8aaa1..04a984ba95d92b7dc2fe9b102b3f5cc5490fc603 100644 (file)
@@ -13,7 +13,7 @@
 use abi;
 use abi::AbiSet;
 use ast::{Sigil, BorrowedSigil, ManagedSigil, OwnedSigil};
-use ast::{CallSugar, NoSugar, DoSugar};
+use ast::{CallSugar, NoSugar};
 use ast::{BareFnTy, ClosureTy};
 use ast::{RegionTyParamBound, TraitTyParamBound};
 use ast::{Provided, Public, Purity};
 use ast::{DeclLocal, DefaultBlock, UnDeref, BiDiv, EMPTY_CTXT, EnumDef, ExplicitSelf};
 use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain};
 use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox};
-use ast::{ExprBreak, ExprCall, ExprCast, ExprDoBody};
+use ast::{ExprBreak, ExprCall, ExprCast};
 use ast::{ExprField, ExprFnBlock, ExprIf, ExprIndex};
 use ast::{ExprLit, ExprLogLevel, ExprLoop, ExprMac};
-use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc, ExprRepeat};
-use ast::{ExprRet, ExprSelf, ExprStruct, ExprTup, ExprUnary};
+use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc};
+use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary};
 use ast::{ExprVec, ExprVstore, ExprVstoreSlice, ExprVstoreBox};
 use ast::{ExprVstoreMutSlice, ExprWhile, ExprForLoop, ExternFn, Field, FnDecl};
 use ast::{ExprVstoreUniq, Onceness, Once, Many};
@@ -122,7 +122,7 @@ struct PathSegmentAndBoundSet {
 }
 
 /// A path paired with optional type bounds.
-struct PathAndBounds {
+pub struct PathAndBounds {
     path: ast::Path,
     bounds: Option<OptVec<TyParamBound>>,
 }
@@ -1093,7 +1093,6 @@ pub fn parse_trait_methods(&mut self) -> ~[TraitMethod] {
                     body: body,
                     id: ast::DUMMY_NODE_ID,
                     span: mk_sp(lo, hi),
-                    self_id: ast::DUMMY_NODE_ID,
                     vis: vis,
                 })
               }
@@ -1237,7 +1236,7 @@ pub fn parse_ty(&mut self, _: bool) -> P<Ty> {
                 Parser::token_is_lifetime(&self.token) {
             // CLOSURE
             //
-            // XXX(pcwalton): Eventually `token::LT` will not unambiguously
+            // FIXME(pcwalton): Eventually `token::LT` will not unambiguously
             // introduce a closure, once procs can have lifetime bounds. We
             // will need to refactor the grammar a little bit at that point.
 
@@ -1687,13 +1686,9 @@ pub fn mk_call(&mut self, f: @Expr, args: ~[@Expr], sugar: CallSugar) -> ast::Ex
         ExprCall(f, args, sugar)
     }
 
-    pub fn mk_method_call(&mut self,
-                      rcvr: @Expr,
-                      ident: Ident,
-                      tps: ~[P<Ty>],
-                      args: ~[@Expr],
+    fn mk_method_call(&mut self, ident: Ident, tps: ~[P<Ty>], args: ~[@Expr],
                       sugar: CallSugar) -> ast::Expr_ {
-        ExprMethodCall(ast::DUMMY_NODE_ID, rcvr, ident, tps, args, sugar)
+        ExprMethodCall(ast::DUMMY_NODE_ID, ident, tps, args, sugar)
     }
 
     pub fn mk_index(&mut self, expr: @Expr, idx: @Expr) -> ast::Expr_ {
@@ -1794,15 +1789,13 @@ pub fn parse_bottom_expr(&mut self) -> @Expr {
 
             return self.mk_expr(lo, body.span.hi, ExprProc(decl, fakeblock));
         } else if self.eat_keyword(keywords::Self) {
-            ex = ExprSelf;
+            let path = ast_util::ident_to_path(mk_sp(lo, hi), special_idents::self_);
+            ex = ExprPath(path);
             hi = self.span.hi;
         } else if self.eat_keyword(keywords::If) {
             return self.parse_if_expr();
         } else if self.eat_keyword(keywords::For) {
             return self.parse_for_expr(None);
-        } else if self.eat_keyword(keywords::Do) {
-            return self.parse_sugary_call_expr(lo, ~"do", DoSugar,
-                                               ExprDoBody);
         } else if self.eat_keyword(keywords::While) {
             return self.parse_while_expr();
         } else if Parser::token_is_lifetime(&self.token) {
@@ -1922,25 +1915,19 @@ pub fn parse_bottom_expr(&mut self) -> @Expr {
                     let mut fields = ~[];
                     let mut base = None;
 
-                    fields.push(self.parse_field());
                     while self.token != token::RBRACE {
-                        self.commit_expr(fields.last().unwrap().expr,
-                                         &[token::COMMA], &[token::RBRACE]);
-
                         if self.eat(&token::DOTDOT) {
                             base = Some(self.parse_expr());
                             break;
                         }
 
-                        if self.token == token::RBRACE {
-                            // Accept an optional trailing comma.
-                            break;
-                        }
                         fields.push(self.parse_field());
+                        self.commit_expr(fields.last().unwrap().expr,
+                                         &[token::COMMA], &[token::RBRACE]);
                     }
 
                     hi = pth.span.hi;
-                    self.commit_expr_expecting(fields.last().unwrap().expr, token::RBRACE);
+                    self.expect(&token::RBRACE);
                     ex = ExprStruct(pth, fields, base);
                     return self.mk_expr(lo, hi, ex);
                 }
@@ -1993,7 +1980,7 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: @Expr) -> @Expr {
                     // expr.f() method call
                     match self.token {
                         token::LPAREN => {
-                            let es = self.parse_unspanned_seq(
+                            let mut es = self.parse_unspanned_seq(
                                 &token::LPAREN,
                                 &token::RPAREN,
                                 seq_sep_trailing_disallowed(token::COMMA),
@@ -2001,7 +1988,8 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: @Expr) -> @Expr {
                             );
                             hi = self.span.hi;
 
-                            let nd = self.mk_method_call(e, i, tys, es, NoSugar);
+                            es.unshift(e);
+                            let nd = self.mk_method_call(i, tys, es, NoSugar);
                             e = self.mk_expr(lo, hi, nd);
                         }
                         _ => {
@@ -2544,77 +2532,6 @@ pub fn parse_for_expr(&mut self, opt_ident: Option<ast::Ident>) -> @Expr {
         self.mk_expr(lo, hi, ExprForLoop(pat, expr, loop_block, opt_ident))
     }
 
-
-    // parse a 'do'.
-    // the 'do' expression parses as a call, but looks like
-    // a function call followed by a closure expression.
-    pub fn parse_sugary_call_expr(&mut self,
-                                  lo: BytePos,
-                                  keyword: ~str,
-                                  sugar: CallSugar,
-                                  ctor: |v: @Expr| -> Expr_)
-                                  -> @Expr {
-        // Parse the callee `foo` in
-        //    do foo || {
-        //    do foo.bar || {
-        // etc, or the portion of the call expression before the lambda in
-        //    do foo() || {
-        // or
-        //    do foo.bar(a) || {
-        // Turn on the restriction to stop at | or || so we can parse
-        // them as the lambda arguments
-        let e = self.parse_expr_res(RESTRICT_NO_BAR_OR_DOUBLEBAR_OP);
-        match e.node {
-            ExprCall(f, ref args, NoSugar) => {
-                let block = self.parse_lambda_block_expr();
-                let last_arg = self.mk_expr(block.span.lo, block.span.hi,
-                                            ctor(block));
-                let args = vec::append((*args).clone(), [last_arg]);
-                self.mk_expr(lo, block.span.hi, ExprCall(f, args, sugar))
-            }
-            ExprMethodCall(_, f, i, ref tps, ref args, NoSugar) => {
-                let block = self.parse_lambda_block_expr();
-                let last_arg = self.mk_expr(block.span.lo, block.span.hi,
-                                            ctor(block));
-                let args = vec::append((*args).clone(), [last_arg]);
-                let method_call = self.mk_method_call(f,
-                                                      i,
-                                                      (*tps).clone(),
-                                                      args,
-                                                      sugar);
-                self.mk_expr(lo, block.span.hi, method_call)
-            }
-            ExprField(f, i, ref tps) => {
-                let block = self.parse_lambda_block_expr();
-                let last_arg = self.mk_expr(block.span.lo, block.span.hi,
-                                            ctor(block));
-                let method_call = self.mk_method_call(f,
-                                                      i,
-                                                      (*tps).clone(),
-                                                      ~[last_arg],
-                                                      sugar);
-                self.mk_expr(lo, block.span.hi, method_call)
-            }
-            ExprPath(..) | ExprCall(..) | ExprMethodCall(..) |
-                ExprParen(..) => {
-                let block = self.parse_lambda_block_expr();
-                let last_arg = self.mk_expr(block.span.lo, block.span.hi,
-                                            ctor(block));
-                let call = self.mk_call(e, ~[last_arg], sugar);
-                self.mk_expr(lo, last_arg.span.hi, call)
-            }
-            _ => {
-                // There may be other types of expressions that can
-                // represent the callee in `do` expressions
-                // but they aren't represented by tests
-                debug!("sugary call on {:?}", e.node);
-                self.span_fatal(
-                    e.span,
-                    format!("`{}` must be followed by a block call", keyword));
-            }
-        }
-    }
-
     pub fn parse_while_expr(&mut self) -> @Expr {
         let lo = self.last_span.lo;
         let cond = self.parse_expr();
@@ -2660,8 +2577,9 @@ pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::Ident>) -> @Expr {
     // For distingishing between struct literals and blocks
     fn looking_at_struct_literal(&mut self) -> bool {
         self.token == token::LBRACE &&
-        (self.look_ahead(1, |t| token::is_plain_ident(t)) &&
-         self.look_ahead(2, |t| *t == token::COLON))
+        ((self.look_ahead(1, |t| token::is_plain_ident(t)) &&
+          self.look_ahead(2, |t| *t == token::COLON))
+         || self.look_ahead(1, |t| *t == token::DOTDOT))
     }
 
     fn parse_match_expr(&mut self) -> @Expr {
@@ -3534,13 +3452,25 @@ fn parse_optional_ty_param_bounds(&mut self) -> Option<OptVec<TyParamBound>> {
         return Some(result);
     }
 
-    // matches typaram = IDENT optbounds
+    // matches typaram = IDENT optbounds ( EQ ty )?
     fn parse_ty_param(&mut self) -> TyParam {
         let ident = self.parse_ident();
         let opt_bounds = self.parse_optional_ty_param_bounds();
         // For typarams we don't care about the difference b/w "<T>" and "<T:>".
         let bounds = opt_bounds.unwrap_or_default();
-        ast::TyParam { ident: ident, id: ast::DUMMY_NODE_ID, bounds: bounds }
+
+        let default = if self.token == token::EQ {
+            self.bump();
+            Some(self.parse_ty(false))
+        }
+        else { None };
+
+        TyParam {
+            ident: ident,
+            id: ast::DUMMY_NODE_ID,
+            bounds: bounds,
+            default: default
+        }
     }
 
     // parse a set of optional generic type parameter declarations
@@ -3550,9 +3480,17 @@ fn parse_ty_param(&mut self) -> TyParam {
     pub fn parse_generics(&mut self) -> ast::Generics {
         if self.eat(&token::LT) {
             let lifetimes = self.parse_lifetimes();
-            let ty_params = self.parse_seq_to_gt(
-                Some(token::COMMA),
-                |p| p.parse_ty_param());
+            let mut seen_default = false;
+            let ty_params = self.parse_seq_to_gt(Some(token::COMMA), |p| {
+                let ty_param = p.parse_ty_param();
+                if ty_param.default.is_some() {
+                    seen_default = true;
+                } else if seen_default {
+                    p.span_err(p.last_span,
+                               "type parameters with a default must be trailing");
+                }
+                ty_param
+            });
             ast::Generics { lifetimes: lifetimes, ty_params: ty_params }
         } else {
             ast_util::empty_generics()
@@ -3712,6 +3650,7 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
         // A bit of complexity and lookahead is needed here in order to be
         // backwards compatible.
         let lo = self.span.lo;
+        let mut mutbl_self = MutImmutable;
         let explicit_self = match self.token {
             token::BINOP(token::AND) => {
                 maybe_parse_borrowed_explicit_self(self)
@@ -3720,57 +3659,60 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
                 maybe_parse_explicit_self(SelfBox, self)
             }
             token::TILDE => {
-                maybe_parse_explicit_self(SelfUniq(MutImmutable), self)
+                maybe_parse_explicit_self(SelfUniq, self)
             }
             token::IDENT(..) if self.is_self_ident() => {
                 self.bump();
-                SelfValue(MutImmutable)
+                SelfValue
             }
             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 Parser::token_is_mutability(&self.token) {
                     self.parse_mutability()
                 } else { MutImmutable };
                 if self.is_self_ident() {
                     self.span_err(self.span, "cannot pass self by unsafe pointer");
                     self.bump();
                 }
-                SelfValue(mutability)
+                SelfValue
             }
             _ if Parser::token_is_mutability(&self.token) &&
                     self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) => {
-                let mutability = self.parse_mutability();
+                mutbl_self = self.parse_mutability();
                 self.expect_self_ident();
-                SelfValue(mutability)
+                SelfValue
             }
             _ 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)) => {
-                let mutability = self.parse_mutability();
+                mutbl_self = self.parse_mutability();
                 self.bump();
                 self.expect_self_ident();
-                SelfUniq(mutability)
+                SelfUniq
             }
             _ => SelfStatic
         };
 
+        let explicit_self_sp = mk_sp(lo, self.span.hi);
+
         // If we parsed a self type, expect a comma before the argument list.
-        let fn_inputs;
-        if explicit_self != SelfStatic {
+        let fn_inputs = if explicit_self != SelfStatic {
             match self.token {
                 token::COMMA => {
                     self.bump();
                     let sep = seq_sep_trailing_disallowed(token::COMMA);
-                    fn_inputs = self.parse_seq_to_before_end(
+                    let mut fn_inputs = self.parse_seq_to_before_end(
                         &token::RPAREN,
                         sep,
                         parse_arg_fn
                     );
+                    fn_inputs.unshift(Arg::new_self(explicit_self_sp, mutbl_self));
+                    fn_inputs
                 }
                 token::RPAREN => {
-                    fn_inputs = ~[];
+                    ~[Arg::new_self(explicit_self_sp, mutbl_self)]
                 }
                 _ => {
                     let token_str = self.this_token_to_str();
@@ -3780,10 +3722,8 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
             }
         } else {
             let sep = seq_sep_trailing_disallowed(token::COMMA);
-            fn_inputs = self.parse_seq_to_before_end(&token::RPAREN,
-                                                     sep,
-                                                     parse_arg_fn);
-        }
+            self.parse_seq_to_before_end(&token::RPAREN, sep, parse_arg_fn)
+        };
 
         self.expect(&token::RPAREN);
 
@@ -3918,7 +3858,6 @@ fn parse_method(&mut self, already_parsed_attrs: Option<~[Attribute]>) -> @Metho
             body: body,
             id: ast::DUMMY_NODE_ID,
             span: mk_sp(lo, hi),
-            self_id: ast::DUMMY_NODE_ID,
             vis: visa,
         }
     }
@@ -3949,7 +3888,7 @@ fn parse_item_impl(&mut self) -> ItemInfo {
         let generics = self.parse_generics();
 
         // This is a new-style impl declaration.
-        // XXX: clownshoes
+        // FIXME: clownshoes
         let ident = special_idents::clownshoes_extensions;
 
         // Special case: if the next identifier that follows is '(', don't
@@ -4071,7 +4010,7 @@ fn parse_item_struct(&mut self) -> ItemInfo {
                                token_str))
         }
 
-        let _ = ast::DUMMY_NODE_ID;  // XXX: Workaround for crazy bug.
+        let _ = ast::DUMMY_NODE_ID;  // FIXME: Workaround for crazy bug.
         let new_id = ast::DUMMY_NODE_ID;
         (class_name,
          ItemStruct(@ast::StructDef {
index 56681ef2def002d2abdc1b200f64965443d592fe..68e2f44ebb18482a302609e6bd24e668604b75a4 100644 (file)
@@ -433,51 +433,50 @@ pub mod keywords {
         (14,                         As,         "as");
         (15,                         Break,      "break");
         (16,                         Const,      "const");
-        (17,                         Do,         "do");
-        (18,                         Else,       "else");
-        (19,                         Enum,       "enum");
-        (20,                         Extern,     "extern");
-        (21,                         False,      "false");
-        (22,                         Fn,         "fn");
-        (23,                         For,        "for");
-        (24,                         If,         "if");
-        (25,                         Impl,       "impl");
-        (26,                         In,         "in");
-        (27,                         Let,        "let");
-        (28,                         __LogLevel, "__log_level");
-        (29,                         Loop,       "loop");
-        (30,                         Match,      "match");
-        (31,                         Mod,        "mod");
-        (32,                         Mut,        "mut");
-        (33,                         Once,       "once");
-        (34,                         Priv,       "priv");
-        (35,                         Pub,        "pub");
-        (36,                         Ref,        "ref");
-        (37,                         Return,     "return");
+        (17,                         Else,       "else");
+        (18,                         Enum,       "enum");
+        (19,                         Extern,     "extern");
+        (20,                         False,      "false");
+        (21,                         Fn,         "fn");
+        (22,                         For,        "for");
+        (23,                         If,         "if");
+        (24,                         Impl,       "impl");
+        (25,                         In,         "in");
+        (26,                         Let,        "let");
+        (27,                         __LogLevel, "__log_level");
+        (28,                         Loop,       "loop");
+        (29,                         Match,      "match");
+        (30,                         Mod,        "mod");
+        (31,                         Mut,        "mut");
+        (32,                         Once,       "once");
+        (33,                         Priv,       "priv");
+        (34,                         Pub,        "pub");
+        (35,                         Ref,        "ref");
+        (36,                         Return,     "return");
         // Static and Self are also special idents (prefill de-dupes)
         (super::STATIC_KEYWORD_NAME, Static,     "static");
         (super::SELF_KEYWORD_NAME,   Self,       "self");
-        (38,                         Struct,     "struct");
-        (39,                         Super,      "super");
-        (40,                         True,       "true");
-        (41,                         Trait,      "trait");
-        (42,                         Type,       "type");
-        (43,                         Unsafe,     "unsafe");
-        (44,                         Use,        "use");
-        (45,                         While,      "while");
-        (46,                         Continue,   "continue");
-        (47,                         Proc,       "proc");
-        (48,                         Box,        "box");
+        (37,                         Struct,     "struct");
+        (38,                         Super,      "super");
+        (39,                         True,       "true");
+        (40,                         Trait,      "trait");
+        (41,                         Type,       "type");
+        (42,                         Unsafe,     "unsafe");
+        (43,                         Use,        "use");
+        (44,                         While,      "while");
+        (45,                         Continue,   "continue");
+        (46,                         Proc,       "proc");
+        (47,                         Box,        "box");
 
         'reserved:
-        (49,                         Alignof,    "alignof");
-        (50,                         Be,         "be");
-        (51,                         Offsetof,   "offsetof");
-        (52,                         Pure,       "pure");
-        (53,                         Sizeof,     "sizeof");
-        (54,                         Typeof,     "typeof");
-        (55,                         Unsized,    "unsized");
-        (56,                         Yield,      "yield");
+        (48,                         Alignof,    "alignof");
+        (49,                         Be,         "be");
+        (50,                         Offsetof,   "offsetof");
+        (51,                         Pure,       "pure");
+        (52,                         Sizeof,     "sizeof");
+        (53,                         Typeof,     "typeof");
+        (54,                         Unsized,    "unsized");
+        (55,                         Yield,      "yield");
     }
 }
 
index 54e9a8bd62937f378677e4f6d9f72b551d95ff2d..2783284ea8b05a862560f4b9a89ae1b2a07c2f42 100644 (file)
@@ -1088,10 +1088,6 @@ pub fn print_call_pre(s: &mut State,
                       base_args: &mut ~[@ast::Expr])
                    -> Option<@ast::Expr> {
     match sugar {
-        ast::DoSugar => {
-            head(s, "do");
-            Some(base_args.pop().unwrap())
-        }
         ast::ForSugar => {
             head(s, "for");
             Some(base_args.pop().unwrap())
@@ -1111,19 +1107,8 @@ pub fn print_call_post(s: &mut State,
     }
     if sugar != ast::NoSugar {
         nbsp(s);
-        match blk.unwrap().node {
-          // need to handle closures specifically
-          ast::ExprDoBody(e) => {
-            end(s); // we close our head box; closure
-                    // will create it's own.
-            print_expr(s, e);
-            end(s); // close outer box, as closures don't
-          }
-          _ => {
-            // not sure if this can happen.
-            print_expr(s, blk.unwrap());
-          }
-        }
+        // not sure if this can happen
+        print_expr(s, blk.unwrap());
     }
 }
 
@@ -1189,8 +1174,10 @@ fn print_field(s: &mut State, field: &ast::Field) {
         match wth {
             Some(expr) => {
                 ibox(s, indent_unit);
-                word(&mut s.s, ",");
-                space(&mut s.s);
+                if !fields.is_empty() {
+                    word(&mut s.s, ",");
+                    space(&mut s.s);
+                }
                 word(&mut s.s, "..");
                 print_expr(s, expr);
                 end(s);
@@ -1213,10 +1200,10 @@ fn print_field(s: &mut State, field: &ast::Field) {
         print_expr(s, func);
         print_call_post(s, sugar, &blk, &mut base_args);
       }
-      ast::ExprMethodCall(_, func, ident, ref tys, ref args, sugar) => {
-        let mut base_args = (*args).clone();
+      ast::ExprMethodCall(_, ident, ref tys, ref args, sugar) => {
+        let mut base_args = args.slice_from(1).to_owned();
         let blk = print_call_pre(s, sugar, &mut base_args);
-        print_expr(s, func);
+        print_expr(s, args[0]);
         word(&mut s.s, ".");
         print_ident(s, ident);
         if tys.len() > 0u {
@@ -1405,9 +1392,6 @@ fn print_field(s: &mut State, field: &ast::Field) {
         // empty box to satisfy the close.
         ibox(s, 0);
       }
-      ast::ExprDoBody(body) => {
-        print_expr(s, body);
-      }
       ast::ExprBlock(blk) => {
         // containing cbox, will be closed by print-block at }
         cbox(s, indent_unit);
@@ -1445,7 +1429,6 @@ fn print_field(s: &mut State, field: &ast::Field) {
         word(&mut s.s, "]");
       }
       ast::ExprPath(ref path) => print_path(s, path, true),
-      ast::ExprSelf => word(&mut s.s, "self"),
       ast::ExprBreak(opt_ident) => {
         word(&mut s.s, "break");
         space(&mut s.s);
@@ -1749,19 +1732,20 @@ fn print_field(s: &mut State, f: &ast::FieldPat) {
 }
 
 pub fn explicit_self_to_str(explicit_self: &ast::ExplicitSelf_, intr: @IdentInterner) -> ~str {
-    to_str(explicit_self, |a, &b| { print_explicit_self(a, b); () }, intr)
+    to_str(explicit_self, |a, &b| { print_explicit_self(a, b, ast::MutImmutable); () }, intr)
 }
 
 // Returns whether it printed anything
-pub fn print_explicit_self(s: &mut State, explicit_self: ast::ExplicitSelf_) -> bool {
+fn print_explicit_self(s: &mut State,
+                       explicit_self: ast::ExplicitSelf_,
+                       mutbl: ast::Mutability) -> bool {
+    print_mutability(s, mutbl);
     match explicit_self {
         ast::SelfStatic => { return false; }
-        ast::SelfValue(m) => {
-            print_mutability(s, m);
+        ast::SelfValue => {
             word(&mut s.s, "self");
         }
-        ast::SelfUniq(m) => {
-            print_mutability(s, m);
+        ast::SelfUniq => {
             word(&mut s.s, "~self");
         }
         ast::SelfRegion(ref lt, m) => {
@@ -1799,11 +1783,25 @@ pub fn print_fn_args(s: &mut State, decl: &ast::FnDecl,
     // self type and the args all in the same box.
     rbox(s, 0u, Inconsistent);
     let mut first = true;
-    for explicit_self in opt_explicit_self.iter() {
-        first = !print_explicit_self(s, *explicit_self);
+    for &explicit_self in opt_explicit_self.iter() {
+        let m = match explicit_self {
+            ast::SelfStatic => ast::MutImmutable,
+            _ => match decl.inputs[0].pat.node {
+                ast::PatIdent(ast::BindByValue(m), _, _) => m,
+                _ => ast::MutImmutable
+            }
+        };
+        first = !print_explicit_self(s, explicit_self, m);
     }
 
-    for arg in decl.inputs.iter() {
+    // HACK(eddyb) ignore the separately printed self argument.
+    let args = if first {
+        decl.inputs.as_slice()
+    } else {
+        decl.inputs.slice_from(1)
+    };
+
+    for arg in args.iter() {
         if first { first = false; } else { word_space(s, ","); }
         print_arg(s, arg);
     }
@@ -1907,6 +1905,14 @@ fn print_item(s: &mut State, generics: &ast::Generics, idx: uint) {
                 let param = generics.ty_params.get(idx);
                 print_ident(s, param.ident);
                 print_bounds(s, &param.bounds, false);
+                match param.default {
+                    Some(default) => {
+                        space(&mut s.s);
+                        word_space(s, "=");
+                        print_type(s, default);
+                    }
+                    _ => {}
+                }
             }
         }
 
@@ -2090,18 +2096,7 @@ pub fn print_ty_fn(s: &mut State,
         popen(s);
     }
 
-    // It is unfortunate to duplicate the commasep logic, but we want the
-    // self type and the args all in the same box.
-    rbox(s, 0u, Inconsistent);
-    let mut first = true;
-    for explicit_self in opt_explicit_self.iter() {
-        first = !print_explicit_self(s, *explicit_self);
-    }
-    for arg in decl.inputs.iter() {
-        if first { first = false; } else { word_space(s, ","); }
-        print_arg(s, arg);
-    }
-    end(s);
+    print_fn_args(s, decl, opt_explicit_self);
 
     if opt_sigil == Some(ast::BorrowedSigil) {
         word(&mut s.s, "|");
@@ -2311,7 +2306,7 @@ pub fn print_string(s: &mut State, st: &str, style: ast::StrStyle) {
     word(&mut s.s, st);
 }
 
-// XXX(pcwalton): A nasty function to extract the string from an `io::Writer`
+// FIXME(pcwalton): A nasty function to extract the string from an `io::Writer`
 // that we "know" to be a `MemWriter` that works around the lack of checked
 // downcasts.
 unsafe fn get_mem_writer(writer: &mut ~io::Writer) -> ~str {
index 484f8dce1f745c685d4124c258c1d04949c7b392..2a6c14f0eaef721d0281d745f43525ae480aecf8 100644 (file)
@@ -186,7 +186,7 @@ fn walk_explicit_self<E: Clone, V: Visitor<E>>(visitor: &mut V,
                                                explicit_self: &ExplicitSelf,
                                                env: E) {
     match explicit_self.node {
-        SelfStatic | SelfValue(_) | SelfBox | SelfUniq(_) => {}
+        SelfStatic | SelfValue | SelfBox | SelfUniq => {}
         SelfRegion(ref lifetime, _) => {
             visitor.visit_opt_lifetime_ref(explicit_self.span, lifetime, env)
         }
@@ -470,7 +470,11 @@ pub fn walk_generics<E: Clone, V: Visitor<E>>(visitor: &mut V,
                                               generics: &Generics,
                                               env: E) {
     for type_parameter in generics.ty_params.iter() {
-        walk_ty_param_bounds(visitor, &type_parameter.bounds, env.clone())
+        walk_ty_param_bounds(visitor, &type_parameter.bounds, env.clone());
+        match type_parameter.default {
+            Some(ty) => visitor.visit_ty(ty, env.clone()),
+            None => {}
+        }
     }
     walk_lifetime_decls(visitor, &generics.lifetimes, env);
 }
@@ -654,20 +658,18 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en
             }
             visitor.visit_expr(callee_expression, env.clone())
         }
-        ExprMethodCall(_, callee, _, ref types, ref arguments, _) => {
+        ExprMethodCall(_, _, ref types, ref arguments, _) => {
             walk_exprs(visitor, *arguments, env.clone());
             for &typ in types.iter() {
                 visitor.visit_ty(typ, env.clone())
             }
-            visitor.visit_expr(callee, env.clone())
         }
         ExprBinary(_, _, left_expression, right_expression) => {
             visitor.visit_expr(left_expression, env.clone());
             visitor.visit_expr(right_expression, env.clone())
         }
         ExprAddrOf(_, subexpression) |
-        ExprUnary(_, _, subexpression) |
-        ExprDoBody(subexpression) => {
+        ExprUnary(_, _, subexpression) => {
             visitor.visit_expr(subexpression, env.clone())
         }
         ExprLit(_) => {}
@@ -734,7 +736,7 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en
         ExprPath(ref path) => {
             visitor.visit_path(path, expression.id, env.clone())
         }
-        ExprSelf | ExprBreak(_) | ExprAgain(_) => {}
+        ExprBreak(_) | ExprAgain(_) => {}
         ExprRet(optional_expression) => {
             walk_expr_opt(visitor, optional_expression, env.clone())
         }
index 535989a92ce1f6f6488c94a2c8f4ed438349f162..e1dabb48f0f898d1a808b3de3a26f5ee3735c7dd 160000 (submodule)
--- a/src/llvm
+++ b/src/llvm
@@ -1 +1 @@
-Subproject commit 535989a92ce1f6f6488c94a2c8f4ed438349f162
+Subproject commit e1dabb48f0f898d1a808b3de3a26f5ee3735c7dd
index 4d859eacecc4e435326a5a05ec777213a98fd674..c8f041c65622765dbe91493109eb4f1428f0b479 100644 (file)
@@ -25,7 +25,7 @@
 
 void*
 rust_uv_loop_new() {
-// XXX libuv doesn't always ignore SIGPIPE even though we don't need it.
+// FIXME libuv doesn't always ignore SIGPIPE even though we don't need it.
 #ifndef __WIN32__
     signal(SIGPIPE, SIG_IGN);
 #endif
index cab9c187eae0d7e2d286637e87fe6503aa470f00..08c17093d2a3ce45c4dbf5ba4b5ec6dbbcf944a0 100644 (file)
@@ -68,7 +68,8 @@ LLVMRustCreateTargetMachine(const char *triple,
                             Reloc::Model RM,
                             CodeGenOpt::Level OptLevel,
                             bool EnableSegmentedStacks,
-                            bool UseSoftFloat) {
+                            bool UseSoftFloat,
+                            bool NoFramePointerElim) {
     std::string Error;
     Triple Trip(Triple::normalize(triple));
     const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Trip.getTriple(),
@@ -79,7 +80,7 @@ LLVMRustCreateTargetMachine(const char *triple,
     }
 
     TargetOptions Options;
-    Options.NoFramePointerElim = true;
+    Options.NoFramePointerElim = NoFramePointerElim;
     Options.EnableSegmentedStacks = EnableSegmentedStacks;
     Options.FloatABIType = FloatABI::Default;
     Options.UseSoftFloat = UseSoftFloat;
@@ -185,7 +186,7 @@ LLVMRustPrintModule(LLVMPassManagerRef PMR,
   std::string ErrorInfo;
   raw_fd_ostream OS(path, ErrorInfo, sys::fs::F_Binary);
   formatted_raw_ostream FOS(OS);
-  PM->add(createPrintModulePass(&FOS));
+  PM->add(createPrintModulePass(FOS));
   PM->run(*unwrap(M));
 }
 
index 280df8cb10f57d9ce4018a796a95f3d118f905ae..75e0375b13ecb9429ecb9d634db1e56c3952ca45 100644 (file)
@@ -156,6 +156,14 @@ DIT unwrapDI(LLVMValueRef ref) {
     return DIT(ref ? unwrap<MDNode>(ref) : NULL);
 }
 
+extern "C" const uint32_t LLVMRustDebugMetadataVersion = DEBUG_METADATA_VERSION;
+
+extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M,
+                                      const char *name,
+                                      uint32_t value) {
+    unwrap(M)->addModuleFlag(Module::Warning, name, value);
+}
+
 extern "C" DIBuilderRef LLVMDIBuilderCreate(LLVMModuleRef M) {
     return new DIBuilder(*unwrap(M));
 }
@@ -537,15 +545,15 @@ extern "C" bool
 LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
     Module *Dst = unwrap(dst);
     MemoryBuffer* buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
-    std::string Err;
-    Module *Src = llvm::getLazyBitcodeModule(buf, Dst->getContext(), &Err);
-    if (Src == NULL) {
-        LLVMRustError = Err.c_str();
+    ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(buf, Dst->getContext());
+    if (!Src) {
+        LLVMRustError = Src.getError().message().c_str();
         delete buf;
         return false;
     }
 
-    if (Linker::LinkModules(Dst, Src, Linker::DestroySource, &Err)) {
+    std::string Err;
+    if (Linker::LinkModules(Dst, *Src, Linker::DestroySource, &Err)) {
         LLVMRustError = Err.c_str();
         return false;
     }
@@ -570,8 +578,8 @@ LLVMRustOpenArchive(char *path) {
 
 extern "C" const char*
 LLVMRustArchiveReadSection(Archive *ar, char *name, size_t *size) {
-    for (Archive::child_iterator child = ar->begin_children(),
-                                   end = ar->end_children();
+    for (Archive::child_iterator child = ar->child_begin(),
+                                   end = ar->child_end();
          child != end; ++child) {
         StringRef sect_name;
         error_code err = child->getName(sect_name);
@@ -589,3 +597,9 @@ extern "C" void
 LLVMRustDestroyArchive(Archive *ar) {
     delete ar;
 }
+
+extern "C" void
+LLVMRustSetDLLExportStorageClass(LLVMValueRef Value) {
+    GlobalValue *V = unwrap<GlobalValue>(Value);
+    V->setDLLStorageClass(GlobalValue::DLLExportStorageClass);
+}
index 96cd67dcec4ff4c846fcc219aaf6a5a9daaa3814..5b16a89b69f1b47b730b1f742b48733d93de6063 100644 (file)
@@ -1,4 +1,4 @@
 # If this file is modified, then llvm will be forcibly cleaned and then rebuilt.
 # The actual contents of this file do not matter, but to trigger a change on the
 # build bots then the contents should be changed so git updates the mtime.
-2014-01-22
+2014-01-27
index ef7199a6ca8cc18fb9a78f5ee3e6c24e7fd3121d..e45a910fc8cab8bc5167be75cb7679a3db38bd1f 100644 (file)
 #include "llvm/PassManager.h"
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/LLVMContext.h"
-#include "llvm/Analysis/Verifier.h"
+#include "llvm/IR/IRPrintingPasses.h"
 #include "llvm/Analysis/Passes.h"
 #include "llvm/Analysis/Lint.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/ADT/DenseSet.h"
-#include "llvm/Assembly/Parser.h"
-#include "llvm/Assembly/PrintModulePass.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FormattedStream.h"
 #include "llvm/Support/Timer.h"
index ed896af69b41fb1537c1806acfab511715f660d6..3bf084b5fdae7abde835fc93f5ebd5bf767a6c03 100644 (file)
@@ -12,8 +12,8 @@
 
 pub fn foo<T:Send + Clone>(x: T) -> Port<T> {
     let (p, c) = Chan::new();
-    do task::spawn() {
+    task::spawn(proc() {
         c.send(x.clone());
-    }
+    });
     p
 }
diff --git a/src/test/auxiliary/default_type_params_xc.rs b/src/test/auxiliary/default_type_params_xc.rs
new file mode 100644 (file)
index 0000000..b2df2c4
--- /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.
+
+#[feature(default_type_params)];
+
+pub struct Heap;
+
+pub struct FakeHeap;
+
+pub struct FakeVec<T, A = FakeHeap>;
index 85847a6fdeb28a5d54de9a0b5ff61f35a608419e..28437c4585d84ef2ec444ba6a3b2692fe614e172 100644 (file)
@@ -13,7 +13,7 @@
 // part of issue-6919.rs
 
 struct C<'a> {
-    k: 'a ||,
+    pub k: 'a ||,
 }
 
 fn no_op() { }
diff --git a/src/test/auxiliary/issue_10031_aux.rs b/src/test/auxiliary/issue_10031_aux.rs
new file mode 100644 (file)
index 0000000..5724d87
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub struct Wrap<A>(A);
index 0892f0ba7359cc65fe065317001673c9f6d69dbe..e5bf8574366c85ea1a9d4a75c43bd18a7c0db80e 100644 (file)
@@ -27,8 +27,8 @@ macro_rules! unexported_macro (() => (3))
 #[macro_registrar]
 pub fn macro_registrar(register: |Name, SyntaxExtension|) {
     register(token::intern("make_a_1"),
-        NormalTT(~SyntaxExpanderTT {
-            expander: SyntaxExpanderTTExpanderWithoutContext(expand_make_a_1),
+        NormalTT(~BasicMacroExpander {
+            expander: expand_make_a_1,
             span: None,
         },
         None));
diff --git a/src/test/auxiliary/struct-field-privacy.rs b/src/test/auxiliary/struct-field-privacy.rs
new file mode 100644 (file)
index 0000000..497d50a
--- /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 A {
+    a: int,
+    pub b: int,
+}
+
+pub struct B {
+    a: int,
+    priv b: int,
+}
index 50cb00b25d4b116ead9b024dc9b2978127c984b5..aa4e0f1ae5809bf5ca10efd4b3293e50777cb2e9 100644 (file)
@@ -64,17 +64,17 @@ fn run(args: &[~str]) {
         let to_child = to_child.clone();
         let mut builder = task::task();
         worker_results.push(builder.future_result());
-        do builder.spawn {
+        builder.spawn(proc() {
             for _ in range(0u, size / workers) {
                 //error!("worker {:?}: sending {:?} bytes", i, num_bytes);
                 to_child.send(bytes(num_bytes));
             }
             //error!("worker {:?} exiting", i);
-        }
+        });
     }
-    do task::spawn || {
+    task::spawn(proc() {
         server(&from_parent, &to_parent);
-    }
+    });
 
     for r in worker_results.iter() {
         r.recv();
index 3cf1a97a36e041821f6a598c89f3f9d3d0d22d87..6ce0f9de8d0a237772cf5ddca820b794795198e0 100644 (file)
@@ -58,13 +58,13 @@ fn run(args: &[~str]) {
         let (from_parent, to_child) = Chan::new();
         let mut builder = task::task();
         worker_results.push(builder.future_result());
-        do builder.spawn {
+        builder.spawn(proc() {
             for _ in range(0u, size / workers) {
                 //error!("worker {:?}: sending {:?} bytes", i, num_bytes);
                 to_child.send(bytes(num_bytes));
             }
             //error!("worker {:?} exiting", i);
-        };
+        });
         from_parent
     } else {
         let (from_parent, to_child) = SharedChan::new();
@@ -72,19 +72,19 @@ fn run(args: &[~str]) {
             let to_child = to_child.clone();
             let mut builder = task::task();
             worker_results.push(builder.future_result());
-            do builder.spawn {
+            builder.spawn(proc() {
                 for _ in range(0u, size / workers) {
                     //error!("worker {:?}: sending {:?} bytes", i, num_bytes);
                     to_child.send(bytes(num_bytes));
                 }
                 //error!("worker {:?} exiting", i);
-            };
+            });
         }
         from_parent
     };
-    do task::spawn || {
+    task::spawn(proc() {
         server(&from_parent, &to_parent);
-    }
+    });
 
     for r in worker_results.iter() {
         r.recv();
index a5838f2017385f56bcda105ce7c03b2e8fe7bfec..b1b2300466a5edb5fc56fee613b6dcd20a1dcc1e 100644 (file)
@@ -91,9 +91,9 @@ fn main() {
         //error!("spawning %?", i);
         let (new_chan, num_port) = init();
         let num_chan_2 = num_chan.clone();
-        let new_future = do Future::spawn() {
+        let new_future = Future::spawn(proc() {
             thread_ring(i, msg_per_task, num_chan_2, num_port)
-        };
+        });
         futures.push(new_future);
         num_chan = new_chan;
     };
index fa7026b6569f9dfb16eeb6e463b406e267e1a440..d7bd0f2f6bd3da361f406fd23a18f98c47443513 100644 (file)
@@ -87,9 +87,9 @@ fn main() {
         //error!("spawning %?", i);
         let (new_chan, num_port) = init();
         let num_chan_2 = num_chan.clone();
-        let new_future = do Future::spawn {
+        let new_future = Future::spawn(proc() {
             thread_ring(i, msg_per_task, num_chan_2, num_port)
-        };
+        });
         futures.push(new_future);
         num_chan = new_chan;
     };
index 6eef71622c5c6232b656d13dc142e295e9af278e..0412a9596f0a24cf4c94eb5e303cbd431267e9b6 100644 (file)
@@ -26,28 +26,28 @@ fn run_pair(n: uint) {
         // Create a stream B->A
         let (pb,cb) = Chan::<()>::new();
 
-        do spawn() || {
+        spawn(proc() {
             let chan = ca;
             let port = pb;
-            n.times(|| {
+            for _ in range(0, n) {
                 chan.send(());
                 port.recv();
-            })
-        }
+            }
+        });
 
-        do spawn() || {
+        spawn(proc() {
             let chan = cb;
             let port = pa;
-            n.times(|| {
+            for _ in range(0, n) {
                 port.recv();
                 chan.send(());
-            })
-        }
+            }
+        });
     }
 
-    m.times(|| {
+    for _ in range(0, m) {
         run_pair(n)
-    })
+    }
 }
 
 
index 6e3c42f2a4dea031194717995a7cfd31e626f7ae..59f5afa47dafd130151c709a82212d2065ffcb4a 100644 (file)
@@ -23,9 +23,9 @@ fn parfib(n: uint) -> uint {
     }
 
     let (port,chan) = Chan::new();
-    do spawn {
+    spawn(proc() {
         chan.send(parfib(n-1));
-    };
+    });
     let m2 = parfib(n-2);
     return (port.recv() + m2);
 }
index e057d6862e6a91685d02bda9e64c291973b9fd99..20ecee5499fdddde2e42a13f7a5c3b06bc1b1930 100644 (file)
@@ -26,8 +26,8 @@ fn main() {
         100000
     };
 
-    n.times(|| {
-        do spawn || {};
-    })
+    for _ in range(0, n) {
+        spawn(proc() {});
+    }
 
 }
index 7abbbdd278cff0a70eaaed680ee218a94f63e0b1..da658e6d041f734889810987f9973864b4443095 100644 (file)
@@ -9,10 +9,11 @@
 // except according to those terms.
 
 extern mod extra;
+extern mod arena;
 
 use std::iter::range_step;
 use extra::future::Future;
-use extra::arena::TypedArena;
+use arena::TypedArena;
 
 enum Tree<'a> {
     Nil,
@@ -64,7 +65,7 @@ fn main() {
     let mut messages = range_step(min_depth, max_depth + 1, 2).map(|depth| {
             use std::num::pow;
             let iterations = pow(2, (max_depth - depth + min_depth) as uint);
-            do Future::spawn {
+            Future::spawn(proc() {
                 let mut chk = 0;
                 for i in range(1, iterations + 1) {
                     let arena = TypedArena::new();
@@ -74,7 +75,7 @@ fn main() {
                 }
                 format!("{}\t trees of depth {}\t check: {}",
                         iterations * 2, depth, chk)
-            }
+            })
         }).to_owned_vec();
 
     for message in messages.mut_iter() {
index 2a5f7f0b87e98285c95444a62ea34337226ad2ed..7281667e6769a62a4c4ffcd16415cca3e11d3cf4 100644 (file)
@@ -152,13 +152,13 @@ fn rendezvous(nn: uint, set: ~[color]) {
             let to_rendezvous = to_rendezvous.clone();
             let to_rendezvous_log = to_rendezvous_log.clone();
             let (from_rendezvous, to_creature) = Chan::new();
-            do task::spawn {
+            task::spawn(proc() {
                 creature(ii,
                          col,
                          from_rendezvous,
                          to_rendezvous.clone(),
                          to_rendezvous_log.clone());
-            }
+            });
             to_creature
         }).collect();
 
index d0f91a358a70cc7c3e11c7ec000d315cad08030a..3719e76b30fc2dd0eaa47d51fb9d0df240966868 100644 (file)
@@ -56,7 +56,7 @@
     AminoAcid { c: 't' as u8, p: 0.3015094502008 },
 ];
 
-// XXX: Use map().
+// FIXME: Use map().
 fn sum_and_scale(a: &'static [AminoAcid]) -> ~[AminoAcid] {
     let mut result = ~[];
     let mut p = 0f32;
index 83eb1388c6b173f13fcf4cb1baf78c3576b5037f..375f9154841f4b73620c8bc27f718ebba4cb8472 100644 (file)
@@ -168,9 +168,9 @@ fn main() {
 
         let (from_parent, to_child) = Chan::new();
 
-        do spawn {
+        spawn(proc() {
             make_sequence_processor(sz, &from_parent, &to_parent_);
-        }
+        });
 
         to_child
     }).collect::<~[Chan<~[u8]>]>();
index 61e76b992830086668bac89431142a9aa19b1d88..94569dc5ac0a2fd785312d5c70f1930d2a0a8089 100644 (file)
@@ -49,7 +49,7 @@ fn pack(string: &str) -> Code {
         code
     }
 
-    // XXX: Inefficient.
+    // FIXME: Inefficient.
     fn unpack(&self, frame: i32) -> ~str {
         let mut key = **self;
         let mut result = ~[];
index 53d188962e849ee26b9e15f7db3bd9ed0c5124d4..c06f338f0186ad3349e985991577f0f419f4270d 100644 (file)
@@ -18,8 +18,8 @@ fn iterate<'a, T>(x: T, f: 'a |&T| -> T) -> Iterate<'a, T> {
     Iterate {f: f, next: x}
 }
 struct Iterate<'a, T> {
-    priv f: 'a |&T| -> T,
-    priv next: T
+    f: 'a |&T| -> T,
+    next: T
 }
 impl<'a, T> Iterator<T> for Iterate<'a, T> {
     fn next(&mut self) -> Option<T> {
@@ -35,7 +35,7 @@ enum List<'a, T> {
     Cons(T, &'a List<'a, T>)
 }
 struct ListIterator<'a, T> {
-    priv cur: &'a List<'a, T>
+    cur: &'a List<'a, T>
 }
 impl<'a, T> List<'a, T> {
     fn iter(&'a self) -> ListIterator<'a, T> {
index aa060ceb0973f1ab7c97ce64795b3516a324358c..040c8526ee04fdfedabfbe1b972c3638f86ca9df 100644 (file)
@@ -79,9 +79,9 @@ fn stress(num_tasks: int) {
     for i in range(0, num_tasks) {
         let mut builder = task::task();
         results.push(builder.future_result());
-        do builder.spawn {
+        builder.spawn(proc() {
             stress_task(i);
-        }
+        });
     }
     for r in results.iter() {
         r.recv();
index 8174347e3869e1fb38ee14ca546df91e4c3d8fc1..d68ca4e0abbae800980bb452569c70bec031621c 100644 (file)
@@ -41,13 +41,13 @@ fn mult(v: RWArc<~[f64]>, out: RWArc<~[f64]>, f: fn(&~[f64], uint) -> f64) {
         let w = wait.clone();
         let v = v.clone();
         let out = out.clone();
-        do spawn {
+        spawn(proc() {
             for i in range(chk, min(len, chk + chunk)) {
                 let val = v.read(|v| f(v, i));
                 out.write(|out| out[i] = val);
             }
             let _ = w;
-        }
+        });
     }
     let _ = wait.unwrap();
 }
index 862b047db22f464c81b219aa81e39a81d9007019..7063194eab862d43fb794209c509ccf3ddcb45d0 100644 (file)
@@ -23,17 +23,17 @@ fn start(n_tasks: int, token: int) {
         let (next_p, ch) = Chan::new();
         let imm_i = i;
         let imm_p = p;
-        do spawn {
+        spawn(proc() {
             roundtrip(imm_i, n_tasks, &imm_p, &ch);
-        };
+        });
         p = next_p;
         i += 1;
     }
     let imm_p = p;
     let imm_ch = ch1;
-    do spawn {
+    spawn(proc() {
         roundtrip(1, n_tasks, &imm_p, &imm_ch);
-    }
+    });
 }
 
 fn roundtrip(id: int, n_tasks: int, p: &Port<int>, ch: &Chan<int>) {
diff --git a/src/test/bench/silly-test-spawn.rs b/src/test/bench/silly-test-spawn.rs
new file mode 100644 (file)
index 0000000..16a9c03
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Useful smoketest for scheduler performance.
+fn main() {
+    for _ in range(1, 100_000) {
+        spawn(proc() {})
+    }
+}
diff --git a/src/test/bench/spawnone.rs b/src/test/bench/spawnone.rs
new file mode 100644 (file)
index 0000000..b55f471
--- /dev/null
@@ -0,0 +1,14 @@
+// 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.
+
+// Useful for checking syscall usage of baseline scheduler usage
+fn main() {
+    spawn(proc() {});
+}
index db46c3db439a7ef0508138d9a171df205b534d09..58fdadc2064da35485a61f74fb7a312883b13ee5 100644 (file)
@@ -34,9 +34,9 @@ fn main() {
 fn run(repeat: int, depth: int) {
     for _ in range(0, repeat) {
         info!("starting {:.4f}", precise_time_s());
-        do task::try {
+        task::try(proc() {
             recurse_or_fail(depth, None)
-        };
+        });
         info!("stopping {:.4f}", precise_time_s());
     }
 }
index dc31ef06fa6f20143f2b1dd8fbd0e19922d34ceb..b41f6bcc50ad85cb31d6a6f146e1c17a4760c8f3 100644 (file)
@@ -26,7 +26,7 @@ fn child_generation(gens_left: uint, c: comm::Chan<()>) {
     // This used to be O(n^2) in the number of generations that ever existed.
     // With this code, only as many generations are alive at a time as tasks
     // alive at a time,
-    do spawn {
+    spawn(proc() {
         if gens_left & 1 == 1 {
             task::deschedule(); // shake things up a bit
         }
@@ -35,7 +35,7 @@ fn child_generation(gens_left: uint, c: comm::Chan<()>) {
         } else {
             c.send(())
         }
-    }
+    });
 }
 
 fn main() {
index eb0e64268f351fece2d7215a7d99c67bc3ca3848..052900102c9a27f8a06c6e600335580b995bca79 100644 (file)
@@ -36,11 +36,11 @@ fn grandchild_group(num_tasks: uint) {
     for _ in range(0, num_tasks) {
         let ch = ch.clone();
         let mut t = task::task();
-        do t.spawn { // linked
+        t.spawn(proc() { // linked
             ch.send(());
             let (p, _c) = stream::<()>();
             p.recv(); // block forever
-        }
+        });
     }
     error!("Grandchild group getting started");
     for _ in range(0, num_tasks) {
@@ -77,17 +77,17 @@ fn main() {
     // Main group #0 waits for unsupervised group #1.
     // Grandparent group #1 waits for middle group #2, then fails, killing #3.
     // Middle group #2 creates grandchild_group #3, waits for it to be ready, exits.
-    let x: result::Result<(), ~Any> = do task::try { // unlinked
-        do spawn_supervised_blocking("grandparent") {
-            do spawn_supervised_blocking("middle") {
+    let x: result::Result<(), ~Any> = task::try(proc() { // unlinked
+        spawn_supervised_blocking("grandparent", proc() {
+            spawn_supervised_blocking("middle", proc() {
                 grandchild_group(num_tasks);
-            }
+            });
             // When grandchild group is ready to go, make the middle group exit.
             error!("Middle group wakes up and exits");
-        }
+        });
         // Grandparent group waits for middle group to be gone, then fails
         error!("Grandparent group wakes up and fails");
         fail!();
-    };
+    });
     assert!(x.is_err());
 }
index cdbec1784b98ebc2c7409894daaf15cebe3881d2..454c7e45cc163d9b0af20449579c408c623f76cc 100644 (file)
@@ -21,9 +21,9 @@ fn calc(children: uint, parent_wait_chan: &Chan<Chan<Chan<int>>>) {
 
     let wait_ports: ~[Port<Chan<Chan<int>>>] = vec::from_fn(children, |_| {
         let (wait_port, wait_chan) = stream::<Chan<Chan<int>>>();
-        do task::spawn {
+        task::spawn(proc() {
             calc(children / 2, &wait_chan);
-        }
+        });
         wait_port
     });
 
@@ -56,15 +56,15 @@ fn main() {
         args
     };
 
-    let children = from_str::<uint>(args[1]).get();
+    let children = from_str::<uint>(args[1]).unwrap();
     let (wait_port, wait_chan) = stream();
-    do task::spawn {
+    task::spawn(proc() {
         calc(children, &wait_chan);
-    };
+    });
 
     let start_chan = wait_port.recv();
     let (sum_port, sum_chan) = stream::<int>();
     start_chan.send(sum_chan);
     let sum = sum_port.recv();
-    error!("How many tasks? %d tasks.", sum);
+    error!("How many tasks? {} tasks.", sum);
 }
index 2fe2095ca879efd22bad0529c5d3dfbf97c57267..716dfe2c8b5c54e2b89af8f032d8615ac01fae77 100644 (file)
@@ -19,5 +19,5 @@ fn main() {
     });
     y.unwrap();
     // Adding this line causes a method unification failure instead
-    // do (&option::unwrap(y)).read |state| { assert!(*state == 1); }
+    // (&option::unwrap(y)).read(|state| { assert!(*state == 1); })
 }
index d9247ab4fc170d16c31a592be1e35132bb7ed5c6..213bf48a08750446aa6220ce09e65a24f71cc739 100644 (file)
@@ -17,5 +17,5 @@ fn main() {
     x.write_downgrade(|write_mode| y = Some(write_mode));
     y.unwrap();
     // Adding this line causes a method unification failure instead
-    // do (&option::unwrap(y)).write |state| { assert!(*state == 1); }
+    // (&option::unwrap(y)).write(|state| { assert!(*state == 1); })
 }
index 90d6147f0eda3416956c715d62251930a2cafd76..82eddf669af7af8d31140773f9a488e3888bd4e5 100644 (file)
@@ -29,9 +29,9 @@ fn new<U>(x: int, _: U) -> S2 {
 }
 
 fn foo<'a>() {
-    let _ = S::new::<int,f64>(1, 1.0);    //~ ERROR the impl referenced by this path has 1 type parameter, but 0 type parameters were supplied
+    let _ = S::new::<int,f64>(1, 1.0);    //~ ERROR the impl referenced by this path needs 1 type parameter, but 0 type parameters were supplied
     let _ = S::<'a,int>::new::<f64>(1, 1.0);  //~ ERROR expected 0 lifetime parameter(s)
-    let _: S2 = Trait::new::<int,f64>(1, 1.0);    //~ ERROR the trait referenced by this path has 1 type parameter, but 0 type parameters were supplied
+    let _: S2 = Trait::new::<int,f64>(1, 1.0);    //~ ERROR the trait referenced by this path needs 1 type parameter, but 0 type parameters were supplied
     let _: S2 = Trait::<'a,int>::new::<f64>(1, 1.0);   //~ ERROR expected 0 lifetime parameter(s)
 }
 
index c25f39a9d4329ec77f8c03f29627dfe6d5b4081a..4f0c71457b2c520536231c746e25c65e7fd96bd1 100644 (file)
@@ -39,9 +39,9 @@ fn block_overarching_alias_mut() {
 
     let mut v = ~3;
     let mut x = &mut v;
-    3.times(|| {
+    for _ in range(0, 3) {
         borrow(v); //~ ERROR cannot borrow
-    });
+    }
     *x = ~5;
 }
 
index c935c9deeac1ce3de65c51107473cf519dfbbcbb..c193288468a20ba3aa120c884469d332a2867b16 100644 (file)
@@ -17,10 +17,10 @@ fn borrow(v: &int, f: |x: &int|) {
 fn box_imm() {
     let v = ~3;
     let _w = &v;
-    do task::spawn {
+    task::spawn(proc() {
         info!("v={}", *v);
         //~^ ERROR cannot move `v` into closure
-    }
+    });
 
     let v = ~3;
     let _w = &v;
diff --git a/src/test/compile-fail/coerce-bare-fn-to-closure-and-proc.rs b/src/test/compile-fail/coerce-bare-fn-to-closure-and-proc.rs
new file mode 100644 (file)
index 0000000..c165802
--- /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.
+
+fn foo() {}
+
+fn main() {
+    let f = foo;
+    let f_closure: || = f;
+    //~^ ERROR: cannot coerce non-statically resolved bare fn
+    let f_proc: proc() = f;
+    //~^ ERROR: cannot coerce non-statically resolved bare fn
+}
diff --git a/src/test/compile-fail/deriving-field-span-enum-struct-variant.rs b/src/test/compile-fail/deriving-field-span-enum-struct-variant.rs
deleted file mode 100644 (file)
index 44b56e0..0000000
+++ /dev/null
@@ -1,23 +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.
-
-#[feature(struct_variant)];
-
-struct NotEq;
-
-#[deriving(Eq)]
-enum Foo {
-    Bar {
-        x: NotEq //~ ERROR mismatched types
-        //~^ ERROR failed to find an implementation of trait std::cmp::Eq for NotEq
-    }
-}
-
-pub fn main() {}
diff --git a/src/test/compile-fail/deriving-field-span-enum.rs b/src/test/compile-fail/deriving-field-span-enum.rs
deleted file mode 100644 (file)
index 8189744..0000000
+++ /dev/null
@@ -1,22 +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.
-
-#[feature(struct_variant)];
-
-struct NotEq;
-
-#[deriving(Eq)]
-enum Foo {
-    Bar(NotEq), //~ ERROR mismatched types
-        //~^ ERROR failed to find an implementation of trait std::cmp::Eq for NotEq
-    Baz { x: NotEq }
-}
-
-pub fn main() {}
diff --git a/src/test/compile-fail/deriving-field-span-struct.rs b/src/test/compile-fail/deriving-field-span-struct.rs
deleted file mode 100644 (file)
index 1add2cd..0000000
+++ /dev/null
@@ -1,19 +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.
-
-struct NotEq;
-
-#[deriving(Eq)]
-struct Foo {
-    x: NotEq //~ ERROR mismatched types
-        //~^ ERROR failed to find an implementation of trait std::cmp::Eq for NotEq
-}
-
-pub fn main() {}
diff --git a/src/test/compile-fail/deriving-field-span-tuple-struct.rs b/src/test/compile-fail/deriving-field-span-tuple-struct.rs
deleted file mode 100644 (file)
index 1f56e77..0000000
+++ /dev/null
@@ -1,19 +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.
-
-struct NotEq;
-
-#[deriving(Eq)]
-struct Foo (
-    NotEq //~ ERROR mismatched types
-        //~^ ERROR failed to find an implementation of trait std::cmp::Eq for NotEq
-        );
-
-pub fn main() {}
diff --git a/src/test/compile-fail/deriving-no-inner-impl-error-message.rs b/src/test/compile-fail/deriving-no-inner-impl-error-message.rs
new file mode 100644 (file)
index 0000000..604aa0d
--- /dev/null
@@ -0,0 +1,24 @@
+// 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 NoCloneOrEq;
+
+#[deriving(Eq)]
+struct E {
+    x: NoCloneOrEq //~ ERROR does not implement any method in scope named `eq`
+         //~^ ERROR does not implement any method in scope named `ne`
+}
+#[deriving(Clone)]
+struct C {
+    x: NoCloneOrEq //~ ERROR does not implement any method in scope named `clone`
+}
+
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-Clone-enum-struct-variant.rs b/src/test/compile-fail/deriving-span-Clone-enum-struct-variant.rs
new file mode 100644 (file)
index 0000000..983156f
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(Clone)]
+enum Enum {
+   A {
+     x: Error //~ ERROR
+   }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-Clone-enum.rs b/src/test/compile-fail/deriving-span-Clone-enum.rs
new file mode 100644 (file)
index 0000000..e5ceef8
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(Clone)]
+enum Enum {
+   A(
+     Error //~ ERROR
+     )
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-Clone-struct.rs b/src/test/compile-fail/deriving-span-Clone-struct.rs
new file mode 100644 (file)
index 0000000..fd763df
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(Clone)]
+struct Struct {
+    x: Error //~ ERROR
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-Clone-tuple-struct.rs b/src/test/compile-fail/deriving-span-Clone-tuple-struct.rs
new file mode 100644 (file)
index 0000000..d444c5e
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(Clone)]
+struct Struct(
+    Error //~ ERROR
+);
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-DeepClone-enum-struct-variant.rs b/src/test/compile-fail/deriving-span-DeepClone-enum-struct-variant.rs
new file mode 100644 (file)
index 0000000..0dc6266
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+#[deriving(Clone)]
+struct Error;
+
+#[deriving(DeepClone,Clone)]
+enum Enum {
+   A {
+     x: Error //~ ERROR
+   }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-DeepClone-enum.rs b/src/test/compile-fail/deriving-span-DeepClone-enum.rs
new file mode 100644 (file)
index 0000000..5b210d0
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+#[deriving(Clone)]
+struct Error;
+
+#[deriving(DeepClone,Clone)]
+enum Enum {
+   A(
+     Error //~ ERROR
+     )
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-DeepClone-struct.rs b/src/test/compile-fail/deriving-span-DeepClone-struct.rs
new file mode 100644 (file)
index 0000000..f063ed5
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+#[deriving(Clone)]
+struct Error;
+
+#[deriving(DeepClone,Clone)]
+struct Struct {
+    x: Error //~ ERROR
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-DeepClone-tuple-struct.rs b/src/test/compile-fail/deriving-span-DeepClone-tuple-struct.rs
new file mode 100644 (file)
index 0000000..1b05389
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+#[deriving(Clone)]
+struct Error;
+
+#[deriving(DeepClone,Clone)]
+struct Struct(
+    Error //~ ERROR
+);
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-Default-struct.rs b/src/test/compile-fail/deriving-span-Default-struct.rs
new file mode 100644 (file)
index 0000000..7c2edd8
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(Default)]
+struct Struct {
+    x: Error //~ ERROR
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-Default-tuple-struct.rs b/src/test/compile-fail/deriving-span-Default-tuple-struct.rs
new file mode 100644 (file)
index 0000000..e0269a6
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(Default)]
+struct Struct(
+    Error //~ ERROR
+);
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-Eq-enum-struct-variant.rs b/src/test/compile-fail/deriving-span-Eq-enum-struct-variant.rs
new file mode 100644 (file)
index 0000000..abedb3e
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(Eq)]
+enum Enum {
+   A {
+     x: Error //~ ERROR
+//~^ ERROR
+   }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-Eq-enum.rs b/src/test/compile-fail/deriving-span-Eq-enum.rs
new file mode 100644 (file)
index 0000000..3486d96
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(Eq)]
+enum Enum {
+   A(
+     Error //~ ERROR
+//~^ ERROR
+     )
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-Eq-struct.rs b/src/test/compile-fail/deriving-span-Eq-struct.rs
new file mode 100644 (file)
index 0000000..32d2e78
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(Eq)]
+struct Struct {
+    x: Error //~ ERROR
+//~^ ERROR
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-Eq-tuple-struct.rs b/src/test/compile-fail/deriving-span-Eq-tuple-struct.rs
new file mode 100644 (file)
index 0000000..acc46a1
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(Eq)]
+struct Struct(
+    Error //~ ERROR
+//~^ ERROR
+);
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-Ord-enum-struct-variant.rs b/src/test/compile-fail/deriving-span-Ord-enum-struct-variant.rs
new file mode 100644 (file)
index 0000000..933da41
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(Ord)]
+enum Enum {
+   A {
+     x: Error //~ ERROR
+//~^ ERROR
+//~^^ ERROR
+//~^^^ ERROR
+//~^^^^ ERROR
+//~^^^^^ ERROR
+//~^^^^^^ ERROR
+//~^^^^^^^ ERROR
+   }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-Ord-enum.rs b/src/test/compile-fail/deriving-span-Ord-enum.rs
new file mode 100644 (file)
index 0000000..c310965
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(Ord)]
+enum Enum {
+   A(
+     Error //~ ERROR
+//~^ ERROR
+//~^^ ERROR
+//~^^^ ERROR
+//~^^^^ ERROR
+//~^^^^^ ERROR
+//~^^^^^^ ERROR
+//~^^^^^^^ ERROR
+     )
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-Ord-struct.rs b/src/test/compile-fail/deriving-span-Ord-struct.rs
new file mode 100644 (file)
index 0000000..327ac73
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(Ord)]
+struct Struct {
+    x: Error //~ ERROR
+//~^ ERROR
+//~^^ ERROR
+//~^^^ ERROR
+//~^^^^ ERROR
+//~^^^^^ ERROR
+//~^^^^^^ ERROR
+//~^^^^^^^ ERROR
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-Ord-tuple-struct.rs b/src/test/compile-fail/deriving-span-Ord-tuple-struct.rs
new file mode 100644 (file)
index 0000000..2a482f8
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(Ord)]
+struct Struct(
+    Error //~ ERROR
+//~^ ERROR
+//~^^ ERROR
+//~^^^ ERROR
+//~^^^^ ERROR
+//~^^^^^ ERROR
+//~^^^^^^ ERROR
+//~^^^^^^^ ERROR
+);
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-Rand-enum-struct-variant.rs b/src/test/compile-fail/deriving-span-Rand-enum-struct-variant.rs
new file mode 100644 (file)
index 0000000..ae0732e
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(Rand)]
+enum Enum {
+   A {
+     x: Error //~ ERROR
+   }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-Rand-enum.rs b/src/test/compile-fail/deriving-span-Rand-enum.rs
new file mode 100644 (file)
index 0000000..ef29ce0
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(Rand)]
+enum Enum {
+   A(
+     Error //~ ERROR
+     )
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-Rand-struct.rs b/src/test/compile-fail/deriving-span-Rand-struct.rs
new file mode 100644 (file)
index 0000000..2ce4d49
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(Rand)]
+struct Struct {
+    x: Error //~ ERROR
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-Rand-tuple-struct.rs b/src/test/compile-fail/deriving-span-Rand-tuple-struct.rs
new file mode 100644 (file)
index 0000000..3f6738f
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(Rand)]
+struct Struct(
+    Error //~ ERROR
+);
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-TotalEq-enum-struct-variant.rs b/src/test/compile-fail/deriving-span-TotalEq-enum-struct-variant.rs
new file mode 100644 (file)
index 0000000..8e55609
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(TotalEq)]
+enum Enum {
+   A {
+     x: Error //~ ERROR
+   }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-TotalEq-enum.rs b/src/test/compile-fail/deriving-span-TotalEq-enum.rs
new file mode 100644 (file)
index 0000000..968f042
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(TotalEq)]
+enum Enum {
+   A(
+     Error //~ ERROR
+     )
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-TotalEq-struct.rs b/src/test/compile-fail/deriving-span-TotalEq-struct.rs
new file mode 100644 (file)
index 0000000..8c53d11
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(TotalEq)]
+struct Struct {
+    x: Error //~ ERROR
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-TotalEq-tuple-struct.rs b/src/test/compile-fail/deriving-span-TotalEq-tuple-struct.rs
new file mode 100644 (file)
index 0000000..16d4995
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(TotalEq)]
+struct Struct(
+    Error //~ ERROR
+);
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-TotalOrd-enum-struct-variant.rs b/src/test/compile-fail/deriving-span-TotalOrd-enum-struct-variant.rs
new file mode 100644 (file)
index 0000000..fe59890
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+#[deriving(TotalEq)]
+struct Error;
+
+#[deriving(TotalOrd,TotalEq)]
+enum Enum {
+   A {
+     x: Error //~ ERROR
+   }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-TotalOrd-enum.rs b/src/test/compile-fail/deriving-span-TotalOrd-enum.rs
new file mode 100644 (file)
index 0000000..6bccd22
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+#[deriving(TotalEq)]
+struct Error;
+
+#[deriving(TotalOrd,TotalEq)]
+enum Enum {
+   A(
+     Error //~ ERROR
+     )
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-TotalOrd-struct.rs b/src/test/compile-fail/deriving-span-TotalOrd-struct.rs
new file mode 100644 (file)
index 0000000..4ff4882
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+#[deriving(TotalEq)]
+struct Error;
+
+#[deriving(TotalOrd,TotalEq)]
+struct Struct {
+    x: Error //~ ERROR
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-TotalOrd-tuple-struct.rs b/src/test/compile-fail/deriving-span-TotalOrd-tuple-struct.rs
new file mode 100644 (file)
index 0000000..08e2c9b
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+#[deriving(TotalEq)]
+struct Error;
+
+#[deriving(TotalOrd,TotalEq)]
+struct Struct(
+    Error //~ ERROR
+);
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-Zero-struct.rs b/src/test/compile-fail/deriving-span-Zero-struct.rs
new file mode 100644 (file)
index 0000000..2892938
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(Zero)]
+struct Struct {
+    x: Error //~ ERROR
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/deriving-span-Zero-tuple-struct.rs b/src/test/compile-fail/deriving-span-Zero-tuple-struct.rs
new file mode 100644 (file)
index 0000000..43d84a5
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py'
+
+#[feature(struct_variant)];
+extern mod extra;
+
+
+struct Error;
+
+#[deriving(Zero)]
+struct Struct(
+    Error //~ ERROR
+);
+
+fn main() {}
diff --git a/src/test/compile-fail/do-lambda-requires-braces.rs b/src/test/compile-fail/do-lambda-requires-braces.rs
deleted file mode 100644 (file)
index a836556..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    do something
-        |x| do somethingelse //~ ERROR: expected `{` but found `do`
-        |y| say(x, y)
-}
diff --git a/src/test/compile-fail/do1.rs b/src/test/compile-fail/do1.rs
deleted file mode 100644 (file)
index d16fa4e..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    let x = do y; //~ ERROR: expected `{` but found
-}
diff --git a/src/test/compile-fail/do2.rs b/src/test/compile-fail/do2.rs
deleted file mode 100644 (file)
index 309abe2..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn f(f: proc(int) -> bool) -> bool { f(10i) }
-
-fn main() {
-    assert!(do f() |i| { i == 10i } == 10i);
-    //~^ ERROR: expected `bool` but found `int`
-}
diff --git a/src/test/compile-fail/gated-default-type-params.rs b/src/test/compile-fail/gated-default-type-params.rs
new file mode 100644 (file)
index 0000000..65575d4
--- /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.
+
+struct Heap;
+
+struct Vec<T, A = Heap>; //~ ERROR: default type parameters are experimental
+
+fn main() {}
diff --git a/src/test/compile-fail/gated-simd.rs b/src/test/compile-fail/gated-simd.rs
new file mode 100644 (file)
index 0000000..a000b91
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[simd]
+pub struct i64x2(i64, i64); //~ ERROR: SIMD types are experimental
+
+fn main() {}
\ No newline at end of file
diff --git a/src/test/compile-fail/gated-trace_macros.rs b/src/test/compile-fail/gated-trace_macros.rs
new file mode 100644 (file)
index 0000000..3e4a8a7
--- /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.
+
+// xfail-fast feature doesn't work.
+
+fn main() {
+    trace_macros!(true); //~ ERROR: `trace_macros` is not stable
+}
diff --git a/src/test/compile-fail/generic-impl-less-params-with-defaults.rs b/src/test/compile-fail/generic-impl-less-params-with-defaults.rs
new file mode 100644 (file)
index 0000000..28e7a37
--- /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.
+
+#[feature(default_type_params)];
+
+struct Foo<A, B, C = (A, B)>;
+
+impl<A, B, C = (A, B)> Foo<A, B, C> {
+    fn new() -> Foo<A, B, C> {Foo}
+}
+
+fn main() {
+    Foo::<int>::new(); //~ ERROR the impl referenced by this path needs at least 2 type parameters, but 1 type parameter were supplied
+    //~^ ERROR not enough type parameters provided: expected at least 2, found 1
+}
diff --git a/src/test/compile-fail/generic-impl-more-params-with-defaults.rs b/src/test/compile-fail/generic-impl-more-params-with-defaults.rs
new file mode 100644 (file)
index 0000000..1040468
--- /dev/null
@@ -0,0 +1,24 @@
+// 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(default_type_params)];
+
+struct Heap;
+
+struct Vec<T, A = Heap>;
+
+impl<T, A = Heap> Vec<T, A> {
+    fn new() -> Vec<T, A> {Vec}
+}
+
+fn main() {
+    Vec::<int, Heap, bool>::new(); //~ ERROR the impl referenced by this path needs at most 2 type parameters, but 3 type parameters were supplied
+    //~^ ERROR too many type parameters provided: expected at most 2, found 3
+}
diff --git a/src/test/compile-fail/generic-non-trailing-defaults.rs b/src/test/compile-fail/generic-non-trailing-defaults.rs
new file mode 100644 (file)
index 0000000..a70a529
--- /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(default_type_params)];
+
+struct Heap;
+
+struct Vec<A = Heap, T>; //~ ERROR type parameters with a default must be trailing
+
+struct Foo<A, B = Vec<C>, C>; //~ ERROR type parameters with a default must be trailing
+
+fn main() {}
diff --git a/src/test/compile-fail/generic-type-less-params-with-defaults.rs b/src/test/compile-fail/generic-type-less-params-with-defaults.rs
new file mode 100644 (file)
index 0000000..c5badee
--- /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(default_type_params)];
+
+struct Heap;
+
+struct Vec<T, A = Heap>;
+
+fn main() {
+    let _: Vec; //~ ERROR wrong number of type arguments: expected at least 1 but found 0
+}
diff --git a/src/test/compile-fail/generic-type-more-params-with-defaults.rs b/src/test/compile-fail/generic-type-more-params-with-defaults.rs
new file mode 100644 (file)
index 0000000..65c0d09
--- /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(default_type_params)];
+
+struct Heap;
+
+struct Vec<T, A = Heap>;
+
+fn main() {
+    let _: Vec<int, Heap, bool>; //~ ERROR wrong number of type arguments: expected at most 2 but found 3
+}
diff --git a/src/test/compile-fail/generic-type-params-name-repr.rs b/src/test/compile-fail/generic-type-params-name-repr.rs
new file mode 100644 (file)
index 0000000..59e6ba8
--- /dev/null
@@ -0,0 +1,34 @@
+// 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(default_type_params)];
+
+struct A;
+struct B;
+struct C;
+struct Foo<T = A, U = B, V = C>;
+
+fn main() {
+    // Ensure that the printed type doesn't include the default type params...
+    let _: Foo<int> = ();
+    //~^ ERROR mismatched types: expected `Foo<int>` but found `()`
+
+    // ...even when they're present, but the same types as the defaults.
+    let _: Foo<int, B, C> = ();
+    //~^ ERROR mismatched types: expected `Foo<int>` but found `()`
+
+    // But not when there's a different type in between.
+    let _: Foo<A, int, C> = ();
+    //~^ ERROR mismatched types: expected `Foo<A,int>` but found `()`
+
+    // And don't print <> at all when there's just defaults.
+    let _: Foo<A, B, C> = ();
+    //~^ ERROR mismatched types: expected `Foo` but found `()`
+}
index 7946510c45903b4b24b122c499c49e4d84974e5a..06a4088617a2bec5065b6f5f411dcf7b2c0daefc 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 fn main() {
-    let _f = 10.times; //~ ERROR attempted to take value of method
+    let _f = 10i.abs; //~ ERROR attempted to take value of method
 }
diff --git a/src/test/compile-fail/issue-3008-1.rs b/src/test/compile-fail/issue-3008-1.rs
new file mode 100644 (file)
index 0000000..6d8dec6
--- /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.
+
+enum foo { foo(bar) }
+enum bar { bar_none, bar_some(bar) } //~ ERROR illegal recursive enum type; wrap the inner value in a box to make it representable
+
+fn main() {
+}
diff --git a/src/test/compile-fail/issue-3008-2.rs b/src/test/compile-fail/issue-3008-2.rs
new file mode 100644 (file)
index 0000000..88ebf61
--- /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.
+
+enum foo { foo(bar) }
+struct bar { x: bar } //~ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable
+//~^ ERROR this type cannot be instantiated without an instance of itself
+
+fn main() {
+}
+
diff --git a/src/test/compile-fail/issue-3008-3.rs b/src/test/compile-fail/issue-3008-3.rs
new file mode 100644 (file)
index 0000000..8680ee8
--- /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.
+
+enum E1 { V1(E2<E1>), }
+enum E2<T> { V2(E2<E1>), } //~ ERROR illegal recursive enum type; wrap the inner value in a box to make it representable
+
+fn main() {
+}
index 310de3657b385e06bc2b7177cd20c85aa7d3d8a2..5fab2ed195cecdd0a1cd469effa23a82d48b2321 100644 (file)
@@ -10,9 +10,9 @@
 
 fn main() {
     let needlesArr: ~[char] = ~['a', 'f'];
-    do needlesArr.iter().fold() |x, y| {
-    }
-    //~^^ ERROR 1 parameter was supplied (including the closure passed by the `do` keyword)
+    needlesArr.iter().fold(|x, y| {
+    });
+    //~^^ ERROR this function takes 2 parameters but 1 parameter was supplied
     //
     // the first error is, um, non-ideal.
 }
diff --git a/src/test/compile-fail/issue-3243.rs b/src/test/compile-fail/issue-3243.rs
deleted file mode 100644 (file)
index f235c4b..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// xfail-test
-fn function() -> &mut [int] {
-    let mut x: &'static mut [int] = &[1,2,3];
-    x[0] = 12345;
-    x //~ ERROR bad
-}
-
-fn main() {
-    let x = function();
-    error!("%?", x);
-}
diff --git a/src/test/compile-fail/issue-3779.rs b/src/test/compile-fail/issue-3779.rs
new file mode 100644 (file)
index 0000000..7936059
--- /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.
+
+struct S { //~ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable
+    element: Option<S>
+}
+
+fn main() {
+    let x = S { element: None };
+}
diff --git a/src/test/compile-fail/issue-511.rs b/src/test/compile-fail/issue-511.rs
deleted file mode 100644 (file)
index ed2eede..0000000
+++ /dev/null
@@ -1,21 +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.
-
-extern mod extra;
-use std::cmp::Eq;
-
-fn f<T:Eq>(o: &mut Option<T>) {
-    assert!(*o == None);
-}
-
-fn main() {
-    f::<int>(&mut None);
-    //~^ ERROR cannot borrow
-}
index bffca995b8e3a7116cdddb6573855868eca23891..2c1809d4d4886f45c25a7f5ff87a679d10eeaa17 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
 struct A;
 impl A {
     fn m(&self) {
-          fn x() {
-              self.m()
-              //~^ ERROR can't capture dynamic environment in a fn item
-              //~^^ ERROR `self` is not allowed in this context
-          }
+        fn x() {
+            self.m() //~ ERROR can't capture dynamic environment in a fn item
+            //~^ ERROR unresolved name `self`
+        }
     }
 }
 fn main() {}
diff --git a/src/test/compile-fail/keyword-do-as-identifier.rs b/src/test/compile-fail/keyword-do-as-identifier.rs
deleted file mode 100644 (file)
index b2a0c8a..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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py do'
-
-fn main() {
-    let do = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/kindck-implicit-close-over-mut-var.rs b/src/test/compile-fail/kindck-implicit-close-over-mut-var.rs
deleted file mode 100644 (file)
index b210633..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::task;
-
-fn user(_i: int) {}
-
-fn foo() {
-    // Here, i is *moved* into the closure: Not actually OK
-    let mut i = 0;
-    do task::spawn {
-        user(i); //~ ERROR mutable variables cannot be implicitly captured
-    }
-}
-
-fn bar() {
-    // Here, i would be implicitly *copied* but it
-    // is mutable: bad
-    let mut i = 0;
-    while i < 10 {
-        do task::spawn {
-            user(i); //~ ERROR mutable variables cannot be implicitly captured
-        }
-        i += 1;
-    }
-}
-
-fn car() {
-    // Here, i is mutable, but *explicitly* shadowed copied:
-    let mut i = 0;
-    while i < 10 {
-        {
-            let i = i;
-            do task::spawn {
-                user(i);
-            }
-        }
-        i += 1;
-    }
-}
-
-fn main() {
-}
diff --git a/src/test/compile-fail/lint-default-type-param-usage.rs b/src/test/compile-fail/lint-default-type-param-usage.rs
new file mode 100644 (file)
index 0000000..e8cacb0
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[feature(default_type_params)];
+
+#[deny(default_type_param_usage)];
+
+pub struct Heap;
+
+pub struct Vec<T, A = Heap>;
+
+pub struct FooAlloc;
+
+pub type VecFoo<T> = Vec<T, FooAlloc>; //~ ERROR provided type arguments with defaults
+
+fn main() {}
index a6440e67f9bebfb56336fef83eeeca563d52b69d..9d640647fe08b9c1b8cd03dff8c9a5abbebf80e1 100644 (file)
@@ -20,7 +20,7 @@
 
 struct Foo {
     a: int,
-    priv b: int,
+    b: int,
 }
 
 pub struct PubFoo { //~ ERROR: missing documentation
@@ -99,7 +99,7 @@ pub fn baz() {}
 enum Baz {
     BazA {
         a: int,
-        priv b: int
+        b: int
     },
     BarB
 }
index ceec1ae3d8a3f0ccf4459d435410d47fbc9012b6..ee683d4de46867ceafa0f8ca820b9118085cbc6a 100644 (file)
@@ -22,7 +22,7 @@ mod cross_crate {
     use self::lint_stability::*;
 
     fn test() {
-        // XXX: attributes on methods are not encoded cross crate.
+        // FIXME: attributes on methods are not encoded cross crate.
         let foo = MethodTester;
 
         deprecated(); //~ ERROR use of deprecated item
diff --git a/src/test/compile-fail/lint-unused-mut-self.rs b/src/test/compile-fail/lint-unused-mut-self.rs
new file mode 100644 (file)
index 0000000..ada534f
--- /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.
+
+#[allow(dead_assignment)];
+#[allow(unused_variable)];
+#[allow(dead_code)];
+#[deny(unused_mut)];
+
+struct Foo;
+impl Foo {
+    fn foo(mut self) {} //~ ERROR: variable does not need to be mutable
+    fn bar(mut ~self) {} //~ ERROR: variable does not need to be mutable
+}
+
+fn main() {}
index 475faa75704623de19d9851d82b9f4a3f00bcf7a..effab305c1a601708475d182f79db70af0aa2ba4 100644 (file)
@@ -12,6 +12,7 @@
 // immediately, so that we get more errors listed at a time.
 
 #[feature(asm)];
+#[feature(trace_macros)];
 
 #[deriving(Default, //~ ERROR
            Rand, //~ ERROR
index dd68cb8e994e93a1ecf7f0cbb76e6508267bc0df..fe9c7ede83a0883e75c40fb38210e7ac907da88e 100644 (file)
@@ -2,8 +2,8 @@
 
 fn main() {
     let x = ~"Hello world!";
-    do task::spawn {
+    task::spawn(proc() {
         println!("{}", x);
-    }
+    });
     println!("{}", x); //~ ERROR use of moved value
 }
index 30c2b9eef8ca00e24dc2fb8a6086db05225d66a9..377c745acf3215df50425b091abcc429bbad6de6 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 struct cat {
-  priv meows : uint,
+  meows : uint,
 
   how_hungry : int,
 }
index a88156a4b477d66cb1e311c50448bb870f22c047..4d77d1824ab825b25b51c2d9cd1593bc4c10bf03 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 struct cat {
-  priv meows : uint,
+  meows : uint,
   how_hungry : int,
 }
 
index 476b890efcd6b8618aef8963dfd8dcf544be7952..24a141c4799d520708ea88020c67da576935e005 100644 (file)
@@ -17,10 +17,10 @@ fn test_mutex_arc_nested() {
     let arc = ~MutexArc::new(1);
     let arc2 = ~MutexArc::new(*arc);
 
-    do task::spawn || {
+    task::spawn(proc() {
         (*arc2).access(|mutex| { //~ ERROR instantiating a type parameter with an incompatible type
         })
-    };
+    });
 }
 
 fn main() {}
index 65e0c07b3580e127ee8edfd6baa96d30b4cf10aa..5ae38e69ec0e30c52ba492dec58694705566a3c2 100644 (file)
@@ -19,10 +19,10 @@ fn main() {
     let v = ~[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
     let arc_v = arc::Arc::new(v);
 
-    do task::spawn() {
+    task::spawn(proc() {
         let v = arc_v.get();
         assert_eq!(v[3], 4);
-    };
+    });
 
     assert_eq!((arc_v.get())[2], 3);
 
index 3cd048040c6f5647e5b7d56b8fc6bc978ebdd7dd..c6c0ba41ab91a45ba21e0fb8af43b6566b61e662 100644 (file)
@@ -17,10 +17,10 @@ fn main() {
     let v = ~[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
     let arc_v = arc::Arc::new(v);
 
-    do task::spawn() {
+    task::spawn(proc() {
         let v = arc_v.get();
         assert_eq!(v[3], 4);
-    };
+    });
 
     assert_eq!((arc_v.get())[2], 3); //~ ERROR use of moved value: `arc_v`
 
index 87173d779240f9c4f55f9eb348b1400d076c6319..9e564e997e6739c91245e0f775d78f3f68be3788 100644 (file)
@@ -32,8 +32,8 @@ fn foo(x: Port<()>) -> foo {
 
     let x = foo(Port(@()));
 
-    do task::spawn {
+    task::spawn(proc() {
         let y = x;   //~ ERROR does not fulfill `Send`
         error!("{:?}", y);
-    }
+    });
 }
index e2220355980e76421474b832380df148b6ab842c..8d5e2229b2e5dc0a10d99eb772db3c6aba21af20 100644 (file)
@@ -22,8 +22,8 @@ fn foo(blk: proc()) {
 
 fn main() {
     let x = arc::Arc::new(true);
-    do foo {
+    foo(proc() {
         assert!(*x.get());
         drop(x);
-    }
+    });
 }
diff --git a/src/test/compile-fail/regions-lifetime-of-struct-or-enum-variant.rs b/src/test/compile-fail/regions-lifetime-of-struct-or-enum-variant.rs
new file mode 100644 (file)
index 0000000..c266952
--- /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.
+
+// This tests verifies that unary structs and enum variants
+// are treated as rvalues and their lifetime is not bounded to
+// the static scope.
+
+struct Test;
+
+enum MyEnum {
+    Variant1
+}
+
+fn structLifetime() -> &Test {
+  let testValue = &Test; //~ ERROR borrowed value does not live long enough
+  testValue
+}
+
+fn variantLifetime() -> &MyEnum {
+  let testValue = &Variant1; //~ ERROR borrowed value does not live long enough
+  testValue
+}
+
+
+fn main() {}
diff --git a/src/test/compile-fail/regions-return-stack-allocated-vec.rs b/src/test/compile-fail/regions-return-stack-allocated-vec.rs
new file mode 100644 (file)
index 0000000..b5f4fca
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+
+// Test that we cannot return a stack allocated slice
+
+fn function(x: int) -> &'static [int] {
+    &[x] //~ ERROR mismatched types
+}
+
+fn main() {
+    let x = function(1);
+    let y = x[0];
+}
diff --git a/src/test/compile-fail/simd-experimental.rs b/src/test/compile-fail/simd-experimental.rs
new file mode 100644 (file)
index 0000000..2ed4317
--- /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.
+
+// xfail-test FIXME #11741 tuple structs ignore stability attributes
+
+#[deny(experimental)];
+
+use std::unstable::simd;
+
+fn main() {
+    let _ = simd::i64x2(0, 0); //~ ERROR: experimental
+}
index 8387b2bc723faf91c83f45c2478cfe4d3b8f0185..266c2a9c4537244dd959984af825a20636ef1c2d 100644 (file)
@@ -1,3 +1,5 @@
+#[feature(simd)];
+
 #[simd]
 struct vec4<T>(T, T, T, T); //~ ERROR SIMD vector cannot be generic
 
diff --git a/src/test/compile-fail/struct-field-privacy.rs b/src/test/compile-fail/struct-field-privacy.rs
new file mode 100644 (file)
index 0000000..f316900
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:struct-field-privacy.rs
+
+extern mod xc = "struct-field-privacy";
+
+struct A {
+    a: int,
+}
+
+mod inner {
+    struct A {
+        a: int,
+        pub b: int,
+        priv c: int, //~ ERROR: unnecessary `priv` visibility
+    }
+    pub struct B {
+        a: int,
+        priv b: int,
+        pub c: int, //~ ERROR: unnecessary `pub` visibility
+    }
+}
+
+fn test(a: A, b: inner::A, c: inner::B, d: xc::A, e: xc::B) {
+    //~^ ERROR: type `A` is private
+    //~^^ ERROR: struct `A` is private
+
+    a.a;
+    b.a; //~ ERROR: field `a` is private
+    b.b;
+    b.c; //~ ERROR: field `c` is private
+    c.a;
+    c.b; //~ ERROR: field `b` is private
+    c.c;
+
+    d.a; //~ ERROR: field `a` is private
+    d.b;
+
+    e.a;
+    e.b; //~ ERROR: field `b` is private
+}
+
+fn main() {}
index e71dfc588161fbcf7404c8d3062f85f7c50ba112..0078841acb139b54a3a1c6c59c915ce4c20670be 100644 (file)
@@ -18,5 +18,5 @@ fn main() {
         y = Some(x.downgrade(write_mode));
     })
     // Adding this line causes a method unification failure instead
-    // do (&option::unwrap(y)).read { }
+    // (&option::unwrap(y)).read(proc() { });
 }
index af0149182aeba1b8b5a81fe8fe973ce380773a3c..6e9216830750b1d729d119a8ea32370860b14f6e 100644 (file)
@@ -18,5 +18,5 @@ fn main() {
         y = Some(write_mode);
     });
     // Adding this line causes a method unification failure instead
-    // do (&option::unwrap(y)).write { }
+    // (&option::unwrap(y)).write(proc() { })
 }
index ebd3320d901269871fee00554297ba856e05e229..0fc3b3912b17b39123083d59349efe3db807a4ee 100644 (file)
@@ -11,9 +11,7 @@
 // error-pattern:mismatched types: expected `char` but found
 // Issue #876
 
-#[no_std];
-
-extern mod std;
+#[no_implicit_prelude];
 
 fn last<T>(v: ~[&T]) -> std::option::Option<T> {
     fail!();
index f293644840a1cec7d911a68ba7cc33b36b185529..ea2062dd2720985aba0cdf0094a14db896a72c1c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -13,7 +13,7 @@ trait foo {
 }
 impl foo for int {
     fn bar(&self) -> int {
-        //~^ ERROR method `bar` has 0 parameters but the declaration in trait `foo::bar` has 1
+        //~^ ERROR method `bar` has 1 parameter but the declaration in trait `foo::bar` has 2
         *self
     }
 }
diff --git a/src/test/compile-fail/unused-result.rs b/src/test/compile-fail/unused-result.rs
new file mode 100644 (file)
index 0000000..eaf4d7d
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[deny(unused_result, unused_must_use)];
+#[allow(dead_code)];
+
+#[must_use]
+enum MustUse { Test }
+
+fn foo<T>() -> T { fail!() }
+
+fn bar() -> int { return foo::<int>(); }
+fn baz() -> MustUse { return foo::<MustUse>(); }
+
+#[allow(unused_result)]
+fn test() {
+    foo::<int>();
+    foo::<MustUse>(); //~ ERROR: unused result which must be used
+}
+
+#[allow(unused_result, unused_must_use)]
+fn test2() {
+    foo::<int>();
+    foo::<MustUse>();
+}
+
+fn main() {
+    foo::<int>(); //~ ERROR: unused result
+    foo::<MustUse>(); //~ ERROR: unused result which must be used
+
+    let _ = foo::<int>();
+    let _ = foo::<MustUse>();
+}
index 3d6841c919a4d2aa6903f7e334a39ce2a55d04ba..5a4dd42f49d3d892942f81b25e495c893a973e73 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct A { pub i: int }         //~ ERROR: unnecessary `pub`
-struct B { priv i: int }        // don't warn b/c B can still be returned
+struct A { pub i: int }
+struct B { priv i: int }        //~ ERROR: unnecessary `priv`
 pub enum C { pub Variant }      //~ ERROR: unnecessary `pub`
 enum D { priv Variant2 }        //~ ERROR: unnecessary `priv`
 
index 4d940c91d2a4cb5db8a285e6c9471c124200df20..da2d4e09fc67f1521cc64ebcc221afa058ff7470 100644 (file)
@@ -244,6 +244,3 @@ fn main() {
     while_expr(40, 41, 42);
     loop_expr(43, 44, 45);
 }
-
-
-
diff --git a/src/test/debug-info/issue11600.rs b/src/test/debug-info/issue11600.rs
new file mode 100644 (file)
index 0000000..425aff8
--- /dev/null
@@ -0,0 +1,27 @@
+fn main() {
+    let args : ~[~str] = ::std::os::args();
+    ::std::io::println(args[0]);
+}
+
+
+// xfail-android: FIXME(#10381)
+
+// This test case checks whether compile unit names are set correctly, so that the correct default
+// source file can be found.
+
+// compile-flags:-Z extra-debug-info
+// debugger:list
+// check:1[...]fn main() {
+// check:2[...]let args : ~[~str] = ::std::os::args();
+// check:3[...]::std::io::println(args[0]);
+// check:4[...]}
+
+// 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.
index faced3531f582eb33550c38932546a4dded15868..be4ad0781f272f9ee40110772d5b1b79000ca3e9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
 
 // error-pattern:index out of bounds: the len is 3 but the index is
 
-use std::uint::max_value;
+use std::uint;
 use std::mem::size_of;
 
 fn main() {
     let xs = [1, 2, 3];
-    xs[max_value / size_of::<int>() + 1];
+    xs[uint::MAX / size_of::<int>() + 1];
 }
index fa8cd005c04567b3fdb36171e1e1829489d29e56..60f3dd9b277f33d3b33562c69fd6aba72080ce9e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -21,7 +21,7 @@ fn main() {
     // length (in bytes), because the scaling of the index will cause it to
     // wrap around to a small number.
 
-    let idx = uint::max_value & !(uint::max_value >> 1u);
+    let idx = uint::MAX & !(uint::MAX >> 1u);
     error!("ov2 idx = 0x%x", idx);
 
     // This should fail.
index 2a5b45435765903e7badfee4404530917e37559f..62c4c5c735a223f5756369c1746874ef03568221 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -23,7 +23,7 @@ fn main() {
 
     // This test is only meaningful on 32-bit hosts.
 
-    let idx = u64::max_value & !(u64::max_value >> 1u);
+    let idx = u64::MAX & !(u64::MAX >> 1u);
     error!("ov3 idx = 0x%8.8x%8.8x",
            (idx >> 32) as uint,
            idx as uint);
index ce5ea56502cc7bb1bdefe63bfb41958110e3001b..0f97db18a1f3705727211a38f33ae35d3bdfac5a 100644 (file)
@@ -41,11 +41,11 @@ fn count(n: uint) -> uint {
 }
 
 fn main() {
-    do 10u.times {
-        do task::spawn {
+    for _ in range(0, 10u) {
+        task::spawn(proc() {
             let result = count(5u);
             info!("result = %?", result);
             fail!();
-        };
+        });
     }
 }
index 9d58c1820087631da317e5c22b10a54d2f070ec0..3f662e6d0e3e4ca673d4203253405ee42e9dc236 100644 (file)
@@ -13,8 +13,8 @@
 use std::task;
 
 fn main() {
-    do task::try {
+    task::try(proc() {
         fail!("test");
         1
-    }.unwrap()
+    }).unwrap()
 }
index 9e87b59db64940216aac261d0c161e4d7988dfd3..a1115a09fb1765d08fa2742a9c9dfe1acab04e15 100644 (file)
@@ -15,8 +15,8 @@
 fn main() {
     let mut t = task::task();
     t.name(~"owned name");
-    do t.try {
+    t.try(proc() {
         fail!("test");
         1
-    }.unwrap()
+    }).unwrap()
 }
index 0e3ef39cd1db347589ca4a534e060549fc445685..ca2472cfa55f159f2ac5b507f13befebbee3b92a 100644 (file)
@@ -13,8 +13,8 @@
 fn main() {
     let mut t = ::std::task::task();
     t.name("send name".to_send_str());
-    do t.try {
+    t.try(proc() {
         fail!("test");
         3
-    }.unwrap()
+    }).unwrap()
 }
index 4fd19fb2a6f22c05751664c54c24d41fb9c269a6..2303ab102d409bedc5d5cc50fe753d353d07772d 100644 (file)
@@ -13,7 +13,7 @@
 fn main() {
     let mut t = ::std::task::task();
     t.name("static name");
-    do t.try {
+    t.try(proc() {
         fail!("test");
-    }.unwrap()
+    }).unwrap()
 }
index 5ac3092640038ae3f4d78a85c81ac2d87041fee3..1094227770efd9e6a63eee7dcd7fc9138bf585d8 100644 (file)
@@ -62,8 +62,8 @@ fn and_then_get_big_again(x:int) -> and_then_get_big_again {
 }
 
 fn main() {
-    do task::spawn {
+    task::spawn(proc() {
         let r = and_then_get_big_again(4);
         getbig_call_c_and_fail(10000);
-    };
+    });
 }
index e6f219710b37bc0b5a43089c3ef224b3aebe0f8f..6acfa0b79f4100a750b40a505ad437f679fa5ebf 100644 (file)
@@ -48,7 +48,7 @@ fn and_then_get_big_again(x:int) -> and_then_get_big_again {
 }
 
 fn main() {
-    do task::spawn {
+    task::spawn(proc() {
         getbig_and_fail(400);
-    };
+    });
 }
index 02a65e91d04456e0890d25a7f2f08f6bd3bcb0cd..8be8e6b44f6afe9232bac06178105987058c4ef7 100644 (file)
@@ -41,7 +41,7 @@ fn and_then_get_big_again(x:int) -> and_then_get_big_again {
 }
 
 fn main() {
-    do task::spawn {
+    task::spawn(proc() {
         getbig_and_fail(1);
-    };
+    });
 }
index 807ee94ce09a45e2eb28f925574286f9241cb85e..20d8a543ae1966483a0695311e50f2483efdda58 100644 (file)
@@ -17,7 +17,7 @@
 
 #[start]
 fn start(argc: int, argv: **u8) -> int {
-    do native::start(argc, argv) {
+    native::start(argc, argv, proc() {
         fail!();
-    }
+    })
 }
index ea70bb0eab9a5ab1a3f73b763953807b50d0c4c4..d19788d8b5b84f72fa9faf00e7f2b5e2f7f3796b 100644 (file)
@@ -34,8 +34,8 @@ fn r(x:int) -> r {
 
 fn main() {
     error!("whatever");
-    do task::spawn {
+    task::spawn(proc() {
       let _i = r(5);
-    };
+    });
     fail!();
 }
index 9a03c772f3a3fef5d713d6af26754e0fc2de8e5c..94119cc0278dab39aff0fb42326c403acaafe35e 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #[crate_id="boot#0.1"];
-#[crate_type="lib"];
+#[crate_type="dylib"];
 #[no_uv];
 
 extern mod rustuv;
@@ -17,9 +17,9 @@
 
 #[no_mangle] // this needs to get called from C
 pub extern "C" fn foo(argc: int, argv: **u8) -> int {
-    do green::start(argc, argv) {
-        do spawn {
+    green::start(argc, argv, proc() {
+        spawn(proc() {
             println!("hello");
-        }
-    }
+        });
+    })
 }
index d0639d45fa569895aa16f02f8f8c9f7a34803a95..2a783606d944acd2ac5589e5776135b0a97c4655 100644 (file)
@@ -9,16 +9,16 @@
 // except according to those terms.
 
 #[crate_id="boot#0.1"];
-#[crate_type="lib"];
+#[crate_type="dylib"];
 #[no_uv];
 
 extern mod native;
 
 #[no_mangle] // this needs to get called from C
 pub extern "C" fn foo(argc: int, argv: **u8) -> int {
-    do native::start(argc, argv) {
-        do spawn {
+    native::start(argc, argv, proc() {
+        spawn(proc() {
             println!("hello");
-        }
-    }
+        });
+    })
 }
index 029933a819cc55195a195e8aad9ccc4891e2673f..96dabf8f07699c6fa01fc362b65dbea69f6f13ce 100644 (file)
@@ -12,11 +12,11 @@ fn drop(&mut self) {
 }
 
 fn main() {
-    do task::try {
+    task::try(proc() {
         let _a = A;
         lib::callback(|| fail!());
         1
-    };
+    });
 
     unsafe {
         assert!(lib::statik == 1);
index 0fcd49790e072604bb373e0d6ccfb3bd65e51990..05225eb0e7adabdadd77e2c22a0e9133929ac73a 100644 (file)
@@ -75,11 +75,11 @@ fn main() {
 
 fn check_pp<T>(cx: fake_ext_ctxt,
                expr: T, f: |pprust::ps, T|, expect: ~str) {
-    let s = do io::with_str_writer |wr| {
+    let s = io::with_str_writer(|wr| {
         let pp = pprust::rust_printer(wr, cx.parse_sess().interner);
         f(pp, expr);
         pp::eof(pp.s);
-    };
+    });
     stdout().write_line(s);
     if expect != ~"" {
         error!("expect: '%s', got: '%s'", expect, s);
index 667d9b738c23f1239268e5f0d1c9563d5e4c938c..eae791b6b08a62294b11fff47d469c7ce831e05e 100644 (file)
@@ -37,7 +37,7 @@ pub fn main() {
     (@"test").test_imm();
     (&"test").test_imm();
 
-    // XXX: Other types of mutable vecs don't currently exist
+    // FIXME: Other types of mutable vecs don't currently exist
 
     // NB: We don't do this double autoreffing for &mut self because that would
     // allow creating a mutable pointer to a temporary, which would be a source
index dca0efd94fab53931a406bcfc468c7a119346eda..a3e11d27f276e4ad72817bdba8735e345181e58e 100644 (file)
@@ -20,5 +20,5 @@ fn bitv_test() {
 }
 
 pub fn main() {
-    10000.times(|| bitv_test());
+    for _ in range(0, 10000) { bitv_test(); }
 }
diff --git a/src/test/run-pass/block-arg-can-be-followed-by-binop.rs b/src/test/run-pass/block-arg-can-be-followed-by-binop.rs
deleted file mode 100644 (file)
index f2149e2..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.
-
-fn add(x: proc(f64) -> f64) -> f64 {
-    x(10.0)
-}
-
-pub fn main() {
-    // Trailing expressions don't require parentheses:
-    let y = do add |x| { x + 10.0 } + 10.0;
-
-    assert_eq!(y, 30.0);
-}
diff --git a/src/test/run-pass/block-arg-can-be-followed-by-block-arg.rs b/src/test/run-pass/block-arg-can-be-followed-by-block-arg.rs
deleted file mode 100644 (file)
index 2cdf0a1..0000000
+++ /dev/null
@@ -1,17 +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.
-
-fn f(_: proc()) -> proc(proc() -> uint) {
-    proc(_: proc() -> uint) {}
-}
-
-pub fn main() {
-    do do f {} { 20 };
-}
diff --git a/src/test/run-pass/block-arg-can-be-followed-by-call.rs b/src/test/run-pass/block-arg-can-be-followed-by-call.rs
deleted file mode 100644 (file)
index 544367b..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn f(_: proc()) -> proc(uint) -> uint {
-    proc(x: uint) { x }
-}
-
-pub fn main() {
-    let z = do f {} (22u);
-    assert_eq!(z, 22u);
-}
diff --git a/src/test/run-pass/block-arg-in-parentheses.rs b/src/test/run-pass/block-arg-in-parentheses.rs
deleted file mode 100644 (file)
index 0832171..0000000
+++ /dev/null
@@ -1,38 +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.
-
-fn f(_: proc(int, int) -> int) -> int {
-    10
-}
-
-fn w_semi() {
-    // the semicolon causes compiler not to
-    // complain about the ignored return value:
-    do f |x, y| { x+y };
-}
-
-fn w_paren1() -> int {
-    (do f |x, y| { x+y }) - 10
-}
-
-fn w_paren2() -> int {
-    (do f |x, y| { x+y } - 10)
-}
-
-fn w_ret() -> int {
-    return do f |x, y| { x+y } - 10;
-}
-
-pub fn main() {
-    w_semi();
-    w_paren1();
-    w_paren2();
-    w_ret();
-}
diff --git a/src/test/run-pass/block-arg-used-as-any.rs b/src/test/run-pass/block-arg-used-as-any.rs
deleted file mode 100644 (file)
index 87a6cbd..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn call_any(f: proc() -> uint) -> uint {
-    return f();
-}
-
-pub fn main() {
-    let x_r = do call_any { 22u };
-    assert_eq!(x_r, 22u);
-}
index afe7747457a8cc320a5ef7ebc8fe2c88b4e19883..d59804b23954e17fa380451779e55eef48c7cf51 100644 (file)
@@ -25,49 +25,4 @@ pub fn main() {
         info!("{:?}", *i);
     }
 
-    // Usable at all:
-    do inty |x| { x };
-
-    // Higher precedence than assignments:
-    let result = do inty |e| { e };
-    assert_eq!(result, 100);
-
-    // Higher precedence than unary operations:
-    let stringy = do inty |e| { e }.to_str();
-    assert!(do booly |_| { true });
-    assert!(!do booly |_| { false });
-
-    // Usable in funny statement-like forms:
-    if !do booly |_| { true } {
-        assert!(false);
-    }
-    match do booly |_| { false } {
-        true => { fail!("incorrect answer."); }
-        false => { }
-    }
-    match 3 {
-      _ if do booly |_| { true } => {
-      }
-      _ => {
-        fail!("wrong answer.");
-      }
-    }
-
-
-    // Lower precedence than binary operations:
-    let w = do inty |_| { 10 } + 10;
-    let y = do inty |_| { 10 } + 10;
-    let z = 10 + do inty |_| { 10 };
-    assert_eq!(w, y);
-    assert_eq!(y, z);
-
-    // In the tail of a block
-    let w = if true {
-        do booly |_| {
-            true
-        }
-    } else {
-        false
-    };
-    assert!(w);
 }
index f108d6cad6fbe9f0d08ff16c0870a213d6554bd3..fe1be6d06db83cce39d251bba32657a582da970c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// 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.
 //
@@ -10,7 +10,6 @@
 
 #[feature(managed_boxes)];
 
-use std::borrow;
 use std::ptr;
 
 fn borrow(x: &int, f: |x: &int|) {
@@ -20,7 +19,7 @@ fn borrow(x: &int, f: |x: &int|) {
 fn test1(x: @~int) {
     borrow(&*(*x).clone(), |p| {
         let x_a = ptr::to_unsafe_ptr(&**x);
-        assert!((x_a as uint) != borrow::to_uint(p));
+        assert!((x_a as uint) != (p as *int as uint));
         assert_eq!(unsafe{*x_a}, *p);
     })
 }
index 0d9fdea4a9d51027f313dfaac49f15a0f81449ee..874075e8c1400bb1a71f4c45ffbecd06de298218 100644 (file)
@@ -28,9 +28,9 @@
 
 fn foo(x: ()) -> Port<()> {
     let (p, c) = Chan::<()>::new();
-    do task::spawn() {
+    task::spawn(proc() {
         c.send(x);
-    }
+    });
     p
 }
 
index b810bfd1c6b71ddcee2d7d4a96a01d37878202ef..171424d8b3b6905ffb0bd4f14be850ac6f0c8c43 100644 (file)
@@ -30,18 +30,18 @@ fn log(&mut self, _level: u32, args: &fmt::Arguments) {
 
 #[start]
 fn start(argc: int, argv: **u8) -> int {
-    do native::start(argc, argv) {
+    native::start(argc, argv, proc() {
         main();
-    }
+    })
 }
 
 fn main() {
     let (p, c) = Chan::new();
     let (mut r, w) = (PortReader::new(p), ChanWriter::new(c));
-    do spawn {
+    spawn(proc() {
         set_logger(~MyWriter(w) as ~Logger);
         debug!("debug");
         info!("info");
-    }
+    });
     assert_eq!(r.read_to_str(), ~"info\n");
 }
index 2a3f79e824594646a73f34b4a2e5e01bb8d5dd9d..a831cd1da69d52d3f04d01b14291e2e5d027f3cd 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// 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.
 //
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::borrow;
-
 pub fn main() {
     let x = 3;
-    info!("&x={:x}", borrow::to_uint(&x));
+    info!("&x={:x}", (&x as *int as uint));
 }
index 8c14276894475f94ebe50a4a349cdd482d173b9b..10b0ac375a95d79732b7d6a1b6499819fd32ead5 100644 (file)
@@ -15,7 +15,7 @@ trait noisy {
 }
 
 struct dog {
-  priv barks: uint,
+  barks: uint,
 
   volume: int,
 }
@@ -50,7 +50,7 @@ fn dog() -> dog {
 
 #[deriving(Clone)]
 struct cat {
-  priv meows: uint,
+  meows: uint,
 
   how_hungry: int,
   name: ~str,
index 86764df6ae07a2fc9e4410213b1fdda092c791a2..56b61dc5691df6b20d71839896ce0fa21635526b 100644 (file)
@@ -15,7 +15,7 @@ trait noisy {
 }
 
 struct cat {
-  priv meows: uint,
+  meows: uint,
   how_hungry: int,
   name: ~str,
 }
index 918547a3a2babcab4d749244a05dddd547c5433a..e8b35c9882f9c49454834ae79a4fba86e00c0da1 100644 (file)
@@ -27,7 +27,7 @@ fn ne(&self, other: &cat_type) -> bool { !(*self).eq(other) }
 // ok: T should be in scope when resolving the trait ref for map
 struct cat<T> {
     // Yes, you can have negative meows
-    priv meows : int,
+    meows : int,
 
     how_hungry : int,
     name : T,
index 88051e18c30f272d79063514532f35d8dbe9ed06..4c492eecd9562232c5327ad3f9481f4132a5fcaa 100644 (file)
@@ -14,7 +14,7 @@
 use cci_class_trait::animals::noisy;
 
 struct cat {
-  priv meows: uint,
+  meows: uint,
 
   how_hungry : int,
   name : ~str,
index 433d7f7a22ff48089fe38ececa8174b57605088e..6d5b9a9329e6158d89d474106721902a9dac64bb 100644 (file)
@@ -16,7 +16,7 @@ trait noisy {
 
 #[deriving(Clone)]
 struct cat {
-    priv meows : uint,
+    meows : uint,
 
     how_hungry : int,
     name : ~str,
index f5fa72e4ce5106f27668f0f32023ef5dd3ae618e..25a2009bb9a6c3c957834485e1782d0b9d12341f 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 struct cat {
-  priv meows : uint,
+  meows : uint,
 
   how_hungry : int,
 }
index 0201501bc7c64848ec7418a8cb214d88034d6c66..f4d3a115ef1367e75e235dce1eee805b7815b3e5 100644 (file)
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 struct cat<U> {
-    priv info : ~[U],
-    priv meows : uint,
+    info : ~[U],
+    meows : uint,
 
     how_hungry : int,
 }
index eb7e608a9f121e2cd282ee18e092c3b47710af71..3e9765f0b2b248f19ea9838554420586ecc29da1 100644 (file)
@@ -12,7 +12,7 @@
 
 // xfail-fast
 struct cat {
-    priv meows : uint,
+    meows : uint,
 
     how_hungry : int,
     name : ~str,
index ab6a8b1597bf673ea9449b5538a104fe11385582..9d4e73da81304fee635ac2775ec4469995e78fc2 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 struct cat<U> {
-    priv meows : uint,
+    meows : uint,
 
     how_hungry : int,
 }
index 6e08a4db14e944baad5400788f40298038312728..6f21afff12000c1166e07699ae7afd4a81080c9d 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 struct cat {
-    priv meows : uint,
+    meows : uint,
 
     how_hungry : int,
 }
index 49e8f5c04e36a0e32f43e107e8892f572820f40c..496efc2172e4896c455403611ed92a6a1d6d238c 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 struct cat {
-    priv meows : uint,
+    meows : uint,
 
     how_hungry : int,
 }
index e5220b15520a7c95c1e351cd16006db7ecb209d4..f65bf329823c2c9fe3a7420a61aabc22c0572f7d 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 struct cat {
-    priv meows : uint,
+    meows : uint,
 
     how_hungry : int,
     name : ~str,
index 3a92f4ba3f401412545f1f2661c2dd2aab8e5455..66fac94ba51e1b41c61af71caeb5d4b0c8a03f09 100644 (file)
@@ -16,8 +16,8 @@ fn foo(blk: proc()) {
 
 pub fn main() {
     let (p,c) = Chan::new();
-    do foo {
+    foo(proc() {
         c.send(());
-    }
+    });
     p.recv();
 }
index 61175a401abe269495918e47eaa5ec5a5d46b044..3ed77cd9fb767cdccfc621e0e8f966b108ebd339 100644 (file)
@@ -38,11 +38,6 @@ fn call_bare_again(f: extern "Rust" fn(&str)) {
 pub fn main() {
     // Procs
 
-    let greeting = ~"Hi ";
-    do call_it |s| {
-        greeting + s
-    }
-
     let greeting = ~"Hello ";
     call_it(proc(s) {
         greeting + s
diff --git a/src/test/run-pass/coerce-to-closure-and-proc.rs b/src/test/run-pass/coerce-to-closure-and-proc.rs
new file mode 100644 (file)
index 0000000..6f643ca
--- /dev/null
@@ -0,0 +1,47 @@
+// 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 id<T>(x: T) -> T {
+    x
+}
+
+#[deriving(Eq)]
+struct Foo<T>(T);
+
+#[deriving(Eq)]
+enum Bar<T> {
+    Bar(T)
+}
+
+pub fn main() {
+    let f: |int| -> int = id;
+    assert_eq!(f(5), 5);
+
+    let f: proc(int) -> int = id;
+    assert_eq!(f(5), 5);
+
+    let f: |int| -> Foo<int> = Foo;
+    assert_eq!(f(5), Foo(5));
+
+    let f: proc(int) -> Foo<int> = Foo;
+    assert_eq!(f(5), Foo(5));
+
+    let f: |int| -> Bar<int> = Bar;
+    assert_eq!(f(5), Bar(5));
+
+    let f: proc(int) -> Bar<int> = Bar;
+    assert_eq!(f(5), Bar(5));
+
+    let f: |int| -> Option<int> = Some;
+    assert_eq!(f(5), Some(5));
+
+    let f: proc(int) -> Option<int> = Some;
+    assert_eq!(f(5), Some(5));
+}
index d16f2135f50152627c66b4da542f378e629323a5..444790bcce99cbac3a5841908161f7ce957ac1c2 100644 (file)
@@ -72,9 +72,9 @@ pub fn main() {
     roundtrip::<C>();
     roundtrip::<D>();
 
-    20.times(|| {
+    for _ in range(0, 20) {
         roundtrip::<E>();
         roundtrip::<F>();
         roundtrip::<G<int>>();
-    })
+    }
 }
index f82d77b28eae97128eb21d72a6b21a53fbe4337c..bf63290a011f917afd5dd55ac84de45c295c9489 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
 
 #[deriving(Eq, FromPrimitive)]
 enum A {
-    Foo = int::max_value,
+    Foo = int::MAX,
     Bar = 1,
     Baz = 3,
     Qux,
 }
 
 pub fn main() {
-    let x: Option<A> = FromPrimitive::from_int(int::max_value);
+    let x: Option<A> = FromPrimitive::from_int(int::MAX);
     assert_eq!(x, Some(Foo));
 
     let x: Option<A> = FromPrimitive::from_int(1);
index 58ef613b7cd9ab9ec6121f91f919c8fb78df2052..a8dc8de0c23b8582785e2db2866594e9c29d53dc 100644 (file)
@@ -34,10 +34,10 @@ enum D {
 
 pub fn main() {
     // check there's no segfaults
-    20.times(|| {
+    for _ in range(0, 20) {
         rand::random::<A>();
         rand::random::<B>();
         rand::random::<C>();
         rand::random::<D>();
-    })
+    }
 }
index fbeb0a05340aa7a9b524c5cbff3c1b9cc1360152..cf53664e32a14457bdd3911d875748eb8a2c00d8 100644 (file)
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
+// xfail-test FIXME #11820: & is unreliable in deriving
+
 use std::cmp::{Less,Equal,Greater};
 
 #[deriving(TotalEq,TotalOrd)]
index 3d7d58878f2189eec6bdc3a0b5774007956c7b81..38eee7430ac5a94676244596d3663934387ca6fa 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// xfail-test FIXME #11820: & is unreliable in deriving
+
 #[deriving(Eq,Ord)]
 struct A<'a> {
     x: &'a int
diff --git a/src/test/run-pass/do-empty-args.rs b/src/test/run-pass/do-empty-args.rs
deleted file mode 100644 (file)
index 56ba2ff..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// no-reformat
-// Testing various forms of `do` with empty arg lists
-
-fn f(_f: proc() -> bool) -> bool {
-    true
-}
-
-pub fn main() {
-    do f() || { true };
-    do f() { true };
-    do f || { true };
-    do f { true };
-}
diff --git a/src/test/run-pass/do-no-args.rs b/src/test/run-pass/do-no-args.rs
deleted file mode 100644 (file)
index 0df5c82..0000000
+++ /dev/null
@@ -1,19 +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.
-
-// Testing that we can drop the || in do exprs
-
-fn f(_f: proc() -> bool) -> bool { true }
-
-fn d(_f: proc()) { }
-
-pub fn main() {
-    do d { }
-}
diff --git a/src/test/run-pass/do1.rs b/src/test/run-pass/do1.rs
deleted file mode 100644 (file)
index bdbad74..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn f(f: proc(int)) { f(10) }
-
-pub fn main() {
-    do f() |i| { assert!(i == 10) }
-}
diff --git a/src/test/run-pass/do2.rs b/src/test/run-pass/do2.rs
deleted file mode 100644 (file)
index f509f7b..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn f(f: proc(int) -> int) -> int { f(10) }
-
-pub fn main() {
-    assert_eq!(do f() |i| { i }, 10);
-}
diff --git a/src/test/run-pass/do3.rs b/src/test/run-pass/do3.rs
deleted file mode 100644 (file)
index cdba14f..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn f(f: proc(int) -> int) -> int { f(10) }
-
-pub fn main() {
-    assert_eq!(do f |i| { i }, 10);
-}
index e18509252235de514e832233a7a8d2943535ccfe..9ca41c56dc9602174be374f0a4961da5e2fde1e5 100644 (file)
@@ -13,7 +13,7 @@
 fn test_fn() {
     type t = 'static || -> int;
     fn ten() -> int { return 10; }
-    let rs: t = { ten };
+    let rs: t = ten;
     assert!((rs() == 10));
 }
 
index 00ac0bfa118eb19763a092219d45b25d2f84bec8..500ae8951ec4aa72459d3f84f251f2e03808b92d 100644 (file)
@@ -40,9 +40,9 @@ fn count(n: uint) -> uint {
 pub fn main() {
     // Make sure we're on a task with small Rust stacks (main currently
     // has a large stack)
-    do task::spawn {
+    task::spawn(proc() {
         let result = count(1000u);
         info!("result = {}", result);
         assert_eq!(result, 1000u);
-    };
+    });
 }
index 0044f0f468f306a28b6507bfb10b37ce208cf10c..c35e84154d80ba48bc9eede4d36fab66ce068a64 100644 (file)
@@ -44,9 +44,9 @@ fn count(n: uint) -> uint {
 pub fn main() {
     // Make sure we're on a task with small Rust stacks (main currently
     // has a large stack)
-    do task::spawn {
+    task::spawn(proc() {
         let result = count(12u);
         info!("result = {}", result);
         assert_eq!(result, 2048u);
-    };
+    });
 }
index 7c16ae74c4a91a1dc65c23a30a6adeeecc79ed61..ef1b26fc1af052c3531e097ad88d7121e0686244 100644 (file)
@@ -41,9 +41,9 @@ fn count(n: uint) -> uint {
 }
 
 pub fn main() {
-    100u.times(|| {
-        do task::spawn {
+    for _ in range(0, 100u) {
+        task::spawn(proc() {
             assert_eq!(count(5u), 16u);
-        };
-    })
+        });
+    }
 }
index a4ac197ac6aed522f2dcc9ce575e3391b72b3874..d7b8ed583a5184821ece5b4b6ec1926bfff60589 100644 (file)
@@ -38,11 +38,11 @@ fn count(n: uint) -> uint {
 }
 
 pub fn main() {
-    10u.times(|| {
-        do task::spawn {
+    for _ in range(0, 10u) {
+        task::spawn(proc() {
             let result = count(5u);
             info!("result = {}", result);
             assert_eq!(result, 16u);
-        };
-    })
+        });
+    }
 }
index 7c6bb1fa379b4d1b5c51ddb265fb7e1064ad6c5e..be4a497989ce8d239ed6f2d1a1e19c88ca65a4a9 100644 (file)
@@ -33,9 +33,9 @@ fn drop(&mut self) {
 }
 
 pub fn main() {
-    let ret = do task::try {
+    let ret = task::try(proc() {
         let _a = A { b: B { foo: 3 } };
-    };
+    });
     assert!(ret.is_err());
     unsafe { assert!(dropped); }
 }
index ee54423a97d7d6d998e4faeff5cf922cf1165565..daaaac93791bd38b8da3e0c7d21bf94c6f3f2d3b 100644 (file)
@@ -10,10 +10,10 @@ fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t),
 
 pub fn main() {
     unsafe {
-        do run_in_bare_thread() {
+        run_in_bare_thread(proc() {
             let i = &100;
             rust_dbg_call(callback, cast::transmute(i));
-        }
+        });
     }
 }
 
diff --git a/src/test/run-pass/generic-default-type-params-cross-crate.rs b/src/test/run-pass/generic-default-type-params-cross-crate.rs
new file mode 100644 (file)
index 0000000..b90b8f3
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:default_type_params_xc.rs
+
+// xfail-fast #[feature] doesn't work with check-fast
+#[feature(default_type_params)];
+
+#[allow(default_type_param_usage)];
+
+extern mod default_type_params_xc;
+
+struct Vec<T, A = default_type_params_xc::Heap>;
+
+struct Foo;
+
+fn main() {
+    let _a = Vec::<int>;
+    let _b = Vec::<int, default_type_params_xc::FakeHeap>;
+    let _c = default_type_params_xc::FakeVec::<int>;
+    let _d = default_type_params_xc::FakeVec::<int, Foo>;
+}
diff --git a/src/test/run-pass/generic-default-type-params.rs b/src/test/run-pass/generic-default-type-params.rs
new file mode 100644 (file)
index 0000000..bb5a923
--- /dev/null
@@ -0,0 +1,57 @@
+// 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.
+
+// xfail-fast #[feature] doesn't work with check-fast
+#[feature(default_type_params)];
+
+#[allow(default_type_param_usage)];
+
+struct Foo<A = (int, char)> {
+    a: A
+}
+
+impl Foo<int> {
+    fn bar_int(&self) -> int {
+        self.a
+    }
+}
+
+impl Foo<char> {
+    fn bar_char(&self) -> char {
+        self.a
+    }
+}
+
+impl Foo {
+    fn bar(&self) {
+        let (i, c): (int, char) = self.a;
+        assert_eq!(Foo { a: i }.bar_int(), i);
+        assert_eq!(Foo { a: c }.bar_char(), c);
+    }
+}
+
+impl<A: Clone> Foo<A> {
+    fn baz(&self) -> A {
+        self.a.clone()
+    }
+}
+
+fn default_foo(x: Foo) {
+    let (i, c): (int, char) = x.a;
+    assert_eq!(i, 1);
+    assert_eq!(c, 'a');
+
+    x.bar();
+    assert_eq!(x.baz(), (1, 'a'));
+}
+
+fn main() {
+    default_foo(Foo { a: (1, 'a') });
+}
index 655bc7771938f1e73c9318cc6b7a995ef58a6e27..9e724d86df5eb0b5ddf30d1708b6e6da81bff0e2 100644 (file)
@@ -12,8 +12,9 @@
 // xfail-win32 TempDir may cause IoError on windows: #10462
 
 extern mod extra;
+extern mod glob;
 
-use extra::glob::glob;
+use glob::glob;
 use extra::tempfile::TempDir;
 use std::unstable::finally::Finally;
 use std::{os, unstable};
index dea0df2e52b348034c41ab2ddf282c78634017db..633c096b689201fb491e2dd836bcfecd9a5f0e81 100644 (file)
@@ -17,7 +17,7 @@
 extern mod extra;
 
 fn loopy(n: int) {
-    if n > 0 { do spawn { loopy(n - 1) }; do spawn { loopy(n - 1) }; }
+    if n > 0 { spawn(proc() { loopy(n - 1) }); spawn(proc() { loopy(n - 1) }); }
     loop { }
 }
 
@@ -25,5 +25,5 @@ pub fn main() {
     // Commenting this out, as this will hang forever otherwise.
     // Even after seeing the comment above, I'm not sure what the
     // intention of this test is.
-    // do spawn { loopy(5) };
+    // spawn(proc() { loopy(5) });
 }
diff --git a/src/test/run-pass/issue-10031.rs b/src/test/run-pass/issue-10031.rs
new file mode 100644 (file)
index 0000000..c3f5bf7
--- /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.
+
+// xfail-fast - check-fast doesn't understand aux-build
+// aux-build:issue_10031_aux.rs
+extern mod issue_10031_aux;
+
+pub fn main() {
+    let _ = issue_10031_aux::Wrap(());
+}
index 9ebeec092cf15876b2f08fca0b2c9e2cc03a0594..cef183e5f33c772fc333b6df4dbd6a74c3f85270 100644 (file)
@@ -51,16 +51,16 @@ fn iter(&self, blk: |v: uint|) { self( |i| blk(i) ) }
 }
 
 fn filter<A,IA:iterable<A>>(self: IA, prd: 'static |A| -> bool, blk: |A|) {
-    do self.iter |a| {
+    self.iter(|a| {
         if prd(a) { blk(a) }
-    }
+    });
 }
 
 fn foldl<A,B,IA:iterable<A>>(self: IA, b0: B, blk: |B, A| -> B) -> B {
     let mut b = b0;
-    do self.iter |a| {
+    self.iter(|a| {
         b = blk(b, a);
-    }
+    });
     b
 }
 
index 978cd586975f91e5e1b408b482cb328a0eafd88b..49b7e50c01e61b942b1f1abb9ca1d654ef90c5e1 100644 (file)
 
 pub fn main() {
     let (p,c) = comm::stream();
-    do task::try || {
+    task::try(|| {
         let (p2,c2) = comm::stream();
-        do task::spawn || {
+        task::spawn(|| {
             p2.recv();
             error!("sibling fails");
             fail!();
-        }
+        });
         let (p3,c3) = comm::stream();
         c.send(c3);
         c2.send(());
         error!("child blocks");
         p3.recv();
-    };
+    });
     error!("parent tries");
     assert!(!p.recv().try_send(()));
     error!("all done!");
index 3d8300010d9d5e586f73f774bf6a8f9b480c10f0..63a457be9f0209f8be67921fc4bc64efb4df104b 100644 (file)
@@ -1,6 +1,6 @@
 pub fn main() {
     let mut x = 0;
-    4096.times(|| x += 1);
+    for _ in range(0, 4096) { x += 1; }
     assert_eq!(x, 4096);
     println!("x = {}", x);
 }
index 57ae7ad015f59fcc0f7228d1d5b5afd4433c604d..54f865a6cd5802fad38509e023d68b30b3edf32c 100644 (file)
@@ -47,8 +47,8 @@ struct Rect {
 struct AsciiArt {
     width: uint,
     height: uint,
-    priv fill: char,
-    priv lines: ~[~[char]],
+    fill: char,
+    lines: ~[~[char]],
 
     // This struct can be quite large so we'll disable copying: developers need
     // to either pass these structs around via references or move them.
@@ -65,7 +65,7 @@ fn AsciiArt(width: uint, height: uint, fill: char) -> AsciiArt {
     // Use an anonymous function to build a vector of vectors containing
     // blank characters for each position in our canvas.
     let lines = vec::build(Some(height), |push| {
-        height.times(|| push(vec::from_elem(width, '.')))
+        for _ in range(0, height) { push(vec::from_elem(width, '.')); }
     });
 
     // Rust code often returns values by omitting the trailing semi-colon
index 4922ab18f8d45bca609903e0f914c4b48762a96c..bcda2e27614c687f1da1d8a2bebac62d311d7cea 100644 (file)
@@ -12,8 +12,7 @@ enum Msg
 }
 
 fn foo(name: ~str, samples_chan: Chan<Msg>) {
-    do task::spawn
-    {
+    task::spawn(proc() {
         let mut samples_chan = samples_chan;
         let callback: SamplesFn = proc(buffer) {
             for i in range(0u, buffer.len()) {
@@ -21,7 +20,7 @@ fn foo(name: ~str, samples_chan: Chan<Msg>) {
             }
         };
         samples_chan.send(GetSamples(name.clone(), callback));
-    };
+    });
 }
 
 pub fn main() {}
index 4cdf7aa3dd02d385aced665f816116bd06dbe6d9..88556af254204b7ec15e31e5f82203346a7828ff 100644 (file)
@@ -44,17 +44,16 @@ enum Result {
 }
 
 priv fn parse_list(len: uint, io: @io::Reader) -> Result {
-  let mut list: ~[Result] = ~[];
-    do len.times {
-    let v =
-        match io.read_char() {
-        '$' => parse_bulk(io),
-        ':' => parse_int(io),
-         _ => fail!()
-    };
-    list.push(v);
+    let mut list: ~[Result] = ~[];
+    for _ in range(0, len) {
+        let v = match io.read_char() {
+            '$' => parse_bulk(io),
+            ':' => parse_int(io),
+             _ => fail!()
+        };
+        list.push(v);
     }
-  return List(list);
+    return List(list);
 }
 
 priv fn chop(s: ~str) -> ~str {
@@ -119,11 +118,11 @@ fn query(cmd: ~[~str], sb: TcpSocketBuf) -> Result {
 
 fn query2(cmd: ~[~str]) -> Result {
   let _cmd = cmd_to_str(cmd);
-    do io::with_str_reader(~"$3\r\nXXX\r\n") |sb| {
+    io::with_str_reader(~"$3\r\nXXX\r\n")(|sb| {
     let res = parse_response(@sb as @io::Reader);
     println!("{:?}", res);
     res
-    }
+    });
 }
 
 
index a6041c79eac1bc3ab92b67e1ead25bb33c26146d..72390cfdad7797866a8236322d29ec6529b5f6c6 100644 (file)
@@ -1,6 +1,6 @@
 pub fn main() {
     let mut count = 0;
-    999_999.times(|| count += 1);
+    for _ in range(0, 999_999) { count += 1; }
     assert_eq!(count, 999_999);
     println!("{}", count);
 }
index baac8d0dcd14c462fe51f36e6b338d45d863bfd5..8f2d9f32440bb186b18d0df39a20b4a309268b11 100644 (file)
@@ -13,9 +13,9 @@
 pub fn main() {
     let (port, chan) = Chan::new();
 
-    do spawn {
+    spawn(proc() {
         println(port.recv());
-    }
+    });
 
     chan.send("hello, world");
 }
index c3f871c79124bae7b74f99610cb09f8f9efff5c8..8fbc35c72005ac673c8c767e7fd6dde6d757a5d7 100644 (file)
@@ -13,9 +13,9 @@
 pub fn main() {
     let (port, chan) = Chan::<&'static str>::new();
 
-    do task::spawn {
+    task::spawn(proc() {
         assert_eq!(port.recv(), "hello, world");
-    }
+    });
 
     chan.send("hello, world");
 }
index 0b2155cc3d03c862f7c0a551ff156f0a01fc24ed..fcb8092b7234fd7f3bed64073c18f77ef67e9bf2 100644 (file)
@@ -14,7 +14,7 @@ trait Fooable {
 
 impl Fooable for uint {
     fn yes(self) {
-        self.times(|| println!("yes"));
+        for _ in range(0, self) { println!("yes"); }
     }
 }
 
diff --git a/src/test/run-pass/issue-6157.rs b/src/test/run-pass/issue-6157.rs
new file mode 100644 (file)
index 0000000..50e5f97
--- /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 trait OpInt<'a> { fn call<'a>(&'a self, int, int) -> int; }
+
+impl<'a> OpInt<'a> for 'a |int, int| -> int {
+    fn call(&self, a:int, b:int) -> int {
+        (*self)(a, b)
+    }
+}
+
+fn squarei<'a>(x: int, op: &'a OpInt) -> int { op.call(x, x) }
+
+fn muli(x:int, y:int) -> int { x * y }
+
+pub fn main() {
+    let f = |x,y| muli(x,y);
+    {
+        let g = &f;
+        let h = g as &OpInt;
+        squarei(3, h);
+    }
+}
diff --git a/src/test/run-pass/kindck-implicit-close-over-mut-var.rs b/src/test/run-pass/kindck-implicit-close-over-mut-var.rs
new file mode 100644 (file)
index 0000000..3f45e86
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::task;
+
+fn user(_i: int) {}
+
+fn foo() {
+    // Here, i is *copied* into the proc (heap closure).
+    // Requires allocation.  The proc's copy is not mutable.
+    let mut i = 0;
+    task::spawn(proc() {
+        user(i);
+        println!("spawned {}", i)
+    });
+    i += 1;
+    println!("original {}", i)
+}
+
+fn bar() {
+    // Here, the original i has not been moved, only copied, so is still
+    // mutable outside of the proc.
+    let mut i = 0;
+    while i < 10 {
+        task::spawn(proc() {
+            user(i);
+        });
+        i += 1;
+    }
+}
+
+fn car() {
+    // Here, i must be shadowed in the proc to be mutable.
+    let mut i = 0;
+    while i < 10 {
+        task::spawn(proc() {
+            let mut i = i;
+            i += 1;
+            user(i);
+        });
+        i += 1;
+    }
+}
+
+pub fn main() {}
+
index a06d025f6c7a5d0ea6dee7f096a61eb48a53956c..d81b5818d6693a53ea00bd506cb72b5b09a2a5c5 100644 (file)
@@ -26,12 +26,12 @@ fn fmt(f: &Foo, _fmt: &mut fmt::Formatter) {
 
 pub fn main() {
     let (p,c) = Chan::new();
-    do spawn {
+    spawn(proc() {
         let mut f = Foo(Cell::new(0));
         debug!("{}", f);
         let Foo(ref mut f) = f;
         assert!(f.get() == 1);
         c.send(());
-    }
+    });
     p.recv();
 }
index 064fb385dccb3243bbcf4ee16e1e0369887a9ef4..eb347ab28ff97b1688bb5e4725f4dc9479b0dd21 100644 (file)
@@ -2,7 +2,7 @@
 
 pub fn main() {
     let x = ~"Hello world!";
-    do task::spawn {
+    task::spawn(proc() {
         println!("{}", x);
-    }
+    });
 }
index cddee0be18df0d8ff7d6540cc3af7fb0a097c5c9..8907db04dadc0b6230f41275c7d3a707dc7d5219 100644 (file)
 #[start]
 fn start(argc: int, argv: **u8) -> int {
     // make sure that native::start always waits for all children to finish
-    do native::start(argc, argv) {
-        do spawn {
+    native::start(argc, argv, proc() {
+        spawn(proc() {
             unsafe { set = true; }
-        }
-    };
+        });
+    });
 
     // if we didn't set the global, then return a nonzero code
     if unsafe {set} {0} else {1}
index 3459f021f39bb94a1bb2e99859376899a0ea27f5..f9567858022b33d306027fe511cfabc25897a8bd 100644 (file)
@@ -24,9 +24,9 @@ fn drop(&mut self) {
 }
 
 fn main() {
-    do task::try::<()> {
+    task::try::<()>(proc() {
         let _a = A;
         fail!();
-    };
+    });
     assert!(unsafe { !HIT });
 }
index 1422f93e612af593b4952161779d660f86bcfa85..34f2c85350984ef17d567277d789b7b676de18d4 100644 (file)
@@ -31,9 +31,6 @@ pub fn main() {
     assert_eq!(15u32.add(&6u32), 21u32);
     assert_eq!(15u64.add(&6u64), 21u64);
 
-    // times
-     15u.times(|| {});
-
 // floats
     // num
     assert_eq!(10f32.to_int().unwrap(), 10);
index 8c3f889c176cd97c4b59c9e8b4b12c323e11c293..bc56712ee3bc1b2b2947c6e8c564b60f13e6a728 100644 (file)
@@ -22,8 +22,8 @@ fn foo(blk: proc()) {
 
 pub fn main() {
     let x = arc::Arc::new(true);
-    do foo {
+    foo(proc() {
         assert!(*x.get());
         drop(x);
-    }
+    });
 }
index 238ea7485c944b7d007f4db40cf6581b90bcc4e9..3e26dc69a84f63a6e69ac952f9658546878c034e 100644 (file)
@@ -10,8 +10,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-extern mod extra;
-use extra::arena::Arena;
+extern mod arena;
+use arena::Arena;
 
 pub fn main() {
     let mut arena = Arena::new();
index f34cc268a0c255ea2632b93c9456867cf49a2bc7..0527f47c112e012dbf1c9d50640440b269fed496 100644 (file)
@@ -29,9 +29,9 @@ pub fn main() {
     let (port, chan) = stream();
 
     info!("main started");
-    do spawn {
+    spawn(proc() {
         starve_main(port);
-    };
+    });
     let mut i: int = 0;
     info!("main waiting for alive signal");
     chan.send(i);
index 868cbbfa8021284dd061e6a9f30ad5468312d05c..93872bebec98bdca6906923611c9ffea548c1072 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 struct cat {
-    priv meows : uint,
+    meows : uint,
 
     how_hungry : int,
 }
index 8b2b5bfa00bfd2da61c2aad19a1e51194e1057ca..b64ca955cde6d3d60b2052d6ff28b7cd31851739 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 struct cat {
-    priv meows : uint,
+    meows : uint,
 
     how_hungry : int,
 }
index e244eace65be626078c4f95eb9ca47f138a4bbe6..6dec5fdaa1cbac0a7a498c600aadc4167042e292 100644 (file)
@@ -436,20 +436,6 @@ fn visit_type(&mut self) -> bool {
         if ! self.inner().visit_type() { return false; }
         true
     }
-
-    fn visit_opaque_box(&mut self) -> bool {
-        self.align_to::<@u8>();
-        if ! self.inner().visit_opaque_box() { return false; }
-        self.bump_past::<@u8>();
-        true
-    }
-
-    fn visit_closure_ptr(&mut self, ck: uint) -> bool {
-        self.align_to::<(uint,uint)>();
-        if ! self.inner().visit_closure_ptr(ck) { return false; }
-        self.bump_past::<(uint,uint)>();
-        true
-    }
 }
 
 struct my_visitor(@RefCell<Stuff>);
@@ -611,8 +597,6 @@ fn visit_trait(&mut self, _name: &str) -> bool { true }
     fn visit_param(&mut self, _i: uint) -> bool { true }
     fn visit_self(&mut self) -> bool { true }
     fn visit_type(&mut self) -> bool { true }
-    fn visit_opaque_box(&mut self) -> bool { true }
-    fn visit_closure_ptr(&mut self, _ck: uint) -> bool { true }
 }
 
 fn get_tydesc_for<T>(_t: T) -> *TyDesc {
index f5871facd1da21666312e4ab2d2a56516e9d5d97..91e69028103a33536aa675b4f6d814f8926a9671 100644 (file)
@@ -137,8 +137,6 @@ fn visit_trait(&mut self, _name: &str) -> bool { true }
     fn visit_param(&mut self, _i: uint) -> bool { true }
     fn visit_self(&mut self) -> bool { true }
     fn visit_type(&mut self) -> bool { true }
-    fn visit_opaque_box(&mut self) -> bool { true }
-    fn visit_closure_ptr(&mut self, _ck: uint) -> bool { true }
 }
 
 fn visit_ty<T>(v: &mut MyVisitor) {
diff --git a/src/test/run-pass/regions-lifetime-static-items-enclosing-scopes.rs b/src/test/run-pass/regions-lifetime-static-items-enclosing-scopes.rs
new file mode 100644 (file)
index 0000000..e207175
--- /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.
+
+// This test verifies that temporary lifetime is correctly computed
+// for static objects in enclosing scopes.
+
+extern mod extra;
+use std::cmp::Eq;
+
+fn f<T:Eq>(o: &mut Option<T>) {
+    assert!(*o == None);
+}
+
+pub fn main() {
+    mod t {
+        enum E {V=1, A=0}
+        static C: E = V;
+    }
+
+    f::<int>(&mut None);
+}
index 50a71278c0656cf0b16ed78deba4a14ffbd8f32b..3b5893358bf1dc4a4b335110599c418530ca66b0 100644 (file)
 // - Multiple lifetime parameters
 // - Arenas
 
-extern mod extra;
+extern mod arena;
 
-use extra::arena;
-use extra::arena::Arena;
+use arena::Arena;
 use std::hashmap::HashMap;
 use std::cast;
 use std::libc;
 
 type Type<'tcx> = &'tcx TypeStructure<'tcx>;
 
-#[deriving(Eq)]
 enum TypeStructure<'tcx> {
     TypeInt,
     TypeFunction(Type<'tcx>, Type<'tcx>),
 }
+impl<'tcx> Eq for TypeStructure<'tcx> {
+    fn eq(&self, other: &TypeStructure<'tcx>) -> bool {
+        match (*self, *other) {
+            (TypeInt, TypeInt) => true,
+            (TypeFunction(s_a, s_b), TypeFunction(o_a, o_b)) => *s_a == *o_a && *s_b == *o_b,
+            _ => false
+        }
+    }
+}
 
 struct TypeContext<'tcx, 'ast> {
     ty_arena: &'tcx Arena,
index 7ede574a4d5bef69a7443cb14c556105148b29b2..474606ad347bd6747933b7509b24f03959021eae 100644 (file)
@@ -27,12 +27,12 @@ fn test(f: int) -> test {
 pub fn main() {
     let (p, c) = Chan::new();
 
-    do task::spawn() {
+    task::spawn(proc() {
         let (pp, cc) = Chan::new();
         c.send(cc);
 
         let _r = pp.recv();
-    }
+    });
 
     p.recv().send(test(42));
 }
index 74502b54d8e395c73ed2547ee604bdb497cd9072..85c6555d7ce18f8de072b2bf3172d5786f26d62f 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::unstable::simd::{i32x4, f32x4};
+#[allow(experimental)];
+
+use std::unstable::simd::{i32x4, f32x4, u32x4};
 
 fn test_int(e: i32) -> i32 {
     let v = i32x4(e, 0i32, 0i32, 0i32);
@@ -22,7 +24,15 @@ fn test_float(e: f32) -> f32 {
     e2
 }
 
+pub fn test_shift(e: u32) -> u32 {
+    let v = u32x4(e, 0u32, 0u32, 0u32);
+    let one = u32x4(1u32, 0u32, 0u32, 0u32);
+    let u32x4(e2, _, _, _) = v << one >> one;
+    e2
+}
+
 pub fn main() {
     assert_eq!(test_int(3i32), 9i32);
     assert_eq!(test_float(3f32), 9f32);
+    assert_eq!(test_shift(3u32), 3u32);
 }
index 643daad397ca528c131279d5be08c1ed44de67fd..029478b4d59653f6d2dfa3b513f913835168428a 100644 (file)
@@ -1,3 +1,7 @@
+// xfail-fast feature doesn't work
+
+#[feature(simd)];
+
 #[simd]
 struct RGBA {
     r: f32,
diff --git a/src/test/run-pass/struct-lit-functional-update-no-fields.rs b/src/test/run-pass/struct-lit-functional-update-no-fields.rs
new file mode 100644 (file)
index 0000000..f63a729
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[deriving(Eq,Clone)]
+struct Foo<T> {
+    bar: T,
+    baz: T
+}
+
+pub fn main() {
+    let foo = Foo {
+        bar: 0,
+        baz: 1
+    };
+
+    let foo_ = foo.clone();
+    let foo = Foo { ..foo };
+    assert_eq!(foo, foo_);
+
+    let foo = Foo {
+        bar: ~"one",
+        baz: ~"two"
+    };
+
+    let foo_ = foo.clone();
+    let foo = Foo { ..foo };
+    assert_eq!(foo, foo_);
+}
index ce30071aaf4456cc2760d86908306036b82a7002..f6f6f3ba240cfd2dcaf1b3ef685442e5d35a1e9d 100644 (file)
@@ -20,9 +20,9 @@ fn test00() {
     let i: int = 0;
     let mut builder = task::task();
     let mut result = builder.future_result();
-    do builder.spawn {
+    builder.spawn(proc() {
         start(i)
-    }
+    });
 
     // Sleep long enough for the task to finish.
     let mut i = 0;
index 43ac3957ae2ed8f3604bae6266b5bc98106846e0..8622ff7608999ed45e77151e7d1e9ae4f1019140 100644 (file)
@@ -31,21 +31,21 @@ fn test00() {
     let number_of_messages: int = 10;
 
     let c = ch.clone();
-    do task::spawn || {
+    task::spawn(proc() {
         test00_start(&c, number_of_messages * 0, number_of_messages);
-    }
+    });
     let c = ch.clone();
-    do task::spawn || {
+    task::spawn(proc() {
         test00_start(&c, number_of_messages * 1, number_of_messages);
-    }
+    });
     let c = ch.clone();
-    do task::spawn || {
+    task::spawn(proc() {
         test00_start(&c, number_of_messages * 2, number_of_messages);
-    }
+    });
     let c = ch.clone();
-    do task::spawn || {
+    task::spawn(proc() {
         test00_start(&c, number_of_messages * 3, number_of_messages);
-    }
+    });
 
     let mut i: int = 0;
     while i < number_of_messages {
index a2463ff76815f2f175bd3e60f1f8572a8f53318e..feae49ffeb83c31d23c317e1b04a0483db2e3ea3 100644 (file)
@@ -29,10 +29,10 @@ fn test00() {
 
     let mut builder = task::task();
     let result = builder.future_result();
-    do builder.spawn {
+    builder.spawn(proc() {
         let mut ch = ch;
         test00_start(&mut ch, number_of_messages);
-    }
+    });
 
     let mut i: int = 0;
     while i < number_of_messages {
index 16e9cb538919cbc173db9a898e51315be0c56a8c..a4be47323e5b99e126d60551f16951a572113d39 100644 (file)
@@ -56,10 +56,10 @@ fn wrapper(c: Chan<bool>, f: ||) {
         *b = true;
     }
     let (p, c) = stream();
-    do task::spawn_unlinked {
+    task::spawn_unlinked(proc() {
         let ccc = c;
         wrapper(ccc, f)
-    }
+    });
     p
 }
 
index b99e6a03bcb3bae24ec5b5bd182c7ab635e2bbc8..2bf18e1ae1d5f67635e4b29eb3c0f8293f8b997f 100644 (file)
@@ -71,13 +71,13 @@ pub fn main() {
                          ~dogge2 as ~Pet:Freeze+Send]);
     let (p1,c1) = Chan::new();
     let arc1 = arc.clone();
-    do task::spawn { check_legs(arc1); c1.send(()); }
+    task::spawn(proc() { check_legs(arc1); c1.send(()); });
     let (p2,c2) = Chan::new();
     let arc2 = arc.clone();
-    do task::spawn { check_names(arc2); c2.send(()); }
+    task::spawn(proc() { check_names(arc2); c2.send(()); });
     let (p3,c3) = Chan::new();
     let arc3 = arc.clone();
-    do task::spawn { check_pedigree(arc3); c3.send(()); }
+    task::spawn(proc() { check_pedigree(arc3); c3.send(()); });
     p1.recv();
     p2.recv();
     p3.recv();
index 5707406de146c4edf822bb23d7989fd84c3ce1fa..04507dd01ce5c0890de6c49014cd7475a584d1f6 100644 (file)
@@ -21,9 +21,9 @@ fn drop(&mut self) {
 }
 
 pub fn main() {
-    let x = do task::try {
+    let x = task::try(proc() {
         let _b = Foo;
-    };
+    });
 
     let s = x.unwrap_err().move::<&'static str>().unwrap();
     assert_eq!(s.as_slice(), "This failure should happen.");