]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #8623 : pnkfelix/rust/fsk-visitor-vpar-defaults-step4, r=nmatsakis
authorbors <bors@rust-lang.org>
Mon, 19 Aug 2013 22:02:07 +0000 (15:02 -0700)
committerbors <bors@rust-lang.org>
Mon, 19 Aug 2013 22:02:07 +0000 (15:02 -0700)
Follow up to #8619 (step 3 of 5).

(See #8527, which was step 1 of 5, for the full outline.)

Part of #7081.

686 files changed:
doc/po/tutorial-container.md.pot
doc/rust.md
doc/tutorial-container.md
doc/tutorial-ffi.md
doc/tutorial.md
mk/rt.mk
mk/target.mk
mk/tools.mk
src/compiletest/procsrv.rs
src/compiletest/runtest.rs
src/etc/cmathconsts.c
src/etc/ziggurat_tables.py
src/etc/zsh/_rust
src/libextra/arc.rs
src/libextra/c_vec.rs
src/libextra/crypto/cryptoutil.rs
src/libextra/crypto/digest.rs
src/libextra/crypto/md5.rs [new file with mode: 0644]
src/libextra/crypto/sha1.rs
src/libextra/crypto/sha2.rs
src/libextra/dlist.rs
src/libextra/enum_set.rs
src/libextra/extra.rs
src/libextra/fileinput.rs
src/libextra/flate.rs
src/libextra/flatpipes.rs
src/libextra/priority_queue.rs
src/libextra/ringbuf.rs
src/libextra/rl.rs
src/libextra/sort.rs
src/libextra/stats.rs
src/libextra/sync.rs
src/libextra/term.rs
src/libextra/test.rs
src/libextra/time.rs
src/libextra/treemap.rs
src/libextra/uuid.rs [new file with mode: 0644]
src/librust/rust.rs
src/librustc/back/link.rs
src/librustc/back/passes.rs
src/librustc/back/upcall.rs
src/librustc/driver/driver.rs
src/librustc/front/test.rs
src/librustc/lib/llvm.rs
src/librustc/metadata/creader.rs
src/librustc/metadata/loader.rs
src/librustc/middle/astencode.rs
src/librustc/middle/check_const.rs
src/librustc/middle/check_match.rs
src/librustc/middle/const_eval.rs
src/librustc/middle/lang_items.rs
src/librustc/middle/lint.rs
src/librustc/middle/pat_util.rs
src/librustc/middle/stack_check.rs [new file with mode: 0644]
src/librustc/middle/trans/_match.rs
src/librustc/middle/trans/asm.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/builder.rs
src/librustc/middle/trans/cabi.rs
src/librustc/middle/trans/cabi_arm.rs
src/librustc/middle/trans/cabi_mips.rs
src/librustc/middle/trans/cabi_x86.rs
src/librustc/middle/trans/cabi_x86_64.rs
src/librustc/middle/trans/callee.rs
src/librustc/middle/trans/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/intrinsic.rs [new file with mode: 0644]
src/librustc/middle/trans/meth.rs
src/librustc/middle/trans/mod.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/typeck/check/mod.rs
src/librustc/middle/typeck/infer/combine.rs
src/librustc/rustc.rs
src/librustc/util/ppaux.rs
src/librustdoc/parse.rs
src/librusti/rusti.rs
src/librustpkg/rustpkg.rs
src/librustpkg/tests.rs
src/librustpkg/util.rs
src/libstd/at_vec.rs
src/libstd/bool.rs
src/libstd/c_str.rs
src/libstd/either.rs
src/libstd/fmt/mod.rs
src/libstd/fmt/parse.rs
src/libstd/hash.rs
src/libstd/hashmap.rs
src/libstd/io.rs
src/libstd/iterator.rs
src/libstd/kinds.rs
src/libstd/libc.rs
src/libstd/local_data.rs
src/libstd/num/f32.rs
src/libstd/num/f64.rs
src/libstd/num/int_macros.rs
src/libstd/num/num.rs
src/libstd/num/uint_macros.rs
src/libstd/os.rs
src/libstd/path.rs
src/libstd/prelude.rs
src/libstd/ptr.rs
src/libstd/rand.rs
src/libstd/rand/distributions.rs
src/libstd/result.rs
src/libstd/rt/args.rs
src/libstd/rt/borrowck.rs
src/libstd/rt/global_heap.rs
src/libstd/rt/io/extensions.rs
src/libstd/rt/io/mod.rs
src/libstd/rt/kill.rs
src/libstd/rt/local_heap.rs
src/libstd/rt/local_ptr.rs
src/libstd/rt/logging.rs
src/libstd/rt/mod.rs
src/libstd/rt/stack.rs
src/libstd/rt/task.rs
src/libstd/rt/test.rs
src/libstd/rt/thread.rs
src/libstd/rt/thread_local_storage.rs
src/libstd/rt/util.rs
src/libstd/rt/uv/mod.rs
src/libstd/rt/uv/uvio.rs
src/libstd/rt/uv/uvll.rs
src/libstd/run.rs
src/libstd/select.rs
src/libstd/std.rs
src/libstd/str.rs
src/libstd/str/ascii.rs
src/libstd/sys.rs
src/libstd/task/local_data_priv.rs
src/libstd/task/mod.rs
src/libstd/to_bytes.rs
src/libstd/to_str.rs
src/libstd/trie.rs
src/libstd/tuple.rs
src/libstd/unstable/atomics.rs
src/libstd/unstable/dynamic_lib.rs
src/libstd/unstable/finally.rs
src/libstd/unstable/intrinsics.rs
src/libstd/unstable/lang.rs
src/libstd/unstable/mod.rs
src/libstd/unstable/sync.rs
src/libstd/vec.rs
src/libsyntax/ast.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/env.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/ifmt.rs
src/libsyntax/ext/quote.rs
src/libsyntax/parse/attr.rs
src/libsyntax/parse/lexer.rs
src/libsyntax/parse/parser.rs
src/libsyntax/parse/token.rs
src/rt/boxed_region.cpp
src/rt/rust_builtin.cpp
src/rt/rust_env.cpp [deleted file]
src/rt/rust_env.h [deleted file]
src/rt/rust_globals.h
src/rt/rust_log.cpp
src/rt/rust_log.h [deleted file]
src/rt/rust_refcount.h [deleted file]
src/rt/rust_signal.h [deleted file]
src/rt/rust_stack.cpp [deleted file]
src/rt/rust_stack.h [deleted file]
src/rt/rust_type.h
src/rt/rust_upcall.cpp
src/rt/rust_upcall.h [deleted file]
src/rt/rust_util.h
src/rt/rust_uv.cpp
src/rt/rustrt.def.in
src/rustllvm/RustWrapper.cpp
src/rustllvm/rustllvm.def.in
src/snapshots.txt
src/test/auxiliary/cci_capture_clause.rs
src/test/auxiliary/cci_class_5.rs
src/test/auxiliary/cci_class_cast.rs
src/test/auxiliary/crate-method-reexport-grrrrrrr2.rs
src/test/auxiliary/crateresolve5-1.rs
src/test/auxiliary/crateresolve5-2.rs
src/test/auxiliary/extern-crosscrate-source.rs
src/test/auxiliary/iss.rs [new file with mode: 0644]
src/test/auxiliary/issue-2526.rs
src/test/auxiliary/issue2378a.rs
src/test/auxiliary/issue_2316_b.rs
src/test/auxiliary/issue_3907.rs [new file with mode: 0644]
src/test/auxiliary/issue_8401.rs [new file with mode: 0644]
src/test/auxiliary/moves_based_on_type_lib.rs
src/test/auxiliary/trait_default_method_xc_aux.rs
src/test/bench/core-std.rs
src/test/bench/msgsend-ring-mutex-arcs.rs
src/test/bench/msgsend-ring-rw-arcs.rs
src/test/bench/noise.rs
src/test/bench/rt-messaging-ping-pong.rs
src/test/bench/rt-parfib.rs
src/test/bench/shootout-ackermann.rs
src/test/bench/shootout-fasta.rs
src/test/bench/shootout-fibo.rs
src/test/bench/shootout-k-nucleotide-pipes.rs
src/test/bench/sudoku.rs
src/test/bench/task-perf-jargon-metal-smoke.rs
src/test/codegen/scalar-function-call.rs
src/test/compile-fail/core-tls-store-pointer.rs
src/test/compile-fail/issue-2817.rs [deleted file]
src/test/compile-fail/issue-3651-2.rs [deleted file]
src/test/compile-fail/issue-3907.rs [new file with mode: 0644]
src/test/compile-fail/issue-5439.rs [new file with mode: 0644]
src/test/compile-fail/issue-5543.rs
src/test/compile-fail/issue-6610.rs [new file with mode: 0644]
src/test/compile-fail/lint-unused-unsafe.rs
src/test/compile-fail/macro-local-data-key-priv.rs [new file with mode: 0644]
src/test/compile-fail/qquote-1.rs
src/test/compile-fail/qquote-2.rs
src/test/compile-fail/static-vec-repeat-not-constant.rs [new file with mode: 0644]
src/test/compile-fail/warn-foreign-int-types.rs
src/test/debug-info/basic-types.rs
src/test/debug-info/borrowed-basic.rs
src/test/debug-info/borrowed-c-style-enum.rs
src/test/debug-info/borrowed-enum.rs
src/test/debug-info/borrowed-managed-basic.rs
src/test/debug-info/borrowed-struct.rs
src/test/debug-info/borrowed-tuple.rs
src/test/debug-info/borrowed-unique-basic.rs
src/test/debug-info/box.rs
src/test/debug-info/boxed-struct.rs
src/test/debug-info/boxed-vec.rs
src/test/debug-info/by-value-struct-argument.rs [new file with mode: 0644]
src/test/debug-info/c-style-enum-in-composite.rs
src/test/debug-info/c-style-enum.rs
src/test/debug-info/closure-in-generic-function.rs [new file with mode: 0644]
src/test/debug-info/destructured-fn-argument.rs
src/test/debug-info/destructured-local.rs
src/test/debug-info/evec-in-struct.rs
src/test/debug-info/generic-function.rs [new file with mode: 0644]
src/test/debug-info/generic-functions-nested.rs [new file with mode: 0644]
src/test/debug-info/generic-method-on-generic-struct.rs [new file with mode: 0644]
src/test/debug-info/generic-static-method-on-struct-and-enum.rs [new file with mode: 0644]
src/test/debug-info/generic-struct-style-enum.rs [new file with mode: 0644]
src/test/debug-info/generic-struct.rs [new file with mode: 0644]
src/test/debug-info/generic-trait-generic-static-default-method.rs [new file with mode: 0644]
src/test/debug-info/generic-tuple-style-enum.rs [new file with mode: 0644]
src/test/debug-info/lexical-scope-in-parameterless-closure.rs [new file with mode: 0644]
src/test/debug-info/managed-enum.rs
src/test/debug-info/managed-pointer-within-unique-vec.rs
src/test/debug-info/managed-pointer-within-unique.rs
src/test/debug-info/method-on-enum.rs [new file with mode: 0644]
src/test/debug-info/method-on-generic-struct.rs [new file with mode: 0644]
src/test/debug-info/method-on-struct.rs [new file with mode: 0644]
src/test/debug-info/method-on-trait.rs [new file with mode: 0644]
src/test/debug-info/method-on-tuple-struct.rs [new file with mode: 0644]
src/test/debug-info/multiple-functions-equal-var-names.rs
src/test/debug-info/multiple-functions.rs
src/test/debug-info/nil-enum.rs
src/test/debug-info/option-like-enum.rs
src/test/debug-info/packed-struct-with-destructor.rs
src/test/debug-info/packed-struct.rs
src/test/debug-info/self-in-default-method.rs [new file with mode: 0644]
src/test/debug-info/self-in-generic-default-method.rs [new file with mode: 0644]
src/test/debug-info/simple-struct.rs
src/test/debug-info/simple-tuple.rs
src/test/debug-info/static-method-on-struct-and-enum.rs [new file with mode: 0644]
src/test/debug-info/struct-in-enum.rs
src/test/debug-info/struct-in-struct.rs
src/test/debug-info/struct-style-enum.rs
src/test/debug-info/struct-with-destructor.rs
src/test/debug-info/trait-generic-static-default-method.rs [new file with mode: 0644]
src/test/debug-info/tuple-in-struct.rs
src/test/debug-info/tuple-in-tuple.rs
src/test/debug-info/tuple-struct.rs [new file with mode: 0644]
src/test/debug-info/tuple-style-enum.rs
src/test/debug-info/unique-enum.rs
src/test/debug-info/vec-slices.rs
src/test/debug-info/vec.rs
src/test/pretty/block-arg-disambig.rs
src/test/pretty/disamb-stmt-expr.rs
src/test/pretty/fn-types.rs
src/test/pretty/for-comment.rs
src/test/pretty/match-naked-expr-long.rs
src/test/pretty/match-naked-expr.rs
src/test/pretty/struct-tuple.rs
src/test/pretty/vec-comments.pp
src/test/pretty/vec-comments.rs
src/test/pretty/vec-type.pp
src/test/pretty/vec-type.rs
src/test/run-fail/args-fail.rs
src/test/run-fail/borrowck-wg-autoderef-and-autoborrowvec-combined-fail-issue-6272.rs
src/test/run-fail/borrowck-wg-fail-2.rs
src/test/run-fail/borrowck-wg-fail-3.rs
src/test/run-fail/borrowck-wg-fail-object-arg.rs
src/test/run-fail/borrowck-wg-imm-then-mut.rs
src/test/run-fail/borrowck-wg-mut-then-imm.rs
src/test/run-fail/bug-811.rs
src/test/run-fail/die-macro-expr.rs
src/test/run-fail/divide-by-zero.rs
src/test/run-fail/doublefail.rs
src/test/run-fail/explicit-fail-msg.rs
src/test/run-fail/expr-if-fail.rs
src/test/run-fail/expr-match-fail.rs
src/test/run-fail/extern-fail.rs
src/test/run-fail/issue-2156.rs
src/test/run-fail/issue-2444.rs
src/test/run-fail/issue-3029.rs
src/test/run-fail/issue-948.rs
src/test/run-fail/linked-failure2.rs
src/test/run-fail/match-bot-fail.rs
src/test/run-fail/mod-zero.rs
src/test/run-fail/rhs-type.rs
src/test/run-fail/rt-set-exit-status-fail2.rs
src/test/run-fail/task-comm-recv-block.rs
src/test/run-fail/task-spawn-barefn.rs
src/test/run-fail/unwind-assert.rs
src/test/run-fail/unwind-closure.rs
src/test/run-fail/unwind-initializer-indirect.rs
src/test/run-fail/unwind-initializer.rs
src/test/run-fail/unwind-interleaved.rs
src/test/run-fail/unwind-iter.rs
src/test/run-fail/unwind-iter2.rs
src/test/run-fail/unwind-lambda.rs
src/test/run-fail/unwind-misc-1.rs
src/test/run-fail/unwind-nested.rs
src/test/run-fail/unwind-partial-box.rs
src/test/run-fail/unwind-partial-unique.rs
src/test/run-fail/unwind-partial-vec.rs
src/test/run-fail/unwind-rec.rs
src/test/run-fail/unwind-rec2.rs
src/test/run-fail/unwind-resource-fail.rs
src/test/run-fail/unwind-stacked.rs
src/test/run-fail/unwind-tup.rs
src/test/run-fail/unwind-tup2.rs
src/test/run-fail/unwind-uninitialized.rs
src/test/run-fail/while-body-fails.rs
src/test/run-fail/while-fail.rs
src/test/run-fail/zip-different-lengths.rs [deleted file]
src/test/run-pass-fulldeps/issue-1926.rs
src/test/run-pass-fulldeps/qquote.rs
src/test/run-pass-fulldeps/quote-tokens.rs
src/test/run-pass/anon-extern-mod-cross-crate-2.rs
src/test/run-pass/anon-extern-mod.rs
src/test/run-pass/argument-passing.rs
src/test/run-pass/arith-unsigned.rs
src/test/run-pass/assign-assign.rs
src/test/run-pass/attr-start.rs
src/test/run-pass/bind-by-move.rs
src/test/run-pass/binops.rs
src/test/run-pass/block-arg-in-parentheses.rs
src/test/run-pass/block-arg.rs
src/test/run-pass/borrowck-mut-uniq.rs
src/test/run-pass/borrowck-pat-reassign-no-binding.rs
src/test/run-pass/borrowck-preserve-box-in-arm-not-taken.rs
src/test/run-pass/borrowck-preserve-box-in-pat.rs
src/test/run-pass/borrowck-preserve-box-sometimes-needed.rs
src/test/run-pass/borrowck-preserve-cond-box.rs
src/test/run-pass/box-in-tup.rs
src/test/run-pass/box-inside-if.rs
src/test/run-pass/box-inside-if2.rs
src/test/run-pass/break.rs
src/test/run-pass/c-stack-as-value.rs
src/test/run-pass/c-stack-returning-int64.rs
src/test/run-pass/capture_nil.rs
src/test/run-pass/cci_iter_exe.rs
src/test/run-pass/child-outlives-parent.rs
src/test/run-pass/class-cast-to-trait-multiple-types.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-cross-crate.rs
src/test/run-pass/class-methods.rs
src/test/run-pass/class-separate-impl.rs
src/test/run-pass/class-str-field.rs
src/test/run-pass/class-typarams.rs
src/test/run-pass/classes-cross-crate.rs
src/test/run-pass/classes-simple-method.rs
src/test/run-pass/classes-simple.rs
src/test/run-pass/cleanup-copy-mode.rs
src/test/run-pass/coerce-reborrow-imm-ptr-rcvr.rs
src/test/run-pass/comm.rs
src/test/run-pass/complex.rs
src/test/run-pass/conditional-compile.rs
src/test/run-pass/const-fields-and-indexing.rs
src/test/run-pass/const-region-ptrs.rs
src/test/run-pass/const-struct.rs
src/test/run-pass/const-vecs-and-slices.rs
src/test/run-pass/core-run-destroy.rs
src/test/run-pass/deep-vector2.rs
src/test/run-pass/deref.rs
src/test/run-pass/deriving-meta-multiple.rs
src/test/run-pass/deriving-meta.rs
src/test/run-pass/die-macro.rs
src/test/run-pass/do-empty-args.rs
src/test/run-pass/do-no-args.rs
src/test/run-pass/do-pure.rs
src/test/run-pass/double-unbox.rs
src/test/run-pass/drop-on-empty-block-exit.rs
src/test/run-pass/drop-on-ret.rs
src/test/run-pass/drop-trait-generic.rs
src/test/run-pass/drop-trait.rs
src/test/run-pass/empty-mutable-vec.rs
src/test/run-pass/enum-alignment.rs
src/test/run-pass/enum-disr-val-pretty.rs
src/test/run-pass/enum-export-inheritance.rs
src/test/run-pass/enum-variants.rs
src/test/run-pass/enum-vec-initializer.rs
src/test/run-pass/estr-slice.rs
src/test/run-pass/estr-uniq.rs
src/test/run-pass/evec-internal-boxes.rs
src/test/run-pass/evec-slice.rs
src/test/run-pass/exec-env.rs
src/test/run-pass/export-abstract-tag.rs
src/test/run-pass/export-glob-imports-target.rs
src/test/run-pass/export-tag-variant.rs
src/test/run-pass/expr-block-fn.rs
src/test/run-pass/expr-block-ref.rs
src/test/run-pass/expr-elseif-ref.rs
src/test/run-pass/expr-elseif-ref2.rs
src/test/run-pass/expr-empty-ret.rs
src/test/run-pass/expr-if-fail-all.rs
src/test/run-pass/expr-match-fail-all.rs
src/test/run-pass/expr-match.rs
src/test/run-pass/extern-call-deep.rs
src/test/run-pass/extern-call-deep2.rs
src/test/run-pass/extern-call-scrub.rs
src/test/run-pass/extern-call.rs
src/test/run-pass/extern-crosscrate.rs
src/test/run-pass/extern-mod-syntax.rs
src/test/run-pass/extern-pass-TwoU32s.rs
src/test/run-pass/extern-pass-TwoU64s-ref.rs
src/test/run-pass/extern-pass-TwoU64s.rs
src/test/run-pass/extern-pass-char.rs
src/test/run-pass/extern-pass-double.rs
src/test/run-pass/extern-pass-u32.rs
src/test/run-pass/extern-pass-u64.rs
src/test/run-pass/extern-return-TwoU16s.rs
src/test/run-pass/extern-return-TwoU32s.rs
src/test/run-pass/extern-return-TwoU64s.rs
src/test/run-pass/extern-return-TwoU8s.rs
src/test/run-pass/extern-stress.rs
src/test/run-pass/extern-yield.rs
src/test/run-pass/fn-coerce-field.rs
src/test/run-pass/fn-lval.rs
src/test/run-pass/fn-type-infer.rs
src/test/run-pass/foreign-call-no-runtime.rs
src/test/run-pass/foreign-dupe.rs
src/test/run-pass/foreign-fn-linkname.rs
src/test/run-pass/foreign-mod-unused-const.rs
src/test/run-pass/foreign-no-abi.rs
src/test/run-pass/foreign2.rs
src/test/run-pass/generic-drop-glue.rs
src/test/run-pass/generic-fn.rs
src/test/run-pass/generic-ivec-leak.rs
src/test/run-pass/generic-ivec.rs
src/test/run-pass/generic-recursive-tag.rs
src/test/run-pass/generic-tag-corruption.rs
src/test/run-pass/generic-tag-local.rs
src/test/run-pass/generic-tag-match.rs
src/test/run-pass/generic-tag.rs
src/test/run-pass/generic-type-synonym.rs
src/test/run-pass/getopts_ref.rs
src/test/run-pass/guards.rs
src/test/run-pass/html-literals.rs
src/test/run-pass/ifmt.rs
src/test/run-pass/import-glob-crate.rs
src/test/run-pass/import3.rs
src/test/run-pass/import4.rs
src/test/run-pass/import6.rs
src/test/run-pass/import7.rs
src/test/run-pass/init-res-into-things.rs
src/test/run-pass/instantiable.rs
src/test/run-pass/int.rs
src/test/run-pass/intrinsic-atomics-cc.rs
src/test/run-pass/intrinsic-move-val.rs
src/test/run-pass/intrinsics-math.rs
src/test/run-pass/invoke-external-foreign.rs
src/test/run-pass/issue-1696.rs
src/test/run-pass/issue-2214.rs
src/test/run-pass/issue-2288.rs
src/test/run-pass/issue-2311-2.rs
src/test/run-pass/issue-2312.rs
src/test/run-pass/issue-2428.rs
src/test/run-pass/issue-2445-b.rs
src/test/run-pass/issue-2445.rs
src/test/run-pass/issue-2463.rs
src/test/run-pass/issue-2526-a.rs
src/test/run-pass/issue-2633.rs
src/test/run-pass/issue-2718.rs
src/test/run-pass/issue-2804.rs
src/test/run-pass/issue-2904.rs
src/test/run-pass/issue-2989.rs
src/test/run-pass/issue-3012-2.rs
src/test/run-pass/issue-3429.rs
src/test/run-pass/issue-3563-3.rs
src/test/run-pass/issue-3574.rs
src/test/run-pass/issue-3743.rs
src/test/run-pass/issue-3860.rs
src/test/run-pass/issue-3878.rs
src/test/run-pass/issue-4107.rs
src/test/run-pass/issue-4387.rs
src/test/run-pass/issue-4464.rs [new file with mode: 0644]
src/test/run-pass/issue-4542.rs
src/test/run-pass/issue-4735.rs
src/test/run-pass/issue-4759-1.rs [new file with mode: 0644]
src/test/run-pass/issue-4759.rs [new file with mode: 0644]
src/test/run-pass/issue-5192.rs
src/test/run-pass/issue-5550.rs
src/test/run-pass/issue-5572.rs
src/test/run-pass/issue-5666.rs [new file with mode: 0644]
src/test/run-pass/issue-5741.rs
src/test/run-pass/issue-5884.rs [new file with mode: 0644]
src/test/run-pass/issue-5917.rs [new file with mode: 0644]
src/test/run-pass/issue-5926.rs [new file with mode: 0644]
src/test/run-pass/issue-6318.rs [new file with mode: 0644]
src/test/run-pass/issue-6470.rs [new file with mode: 0644]
src/test/run-pass/issue-6557.rs [new file with mode: 0644]
src/test/run-pass/issue-6898.rs [new file with mode: 0644]
src/test/run-pass/issue-6919.rs [new file with mode: 0644]
src/test/run-pass/issue-7222.rs [new file with mode: 0644]
src/test/run-pass/issue-8248.rs [new file with mode: 0644]
src/test/run-pass/issue-8249.rs [new file with mode: 0644]
src/test/run-pass/issue-8398.rs [new file with mode: 0644]
src/test/run-pass/issue-8401.rs [new file with mode: 0644]
src/test/run-pass/issue-8498.rs [new file with mode: 0644]
src/test/run-pass/issue-979.rs
src/test/run-pass/istr.rs
src/test/run-pass/item-attributes.rs
src/test/run-pass/ivec-pass-by-value.rs
src/test/run-pass/ivec-tag.rs
src/test/run-pass/lambda-infer-unresolved.rs
src/test/run-pass/large-records.rs
src/test/run-pass/leak-box-as-tydesc.rs
src/test/run-pass/leak-tag-copy.rs
src/test/run-pass/leak-unique-as-tydesc.rs
src/test/run-pass/let-destruct-fresh-mem.rs
src/test/run-pass/liveness-assign-imm-local-after-loop.rs
src/test/run-pass/liveness-assign-imm-local-after-ret.rs
src/test/run-pass/log-err-phi.rs
src/test/run-pass/log-knows-the-names-of-variants-in-std.rs
src/test/run-pass/log-linearized.rs
src/test/run-pass/long-while.rs
src/test/run-pass/loop-break-cont-1.rs
src/test/run-pass/macro-local-data-key.rs [new file with mode: 0644]
src/test/run-pass/match-borrowed_str.rs
src/test/run-pass/match-implicit-copy-unique.rs
src/test/run-pass/match-naked-record-expr.rs
src/test/run-pass/match-naked-record.rs
src/test/run-pass/match-pattern-no-type-params.rs
src/test/run-pass/match-pattern-simple.rs
src/test/run-pass/match-phi.rs
src/test/run-pass/match-pipe-binding.rs [new file with mode: 0644]
src/test/run-pass/match-with-ret-arm.rs
src/test/run-pass/mod-view-items.rs
src/test/run-pass/module-qualified-struct-destructure.rs
src/test/run-pass/monad.rs
src/test/run-pass/move-3.rs
src/test/run-pass/move-nullary-fn.rs
src/test/run-pass/move-out-of-field.rs
src/test/run-pass/mut-vstore-expr.rs
src/test/run-pass/mutable-alias-vec.rs
src/test/run-pass/mutable-vec-drop.rs
src/test/run-pass/nested-matchs.rs
src/test/run-pass/nested-pattern.rs
src/test/run-pass/nested-patterns.rs
src/test/run-pass/new-vstore-mut-box-syntax.rs
src/test/run-pass/newlambdas.rs
src/test/run-pass/newtype-struct-drop-run.rs
src/test/run-pass/newtype-struct-with-dtor.rs
src/test/run-pass/option-ext.rs
src/test/run-pass/option-unwrap.rs
src/test/run-pass/output-slot-variants.rs
src/test/run-pass/parse-fail.rs
src/test/run-pass/path.rs
src/test/run-pass/pattern-bound-var-in-for-each.rs
src/test/run-pass/pattern-in-closure.rs
src/test/run-pass/pred-not-bool.rs
src/test/run-pass/pub-extern-privacy.rs
src/test/run-pass/pub-use-xcrate.rs
src/test/run-pass/pub_use_mods_xcrate_exe.rs
src/test/run-pass/rcvr-borrowed-to-slice.rs
src/test/run-pass/region-dependent-addr-of.rs
src/test/run-pass/regions-appearance-constraint.rs
src/test/run-pass/regions-bot.rs
src/test/run-pass/regions-creating-enums5.rs
src/test/run-pass/regions-fn-subtyping.rs
src/test/run-pass/regions-mock-trans.rs
src/test/run-pass/repeat-expr-in-static.rs [new file with mode: 0644]
src/test/run-pass/resource-assign-is-not-copy.rs
src/test/run-pass/resource-cycle2.rs
src/test/run-pass/resource-destruct.rs
src/test/run-pass/resource-in-struct.rs
src/test/run-pass/return-nil.rs
src/test/run-pass/send-iloop.rs
src/test/run-pass/send-resource.rs
src/test/run-pass/send-type-inference.rs
src/test/run-pass/shadow.rs
src/test/run-pass/size-and-align.rs
src/test/run-pass/smallest-hello-world.rs
src/test/run-pass/spawn-fn.rs
src/test/run-pass/spawn-types.rs
src/test/run-pass/stat.rs
src/test/run-pass/static-impl.rs
src/test/run-pass/static-mut-foreign.rs
src/test/run-pass/str-append.rs
src/test/run-pass/string-self-append.rs
src/test/run-pass/struct-like-variant-construct.rs
src/test/run-pass/struct-order-of-eval-1.rs
src/test/run-pass/struct-order-of-eval-2.rs
src/test/run-pass/struct-return.rs
src/test/run-pass/swap-overlapping.rs
src/test/run-pass/syntax-extension-fmt.rs
src/test/run-pass/syntax-extension-minor.rs
src/test/run-pass/syntax-extension-source-utils.rs
src/test/run-pass/tag-in-block.rs
src/test/run-pass/task-comm-0.rs
src/test/run-pass/task-comm-10.rs
src/test/run-pass/task-comm-11.rs
src/test/run-pass/task-comm-12.rs
src/test/run-pass/task-comm-13.rs
src/test/run-pass/task-comm-3.rs
src/test/run-pass/task-comm-4.rs
src/test/run-pass/task-comm-5.rs
src/test/run-pass/task-comm-6.rs
src/test/run-pass/task-comm-7.rs
src/test/run-pass/task-killjoin-rsrc.rs
src/test/run-pass/task-killjoin.rs
src/test/run-pass/task-life-0.rs
src/test/run-pass/task-spawn-move-and-copy.rs
src/test/run-pass/terminate-in-initializer.rs
src/test/run-pass/trait-default-method-xc.rs
src/test/run-pass/trait-inheritance-num5.rs
src/test/run-pass/trait-static-method-overwriting.rs
src/test/run-pass/trait-to-str.rs
src/test/run-pass/traits-default-method-mut.rs
src/test/run-pass/type-in-nested-module.rs
src/test/run-pass/type-param-constraints.rs
src/test/run-pass/type-params-in-for-each.rs
src/test/run-pass/typestate-cfg-nesting.rs
src/test/run-pass/uint.rs
src/test/run-pass/unary-minus-suffix-inference.rs
src/test/run-pass/unique-assign-drop.rs
src/test/run-pass/unique-containing-tag.rs
src/test/run-pass/unique-copy-box.rs
src/test/run-pass/unique-decl.rs
src/test/run-pass/unique-drop-complex.rs
src/test/run-pass/unique-init.rs
src/test/run-pass/unique-move-drop.rs
src/test/run-pass/unique-object-move.rs
src/test/run-pass/unique-pinned-nocopy-2.rs
src/test/run-pass/unique-send.rs
src/test/run-pass/unit.rs
src/test/run-pass/unnamed_argument_mode.rs
src/test/run-pass/unreachable-code-1.rs
src/test/run-pass/unreachable-code.rs
src/test/run-pass/unused-move-capture.rs
src/test/run-pass/unused-move.rs
src/test/run-pass/unwind-box.rs
src/test/run-pass/unwind-resource2.rs
src/test/run-pass/unwind-unique.rs
src/test/run-pass/use-uninit-match.rs
src/test/run-pass/use-uninit-match2.rs
src/test/run-pass/use.rs
src/test/run-pass/utf8_chars.rs
src/test/run-pass/vec-drop.rs
src/test/run-pass/vec-ivec-deadlock.rs
src/test/run-pass/vec-matching-autoslice.rs
src/test/run-pass/vec-slice-drop.rs
src/test/run-pass/vec-tail-matching.rs
src/test/run-pass/vector-no-ann-2.rs
src/test/run-pass/weird-exprs.rs
src/test/run-pass/while-flow-graph.rs
src/test/run-pass/while-loop-constraints-2.rs
src/test/run-pass/while-with-break.rs
src/test/run-pass/x86stdcall2.rs
src/test/run-pass/xcrate-unit-struct.rs
src/test/run-pass/yield.rs
src/test/run-pass/yield1.rs
src/test/run-pass/yield2.rs
src/test/run-pass/zip-same-length.rs [deleted file]

index 7f4f896076f3bb227fc583ac77a984bf368d9f6e..a93d5801dccf8b26a68426a672516dc5830dbfe1 100644 (file)
@@ -481,8 +481,8 @@ msgstr ""
 #, no-wrap
 msgid ""
 "~~~\n"
-"impl<A, T: Iterator<A>> FromIterator<A, T> for ~[A] {\n"
-"    pub fn from_iterator(iterator: &mut T) -> ~[A] {\n"
+"impl<A> FromIterator<A> for ~[A] {\n"
+"    pub fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> ~[A] {\n"
 "        let (lower, _) = iterator.size_hint();\n"
 "        let mut xs = with_capacity(lower);\n"
 "        for x in iterator {\n"
index d285253ffe200158075a3e305131aec574079966..8b06c170f035f90c3c735de91d1dc7b26275ebae 100644 (file)
@@ -582,7 +582,7 @@ a referencing source file, or by the name of the crate itself.
 
 Each source file contains a sequence of zero or more `item` definitions,
 and may optionally begin with any number of `attributes` that apply to the containing module.
-Atributes on the anonymous crate module define important metadata that influences
+Attributes on the anonymous crate module define important metadata that influences
 the behavior of the compiler.
 
 ~~~~~~~~
@@ -1273,7 +1273,7 @@ since the typechecker checks that any type with an implementation of `Circle` al
 
 In type-parameterized functions,
 methods of the supertrait may be called on values of subtrait-bound type parameters.
-Refering to the previous example of `trait Circle : Shape`:
+Referring to the previous example of `trait Circle : Shape`:
 
 ~~~
 # trait Shape { fn area(&self) -> float; }
@@ -1914,7 +1914,7 @@ A field access on a record is an [lvalue](#lvalues-rvalues-and-temporaries) refe
 When the field is mutable, it can be [assigned](#assignment-expressions) to.
 
 When the type of the expression to the left of the dot is a pointer to a record or structure,
-it is automatically derferenced to make the field access possible.
+it is automatically dereferenced to make the field access possible.
 
 
 ### Vector expressions
index 19cd58bd3b403e03bf8d7aa46b01f45636ca12cb..1f47c3df14f89b346dd53542334f3d303f51e01f 100644 (file)
@@ -112,10 +112,10 @@ iterator object. For example, vector slices several iterators available:
 
 * `iter()` and `rev_iter()`, for immutable references to the elements
 * `mut_iter()` and `mut_rev_iter()`, for mutable references to the elements
-* `consume_iter()` and `consume_rev_iter`, to move the elements out by-value
+* `move_iter()` and `move_rev_iter`, to move the elements out by-value
 
 A typical mutable container will implement at least `iter()`, `mut_iter()` and
-`consume_iter()` along with the reverse variants if it maintains an order.
+`move_iter()` along with the reverse variants if it maintains an order.
 
 ### Freezing
 
@@ -139,9 +139,9 @@ and `&mut`.
 
 ## Iterator adaptors
 
-The `IteratorUtil` trait implements common algorithms as methods extending
-every `Iterator` implementation. For example, the `fold` method will accumulate
-the items yielded by an `Iterator` into a single value:
+The `Iterator` trait provides many common algorithms as default methods. For
+example, the `fold` method will accumulate the items yielded by an `Iterator`
+into a single value:
 
 ~~~
 let xs = [1, 9, 2, 3, 14, 12];
@@ -154,14 +154,10 @@ Some adaptors return an adaptor object implementing the `Iterator` trait itself:
 ~~~
 let xs = [1, 9, 2, 3, 14, 12];
 let ys = [5, 2, 1, 8];
-let sum = xs.iter().chain_(ys.iter()).fold(0, |a, b| a + *b);
+let sum = xs.iter().chain(ys.iter()).fold(0, |a, b| a + *b);
 assert_eq!(sum, 57);
 ~~~
 
-Note that some adaptors like the `chain_` method above use a trailing
-underscore to work around an issue with method resolve. The underscores will be
-dropped when they become unnecessary.
-
 ## For loops
 
 The `for` keyword can be used as sugar for iterating through any iterator:
@@ -212,7 +208,7 @@ Iterators offer generic conversion to containers with the `collect` adaptor:
 
 ~~~
 let xs = [0, 1, 1, 2, 3, 5, 8];
-let ys = xs.rev_iter().skip(1).transform(|&x| x * 2).collect::<~[int]>();
+let ys = xs.rev_iter().skip(1).map(|&x| x * 2).collect::<~[int]>();
 assert_eq!(ys, ~[10, 6, 4, 2, 2, 0]);
 ~~~
 
@@ -224,8 +220,8 @@ implementing the `FromIterator` trait. For example, the implementation for
 vectors is as follows:
 
 ~~~
-impl<A, T: Iterator<A>> FromIterator<A, T> for ~[A] {
-    pub fn from_iterator(iterator: &mut T) -> ~[A] {
+impl<A> FromIterator<A> for ~[A] {
+    pub fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> ~[A] {
         let (lower, _) = iterator.size_hint();
         let mut xs = with_capacity(lower);
         for x in iterator {
@@ -307,13 +303,13 @@ for &x in it.invert() {
 The `rev_iter` and `mut_rev_iter` methods on vectors just return an inverted
 version of the standard immutable and mutable vector iterators.
 
-The `chain_`, `transform`, `filter`, `filter_map` and `peek` adaptors are
+The `chain`, `map`, `filter`, `filter_map` and `inspect` adaptors are
 `DoubleEndedIterator` implementations if the underlying iterators are.
 
 ~~~
 let xs = [1, 2, 3, 4];
 let ys = [5, 6, 7, 8];
-let mut it = xs.iter().chain_(ys.iter()).transform(|&x| x * 2);
+let mut it = xs.iter().chain(ys.iter()).map(|&x| x * 2);
 
 printfln!("%?", it.next()); // prints `Some(2)`
 
@@ -329,13 +325,13 @@ The `RandomAccessIterator` trait represents an iterator offering random access
 to the whole range. The `indexable` method retrieves the number of elements
 accessible with the `idx` method.
 
-The `chain_` adaptor is an implementation of `RandomAccessIterator` if the
+The `chain` adaptor is an implementation of `RandomAccessIterator` if the
 underlying iterators are.
 
 ~~~
 let xs = [1, 2, 3, 4, 5];
 let ys = ~[7, 9, 11];
-let mut it = xs.iter().chain_(ys.iter());
+let mut it = xs.iter().chain(ys.iter());
 printfln!("%?", it.idx(0)); // prints `Some(&1)`
 printfln!("%?", it.idx(5)); // prints `Some(&7)`
 printfln!("%?", it.idx(7)); // prints `Some(&11)`
index d1aa793e5fc1b83d0501baea22f99cbf542b66c8..278273b16719321c17b5be3445f140ec12e1a5c5 100644 (file)
@@ -19,6 +19,7 @@ extern {
     fn snappy_max_compressed_length(source_length: size_t) -> size_t;
 }
 
+#[fixed_stack_segment]
 fn main() {
     let x = unsafe { snappy_max_compressed_length(100) };
     println(fmt!("max compressed length of a 100 byte buffer: %?", x));
@@ -35,6 +36,11 @@ interfaces that aren't thread-safe, and almost any function that takes a pointer
 valid for all possible inputs since the pointer could be dangling, and raw pointers fall outside of
 Rust's safe memory model.
 
+Finally, the `#[fixed_stack_segment]` annotation that appears on
+`main()` instructs the Rust compiler that when `main()` executes, it
+should request a "very large" stack segment.  More details on
+stack management can be found in the following sections.
+
 When declaring the argument types to a foreign function, the Rust compiler will not check if the
 declaration is correct, so specifying it correctly is part of keeping the binding correct at
 runtime.
@@ -75,6 +81,8 @@ length is number of elements currently contained, and the capacity is the total
 the allocated memory. The length is less than or equal to the capacity.
 
 ~~~~ {.xfail-test}
+#[fixed_stack_segment]
+#[inline(never)]
 pub fn validate_compressed_buffer(src: &[u8]) -> bool {
     unsafe {
         snappy_validate_compressed_buffer(vec::raw::to_ptr(src), src.len() as size_t) == 0
@@ -86,6 +94,36 @@ The `validate_compressed_buffer` wrapper above makes use of an `unsafe` block, b
 guarantee that calling it is safe for all inputs by leaving off `unsafe` from the function
 signature.
 
+The `validate_compressed_buffer` wrapper is also annotated with two
+attributes `#[fixed_stack_segment]` and `#[inline(never)]`. The
+purpose of these attributes is to guarantee that there will be
+sufficient stack for the C function to execute. This is necessary
+because Rust, unlike C, does not assume that the stack is allocated in
+one continuous chunk. Instead, we rely on a *segmented stack* scheme,
+in which the stack grows and shrinks as necessary.  C code, however,
+expects one large stack, and so callers of C functions must request a
+large stack segment to ensure that the C routine will not run off the
+end of the stack.
+
+The compiler includes a lint mode that will report an error if you
+call a C function without a `#[fixed_stack_segment]` attribute. More
+details on the lint mode are given in a later section.
+
+You may be wondering why we include a `#[inline(never)]` directive.
+This directive informs the compiler never to inline this function.
+While not strictly necessary, it is usually a good idea to use an
+`#[inline(never)]` directive in concert with `#[fixed_stack_segment]`.
+The reason is that if a fn annotated with `fixed_stack_segment` is
+inlined, then its caller also inherits the `fixed_stack_segment`
+annotation. This means that rather than requesting a large stack
+segment only for the duration of the call into C, the large stack
+segment would be used for the entire duration of the caller. This is
+not necessarily *bad* -- it can for example be more efficient,
+particularly if `validate_compressed_buffer()` is called multiple
+times in a row -- but it does work against the purpose of the
+segmented stack scheme, which is to keep stacks small and thus
+conserve address space.
+
 The `snappy_compress` and `snappy_uncompress` functions are more complex, since a buffer has to be
 allocated to hold the output too.
 
@@ -96,6 +134,8 @@ the true length after compression for setting the length.
 
 ~~~~ {.xfail-test}
 pub fn compress(src: &[u8]) -> ~[u8] {
+    #[fixed_stack_segment]; #[inline(never)];
+    
     unsafe {
         let srclen = src.len() as size_t;
         let psrc = vec::raw::to_ptr(src);
@@ -116,6 +156,8 @@ format and `snappy_uncompressed_length` will retrieve the exact buffer size requ
 
 ~~~~ {.xfail-test}
 pub fn uncompress(src: &[u8]) -> Option<~[u8]> {
+    #[fixed_stack_segment]; #[inline(never)];
+    
     unsafe {
         let srclen = src.len() as size_t;
         let psrc = vec::raw::to_ptr(src);
@@ -139,6 +181,99 @@ pub fn uncompress(src: &[u8]) -> Option<~[u8]> {
 For reference, the examples used here are also available as an [library on
 GitHub](https://github.com/thestinger/rust-snappy).
 
+# Automatic wrappers
+
+Sometimes writing Rust wrappers can be quite tedious.  For example, if
+function does not take any pointer arguments, often there is no need
+for translating types. In such cases, it is usually still a good idea
+to have a Rust wrapper so as to manage the segmented stacks, but you
+can take advantage of the (standard) `externfn!` macro to remove some
+of the tedium.
+
+In the initial section, we showed an extern block that added a call
+to a specific snappy API:
+
+~~~~ {.xfail-test}
+use std::libc::size_t;
+
+#[link_args = "-lsnappy"]
+extern {
+    fn snappy_max_compressed_length(source_length: size_t) -> size_t;
+}
+
+#[fixed_stack_segment]
+fn main() {
+    let x = unsafe { snappy_max_compressed_length(100) };
+    println(fmt!("max compressed length of a 100 byte buffer: %?", x));
+}
+~~~~
+
+To avoid the need to create a wrapper fn for `snappy_max_compressed_length()`,
+and also to avoid the need to think about `#[fixed_stack_segment]`, we
+could simply use the `externfn!` macro instead, as shown here:
+
+~~~~ {.xfail-test}
+use std::libc::size_t;
+
+externfn!(#[link_args = "-lsnappy"]
+          fn snappy_max_compressed_length(source_length: size_t) -> size_t)
+
+fn main() {
+    let x = unsafe { snappy_max_compressed_length(100) };
+    println(fmt!("max compressed length of a 100 byte buffer: %?", x));
+}
+~~~~
+
+As you can see from the example, `externfn!` replaces the extern block
+entirely. After macro expansion, it will create something like this:
+
+~~~~ {.xfail-test}
+use std::libc::size_t;
+
+// Automatically generated by
+//   externfn!(#[link_args = "-lsnappy"]
+//             fn snappy_max_compressed_length(source_length: size_t) -> size_t)
+unsafe fn snappy_max_compressed_length(source_length: size_t) -> size_t {
+    #[fixed_stack_segment]; #[inline(never)];
+    return snappy_max_compressed_length(source_length);
+    
+    #[link_args = "-lsnappy"]
+    extern {
+        fn snappy_max_compressed_length(source_length: size_t) -> size_t;
+    }
+}
+
+fn main() {
+    let x = unsafe { snappy_max_compressed_length(100) };
+    println(fmt!("max compressed length of a 100 byte buffer: %?", x));
+}
+~~~~
+
+# Segmented stacks and the linter
+
+By default, whenever you invoke a non-Rust fn, the `cstack` lint will
+check that one of the following conditions holds:
+
+1. The call occurs inside of a fn that has been annotated with
+   `#[fixed_stack_segment]`;
+2. The call occurs inside of an `extern fn`;
+3. The call occurs within a stack closure created by some other
+   safe fn.
+   
+All of these conditions ensure that you are running on a large stack
+segmented. However, they are sometimes too strict. If your application
+will be making many calls into C, it is often beneficial to promote
+the `#[fixed_stack_segment]` attribute higher up the call chain.  For
+example, the Rust compiler actually labels main itself as requiring a
+`#[fixed_stack_segment]`. In such cases, the linter is just an
+annoyance, because all C calls that occur from within the Rust
+compiler are made on a large stack. Another situation where this
+frequently occurs is on a 64-bit architecture, where large stacks are
+the default. In cases, you can disable the linter by including a
+`#[allow(cstack)]` directive somewhere, which permits violations of
+the "cstack" rules given above (you can also use `#[warn(cstack)]` to
+convert the errors into warnings, if you prefer).
+
 # Destructors
 
 Foreign libraries often hand off ownership of resources to the calling code,
@@ -161,6 +296,9 @@ pub struct Unique<T> {
 
 impl<T: Send> Unique<T> {
     pub fn new(value: T) -> Unique<T> {
+        #[fixed_stack_segment];
+        #[inline(never)];
+        
         unsafe {
             let ptr = malloc(std::sys::size_of::<T>() as size_t) as *mut T;
             assert!(!ptr::is_null(ptr));
@@ -184,6 +322,9 @@ impl<T: Send> Unique<T> {
 #[unsafe_destructor]
 impl<T: Send> Drop for Unique<T> {
     fn drop(&self) {
+        #[fixed_stack_segment];
+        #[inline(never)];
+        
         unsafe {
             let x = intrinsics::init(); // dummy value to swap in
             // moving the object out is needed to call the destructor
index f4264b0d5afc36d21b4ea116f6a607a9ad933fda..1813356a1f309ed0d1a900a76fac8472005ae15e 100644 (file)
@@ -436,7 +436,7 @@ control reaches the end of the block:
 fn signum(x: int) -> int {
     if x < 0 { -1 }
     else if x > 0 { 1 }
-    else { return 0 }
+    else { 0 }
 }
 ~~~~
 
index 0aeeec3b487e80f2bc05ca0cc9f1c627dd388d70..e6969a79f5a79abe95a97dd70a37a231e01b424b 100644 (file)
--- a/mk/rt.mk
+++ b/mk/rt.mk
@@ -68,9 +68,7 @@ RUNTIME_CXXS_$(1)_$(2) := \
               rt/sync/rust_thread.cpp \
               rt/rust_builtin.cpp \
               rt/rust_run_program.cpp \
-              rt/rust_env.cpp \
               rt/rust_rng.cpp \
-              rt/rust_stack.cpp \
               rt/rust_upcall.cpp \
               rt/rust_uv.cpp \
               rt/rust_crate_map.cpp \
index fce6e8a9e2fccf190bf34d8c1a51ec93e3202f7e..0d798f4cc1b4c49deadc7426d27bc53cd43fd52a 100644 (file)
@@ -69,7 +69,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(3)): \
                | $$(TLIB$(1)_T_$(2)_H_$(3))/
        @$$(call E, compile_and_link: $$@)
        $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBSYNTAX_GLOB_$(2)),$$(notdir $$@))
-       $$(STAGE$(1)_T_$(2)_H_$(3)) $(BORROWCK) --out-dir $$(@D) $$< && touch $$@
+       $$(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 $$@))
 
 # Only build the compiler for host triples
@@ -90,7 +90,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(3)):              \
                | $$(TLIB$(1)_T_$(2)_H_$(3))/
        @$$(call E, compile_and_link: $$@)
        $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTC_GLOB_$(2)),$$(notdir $$@))
-       $$(STAGE$(1)_T_$(2)_H_$(3)) --out-dir $$(@D) $$< && touch $$@
+       $$(STAGE$(1)_T_$(2)_H_$(3)) $$(WFLAGS_ST$(1)) --out-dir $$(@D) $$< && touch $$@
        $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTC_GLOB_$(2)),$$(notdir $$@))
 
 $$(TBIN$(1)_T_$(2)_H_$(3))/rustc$$(X_$(3)):                    \
index 32c034d878cb9671a5ef7ada47c308dd9be0e550..09c3de014782d3b0f1e1e4dd3d2265ca27f01e86 100644 (file)
@@ -67,7 +67,7 @@ $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTDOC_$(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)) --out-dir $$(@D) $$< && touch $$@
+       $$(STAGE$(1)_T_$(4)_H_$(3)) $$(WFLAGS_ST$(1)) --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)):                  \
@@ -85,7 +85,7 @@ $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTI_$(4)):              \
                | $$(TLIB$(1)_T_$(4)_H_$(3))/
        @$$(call E, compile_and_link: $$@)
        $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTI_GLOB_$(4)),$$(notdir $$@))
-       $$(STAGE$(1)_T_$(4)_H_$(3)) --out-dir $$(@D) $$< && touch $$@
+       $$(STAGE$(1)_T_$(4)_H_$(3)) $$(WFLAGS_ST$(1)) --out-dir $$(@D) $$< && touch $$@
        $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTI_GLOB_$(4)),$$(notdir $$@))
 
 $$(TBIN$(1)_T_$(4)_H_$(3))/rusti$$(X_$(4)):                    \
@@ -106,7 +106,7 @@ $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUST_$(4)):             \
                | $$(TLIB$(1)_T_$(4)_H_$(3))/
        @$$(call E, compile_and_link: $$@)
        $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUST_GLOB_$(4)),$$(notdir $$@))
-       $$(STAGE$(1)_T_$(4)_H_$(3)) --out-dir $$(@D) $$< && touch $$@
+       $$(STAGE$(1)_T_$(4)_H_$(3)) $$(WFLAGS_ST$(1)) --out-dir $$(@D) $$< && touch $$@
        $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUST_GLOB_$(4)),$$(notdir $$@))
 
 $$(TBIN$(1)_T_$(4)_H_$(3))/rust$$(X_$(4)):                     \
index a5d308007b48a3db5dc8042e5de20b32b06396c7..45e4f756d7a15752a7e3d3e7ed672ac2547c8296 100644 (file)
@@ -49,7 +49,7 @@ pub fn run(lib_path: &str,
 
     let env = env + target_env(lib_path, prog);
     let mut proc = run::Process::new(prog, args, run::ProcessOptions {
-        env: Some(env.slice(0, env.len())),
+        env: Some(env),
         dir: None,
         in_fd: None,
         out_fd: None,
index 0fb64152d376c6eab42d744c83e21a3abf695979..2346aba3bcbb655cd5553fe4a883cccb906b50b5 100644 (file)
 use util;
 use util::logv;
 
+use std::cell::Cell;
 use std::io;
 use std::os;
 use std::str;
+use std::task::{spawn_sched, SingleThreaded};
 use std::vec;
 
 use extra::test::MetricMap;
 
 pub fn run(config: config, testfile: ~str) {
-    let mut _mm = MetricMap::new();
-    run_metrics(config, testfile, &mut _mm);
+    let config = Cell::new(config);
+    let testfile = Cell::new(testfile);
+    // FIXME #6436: Creating another thread to run the test because this
+    // is going to call waitpid. The new scheduler has some strange
+    // interaction between the blocking tasks and 'friend' schedulers
+    // that destroys parallelism if we let normal schedulers block.
+    // It should be possible to remove this spawn once std::run is
+    // rewritten to be non-blocking.
+    do spawn_sched(SingleThreaded) {
+        let config = config.take();
+        let testfile = testfile.take();
+        let mut _mm = MetricMap::new();
+        run_metrics(config, testfile, &mut _mm);
+    }
 }
 
 pub fn run_metrics(config: config, testfile: ~str, mm: &mut MetricMap) {
index 7a7f13a7e9764545f2e56ea2e1347e5b55017557..21b1b377afa6339214821852b13606fbe6dd8641 100644 (file)
@@ -13,7 +13,7 @@
 #include <math.h>
 #include <stdio.h>
 
-// must match core::ctypes
+// must match std::ctypes
 
 #define C_FLT(x) (float)x
 #define C_DBL(x) (double)x
index c8f873037d8cc581c2f7413c8453b606896a5956..51c0da39bd5ac167df3222ce41c469389870b137 100755 (executable)
@@ -2,7 +2,7 @@
 # xfail-license
 
 # This creates the tables used for distributions implemented using the
-# ziggurat algorithm in `core::rand::distributions;`. They are
+# ziggurat algorithm in `std::rand::distributions;`. They are
 # (basically) the tables as used in the ZIGNOR variant (Doornik 2005).
 # They are changed rarely, so the generated file should be checked in
 # to git.
index 7320eced7e1be74ab9f2158bfa2a8b6e5e411f1a..3d0163d9e259305d5531df46fc615acbaae1364d 100644 (file)
@@ -36,7 +36,7 @@ _rustc_opts_lint=(
     'path-statement[path statements with no effect]'
     'missing-trait-doc[detects missing documentation for traits]'
     'missing-struct-doc[detects missing documentation for structs]'
-    'ctypes[proper use of core::libc types in foreign modules]'
+    'ctypes[proper use of std::libc types in foreign modules]'
     "unused-mut[detect mut variables which don't need to be mutable]"
     'unused-imports[imports that are never used]'
     'heap-memory[use of any (~ type or @ type) heap memory]'
index 5f00f1abae0eb26ca07ad866c6d233d8b1387aa4..1704e9a48d6c591b5377daef26e29421f7a12fc0 100644 (file)
@@ -762,7 +762,7 @@ fn test_rw_arc() {
                 do 10.times {
                     let tmp = *num;
                     *num = -1;
-                    task::yield();
+                    task::deschedule();
                     *num = tmp + 1;
                 }
                 c.send(());
@@ -913,7 +913,7 @@ fn test_rw_write_cond_downgrade_read_race_helper() {
             do read_mode.read |state| {
                 // if writer mistakenly got in, make sure it mutates state
                 // before we assert on it
-                do 5.times { task::yield(); }
+                do 5.times { task::deschedule(); }
                 // make sure writer didn't get in.
                 assert!(*state);
             }
@@ -921,9 +921,9 @@ fn test_rw_write_cond_downgrade_read_race_helper() {
     }
     #[test]
     fn test_rw_write_cond_downgrade_read_race() {
-        // Ideally the above test case would have yield statements in it that
+        // Ideally the above test case would have deschedule statements in it that
         // helped to expose the race nearly 100% of the time... but adding
-        // yields in the intuitively-right locations made it even less likely,
+        // deschedules in the intuitively-right locations made it even less likely,
         // and I wasn't sure why :( . This is a mediocre "next best" option.
         do 8.times { test_rw_write_cond_downgrade_read_race_helper() }
     }
index e656360aa5a793c859d2059d284ad43131e0b681..9e1504aad2a5625ebda57cb59fd429ff3153f92f 100644 (file)
@@ -155,12 +155,20 @@ mod tests {
     use std::libc;
 
     fn malloc(n: size_t) -> CVec<u8> {
+        #[fixed_stack_segment];
+        #[inline(never)];
+
         unsafe {
             let mem = libc::malloc(n);
 
             assert!(mem as int != 0);
 
-            c_vec_with_dtor(mem as *mut u8, n as uint, || free(mem))
+            return c_vec_with_dtor(mem as *mut u8, n as uint, || f(mem));
+        }
+
+        fn f(mem: *c_void) {
+            #[fixed_stack_segment]; #[inline(never)];
+            unsafe { libc::free(mem) }
         }
     }
 
index 43e3b5c89af484a84f32d08572fcfa830fa5e635..d4d43558110b15482df457b55ca22d40f0dc0119 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::num::One;
+use std::num::{One, Zero, CheckedAdd};
 use std::vec::bytes::{MutableByteVector, copy_memory};
 
 
@@ -36,6 +36,18 @@ pub fn write_u32_be(dst: &mut[u8], input: u32) {
     }
 }
 
+/// Write a u32 into a vector, which must be 4 bytes long. The value is written in little-endian
+/// format.
+pub fn write_u32_le(dst: &mut[u8], input: u32) {
+    use std::cast::transmute;
+    use std::unstable::intrinsics::to_le32;
+    assert!(dst.len() == 4);
+    unsafe {
+        let x: *mut i32 = transmute(dst.unsafe_mut_ref(0));
+        *x = to_le32(input as i32);
+    }
+}
+
 /// Read a vector of bytes into a vector of u64s. The values are read in big-endian format.
 pub fn read_u64v_be(dst: &mut[u64], input: &[u8]) {
     use std::cast::transmute;
@@ -68,51 +80,90 @@ pub fn read_u32v_be(dst: &mut[u32], input: &[u8]) {
     }
 }
 
+/// Read a vector of bytes into a vector of u32s. The values are read in little-endian format.
+pub fn read_u32v_le(dst: &mut[u32], input: &[u8]) {
+    use std::cast::transmute;
+    use std::unstable::intrinsics::to_le32;
+    assert!(dst.len() * 4 == input.len());
+    unsafe {
+        let mut x: *mut i32 = transmute(dst.unsafe_mut_ref(0));
+        let mut y: *i32 = transmute(input.unsafe_ref(0));
+        do dst.len().times() {
+            *x = to_le32(*y);
+            x = x.offset(1);
+            y = y.offset(1);
+        }
+    }
+}
+
 
-/// Returns true if adding the two parameters will result in integer overflow
-pub fn will_add_overflow<T: Int + Unsigned>(x: T, y: T) -> bool {
-    // This doesn't handle negative values! Don't copy this code elsewhere without considering if
-    // negative values are important to you!
-    let max: T = Bounded::max_value();
-    return x > max - y;
+trait ToBits {
+    /// Convert the value in bytes to the number of bits, a tuple where the 1st item is the
+    /// high-order value and the 2nd item is the low order value.
+    fn to_bits(self) -> (Self, Self);
 }
 
-/// Shifts the second parameter and then adds it to the first. fails!() if there would be unsigned
-/// integer overflow.
-pub fn shift_add_check_overflow<T: Int + Unsigned + Clone>(x: T, mut y: T, shift: T) -> T {
-    if y.leading_zeros() < shift {
-        fail!("Could not add values - integer overflow.");
+impl ToBits for u64 {
+    fn to_bits(self) -> (u64, u64) {
+        return (self >> 61, self << 3);
     }
-    y = y << shift;
+}
 
-    if will_add_overflow(x.clone(), y.clone()) {
-        fail!("Could not add values - integer overflow.");
-    }
+/// Adds the specified number of bytes to the bit count. fail!() if this would cause numeric
+/// overflow.
+pub fn add_bytes_to_bits<T: Int + CheckedAdd + ToBits>(bits: T, bytes: T) -> T {
+    let (new_high_bits, new_low_bits) = bytes.to_bits();
 
-    return x + y;
-}
+    if new_high_bits > Zero::zero() {
+        fail!("Numeric overflow occured.")
+    }
 
-/// Shifts the second parameter and then adds it to the first, which is a tuple where the first
-/// element is the high order value. fails!() if there would be unsigned integer overflow.
-pub fn shift_add_check_overflow_tuple
-        <T: Int + Unsigned + Clone>
-        (x: (T, T), mut y: T, shift: T) -> (T, T) {
-    if y.leading_zeros() < shift {
-        fail!("Could not add values - integer overflow.");
+    match bits.checked_add(&new_low_bits) {
+        Some(x) => return x,
+        None => fail!("Numeric overflow occured.")
     }
-    y = y << shift;
+}
 
-    match x {
-        (hi, low) => {
-            let one: T = One::one();
-            if will_add_overflow(low.clone(), y.clone()) {
-                if will_add_overflow(hi.clone(), one.clone()) {
-                    fail!("Could not add values - integer overflow.");
-                } else {
-                    return (hi + one, low + y);
-                }
+/// Adds the specified number of bytes to the bit count, which is a tuple where the first element is
+/// the high order value. fail!() if this would cause numeric overflow.
+pub fn add_bytes_to_bits_tuple
+        <T: Int + Unsigned + CheckedAdd + ToBits>
+        (bits: (T, T), bytes: T) -> (T, T) {
+    let (new_high_bits, new_low_bits) = bytes.to_bits();
+    let (hi, low) = bits;
+
+    // Add the low order value - if there is no overflow, then add the high order values
+    // If the addition of the low order values causes overflow, add one to the high order values
+    // before adding them.
+    match low.checked_add(&new_low_bits) {
+        Some(x) => {
+            if new_high_bits == Zero::zero() {
+                // This is the fast path - every other alternative will rarely occur in practice
+                // considering how large an input would need to be for those paths to be used.
+                return (hi, x);
             } else {
-                return (hi, low + y);
+                match hi.checked_add(&new_high_bits) {
+                    Some(y) => return (y, x),
+                    None => fail!("Numeric overflow occured.")
+                }
+            }
+        },
+        None => {
+            let one: T = One::one();
+            let z = match new_high_bits.checked_add(&one) {
+                Some(w) => w,
+                None => fail!("Numeric overflow occured.")
+            };
+            match hi.checked_add(&z) {
+                // This re-executes the addition that was already performed earlier when overflow
+                // occured, this time allowing the overflow to happen. Technically, this could be
+                // avoided by using the checked add intrinsic directly, but that involves using
+                // unsafe code and is not really worthwhile considering how infrequently code will
+                // run in practice. This is the reason that this function requires that the type T
+                // be Unsigned - overflow is not defined for Signed types. This function could be
+                // implemented for signed types as well if that were needed.
+                Some(y) => return (y, low + new_low_bits),
+                None => fail!("Numeric overflow occured.")
             }
         }
     }
@@ -125,7 +176,7 @@ pub fn shift_add_check_overflow_tuple
 /// method that modifies the buffer directory or provides the caller with bytes that can be modifies
 /// results in those bytes being marked as used by the buffer.
 pub trait FixedBuffer {
-    /// Input a vector of bytes. If the buffer becomes full, proccess it with the provided
+    /// Input a vector of bytes. If the buffer becomes full, process it with the provided
     /// function and then clear the buffer.
     fn input(&mut self, input: &[u8], func: &fn(&[u8]));
 
@@ -300,6 +351,7 @@ mod test {
     use std::rand::RngUtil;
     use std::vec;
 
+    use cryptoutil::{add_bytes_to_bits, add_bytes_to_bits_tuple};
     use digest::Digest;
 
     /// Feed 1,000,000 'a's into the digest with varying input sizes and check that the result is
@@ -324,4 +376,50 @@ pub fn test_digest_1million_random<D: Digest>(digest: &mut D, blocksize: uint, e
 
         assert!(expected == result_str);
     }
+
+    // A normal addition - no overflow occurs
+    #[test]
+    fn test_add_bytes_to_bits_ok() {
+        assert!(add_bytes_to_bits::<u64>(100, 10) == 180);
+    }
+
+    // A simple failure case - adding 1 to the max value
+    #[test]
+    #[should_fail]
+    fn test_add_bytes_to_bits_overflow() {
+        add_bytes_to_bits::<u64>(Bounded::max_value(), 1);
+    }
+
+    // A normal addition - no overflow occurs (fast path)
+    #[test]
+    fn test_add_bytes_to_bits_tuple_ok() {
+        assert!(add_bytes_to_bits_tuple::<u64>((5, 100), 10) == (5, 180));
+    }
+
+    // The low order value overflows into the high order value
+    #[test]
+    fn test_add_bytes_to_bits_tuple_ok2() {
+        assert!(add_bytes_to_bits_tuple::<u64>((5, Bounded::max_value()), 1) == (6, 7));
+    }
+
+    // The value to add is too large to be converted into bits without overflowing its type
+    #[test]
+    fn test_add_bytes_to_bits_tuple_ok3() {
+        assert!(add_bytes_to_bits_tuple::<u64>((5, 0), 0x4000000000000001) == (7, 8));
+    }
+
+    // A simple failure case - adding 1 to the max value
+    #[test]
+    #[should_fail]
+    fn test_add_bytes_to_bits_tuple_overflow() {
+        add_bytes_to_bits_tuple::<u64>((Bounded::max_value(), Bounded::max_value()), 1);
+    }
+
+    // The value to add is too large to convert to bytes without overflowing its type, but the high
+    // order value from this conversion overflows when added to the existing high order value
+    #[test]
+    #[should_fail]
+    fn test_add_bytes_to_bits_tuple_overflow2() {
+        add_bytes_to_bits_tuple::<u64>((Bounded::max_value::<u64>() - 1, 0), 0x8000000000000000);
+    }
 }
index 217f5b0a4175e2f903f8772504b3f68cef36489e..c7f228af332a3bdf246af290ebbc173c2b32df29 100644 (file)
@@ -47,18 +47,18 @@ pub trait Digest {
     fn output_bits(&self) -> uint;
 
     /**
-     * Convenience functon that feeds a string into a digest
+     * Convenience function that feeds a string into a digest.
      *
      * # Arguments
      *
-     * * in The string to feed into the digest
+     * * `input` The string to feed into the digest
      */
     fn input_str(&mut self, input: &str) {
         self.input(input.as_bytes());
     }
 
     /**
-     * Convenience functon that retrieves the result of a digest as a
+     * Convenience function that retrieves the result of a digest as a
      * ~str in hexadecimal format.
      */
     fn result_str(&mut self) -> ~str {
diff --git a/src/libextra/crypto/md5.rs b/src/libextra/crypto/md5.rs
new file mode 100644 (file)
index 0000000..8e8b752
--- /dev/null
@@ -0,0 +1,329 @@
+// 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.
+
+use std::uint;
+
+use cryptoutil::{write_u32_le, read_u32v_le, FixedBuffer, FixedBuffer64, StandardPadding};
+use digest::Digest;
+
+
+// A structure that represents that state of a digest computation for the MD5 digest function
+struct Md5State {
+    s0: u32,
+    s1: u32,
+    s2: u32,
+    s3: u32
+}
+
+impl Md5State {
+    fn new() -> Md5State {
+        return Md5State {
+            s0: 0x67452301,
+            s1: 0xefcdab89,
+            s2: 0x98badcfe,
+            s3: 0x10325476
+        };
+    }
+
+    fn reset(&mut self) {
+        self.s0 = 0x67452301;
+        self.s1 = 0xefcdab89;
+        self.s2 = 0x98badcfe;
+        self.s3 = 0x10325476;
+    }
+
+    fn process_block(&mut self, input: &[u8]) {
+        fn f(u: u32, v: u32, w: u32) -> u32 {
+            return (u & v) | (!u & w);
+        }
+
+        fn g(u: u32, v: u32, w: u32) -> u32 {
+            return (u & w) | (v & !w);
+        }
+
+        fn h(u: u32, v: u32, w: u32) -> u32 {
+            return u ^ v ^ w;
+        }
+
+        fn i(u: u32, v: u32, w: u32) -> u32 {
+            return v ^ (u | !w);
+        }
+
+        fn rotate_left(x: u32, n: u32) -> u32 {
+            return (x << n) | (x >> (32 - n));
+        }
+
+        fn op_f(w: u32, x: u32, y: u32, z: u32, m: u32, s: u32) -> u32 {
+            return rotate_left(w + f(x, y, z) + m, s) + x;
+        }
+
+        fn op_g(w: u32, x: u32, y: u32, z: u32, m: u32, s: u32) -> u32 {
+            return rotate_left(w + g(x, y, z) + m, s) + x;
+        }
+
+        fn op_h(w: u32, x: u32, y: u32, z: u32, m: u32, s: u32) -> u32 {
+            return rotate_left(w + h(x, y, z) + m, s) + x;
+        }
+
+        fn op_i(w: u32, x: u32, y: u32, z: u32, m: u32, s: u32) -> u32 {
+            return rotate_left(w + i(x, y, z) + m, s) + x;
+        }
+
+        let mut a = self.s0;
+        let mut b = self.s1;
+        let mut c = self.s2;
+        let mut d = self.s3;
+
+        let mut data = [0u32, ..16];
+
+        read_u32v_le(data, input);
+
+        // round 1
+        do uint::range_step(0, 16, 4) |i| {
+            a = op_f(a, b, c, d, data[i] + C1[i], 7);
+            d = op_f(d, a, b, c, data[i + 1] + C1[i + 1], 12);
+            c = op_f(c, d, a, b, data[i + 2] + C1[i + 2], 17);
+            b = op_f(b, c, d, a, data[i + 3] + C1[i + 3], 22);
+            true
+        };
+
+        // round 2
+        let mut t = 1;
+        do uint::range_step(0, 16, 4) |i| {
+            a = op_g(a, b, c, d, data[t & 0x0f] + C2[i], 5);
+            d = op_g(d, a, b, c, data[(t + 5) & 0x0f] + C2[i + 1], 9);
+            c = op_g(c, d, a, b, data[(t + 10) & 0x0f] + C2[i + 2], 14);
+            b = op_g(b, c, d, a, data[(t + 15) & 0x0f] + C2[i + 3], 20);
+            t += 20;
+            true
+        };
+
+        // round 3
+        t = 5;
+        do uint::range_step(0, 16, 4) |i| {
+            a = op_h(a, b, c, d, data[t & 0x0f] + C3[i], 4);
+            d = op_h(d, a, b, c, data[(t + 3) & 0x0f] + C3[i + 1], 11);
+            c = op_h(c, d, a, b, data[(t + 6) & 0x0f] + C3[i + 2], 16);
+            b = op_h(b, c, d, a, data[(t + 9) & 0x0f] + C3[i + 3], 23);
+            t += 12;
+            true
+        };
+
+        // round 4
+        t = 0;
+        do uint::range_step(0, 16, 4) |i| {
+            a = op_i(a, b, c, d, data[t & 0x0f] + C4[i], 6);
+            d = op_i(d, a, b, c, data[(t + 7) & 0x0f] + C4[i + 1], 10);
+            c = op_i(c, d, a, b, data[(t + 14) & 0x0f] + C4[i + 2], 15);
+            b = op_i(b, c, d, a, data[(t + 21) & 0x0f] + C4[i + 3], 21);
+            t += 28;
+            true
+        };
+
+        self.s0 += a;
+        self.s1 += b;
+        self.s2 += c;
+        self.s3 += d;
+    }
+}
+
+// Round 1 constants
+static C1: [u32, ..16] = [
+    0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
+    0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821
+];
+
+// Round 2 constants
+static C2: [u32, ..16] = [
+    0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
+    0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a
+];
+
+// Round 3 constants
+static C3: [u32, ..16] = [
+    0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
+    0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665
+];
+
+// Round 4 constants
+static C4: [u32, ..16] = [
+    0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
+    0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
+];
+
+
+/// The MD5 Digest algorithm
+struct Md5 {
+    priv length_bytes: u64,
+    priv buffer: FixedBuffer64,
+    priv state: Md5State,
+    priv finished: bool,
+}
+
+impl Md5 {
+    /// Construct a new instance of the MD5 Digest.
+    pub fn new() -> Md5 {
+        return Md5 {
+            length_bytes: 0,
+            buffer: FixedBuffer64::new(),
+            state: Md5State::new(),
+            finished: false
+        }
+    }
+}
+
+impl Digest for Md5 {
+    fn input(&mut self, input: &[u8]) {
+        assert!(!self.finished);
+        // Unlike Sha1 and Sha2, the length value in MD5 is defined as the length of the message mod
+        // 2^64 - ie: integer overflow is OK.
+        self.length_bytes += input.len() as u64;
+        self.buffer.input(input, |d: &[u8]| { self.state.process_block(d); });
+    }
+
+    fn reset(&mut self) {
+        self.length_bytes = 0;
+        self.buffer.reset();
+        self.state.reset();
+        self.finished = false;
+    }
+
+    fn result(&mut self, out: &mut [u8]) {
+        if !self.finished {
+            self.buffer.standard_padding(8, |d: &[u8]| { self.state.process_block(d); });
+            write_u32_le(self.buffer.next(4), (self.length_bytes << 3) as u32);
+            write_u32_le(self.buffer.next(4), (self.length_bytes >> 29) as u32);
+            self.state.process_block(self.buffer.full_buffer());
+            self.finished = true;
+        }
+
+        write_u32_le(out.mut_slice(0, 4), self.state.s0);
+        write_u32_le(out.mut_slice(4, 8), self.state.s1);
+        write_u32_le(out.mut_slice(8, 12), self.state.s2);
+        write_u32_le(out.mut_slice(12, 16), self.state.s3);
+    }
+
+    fn output_bits(&self) -> uint { 128 }
+}
+
+
+#[cfg(test)]
+mod tests {
+    use cryptoutil::test::test_digest_1million_random;
+    use digest::Digest;
+    use md5::Md5;
+
+
+    struct Test {
+        input: ~str,
+        output_str: ~str,
+    }
+
+    fn test_hash<D: Digest>(sh: &mut D, tests: &[Test]) {
+        // Test that it works when accepting the message all at once
+        for t in tests.iter() {
+            sh.input_str(t.input);
+
+            let out_str = sh.result_str();
+            assert!(out_str == t.output_str);
+
+            sh.reset();
+        }
+
+        // Test that it works when accepting the message in pieces
+        for t in tests.iter() {
+            let len = t.input.len();
+            let mut left = len;
+            while left > 0u {
+                let take = (left + 1u) / 2u;
+                sh.input_str(t.input.slice(len - left, take + len - left));
+                left = left - take;
+            }
+
+            let out_str = sh.result_str();
+            assert!(out_str == t.output_str);
+
+            sh.reset();
+        }
+    }
+
+    #[test]
+    fn test_md5() {
+        // Examples from wikipedia
+        let wikipedia_tests = ~[
+            Test {
+                input: ~"",
+                output_str: ~"d41d8cd98f00b204e9800998ecf8427e"
+            },
+            Test {
+                input: ~"The quick brown fox jumps over the lazy dog",
+                output_str: ~"9e107d9d372bb6826bd81d3542a419d6"
+            },
+            Test {
+                input: ~"The quick brown fox jumps over the lazy dog.",
+                output_str: ~"e4d909c290d0fb1ca068ffaddf22cbd0"
+            },
+        ];
+
+        let tests = wikipedia_tests;
+
+        let mut sh = Md5::new();
+
+        test_hash(&mut sh, tests);
+    }
+
+    #[test]
+    fn test_1million_random_md5() {
+        let mut sh = Md5::new();
+        test_digest_1million_random(
+            &mut sh,
+            64,
+            "7707d6ae4e027c70eea2a935c2296f21");
+    }
+}
+
+
+#[cfg(test)]
+mod bench {
+    use extra::test::BenchHarness;
+
+    use md5::Md5;
+
+
+    #[bench]
+    pub fn md5_10(bh: & mut BenchHarness) {
+        let mut sh = Md5::new();
+        let bytes = [1u8, ..10];
+        do bh.iter {
+            sh.input(bytes);
+        }
+        bh.bytes = bytes.len() as u64;
+    }
+
+    #[bench]
+    pub fn md5_1k(bh: & mut BenchHarness) {
+        let mut sh = Md5::new();
+        let bytes = [1u8, ..1024];
+        do bh.iter {
+            sh.input(bytes);
+        }
+        bh.bytes = bytes.len() as u64;
+    }
+
+    #[bench]
+    pub fn md5_64k(bh: & mut BenchHarness) {
+        let mut sh = Md5::new();
+        let bytes = [1u8, ..65536];
+        do bh.iter {
+            sh.input(bytes);
+        }
+        bh.bytes = bytes.len() as u64;
+    }
+}
index 8ee9006f6136c0f33984a8ce5aa7f43a0dee8c28..4d4d47feee817c0bb07f4136215d88c327ad027f 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 
-use cryptoutil::{write_u32_be, read_u32v_be, shift_add_check_overflow, FixedBuffer, FixedBuffer64,
+use cryptoutil::{write_u32_be, read_u32v_be, add_bytes_to_bits, FixedBuffer, FixedBuffer64,
     StandardPadding};
 use digest::Digest;
 
@@ -52,7 +52,7 @@ pub struct Sha1 {
 fn add_input(st: &mut Sha1, msg: &[u8]) {
     assert!((!st.computed));
     // Assumes that msg.len() can be converted to u64 without overflow
-    st.length_bits = shift_add_check_overflow(st.length_bits, msg.len() as u64, 3);
+    st.length_bits = add_bytes_to_bits(st.length_bits, msg.len() as u64);
     st.buffer.input(msg, |d: &[u8]| { process_msg_block(d, &mut st.h); });
 }
 
index 47535d5103ab113946adb4fd76df84da91373516..96f3e13eb2202530edf5125c5b4ce336a3aae44d 100644 (file)
@@ -10,8 +10,8 @@
 
 use std::uint;
 
-use cryptoutil::{write_u64_be, write_u32_be, read_u64v_be, read_u32v_be, shift_add_check_overflow,
-    shift_add_check_overflow_tuple, FixedBuffer, FixedBuffer128, FixedBuffer64, StandardPadding};
+use cryptoutil::{write_u64_be, write_u32_be, read_u64v_be, read_u32v_be, add_bytes_to_bits,
+    add_bytes_to_bits_tuple, FixedBuffer, FixedBuffer128, FixedBuffer64, StandardPadding};
 use digest::Digest;
 
 
@@ -210,7 +210,7 @@ fn reset(&mut self, h: &[u64, ..8]) {
     fn input(&mut self, input: &[u8]) {
         assert!(!self.finished)
         // Assumes that input.len() can be converted to u64 without overflow
-        self.length_bits = shift_add_check_overflow_tuple(self.length_bits, input.len() as u64, 3);
+        self.length_bits = add_bytes_to_bits_tuple(self.length_bits, input.len() as u64);
         self.buffer.input(input, |input: &[u8]| { self.state.process_block(input) });
     }
 
@@ -602,7 +602,7 @@ fn reset(&mut self, h: &[u32, ..8]) {
     fn input(&mut self, input: &[u8]) {
         assert!(!self.finished)
         // Assumes that input.len() can be converted to u64 without overflow
-        self.length_bits = shift_add_check_overflow(self.length_bits, input.len() as u64, 3);
+        self.length_bits = add_bytes_to_bits(self.length_bits, input.len() as u64);
         self.buffer.input(input, |input: &[u8]| { self.state.process_block(input) });
     }
 
index 788ed726d0fc0329187e434cac8ffe90189dce19..076e86dd5b04095e1988089e1bfcb353437b7e57 100644 (file)
@@ -573,16 +573,16 @@ impl<A> DoubleEndedIterator<A> for MoveIterator<A> {
     fn next_back(&mut self) -> Option<A> { self.list.pop_back() }
 }
 
-impl<A, T: Iterator<A>> FromIterator<A, T> for DList<A> {
-    fn from_iterator(iterator: &mut T) -> DList<A> {
+impl<A> FromIterator<A> for DList<A> {
+    fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> DList<A> {
         let mut ret = DList::new();
         ret.extend(iterator);
         ret
     }
 }
 
-impl<A, T: Iterator<A>> Extendable<A, T> for DList<A> {
-    fn extend(&mut self, iterator: &mut T) {
+impl<A> Extendable<A> for DList<A> {
+    fn extend<T: Iterator<A>>(&mut self, iterator: &mut T) {
         for elt in *iterator { self.push_back(elt); }
     }
 }
@@ -1163,4 +1163,3 @@ fn bench_iter_mut_rev(b: &mut test::BenchHarness) {
         }
     }
 }
-
index 28ff16c43e8afbc79d9ad5efe665d35507a6b86d..2b1246b0af0078d68986f58b14793ad3ead4d5cc 100644 (file)
@@ -18,7 +18,7 @@ pub struct EnumSet<E> {
     priv bits: uint
 }
 
-/// An iterface for casting C-like enum to uint and back.
+/// An interface for casting C-like enum to uint and back.
 pub trait CLike {
     /// Converts C-like enum to uint.
     fn to_uint(&self) -> uint;
index 44781a1fd19b632f0794802ae3d9ee8cbae167ce..da6525f78155887b5723b521131321df99fd3f05 100644 (file)
@@ -71,6 +71,8 @@
 mod cryptoutil;
 #[path="crypto/digest.rs"]
 pub mod digest;
+#[path="crypto/md5.rs"]
+pub mod md5;
 #[path="crypto/sha1.rs"]
 pub mod sha1;
 #[path="crypto/sha2.rs"]
 pub mod fileinput;
 pub mod flate;
 pub mod hex;
+pub mod uuid;
+
 
 #[cfg(unicode)]
 mod unicode;
index e268e83bf3fb0653d290147ee24bb7fb1844406e..3b4fad3eaa794e0dffa83aad6a55fff82f02f336 100644 (file)
@@ -156,7 +156,7 @@ impl FileInput {
     /**
     Create a `FileInput` object from a vec of files. An empty
     vec means lines are read from `stdin` (use `from_vec_raw` to stop
-    this behaviour). Any occurence of `None` represents `stdin`.
+    this behaviour). Any occurrence of `None` represents `stdin`.
     */
     pub fn from_vec(files: ~[Option<Path>]) -> FileInput {
         FileInput::from_vec_raw(
index ed8cbcd0663f3f9874afc34e6ef92a827c76eeae..530885001292c51d77d5b0df33ba1cb21c42d452 100644 (file)
@@ -47,6 +47,8 @@ pub fn tinfl_decompress_mem_to_heap(psrc_buf: *const c_void,
 static TDEFL_WRITE_ZLIB_HEADER : c_int = 0x01000; // write zlib header and adler32 checksum
 
 fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> ~[u8] {
+    #[fixed_stack_segment]; #[inline(never)];
+
     do bytes.as_imm_buf |b, len| {
         unsafe {
             let mut outsz : size_t = 0;
@@ -73,6 +75,8 @@ pub fn deflate_bytes_zlib(bytes: &[u8]) -> ~[u8] {
 }
 
 fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> ~[u8] {
+    #[fixed_stack_segment]; #[inline(never)];
+
     do bytes.as_imm_buf |b, len| {
         unsafe {
             let mut outsz : size_t = 0;
index 74653828121e96516778c3363e8c0f4b7e06cbc3..aa7c6433f1fccd7ebad5269972c4fd5fdd10e494 100644 (file)
@@ -166,7 +166,7 @@ pub fn pipe_stream<T: Encodable<DefaultEncoder> +
 
 This module is currently unsafe because it uses `Clone + Send` as a type
 parameter bounds meaning POD (plain old data), but `Clone + Send` and
-POD are not equivelant.
+POD are not equivalent.
 
 */
 pub mod pod {
index 4b94219b30d537237406faad9799e06da2cfefdd..4f0fed5fccf4781245f6eea55c4a72e0ffd66913 100644 (file)
@@ -190,8 +190,8 @@ fn next(&mut self) -> Option<(&'self T)> { self.iter.next() }
     fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
 }
 
-impl<T: Ord, Iter: Iterator<T>> FromIterator<T, Iter> for PriorityQueue<T> {
-    fn from_iterator(iter: &mut Iter) -> PriorityQueue<T> {
+impl<T: Ord> FromIterator<T> for PriorityQueue<T> {
+    fn from_iterator<Iter: Iterator<T>>(iter: &mut Iter) -> PriorityQueue<T> {
         let mut q = PriorityQueue::new();
         q.extend(iter);
 
@@ -199,8 +199,8 @@ fn from_iterator(iter: &mut Iter) -> PriorityQueue<T> {
     }
 }
 
-impl<T: Ord, Iter: Iterator<T>> Extendable<T, Iter> for PriorityQueue<T> {
-    fn extend(&mut self, iter: &mut Iter) {
+impl<T: Ord> Extendable<T> for PriorityQueue<T> {
+    fn extend<Iter: Iterator<T>>(&mut self, iter: &mut Iter) {
         let (lower, _) = iter.size_hint();
 
         let len = self.capacity();
index bb9ac74bc77ac3d51563e2a6b73ec8b32859e65a..a38cb580c50578aa066e9f4ff6e83d37d335d324 100644 (file)
@@ -322,8 +322,8 @@ fn ne(&self, other: &RingBuf<A>) -> bool {
     }
 }
 
-impl<A, T: Iterator<A>> FromIterator<A, T> for RingBuf<A> {
-    fn from_iterator(iterator: &mut T) -> RingBuf<A> {
+impl<A> FromIterator<A> for RingBuf<A> {
+    fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> RingBuf<A> {
         let (lower, _) = iterator.size_hint();
         let mut deq = RingBuf::with_capacity(lower);
         deq.extend(iterator);
@@ -331,8 +331,8 @@ fn from_iterator(iterator: &mut T) -> RingBuf<A> {
     }
 }
 
-impl<A, T: Iterator<A>> Extendable<A, T> for RingBuf<A> {
-    fn extend(&mut self, iterator: &mut T) {
+impl<A> Extendable<A> for RingBuf<A> {
+    fn extend<T: Iterator<A>>(&mut self, iterator: &mut T) {
         for elt in *iterator {
             self.push_back(elt);
         }
index 9106d4cd684d916f5c6d58bcbb83dd87962cce90..db87cf94641bb59290ffb1b3fb598db6426caee7 100644 (file)
 pub mod rustrt {
     use std::libc::{c_char, c_int};
 
-    extern {
-        pub fn linenoise(prompt: *c_char) -> *c_char;
-        pub fn linenoiseHistoryAdd(line: *c_char) -> c_int;
-        pub fn linenoiseHistorySetMaxLen(len: c_int) -> c_int;
-        pub fn linenoiseHistorySave(file: *c_char) -> c_int;
-        pub fn linenoiseHistoryLoad(file: *c_char) -> c_int;
-        pub fn linenoiseSetCompletionCallback(callback: *u8);
-        pub fn linenoiseAddCompletion(completions: *(), line: *c_char);
+    #[cfg(stage0)]
+    mod macro_hack {
+    #[macro_escape];
+    macro_rules! externfn(
+        (fn $name:ident ($($arg_name:ident : $arg_ty:ty),*) $(-> $ret_ty:ty),*) => (
+            extern {
+                fn $name($($arg_name : $arg_ty),*) $(-> $ret_ty),*;
+            }
+        )
+    )
     }
+
+    externfn!(fn linenoise(prompt: *c_char) -> *c_char)
+    externfn!(fn linenoiseHistoryAdd(line: *c_char) -> c_int)
+    externfn!(fn linenoiseHistorySetMaxLen(len: c_int) -> c_int)
+    externfn!(fn linenoiseHistorySave(file: *c_char) -> c_int)
+    externfn!(fn linenoiseHistoryLoad(file: *c_char) -> c_int)
+    externfn!(fn linenoiseSetCompletionCallback(callback: *u8))
+    externfn!(fn linenoiseAddCompletion(completions: *(), line: *c_char))
 }
 
 /// Add a line to history
 pub unsafe fn add_history(line: &str) -> bool {
-    do line.to_c_str().with_ref |buf| {
+    do line.with_c_str |buf| {
         rustrt::linenoiseHistoryAdd(buf) == 1 as c_int
     }
 }
@@ -44,21 +54,21 @@ pub unsafe fn set_history_max_len(len: int) -> bool {
 
 /// Save line history to a file
 pub unsafe fn save_history(file: &str) -> bool {
-    do file.to_c_str().with_ref |buf| {
+    do file.with_c_str |buf| {
         rustrt::linenoiseHistorySave(buf) == 1 as c_int
     }
 }
 
 /// Load line history from a file
 pub unsafe fn load_history(file: &str) -> bool {
-    do file.to_c_str().with_ref |buf| {
+    do file.with_c_str |buf| {
         rustrt::linenoiseHistoryLoad(buf) == 1 as c_int
     }
 }
 
 /// Print out a prompt and then wait for input and return it
 pub unsafe fn read(prompt: &str) -> Option<~str> {
-    do prompt.to_c_str().with_ref |buf| {
+    do prompt.with_c_str |buf| {
         let line = rustrt::linenoise(buf);
 
         if line.is_null() { None }
@@ -80,11 +90,11 @@ pub unsafe fn complete(cb: CompletionCb) {
 
             unsafe {
                 do cb(str::raw::from_c_str(line)) |suggestion| {
-                    do suggestion.to_c_str().with_ref |buf| {
+                    do suggestion.with_c_str |buf| {
                         rustrt::linenoiseAddCompletion(completions, buf);
                     }
                 }
-}
+            }
         }
     }
 
index c7920e727089059032033c9bb0f0084081d34271..bea7868fd32b7c96d0dbd4196ced81b76d5336fa 100644 (file)
@@ -782,11 +782,8 @@ fn test() {
 
 #[cfg(test)]
 mod test_qsort {
-
     use sort::*;
 
-    use std::vec;
-
     fn check_sort(v1: &mut [int], v2: &mut [int]) {
         let len = v1.len();
         fn leual(a: &int, b: &int) -> bool { *a <= *b }
@@ -835,9 +832,7 @@ fn test_simple() {
 
         let immut_names = names;
 
-        let pairs = vec::zip_slice(expected, immut_names);
-        for p in pairs.iter() {
-            let (a, b) = *p;
+        for (&a, &b) in expected.iter().zip(immut_names.iter()) {
             debug!("%d %d", a, b);
             assert_eq!(a, b);
         }
index 0868c767e168c545a6e1506b47a77ae59e3d1b9f..0cea4c1ac6c015f597309cba8168697bba9f00b6 100644 (file)
@@ -365,7 +365,7 @@ pub fn write_boxplot(w: @io::Writer, s: &Summary, width_hint: uint) {
     w.write_str(histr);
 }
 
-/// Returns a HashMap with the number of occurences of every element in the
+/// Returns a HashMap with the number of occurrences of every element in the
 /// sequence that the iterator exposes.
 pub fn freq_count<T: Iterator<U>, U: Eq+Hash>(mut iter: T) -> hashmap::HashMap<U, uint> {
     let mut map = hashmap::HashMap::new::<U, uint>();
index 756a5c7da006594a0efcec42dcdaf2ffe83c21e0..d32b7d6af03cd57ec45af451cb4e0a04030d2608 100644 (file)
@@ -112,7 +112,7 @@ pub fn acquire(&self) {
                 }
             }
             // Uncomment if you wish to test for sem races. Not valgrind-friendly.
-            /* do 1000.times { task::yield(); } */
+            /* do 1000.times { task::deschedule(); } */
             // Need to wait outside the exclusive.
             if waiter_nobe.is_some() {
                 let _ = waiter_nobe.unwrap().recv();
@@ -225,7 +225,7 @@ pub fn wait_on(&self, condvar_id: uint) {
                 }
             }
 
-            // If yield checks start getting inserted anywhere, we can be
+            // If deschedule checks start getting inserted anywhere, we can be
             // killed before or after enqueueing. Deciding whether to
             // unkillably reacquire the lock needs to happen atomically
             // wrt enqueuing.
@@ -731,11 +731,11 @@ fn test_sem_as_mutex() {
         let s2 = ~s.clone();
         do task::spawn || {
             do s2.access {
-                do 5.times { task::yield(); }
+                do 5.times { task::deschedule(); }
             }
         }
         do s.access {
-            do 5.times { task::yield(); }
+            do 5.times { task::deschedule(); }
         }
     }
     #[test]
@@ -748,7 +748,7 @@ fn test_sem_as_cvar() {
             s2.acquire();
             c.send(());
         }
-        do 5.times { task::yield(); }
+        do 5.times { task::deschedule(); }
         s.release();
         let _ = p.recv();
 
@@ -757,7 +757,7 @@ fn test_sem_as_cvar() {
         let s = ~Semaphore::new(0);
         let s2 = ~s.clone();
         do task::spawn || {
-            do 5.times { task::yield(); }
+            do 5.times { task::deschedule(); }
             s2.release();
             let _ = p.recv();
         }
@@ -800,7 +800,7 @@ fn test_sem_runtime_friendly_blocking() {
                     c.send(());
                 }
                 let _ = p.recv(); // wait for child to come alive
-                do 5.times { task::yield(); } // let the child contend
+                do 5.times { task::deschedule(); } // let the child contend
             }
             let _ = p.recv(); // wait for child to be done
         }
@@ -837,7 +837,7 @@ fn access_shared(sharedstate: &mut int, m: &Mutex, n: uint) {
             do n.times {
                 do m.lock {
                     let oldval = *sharedstate;
-                    task::yield();
+                    task::deschedule();
                     *sharedstate = oldval + 1;
                 }
             }
@@ -948,7 +948,7 @@ fn test_mutex_killed_cond() {
             let (p,c) = comm::stream();
             do task::spawn || { // linked
                 let _ = p.recv(); // wait for sibling to get in the mutex
-                task::yield();
+                task::deschedule();
                 fail!();
             }
             do m2.lock_cond |cond| {
@@ -1114,7 +1114,7 @@ fn access_shared(sharedstate: &mut int, x: &RWLock, mode: RWLockMode,
             do n.times {
                 do lock_rwlock_in_mode(x, mode) {
                     let oldval = *sharedstate;
-                    task::yield();
+                    task::deschedule();
                     *sharedstate = oldval + 1;
                 }
             }
index d0412b8954db2abc963e43f87979ca96503709c8..d8eb3cfa50000614488cd676f32e0fc1a16449fd 100644 (file)
@@ -157,7 +157,7 @@ pub fn fg(&self, color: color::Color) -> bool {
     /// If the color is a bright color, but the terminal only supports 8 colors,
     /// the corresponding normal color will be used instead.
     ///
-    /// Rturns true if the color was set, false otherwise.
+    /// Returns true if the color was set, false otherwise.
     pub fn bg(&self, color: color::Color) -> bool {
         let color = self.dim_if_necessary(color);
         if self.num_colors > color {
index a9c3bf98cb6599684c13cfc5bb99bba9abe56e78..75d00f9ea5999cdf2793c32d89f386bee73fa27f 100644 (file)
@@ -188,6 +188,8 @@ fn optgroups() -> ~[getopts::groups::OptGroup] {
 }
 
 fn usage(binary: &str, helpstr: &str) -> ! {
+    #[fixed_stack_segment]; #[inline(never)];
+
     let message = fmt!("Usage: %s [OPTIONS] [FILTER]", binary);
     println(groups::usage(message, optgroups()));
     println("");
@@ -1121,7 +1123,6 @@ mod tests {
 
     use std::either;
     use std::comm::{stream, SharedChan};
-    use std::vec;
     use tempfile;
     use std::os;
 
@@ -1309,14 +1310,8 @@ fn testfn() { }
               ~"test::parse_ignored_flag",
               ~"test::sort_tests"];
 
-        let pairs = vec::zip(expected, filtered);
-
-        for p in pairs.iter() {
-            match *p {
-                (ref a, ref b) => {
-                    assert!(*a == b.desc.name.to_str());
-                }
-            }
+        for (a, b) in expected.iter().zip(filtered.iter()) {
+            assert!(*a == b.desc.name.to_str());
         }
     }
 
index f79e01b6f28b296d031de972c042cb7a6a655035..ab35bf2386ca4d89ed9345c7004ff4a2f5ce182f 100644 (file)
@@ -34,7 +34,7 @@ pub mod rustrt {
 }
 
 /// A record specifying a time value in seconds and nanoseconds.
-#[deriving(Eq, Encodable, Decodable)]
+#[deriving(Clone, DeepClone, Eq, Encodable, Decodable)]
 pub struct Timespec { sec: i64, nsec: i32 }
 
 /*
@@ -64,6 +64,8 @@ fn lt(&self, other: &Timespec) -> bool {
  * nanoseconds since 1970-01-01T00:00:00Z.
  */
 pub fn get_time() -> Timespec {
+    #[fixed_stack_segment]; #[inline(never)];
+
     unsafe {
         let mut sec = 0i64;
         let mut nsec = 0i32;
@@ -78,6 +80,8 @@ pub fn get_time() -> Timespec {
  * in nanoseconds since an unspecified epoch.
  */
 pub fn precise_time_ns() -> u64 {
+    #[fixed_stack_segment]; #[inline(never)];
+
     unsafe {
         let mut ns = 0u64;
         rustrt::precise_time_ns(&mut ns);
@@ -95,12 +99,14 @@ pub fn precise_time_s() -> float {
 }
 
 pub fn tzset() {
+    #[fixed_stack_segment]; #[inline(never)];
+
     unsafe {
         rustrt::rust_tzset();
     }
 }
 
-#[deriving(Eq, Encodable, Decodable)]
+#[deriving(Clone, DeepClone, Eq, Encodable, Decodable)]
 pub struct Tm {
     tm_sec: i32, // seconds after the minute ~[0-60]
     tm_min: i32, // minutes after the hour ~[0-59]
@@ -135,6 +141,8 @@ pub fn empty_tm() -> Tm {
 
 /// Returns the specified time in UTC
 pub fn at_utc(clock: Timespec) -> Tm {
+    #[fixed_stack_segment]; #[inline(never)];
+
     unsafe {
         let Timespec { sec, nsec } = clock;
         let mut tm = empty_tm();
@@ -150,6 +158,8 @@ pub fn now_utc() -> Tm {
 
 /// Returns the specified time in the local timezone
 pub fn at(clock: Timespec) -> Tm {
+    #[fixed_stack_segment]; #[inline(never)];
+
     unsafe {
         let Timespec { sec, nsec } = clock;
         let mut tm = empty_tm();
@@ -176,6 +186,8 @@ pub fn strftime(format: &str, tm: &Tm) -> ~str {
 impl Tm {
     /// Convert time to the seconds from January 1, 1970
     pub fn to_timespec(&self) -> Timespec {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             let sec = match self.tm_gmtoff {
                 0_i32 => rustrt::rust_timegm(self),
index 486a7dab5c1bb105a58c797152254ef2be690c06..118754ec02830a1d5b6a3fee9e7f3e6e99a02125 100644 (file)
@@ -835,34 +835,34 @@ fn heir_swap<K: TotalOrd, V>(node: &mut ~TreeNode<K, V>,
     };
 }
 
-impl<K: TotalOrd, V, T: Iterator<(K, V)>> FromIterator<(K, V), T> for TreeMap<K, V> {
-    fn from_iterator(iter: &mut T) -> TreeMap<K, V> {
+impl<K: TotalOrd, V> FromIterator<(K, V)> for TreeMap<K, V> {
+    fn from_iterator<T: Iterator<(K, V)>>(iter: &mut T) -> TreeMap<K, V> {
         let mut map = TreeMap::new();
         map.extend(iter);
         map
     }
 }
 
-impl<K: TotalOrd, V, T: Iterator<(K, V)>> Extendable<(K, V), T> for TreeMap<K, V> {
+impl<K: TotalOrd, V> Extendable<(K, V)> for TreeMap<K, V> {
     #[inline]
-    fn extend(&mut self, iter: &mut T) {
+    fn extend<T: Iterator<(K, V)>>(&mut self, iter: &mut T) {
         for (k, v) in *iter {
             self.insert(k, v);
         }
     }
 }
 
-impl<T: TotalOrd, Iter: Iterator<T>> FromIterator<T, Iter> for TreeSet<T> {
-    fn from_iterator(iter: &mut Iter) -> TreeSet<T> {
+impl<T: TotalOrd> FromIterator<T> for TreeSet<T> {
+    fn from_iterator<Iter: Iterator<T>>(iter: &mut Iter) -> TreeSet<T> {
         let mut set = TreeSet::new();
         set.extend(iter);
         set
     }
 }
 
-impl<T: TotalOrd, Iter: Iterator<T>> Extendable<T, Iter> for TreeSet<T> {
+impl<T: TotalOrd> Extendable<T> for TreeSet<T> {
     #[inline]
-    fn extend(&mut self, iter: &mut Iter) {
+    fn extend<Iter: Iterator<T>>(&mut self, iter: &mut Iter) {
         for elem in *iter {
             self.insert(elem);
         }
diff --git a/src/libextra/uuid.rs b/src/libextra/uuid.rs
new file mode 100644 (file)
index 0000000..1a99de1
--- /dev/null
@@ -0,0 +1,793 @@
+// 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.
+
+/*!
+Generate and parse UUIDs
+
+Provides support for Universally Unique Identifiers (UUIDs). A UUID is a
+unique 128-bit number, stored as 16 octets.  UUIDs are used to  assign unique
+identifiers to entities without requiring a central allocating authority.
+
+They are particularly useful in distributed systems, though can be used in
+disparate areas, such as databases and network protocols.  Typically a UUID is
+displayed in a readable string form as a sequence of hexadecimals digits,
+separated into groups by hyphens.
+
+The uniqueness property is not strictly guaranteed, however for all practical
+purposes, it can be assumed that an unintentional collision would be extremely
+unlikely.
+
+# Examples
+
+To create a new random (V4) UUID and print it out in hexadecimal form:
+
+~~~ {.rust}
+extern mod extra;
+use extra::uuid::Uuid;
+
+fn main() {
+    let uuid1 = Uuid::new_v4();
+    println(uuid1.to_str());
+}
+~~~
+
+# Strings
+
+Examples of string representations:
+
+* simple: `936DA01F9ABD4d9d80C702AF85C822A8`
+* hyphenated: `550e8400-e29b-41d4-a716-446655440000`
+* urn: `urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4`
+
+# References
+
+* [Wikipedia: Universally Unique Identifier](
+    http://en.wikipedia.org/wiki/Universally_unique_identifier)
+* [RFC4122: A Universally Unique IDentifier (UUID) URN Namespace](
+    http://tools.ietf.org/html/rfc4122)
+
+*/
+
+use std::str;
+use std::vec;
+use std::num::{FromStrRadix, Zero};
+use std::char::Char;
+use std::container::Container;
+use std::to_str::ToStr;
+use std::rand;
+use std::rand::RngUtil;
+use std::cmp::Eq;
+use std::cast::{transmute,transmute_copy};
+
+/// A 128-bit (16 byte) buffer containing the ID
+pub type UuidBytes = [u8, ..16];
+
+/// The version of the UUID, denoting the generating algorithm
+#[deriving(Eq)]
+pub enum UuidVersion {
+    /// Version 1: MAC address
+    Version1Mac    = 1,
+    /// Version 2: DCE Security
+    Version2Dce    = 2,
+    /// Version 3: MD5 hash
+    Version3Md5    = 3,
+    /// Version 4: Random
+    Version4Random = 4,
+    /// Version 5: SHA-1 hash
+    Version5Sha1   = 5,
+}
+
+/// The reserved variants of UUIDs
+#[deriving(Eq)]
+pub enum UuidVariant {
+    /// Reserved by the NCS for backward compatability
+    VariantNCS,
+    /// As described in the RFC4122 Specification (default)
+    VariantRFC4122,
+    /// Resreved by Microsoft for backward compatability
+    VariantMicrosoft,
+    /// Reserved for future expansion
+    VariantFuture,
+}
+
+/// A Universally Unique Identifier (UUID)
+pub struct Uuid {
+    /// The 128-bit number stored in 16 bytes
+    bytes: UuidBytes
+}
+
+/// A UUID stored as fields (identical to UUID, used only for conversions)
+struct UuidFields {
+    /// First field, 32-bit word
+    data1: u32,
+    /// Second field, 16-bit short
+    data2: u16,
+    /// Third field, 16-bit short
+    data3: u16,
+    /// Fourth field, 8 bytes
+    data4: [u8, ..8]
+}
+
+/// Error details for string parsing failures
+pub enum ParseError {
+    ErrorInvalidLength(uint),
+    ErrorInvalidCharacter(char, uint),
+    ErrorInvalidGroups(uint),
+    ErrorInvalidGroupLength(uint, uint, uint),
+}
+
+/// Converts a ParseError to a string
+impl ToStr for ParseError {
+    #[inline]
+    fn to_str(&self) -> ~str {
+        match *self {
+            ErrorInvalidLength(found) =>
+                fmt!("Invalid length; expecting 32, 36 or 45 chars, found %u",
+                    found),
+            ErrorInvalidCharacter(found, pos) =>
+                fmt!("Invalid character; found `%c` (0x%02x) at offset %u",
+                    found, found as uint, pos),
+            ErrorInvalidGroups(found) =>
+                fmt!("Malformed; wrong number of groups: expected 1 or 5, found %u",
+                    found),
+            ErrorInvalidGroupLength(group, found, expecting) =>
+                fmt!("Malformed; length of group %u was %u, expecting %u",
+                    group, found, expecting),
+        }
+    }
+}
+
+// Length of each hyphenated group in hex digits
+static UuidGroupLens: [uint, ..5] = [8u, 4u, 4u, 4u, 12u];
+
+/// UUID support
+impl Uuid {
+
+    /// Returns a nil or empty UUID (containing all zeroes)
+    pub fn new_nil() -> Uuid {
+        let uuid = Uuid{ bytes: [0, .. 16] };
+        uuid
+    }
+
+    /// Create a new UUID of the specified version
+    pub fn new(v: UuidVersion) -> Option<Uuid> {
+        match v {
+            Version4Random => Some(Uuid::new_v4()),
+            _ => None
+        }
+    }
+
+    /// Creates a new random UUID
+    ///
+    /// Uses the `rand` module's default RNG task as the source
+    /// of random numbers. Use the rand::Rand trait to supply
+    /// a custom generator if required.
+    pub fn new_v4() -> Uuid {
+        let ub = rand::task_rng().gen_bytes(16);
+        let mut uuid = Uuid{ bytes: [0, .. 16] };
+        vec::bytes::copy_memory(uuid.bytes, ub, 16);
+        uuid.set_variant(VariantRFC4122);
+        uuid.set_version(Version4Random);
+        uuid
+    }
+
+    /// Creates a UUID using the supplied field values
+    ///
+    /// # Arguments
+    /// * `d1` A 32-bit word
+    /// * `d2` A 16-bit word
+    /// * `d3` A 16-bit word
+    /// * `d4` Array of 8 octets
+    pub fn from_fields(d1: u32, d2: u16, d3: u16, d4: &[u8]) -> Uuid {
+        use std::unstable::intrinsics::{to_be16, to_be32};
+
+        // First construct a temporary field-based struct
+        let mut fields = UuidFields {
+                data1: 0,
+                data2: 0,
+                data3: 0,
+                data4: [0, ..8]
+        };
+
+        fields.data1 = to_be32(d1 as i32) as u32;
+        fields.data2 = to_be16(d2 as i16) as u16;
+        fields.data3 = to_be16(d3 as i16) as u16;
+        vec::bytes::copy_memory(fields.data4, d4, 8);
+
+        unsafe {
+            transmute(fields)
+        }
+    }
+
+    /// Creates a UUID using the supplied bytes
+    ///
+    /// # Arguments
+    /// * `b` An array or slice of 16 bytes
+    pub fn from_bytes(b: &[u8]) -> Option<Uuid> {
+        if b.len() != 16 {
+            return None
+        }
+
+        let mut uuid = Uuid{ bytes: [0, .. 16] };
+        unsafe {
+            vec::raw::copy_memory(uuid.bytes, b, 16);
+        }
+        Some(uuid)
+    }
+
+    /// Specifies the variant of the UUID structure
+    fn set_variant(&mut self, v: UuidVariant) {
+        // Octet 8 contains the variant in the most significant 3 bits
+        match v {
+            VariantNCS =>        // b0xx...
+                self.bytes[8] =  self.bytes[8] & 0x7f,
+            VariantRFC4122 =>    // b10x...
+                self.bytes[8] = (self.bytes[8] & 0x3f) | 0x80,
+            VariantMicrosoft =>  // b110...
+                self.bytes[8] = (self.bytes[8] & 0x1f) | 0xc0,
+            VariantFuture =>     // b111...
+                self.bytes[8] = (self.bytes[8] & 0x1f) | 0xe0,
+        }
+    }
+
+    /// Returns the variant of the UUID structure
+    ///
+    /// This determines the interpretation of the structure of the UUID.
+    /// Currently only the RFC4122 variant is generated by this module.
+    ///
+    /// * [Variant Reference](http://tools.ietf.org/html/rfc4122#section-4.1.1)
+    pub fn get_variant(&self) -> Option<UuidVariant> {
+        if self.bytes[8] & 0x80 == 0x00 {
+            Some(VariantNCS)
+        } else if self.bytes[8] & 0xc0 == 0x80 {
+            Some(VariantRFC4122)
+        } else if self.bytes[8] & 0xe0 == 0xc0  {
+            Some(VariantMicrosoft)
+        } else if self.bytes[8] & 0xe0 == 0xe0 {
+            Some(VariantFuture)
+        } else  {
+            None
+        }
+    }
+
+    /// Specifies the version number of the UUID
+    fn set_version(&mut self, v: UuidVersion) {
+        self.bytes[6] = (self.bytes[6] & 0xF) | ((v as u8) << 4);
+    }
+
+    /// Returns the version number of the UUID
+    ///
+    /// This represents the algorithm used to generate the contents.
+    ///
+    /// Currently only the Random (V4) algorithm is supported by this
+    /// module.  There are security and privacy implications for using
+    /// older versions - see [Wikipedia: Universally Unique Identifier](
+    /// http://en.wikipedia.org/wiki/Universally_unique_identifier) for
+    /// details.
+    ///
+    /// * [Version Reference](http://tools.ietf.org/html/rfc4122#section-4.1.3)
+    pub fn get_version_num(&self) -> uint {
+        (self.bytes[6] >> 4) as uint
+    }
+
+    /// Returns the version of the UUID
+    ///
+    /// This represents the algorithm used to generate the contents
+    pub fn get_version(&self) -> Option<UuidVersion> {
+        let v = (self.bytes[6] >> 4);
+        match v {
+            1 => Some(Version1Mac),
+            2 => Some(Version2Dce),
+            3 => Some(Version3Md5),
+            4 => Some(Version4Random),
+            5 => Some(Version5Sha1),
+            _ => None
+        }
+    }
+
+    /// Return an array of 16 octets containing the UUID data
+    pub fn to_bytes<'a>(&'a self) -> &'a [u8] {
+        self.bytes.as_slice()
+    }
+
+    /// Returns the UUID as a string of 16 hexadecimal digits
+    ///
+    /// Example: `936DA01F9ABD4d9d80C702AF85C822A8`
+    pub fn to_simple_str(&self) -> ~str {
+        let mut s: ~[u8] = vec::from_elem(32, 0u8);
+        for i in range(0u, 16u) {
+            let digit = fmt!("%02x", self.bytes[i] as uint);
+            s[i*2+0] = digit[0];
+            s[i*2+1] = digit[1];
+        }
+        str::from_bytes(s)
+    }
+
+    /// Returns a string of hexadecimal digits, separated into groups with a hypen
+    ///
+    /// Example: `550e8400-e29b-41d4-a716-446655440000`
+    pub fn to_hyphenated_str(&self) -> ~str {
+        use std::unstable::intrinsics::{to_be16, to_be32};
+        // Convert to field-based struct as it matches groups in output.
+        // Ensure fields are in network byte order, as per RFC.
+        let mut uf: UuidFields;
+        unsafe {
+            uf = transmute_copy(&self.bytes);
+        }
+        uf.data1 = to_be32(uf.data1 as i32) as u32;
+        uf.data2 = to_be16(uf.data2 as i16) as u16;
+        uf.data3 = to_be16(uf.data3 as i16) as u16;
+        let s = fmt!("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+            uf.data1 as uint,
+            uf.data2 as uint, uf.data3 as uint,
+            uf.data4[0] as uint, uf.data4[1] as uint,
+            uf.data4[2] as uint, uf.data4[3] as uint, uf.data4[4] as uint,
+            uf.data4[5] as uint, uf.data4[6] as uint, uf.data4[7] as uint);
+        s
+    }
+
+    /// Returns the UUID formatted as a full URN string
+    ///
+    /// This is the same as the hyphenated format, but with the "urn:uuid:" prefix.
+    ///
+    /// Example: `urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4`
+    pub fn to_urn_str(&self) -> ~str {
+        "urn:uuid:" + self.to_hyphenated_str()
+    }
+
+    /// Parses a UUID from a string of hexadecimal digits with optional hyphens
+    ///
+    /// Any of the formats generated by this module (simple, hyphenated, urn) are
+    /// supported by this parsing function.
+    pub fn parse_string(us: &str) -> Result<Uuid, ParseError> {
+
+        let mut us = us.clone();
+        let orig_len = us.len();
+
+        // Ensure length is valid for any of the supported formats
+        if orig_len != 32 && orig_len != 36 && orig_len != 45 {
+            return Err(ErrorInvalidLength(orig_len));
+        }
+
+        // Strip off URN prefix if present
+        if us.starts_with("urn:uuid:") {
+            us = us.slice(9, orig_len);
+        }
+
+        // Make sure all chars are either hex digits or hyphen
+        for (i, c) in us.iter().enumerate() {
+            match c {
+                '0'..'9' | 'A'..'F' | 'a'..'f' | '-' => {},
+                _ => return Err(ErrorInvalidCharacter(c, i)),
+            }
+        }
+
+        // Split string up by hyphens into groups
+        let hex_groups: ~[&str] = us.split_str_iter("-").collect();
+
+        // Get the length of each group
+        let group_lens: ~[uint] = hex_groups.iter().map(|&v| v.len()).collect();
+
+        // Ensure the group lengths are valid
+        match group_lens.len() {
+            // Single group, no hyphens
+            1 => {
+                if group_lens[0] != 32 {
+                    return Err(ErrorInvalidLength(group_lens[0]));
+                }
+            },
+            // Five groups, hyphens in between each
+            5 => {
+                // Ensure each group length matches the expected
+                for (i, (&gl, &expected)) in
+                    group_lens.iter().zip(UuidGroupLens.iter()).enumerate() {
+                    if gl != expected {
+                        return Err(ErrorInvalidGroupLength(i, gl, expected))
+                    }
+                }
+            },
+            _ => {
+                return Err(ErrorInvalidGroups(group_lens.len()));
+            }
+        }
+
+        // Normalise into one long hex string
+        let vs = hex_groups.concat();
+
+        // At this point, we know we have a valid hex string, without hyphens
+        assert!(vs.len() == 32);
+        assert!(vs.iter().all(|c| c.is_digit_radix(16)));
+
+        // Allocate output UUID buffer
+        let mut ub = [0u8, ..16];
+
+        // Extract each hex digit from the string
+        for i in range(0u, 16u) {
+            ub[i] = FromStrRadix::from_str_radix(vs.slice(i*2, (i+1)*2), 16).unwrap();
+        }
+
+        Ok(Uuid::from_bytes(ub).unwrap())
+    }
+}
+
+impl Zero for Uuid {
+    /// Returns the nil UUID, which is all zeroes
+    fn zero() -> Uuid {
+        Uuid::new_nil()
+    }
+
+    /// Tests if the UUID is nil or all zeroes
+    fn is_zero(&self) -> bool {
+        return self.bytes.iter().all(|&b| b == 0);
+    }
+}
+
+impl Clone for Uuid {
+    /// Returns a copy of the UUID
+    fn clone(&self) -> Uuid {
+        let mut clone = Uuid{ bytes: [0, .. 16] };
+        vec::bytes::copy_memory(clone.bytes, self.bytes, 16);
+        clone
+    }
+}
+
+impl FromStr for Uuid {
+    /// Parse a hex string and interpret as a UUID
+    ///
+    /// Accepted formats are a sequence of 32 hexadecimal characters,
+    /// with or without hypens (grouped as 8, 4, 4, 4, 12).
+    fn from_str(us: &str) -> Option<Uuid> {
+        let result = Uuid::parse_string(us);
+        match result {
+            Ok(u) => Some(u),
+            Err(_) => None
+        }
+    }
+}
+
+/// Convert the UUID to a hexadecimal-based string representation
+impl ToStr for Uuid {
+    fn to_str(&self) -> ~str {
+        self.to_simple_str()
+    }
+}
+
+/// Test two UUIDs for equality
+///
+/// UUIDs are equal only when they are byte-for-byte identical
+impl Eq for Uuid {
+    fn eq(&self, other: &Uuid) -> bool {
+        self.bytes == other.bytes
+    }
+}
+
+/// Test two UUIDs for equality
+///
+/// UUIDs are equal only when they are byte-for-byte identical
+impl TotalEq for Uuid {
+    fn equals(&self, other: &Uuid) -> bool {
+        self.bytes == other.bytes
+    }
+}
+
+/// Generates a random instance of UUID (V4 conformant)
+impl rand::Rand for Uuid {
+    #[inline]
+    fn rand<R: rand::Rng>(rng: &mut R) -> Uuid {
+        let ub = rng.gen_bytes(16);
+        let mut uuid = Uuid{ bytes: [0, .. 16] };
+        vec::bytes::copy_memory(uuid.bytes, ub, 16);
+        uuid.set_variant(VariantRFC4122);
+        uuid.set_version(Version4Random);
+        uuid
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    use std::str;
+    use std::rand;
+    use std::num::Zero;
+
+    #[test]
+    fn test_new_nil() {
+        let nil = Uuid::new_nil();
+        let nb = nil.to_bytes();
+
+        assert!(nb.iter().all(|&b| b == 0));
+    }
+
+    #[test]
+    fn test_zero() {
+        let uz: Uuid = Zero::zero();
+        let nz = Uuid::new_v4();
+
+        assert!(uz.is_zero());
+        assert!(! nz.is_zero());
+    }
+
+    #[test]
+    fn test_new() {
+        // Supported
+        let uuid1 = Uuid::new(Version4Random).unwrap();
+        let s = uuid1.to_simple_str();
+
+        assert!(s.len() == 32);
+        assert!(uuid1.get_version().unwrap() == Version4Random);
+
+        // Test unsupported versions
+        assert!(Uuid::new(Version1Mac) == None);
+        assert!(Uuid::new(Version2Dce) == None);
+        assert!(Uuid::new(Version3Md5) == None);
+        assert!(Uuid::new(Version5Sha1) == None);
+    }
+
+    #[test]
+    fn test_new_v4() {
+        let uuid1 = Uuid::new_v4();
+
+        assert!(uuid1.get_version().unwrap() == Version4Random);
+        assert!(uuid1.get_variant().unwrap() == VariantRFC4122);
+    }
+
+    #[test]
+    fn test_get_version() {
+        let uuid1 = Uuid::new_v4();
+
+        assert!(uuid1.get_version().unwrap() == Version4Random);
+        assert!(uuid1.get_version_num() == 4);
+    }
+
+    #[test]
+    fn test_get_variant() {
+        let uuid1 = Uuid::new_v4();
+        let uuid2 = Uuid::parse_string("550e8400-e29b-41d4-a716-446655440000").unwrap();
+        let uuid3 = Uuid::parse_string("67e55044-10b1-426f-9247-bb680e5fe0c8").unwrap();
+        let uuid4 = Uuid::parse_string("936DA01F9ABD4d9dC0C702AF85C822A8").unwrap();
+        let uuid5 = Uuid::parse_string("F9168C5E-CEB2-4faa-D6BF-329BF39FA1E4").unwrap();
+        let uuid6 = Uuid::parse_string("f81d4fae-7dec-11d0-7765-00a0c91e6bf6").unwrap();
+
+        assert!(uuid1.get_variant().unwrap() == VariantRFC4122);
+        assert!(uuid2.get_variant().unwrap() == VariantRFC4122);
+        assert!(uuid3.get_variant().unwrap() == VariantRFC4122);
+        assert!(uuid4.get_variant().unwrap() == VariantMicrosoft);
+        assert!(uuid5.get_variant().unwrap() == VariantMicrosoft);
+        assert!(uuid6.get_variant().unwrap() == VariantNCS);
+    }
+
+    #[test]
+    fn test_parse_uuid_v4() {
+
+        // Invalid
+        assert!(Uuid::parse_string("").is_err());
+        assert!(Uuid::parse_string("!").is_err());
+        assert!(Uuid::parse_string("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E45").is_err());
+        assert!(Uuid::parse_string("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4").is_err());
+        assert!(Uuid::parse_string("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4").is_err());
+        assert!(Uuid::parse_string("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4").is_err());
+        assert!(Uuid::parse_string("F9168C5E-CEB2-4faa").is_err());
+        assert!(Uuid::parse_string("F9168C5E-CEB2-4faaXB6BFF329BF39FA1E4").is_err());
+        assert!(Uuid::parse_string("F9168C5E-CEB-24fa-eB6BFF32-BF39FA1E4").is_err());
+        assert!(Uuid::parse_string("01020304-1112-2122-3132-41424344").is_err());
+        assert!(Uuid::parse_string("67e5504410b1426f9247bb680e5fe0c").is_err());
+        assert!(Uuid::parse_string("67e5504410b1426f9247bb680e5fe0c88").is_err());
+        assert!(Uuid::parse_string("67e5504410b1426f9247bb680e5fe0cg8").is_err());
+        assert!(Uuid::parse_string("67e5504410b1426%9247bb680e5fe0c8").is_err());
+
+        // Valid
+        assert!(Uuid::parse_string("00000000000000000000000000000000").is_ok());
+        assert!(Uuid::parse_string("67e55044-10b1-426f-9247-bb680e5fe0c8").is_ok());
+        assert!(Uuid::parse_string("67e55044-10b1-426f-9247-bb680e5fe0c8").is_ok());
+        assert!(Uuid::parse_string("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").is_ok());
+        assert!(Uuid::parse_string("67e5504410b1426f9247bb680e5fe0c8").is_ok());
+        assert!(Uuid::parse_string("01020304-1112-2122-3132-414243444546").is_ok());
+        assert!(Uuid::parse_string("urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8").is_ok());
+
+        // Nil
+        let nil = Uuid::new_nil();
+        assert!(Uuid::parse_string("00000000000000000000000000000000").unwrap()  == nil);
+        assert!(Uuid::parse_string("00000000-0000-0000-0000-000000000000").unwrap() == nil);
+
+        // Round-trip
+        let uuid_orig = Uuid::new_v4();
+        let orig_str = uuid_orig.to_str();
+        let uuid_out = Uuid::parse_string(orig_str).unwrap();
+        assert!(uuid_orig == uuid_out);
+
+        // Test error reporting
+        let e = Uuid::parse_string("67e5504410b1426f9247bb680e5fe0c").unwrap_err();
+        assert!(match(e){ ErrorInvalidLength(n) => n==31, _ => false });
+
+        let e = Uuid::parse_string("67e550X410b1426f9247bb680e5fe0cd").unwrap_err();
+        assert!(match(e){ ErrorInvalidCharacter(c, n) => c=='X' && n==6, _ => false });
+
+        let e = Uuid::parse_string("67e550-4105b1426f9247bb680e5fe0c").unwrap_err();
+        assert!(match(e){ ErrorInvalidGroups(n) => n==2, _ => false });
+
+        let e = Uuid::parse_string("F9168C5E-CEB2-4faa-B6BF1-02BF39FA1E4").unwrap_err();
+        assert!(match(e){ ErrorInvalidGroupLength(g, n, e) => g==3 && n==5 && e==4, _ => false });
+    }
+
+    #[test]
+    fn test_to_simple_str() {
+        let uuid1 = Uuid::new_v4();
+        let s = uuid1.to_simple_str();
+
+        assert!(s.len() == 32);
+        assert!(s.iter().all(|c| c.is_digit_radix(16)));
+    }
+
+    #[test]
+    fn test_to_str() {
+        let uuid1 = Uuid::new_v4();
+        let s = uuid1.to_str();
+
+        assert!(s.len() == 32);
+        assert!(s.iter().all(|c| c.is_digit_radix(16)));
+    }
+
+    #[test]
+    fn test_to_hyphenated_str() {
+        let uuid1 = Uuid::new_v4();
+        let s = uuid1.to_hyphenated_str();
+
+        assert!(s.len() == 36);
+        assert!(s.iter().all(|c| c.is_digit_radix(16) || c == '-'));
+    }
+
+    #[test]
+    fn test_to_urn_str() {
+        let uuid1 = Uuid::new_v4();
+        let ss = uuid1.to_urn_str();
+        let s = ss.slice(9, ss.len());
+
+        assert!(ss.starts_with("urn:uuid:"));
+        assert!(s.len() == 36);
+        assert!(s.iter().all(|c| c.is_digit_radix(16) || c == '-'));
+    }
+
+    #[test]
+    fn test_to_str_matching() {
+        let uuid1 = Uuid::new_v4();
+
+        let hs = uuid1.to_hyphenated_str();
+        let ss = uuid1.to_str();
+
+        let hsn = str::from_chars(hs.iter().filter(|&c| c != '-').collect::<~[char]>());
+
+        assert!(hsn == ss);
+    }
+
+    #[test]
+    fn test_string_roundtrip() {
+        let uuid = Uuid::new_v4();
+
+        let hs = uuid.to_hyphenated_str();
+        let uuid_hs = Uuid::parse_string(hs).unwrap();
+        assert!(uuid_hs == uuid);
+
+        let ss = uuid.to_str();
+        let uuid_ss = Uuid::parse_string(ss).unwrap();
+        assert!(uuid_ss == uuid);
+    }
+
+    #[test]
+    fn test_compare() {
+        let uuid1 = Uuid::new_v4();
+        let uuid2 = Uuid::new_v4();
+
+        assert!(uuid1 == uuid1);
+        assert!(uuid2 == uuid2);
+        assert!(uuid1 != uuid2);
+        assert!(uuid2 != uuid1);
+    }
+
+    #[test]
+    fn test_from_fields() {
+        let d1: u32 = 0xa1a2a3a4;
+        let d2: u16 = 0xb1b2;
+        let d3: u16 = 0xc1c2;
+        let d4: ~[u8] = ~[0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
+
+        let u = Uuid::from_fields(d1, d2, d3, d4);
+
+        let expected = ~"a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
+        let result = u.to_simple_str();
+        assert!(result == expected);
+    }
+
+    #[test]
+    fn test_from_bytes() {
+        let b = ~[ 0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2,
+                   0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8 ];
+
+        let u = Uuid::from_bytes(b).unwrap();
+        let expected = ~"a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
+
+        assert!(u.to_simple_str() == expected);
+    }
+
+    #[test]
+    fn test_to_bytes() {
+        let u = Uuid::new_v4();
+        let ub = u.to_bytes();
+
+        assert!(ub.len() == 16);
+        assert!(! ub.iter().all(|&b| b == 0));
+    }
+
+    #[test]
+    fn test_bytes_roundtrip() {
+        let b_in: [u8, ..16] = [ 0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2,
+                                 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8 ];
+
+        let u = Uuid::from_bytes(b_in.clone()).unwrap();
+
+        let b_out = u.to_bytes();
+
+        assert!(b_in == b_out);
+    }
+
+    #[test]
+    fn test_operator_eq() {
+        let u1 = Uuid::new_v4();
+        let u2 = u1.clone();
+        let u3 = Uuid::new_v4();
+
+        assert!(u1 == u1);
+        assert!(u1 == u2);
+        assert!(u2 == u1);
+
+        assert!(u1 != u3);
+        assert!(u3 != u1);
+        assert!(u2 != u3);
+        assert!(u3 != u2);
+    }
+
+    #[test]
+    fn test_rand_rand() {
+        let mut rng = rand::rng();
+        let u: ~Uuid = rand::Rand::rand(&mut rng);
+        let ub = u.to_bytes();
+
+        assert!(ub.len() == 16);
+        assert!(! ub.iter().all(|&b| b == 0));
+    }
+}
+
+#[cfg(test)]
+mod bench {
+    use super::*;
+    use test::BenchHarness;
+
+    #[bench]
+    pub fn create_uuids(bh: &mut BenchHarness) {
+        do bh.iter {
+            Uuid::new_v4();
+        }
+    }
+
+    #[bench]
+    pub fn uuid_to_str(bh: &mut BenchHarness) {
+        let u = Uuid::new_v4();
+        do bh.iter {
+            u.to_str();
+        }
+    }
+
+    #[bench]
+    pub fn parse_str(bh: &mut BenchHarness) {
+        let s = "urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4";
+        do bh.iter {
+            let u = Uuid::parse_string(s);
+        }
+    }
+}
index b8f81a44759cecfaf4bd90fc8b979e8f84c8f79e..d010f7d52d8a82dc05dd2c996f5b7b7c53f82922 100644 (file)
@@ -229,6 +229,8 @@ fn usage() {
 }
 
 pub fn main() {
+    #[fixed_stack_segment]; #[inline(never)];
+
     let os_args = os::args();
 
     if (os_args.len() > 1 && (os_args[1] == ~"-v" || os_args[1] == ~"--version")) {
index ed6eab5de193a93f6e700f7c01e6e4d4cddf1099..91b6ee2411091982c3acb9766abd30d1c3a66ee0 100644 (file)
@@ -78,10 +78,10 @@ pub fn WriteOutputFile(sess: Session,
         OptLevel: c_int,
         EnableSegmentedStacks: bool) {
     unsafe {
-        do Triple.to_c_str().with_ref |Triple| {
-            do Cpu.to_c_str().with_ref |Cpu| {
-                do Feature.to_c_str().with_ref |Feature| {
-                    do Output.to_c_str().with_ref |Output| {
+        do Triple.with_c_str |Triple| {
+            do Cpu.with_c_str |Cpu| {
+                do Feature.with_c_str |Feature| {
+                    do Output.with_c_str |Output| {
                         let result = llvm::LLVMRustWriteOutputFile(
                                 PM,
                                 M,
@@ -152,7 +152,7 @@ pub fn exec(sess: Session,
 
                 debug!("linking: %s", path);
 
-                do path.to_c_str().with_ref |buf_t| {
+                do path.with_c_str |buf_t| {
                     if !llvm::LLVMRustLoadCrate(manager, buf_t) {
                         llvm_err(sess, ~"Could not link");
                     }
@@ -171,7 +171,7 @@ pub fn exec(sess: Session,
             // Next, we need to get a handle on the _rust_main function by
             // looking up it's corresponding ValueRef and then requesting that
             // the execution engine compiles the function.
-            let fun = do "_rust_main".to_c_str().with_ref |entry| {
+            let fun = do "_rust_main".with_c_str |entry| {
                 llvm::LLVMGetNamedFunction(m, entry)
             };
             if fun.is_null() {
@@ -270,14 +270,14 @@ pub fn run_passes(sess: Session,
                   output_type_bitcode => {
                     if opts.optimize != session::No {
                         let filename = output.with_filetype("no-opt.bc");
-                        do filename.to_c_str().with_ref |buf| {
+                        do filename.with_c_str |buf| {
                             llvm::LLVMWriteBitcodeToFile(llmod, buf);
                         }
                     }
                   }
                   _ => {
                     let filename = output.with_filetype("bc");
-                    do filename.to_c_str().with_ref |buf| {
+                    do filename.with_c_str |buf| {
                         llvm::LLVMWriteBitcodeToFile(llmod, buf);
                     }
                   }
@@ -340,7 +340,7 @@ pub fn run_passes(sess: Session,
                     // Always output the bitcode file with --save-temps
 
                     let filename = output.with_filetype("opt.bc");
-                    do filename.to_c_str().with_ref |buf| {
+                    do filename.with_c_str |buf| {
                         llvm::LLVMWriteBitcodeToFile(llmod, buf)
                     };
                     // Save the assembly file if -S is used
@@ -401,13 +401,13 @@ pub fn run_passes(sess: Session,
 
             if output_type == output_type_llvm_assembly {
                 // Given options "-S --emit-llvm": output LLVM assembly
-                do output.to_c_str().with_ref |buf_o| {
+                do output.with_c_str |buf_o| {
                     llvm::LLVMRustAddPrintModulePass(pm.llpm, llmod, buf_o);
                 }
             } else {
                 // If only a bitcode file is asked for by using the
                 // '--emit-llvm' flag, then output it here
-                do output.to_c_str().with_ref |buf| {
+                do output.with_c_str |buf| {
                     llvm::LLVMWriteBitcodeToFile(llmod, buf);
                 }
             }
index 854d11fd3503599e030e2d33d8f8a9dbd36ceb21..29bc577dff960c844c87756c581062e487719d02 100644 (file)
@@ -173,7 +173,7 @@ pub fn populate_pass_manager(sess: Session, pm: &mut PassManager, pass_list:&[~s
 }
 
 pub fn create_pass(name:&str) -> Option<PassRef> {
-    do name.to_c_str().with_ref |s| {
+    do name.with_c_str |s| {
         unsafe {
             let p = llvm::LLVMCreatePass(s);
             if p.is_null() {
index 76bba481619859677b262aeb1626d6d537c8b3c3..0ad53c4d49c1a14ed20222222d42d296bf89163b 100644 (file)
@@ -16,8 +16,6 @@
 
 pub struct Upcalls {
     trace: ValueRef,
-    call_shim_on_c_stack: ValueRef,
-    call_shim_on_rust_stack: ValueRef,
     rust_personality: ValueRef,
     reset_stack_limit: ValueRef
 }
@@ -47,9 +45,6 @@ pub fn declare_upcalls(targ_cfg: @session::config, llmod: ModuleRef) -> @Upcalls
 
     @Upcalls {
         trace: upcall!(fn trace(opaque_ptr, opaque_ptr, int_ty) -> Type::void()),
-        call_shim_on_c_stack: upcall!(fn call_shim_on_c_stack(opaque_ptr, opaque_ptr) -> int_ty),
-        call_shim_on_rust_stack:
-            upcall!(fn call_shim_on_rust_stack(opaque_ptr, opaque_ptr) -> int_ty),
         rust_personality: upcall!(nothrow fn rust_personality -> Type::i32()),
         reset_stack_limit: upcall!(nothrow fn reset_stack_limit -> Type::void())
     }
index ca2e33b6a6dd5a9729a63fecfea75fa7d06edfff..cdafb7400e1a294e4e6fd9c3061f56bc64ed2fe7 100644 (file)
@@ -65,14 +65,14 @@ pub fn source_name(input: &input) -> @str {
     }
 }
 
-pub fn default_configuration(sess: Session, argv0: @str, input: &input) ->
+pub fn default_configuration(sess: Session) ->
    ast::CrateConfig {
-    let (libc, tos) = match sess.targ_cfg.os {
-        session::os_win32 =>   (@"msvcrt.dll", @"win32"),
-        session::os_macos =>   (@"libc.dylib", @"macos"),
-        session::os_linux =>   (@"libc.so.6",  @"linux"),
-        session::os_android => (@"libc.so",    @"android"),
-        session::os_freebsd => (@"libc.so.7",  @"freebsd")
+    let tos = match sess.targ_cfg.os {
+        session::os_win32 =>   @"win32",
+        session::os_macos =>   @"macos",
+        session::os_linux =>   @"linux",
+        session::os_android => @"android",
+        session::os_freebsd => @"freebsd"
     };
 
     // ARM is bi-endian, however using NDK seems to default
@@ -92,10 +92,7 @@ pub fn default_configuration(sess: Session, argv0: @str, input: &input) ->
          mk(@"target_arch", arch),
          mk(@"target_endian", end),
          mk(@"target_word_size", wordsz),
-         mk(@"target_libc", libc),
-         // Build bindings.
-         mk(@"build_compiler", argv0),
-         mk(@"build_input", source_name(input))];
+    ];
 }
 
 pub fn append_configuration(cfg: &mut ast::CrateConfig, name: @str) {
@@ -104,11 +101,11 @@ pub fn append_configuration(cfg: &mut ast::CrateConfig, name: @str) {
     }
 }
 
-pub fn build_configuration(sess: Session, argv0: @str, input: &input) ->
+pub fn build_configuration(sess: Session) ->
    ast::CrateConfig {
     // Combine the configuration requested by the session (command line) with
     // some default and generated configuration items
-    let default_cfg = default_configuration(sess, argv0, input);
+    let default_cfg = default_configuration(sess);
     let mut user_cfg = sess.opts.cfg.clone();
     // If the user wants a test runner, then add the test cfg
     if sess.opts.test { append_configuration(&mut user_cfg, @"test") }
@@ -268,6 +265,9 @@ pub fn phase_3_run_analysis_passes(sess: Session,
     time(time_passes, ~"loop checking", ||
          middle::check_loop::check_crate(ty_cx, crate));
 
+    time(time_passes, ~"stack checking", ||
+         middle::stack_check::stack_check_crate(ty_cx, crate));
+
     let middle::moves::MoveMaps {moves_map, moved_variables_set,
                                  capture_map} =
         time(time_passes, ~"compute moves", ||
@@ -645,9 +645,13 @@ pub fn build_session_options(binary: @str,
         }
         debugging_opts |= this_bit;
     }
+
     if debugging_opts & session::debug_llvm != 0 {
-        unsafe {
-            llvm::LLVMSetDebug(1);
+        set_llvm_debug();
+
+        fn set_llvm_debug() {
+            #[fixed_stack_segment]; #[inline(never)];
+            unsafe { llvm::LLVMSetDebug(1); }
         }
     }
 
@@ -694,6 +698,14 @@ pub fn build_session_options(binary: @str,
     let extra_debuginfo = debugging_opts & session::extra_debug_info != 0;
     let debuginfo = debugging_opts & session::debug_info != 0 ||
         extra_debuginfo;
+
+    // If debugging info is generated, do not collapse monomorphized function instances.
+    // Functions with equivalent llvm code still need separate debugging descriptions because names
+    // might differ.
+    if debuginfo {
+        debugging_opts |= session::no_monomorphic_collapse;
+    }
+
     let statik = debugging_opts & session::statik != 0;
 
     let addl_lib_search_paths = getopts::opt_strs(matches, "L").map(|s| Path(*s));
@@ -980,7 +992,7 @@ pub fn list_metadata(sess: Session, path: &Path, out: @io::Writer) {
 mod test {
 
     use driver::driver::{build_configuration, build_session};
-    use driver::driver::{build_session_options, optgroups, str_input};
+    use driver::driver::{build_session_options, optgroups};
 
     use extra::getopts::groups::getopts;
     use extra::getopts;
@@ -998,7 +1010,7 @@ fn test_switch_implies_cfg_test() {
         let sessopts = build_session_options(
             @"rustc", matches, diagnostic::emit);
         let sess = build_session(sessopts, diagnostic::emit);
-        let cfg = build_configuration(sess, @"whatever", &str_input(@""));
+        let cfg = build_configuration(sess);
         assert!((attr::contains_name(cfg, "test")));
     }
 
@@ -1016,7 +1028,7 @@ fn test_switch_implies_cfg_test_unless_cfg_test() {
         let sessopts = build_session_options(
             @"rustc", matches, diagnostic::emit);
         let sess = build_session(sessopts, diagnostic::emit);
-        let cfg = build_configuration(sess, @"whatever", &str_input(@""));
+        let cfg = build_configuration(sess);
         let mut test_items = cfg.iter().filter(|m| "test" == m.name());
         assert!(test_items.next().is_some());
         assert!(test_items.next().is_none());
index 597de440ae1fc0f986bbd48f81f1a182f2b14875..0aacd4c5063db28a3c8eea9a972cb04b237acba4 100644 (file)
@@ -292,6 +292,7 @@ fn mk_std(cx: &TestCtxt) -> ast::view_item {
     }
 }
 
+#[cfg(stage0)]
 fn mk_test_module(cx: &TestCtxt) -> @ast::item {
 
     // Link to extra
@@ -334,6 +335,48 @@ pub fn main() {
 
     return @item;
 }
+#[cfg(not(stage0))]
+fn mk_test_module(cx: &TestCtxt) -> @ast::item {
+
+    // Link to extra
+    let view_items = ~[mk_std(cx)];
+
+    // A constant vector of test descriptors.
+    let tests = mk_tests(cx);
+
+    // The synthesized main function which will call the console test runner
+    // with our list of tests
+    let mainfn = (quote_item!(cx.ext_cx,
+        pub fn main() {
+            #[main];
+            extra::test::test_main_static(::std::os::args(), TESTS);
+        }
+    )).unwrap();
+
+    let testmod = ast::_mod {
+        view_items: view_items,
+        items: ~[mainfn, tests],
+    };
+    let item_ = ast::item_mod(testmod);
+
+    // This attribute tells resolve to let us call unexported functions
+    let resolve_unexported_attr =
+        attr::mk_attr(attr::mk_word_item(@"!resolve_unexported"));
+
+    let item = ast::item {
+        ident: cx.sess.ident_of("__test"),
+        attrs: ~[resolve_unexported_attr],
+        id: cx.sess.next_node_id(),
+        node: item_,
+        vis: ast::public,
+        span: dummy_sp(),
+     };
+
+    debug!("Synthetic test module:\n%s\n",
+           pprust::item_to_str(@item.clone(), cx.sess.intr()));
+
+    return @item;
+}
 
 fn nospan<T>(t: T) -> codemap::spanned<T> {
     codemap::spanned { node: t, span: dummy_sp() }
@@ -355,6 +398,7 @@ fn path_node_global(ids: ~[ast::ident]) -> ast::Path {
                  types: ~[] }
 }
 
+#[cfg(stage0)]
 fn mk_tests(cx: &TestCtxt) -> @ast::item {
 
     let ext_cx = cx.ext_cx;
@@ -368,6 +412,17 @@ fn mk_tests(cx: &TestCtxt) -> @ast::item {
         ;
     )).unwrap()
 }
+#[cfg(not(stage0))]
+fn mk_tests(cx: &TestCtxt) -> @ast::item {
+    // The vector of test_descs for this crate
+    let test_descs = mk_test_descs(cx);
+
+    (quote_item!(cx.ext_cx,
+        pub static TESTS : &'static [self::extra::test::TestDescAndFn] =
+            $test_descs
+        ;
+    )).unwrap()
+}
 
 fn is_extra(cx: &TestCtxt) -> bool {
     let items = attr::find_linkage_metas(cx.crate.attrs);
@@ -398,6 +453,7 @@ fn mk_test_descs(cx: &TestCtxt) -> @ast::expr {
     }
 }
 
+#[cfg(stage0)]
 fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> @ast::expr {
     let span = test.span;
     let path = test.path.clone();
@@ -453,3 +509,57 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> @ast::expr {
     );
     e
 }
+#[cfg(not(stage0))]
+fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> @ast::expr {
+    let span = test.span;
+    let path = test.path.clone();
+
+    debug!("encoding %s", ast_util::path_name_i(path));
+
+    let name_lit: ast::lit =
+        nospan(ast::lit_str(ast_util::path_name_i(path).to_managed()));
+
+    let name_expr = @ast::expr {
+          id: cx.sess.next_node_id(),
+          node: ast::expr_lit(@name_lit),
+          span: span
+    };
+
+    let fn_path = path_node_global(path);
+
+    let fn_expr = @ast::expr {
+        id: cx.sess.next_node_id(),
+        node: ast::expr_path(fn_path),
+        span: span,
+    };
+
+    let t_expr = if test.bench {
+        quote_expr!(cx.ext_cx, self::extra::test::StaticBenchFn($fn_expr) )
+    } else {
+        quote_expr!(cx.ext_cx, self::extra::test::StaticTestFn($fn_expr) )
+    };
+
+    let ignore_expr = if test.ignore {
+        quote_expr!(cx.ext_cx, true )
+    } else {
+        quote_expr!(cx.ext_cx, false )
+    };
+
+    let fail_expr = if test.should_fail {
+        quote_expr!(cx.ext_cx, true )
+    } else {
+        quote_expr!(cx.ext_cx, false )
+    };
+
+    let e = quote_expr!(cx.ext_cx,
+        self::extra::test::TestDescAndFn {
+            desc: self::extra::test::TestDesc {
+                name: self::extra::test::StaticTestName($name_expr),
+                ignore: $ignore_expr,
+                should_fail: $fail_expr
+            },
+            testfn: $t_expr,
+        }
+    );
+    e
+}
index 156aafacfec628d5b375ab75d7ae30a7268f5f0d..9175c13c8aeebbd2940d143aef154ac4980ff163 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// LLVM wrappers are intended to be called from trans,
+// which already runs in a #[fixed_stack_segment]
+#[allow(cstack)];
+
 use std::c_str::ToCStr;
 use std::hashmap::HashMap;
 use std::libc::{c_uint, c_ushort};
@@ -2086,6 +2090,16 @@ pub fn LLVMDIBuilderCreateUnionType(Builder: DIBuilderRef,
 
         #[fast_ffi]
         pub fn LLVMSetUnnamedAddr(GlobalVar: ValueRef, UnnamedAddr: Bool);
+
+        #[fast_ffi]
+        pub fn LLVMDIBuilderCreateTemplateTypeParameter(Builder: DIBuilderRef,
+                                                        Scope: ValueRef,
+                                                        Name: *c_char,
+                                                        Ty: ValueRef,
+                                                        File: ValueRef,
+                                                        LineNo: c_uint,
+                                                        ColumnNo: c_uint)
+                                                        -> ValueRef;
     }
 }
 
@@ -2236,6 +2250,11 @@ pub fn type_to_str(&self, ty: Type) -> ~str {
         self.type_to_str_depth(ty, 30)
     }
 
+    pub fn types_to_str(&self, tys: &[Type]) -> ~str {
+        let strs = tys.map(|t| self.type_to_str(*t));
+        fmt!("[%s]", strs.connect(","))
+    }
+
     pub fn val_to_str(&self, val: ValueRef) -> ~str {
         unsafe {
             let ty = Type::from_ref(llvm::LLVMTypeOf(val));
@@ -2271,7 +2290,7 @@ pub struct TargetData {
 }
 
 pub fn mk_target_data(string_rep: &str) -> TargetData {
-    let lltd = do string_rep.to_c_str().with_ref |buf| {
+    let lltd = do string_rep.with_c_str |buf| {
         unsafe { llvm::LLVMCreateTargetData(buf) }
     };
 
index eaf01241c8165d0b9eebc00a591edccb5d233b3e..c8c4a396c87af99c0041f1274fcd3acf92b353c7 100644 (file)
@@ -57,6 +57,7 @@ pub fn read_crates(diag: @mut span_handler,
     warn_if_multiple_versions(e, diag, *e.crate_cache);
 }
 
+#[deriving(Clone)]
 struct cache_entry {
     cnum: int,
     span: span,
@@ -76,22 +77,13 @@ fn dump_crates(crate_cache: &[cache_entry]) {
 fn warn_if_multiple_versions(e: @mut Env,
                              diag: @mut span_handler,
                              crate_cache: &[cache_entry]) {
-    use std::either::*;
-
     if crate_cache.len() != 0u {
         let name = loader::crate_name_from_metas(
             *crate_cache[crate_cache.len() - 1].metas
         );
 
-        let vec: ~[Either<cache_entry, cache_entry>] = crate_cache.iter().map(|&entry| {
-            let othername = loader::crate_name_from_metas(*entry.metas);
-            if name == othername {
-                Left(entry)
-            } else {
-                Right(entry)
-            }
-        }).collect();
-        let (matches, non_matches) = partition(vec);
+        let (matches, non_matches) = crate_cache.partitioned(|entry|
+            name == loader::crate_name_from_metas(*entry.metas));
 
         assert!(!matches.is_empty());
 
index 554cdf4b2b4feb13a9055357ec18cd10316e375f..d0060931a6607eca54c753346ff492fbf8146d20 100644 (file)
@@ -199,7 +199,7 @@ pub fn metadata_matches(extern_metas: &[@ast::MetaItem],
 fn get_metadata_section(os: os,
                         filename: &Path) -> Option<@~[u8]> {
     unsafe {
-        let mb = do filename.to_c_str().with_ref |buf| {
+        let mb = do filename.with_c_str |buf| {
             llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf)
         };
         if mb as int == 0 { return option::None::<@~[u8]>; }
index d6342c582f0525dc21e9cbd5f5d30eb4b3218bf3..bca1a811a13727d17b14b3386a41a298a84a038d 100644 (file)
@@ -1288,24 +1288,24 @@ fn roundtrip(in_item: Option<@ast::item>) {
 
 #[test]
 fn test_basic() {
-    let ext_cx = mk_ctxt();
-    roundtrip(quote_item!(
+    let cx = mk_ctxt();
+    roundtrip(quote_item!(cx,
         fn foo() {}
     ));
 }
 
 #[test]
 fn test_smalltalk() {
-    let ext_cx = mk_ctxt();
-    roundtrip(quote_item!(
+    let cx = mk_ctxt();
+    roundtrip(quote_item!(cx,
         fn foo() -> int { 3 + 4 } // first smalltalk program ever executed.
     ));
 }
 
 #[test]
 fn test_more() {
-    let ext_cx = mk_ctxt();
-    roundtrip(quote_item!(
+    let cx = mk_ctxt();
+    roundtrip(quote_item!(cx,
         fn foo(x: uint, y: uint) -> uint {
             let z = x + y;
             return z;
@@ -1315,15 +1315,15 @@ fn foo(x: uint, y: uint) -> uint {
 
 #[test]
 fn test_simplification() {
-    let ext_cx = mk_ctxt();
-    let item_in = ast::ii_item(quote_item!(
+    let cx = mk_ctxt();
+    let item_in = ast::ii_item(quote_item!(cx,
         fn new_int_alist<B>() -> alist<int, B> {
             fn eq_int(a: int, b: int) -> bool { a == b }
             return alist {eq_fn: eq_int, data: ~[]};
         }
     ).unwrap());
     let item_out = simplify_ast(&item_in);
-    let item_exp = ast::ii_item(quote_item!(
+    let item_exp = ast::ii_item(quote_item!(cx,
         fn new_int_alist<B>() -> alist<int, B> {
             return alist {eq_fn: eq_int, data: ~[]};
         }
index b772ca7e9bbf5709188174a4cad1e48b535f1bc4..0530ffd30b4f0841f663f74faab5a4977560e626 100644 (file)
@@ -184,6 +184,7 @@ pub fn check_expr(v: &mut CheckCrateVisitor,
           expr_field(*) |
           expr_index(*) |
           expr_tup(*) |
+          expr_repeat(*) |
           expr_struct(*) => { }
           expr_addr_of(*) => {
                 sess.span_err(
index f3d7565da26263f0806abb2d5b9e997e29e7fd79..3f321fcfcd28f8d5bd4534589894a7df3f5c9672 100644 (file)
@@ -895,7 +895,9 @@ pub fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
 
     let check_move: &fn(@pat, Option<@pat>) = |p, sub| {
         // check legality of moving out of the enum
-        if sub.is_some() {
+
+        // x @ Foo(*) is legal, but x @ Foo(y) isn't.
+        if sub.map_move_default(false, |p| pat_contains_bindings(def_map, p)) {
             tcx.sess.span_err(
                 p.span,
                 "cannot bind by-move with sub-bindings");
index b4096298a3e330a53d034c67d7b28bf7be8862ed..2e8d0d351d997c8b48e07b042dbe07e9c32cf120 100644 (file)
@@ -155,6 +155,8 @@ pub fn classify(e: &expr,
                 lookup_constness(tcx, e)
               }
 
+              ast::expr_repeat(*) => general_const,
+
               _ => non_const
             };
         tcx.ccache.insert(did, cn);
index 18af303f239a3fce42f6b65d1a0c51e27a9255cf..9b11301a9c494256c644730a9d4f049783d77b6e 100644 (file)
@@ -58,28 +58,27 @@ pub enum LangItem {
 
     StrEqFnLangItem,                   // 19
     UniqStrEqFnLangItem,               // 20
-    AnnihilateFnLangItem,              // 21
-    LogTypeFnLangItem,                 // 22
-    FailFnLangItem,                    // 23
-    FailBoundsCheckFnLangItem,         // 24
-    ExchangeMallocFnLangItem,          // 25
-    ClosureExchangeMallocFnLangItem,   // 26
-    ExchangeFreeFnLangItem,            // 27
-    MallocFnLangItem,                  // 28
-    FreeFnLangItem,                    // 29
-    BorrowAsImmFnLangItem,             // 30
-    BorrowAsMutFnLangItem,             // 31
-    ReturnToMutFnLangItem,             // 32
-    CheckNotBorrowedFnLangItem,        // 33
-    StrDupUniqFnLangItem,              // 34
-    RecordBorrowFnLangItem,            // 35
-    UnrecordBorrowFnLangItem,          // 36
-
-    StartFnLangItem,                   // 37
-
-    TyDescStructLangItem,              // 38
-    TyVisitorTraitLangItem,            // 39
-    OpaqueStructLangItem,              // 40
+    LogTypeFnLangItem,                 // 21
+    FailFnLangItem,                    // 22
+    FailBoundsCheckFnLangItem,         // 23
+    ExchangeMallocFnLangItem,          // 24
+    ClosureExchangeMallocFnLangItem,   // 25
+    ExchangeFreeFnLangItem,            // 26
+    MallocFnLangItem,                  // 27
+    FreeFnLangItem,                    // 28
+    BorrowAsImmFnLangItem,             // 29
+    BorrowAsMutFnLangItem,             // 30
+    ReturnToMutFnLangItem,             // 31
+    CheckNotBorrowedFnLangItem,        // 32
+    StrDupUniqFnLangItem,              // 33
+    RecordBorrowFnLangItem,            // 34
+    UnrecordBorrowFnLangItem,          // 35
+
+    StartFnLangItem,                   // 36
+
+    TyDescStructLangItem,              // 37
+    TyVisitorTraitLangItem,            // 38
+    OpaqueStructLangItem,              // 39
 }
 
 pub struct LanguageItems {
@@ -123,28 +122,27 @@ pub fn item_name(index: uint) -> &'static str {
 
             19 => "str_eq",
             20 => "uniq_str_eq",
-            21 => "annihilate",
-            22 => "log_type",
-            23 => "fail_",
-            24 => "fail_bounds_check",
-            25 => "exchange_malloc",
-            26 => "closure_exchange_malloc",
-            27 => "exchange_free",
-            28 => "malloc",
-            29 => "free",
-            30 => "borrow_as_imm",
-            31 => "borrow_as_mut",
-            32 => "return_to_mut",
-            33 => "check_not_borrowed",
-            34 => "strdup_uniq",
-            35 => "record_borrow",
-            36 => "unrecord_borrow",
-
-            37 => "start",
-
-            38 => "ty_desc",
-            39 => "ty_visitor",
-            40 => "opaque",
+            21 => "log_type",
+            22 => "fail_",
+            23 => "fail_bounds_check",
+            24 => "exchange_malloc",
+            25 => "closure_exchange_malloc",
+            26 => "exchange_free",
+            27 => "malloc",
+            28 => "free",
+            29 => "borrow_as_imm",
+            30 => "borrow_as_mut",
+            31 => "return_to_mut",
+            32 => "check_not_borrowed",
+            33 => "strdup_uniq",
+            34 => "record_borrow",
+            35 => "unrecord_borrow",
+
+            36 => "start",
+
+            37 => "ty_desc",
+            38 => "ty_visitor",
+            39 => "opaque",
 
             _ => "???"
         }
@@ -227,9 +225,6 @@ pub fn str_eq_fn(&self) -> Option<def_id> {
     pub fn uniq_str_eq_fn(&self) -> Option<def_id> {
         self.items[UniqStrEqFnLangItem as uint]
     }
-    pub fn annihilate_fn(&self) -> Option<def_id> {
-        self.items[AnnihilateFnLangItem as uint]
-    }
     pub fn log_type_fn(&self) -> Option<def_id> {
         self.items[LogTypeFnLangItem as uint]
     }
@@ -349,7 +344,6 @@ pub fn new<'a>(crate: &'a Crate, session: Session)
 
         item_refs.insert(@"str_eq", StrEqFnLangItem as uint);
         item_refs.insert(@"uniq_str_eq", UniqStrEqFnLangItem as uint);
-        item_refs.insert(@"annihilate", AnnihilateFnLangItem as uint);
         item_refs.insert(@"log_type", LogTypeFnLangItem as uint);
         item_refs.insert(@"fail_", FailFnLangItem as uint);
         item_refs.insert(@"fail_bounds_check",
index 55425b647953098d70b2492bd60d3bc90dde8ba1..880095db2ee1de151d90f41d4bde0efa81aa24e2 100644 (file)
@@ -73,6 +73,7 @@
 #[deriving(Clone, Eq)]
 pub enum lint {
     ctypes,
+    cstack,
     unused_imports,
     unnecessary_qualification,
     while_true,
@@ -146,6 +147,13 @@ enum LintSource {
         default: warn
      }),
 
+    ("cstack",
+     LintSpec {
+        lint: cstack,
+        desc: "only invoke foreign functions from fixedstacksegment fns",
+        default: deny
+     }),
+
     ("unused_imports",
      LintSpec {
         lint: unused_imports,
@@ -480,7 +488,7 @@ fn process(@mut self, n: AttributedNode) {
                             (orig.visit_item)(it, (self, stopping));
                         }
                         NewVisitor(new_visitor) => {
-                            let mut new_visitor = new_visitor;
+                            let new_visitor = new_visitor;
                             new_visitor.visit_item(it, ());
                         }
                     }
@@ -520,7 +528,7 @@ fn process(@mut self, n: AttributedNode) {
                             let fk = visit::fk_method(m.ident,
                                                       &m.generics,
                                                       m);
-                            let mut new_visitor = new_visitor;
+                            let new_visitor = new_visitor;
                             new_visitor.visit_fn(&fk,
                                                  &m.decl,
                                                  &m.body,
index 9bf14697d9ad764b9b9c1d245ed3b98114652eda..a67a488ef30fce2147a9593ba3bda8bd1ffe875c 100644 (file)
@@ -88,3 +88,18 @@ pub fn pat_binding_ids(dm: resolve::DefMap, pat: @pat) -> ~[NodeId] {
     pat_bindings(dm, pat, |_bm, b_id, _sp, _pt| found.push(b_id) );
     return found;
 }
+
+/// Checks if the pattern contains any patterns that bind something to
+/// an ident, e.g. `foo`, or `Foo(foo)` or `foo @ Bar(*)`.
+pub fn pat_contains_bindings(dm: resolve::DefMap, pat: @pat) -> bool {
+    let mut contains_bindings = false;
+    do walk_pat(pat) |p| {
+        if pat_is_binding(dm, p) {
+            contains_bindings = true;
+            false // there's at least one binding, can short circuit now.
+        } else {
+            true
+        }
+    };
+    contains_bindings
+}
diff --git a/src/librustc/middle/stack_check.rs b/src/librustc/middle/stack_check.rs
new file mode 100644 (file)
index 0000000..8837a94
--- /dev/null
@@ -0,0 +1,159 @@
+// 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.
+
+/*!
+
+Lint mode to detect cases where we call non-Rust fns, which do not
+have a stack growth check, from locations not annotated to request
+large stacks.
+
+*/
+
+use middle::lint;
+use middle::ty;
+use syntax::ast;
+use syntax::ast_map;
+use syntax::attr;
+use syntax::codemap::span;
+use visit = syntax::oldvisit;
+use util::ppaux::Repr;
+
+#[deriving(Clone)]
+struct Context {
+    tcx: ty::ctxt,
+    safe_stack: bool
+}
+
+pub fn stack_check_crate(tcx: ty::ctxt,
+                         crate: &ast::Crate) {
+    let new_cx = Context {
+        tcx: tcx,
+        safe_stack: false
+    };
+    let visitor = visit::mk_vt(@visit::Visitor {
+        visit_item: stack_check_item,
+        visit_fn: stack_check_fn,
+        visit_expr: stack_check_expr,
+        ..*visit::default_visitor()
+    });
+    visit::visit_crate(crate, (new_cx, visitor));
+}
+
+fn stack_check_item(item: @ast::item,
+                    (in_cx, v): (Context, visit::vt<Context>)) {
+    match item.node {
+        ast::item_fn(_, ast::extern_fn, _, _, _) => {
+            // an extern fn is already being called from C code...
+            let new_cx = Context {safe_stack: true, ..in_cx};
+            visit::visit_item(item, (new_cx, v));
+        }
+        ast::item_fn(*) => {
+            let safe_stack = fixed_stack_segment(item.attrs);
+            let new_cx = Context {safe_stack: safe_stack, ..in_cx};
+            visit::visit_item(item, (new_cx, v));
+        }
+        ast::item_impl(_, _, _, ref methods) => {
+            // visit_method() would make this nicer
+            for &method in methods.iter() {
+                let safe_stack = fixed_stack_segment(method.attrs);
+                let new_cx = Context {safe_stack: safe_stack, ..in_cx};
+                visit::visit_method_helper(method, (new_cx, v));
+            }
+        }
+        _ => {
+            visit::visit_item(item, (in_cx, v));
+        }
+    }
+
+    fn fixed_stack_segment(attrs: &[ast::Attribute]) -> bool {
+        attr::contains_name(attrs, "fixed_stack_segment")
+    }
+}
+
+fn stack_check_fn<'a>(fk: &visit::fn_kind,
+                      decl: &ast::fn_decl,
+                      body: &ast::Block,
+                      sp: span,
+                      id: ast::NodeId,
+                      (in_cx, v): (Context, visit::vt<Context>)) {
+    let safe_stack = match *fk {
+        visit::fk_method(*) | visit::fk_item_fn(*) => {
+            in_cx.safe_stack // see stack_check_item above
+        }
+        visit::fk_anon(*) | visit::fk_fn_block => {
+            match ty::get(ty::node_id_to_type(in_cx.tcx, id)).sty {
+                ty::ty_bare_fn(*) |
+                ty::ty_closure(ty::ClosureTy {sigil: ast::OwnedSigil, _}) |
+                ty::ty_closure(ty::ClosureTy {sigil: ast::ManagedSigil, _}) => {
+                    false
+                }
+                _ => {
+                    in_cx.safe_stack
+                }
+            }
+        }
+    };
+    let new_cx = Context {safe_stack: safe_stack, ..in_cx};
+    debug!("stack_check_fn(safe_stack=%b, id=%?)", safe_stack, id);
+    visit::visit_fn(fk, decl, body, sp, id, (new_cx, v));
+}
+
+fn stack_check_expr<'a>(expr: @ast::expr,
+                        (cx, v): (Context, visit::vt<Context>)) {
+    debug!("stack_check_expr(safe_stack=%b, expr=%s)",
+           cx.safe_stack, expr.repr(cx.tcx));
+    if !cx.safe_stack {
+        match expr.node {
+            ast::expr_call(callee, _, _) => {
+                let callee_ty = ty::expr_ty(cx.tcx, callee);
+                debug!("callee_ty=%s", callee_ty.repr(cx.tcx));
+                match ty::get(callee_ty).sty {
+                    ty::ty_bare_fn(ref fty) => {
+                        if !fty.abis.is_rust() && !fty.abis.is_intrinsic() {
+                            call_to_extern_fn(cx, callee);
+                        }
+                    }
+                    _ => {}
+                }
+            }
+            _ => {}
+        }
+    }
+    visit::visit_expr(expr, (cx, v));
+}
+
+fn call_to_extern_fn(cx: Context, callee: @ast::expr) {
+    // Permit direct calls to extern fns that are annotated with
+    // #[rust_stack]. This is naturally a horrible pain to achieve.
+    match callee.node {
+        ast::expr_path(*) => {
+            match cx.tcx.def_map.find(&callee.id) {
+                Some(&ast::def_fn(id, _)) if id.crate == ast::LOCAL_CRATE => {
+                    match cx.tcx.items.find(&id.node) {
+                        Some(&ast_map::node_foreign_item(item, _, _, _)) => {
+                            if attr::contains_name(item.attrs, "rust_stack") {
+                                return;
+                            }
+                        }
+                        _ => {}
+                    }
+                }
+                _ => {}
+            }
+        }
+        _ => {}
+    }
+
+    cx.tcx.sess.add_lint(lint::cstack,
+                         callee.id,
+                         callee.span,
+                         fmt!("invoking non-Rust fn in fn without \
+                              #[fixed_stack_segment]"));
+}
index bb1e3fa1718dc3d83854420507bb31eab6c414e9..1eeafeacc6f05a75b395d59360ec0c572d0e94c4 100644 (file)
@@ -399,10 +399,17 @@ struct ArmData<'self> {
     bindings_map: @BindingsMap
 }
 
+/**
+ * Info about Match.
+ * If all `pats` are matched then arm `data` will be executed.
+ * As we proceed `bound_ptrs` are filled with pointers to values to be bound,
+ * these pointers are stored in llmatch variables just before executing `data` arm.
+ */
 #[deriving(Clone)]
 struct Match<'self> {
     pats: ~[@ast::pat],
-    data: ArmData<'self>
+    data: ArmData<'self>,
+    bound_ptrs: ~[(ident, ValueRef)]
 }
 
 impl<'self> Repr for Match<'self> {
@@ -447,14 +454,13 @@ fn expand_nested_bindings<'r>(bcx: @mut Block,
                                 br.pats.slice(col + 1u,
                                            br.pats.len())));
 
-                let binding_info =
-                    br.data.bindings_map.get(&path_to_ident(path));
-
-                Store(bcx, val, binding_info.llmatch);
-                Match {
+                let mut res = Match {
                     pats: pats,
-                    data: br.data.clone()
-                }
+                    data: br.data.clone(),
+                    bound_ptrs: br.bound_ptrs.clone()
+                };
+                res.bound_ptrs.push((path_to_ident(path), val));
+                res
             }
             _ => (*br).clone(),
         }
@@ -496,13 +502,11 @@ fn enter_match<'r>(bcx: @mut Block,
                         br.pats.slice(col + 1u, br.pats.len()));
 
                 let this = br.pats[col];
+                let mut bound_ptrs = br.bound_ptrs.clone();
                 match this.node {
                     ast::pat_ident(_, ref path, None) => {
                         if pat_is_binding(dm, this) {
-                            let binding_info =
-                                br.data.bindings_map.get(
-                                    &path_to_ident(path));
-                            Store(bcx, val, binding_info.llmatch);
+                            bound_ptrs.push((path_to_ident(path), val));
                         }
                     }
                     _ => {}
@@ -510,7 +514,8 @@ fn enter_match<'r>(bcx: @mut Block,
 
                 result.push(Match {
                     pats: pats,
-                    data: br.data.clone()
+                    data: br.data.clone(),
+                    bound_ptrs: bound_ptrs
                 });
             }
             None => ()
@@ -1294,7 +1299,6 @@ fn store_non_ref_bindings(bcx: @mut Block,
 
 fn insert_lllocals(bcx: @mut Block,
                    bindings_map: &BindingsMap,
-                   binding_mode: IrrefutablePatternBindingMode,
                    add_cleans: bool) -> @mut Block {
     /*!
      * For each binding in `data.bindings_map`, adds an appropriate entry into
@@ -1302,10 +1306,7 @@ fn insert_lllocals(bcx: @mut Block,
      * the bindings.
      */
 
-    let llmap = match binding_mode {
-        BindLocal => bcx.fcx.lllocals,
-        BindArgument => bcx.fcx.llargs
-    };
+    let llmap = bcx.fcx.lllocals;
 
     for (&ident, &binding_info) in bindings_map.iter() {
         let llval = match binding_info.trmode {
@@ -1358,7 +1359,7 @@ fn compile_guard(bcx: @mut Block,
     bcx = store_non_ref_bindings(bcx,
                                  data.bindings_map,
                                  Some(&mut temp_cleanups));
-    bcx = insert_lllocals(bcx, data.bindings_map, BindLocal, false);
+    bcx = insert_lllocals(bcx, data.bindings_map, false);
 
     let val = unpack_result!(bcx, {
         do with_scope_result(bcx, guard_expr.info(),
@@ -1418,6 +1419,10 @@ fn compile_submatch(bcx: @mut Block,
     }
     if m[0].pats.len() == 0u {
         let data = &m[0].data;
+        for &(ref ident, ref value_ptr) in m[0].bound_ptrs.iter() {
+            let llmatch = data.bindings_map.get(ident).llmatch;
+            Store(bcx, *value_ptr, llmatch);
+        }
         match data.arm.guard {
             Some(guard_expr) => {
                 bcx = compile_guard(bcx,
@@ -1843,6 +1848,7 @@ fn trans_match_inner(scope_cx: @mut Block,
             matches.push(Match {
                 pats: ~[*p],
                 data: arm_data.clone(),
+                bound_ptrs: ~[],
             });
         }
     }
@@ -1875,7 +1881,7 @@ fn trans_match_inner(scope_cx: @mut Block,
         }
 
         // insert bindings into the lllocals map and add cleanups
-        bcx = insert_lllocals(bcx, arm_data.bindings_map, BindLocal, true);
+        bcx = insert_lllocals(bcx, arm_data.bindings_map, true);
 
         bcx = controlflow::trans_block(bcx, &arm_data.arm.body, dest);
         bcx = trans_block_cleanups(bcx, block_cleanups(arm_data.bodycx));
index b6057199a280fbccddba02aefe60d7b20f42c5f7..3400da75b9e5e880d237ea3192ce50b7b6659e8c 100644 (file)
@@ -120,8 +120,8 @@ pub fn trans_inline_asm(bcx: @mut Block, ia: &ast::inline_asm) -> @mut Block {
         ast::asm_intel => lib::llvm::AD_Intel
     };
 
-    let r = do ia.asm.to_c_str().with_ref |a| {
-        do constraints.to_c_str().with_ref |c| {
+    let r = do ia.asm.with_c_str |a| {
+        do constraints.with_c_str |c| {
             InlineAsmCall(bcx, a, c, inputs, output, ia.volatile, ia.alignstack, dialect)
         }
     };
index 18634b1242ac6d7f44239e202145ff59fd82d514..f4d52c3aa31e014ef46b634c7337c8cf2818d70c 100644 (file)
@@ -133,7 +133,7 @@ pub fn push_ctxt(s: &'static str) -> _InsnCtxt {
 
 fn fcx_has_nonzero_span(fcx: &FunctionContext) -> bool {
     match fcx.span {
-        None => true,
+        None => false,
         Some(span) => *span.lo != 0 || *span.hi != 0
     }
 }
@@ -181,7 +181,7 @@ fn drop(&self) {
 }
 
 pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, ty: Type) -> ValueRef {
-    let llfn: ValueRef = do name.to_c_str().with_ref |buf| {
+    let llfn: ValueRef = do name.with_c_str |buf| {
         unsafe {
             llvm::LLVMGetOrInsertFunction(llmod, buf, ty.to_ref())
         }
@@ -203,28 +203,28 @@ pub fn decl_internal_cdecl_fn(llmod: ModuleRef, name: &str, ty: Type) -> ValueRe
     return llfn;
 }
 
-pub fn get_extern_fn(externs: &mut ExternMap, llmod: ModuleRef, name: @str,
+pub fn get_extern_fn(externs: &mut ExternMap, llmod: ModuleRef, name: &str,
                      cc: lib::llvm::CallConv, ty: Type) -> ValueRef {
-    match externs.find_copy(&name) {
-        Some(n) => return n,
+    match externs.find_equiv(&name) {
+        Some(n) => return *n,
         None => ()
     }
     let f = decl_fn(llmod, name, cc, ty);
-    externs.insert(name, f);
+    externs.insert(name.to_owned(), f);
     return f;
 }
 
 pub fn get_extern_const(externs: &mut ExternMap, llmod: ModuleRef,
-                        name: @str, ty: Type) -> ValueRef {
-    match externs.find_copy(&name) {
-        Some(n) => return n,
+                        name: &str, ty: Type) -> ValueRef {
+    match externs.find_equiv(&name) {
+        Some(n) => return *n,
         None => ()
     }
     unsafe {
-        let c = do name.to_c_str().with_ref |buf| {
+        let c = do name.with_c_str |buf| {
             llvm::LLVMAddGlobal(llmod, ty.to_ref(), buf)
         };
-        externs.insert(name, c);
+        externs.insert(name.to_owned(), c);
         return c;
     }
 }
@@ -511,7 +511,6 @@ pub fn get_res_dtor(ccx: @mut CrateContext,
                                      None,
                                      ty::lookup_item_type(tcx, parent_id).ty);
         let llty = type_of_dtor(ccx, class_ty);
-        let name = name.to_managed(); // :-(
         get_extern_fn(&mut ccx.externs,
                       ccx.llmod,
                       name,
@@ -523,7 +522,7 @@ pub fn get_res_dtor(ccx: @mut CrateContext,
 // Structural comparison: a rather involved form of glue.
 pub fn maybe_name_value(cx: &CrateContext, v: ValueRef, s: &str) {
     if cx.sess.opts.save_temps {
-        do s.to_c_str().with_ref |buf| {
+        do s.with_c_str |buf| {
             unsafe {
                 llvm::LLVMSetValueName(v, buf)
             }
@@ -798,13 +797,13 @@ pub fn fail_if_zero(cx: @mut Block, span: span, divrem: ast::binop,
     }
 }
 
-pub fn null_env_ptr(bcx: @mut Block) -> ValueRef {
-    C_null(Type::opaque_box(bcx.ccx()).ptr_to())
+pub fn null_env_ptr(ccx: &CrateContext) -> ValueRef {
+    C_null(Type::opaque_box(ccx).ptr_to())
 }
 
 pub fn trans_external_path(ccx: &mut CrateContext, did: ast::def_id, t: ty::t)
     -> ValueRef {
-    let name = csearch::get_symbol(ccx.sess.cstore, did).to_managed(); // Sad
+    let name = csearch::get_symbol(ccx.sess.cstore, did);
     match ty::get(t).sty {
       ty::ty_bare_fn(_) | ty::ty_closure(_) => {
         let llty = type_of_fn_from_ty(ccx, t);
@@ -1136,7 +1135,7 @@ pub fn new_block(cx: @mut FunctionContext,
                  opt_node_info: Option<NodeInfo>)
               -> @mut Block {
     unsafe {
-        let llbb = do name.to_c_str().with_ref |buf| {
+        let llbb = do name.with_c_str |buf| {
             llvm::LLVMAppendBasicBlockInContext(cx.ccx.llcx, cx.llfn, buf)
         };
         let bcx = @mut Block::new(llbb,
@@ -1553,7 +1552,7 @@ pub struct BasicBlocks {
 pub fn mk_staticallocas_basic_block(llfn: ValueRef) -> BasicBlockRef {
     unsafe {
         let cx = task_llcx();
-        do "static_allocas".to_c_str().with_ref | buf| {
+        do "static_allocas".with_c_str | buf| {
             llvm::LLVMAppendBasicBlockInContext(cx, llfn, buf)
         }
     }
@@ -1562,7 +1561,7 @@ pub fn mk_staticallocas_basic_block(llfn: ValueRef) -> BasicBlockRef {
 pub fn mk_return_basic_block(llfn: ValueRef) -> BasicBlockRef {
     unsafe {
         let cx = task_llcx();
-        do "return".to_c_str().with_ref |buf| {
+        do "return".with_c_str |buf| {
             llvm::LLVMAppendBasicBlockInContext(cx, llfn, buf)
         }
     }
@@ -1572,7 +1571,7 @@ pub fn mk_return_basic_block(llfn: ValueRef) -> BasicBlockRef {
 // slot where the return value of the function must go.
 pub fn make_return_pointer(fcx: @mut FunctionContext, output_type: ty::t) -> ValueRef {
     unsafe {
-        if !ty::type_is_immediate(fcx.ccx.tcx, output_type) {
+        if type_of::return_uses_outptr(fcx.ccx.tcx, output_type) {
             llvm::LLVMGetParam(fcx.llfn, 0)
         } else {
             let lloutputtype = type_of::type_of(fcx.ccx, output_type);
@@ -1612,7 +1611,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
             ty::subst_tps(ccx.tcx, substs.tys, substs.self_ty, output_type)
         }
     };
-    let is_immediate = ty::type_is_immediate(ccx.tcx, substd_output_type);
+    let uses_outptr = type_of::return_uses_outptr(ccx.tcx, substd_output_type);
     let fcx = @mut FunctionContext {
           llfn: llfndecl,
           llenv: unsafe {
@@ -1624,7 +1623,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
           llreturn: None,
           llself: None,
           personality: None,
-          has_immediate_return_value: is_immediate,
+          caller_expects_out_pointer: uses_outptr,
           llargs: @mut HashMap::new(),
           lllocals: @mut HashMap::new(),
           llupvars: @mut HashMap::new(),
@@ -1647,8 +1646,15 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
         fcx.alloca_insert_pt = Some(llvm::LLVMGetFirstInstruction(entry_bcx.llbb));
     }
 
-    if !ty::type_is_nil(substd_output_type) && !(is_immediate && skip_retptr) {
-        fcx.llretptr = Some(make_return_pointer(fcx, substd_output_type));
+    if !ty::type_is_voidish(substd_output_type) {
+        // If the function returns nil/bot, there is no real return
+        // value, so do not set `llretptr`.
+        if !skip_retptr || uses_outptr {
+            // Otherwise, we normally allocate the llretptr, unless we
+            // have been instructed to skip it for immediate return
+            // values.
+            fcx.llretptr = Some(make_return_pointer(fcx, substd_output_type));
+        }
     }
     fcx
 }
@@ -1739,6 +1745,10 @@ pub fn copy_args_to_allocas(fcx: @mut FunctionContext,
 
             fcx.llself = Some(ValSelfData {v: self_val, ..slf});
             add_clean(bcx, self_val, slf.t);
+
+            if fcx.ccx.sess.opts.extra_debuginfo && fcx_has_nonzero_span(fcx) {
+                debuginfo::create_self_argument_metadata(bcx, slf.t, self_val);
+            }
         }
         _ => {}
     }
@@ -1792,7 +1802,7 @@ pub fn finish_fn(fcx: @mut FunctionContext, last_bcx: @mut Block) {
 // Builds the return block for a function.
 pub fn build_return_block(fcx: &FunctionContext, ret_cx: @mut Block) {
     // Return the value if this function immediate; otherwise, return void.
-    if fcx.llretptr.is_none() || !fcx.has_immediate_return_value {
+    if fcx.llretptr.is_none() || fcx.caller_expects_out_pointer {
         return RetVoid(ret_cx);
     }
 
@@ -1859,6 +1869,10 @@ pub fn trans_closure(ccx: @mut CrateContext,
         set_fixed_stack_segment(fcx.llfn);
     }
 
+    if ccx.sess.opts.debuginfo && fcx_has_nonzero_span(fcx) {
+        debuginfo::create_function_metadata(fcx);
+    }
+
     // Create the first basic block in the function and keep a handle on it to
     //  pass to finish_fn later.
     let bcx_top = fcx.entry_bcx.unwrap();
@@ -1874,9 +1888,7 @@ pub fn trans_closure(ccx: @mut CrateContext,
     // translation calls that don't have a return value (trans_crate,
     // trans_mod, trans_item, et cetera) and those that do
     // (trans_block, trans_expr, et cetera).
-    if body.expr.is_none() || ty::type_is_bot(block_ty) ||
-        ty::type_is_nil(block_ty)
-    {
+    if body.expr.is_none() || ty::type_is_voidish(block_ty) {
         bcx = controlflow::trans_block(bcx, body, expr::Ignore);
     } else {
         let dest = expr::SaveIn(fcx.llretptr.unwrap());
@@ -1929,12 +1941,7 @@ pub fn trans_fn(ccx: @mut CrateContext,
                   id,
                   attrs,
                   output_type,
-                  |fcx| {
-                      if ccx.sess.opts.debuginfo
-                          && fcx_has_nonzero_span(fcx) {
-                          debuginfo::create_function_metadata(fcx);
-                      }
-                  });
+                  |_fcx| { });
 }
 
 fn insert_synthetic_type_entries(bcx: @mut Block,
@@ -2126,13 +2133,14 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) {
       ast::item_fn(ref decl, purity, _abis, ref generics, ref body) => {
         if purity == ast::extern_fn  {
             let llfndecl = get_item_val(ccx, item.id);
-            foreign::trans_foreign_fn(ccx,
-                                      vec::append((*path).clone(),
-                                                  [path_name(item.ident)]),
-                                      decl,
-                                      body,
-                                      llfndecl,
-                                      item.id);
+            foreign::trans_rust_fn_with_foreign_abi(
+                ccx,
+                &vec::append((*path).clone(),
+                             [path_name(item.ident)]),
+                decl,
+                body,
+                llfndecl,
+                item.id);
         } else if !generics.is_type_parameterized() {
             let llfndecl = get_item_val(ccx, item.id);
             trans_fn(ccx,
@@ -2193,7 +2201,7 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) {
           }
       },
       ast::item_foreign_mod(ref foreign_mod) => {
-        foreign::trans_foreign_mod(ccx, path, foreign_mod);
+        foreign::trans_foreign_mod(ccx, foreign_mod);
       }
       ast::item_struct(struct_def, ref generics) => {
         if !generics.is_type_parameterized() {
@@ -2288,8 +2296,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
 
     fn create_main(ccx: @mut CrateContext, main_llfn: ValueRef) -> ValueRef {
         let nt = ty::mk_nil();
-
-        let llfty = type_of_fn(ccx, [], nt);
+        let llfty = type_of_rust_fn(ccx, [], nt);
         let llfdecl = decl_fn(ccx.llmod, "_rust_main",
                               lib::llvm::CCallConv, llfty);
 
@@ -2297,7 +2304,7 @@ fn create_main(ccx: @mut CrateContext, main_llfn: ValueRef) -> ValueRef {
 
         // the args vector built in create_entry_fn will need
         // be updated if this assertion starts to fail.
-        assert!(fcx.has_immediate_return_value);
+        assert!(!fcx.caller_expects_out_pointer);
 
         let bcx = fcx.entry_bcx.unwrap();
         // Call main.
@@ -2328,7 +2335,7 @@ fn create_entry_fn(ccx: @mut CrateContext,
             };
             decl_cdecl_fn(ccx.llmod, main_name, llfty)
         };
-        let llbb = do "top".to_c_str().with_ref |buf| {
+        let llbb = do "top".with_c_str |buf| {
             unsafe {
                 llvm::LLVMAppendBasicBlockInContext(ccx.llcx, llfn, buf)
             }
@@ -2338,7 +2345,7 @@ fn create_entry_fn(ccx: @mut CrateContext,
             llvm::LLVMPositionBuilderAtEnd(bld, llbb);
 
             let crate_map = ccx.crate_map;
-            let opaque_crate_map = do "crate_map".to_c_str().with_ref |buf| {
+            let opaque_crate_map = do "crate_map".with_c_str |buf| {
                 llvm::LLVMBuildPointerCast(bld, crate_map, Type::i8p().to_ref(), buf)
             };
 
@@ -2356,7 +2363,7 @@ fn create_entry_fn(ccx: @mut CrateContext,
                 };
 
                 let args = {
-                    let opaque_rust_main = do "rust_main".to_c_str().with_ref |buf| {
+                    let opaque_rust_main = do "rust_main".with_c_str |buf| {
                         llvm::LLVMBuildPointerCast(bld, rust_main, Type::i8p().to_ref(), buf)
                     };
 
@@ -2438,7 +2445,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
 
                             unsafe {
                                 let llty = llvm::LLVMTypeOf(v);
-                                let g = do sym.to_c_str().with_ref |buf| {
+                                let g = do sym.with_c_str |buf| {
                                     llvm::LLVMAddGlobal(ccx.llmod, llty, buf)
                                 };
 
@@ -2460,7 +2467,10 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
                             let llfn = if purity != ast::extern_fn {
                                 register_fn(ccx, i.span, sym, i.id, ty)
                             } else {
-                                foreign::register_foreign_fn(ccx, i.span, sym, i.id)
+                                foreign::register_rust_fn_with_foreign_abi(ccx,
+                                                                           i.span,
+                                                                           sym,
+                                                                           i.id)
                             };
                             set_inline_hint_if_appr(i.attrs, llfn);
                             llfn
@@ -2471,7 +2481,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
 
                     match (attr::first_attr_value_str_by_name(i.attrs, "link_section")) {
                         Some(sect) => unsafe {
-                            do sect.to_c_str().with_ref |buf| {
+                            do sect.with_c_str |buf| {
                                 llvm::LLVMSetSection(v, buf);
                             }
                         },
@@ -2499,20 +2509,18 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
                     register_method(ccx, id, pth, m)
                 }
 
-                ast_map::node_foreign_item(ni, _, _, pth) => {
+                ast_map::node_foreign_item(ni, abis, _, pth) => {
                     let ty = ty::node_id_to_type(ccx.tcx, ni.id);
                     exprt = true;
 
                     match ni.node {
                         ast::foreign_item_fn(*) => {
                             let path = vec::append((*pth).clone(), [path_name(ni.ident)]);
-                            let sym = exported_name(ccx, path, ty, ni.attrs);
-
-                            register_fn(ccx, ni.span, sym, ni.id, ty)
+                            foreign::register_foreign_item_fn(ccx, abis, &path, ni)
                         }
                         ast::foreign_item_static(*) => {
                             let ident = token::ident_to_str(&ni.ident);
-                            let g = do ident.to_c_str().with_ref |buf| {
+                            let g = do ident.with_c_str |buf| {
                                 unsafe {
                                     let ty = type_of(ccx, ty);
                                     llvm::LLVMAddGlobal(ccx.llmod, ty.to_ref(), buf)
@@ -2619,7 +2627,7 @@ pub fn trans_constant(ccx: &mut CrateContext, it: @ast::item) {
             let s = mangle_exported_name(ccx, p, ty::mk_int()).to_managed();
             let disr_val = vi[i].disr_val;
             note_unique_llvm_symbol(ccx, s);
-            let discrim_gvar = do s.to_c_str().with_ref |buf| {
+            let discrim_gvar = do s.with_c_str |buf| {
                 unsafe {
                     llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf)
                 }
@@ -2819,7 +2827,7 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) {
     }
 
     let gc_metadata_name = ~"_gc_module_metadata_" + llmod_id;
-    let gc_metadata = do gc_metadata_name.to_c_str().with_ref |buf| {
+    let gc_metadata = do gc_metadata_name.with_c_str |buf| {
         unsafe {
             llvm::LLVMAddGlobal(ccx.llmod, Type::i32().to_ref(), buf)
         }
@@ -2834,7 +2842,7 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) {
 pub fn create_module_map(ccx: &mut CrateContext) -> ValueRef {
     let elttype = Type::struct_([ccx.int_type, ccx.int_type], false);
     let maptype = Type::array(&elttype, (ccx.module_data.len() + 1) as u64);
-    let map = do "_rust_mod_map".to_c_str().with_ref |buf| {
+    let map = do "_rust_mod_map".with_c_str |buf| {
         unsafe {
             llvm::LLVMAddGlobal(ccx.llmod, maptype.to_ref(), buf)
         }
@@ -2882,7 +2890,7 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
     let sym_name = ~"_rust_crate_map_" + mapname;
     let arrtype = Type::array(&int_type, n_subcrates as u64);
     let maptype = Type::struct_([Type::i32(), Type::i8p(), int_type, arrtype], false);
-    let map = do sym_name.to_c_str().with_ref |buf| {
+    let map = do sym_name.with_c_str |buf| {
         unsafe {
             llvm::LLVMAddGlobal(llmod, maptype.to_ref(), buf)
         }
@@ -2901,7 +2909,7 @@ pub fn fill_crate_map(ccx: @mut CrateContext, map: ValueRef) {
                       cdata.name,
                       cstore::get_crate_vers(cstore, i),
                       cstore::get_crate_hash(cstore, i));
-        let cr = do nm.to_c_str().with_ref |buf| {
+        let cr = do nm.with_c_str |buf| {
             unsafe {
                 llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf)
             }
@@ -2911,24 +2919,12 @@ pub fn fill_crate_map(ccx: @mut CrateContext, map: ValueRef) {
     }
     subcrates.push(C_int(ccx, 0));
 
-    let llannihilatefn = match ccx.tcx.lang_items.annihilate_fn() {
-        Some(annihilate_def_id) => {
-            if annihilate_def_id.crate == ast::LOCAL_CRATE {
-                get_item_val(ccx, annihilate_def_id.node)
-            } else {
-                let annihilate_fn_type = csearch::get_type(ccx.tcx,
-                                                           annihilate_def_id).ty;
-                trans_external_path(ccx, annihilate_def_id, annihilate_fn_type)
-            }
-        }
-        None => { C_null(Type::i8p()) }
-    };
-
     unsafe {
         let mod_map = create_module_map(ccx);
         llvm::LLVMSetInitializer(map, C_struct(
             [C_i32(1),
-             lib::llvm::llvm::LLVMConstPointerCast(llannihilatefn, Type::i8p().to_ref()),
+             // FIXME #8431 This used to be the annihilate function, now it's nothing
+             C_null(Type::i8p()),
              p2i(ccx, mod_map),
              C_array(ccx.int_type, subcrates)]));
     }
@@ -2964,21 +2960,21 @@ pub fn write_metadata(cx: &mut CrateContext, crate: &ast::Crate) {
     let encode_parms = crate_ctxt_to_encode_parms(cx, encode_inlined_item);
     let llmeta = C_bytes(encoder::encode_metadata(encode_parms, crate));
     let llconst = C_struct([llmeta]);
-    let mut llglobal = do "rust_metadata".to_c_str().with_ref |buf| {
+    let mut llglobal = do "rust_metadata".with_c_str |buf| {
         unsafe {
             llvm::LLVMAddGlobal(cx.llmod, val_ty(llconst).to_ref(), buf)
         }
     };
     unsafe {
         llvm::LLVMSetInitializer(llglobal, llconst);
-        do cx.sess.targ_cfg.target_strs.meta_sect_name.to_c_str().with_ref |buf| {
+        do cx.sess.targ_cfg.target_strs.meta_sect_name.with_c_str |buf| {
             llvm::LLVMSetSection(llglobal, buf)
         };
         lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage);
 
         let t_ptr_i8 = Type::i8p();
         llglobal = llvm::LLVMConstBitCast(llglobal, t_ptr_i8.to_ref());
-        let llvm_used = do "llvm.used".to_c_str().with_ref |buf| {
+        let llvm_used = do "llvm.used".with_c_str |buf| {
             llvm::LLVMAddGlobal(cx.llmod, Type::array(&t_ptr_i8, 1).to_ref(), buf)
         };
         lib::llvm::SetLinkage(llvm_used, lib::llvm::AppendingLinkage);
@@ -2992,7 +2988,7 @@ fn mk_global(ccx: &CrateContext,
              internal: bool)
           -> ValueRef {
     unsafe {
-        let llglobal = do name.to_c_str().with_ref |buf| {
+        let llglobal = do name.with_c_str |buf| {
             llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval).to_ref(), buf)
         };
         llvm::LLVMSetInitializer(llglobal, llval);
index 5c216b2e14346684620185f0213be2666003b9b0..cba7a2253952ff55989de9d882914dbfbd7d4510 100644 (file)
@@ -423,7 +423,7 @@ pub fn alloca(&self, ty: Type, name: &str) -> ValueRef {
             if name.is_empty() {
                 llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), noname())
             } else {
-                do name.to_c_str().with_ref |c| {
+                do name.with_c_str |c| {
                     llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), c)
                 }
             }
@@ -739,7 +739,7 @@ pub fn add_comment(&self, text: &str) {
             let sanitized = text.replace("$", "");
             let comment_text = fmt!("# %s", sanitized.replace("\n", "\n\t# "));
             self.count_insn("inlineasm");
-            let asm = do comment_text.to_c_str().with_ref |c| {
+            let asm = do comment_text.with_c_str |c| {
                 unsafe {
                     llvm::LLVMConstInlineAsm(Type::func([], &Type::void()).to_ref(),
                                              c, noname(), False, False)
@@ -895,7 +895,7 @@ pub fn trap(&self) {
             let BB: BasicBlockRef = llvm::LLVMGetInsertBlock(self.llbuilder);
             let FN: ValueRef = llvm::LLVMGetBasicBlockParent(BB);
             let M: ModuleRef = llvm::LLVMGetGlobalParent(FN);
-            let T: ValueRef = do "llvm.trap".to_c_str().with_ref |buf| {
+            let T: ValueRef = do "llvm.trap".with_c_str |buf| {
                 llvm::LLVMGetNamedFunction(M, buf)
             };
             assert!((T as int != 0));
index 6a1905c451f97e4d99f397cc3498e841d754244e..005483a075f8df31145a6fc14e80ba2794fb7e4a 100644 (file)
@@ -8,19 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use lib::llvm::{llvm, ValueRef, Attribute, Void};
-use middle::trans::base::*;
-use middle::trans::build::*;
-use middle::trans::common::*;
-
-use middle::trans::type_::Type;
-
-use std::libc::c_uint;
+use lib::llvm::Attribute;
 use std::option;
-
-pub trait ABIInfo {
-    fn compute_info(&self, atys: &[Type], rty: Type, ret_def: bool) -> FnType;
-}
+use middle::trans::context::CrateContext;
+use middle::trans::cabi_x86;
+use middle::trans::cabi_x86_64;
+use middle::trans::cabi_arm;
+use middle::trans::cabi_mips;
+use middle::trans::type_::Type;
+use syntax::abi::{X86, X86_64, Arm, Mips};
 
 #[deriving(Clone)]
 pub struct LLVMType {
@@ -28,149 +24,38 @@ pub struct LLVMType {
     ty: Type
 }
 
+/// Metadata describing how the arguments to a native function
+/// should be passed in order to respect the native ABI.
+///
+/// I will do my best to describe this structure, but these
+/// comments are reverse-engineered and may be inaccurate. -NDM
 pub struct FnType {
+    /// The LLVM types of each argument. If the cast flag is true,
+    /// then the argument should be cast, typically because the
+    /// official argument type will be an int and the rust type is i8
+    /// or something like that.
     arg_tys: ~[LLVMType],
-    ret_ty: LLVMType,
-    attrs: ~[option::Option<Attribute>],
-    sret: bool
-}
-
-impl FnType {
-    pub fn decl_fn(&self, decl: &fn(fnty: Type) -> ValueRef) -> ValueRef {
-        let atys = self.arg_tys.iter().map(|t| t.ty).collect::<~[Type]>();
-        let rty = self.ret_ty.ty;
-        let fnty = Type::func(atys, &rty);
-        let llfn = decl(fnty);
-
-        for (i, a) in self.attrs.iter().enumerate() {
-            match *a {
-                option::Some(attr) => {
-                    unsafe {
-                        let llarg = get_param(llfn, i);
-                        llvm::LLVMAddAttribute(llarg, attr as c_uint);
-                    }
-                }
-                _ => ()
-            }
-        }
-        return llfn;
-    }
 
-    pub fn build_shim_args(&self, bcx: @mut Block, arg_tys: &[Type], llargbundle: ValueRef)
-                           -> ~[ValueRef] {
-        let mut atys: &[LLVMType] = self.arg_tys;
-        let mut attrs: &[option::Option<Attribute>] = self.attrs;
-
-        let mut llargvals = ~[];
-        let mut i = 0u;
-        let n = arg_tys.len();
-
-        if self.sret {
-            let llretptr = GEPi(bcx, llargbundle, [0u, n]);
-            let llretloc = Load(bcx, llretptr);
-                llargvals = ~[llretloc];
-                atys = atys.tail();
-                attrs = attrs.tail();
-        }
-
-        while i < n {
-            let llargval = if atys[i].cast {
-                let arg_ptr = GEPi(bcx, llargbundle, [0u, i]);
-                let arg_ptr = BitCast(bcx, arg_ptr, atys[i].ty.ptr_to());
-                Load(bcx, arg_ptr)
-            } else if attrs[i].is_some() {
-                GEPi(bcx, llargbundle, [0u, i])
-            } else {
-                load_inbounds(bcx, llargbundle, [0u, i])
-            };
-            llargvals.push(llargval);
-            i += 1u;
-        }
-
-        return llargvals;
-    }
-
-    pub fn build_shim_ret(&self, bcx: @mut Block, arg_tys: &[Type], ret_def: bool,
-                          llargbundle: ValueRef, llretval: ValueRef) {
-        for (i, a) in self.attrs.iter().enumerate() {
-            match *a {
-                option::Some(attr) => {
-                    unsafe {
-                        llvm::LLVMAddInstrAttribute(llretval, (i + 1u) as c_uint, attr as c_uint);
-                    }
-                }
-                _ => ()
-            }
-        }
-        if self.sret || !ret_def {
-            return;
-        }
-        let n = arg_tys.len();
-        // R** llretptr = &args->r;
-        let llretptr = GEPi(bcx, llargbundle, [0u, n]);
-        // R* llretloc = *llretptr; /* (args->r) */
-        let llretloc = Load(bcx, llretptr);
-        if self.ret_ty.cast {
-            let tmp_ptr = BitCast(bcx, llretloc, self.ret_ty.ty.ptr_to());
-            // *args->r = r;
-            Store(bcx, llretval, tmp_ptr);
-        } else {
-            // *args->r = r;
-            Store(bcx, llretval, llretloc);
-        };
-    }
-
-    pub fn build_wrap_args(&self, bcx: @mut Block, ret_ty: Type,
-                           llwrapfn: ValueRef, llargbundle: ValueRef) {
-        let mut atys: &[LLVMType] = self.arg_tys;
-        let mut attrs: &[option::Option<Attribute>] = self.attrs;
-        let mut j = 0u;
-        let llretptr = if self.sret {
-            atys = atys.tail();
-            attrs = attrs.tail();
-            j = 1u;
-            get_param(llwrapfn, 0u)
-        } else if self.ret_ty.cast {
-            let retptr = alloca(bcx, self.ret_ty.ty, "");
-            BitCast(bcx, retptr, ret_ty.ptr_to())
-        } else {
-            alloca(bcx, ret_ty, "")
-        };
+    /// A list of attributes to be attached to each argument (parallel
+    /// the `arg_tys` array). If the attribute for a given is Some,
+    /// then the argument should be passed by reference.
+    attrs: ~[option::Option<Attribute>],
 
-        let mut i = 0u;
-        let n = atys.len();
-        while i < n {
-            let mut argval = get_param(llwrapfn, i + j);
-            if attrs[i].is_some() {
-                argval = Load(bcx, argval);
-                store_inbounds(bcx, argval, llargbundle, [0u, i]);
-            } else if atys[i].cast {
-                let argptr = GEPi(bcx, llargbundle, [0u, i]);
-                let argptr = BitCast(bcx, argptr, atys[i].ty.ptr_to());
-                Store(bcx, argval, argptr);
-            } else {
-                store_inbounds(bcx, argval, llargbundle, [0u, i]);
-            }
-            i += 1u;
-        }
-        store_inbounds(bcx, llretptr, llargbundle, [0u, n]);
-    }
+    /// LLVM return type.
+    ret_ty: LLVMType,
 
-    pub fn build_wrap_ret(&self, bcx: @mut Block, arg_tys: &[Type], llargbundle: ValueRef) {
-        if self.ret_ty.ty.kind() == Void {
-            return;
-        }
+    /// If true, then an implicit pointer should be added for the result.
+    sret: bool
+}
 
-        if bcx.fcx.llretptr.is_some() {
-            let llretval = load_inbounds(bcx, llargbundle, [ 0, arg_tys.len() ]);
-            let llretval = if self.ret_ty.cast {
-                let retptr = BitCast(bcx, llretval, self.ret_ty.ty.ptr_to());
-                Load(bcx, retptr)
-            } else {
-                Load(bcx, llretval)
-            };
-            let llretptr = BitCast(bcx, bcx.fcx.llretptr.unwrap(), self.ret_ty.ty.ptr_to());
-            Store(bcx, llretval, llretptr);
-        }
+pub fn compute_abi_info(ccx: &mut CrateContext,
+                        atys: &[Type],
+                        rty: Type,
+                        ret_def: bool) -> FnType {
+    match ccx.sess.targ_cfg.arch {
+        X86 => cabi_x86::compute_abi_info(ccx, atys, rty, ret_def),
+        X86_64 => cabi_x86_64::compute_abi_info(ccx, atys, rty, ret_def),
+        Arm => cabi_arm::compute_abi_info(ccx, atys, rty, ret_def),
+        Mips => cabi_mips::compute_abi_info(ccx, atys, rty, ret_def),
     }
 }
index 7f1fc5978c4396d68517f5377a8aeac321a37d67..19f0b9b78eb353baa4c4bd3d12ed7bf47ab1017c 100644 (file)
@@ -10,7 +10,8 @@
 
 use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array};
 use lib::llvm::{Attribute, StructRetAttribute};
-use middle::trans::cabi::{ABIInfo, FnType, LLVMType};
+use middle::trans::cabi::{FnType, LLVMType};
+use middle::trans::context::CrateContext;
 
 use middle::trans::type_::Type;
 
@@ -124,45 +125,37 @@ fn is_reg_ty(ty: Type) -> bool {
     }
 }
 
-enum ARM_ABIInfo { ARM_ABIInfo }
-
-impl ABIInfo for ARM_ABIInfo {
-    fn compute_info(&self,
-                    atys: &[Type],
-                    rty: Type,
-                    ret_def: bool) -> FnType {
-        let mut arg_tys = ~[];
-        let mut attrs = ~[];
-        for &aty in atys.iter() {
-            let (ty, attr) = classify_arg_ty(aty);
-            arg_tys.push(ty);
-            attrs.push(attr);
-        }
-
-        let (ret_ty, ret_attr) = if ret_def {
-            classify_ret_ty(rty)
-        } else {
-            (LLVMType { cast: false, ty: Type::void() }, None)
-        };
+pub fn compute_abi_info(_ccx: &mut CrateContext,
+                        atys: &[Type],
+                        rty: Type,
+                        ret_def: bool) -> FnType {
+    let mut arg_tys = ~[];
+    let mut attrs = ~[];
+    for &aty in atys.iter() {
+        let (ty, attr) = classify_arg_ty(aty);
+        arg_tys.push(ty);
+        attrs.push(attr);
+    }
 
-        let mut ret_ty = ret_ty;
+    let (ret_ty, ret_attr) = if ret_def {
+        classify_ret_ty(rty)
+    } else {
+        (LLVMType { cast: false, ty: Type::void() }, None)
+    };
 
-        let sret = ret_attr.is_some();
-        if sret {
-            arg_tys.unshift(ret_ty);
-            attrs.unshift(ret_attr);
-            ret_ty = LLVMType { cast: false, ty: Type::void() };
-        }
+    let mut ret_ty = ret_ty;
 
-        return FnType {
-            arg_tys: arg_tys,
-            ret_ty: ret_ty,
-            attrs: attrs,
-            sret: sret
-        };
+    let sret = ret_attr.is_some();
+    if sret {
+        arg_tys.unshift(ret_ty);
+        attrs.unshift(ret_attr);
+        ret_ty = LLVMType { cast: false, ty: Type::void() };
     }
-}
 
-pub fn abi_info() -> @ABIInfo {
-    return @ARM_ABIInfo as @ABIInfo;
+    return FnType {
+        arg_tys: arg_tys,
+        ret_ty: ret_ty,
+        attrs: attrs,
+        sret: sret
+    };
 }
index f5fb68a70578c2fcf60536019877e5f00e07d236..4577bf11b84de8b7a5c5b78efb22b3d5e7c9ca33 100644 (file)
@@ -14,6 +14,7 @@
 use std::vec;
 use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array};
 use lib::llvm::{Attribute, StructRetAttribute};
+use middle::trans::context::CrateContext;
 use middle::trans::context::task_llcx;
 use middle::trans::cabi::*;
 
@@ -170,47 +171,39 @@ fn struct_ty(ty: Type,
     return Type::struct_(fields, false);
 }
 
-enum MIPS_ABIInfo { MIPS_ABIInfo }
-
-impl ABIInfo for MIPS_ABIInfo {
-    fn compute_info(&self,
-                    atys: &[Type],
-                    rty: Type,
-                    ret_def: bool) -> FnType {
-        let (ret_ty, ret_attr) = if ret_def {
-            classify_ret_ty(rty)
-        } else {
-            (LLVMType { cast: false, ty: Type::void() }, None)
-        };
-
-        let mut ret_ty = ret_ty;
-
-        let sret = ret_attr.is_some();
-        let mut arg_tys = ~[];
-        let mut attrs = ~[];
-        let mut offset = if sret { 4 } else { 0 };
-
-        for aty in atys.iter() {
-            let (ty, attr) = classify_arg_ty(*aty, &mut offset);
-            arg_tys.push(ty);
-            attrs.push(attr);
-        };
-
-        if sret {
-            arg_tys = vec::append(~[ret_ty], arg_tys);
-            attrs = vec::append(~[ret_attr], attrs);
-            ret_ty = LLVMType { cast: false, ty: Type::void() };
-        }
+pub fn compute_abi_info(_ccx: &mut CrateContext,
+                        atys: &[Type],
+                        rty: Type,
+                        ret_def: bool) -> FnType {
+    let (ret_ty, ret_attr) = if ret_def {
+        classify_ret_ty(rty)
+    } else {
+        (LLVMType { cast: false, ty: Type::void() }, None)
+    };
+
+    let mut ret_ty = ret_ty;
+
+    let sret = ret_attr.is_some();
+    let mut arg_tys = ~[];
+    let mut attrs = ~[];
+    let mut offset = if sret { 4 } else { 0 };
 
-        return FnType {
-            arg_tys: arg_tys,
-            ret_ty: ret_ty,
-            attrs: attrs,
-            sret: sret
-        };
+    for aty in atys.iter() {
+        let (ty, attr) = classify_arg_ty(*aty, &mut offset);
+        arg_tys.push(ty);
+        attrs.push(attr);
+    };
+
+    if sret {
+        arg_tys = vec::append(~[ret_ty], arg_tys);
+        attrs = vec::append(~[ret_attr], attrs);
+        ret_ty = LLVMType { cast: false, ty: Type::void() };
     }
-}
 
-pub fn abi_info() -> @ABIInfo {
-    return @MIPS_ABIInfo as @ABIInfo;
+    return FnType {
+        arg_tys: arg_tys,
+        ret_ty: ret_ty,
+        attrs: attrs,
+        sret: sret
+    };
 }
index 8c5a2e70484bcd73ce8f5ce094427578de6989ac..f0af31e795af239c218bcc3c350bf09715939df6 100644 (file)
 use super::cabi::*;
 use super::common::*;
 use super::machine::*;
-
 use middle::trans::type_::Type;
 
-struct X86_ABIInfo {
-    ccx: @mut CrateContext
-}
+pub fn compute_abi_info(ccx: &mut CrateContext,
+                        atys: &[Type],
+                        rty: Type,
+                        ret_def: bool) -> FnType {
+    let mut arg_tys = ~[];
+    let mut attrs = ~[];
 
-impl ABIInfo for X86_ABIInfo {
-    fn compute_info(&self,
-                    atys: &[Type],
-                    rty: Type,
-                    ret_def: bool) -> FnType {
-        let mut arg_tys = do atys.map |a| {
-            LLVMType { cast: false, ty: *a }
-        };
-        let mut ret_ty = LLVMType {
+    let ret_ty;
+    let sret;
+    if !ret_def {
+        ret_ty = LLVMType {
             cast: false,
-            ty: rty
+            ty: Type::void(),
         };
-        let mut attrs = do atys.map |_| {
-            None
-        };
-
-        // Rules for returning structs taken from
+        sret = false;
+    } else if rty.kind() == Struct {
+        // Returning a structure. Most often, this will use
+        // a hidden first argument. On some platforms, though,
+        // small structs are returned as integers.
+        //
+        // Some links:
         // http://www.angelcode.com/dev/callconv/callconv.html
         // Clang's ABI handling is in lib/CodeGen/TargetInfo.cpp
-        let sret = {
-            let returning_a_struct = rty.kind() == Struct && ret_def;
-            let big_struct = match self.ccx.sess.targ_cfg.os {
-                os_win32 | os_macos => llsize_of_alloc(self.ccx, rty) > 8,
-                _ => true
-            };
-            returning_a_struct && big_struct
+
+        enum Strategy { RetValue(Type), RetPointer }
+        let strategy = match ccx.sess.targ_cfg.os {
+            os_win32 | os_macos => {
+                match llsize_of_alloc(ccx, rty) {
+                    1 => RetValue(Type::i8()),
+                    2 => RetValue(Type::i16()),
+                    4 => RetValue(Type::i32()),
+                    8 => RetValue(Type::i64()),
+                    _ => RetPointer
+                }
+            }
+            _ => {
+                RetPointer
+            }
         };
 
-        if sret {
-            let ret_ptr_ty = LLVMType {
-                cast: false,
-                ty: ret_ty.ty.ptr_to()
-            };
-            arg_tys = ~[ret_ptr_ty] + arg_tys;
-            attrs = ~[Some(StructRetAttribute)] + attrs;
-            ret_ty = LLVMType {
-                cast: false,
-                ty: Type::void(),
-            };
-        } else if !ret_def {
-            ret_ty = LLVMType {
-                cast: false,
-                ty: Type::void()
-            };
-        }
+        match strategy {
+            RetValue(t) => {
+                ret_ty = LLVMType {
+                    cast: true,
+                    ty: t
+                };
+                sret = false;
+            }
+            RetPointer => {
+                arg_tys.push(LLVMType {
+                    cast: false,
+                    ty: rty.ptr_to()
+                });
+                attrs.push(Some(StructRetAttribute));
 
-        return FnType {
-            arg_tys: arg_tys,
-            ret_ty: ret_ty,
-            attrs: attrs,
-            sret: sret
+                ret_ty = LLVMType {
+                    cast: false,
+                    ty: Type::void(),
+                };
+                sret = true;
+            }
+        }
+    } else {
+        ret_ty = LLVMType {
+            cast: false,
+            ty: rty
         };
+        sret = false;
+    }
+
+    for &a in atys.iter() {
+        arg_tys.push(LLVMType { cast: false, ty: a });
+        attrs.push(None);
     }
-}
 
-pub fn abi_info(ccx: @mut CrateContext) -> @ABIInfo {
-    return @X86_ABIInfo {
-        ccx: ccx
-    } as @ABIInfo;
+    return FnType {
+        arg_tys: arg_tys,
+        ret_ty: ret_ty,
+        attrs: attrs,
+        sret: sret
+    };
 }
index dd24ec3ff1ac198222cecf77cb54afb0b97cfa1d..179366878418f0a879d0481a7454925480c613c5 100644 (file)
@@ -15,6 +15,7 @@
 use lib::llvm::{Struct, Array, Attribute};
 use lib::llvm::{StructRetAttribute, ByValAttribute};
 use middle::trans::cabi::*;
+use middle::trans::context::CrateContext;
 
 use middle::trans::type_::Type;
 
@@ -331,10 +332,10 @@ fn llvec_len(cls: &[RegClass]) -> uint {
     return Type::struct_(tys, false);
 }
 
-fn x86_64_tys(atys: &[Type],
-              rty: Type,
-              ret_def: bool) -> FnType {
-
+pub fn compute_abi_info(_ccx: &mut CrateContext,
+                        atys: &[Type],
+                        rty: Type,
+                        ret_def: bool) -> FnType {
     fn x86_64_ty(ty: Type,
                  is_mem_cls: &fn(cls: &[RegClass]) -> bool,
                  attr: Attribute) -> (LLVMType, Option<Attribute>) {
@@ -384,18 +385,3 @@ fn x86_64_ty(ty: Type,
         sret: sret
     };
 }
-
-enum X86_64_ABIInfo { X86_64_ABIInfo }
-
-impl ABIInfo for X86_64_ABIInfo {
-    fn compute_info(&self,
-                    atys: &[Type],
-                    rty: Type,
-                    ret_def: bool) -> FnType {
-        return x86_64_tys(atys, rty, ret_def);
-    }
-}
-
-pub fn abi_info() -> @ABIInfo {
-    return @X86_64_ABIInfo as @ABIInfo;
-}
index 15dbcf554883944324a7e5b6755afa1ec837efd3..ab5f3289cc7226619160e52f8dd18df918570dd5 100644 (file)
@@ -37,6 +37,7 @@
 use middle::trans::meth;
 use middle::trans::monomorphize;
 use middle::trans::type_of;
+use middle::trans::foreign;
 use middle::ty;
 use middle::subst::Subst;
 use middle::typeck;
@@ -46,6 +47,7 @@
 use middle::trans::type_::Type;
 
 use syntax::ast;
+use syntax::abi::AbiSet;
 use syntax::ast_map;
 use syntax::visit;
 use syntax::visit::Visitor;
@@ -241,20 +243,20 @@ pub fn trans_fn_ref_with_vtables(
         type_params: &[ty::t], // values for fn's ty params
         vtables: Option<typeck::vtable_res>) // vtables for the call
      -> FnData {
-    //!
-    //
-    // Translates a reference to a fn/method item, monomorphizing and
-    // inlining as it goes.
-    //
-    // # Parameters
-    //
-    // - `bcx`: the current block where the reference to the fn occurs
-    // - `def_id`: def id of the fn or method item being referenced
-    // - `ref_id`: node id of the reference to the fn/method, if applicable.
-    //   This parameter may be zero; but, if so, the resulting value may not
-    //   have the right type, so it must be cast before being used.
-    // - `type_params`: values for each of the fn/method's type parameters
-    // - `vtables`: values for each bound on each of the type parameters
+    /*!
+     * Translates a reference to a fn/method item, monomorphizing and
+     * inlining as it goes.
+     *
+     * # Parameters
+     *
+     * - `bcx`: the current block where the reference to the fn occurs
+     * - `def_id`: def id of the fn or method item being referenced
+     * - `ref_id`: node id of the reference to the fn/method, if applicable.
+     *   This parameter may be zero; but, if so, the resulting value may not
+     *   have the right type, so it must be cast before being used.
+     * - `type_params`: values for each of the fn/method's type parameters
+     * - `vtables`: values for each bound on each of the type parameters
+     */
 
     let _icx = push_ctxt("trans_fn_ref_with_vtables");
     let ccx = bcx.ccx();
@@ -387,7 +389,7 @@ pub fn trans_fn_ref_with_vtables(
     }
 
     // Find the actual function pointer.
-    let val = {
+    let mut val = {
         if def_id.crate == ast::LOCAL_CRATE {
             // Internal reference.
             get_item_val(ccx, def_id.node)
@@ -397,6 +399,35 @@ pub fn trans_fn_ref_with_vtables(
         }
     };
 
+    // This is subtle and surprising, but sometimes we have to bitcast
+    // the resulting fn pointer.  The reason has to do with external
+    // functions.  If you have two crates that both bind the same C
+    // library, they may not use precisely the same types: for
+    // example, they will probably each declare their own structs,
+    // which are distinct types from LLVM's point of view (nominal
+    // types).
+    //
+    // Now, if those two crates are linked into an application, and
+    // they contain inlined code, you can wind up with a situation
+    // where both of those functions wind up being loaded into this
+    // application simultaneously. In that case, the same function
+    // (from LLVM's point of view) requires two types. But of course
+    // LLVM won't allow one function to have two types.
+    //
+    // What we currently do, therefore, is declare the function with
+    // one of the two types (whichever happens to come first) and then
+    // bitcast as needed when the function is referenced to make sure
+    // it has the type we expect.
+    //
+    // 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, fn_tpt.ty);
+    let llptrty = llty.ptr_to();
+    if val_ty(val) != llptrty {
+        val = BitCast(bcx, val, llptrty);
+    }
+
     return FnData {llfn: val};
 }
 
@@ -552,16 +583,26 @@ pub fn body_contains_ret(body: &ast::Block) -> bool {
     *cx
 }
 
-// See [Note-arg-mode]
 pub fn trans_call_inner(in_cx: @mut Block,
                         call_info: Option<NodeInfo>,
-                        fn_expr_ty: ty::t,
+                        callee_ty: ty::t,
                         ret_ty: ty::t,
                         get_callee: &fn(@mut Block) -> Callee,
                         args: CallArgs,
                         dest: Option<expr::Dest>,
                         autoref_arg: AutorefArg)
                         -> Result {
+    /*!
+     * This behemoth of a function translates function calls.
+     * Unfortunately, in order to generate more efficient LLVM
+     * output at -O0, it has quite a complex signature (refactoring
+     * this into two functions seems like a good idea).
+     *
+     * In particular, for lang items, it is invoked with a dest of
+     * None, and
+     */
+
+
     do base::with_scope_result(in_cx, call_info, "call") |cx| {
         let callee = get_callee(cx);
         let mut bcx = callee.bcx;
@@ -589,98 +630,125 @@ pub fn trans_call_inner(in_cx: @mut Block,
             }
         };
 
-        let llretslot = trans_ret_slot(bcx, fn_expr_ty, dest);
+        let abi = match ty::get(callee_ty).sty {
+            ty::ty_bare_fn(ref f) => f.abis,
+            _ => AbiSet::Rust()
+        };
+        let is_rust_fn =
+            abi.is_rust() ||
+            abi.is_intrinsic();
+
+        // Generate a location to store the result. If the user does
+        // not care about the result, just make a stack slot.
+        let opt_llretslot = match dest {
+            None => {
+                assert!(!type_of::return_uses_outptr(in_cx.tcx(), ret_ty));
+                None
+            }
+            Some(expr::SaveIn(dst)) => Some(dst),
+            Some(expr::Ignore) => {
+                if !ty::type_is_voidish(ret_ty) {
+                    Some(alloc_ty(bcx, ret_ty, "__llret"))
+                } else {
+                    unsafe {
+                        Some(llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()))
+                    }
+                }
+            }
+        };
 
-        let mut llargs = ~[];
+        let mut llresult = unsafe {
+            llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref())
+        };
 
-        if !ty::type_is_immediate(bcx.tcx(), ret_ty) {
-            llargs.push(llretslot);
-        }
+        // The code below invokes the function, using either the Rust
+        // conventions (if it is a rust fn) or the native conventions
+        // (otherwise).  The important part is that, when all is sad
+        // and done, either the return value of the function will have been
+        // written in opt_llretslot (if it is Some) or `llresult` will be
+        // set appropriately (otherwise).
+        if is_rust_fn {
+            let mut llargs = ~[];
+
+            // Push the out-pointer if we use an out-pointer for this
+            // return type, otherwise push "undef".
+            if type_of::return_uses_outptr(in_cx.tcx(), ret_ty) {
+                llargs.push(opt_llretslot.unwrap());
+            }
+
+            // Push the environment.
+            llargs.push(llenv);
 
-        llargs.push(llenv);
-        bcx = trans_args(bcx, args, fn_expr_ty, autoref_arg, &mut llargs);
+            // Push the arguments.
+            bcx = trans_args(bcx, args, callee_ty,
+                             autoref_arg, &mut llargs);
 
-        // Now that the arguments have finished evaluating, we need to revoke
-        // the cleanup for the self argument
-        match callee.data {
-            Method(d) => {
-                for &v in d.temp_cleanup.iter() {
-                    revoke_clean(bcx, v);
+            // Now that the arguments have finished evaluating, we
+            // need to revoke the cleanup for the self argument
+            match callee.data {
+                Method(d) => {
+                    for &v in d.temp_cleanup.iter() {
+                        revoke_clean(bcx, v);
+                    }
                 }
+                _ => {}
             }
-            _ => {}
-        }
 
-        // Uncomment this to debug calls.
-        /*
-        printfln!("calling: %s", bcx.val_to_str(llfn));
-        for llarg in llargs.iter() {
-            printfln!("arg: %s", bcx.val_to_str(*llarg));
+            // Invoke the actual rust fn and update bcx/llresult.
+            let (llret, b) = base::invoke(bcx, llfn, llargs);
+            bcx = b;
+            llresult = llret;
+
+            // If the Rust convention for this type is return via
+            // the return value, copy it into llretslot.
+            match opt_llretslot {
+                Some(llretslot) => {
+                    if !type_of::return_uses_outptr(bcx.tcx(), ret_ty) &&
+                        !ty::type_is_voidish(ret_ty)
+                    {
+                        Store(bcx, llret, llretslot);
+                    }
+                }
+                None => {}
+            }
+        } else {
+            // Lang items are the only case where dest is None, and
+            // they are always Rust fns.
+            assert!(dest.is_some());
+
+            let mut llargs = ~[];
+            bcx = trans_args(bcx, args, callee_ty,
+                             autoref_arg, &mut llargs);
+            bcx = foreign::trans_native_call(bcx, callee_ty,
+                                             llfn, opt_llretslot.unwrap(), llargs);
         }
-        io::println("---");
-        */
-
-        // If the block is terminated, then one or more of the args
-        // has type _|_. Since that means it diverges, the code for
-        // the call itself is unreachable.
-        let (llresult, new_bcx) = base::invoke(bcx, llfn, llargs);
-        bcx = new_bcx;
 
+        // If the caller doesn't care about the result of this fn call,
+        // drop the temporary slot we made.
         match dest {
-            None => { assert!(ty::type_is_immediate(bcx.tcx(), ret_ty)) }
+            None => {
+                assert!(!type_of::return_uses_outptr(bcx.tcx(), ret_ty));
+            }
             Some(expr::Ignore) => {
                 // drop the value if it is not being saved.
-                if ty::type_needs_drop(bcx.tcx(), ret_ty) {
-                    if ty::type_is_immediate(bcx.tcx(), ret_ty) {
-                        let llscratchptr = alloc_ty(bcx, ret_ty, "__ret");
-                        Store(bcx, llresult, llscratchptr);
-                        bcx = glue::drop_ty(bcx, llscratchptr, ret_ty);
-                    } else {
-                        bcx = glue::drop_ty(bcx, llretslot, ret_ty);
-                    }
-                }
-            }
-            Some(expr::SaveIn(lldest)) => {
-                // If this is an immediate, store into the result location.
-                // (If this was not an immediate, the result will already be
-                // directly written into the output slot.)
-                if ty::type_is_immediate(bcx.tcx(), ret_ty) {
-                    Store(bcx, llresult, lldest);
-                }
+                bcx = glue::drop_ty(bcx, opt_llretslot.unwrap(), ret_ty);
             }
+            Some(expr::SaveIn(_)) => { }
         }
 
         if ty::type_is_bot(ret_ty) {
             Unreachable(bcx);
         }
+
         rslt(bcx, llresult)
     }
 }
 
-
 pub enum CallArgs<'self> {
     ArgExprs(&'self [@ast::expr]),
     ArgVals(&'self [ValueRef])
 }
 
-pub fn trans_ret_slot(bcx: @mut Block, fn_ty: ty::t, dest: Option<expr::Dest>)
-                      -> ValueRef {
-    let retty = ty::ty_fn_ret(fn_ty);
-
-    match dest {
-        Some(expr::SaveIn(dst)) => dst,
-        _ => {
-            if ty::type_is_immediate(bcx.tcx(), retty) {
-                unsafe {
-                    llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref())
-                }
-            } else {
-                alloc_ty(bcx, retty, "__trans_ret_slot")
-            }
-        }
-    }
-}
-
 pub fn trans_args(cx: @mut Block,
                   args: CallArgs,
                   fn_ty: ty::t,
@@ -804,7 +872,7 @@ pub fn trans_arg_expr(bcx: @mut Block,
 
         if formal_arg_ty != arg_datum.ty {
             // this could happen due to e.g. subtyping
-            let llformal_arg_ty = type_of::type_of_explicit_arg(ccx, &formal_arg_ty);
+            let llformal_arg_ty = type_of::type_of_explicit_arg(ccx, formal_arg_ty);
             debug!("casting actual type (%s) to match formal (%s)",
                    bcx.val_to_str(val), bcx.llty_str(llformal_arg_ty));
             val = PointerCast(bcx, val, llformal_arg_ty);
index fde33220d8426cd076adbe384283a759eb222281..027696d37f128746950816a78c19672537731df1 100644 (file)
@@ -36,7 +36,7 @@
 use std::cast::transmute;
 use std::cast;
 use std::hashmap::{HashMap};
-use std::libc::{c_uint, c_longlong, c_ulonglong};
+use std::libc::{c_uint, c_longlong, c_ulonglong, c_char};
 use std::vec;
 use syntax::ast::ident;
 use syntax::ast_map::{path, path_elt};
@@ -121,7 +121,7 @@ pub fn BuilderRef_res(B: BuilderRef) -> BuilderRef_res {
     }
 }
 
-pub type ExternMap = HashMap<@str, ValueRef>;
+pub type ExternMap = HashMap<~str, ValueRef>;
 
 // Types used for llself.
 pub struct ValSelfData {
@@ -197,10 +197,10 @@ pub struct FunctionContext {
     // outputting the resume instruction.
     personality: Option<ValueRef>,
 
-    // True if this function has an immediate return value, false otherwise.
-    // If this is false, the llretptr will alias the first argument of the
-    // function.
-    has_immediate_return_value: bool,
+    // True if the caller expects this fn to use the out pointer to
+    // return. Either way, your code should write into llretptr, but if
+    // this value is false, llretptr will be a local alloca.
+    caller_expects_out_pointer: bool,
 
     // Maps arguments to allocas created for them in llallocas.
     llargs: @mut HashMap<ast::NodeId, ValueRef>,
@@ -232,20 +232,20 @@ pub struct FunctionContext {
 
 impl FunctionContext {
     pub fn arg_pos(&self, arg: uint) -> uint {
-        if self.has_immediate_return_value {
-            arg + 1u
-        } else {
+        if self.caller_expects_out_pointer {
             arg + 2u
+        } else {
+            arg + 1u
         }
     }
 
     pub fn out_arg_pos(&self) -> uint {
-        assert!(!self.has_immediate_return_value);
+        assert!(self.caller_expects_out_pointer);
         0u
     }
 
     pub fn env_arg_pos(&self) -> uint {
-        if !self.has_immediate_return_value {
+        if self.caller_expects_out_pointer {
             1u
         } else {
             0u
@@ -709,7 +709,7 @@ pub fn C_integral(t: Type, u: u64, sign_extend: bool) -> ValueRef {
 
 pub fn C_floating(s: &str, t: Type) -> ValueRef {
     unsafe {
-        do s.to_c_str().with_ref |buf| {
+        do s.with_c_str |buf| {
             llvm::LLVMConstRealOfString(t.to_ref(), buf)
         }
     }
@@ -757,12 +757,12 @@ pub fn C_cstr(cx: &mut CrateContext, s: @str) -> ValueRef {
             None => ()
         }
 
-        let sc = do s.to_c_str().with_ref |buf| {
-            llvm::LLVMConstStringInContext(cx.llcx, buf, s.len() as c_uint, False)
+        let sc = do s.as_imm_buf |buf, buflen| {
+            llvm::LLVMConstStringInContext(cx.llcx, buf as *c_char, buflen as c_uint, False)
         };
 
         let gsym = token::gensym("str");
-        let g = do fmt!("str%u", gsym).to_c_str().with_ref |buf| {
+        let g = do fmt!("str%u", gsym).with_c_str |buf| {
             llvm::LLVMAddGlobal(cx.llmod, val_ty(sc).to_ref(), buf)
         };
         llvm::LLVMSetInitializer(g, sc);
index 1992d71427f2053baacc7413c310324c9602202e..87d26fa5ba07c6f7b4be346e0a25166583f08159 100644 (file)
@@ -32,6 +32,7 @@
 
 use std::c_str::ToCStr;
 use std::libc::c_uint;
+use std::vec;
 use syntax::{ast, ast_util, ast_map};
 
 pub fn const_lit(cx: &mut CrateContext, e: &ast::expr, lit: ast::lit)
@@ -102,7 +103,7 @@ pub fn const_vec(cx: @mut CrateContext, e: &ast::expr, es: &[@ast::expr])
 
 fn const_addr_of(cx: &mut CrateContext, cv: ValueRef) -> ValueRef {
     unsafe {
-        let gv = do "const".to_c_str().with_ref |name| {
+        let gv = do "const".with_c_str |name| {
             llvm::LLVMAddGlobal(cx.llmod, val_ty(cv).to_ref(), name)
         };
         llvm::LLVMSetInitializer(gv, cv);
@@ -528,7 +529,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: &ast::expr) -> ValueRef {
               ast::expr_vec(ref es, ast::m_imm) => {
                 let (cv, sz, llunitty) = const_vec(cx, e, *es);
                 let llty = val_ty(cv);
-                let gv = do "const".to_c_str().with_ref |name| {
+                let gv = do "const".with_c_str |name| {
                     llvm::LLVMAddGlobal(cx.llmod, llty.to_ref(), name)
                 };
                 llvm::LLVMSetInitializer(gv, cv);
@@ -540,6 +541,23 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: &ast::expr) -> ValueRef {
               _ => cx.sess.span_bug(e.span, "bad const-slice expr")
             }
           }
+          ast::expr_repeat(elem, count, _) => {
+            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 n = match const_eval::eval_const_expr(cx.tcx, count) {
+                const_eval::const_int(i)  => i as uint,
+                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));
+            let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
+                C_struct(vs)
+            } else {
+                C_array(llunitty, vs)
+            };
+            v
+          }
           ast::expr_path(ref pth) => {
             assert_eq!(pth.types.len(), 0);
             let tcx = cx.tcx;
index c0c1475e80834afce5aa171010f095c4b15f5c83..5d0849ef12c9ab2ba2bcca0e845b013959ed84fc 100644 (file)
@@ -128,15 +128,15 @@ pub fn new(sess: session::Session,
         unsafe {
             let llcx = llvm::LLVMContextCreate();
             set_task_llcx(llcx);
-            let llmod = do name.to_c_str().with_ref |buf| {
+            let llmod = do name.with_c_str |buf| {
                 llvm::LLVMModuleCreateWithNameInContext(buf, llcx)
             };
             let data_layout: &str = sess.targ_cfg.target_strs.data_layout;
             let targ_triple: &str = sess.targ_cfg.target_strs.target_triple;
-            do data_layout.to_c_str().with_ref |buf| {
+            do data_layout.with_c_str |buf| {
                 llvm::LLVMSetDataLayout(llmod, buf)
             };
-            do targ_triple.to_c_str().with_ref |buf| {
+            do targ_triple.with_c_str |buf| {
                 llvm::LLVMSetTarget(llmod, buf)
             };
             let targ_cfg = sess.targ_cfg;
index ed061e66f4194dd0eab1df915f87b7fd188b8312..04d401f82970ceb567c12dd1f24f4554b26374e4 100644 (file)
@@ -237,7 +237,7 @@ pub fn trans_log(log_ex: &ast::expr,
             ccx, modpath, "loglevel");
         let global;
         unsafe {
-            global = do s.to_c_str().with_ref |buf| {
+            global = do s.with_c_str |buf| {
                 llvm::LLVMAddGlobal(ccx.llmod, Type::i32().to_ref(), buf)
             };
             llvm::LLVMSetGlobalConstant(global, False);
index c8a09ce87c0a15beeb32eb8ad4735a3ea02619b6..1060a06a5cfa9d5a6b9a1511c7df0a65ab8ce014 100644 (file)
@@ -190,12 +190,12 @@ pub fn scratch_datum(bcx: @mut Block, ty: ty::t, name: &str, zero: bool) -> Datu
 
 pub fn appropriate_mode(tcx: ty::ctxt, ty: ty::t) -> DatumMode {
     /*!
-    *
-    * Indicates the "appropriate" mode for this value,
-    * which is either by ref or by value, depending
-    * on whether type is immediate or not. */
+     * Indicates the "appropriate" mode for this value,
+     * which is either by ref or by value, depending
+     * on whether type is immediate or not.
+     */
 
-    if ty::type_is_nil(ty) || ty::type_is_bot(ty) {
+    if ty::type_is_voidish(ty) {
         ByValue
     } else if ty::type_is_immediate(tcx, ty) {
         ByValue
@@ -271,7 +271,7 @@ pub fn copy_to(&self, bcx: @mut Block, action: CopyAction, dst: ValueRef)
 
         let _icx = push_ctxt("copy_to");
 
-        if ty::type_is_nil(self.ty) || ty::type_is_bot(self.ty) {
+        if ty::type_is_voidish(self.ty) {
             return bcx;
         }
 
@@ -343,7 +343,7 @@ pub fn move_to(&self, bcx: @mut Block, action: CopyAction, dst: ValueRef)
         debug!("move_to(self=%s, action=%?, dst=%s)",
                self.to_str(bcx.ccx()), action, bcx.val_to_str(dst));
 
-        if ty::type_is_nil(self.ty) || ty::type_is_bot(self.ty) {
+        if ty::type_is_voidish(self.ty) {
             return bcx;
         }
 
@@ -432,7 +432,7 @@ pub fn to_value_llval(&self, bcx: @mut Block) -> ValueRef {
          *
          * Yields the value itself. */
 
-        if ty::type_is_nil(self.ty) || ty::type_is_bot(self.ty) {
+        if ty::type_is_voidish(self.ty) {
             C_nil()
         } else {
             match self.mode {
@@ -469,7 +469,7 @@ pub fn to_ref_llval(&self, bcx: @mut Block) -> ValueRef {
         match self.mode {
             ByRef(_) => self.val,
             ByValue => {
-                if ty::type_is_nil(self.ty) || ty::type_is_bot(self.ty) {
+                if ty::type_is_voidish(self.ty) {
                     C_null(type_of::type_of(bcx.ccx(), self.ty).ptr_to())
                 } else {
                     let slot = alloc_ty(bcx, self.ty, "");
index 66ff2495c296de6dfcd05328a9732c5df722d73c..f5073cc71e5d031559a410f17a27f85cd0d094ab 100644 (file)
@@ -51,7 +51,7 @@
 
 use driver::session;
 use lib::llvm::llvm;
-use lib::llvm::{ModuleRef, ContextRef};
+use lib::llvm::{ModuleRef, ContextRef, ValueRef};
 use lib::llvm::debuginfo::*;
 use middle::trans::common::*;
 use middle::trans::machine;
@@ -69,7 +69,8 @@
 use std::ptr;
 use std::vec;
 use syntax::codemap::span;
-use syntax::{ast, codemap, ast_util, ast_map};
+use syntax::{ast, codemap, ast_util, ast_map, opt_vec};
+use syntax::parse::token::special_idents;
 
 static DW_LANG_RUST: int = 0x9000;
 
@@ -97,7 +98,7 @@ pub struct DebugContext {
     priv builder: DIBuilderRef,
     priv curr_loc: (uint, uint),
     priv created_files: HashMap<~str, DIFile>,
-    priv created_functions: HashMap<ast::NodeId, DISubprogram>,
+    priv created_functions: HashMap<FunctionCacheKey, DISubprogram>,
     priv created_blocks: HashMap<ast::NodeId, DILexicalBlock>,
     priv created_types: HashMap<uint, DIType>
 }
@@ -121,21 +122,25 @@ pub fn new(llmod: ModuleRef, crate: ~str) -> DebugContext {
     }
 }
 
+#[deriving(Eq,IterBytes)]
+struct FunctionCacheKey {
+    // Use the address of the llvm function (FunctionContext::llfn) as key for the cache. This
+    // nicely takes care of monomorphization, where two specializations will have the same
+    // ast::NodeId but different llvm functions (each needing its own debug description).
+    priv llfn: ValueRef
+}
+
+impl FunctionCacheKey {
+    fn for_function_context(fcx: &FunctionContext) -> FunctionCacheKey {
+        FunctionCacheKey { llfn: fcx.llfn }
+    }
+}
 
 pub struct FunctionDebugContext {
     priv scope_map: HashMap<ast::NodeId, DIScope>,
     priv argument_counter: uint,
 }
 
-impl FunctionDebugContext {
-    fn new() -> FunctionDebugContext {
-        return FunctionDebugContext {
-            scope_map: HashMap::new(),
-            argument_counter: 1,
-        };
-    }
-}
-
 /// Create any deferred debug metadata nodes
 pub fn finalize(cx: @mut CrateContext) {
     debug!("finalize");
@@ -162,6 +167,9 @@ pub fn create_local_var_metadata(bcx: @mut Block, local: &ast::Local) {
     }
 }
 
+/// Creates debug information for a local variable introduced in the head of a match-statement arm.
+///
+/// Adds the created metadata nodes directly to the crate's IR.
 pub fn create_match_binding_metadata(bcx: @mut Block,
                                      variable_ident: ast::ident,
                                      node_id: ast::NodeId,
@@ -170,6 +178,52 @@ pub fn create_match_binding_metadata(bcx: @mut Block,
     declare_local(bcx, variable_ident, node_id, variable_type, 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: @mut Block,
+                                     variable_type: ty::t,
+                                     llptr: ValueRef) {
+    assert_fcx_has_span(bcx.fcx);
+    let span = bcx.fcx.span.unwrap();
+
+    let cx = bcx.ccx();
+
+    let filename = span_start(cx, span).file.name;
+    let file_metadata = file_metadata(cx, filename);
+
+    let loc = span_start(cx, span);
+    let type_metadata = type_metadata(cx, variable_type, span);
+    let scope = create_function_metadata(bcx.fcx);
+
+    let var_metadata = do cx.sess.str_of(special_idents::self_).to_c_str().with_ref |name| {
+        unsafe {
+            llvm::LLVMDIBuilderCreateLocalVariable(
+                DIB(cx),
+                DW_TAG_arg_variable,
+                scope,
+                name,
+                file_metadata,
+                loc.line as c_uint,
+                type_metadata,
+                false,
+                0,
+                1)
+        }
+    };
+
+    set_debug_location(cx, scope, loc.line, loc.col.to_uint());
+    unsafe {
+        let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(
+            DIB(cx),
+            llptr,
+            var_metadata,
+            bcx.llbb);
+
+        llvm::LLVMSetInstDebugLocation(trans::build::B(bcx).llbuilder, instr);
+    }
+}
+
 /// Creates debug information for the given function argument.
 ///
 /// Adds the created metadata nodes directly to the crate's IR.
@@ -207,7 +261,7 @@ pub fn create_argument_metadata(bcx: @mut Block,
             argument_index as c_uint
         };
 
-        let arg_metadata = do name.to_c_str().with_ref |name| {
+        let arg_metadata = do name.with_c_str |name| {
             unsafe {
                 llvm::LLVMDIBuilderCreateLocalVariable(
                     DIB(cx),
@@ -243,9 +297,10 @@ pub fn create_argument_metadata(bcx: @mut Block,
     }
 }
 
-/// Sets the current debug location at the beginning of the span
+/// Sets the current debug location at the beginning of the span.
 ///
-/// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...)
+/// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...). The node_id parameter is used to
+/// reliably find the correct visibility scope for the code position.
 pub fn update_source_pos(fcx: &FunctionContext,
                          node_id: ast::NodeId,
                          span: span) {
@@ -269,13 +324,24 @@ pub fn update_source_pos(fcx: &FunctionContext,
 /// The return value should be ignored if called from outside of the debuginfo module.
 pub fn create_function_metadata(fcx: &mut FunctionContext) -> DISubprogram {
     let cx = fcx.ccx;
+    let cache_key = FunctionCacheKey::for_function_context(fcx);
+
+    match dbg_cx(cx).created_functions.find_copy(&cache_key) {
+        Some(fn_metadata) => {
+            assert!(fcx.debug_context.is_some());
+            return fn_metadata;
+        }
+        None => { /* fallthrough */}
+    }
+
+    let empty_generics = ast::Generics { lifetimes: opt_vec::Empty, ty_params: opt_vec::Empty };
 
     let fnitem = cx.tcx.items.get_copy(&fcx.id);
-    let (ident, fn_decl, id) = match fnitem {
+    let (ident, fn_decl, generics, span) = match fnitem {
         ast_map::node_item(ref item, _) => {
             match item.node {
-                ast::item_fn(ref fn_decl, _, _, _, _) => {
-                    (item.ident, fn_decl, item.id)
+                ast::item_fn(ref fn_decl, _, _, ref generics, _) => {
+                    (item.ident, fn_decl, generics, item.span)
                 }
                 _ => fcx.ccx.sess.span_bug(item.span,
                                            "create_function_metadata: item bound to non-function")
@@ -284,19 +350,24 @@ pub fn create_function_metadata(fcx: &mut FunctionContext) -> DISubprogram {
         ast_map::node_method(
             @ast::method {
                 decl: ref fn_decl,
-                id: id,
                 ident: ident,
+                generics: ref generics,
+                span: span,
                 _
             },
             _,
             _) => {
-            (ident, fn_decl, id)
+            (ident, fn_decl, generics, span)
         }
         ast_map::node_expr(ref expr) => {
             match expr.node {
                 ast::expr_fn_block(ref fn_decl, _) => {
                     let name = gensym_name("fn");
-                    (name, fn_decl, expr.id)
+                    (name, fn_decl,
+                        // This is not quite right. It should actually inherit the generics of the
+                        // enclosing function.
+                        &empty_generics,
+                        expr.span)
                 }
                 _ => fcx.ccx.sess.span_bug(expr.span,
                         "create_function_metadata: expected an expr_fn_block here")
@@ -306,27 +377,18 @@ pub fn create_function_metadata(fcx: &mut FunctionContext) -> DISubprogram {
             @ast::provided(
                 @ast::method {
                     decl: ref fn_decl,
-                    id: id,
                     ident: ident,
+                    generics: ref generics,
+                    span: span,
                     _
                 }),
             _,
             _) => {
-            (ident, fn_decl, id)
+            (ident, fn_decl, generics, span)
         }
         _ => fcx.ccx.sess.bug(fmt!("create_function_metadata: unexpected sort of node: %?", fnitem))
     };
 
-    match dbg_cx(cx).created_functions.find_copy(&id) {
-        Some(fn_metadata) => return fn_metadata,
-        None => ()
-    }
-
-    let span = match fcx.span {
-        Some(value) => value,
-        None => codemap::dummy_sp()
-    };
-
     debug!("create_function_metadata: %s, %s",
            cx.sess.str_of(ident),
            cx.sess.codemap.span_to_str(span));
@@ -334,68 +396,210 @@ pub fn create_function_metadata(fcx: &mut FunctionContext) -> DISubprogram {
     let loc = span_start(cx, span);
     let file_metadata = file_metadata(cx, loc.file.name);
 
-    let return_type_metadata = if cx.sess.opts.extra_debuginfo {
-        match fn_decl.output.node {
-          ast::ty_nil => ptr::null(),
-          _ => type_metadata(cx, ty::node_id_to_type(cx.tcx, id), fn_decl.output.span)
-        }
-    } else {
-        ptr::null()
+    let function_type_metadata = unsafe {
+        let fn_signature = get_function_signature(fcx, fn_decl);
+        llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), file_metadata, fn_signature)
     };
 
-    let fn_ty = unsafe {
-        llvm::LLVMDIBuilderCreateSubroutineType(
-            DIB(cx),
-            file_metadata,
-            create_DIArray(DIB(cx), [return_type_metadata]))
+    // get_template_parameters() will append a `<...>` clause to the function name if necessary.
+    let mut function_name = cx.sess.str_of(ident).to_owned();
+    let template_parameters = get_template_parameters(fcx,
+                                                      generics,
+                                                      file_metadata,
+                                                      &mut function_name);
+
+    let fn_metadata = do function_name.to_c_str().with_ref |function_name| {
+        unsafe {
+            llvm::LLVMDIBuilderCreateFunction(
+                DIB(cx),
+                file_metadata,
+                function_name,
+                function_name,
+                file_metadata,
+                loc.line as c_uint,
+                function_type_metadata,
+                false,
+                true,
+                loc.line as c_uint,
+                FlagPrototyped as c_uint,
+                cx.sess.opts.optimize != session::No,
+                fcx.llfn,
+                template_parameters,
+                ptr::null())
+        }
     };
 
-    let fn_metadata =
-        do cx.sess.str_of(ident).to_c_str().with_ref |name| {
-        do cx.sess.str_of(ident).to_c_str().with_ref |linkage| {
-            unsafe {
-                llvm::LLVMDIBuilderCreateFunction(
-                    DIB(cx),
-                    file_metadata,
-                    name,
-                    linkage,
-                    file_metadata,
-                    loc.line as c_uint,
-                    fn_ty,
-                    false,
-                    true,
-                    loc.line as c_uint,
-                    FlagPrototyped as c_uint,
-                    cx.sess.opts.optimize != session::No,
-                    fcx.llfn,
-                    ptr::null(),
-                    ptr::null())
+    dbg_cx(cx).created_functions.insert(cache_key, fn_metadata);
+
+    // Initialize fn debug context (including scope map)
+    {
+        assert!(fcx.debug_context.is_none());
+
+        let mut fn_debug_context = ~FunctionDebugContext {
+            scope_map: HashMap::new(),
+            argument_counter: if fcx.llself.is_some() { 2 } else { 1 }
+        };
+
+        let entry_block_id = fcx.entry_bcx.get_ref().node_info.get_ref().id;
+        let entry_block = cx.tcx.items.get(&entry_block_id);
+
+        match *entry_block {
+            ast_map::node_block(ref block) => {
+                let scope_map = &mut fn_debug_context.scope_map;
+                let arg_pats = do fn_decl.inputs.map |arg_ref| { arg_ref.pat };
+
+                populate_scope_map(cx, arg_pats, block, fn_metadata, scope_map);
             }
-        }};
+            _ => cx.sess.span_bug(span,
+                    fmt!("debuginfo::create_function_metadata() - \
+                         FunctionContext::entry_bcx::node_info points to wrong type of ast_map \
+                         entry. Expected: ast_map::node_block, actual: %?", *entry_block))
+        }
+
+        fcx.debug_context = Some(fn_debug_context);
+    }
+
+    return fn_metadata;
 
-    assert!(fcx.debug_context.is_none());
+    fn get_function_signature(fcx: &FunctionContext, fn_decl: &ast::fn_decl) -> DIArray {
+        let cx = fcx.ccx;
 
-    let mut fn_debug_context = ~FunctionDebugContext::new();
-    let entry_block_id = fcx.entry_bcx.get_ref().node_info.get_ref().id;
-    let entry_block = cx.tcx.items.get(&entry_block_id);
+        if !cx.sess.opts.extra_debuginfo {
+            return create_DIArray(DIB(cx), []);
+        }
+
+        let mut signature = vec::with_capacity(fn_decl.inputs.len() + 1);
 
-    match *entry_block {
-        ast_map::node_block(ref block) => {
-            let scope_map = &mut fn_debug_context.scope_map;
-            let arg_pats = do fn_decl.inputs.map |arg_ref| { arg_ref.pat };
+        // Return type -- llvm::DIBuilder wants this at index 0
+        match fn_decl.output.node {
+            ast::ty_nil => {
+                signature.push(ptr::null());
+            }
+            _ => {
+                let return_type = ty::node_id_to_type(cx.tcx, fcx.id);
+                let return_type = match fcx.param_substs {
+                    None => return_type,
+                    Some(substs) => {
+                        ty::subst_tps(cx.tcx, substs.tys, substs.self_ty, return_type)
+                    }
+                };
 
-            populate_scope_map(cx, arg_pats, block, fn_metadata, scope_map);
+                signature.push(type_metadata(cx, return_type, codemap::dummy_sp()));
+            }
         }
-        _ => cx.sess.span_bug(span,
-                fmt!("debuginfo::create_function_metadata() - \
-                     FunctionContext::entry_bcx::node_info points to wrong type of ast_map entry. \
-                     Expected: ast_map::node_block, actual: %?", *entry_block))
+
+        // arguments types
+        for arg in fn_decl.inputs.iter() {
+            let arg_type = ty::node_id_to_type(cx.tcx, arg.pat.id);
+            let arg_type = match fcx.param_substs {
+                None => arg_type,
+                Some(substs) => {
+                    ty::subst_tps(cx.tcx, substs.tys, substs.self_ty, arg_type)
+                }
+            };
+
+            signature.push(type_metadata(cx, arg_type, codemap::dummy_sp()));
+        }
+
+        return create_DIArray(DIB(cx), signature);
     }
 
-    fcx.debug_context = Some(fn_debug_context);
+    fn get_template_parameters(fcx: &FunctionContext,
+                               generics: &ast::Generics,
+                               file_metadata: DIFile,
+                               name_to_append_suffix_to: &mut ~str)
+                            -> DIArray {
+        let cx = fcx.ccx;
 
-    dbg_cx(cx).created_functions.insert(id, fn_metadata);
-    return fn_metadata;
+        let self_type = match fcx.param_substs {
+            Some(@param_substs{ self_ty: self_type, _ }) => self_type,
+            _ => None
+        };
+
+        // Only true for static default methods:
+        let has_self_type = self_type.is_some();
+
+        if !generics.is_type_parameterized() && !has_self_type {
+            return ptr::null();
+        }
+
+        name_to_append_suffix_to.push_char('<');
+
+        // The list to be filled with template parameters:
+        let mut template_params: ~[DIDescriptor] = vec::with_capacity(generics.ty_params.len() + 1);
+
+        // Handle self type
+        if has_self_type {
+            let actual_self_type = self_type.unwrap();
+            let actual_self_type_metadata = type_metadata(cx,
+                                                          actual_self_type,
+                                                          codemap::dummy_sp());
+
+            // Add self type name to <...> clause of function name
+            let actual_self_type_name = ty_to_str(cx.tcx, actual_self_type);
+            name_to_append_suffix_to.push_str(actual_self_type_name);
+            if generics.is_type_parameterized() {
+                name_to_append_suffix_to.push_str(",");
+            }
+
+            let ident = special_idents::type_self;
+
+            let param_metadata = do cx.sess.str_of(ident).to_c_str().with_ref |name| {
+                unsafe {
+                    llvm::LLVMDIBuilderCreateTemplateTypeParameter(
+                        DIB(cx),
+                        file_metadata,
+                        name,
+                        actual_self_type_metadata,
+                        ptr::null(),
+                        0,
+                        0)
+                }
+            };
+
+            template_params.push(param_metadata);
+        }
+
+        // Handle other generic parameters
+        let actual_types = match fcx.param_substs {
+            Some(@param_substs { tys: ref types, _ }) => types,
+            None => {
+                return create_DIArray(DIB(cx), template_params);
+            }
+        };
+
+        for (index, &ast::TyParam{ ident: ident, _ }) in generics.ty_params.iter().enumerate() {
+            let actual_type = actual_types[index];
+            let actual_type_metadata = type_metadata(cx, actual_type, codemap::dummy_sp());
+
+            // Add actual type name to <...> clause of function name
+            let actual_type_name = ty_to_str(cx.tcx, actual_type);
+            name_to_append_suffix_to.push_str(actual_type_name);
+
+            if index != generics.ty_params.len() - 1 {
+                name_to_append_suffix_to.push_str(",");
+            }
+
+            let param_metadata = do cx.sess.str_of(ident).to_c_str().with_ref |name| {
+                unsafe {
+                    llvm::LLVMDIBuilderCreateTemplateTypeParameter(
+                        DIB(cx),
+                        file_metadata,
+                        name,
+                        actual_type_metadata,
+                        ptr::null(),
+                        0,
+                        0)
+                }
+            };
+
+            template_params.push(param_metadata);
+        }
+
+        name_to_append_suffix_to.push_char('>');
+
+        return create_DIArray(DIB(cx), template_params);
+    }
 }
 
 
@@ -420,11 +624,11 @@ fn compile_unit_metadata(cx: @mut CrateContext) {
     let work_dir = cx.sess.working_dir.to_str();
     let producer = fmt!("rustc version %s", env!("CFG_VERSION"));
 
-    do crate_name.to_c_str().with_ref |crate_name| {
-    do work_dir.to_c_str().with_ref |work_dir| {
-    do producer.to_c_str().with_ref |producer| {
-    do "".to_c_str().with_ref |flags| {
-    do "".to_c_str().with_ref |split_name| {
+    do crate_name.with_c_str |crate_name| {
+    do work_dir.with_c_str |work_dir| {
+    do producer.with_c_str |producer| {
+    do "".with_c_str |flags| {
+    do "".with_c_str |split_name| {
         unsafe {
             llvm::LLVMDIBuilderCreateCompileUnit(dcx.builder,
                 DW_LANG_RUST as c_uint, crate_name, work_dir, producer,
@@ -449,7 +653,7 @@ fn declare_local(bcx: @mut Block,
     let type_metadata = type_metadata(cx, variable_type, span);
     let scope = scope_metadata(bcx.fcx, node_id, span);
 
-    let var_metadata = do name.to_c_str().with_ref |name| {
+    let var_metadata = do name.with_c_str |name| {
         unsafe {
             llvm::LLVMDIBuilderCreateLocalVariable(
                 DIB(cx),
@@ -501,8 +705,8 @@ fn file_metadata(cx: &mut CrateContext, full_path: &str) -> DIFile {
         };
 
     let file_metadata =
-        do file_name.to_c_str().with_ref |file_name| {
-        do work_dir.to_c_str().with_ref |work_dir| {
+        do file_name.with_c_str |file_name| {
+        do work_dir.with_c_str |work_dir| {
             unsafe {
                 llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name, work_dir)
             }
@@ -566,7 +770,7 @@ fn basic_type_metadata(cx: &mut CrateContext, t: ty::t) -> DIType {
 
     let llvm_type = type_of::type_of(cx, t);
     let (size, align) = size_and_align_of(cx, llvm_type);
-    let ty_metadata = do name.to_c_str().with_ref |name| {
+    let ty_metadata = do name.with_c_str |name| {
         unsafe {
             llvm::LLVMDIBuilderCreateBasicType(
                 DIB(cx),
@@ -587,7 +791,7 @@ fn pointer_type_metadata(cx: &mut CrateContext,
     let pointer_llvm_type = type_of::type_of(cx, pointer_type);
     let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type);
     let name = ty_to_str(cx.tcx, pointer_type);
-    let ptr_metadata = do name.to_c_str().with_ref |name| {
+    let ptr_metadata = do name.with_c_str |name| {
         unsafe {
             llvm::LLVMDIBuilderCreatePointerType(
                 DIB(cx),
@@ -611,7 +815,13 @@ fn struct_metadata(cx: &mut CrateContext,
     let struct_llvm_type = type_of::type_of(cx, struct_type);
 
     let field_llvm_types = do fields.map |field| { type_of::type_of(cx, field.mt.ty) };
-    let field_names = do fields.map |field| { cx.sess.str_of(field.ident).to_owned() };
+    let field_names = do fields.map |field| {
+        if field.ident == special_idents::unnamed_field {
+            ~""
+        } else {
+            cx.sess.str_of(field.ident).to_owned()
+        }
+    };
     let field_types_metadata = do fields.map |field| {
         type_metadata(cx, field.mt.ty, span)
     };
@@ -681,7 +891,7 @@ fn enum_metadata(cx: &mut CrateContext,
             let name: &str = cx.sess.str_of(v.name);
             let discriminant_value = v.disr_val as c_ulonglong;
 
-            do name.to_c_str().with_ref |name| {
+            do name.with_c_str |name| {
                 unsafe {
                     llvm::LLVMDIBuilderCreateEnumerator(
                         DIB(cx),
@@ -695,7 +905,7 @@ fn enum_metadata(cx: &mut CrateContext,
     let loc = span_start(cx, span);
     let file_metadata = file_metadata(cx, loc.file.name);
 
-    let discriminant_type_metadata = do enum_name.to_c_str().with_ref |enum_name| {
+    let discriminant_type_metadata = do enum_name.with_c_str |enum_name| {
         unsafe {
             llvm::LLVMDIBuilderCreateEnumerationType(
                 DIB(cx),
@@ -732,7 +942,7 @@ fn enum_metadata(cx: &mut CrateContext,
                         Some(discriminant_type_metadata),
                         span);
 
-                    do "".to_c_str().with_ref |name| {
+                    do "".with_c_str |name| {
                         unsafe {
                             llvm::LLVMDIBuilderCreateMemberType(
                                 DIB(cx),
@@ -752,7 +962,7 @@ fn enum_metadata(cx: &mut CrateContext,
             let enum_llvm_type = type_of::type_of(cx, enum_type);
             let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_type);
 
-            return do enum_name.to_c_str().with_ref |enum_name| {
+            return do enum_name.with_c_str |enum_name| {
                 unsafe {
                     llvm::LLVMDIBuilderCreateUnionType(
                     DIB(cx),
@@ -836,7 +1046,7 @@ fn composite_type_metadata(cx: &mut CrateContext,
             let member_offset = machine::llelement_offset(cx, composite_llvm_type, i);
             let member_name: &str = member_names[i];
 
-            do member_name.to_c_str().with_ref |member_name| {
+            do member_name.with_c_str |member_name| {
                 unsafe {
                     llvm::LLVMDIBuilderCreateMemberType(
                         DIB(cx),
@@ -854,7 +1064,7 @@ fn composite_type_metadata(cx: &mut CrateContext,
         })
         .collect();
 
-    return do composite_type_name.to_c_str().with_ref |name| {
+    return do composite_type_name.with_c_str |name| {
         unsafe {
             llvm::LLVMDIBuilderCreateStructType(
                 DIB(cx),
@@ -1080,7 +1290,7 @@ fn unimplemented_type_metadata(cx: &mut CrateContext, t: ty::t) -> DIType {
     debug!("unimplemented_type_metadata: %?", ty::get(t));
 
     let name = ty_to_str(cx.tcx, t);
-    let metadata = do fmt!("NYI<%s>", name).to_c_str().with_ref |name| {
+    let metadata = do fmt!("NYI<%s>", name).with_c_str |name| {
         unsafe {
             llvm::LLVMDIBuilderCreateBasicType(
                 DIB(cx),
@@ -1271,6 +1481,13 @@ fn DIB(cx: &CrateContext) -> DIBuilderRef {
     cx.dbg_cx.get_ref().builder
 }
 
+fn assert_fcx_has_span(fcx: &FunctionContext) {
+    if fcx.span.is_none() {
+        fcx.ccx.sess.bug(fmt!("debuginfo: Encountered function %s with invalid source span. \
+            This function should have been ignored by debuginfo generation.",
+            ast_map::path_to_str(fcx.path, fcx.ccx.sess.intr())));
+    }
+}
 
 // This procedure builds the *scope map* for a given function, which maps any given ast::NodeId in
 // the function's AST to the correct DIScope metadata instance.
index 2a63ce976b6db273e9e1c7a1494b2f71189aaf42..2ce8756848fa818b710307d5ece1e98a99d3cd3a 100644 (file)
@@ -290,7 +290,7 @@ fn add_env(bcx: @mut Block, expr: &ast::expr, datum: Datum) -> DatumBlock {
         assert_eq!(datum.appropriate_mode(tcx), ByValue);
         Store(bcx, datum.to_appropriate_llval(bcx), llfn);
         let llenv = GEPi(bcx, scratch.val, [0u, abi::fn_field_box]);
-        Store(bcx, base::null_env_ptr(bcx), llenv);
+        Store(bcx, base::null_env_ptr(bcx.ccx()), llenv);
         DatumBlock {bcx: bcx, datum: scratch}
     }
 
@@ -416,7 +416,7 @@ pub fn trans_into(bcx: @mut Block, expr: @ast::expr, dest: Dest) -> @mut Block {
     debuginfo::update_source_pos(bcx.fcx, expr.id, expr.span);
 
     let dest = {
-        if ty::type_is_nil(ty) || ty::type_is_bot(ty) {
+        if ty::type_is_voidish(ty) {
             Ignore
         } else {
             dest
@@ -507,7 +507,7 @@ fn trans_to_datum_unadjusted(bcx: @mut Block, expr: @ast::expr) -> DatumBlock {
 
         ty::RvalueDpsExpr => {
             let ty = expr_ty(bcx, expr);
-            if ty::type_is_nil(ty) || ty::type_is_bot(ty) {
+            if ty::type_is_voidish(ty) {
                 bcx = trans_rvalue_dps_unadjusted(bcx, expr, Ignore);
                 return nil(bcx, ty);
             } else {
@@ -1030,7 +1030,7 @@ fn get_val(bcx: @mut Block, did: ast::def_id, const_ty: ty::t)
                             let symbol = csearch::get_symbol(
                                 bcx.ccx().sess.cstore,
                                 did);
-                            let llval = do symbol.to_c_str().with_ref |buf| {
+                            let llval = do symbol.with_c_str |buf| {
                                 llvm::LLVMAddGlobal(bcx.ccx().llmod,
                                                     llty.to_ref(),
                                                     buf)
index 7694f690286b77c7c83edb15f3c56fbcc9144b0b..5586f1183ef87257539f97f63d1f9ec98f0489cc 100644 (file)
 // except according to those terms.
 
 
-use back::{link, abi};
-use lib::llvm::{Pointer, ValueRef};
+use back::{link};
+use std::libc::c_uint;
+use lib::llvm::{ValueRef, Attribute, CallConv};
+use lib::llvm::llvm;
 use lib;
-use middle::trans::base::*;
+use middle::trans::machine;
+use middle::trans::base;
+use middle::trans::base::push_ctxt;
 use middle::trans::cabi;
-use middle::trans::cabi_x86;
-use middle::trans::cabi_x86_64;
-use middle::trans::cabi_arm;
-use middle::trans::cabi_mips;
 use middle::trans::build::*;
-use middle::trans::callee::*;
+use middle::trans::builder::noname;
 use middle::trans::common::*;
-use middle::trans::datum::*;
-use middle::trans::expr::Ignore;
-use middle::trans::machine::llsize_of;
-use middle::trans::glue;
-use middle::trans::machine;
 use middle::trans::type_of::*;
 use middle::trans::type_of;
 use middle::ty;
 use middle::ty::FnSig;
-use util::ppaux::ty_to_str;
 
-use std::cell::Cell;
+use std::uint;
 use std::vec;
 use syntax::codemap::span;
-use syntax::{ast, ast_util};
+use syntax::{ast};
 use syntax::{attr, ast_map};
-use syntax::opt_vec;
 use syntax::parse::token::special_idents;
-use syntax::parse::token;
-use syntax::abi::{X86, X86_64, Arm, Mips};
 use syntax::abi::{RustIntrinsic, Rust, Stdcall, Fastcall,
-                  Cdecl, Aapcs, C};
+                  Cdecl, Aapcs, C, AbiSet};
+use util::ppaux::{Repr, UserString};
 use middle::trans::type_::Type;
 
-fn abi_info(ccx: @mut CrateContext) -> @cabi::ABIInfo {
-    return match ccx.sess.targ_cfg.arch {
-        X86 => cabi_x86::abi_info(ccx),
-        X86_64 => cabi_x86_64::abi_info(),
-        Arm => cabi_arm::abi_info(),
-        Mips => cabi_mips::abi_info(),
-    }
-}
-
-pub fn link_name(ccx: &CrateContext, i: &ast::foreign_item) -> @str {
-     match attr::first_attr_value_str_by_name(i.attrs, "link_name") {
-        None => ccx.sess.str_of(i.ident),
-        Some(ln) => ln,
-    }
-}
+///////////////////////////////////////////////////////////////////////////
+// Type definitions
 
-struct ShimTypes {
+struct ForeignTypes {
+    /// Rust signature of the function
     fn_sig: ty::FnSig,
 
+    /// Adapter object for handling native ABI rules (trust me, you
+    /// don't want to know)
+    fn_ty: cabi::FnType,
+
     /// LLVM types that will appear on the foreign function
     llsig: LlvmSignature,
 
     /// True if there is a return value (not bottom, not unit)
     ret_def: bool,
-
-    /// Type of the struct we will use to shuttle values back and forth.
-    /// This is always derived from the llsig.
-    bundle_ty: Type,
-
-    /// Type of the shim function itself.
-    shim_fn_ty: Type,
-
-    /// Adapter object for handling native ABI rules (trust me, you
-    /// don't want to know).
-    fn_ty: cabi::FnType
 }
 
 struct LlvmSignature {
+    // LLVM versions of the types of this function's arguments.
     llarg_tys: ~[Type],
-    llret_ty: Type,
-    sret: bool,
-}
 
-fn foreign_signature(ccx: &mut CrateContext, fn_sig: &ty::FnSig)
-                     -> LlvmSignature {
-    /*!
-     * The ForeignSignature is the LLVM types of the arguments/return type
-     * of a function.  Note that these LLVM types are not quite the same
-     * as the LLVM types would be for a native Rust function because foreign
-     * functions just plain ignore modes.  They also don't pass aggregate
-     * values by pointer like we do.
-     */
+    // LLVM version of the type that this function returns.  Note that
+    // this *may not be* the declared return type of the foreign
+    // function, because the foreign function may opt to return via an
+    // out pointer.
+    llret_ty: Type,
 
-    let llarg_tys = fn_sig.inputs.map(|arg_ty| type_of(ccx, *arg_ty));
-    let llret_ty = type_of::type_of(ccx, fn_sig.output);
-    LlvmSignature {
-        llarg_tys: llarg_tys,
-        llret_ty: llret_ty,
-        sret: !ty::type_is_immediate(ccx.tcx, fn_sig.output),
-    }
+    // True if *Rust* would use an outpointer for this function.
+    sret: bool,
 }
 
-fn shim_types(ccx: @mut CrateContext, id: ast::NodeId) -> ShimTypes {
-    let fn_sig = match ty::get(ty::node_id_to_type(ccx.tcx, id)).sty {
-        ty::ty_bare_fn(ref fn_ty) => fn_ty.sig.clone(),
-        _ => ccx.sess.bug("c_arg_and_ret_lltys called on non-function type")
-    };
-    let llsig = foreign_signature(ccx, &fn_sig);
-    let bundle_ty = Type::struct_(llsig.llarg_tys + &[llsig.llret_ty.ptr_to()], false);
-    let ret_def = !ty::type_is_bot(fn_sig.output) &&
-                  !ty::type_is_nil(fn_sig.output);
-    let fn_ty = abi_info(ccx).compute_info(llsig.llarg_tys, llsig.llret_ty, ret_def);
-    ShimTypes {
-        fn_sig: fn_sig,
-        llsig: llsig,
-        ret_def: ret_def,
-        bundle_ty: bundle_ty,
-        shim_fn_ty: Type::func([bundle_ty.ptr_to()], &Type::void()),
-        fn_ty: fn_ty
-    }
-}
 
-type shim_arg_builder<'self> =
-    &'self fn(bcx: @mut Block, tys: &ShimTypes,
-              llargbundle: ValueRef) -> ~[ValueRef];
-
-type shim_ret_builder<'self> =
-    &'self fn(bcx: @mut Block, tys: &ShimTypes,
-              llargbundle: ValueRef,
-              llretval: ValueRef);
-
-fn build_shim_fn_(ccx: @mut CrateContext,
-                  shim_name: &str,
-                  llbasefn: ValueRef,
-                  tys: &ShimTypes,
-                  cc: lib::llvm::CallConv,
-                  arg_builder: shim_arg_builder,
-                  ret_builder: shim_ret_builder)
-               -> ValueRef {
-    let llshimfn = decl_internal_cdecl_fn(
-        ccx.llmod, shim_name, tys.shim_fn_ty);
-
-    // Declare the body of the shim function:
-    let fcx = new_fn_ctxt(ccx, ~[], llshimfn, tys.fn_sig.output, None);
-    let bcx = fcx.entry_bcx.unwrap();
-
-    let llargbundle = get_param(llshimfn, 0u);
-    let llargvals = arg_builder(bcx, tys, llargbundle);
-
-    // Create the call itself and store the return value:
-    let llretval = CallWithConv(bcx, llbasefn, llargvals, cc);
-
-    ret_builder(bcx, tys, llargbundle, llretval);
-
-    // Don't finish up the function in the usual way, because this doesn't
-    // follow the normal Rust calling conventions.
-    let ret_cx = match fcx.llreturn {
-        Some(llreturn) => raw_block(fcx, false, llreturn),
-        None => bcx
-    };
-    RetVoid(ret_cx);
-    fcx.cleanup();
+///////////////////////////////////////////////////////////////////////////
+// Calls to external functions
 
-    return llshimfn;
-}
+fn llvm_calling_convention(ccx: @mut CrateContext,
+                           abis: AbiSet)
+                           -> Option<CallConv> {
+    let arch = ccx.sess.targ_cfg.arch;
+    abis.for_arch(arch).map(|abi| {
+        match *abi {
+            RustIntrinsic => {
+                // Intrinsics are emitted by monomorphic fn
+                ccx.sess.bug(fmt!("Asked to register intrinsic fn"));
+            }
 
-type wrap_arg_builder<'self> = &'self fn(bcx: @mut Block,
-                                         tys: &ShimTypes,
-                                         llwrapfn: ValueRef,
-                                         llargbundle: ValueRef);
-
-type wrap_ret_builder<'self> = &'self fn(bcx: @mut Block,
-                                         tys: &ShimTypes,
-                                         llargbundle: ValueRef);
-
-fn build_wrap_fn_(ccx: @mut CrateContext,
-                  tys: &ShimTypes,
-                  llshimfn: ValueRef,
-                  llwrapfn: ValueRef,
-                  shim_upcall: ValueRef,
-                  needs_c_return: bool,
-                  arg_builder: wrap_arg_builder,
-                  ret_builder: wrap_ret_builder) {
-    let _icx = push_ctxt("foreign::build_wrap_fn_");
-    let fcx = new_fn_ctxt(ccx, ~[], llwrapfn, tys.fn_sig.output, None);
-    let bcx = fcx.entry_bcx.unwrap();
-
-    // Patch up the return type if it's not immediate and we're returning via
-    // the C ABI.
-    if needs_c_return && !ty::type_is_immediate(ccx.tcx, tys.fn_sig.output) {
-        let lloutputtype = type_of::type_of(fcx.ccx, tys.fn_sig.output);
-        fcx.llretptr = Some(alloca(bcx, lloutputtype, ""));
-    }
+            Rust => {
+                // FIXME(#3678) Implement linking to foreign fns with Rust ABI
+                ccx.sess.unimpl(
+                    fmt!("Foreign functions with Rust ABI"));
+            }
 
-    // Allocate the struct and write the arguments into it.
-    let llargbundle = alloca(bcx, tys.bundle_ty, "__llargbundle");
-    arg_builder(bcx, tys, llwrapfn, llargbundle);
+            Stdcall => lib::llvm::X86StdcallCallConv,
+            Fastcall => lib::llvm::X86FastcallCallConv,
+            C => lib::llvm::CCallConv,
 
-    // Create call itself.
-    let llshimfnptr = PointerCast(bcx, llshimfn, Type::i8p());
-    let llrawargbundle = PointerCast(bcx, llargbundle, Type::i8p());
-    Call(bcx, shim_upcall, [llrawargbundle, llshimfnptr]);
-    ret_builder(bcx, tys, llargbundle);
+            // NOTE These API constants ought to be more specific
+            Cdecl => lib::llvm::CCallConv,
+            Aapcs => lib::llvm::CCallConv,
+        }
+    })
+}
 
-    // Then return according to the C ABI.
-    let return_context = match fcx.llreturn {
-        Some(llreturn) => raw_block(fcx, false, llreturn),
-        None => bcx
-    };
 
-    let llfunctiontype = val_ty(llwrapfn);
-    let llfunctiontype = llfunctiontype.element_type();
-    let return_type = llfunctiontype.return_type();
-    if return_type.kind() == ::lib::llvm::Void {
-        // XXX: This might be wrong if there are any functions for which
-        // the C ABI specifies a void output pointer and the Rust ABI
-        // does not.
-        RetVoid(return_context);
-    } else {
-        // Cast if we have to...
-        // XXX: This is ugly.
-        let llretptr = BitCast(return_context, fcx.llretptr.unwrap(), return_type.ptr_to());
-        Ret(return_context, Load(return_context, llretptr));
-    }
-    fcx.cleanup();
-}
+pub fn register_foreign_item_fn(ccx: @mut CrateContext,
+                                abis: AbiSet,
+                                path: &ast_map::path,
+                                foreign_item: @ast::foreign_item) -> ValueRef {
+    /*!
+     * Registers a foreign function found in a library.
+     * Just adds a LLVM global.
+     */
 
-// For each foreign function F, we generate a wrapper function W and a shim
-// function S that all work together.  The wrapper function W is the function
-// that other rust code actually invokes.  Its job is to marshall the
-// arguments into a struct.  It then uses a small bit of assembly to switch
-// over to the C stack and invoke the shim function.  The shim function S then
-// unpacks the arguments from the struct and invokes the actual function F
-// according to its specified calling convention.
-//
-// Example: Given a foreign c-stack function F(x: X, y: Y) -> Z,
-// we generate a wrapper function W that looks like:
-//
-//    void W(Z* dest, void *env, X x, Y y) {
-//        struct { X x; Y y; Z *z; } args = { x, y, z };
-//        call_on_c_stack_shim(S, &args);
-//    }
-//
-// The shim function S then looks something like:
-//
-//     void S(struct { X x; Y y; Z *z; } *args) {
-//         *args->z = F(args->x, args->y);
-//     }
-//
-// However, if the return type of F is dynamically sized or of aggregate type,
-// the shim function looks like:
-//
-//     void S(struct { X x; Y y; Z *z; } *args) {
-//         F(args->z, args->x, args->y);
-//     }
-//
-// Note: on i386, the layout of the args struct is generally the same
-// as the desired layout of the arguments on the C stack.  Therefore,
-// we could use upcall_alloc_c_stack() to allocate the `args`
-// structure and switch the stack pointer appropriately to avoid a
-// round of copies.  (In fact, the shim function itself is
-// unnecessary). We used to do this, in fact, and will perhaps do so
-// in the future.
-pub fn trans_foreign_mod(ccx: @mut CrateContext,
-                         path: &ast_map::path,
-                         foreign_mod: &ast::foreign_mod) {
-    let _icx = push_ctxt("foreign::trans_foreign_mod");
+    debug!("register_foreign_item_fn(abis=%s, \
+            path=%s, \
+            foreign_item.id=%?)",
+           abis.repr(ccx.tcx),
+           path.repr(ccx.tcx),
+           foreign_item.id);
 
-    let arch = ccx.sess.targ_cfg.arch;
-    let abi = match foreign_mod.abis.for_arch(arch) {
+    let cc = match llvm_calling_convention(ccx, abis) {
+        Some(cc) => cc,
         None => {
+            // FIXME(#8357) We really ought to report a span here
             ccx.sess.fatal(
-                fmt!("No suitable ABI for target architecture \
+                fmt!("ABI `%s` has no suitable ABI \
+                      for target architecture \
                       in module %s",
+                     abis.user_string(ccx.tcx),
                      ast_map::path_to_str(*path,
                                           ccx.sess.intr())));
         }
-
-        Some(abi) => abi,
     };
 
-    for &foreign_item in foreign_mod.items.iter() {
-        match foreign_item.node {
-            ast::foreign_item_fn(*) => {
-                let id = foreign_item.id;
-                match abi {
-                    RustIntrinsic => {
-                        // Intrinsics are emitted by monomorphic fn
-                    }
-
-                    Rust => {
-                        // FIXME(#3678) Implement linking to foreign fns with Rust ABI
-                        ccx.sess.unimpl(
-                            fmt!("Foreign functions with Rust ABI"));
-                    }
-
-                    Stdcall => {
-                        build_foreign_fn(ccx, id, foreign_item,
-                                         lib::llvm::X86StdcallCallConv);
-                    }
-
-                    Fastcall => {
-                        build_foreign_fn(ccx, id, foreign_item,
-                                         lib::llvm::X86FastcallCallConv);
-                    }
-
-                    Cdecl => {
-                        // FIXME(#3678) should really be more specific
-                        build_foreign_fn(ccx, id, foreign_item,
-                                         lib::llvm::CCallConv);
-                    }
-
-                    Aapcs => {
-                        // FIXME(#3678) should really be more specific
-                        build_foreign_fn(ccx, id, foreign_item,
-                                         lib::llvm::CCallConv);
-                    }
-
-                    C => {
-                        build_foreign_fn(ccx, id, foreign_item,
-                                         lib::llvm::CCallConv);
-                    }
-                }
-            }
-            ast::foreign_item_static(*) => {
-                let ident = token::ident_to_str(&foreign_item.ident);
-                ccx.item_symbols.insert(foreign_item.id, /* bad */ident.to_owned());
-            }
-        }
-    }
+    // Register the function as a C extern fn
+    let lname = link_name(ccx, foreign_item);
+    let tys = foreign_types_for_id(ccx, foreign_item.id);
 
-    fn build_foreign_fn(ccx: @mut CrateContext,
-                        id: ast::NodeId,
-                        foreign_item: @ast::foreign_item,
-                        cc: lib::llvm::CallConv) {
-        let llwrapfn = get_item_val(ccx, id);
-        let tys = shim_types(ccx, id);
-        if attr::contains_name(foreign_item.attrs, "rust_stack") {
-            build_direct_fn(ccx, llwrapfn, foreign_item,
-                            &tys, cc);
-        } else if attr::contains_name(foreign_item.attrs, "fast_ffi") {
-            build_fast_ffi_fn(ccx, llwrapfn, foreign_item, &tys, cc);
-        } else {
-            let llshimfn = build_shim_fn(ccx, foreign_item, &tys, cc);
-            build_wrap_fn(ccx, &tys, llshimfn, llwrapfn);
-        }
-    }
+    // Create the LLVM value for the C extern fn
+    let llfn_ty = lltype_for_fn_from_foreign_types(&tys);
+    let llfn = base::get_extern_fn(&mut ccx.externs, ccx.llmod,
+                                   lname, cc, llfn_ty);
+    add_argument_attributes(&tys, llfn);
 
-    fn build_shim_fn(ccx: @mut CrateContext,
-                     foreign_item: &ast::foreign_item,
-                     tys: &ShimTypes,
-                     cc: lib::llvm::CallConv)
-                  -> ValueRef {
-        /*!
-         *
-         * Build S, from comment above:
-         *
-         *     void S(struct { X x; Y y; Z *z; } *args) {
-         *         F(args->z, args->x, args->y);
-         *     }
-         */
-
-        let _icx = push_ctxt("foreign::build_shim_fn");
-
-        fn build_args(bcx: @mut Block, tys: &ShimTypes, llargbundle: ValueRef)
-                   -> ~[ValueRef] {
-            let _icx = push_ctxt("foreign::shim::build_args");
-            tys.fn_ty.build_shim_args(bcx, tys.llsig.llarg_tys, llargbundle)
-        }
+    return llfn;
+}
 
-        fn build_ret(bcx: @mut Block,
-                     tys: &ShimTypes,
-                     llargbundle: ValueRef,
-                     llretval: ValueRef) {
-            let _icx = push_ctxt("foreign::shim::build_ret");
-            tys.fn_ty.build_shim_ret(bcx,
-                                     tys.llsig.llarg_tys,
-                                     tys.ret_def,
-                                     llargbundle,
-                                     llretval);
-        }
+pub fn trans_native_call(bcx: @mut Block,
+                         callee_ty: ty::t,
+                         llfn: ValueRef,
+                         llretptr: ValueRef,
+                         llargs_rust: &[ValueRef]) -> @mut Block {
+    /*!
+     * Prepares a call to a native function. This requires adapting
+     * from the Rust argument passing rules to the native rules.
+     *
+     * # Parameters
+     *
+     * - `callee_ty`: Rust type for the function we are calling
+     * - `llfn`: the function pointer we are calling
+     * - `llretptr`: where to store the return value of the function
+     * - `llargs_rust`: a list of the argument values, prepared
+     *   as they would be if calling a Rust function
+     */
 
-        let lname = link_name(ccx, foreign_item);
-        let llbasefn = base_fn(ccx, lname, tys, cc);
-        // Name the shim function
-        let shim_name = fmt!("%s__c_stack_shim", lname);
-        build_shim_fn_(ccx,
-                       shim_name,
-                       llbasefn,
-                       tys,
-                       cc,
-                       build_args,
-                       build_ret)
-    }
+    let ccx = bcx.ccx();
+    let tcx = bcx.tcx();
 
-    fn base_fn(ccx: &CrateContext,
-               lname: &str,
-               tys: &ShimTypes,
-               cc: lib::llvm::CallConv)
-               -> ValueRef {
-        // Declare the "prototype" for the base function F:
-        do tys.fn_ty.decl_fn |fnty| {
-            decl_fn(ccx.llmod, lname, cc, fnty)
-        }
-    }
+    debug!("trans_native_call(callee_ty=%s, \
+            llfn=%s, \
+            llretptr=%s)",
+           callee_ty.repr(tcx),
+           ccx.tn.val_to_str(llfn),
+           ccx.tn.val_to_str(llretptr));
 
-    // FIXME (#2535): this is very shaky and probably gets ABIs wrong all
-    // over the place
-    fn build_direct_fn(ccx: @mut CrateContext,
-                       decl: ValueRef,
-                       item: &ast::foreign_item,
-                       tys: &ShimTypes,
-                       cc: lib::llvm::CallConv) {
-        debug!("build_direct_fn(%s)", link_name(ccx, item));
-
-        let fcx = new_fn_ctxt(ccx, ~[], decl, tys.fn_sig.output, None);
-        let bcx = fcx.entry_bcx.unwrap();
-        let llbasefn = base_fn(ccx, link_name(ccx, item), tys, cc);
-        let ty = ty::lookup_item_type(ccx.tcx,
-                                      ast_util::local_def(item.id)).ty;
-        let ret_ty = ty::ty_fn_ret(ty);
-        let args = vec::from_fn(ty::ty_fn_args(ty).len(), |i| {
-            get_param(decl, fcx.arg_pos(i))
-        });
-        let retval = Call(bcx, llbasefn, args);
-        if !ty::type_is_nil(ret_ty) && !ty::type_is_bot(ret_ty) {
-            Store(bcx, retval, fcx.llretptr.unwrap());
+    let (fn_abis, fn_sig) = match ty::get(callee_ty).sty {
+        ty::ty_bare_fn(ref fn_ty) => (fn_ty.abis, fn_ty.sig.clone()),
+        _ => ccx.sess.bug("trans_native_call called on non-function type")
+    };
+    let llsig = foreign_signature(ccx, &fn_sig);
+    let ret_def = !ty::type_is_voidish(fn_sig.output);
+    let fn_type = cabi::compute_abi_info(ccx,
+                                         llsig.llarg_tys,
+                                         llsig.llret_ty,
+                                         ret_def);
+
+    let all_arg_tys: &[cabi::LLVMType] = fn_type.arg_tys;
+    let all_attributes: &[Option<Attribute>] = fn_type.attrs;
+
+    let mut llargs_foreign = ~[];
+
+    // If the foreign ABI expects return value by pointer, supply the
+    // pointer that Rust gave us. Sometimes we have to bitcast
+    // because foreign fns return slightly different (but equivalent)
+    // views on the same type (e.g., i64 in place of {i32,i32}).
+    let (arg_tys, attributes) = {
+        if fn_type.sret {
+            if all_arg_tys[0].cast {
+                let llcastedretptr =
+                    BitCast(bcx, llretptr, all_arg_tys[0].ty.ptr_to());
+                llargs_foreign.push(llcastedretptr);
+            } else {
+                llargs_foreign.push(llretptr);
+            }
+            (all_arg_tys.tail(), all_attributes.tail())
+        } else {
+            (all_arg_tys, all_attributes)
         }
-        finish_fn(fcx, bcx);
-    }
+    };
 
-    // FIXME (#2535): this is very shaky and probably gets ABIs wrong all
-    // over the place
-    fn build_fast_ffi_fn(ccx: @mut CrateContext,
-                         decl: ValueRef,
-                         item: &ast::foreign_item,
-                         tys: &ShimTypes,
-                         cc: lib::llvm::CallConv) {
-        debug!("build_fast_ffi_fn(%s)", link_name(ccx, item));
-
-        let fcx = new_fn_ctxt(ccx, ~[], decl, tys.fn_sig.output, None);
-        let bcx = fcx.entry_bcx.unwrap();
-        let llbasefn = base_fn(ccx, link_name(ccx, item), tys, cc);
-        set_no_inline(fcx.llfn);
-        set_fixed_stack_segment(fcx.llfn);
-        let ty = ty::lookup_item_type(ccx.tcx,
-                                      ast_util::local_def(item.id)).ty;
-        let ret_ty = ty::ty_fn_ret(ty);
-        let args = vec::from_fn(ty::ty_fn_args(ty).len(), |i| {
-            get_param(decl, fcx.arg_pos(i))
-        });
-        let retval = Call(bcx, llbasefn, args);
-        if !ty::type_is_nil(ret_ty) && !ty::type_is_bot(ret_ty) {
-            Store(bcx, retval, fcx.llretptr.unwrap());
-        }
-        finish_fn(fcx, bcx);
-    }
+    for (i, &llarg_rust) in llargs_rust.iter().enumerate() {
+        let mut llarg_rust = llarg_rust;
 
-    fn build_wrap_fn(ccx: @mut CrateContext,
-                     tys: &ShimTypes,
-                     llshimfn: ValueRef,
-                     llwrapfn: ValueRef) {
-        /*!
-         *
-         * Build W, from comment above:
-         *
-         *     void W(Z* dest, void *env, X x, Y y) {
-         *         struct { X x; Y y; Z *z; } args = { x, y, z };
-         *         call_on_c_stack_shim(S, &args);
-         *     }
-         *
-         * One thing we have to be very careful of is to
-         * account for the Rust modes.
-         */
-
-        let _icx = push_ctxt("foreign::build_wrap_fn");
-
-        build_wrap_fn_(ccx,
-                       tys,
-                       llshimfn,
-                       llwrapfn,
-                       ccx.upcalls.call_shim_on_c_stack,
-                       false,
-                       build_args,
-                       build_ret);
-
-        fn build_args(bcx: @mut Block,
-                      tys: &ShimTypes,
-                      llwrapfn: ValueRef,
-                      llargbundle: ValueRef) {
-            let _icx = push_ctxt("foreign::wrap::build_args");
-            let ccx = bcx.ccx();
-            let n = tys.llsig.llarg_tys.len();
-            for i in range(0u, n) {
-                let arg_i = bcx.fcx.arg_pos(i);
-                let mut llargval = get_param(llwrapfn, arg_i);
-
-                // In some cases, Rust will pass a pointer which the
-                // native C type doesn't have.  In that case, just
-                // load the value from the pointer.
-                if type_of::arg_is_indirect(ccx, &tys.fn_sig.inputs[i]) {
-                    llargval = Load(bcx, llargval);
-                }
+        // Does Rust pass this argument by pointer?
+        let rust_indirect = type_of::arg_is_indirect(ccx, fn_sig.inputs[i]);
 
-                store_inbounds(bcx, llargval, llargbundle, [0u, i]);
-            }
+        debug!("argument %u, llarg_rust=%s, rust_indirect=%b, arg_ty=%s",
+               i,
+               ccx.tn.val_to_str(llarg_rust),
+               rust_indirect,
+               ccx.tn.type_to_str(arg_tys[i].ty));
 
-            for &retptr in bcx.fcx.llretptr.iter() {
-                store_inbounds(bcx, retptr, llargbundle, [0u, n]);
-            }
+        // Ensure that we always have the Rust value indirectly,
+        // because it makes bitcasting easier.
+        if !rust_indirect {
+            let scratch = base::alloca(bcx, arg_tys[i].ty, "__arg");
+            Store(bcx, llarg_rust, scratch);
+            llarg_rust = scratch;
         }
 
-        fn build_ret(bcx: @mut Block,
-                     shim_types: &ShimTypes,
-                     llargbundle: ValueRef) {
-            let _icx = push_ctxt("foreign::wrap::build_ret");
-            let arg_count = shim_types.fn_sig.inputs.len();
-            for &retptr in bcx.fcx.llretptr.iter() {
-                let llretptr = load_inbounds(bcx, llargbundle, [0, arg_count]);
-                Store(bcx, Load(bcx, llretptr), retptr);
-            }
-        }
-    }
-}
+        debug!("llarg_rust=%s (after indirection)",
+               ccx.tn.val_to_str(llarg_rust));
 
-pub fn trans_intrinsic(ccx: @mut CrateContext,
-                       decl: ValueRef,
-                       item: &ast::foreign_item,
-                       path: ast_map::path,
-                       substs: @param_substs,
-                       attributes: &[ast::Attribute],
-                       ref_id: Option<ast::NodeId>) {
-    debug!("trans_intrinsic(item.ident=%s)", ccx.sess.str_of(item.ident));
-
-    fn simple_llvm_intrinsic(bcx: @mut Block, name: &'static str, num_args: uint) {
-        assert!(num_args <= 4);
-        let mut args = [0 as ValueRef, ..4];
-        let first_real_arg = bcx.fcx.arg_pos(0u);
-        for i in range(0u, num_args) {
-            args[i] = get_param(bcx.fcx.llfn, first_real_arg + i);
+        // Check whether we need to do any casting
+        let foreignarg_ty = arg_tys[i].ty;
+        if arg_tys[i].cast {
+            llarg_rust = BitCast(bcx, llarg_rust, foreignarg_ty.ptr_to());
         }
-        let llfn = bcx.ccx().intrinsics.get_copy(&name);
-        Ret(bcx, Call(bcx, llfn, args.slice(0, num_args)));
-    }
-
-    fn with_overflow_instrinsic(bcx: @mut Block, name: &'static str) {
-        let first_real_arg = bcx.fcx.arg_pos(0u);
-        let a = get_param(bcx.fcx.llfn, first_real_arg);
-        let b = get_param(bcx.fcx.llfn, first_real_arg + 1);
-        let llfn = bcx.ccx().intrinsics.get_copy(&name);
-
-        // convert `i1` to a `bool`, and write to the out parameter
-        let val = Call(bcx, llfn, [a, b]);
-        let result = ExtractValue(bcx, val, 0);
-        let overflow = ZExt(bcx, ExtractValue(bcx, val, 1), Type::bool());
-        let retptr = get_param(bcx.fcx.llfn, bcx.fcx.out_arg_pos());
-        let ret = Load(bcx, retptr);
-        let ret = InsertValue(bcx, ret, result, 0);
-        let ret = InsertValue(bcx, ret, overflow, 1);
-        Store(bcx, ret, retptr);
-        RetVoid(bcx)
-    }
 
-    fn memcpy_intrinsic(bcx: @mut Block, name: &'static str, tp_ty: ty::t, sizebits: u8) {
-        let ccx = bcx.ccx();
-        let lltp_ty = type_of::type_of(ccx, tp_ty);
-        let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32);
-        let size = match sizebits {
-            32 => C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32),
-            64 => C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64),
-            _ => ccx.sess.fatal("Invalid value for sizebits")
-        };
+        debug!("llarg_rust=%s (after casting)",
+               ccx.tn.val_to_str(llarg_rust));
 
-        let decl = bcx.fcx.llfn;
-        let first_real_arg = bcx.fcx.arg_pos(0u);
-        let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p());
-        let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p());
-        let count = get_param(decl, first_real_arg + 2);
-        let volatile = C_i1(false);
-        let llfn = bcx.ccx().intrinsics.get_copy(&name);
-        Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]);
-        RetVoid(bcx);
-    }
-
-    fn memset_intrinsic(bcx: @mut Block, name: &'static str, tp_ty: ty::t, sizebits: u8) {
-        let ccx = bcx.ccx();
-        let lltp_ty = type_of::type_of(ccx, tp_ty);
-        let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32);
-        let size = match sizebits {
-            32 => C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32),
-            64 => C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64),
-            _ => ccx.sess.fatal("Invalid value for sizebits")
+        // Finally, load the value if needed for the foreign ABI
+        let foreign_indirect = attributes[i].is_some();
+        let llarg_foreign = if foreign_indirect {
+            llarg_rust
+        } else {
+            Load(bcx, llarg_rust)
         };
 
-        let decl = bcx.fcx.llfn;
-        let first_real_arg = bcx.fcx.arg_pos(0u);
-        let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p());
-        let val = get_param(decl, first_real_arg + 1);
-        let count = get_param(decl, first_real_arg + 2);
-        let volatile = C_i1(false);
-        let llfn = bcx.ccx().intrinsics.get_copy(&name);
-        Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile]);
-        RetVoid(bcx);
-    }
+        debug!("argument %u, llarg_foreign=%s",
+               i, ccx.tn.val_to_str(llarg_foreign));
 
-    fn count_zeros_intrinsic(bcx: @mut Block, name: &'static str) {
-        let x = get_param(bcx.fcx.llfn, bcx.fcx.arg_pos(0u));
-        let y = C_i1(false);
-        let llfn = bcx.ccx().intrinsics.get_copy(&name);
-        Ret(bcx, Call(bcx, llfn, [x, y]));
+        llargs_foreign.push(llarg_foreign);
     }
 
-    let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, item.id));
-
-    let fcx = new_fn_ctxt_w_id(ccx,
-                               path,
-                               decl,
-                               item.id,
-                               output_type,
-                               true,
-                               Some(substs),
-                               None,
-                               Some(item.span));
-
-    set_always_inline(fcx.llfn);
+    let cc = match llvm_calling_convention(ccx, fn_abis) {
+        Some(cc) => cc,
+        None => {
+            // FIXME(#8357) We really ought to report a span here
+            ccx.sess.fatal(
+                fmt!("ABI string `%s` has no suitable ABI \
+                      for target architecture",
+                     fn_abis.user_string(ccx.tcx)));
+        }
+    };
 
-    // Set the fixed stack segment flag if necessary.
-    if attr::contains_name(attributes, "fixed_stack_segment") {
-        set_fixed_stack_segment(fcx.llfn);
-    }
+    let llforeign_retval = CallWithConv(bcx, llfn, llargs_foreign, cc);
 
-    let mut bcx = fcx.entry_bcx.unwrap();
-    let first_real_arg = fcx.arg_pos(0u);
+    // If the function we just called does not use an outpointer,
+    // store the result into the rust outpointer. Cast the outpointer
+    // type to match because some ABIs will use a different type than
+    // the Rust type. e.g., a {u32,u32} struct could be returned as
+    // u64.
+    if ret_def && !fn_type.sret {
+        let llrust_ret_ty = llsig.llret_ty;
+        let llforeign_ret_ty = fn_type.ret_ty.ty;
 
-    let nm = ccx.sess.str_of(item.ident);
-    let name = nm.as_slice();
+        debug!("llretptr=%s", ccx.tn.val_to_str(llretptr));
+        debug!("llforeign_retval=%s", ccx.tn.val_to_str(llforeign_retval));
+        debug!("llrust_ret_ty=%s", ccx.tn.type_to_str(llrust_ret_ty));
+        debug!("llforeign_ret_ty=%s", ccx.tn.type_to_str(llforeign_ret_ty));
 
-    // This requires that atomic intrinsics follow a specific naming pattern:
-    // "atomic_<operation>[_<ordering>], and no ordering means SeqCst
-    if name.starts_with("atomic_") {
-        let split : ~[&str] = name.split_iter('_').collect();
-        assert!(split.len() >= 2, "Atomic intrinsic not correct format");
-        let order = if split.len() == 2 {
-            lib::llvm::SequentiallyConsistent
+        if llrust_ret_ty == llforeign_ret_ty {
+            Store(bcx, llforeign_retval, llretptr);
         } else {
-            match split[2] {
-                "relaxed" => lib::llvm::Monotonic,
-                "acq"     => lib::llvm::Acquire,
-                "rel"     => lib::llvm::Release,
-                "acqrel"  => lib::llvm::AcquireRelease,
-                _ => ccx.sess.fatal("Unknown ordering in atomic intrinsic")
-            }
-        };
-
-        match split[1] {
-            "cxchg" => {
-                let old = AtomicCmpXchg(bcx, get_param(decl, first_real_arg),
-                                        get_param(decl, first_real_arg + 1u),
-                                        get_param(decl, first_real_arg + 2u),
-                                        order);
-                Ret(bcx, old);
-            }
-            "load" => {
-                let old = AtomicLoad(bcx, get_param(decl, first_real_arg),
-                                     order);
-                Ret(bcx, old);
-            }
-            "store" => {
-                AtomicStore(bcx, get_param(decl, first_real_arg + 1u),
-                            get_param(decl, first_real_arg),
-                            order);
-                RetVoid(bcx);
-            }
-            "fence" => {
-                AtomicFence(bcx, order);
-                RetVoid(bcx);
-            }
-            op => {
-                // These are all AtomicRMW ops
-                let atom_op = match op {
-                    "xchg"  => lib::llvm::Xchg,
-                    "xadd"  => lib::llvm::Add,
-                    "xsub"  => lib::llvm::Sub,
-                    "and"   => lib::llvm::And,
-                    "nand"  => lib::llvm::Nand,
-                    "or"    => lib::llvm::Or,
-                    "xor"   => lib::llvm::Xor,
-                    "max"   => lib::llvm::Max,
-                    "min"   => lib::llvm::Min,
-                    "umax"  => lib::llvm::UMax,
-                    "umin"  => lib::llvm::UMin,
-                    _ => ccx.sess.fatal("Unknown atomic operation")
-                };
-
-                let old = AtomicRMW(bcx, atom_op, get_param(decl, first_real_arg),
-                                    get_param(decl, first_real_arg + 1u),
-                                    order);
-                Ret(bcx, old);
-            }
+            // The actual return type is a struct, but the ABI
+            // adaptation code has cast it into some scalar type.  The
+            // code that follows is the only reliable way I have
+            // found to do a transform like i64 -> {i32,i32}.
+            // Basically we dump the data onto the stack then memcpy it.
+            //
+            // Other approaches I tried:
+            // - Casting rust ret pointer to the foreign type and using Store
+            //   is (a) unsafe if size of foreign type > size of rust type and
+            //   (b) runs afoul of strict aliasing rules, yielding invalid
+            //   assembly under -O (specifically, the store gets removed).
+            // - Truncating foreign type to correct integral type and then
+            //   bitcasting to the struct type yields invalid cast errors.
+            let llscratch = base::alloca(bcx, llforeign_ret_ty, "__cast");
+            Store(bcx, llforeign_retval, llscratch);
+            let llscratch_i8 = BitCast(bcx, llscratch, Type::i8().ptr_to());
+            let llretptr_i8 = BitCast(bcx, llretptr, Type::i8().ptr_to());
+            let llrust_size = machine::llsize_of_store(ccx, llrust_ret_ty);
+            let llforeign_align = machine::llalign_of_min(ccx, llforeign_ret_ty);
+            let llrust_align = machine::llalign_of_min(ccx, llrust_ret_ty);
+            let llalign = uint::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);
         }
-
-        fcx.cleanup();
-        return;
     }
 
-    match name {
-        "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)));
-        }
-        "move_val" => {
-            // Create a datum reflecting the value being moved.
-            // Use `appropriate_mode` so that the datum is by ref
-            // if the value is non-immediate. Note that, with
-            // intrinsics, there are no argument cleanups to
-            // concern ourselves with.
-            let tp_ty = substs.tys[0];
-            let mode = appropriate_mode(ccx.tcx, tp_ty);
-            let src = Datum {val: get_param(decl, first_real_arg + 1u),
-                             ty: tp_ty, mode: mode};
-            bcx = src.move_to(bcx, DROP_EXISTING,
-                              get_param(decl, first_real_arg));
-            RetVoid(bcx);
-        }
-        "move_val_init" => {
-            // See comments for `"move_val"`.
-            let tp_ty = substs.tys[0];
-            let mode = appropriate_mode(ccx.tcx, tp_ty);
-            let src = Datum {val: get_param(decl, first_real_arg + 1u),
-                             ty: tp_ty, mode: mode};
-            bcx = src.move_to(bcx, INIT, get_param(decl, first_real_arg));
-            RetVoid(bcx);
-        }
-        "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)));
-        }
-        "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)));
-        }
-        "get_tydesc" => {
-            let tp_ty = substs.tys[0];
-            let static_ti = get_tydesc(ccx, tp_ty);
-            glue::lazily_emit_all_tydesc_glue(ccx, static_ti);
-
-            // FIXME (#3730): ideally this shouldn't need a cast,
-            // but there's a circularity between translating rust types to llvm
-            // types and having a tydesc type available. So I can't directly access
-            // the llvm type of intrinsic::TyDesc struct.
-            let userland_tydesc_ty = type_of::type_of(ccx, output_type);
-            let td = PointerCast(bcx, static_ti.tydesc, userland_tydesc_ty);
-            Ret(bcx, td);
-        }
-        "init" => {
-            let tp_ty = substs.tys[0];
-            let lltp_ty = type_of::type_of(ccx, tp_ty);
-            match bcx.fcx.llretptr {
-                Some(ptr) => { Store(bcx, C_null(lltp_ty), ptr); RetVoid(bcx); }
-                None if ty::type_is_nil(tp_ty) => RetVoid(bcx),
-                None => Ret(bcx, C_null(lltp_ty)),
-            }
-        }
-        "uninit" => {
-            // Do nothing, this is effectively a no-op
-            let retty = substs.tys[0];
-            if ty::type_is_immediate(ccx.tcx, retty) && !ty::type_is_nil(retty) {
-                unsafe {
-                    Ret(bcx, lib::llvm::llvm::LLVMGetUndef(type_of(ccx, retty).to_ref()));
-                }
-            } else {
-                RetVoid(bcx)
-            }
-        }
-        "forget" => {
-            RetVoid(bcx);
-        }
-        "transmute" => {
-            let (in_type, out_type) = (substs.tys[0], substs.tys[1]);
-            let llintype = type_of::type_of(ccx, in_type);
-            let llouttype = type_of::type_of(ccx, out_type);
-
-            let in_type_size = machine::llbitsize_of_real(ccx, llintype);
-            let out_type_size = machine::llbitsize_of_real(ccx, llouttype);
-            if in_type_size != out_type_size {
-                let sp = match ccx.tcx.items.get_copy(&ref_id.unwrap()) {
-                    ast_map::node_expr(e) => e.span,
-                    _ => fail!("transmute has non-expr arg"),
-                };
-                let pluralize = |n| if 1u == n { "" } else { "s" };
-                ccx.sess.span_fatal(sp,
-                                    fmt!("transmute called on types with \
-                                          different sizes: %s (%u bit%s) to \
-                                          %s (%u bit%s)",
-                                         ty_to_str(ccx.tcx, in_type),
-                                         in_type_size,
-                                         pluralize(in_type_size),
-                                         ty_to_str(ccx.tcx, out_type),
-                                         out_type_size,
-                                         pluralize(out_type_size)));
-            }
+    return bcx;
+}
 
-            if !ty::type_is_nil(out_type) {
-                let llsrcval = get_param(decl, first_real_arg);
-                if ty::type_is_immediate(ccx.tcx, in_type) {
-                    match fcx.llretptr {
-                        Some(llretptr) => {
-                            Store(bcx, llsrcval, PointerCast(bcx, llretptr, llintype.ptr_to()));
-                            RetVoid(bcx);
-                        }
-                        None => match (llintype.kind(), llouttype.kind()) {
-                            (Pointer, other) | (other, Pointer) if other != Pointer => {
-                                let tmp = Alloca(bcx, llouttype, "");
-                                Store(bcx, llsrcval, PointerCast(bcx, tmp, llintype.ptr_to()));
-                                Ret(bcx, Load(bcx, tmp));
-                            }
-                            _ => Ret(bcx, BitCast(bcx, llsrcval, llouttype))
-                        }
-                    }
-                } else if ty::type_is_immediate(ccx.tcx, out_type) {
-                    let llsrcptr = PointerCast(bcx, llsrcval, llouttype.ptr_to());
-                    Ret(bcx, Load(bcx, llsrcptr));
-                } else {
-                    // NB: Do not use a Load and Store here. This causes massive
-                    // code bloat when `transmute` is used on large structural
-                    // types.
-                    let lldestptr = fcx.llretptr.unwrap();
-                    let lldestptr = PointerCast(bcx, lldestptr, Type::i8p());
-                    let llsrcptr = PointerCast(bcx, llsrcval, Type::i8p());
-
-                    let llsize = llsize_of(ccx, llintype);
-                    call_memcpy(bcx, lldestptr, llsrcptr, llsize, 1);
-                    RetVoid(bcx);
-                };
-            } else {
-                RetVoid(bcx);
-            }
-        }
-        "needs_drop" => {
-            let tp_ty = substs.tys[0];
-            Ret(bcx, C_bool(ty::type_needs_drop(ccx.tcx, tp_ty)));
-        }
-        "contains_managed" => {
-            let tp_ty = substs.tys[0];
-            Ret(bcx, C_bool(ty::type_contents(ccx.tcx, tp_ty).contains_managed()));
-        }
-        "visit_tydesc" => {
-            let td = get_param(decl, first_real_arg);
-            let visitor = get_param(decl, first_real_arg + 1u);
-            let td = PointerCast(bcx, td, ccx.tydesc_type.ptr_to());
-            glue::call_tydesc_glue_full(bcx, visitor, td,
-                                        abi::tydesc_field_visit_glue, None);
-            RetVoid(bcx);
-        }
-        "frame_address" => {
-            let frameaddress = ccx.intrinsics.get_copy(& &"llvm.frameaddress");
-            let frameaddress_val = Call(bcx, frameaddress, [C_i32(0i32)]);
-            let star_u8 = ty::mk_imm_ptr(
-                bcx.tcx(),
-                ty::mk_mach_uint(ast::ty_u8));
-            let fty = ty::mk_closure(bcx.tcx(), ty::ClosureTy {
-                purity: ast::impure_fn,
-                sigil: ast::BorrowedSigil,
-                onceness: ast::Many,
-                region: ty::re_bound(ty::br_anon(0)),
-                bounds: ty::EmptyBuiltinBounds(),
-                sig: FnSig {
-                    bound_lifetime_names: opt_vec::Empty,
-                    inputs: ~[ star_u8 ],
-                    output: ty::mk_nil()
-                }
-            });
-            let datum = Datum {val: get_param(decl, first_real_arg),
-                               mode: ByRef(ZeroMem), ty: fty};
-            let arg_vals = ~[frameaddress_val];
-            bcx = trans_call_inner(
-                bcx, None, fty, ty::mk_nil(),
-                |bcx| Callee {bcx: bcx, data: Closure(datum)},
-                ArgVals(arg_vals), Some(Ignore), DontAutorefArg).bcx;
-            RetVoid(bcx);
-        }
-        "morestack_addr" => {
-            // XXX 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_fn(bcx.ccx(), [], ty::mk_nil());
-            let morestack_addr = decl_cdecl_fn(
-                bcx.ccx().llmod, "__morestack", llfty);
-            let morestack_addr = PointerCast(bcx, morestack_addr, Type::nil().ptr_to());
-            Ret(bcx, morestack_addr);
-        }
-        "offset" => {
-            let ptr = get_param(decl, first_real_arg);
-            let offset = get_param(decl, first_real_arg + 1);
-            Ret(bcx, GEP(bcx, ptr, [offset]));
-        }
-        "offset_inbounds" => {
-            let ptr = get_param(decl, first_real_arg);
-            let offset = get_param(decl, first_real_arg + 1);
-            Ret(bcx, InBoundsGEP(bcx, ptr, [offset]));
-        }
-        "memcpy32" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i32", substs.tys[0], 32),
-        "memcpy64" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i64", substs.tys[0], 64),
-        "memmove32" => memcpy_intrinsic(bcx, "llvm.memmove.p0i8.p0i8.i32", substs.tys[0], 32),
-        "memmove64" => memcpy_intrinsic(bcx, "llvm.memmove.p0i8.p0i8.i64", substs.tys[0], 64),
-        "memset32" => memset_intrinsic(bcx, "llvm.memset.p0i8.i32", substs.tys[0], 32),
-        "memset64" => memset_intrinsic(bcx, "llvm.memset.p0i8.i64", substs.tys[0], 64),
-        "sqrtf32" => simple_llvm_intrinsic(bcx, "llvm.sqrt.f32", 1),
-        "sqrtf64" => simple_llvm_intrinsic(bcx, "llvm.sqrt.f64", 1),
-        "powif32" => simple_llvm_intrinsic(bcx, "llvm.powi.f32", 2),
-        "powif64" => simple_llvm_intrinsic(bcx, "llvm.powi.f64", 2),
-        "sinf32" => simple_llvm_intrinsic(bcx, "llvm.sin.f32", 1),
-        "sinf64" => simple_llvm_intrinsic(bcx, "llvm.sin.f64", 1),
-        "cosf32" => simple_llvm_intrinsic(bcx, "llvm.cos.f32", 1),
-        "cosf64" => simple_llvm_intrinsic(bcx, "llvm.cos.f64", 1),
-        "powf32" => simple_llvm_intrinsic(bcx, "llvm.pow.f32", 2),
-        "powf64" => simple_llvm_intrinsic(bcx, "llvm.pow.f64", 2),
-        "expf32" => simple_llvm_intrinsic(bcx, "llvm.exp.f32", 1),
-        "expf64" => simple_llvm_intrinsic(bcx, "llvm.exp.f64", 1),
-        "exp2f32" => simple_llvm_intrinsic(bcx, "llvm.exp2.f32", 1),
-        "exp2f64" => simple_llvm_intrinsic(bcx, "llvm.exp2.f64", 1),
-        "logf32" => simple_llvm_intrinsic(bcx, "llvm.log.f32", 1),
-        "logf64" => simple_llvm_intrinsic(bcx, "llvm.log.f64", 1),
-        "log10f32" => simple_llvm_intrinsic(bcx, "llvm.log10.f32", 1),
-        "log10f64" => simple_llvm_intrinsic(bcx, "llvm.log10.f64", 1),
-        "log2f32" => simple_llvm_intrinsic(bcx, "llvm.log2.f32", 1),
-        "log2f64" => simple_llvm_intrinsic(bcx, "llvm.log2.f64", 1),
-        "fmaf32" => simple_llvm_intrinsic(bcx, "llvm.fma.f32", 3),
-        "fmaf64" => simple_llvm_intrinsic(bcx, "llvm.fma.f64", 3),
-        "fabsf32" => simple_llvm_intrinsic(bcx, "llvm.fabs.f32", 1),
-        "fabsf64" => simple_llvm_intrinsic(bcx, "llvm.fabs.f64", 1),
-        "floorf32" => simple_llvm_intrinsic(bcx, "llvm.floor.f32", 1),
-        "floorf64" => simple_llvm_intrinsic(bcx, "llvm.floor.f64", 1),
-        "ceilf32" => simple_llvm_intrinsic(bcx, "llvm.ceil.f32", 1),
-        "ceilf64" => simple_llvm_intrinsic(bcx, "llvm.ceil.f64", 1),
-        "truncf32" => simple_llvm_intrinsic(bcx, "llvm.trunc.f32", 1),
-        "truncf64" => simple_llvm_intrinsic(bcx, "llvm.trunc.f64", 1),
-        "ctpop8" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i8", 1),
-        "ctpop16" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i16", 1),
-        "ctpop32" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i32", 1),
-        "ctpop64" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i64", 1),
-        "ctlz8" => count_zeros_intrinsic(bcx, "llvm.ctlz.i8"),
-        "ctlz16" => count_zeros_intrinsic(bcx, "llvm.ctlz.i16"),
-        "ctlz32" => count_zeros_intrinsic(bcx, "llvm.ctlz.i32"),
-        "ctlz64" => count_zeros_intrinsic(bcx, "llvm.ctlz.i64"),
-        "cttz8" => count_zeros_intrinsic(bcx, "llvm.cttz.i8"),
-        "cttz16" => count_zeros_intrinsic(bcx, "llvm.cttz.i16"),
-        "cttz32" => count_zeros_intrinsic(bcx, "llvm.cttz.i32"),
-        "cttz64" => count_zeros_intrinsic(bcx, "llvm.cttz.i64"),
-        "bswap16" => simple_llvm_intrinsic(bcx, "llvm.bswap.i16", 1),
-        "bswap32" => simple_llvm_intrinsic(bcx, "llvm.bswap.i32", 1),
-        "bswap64" => simple_llvm_intrinsic(bcx, "llvm.bswap.i64", 1),
-
-        "i8_add_with_overflow" => with_overflow_instrinsic(bcx, "llvm.sadd.with.overflow.i8"),
-        "i16_add_with_overflow" => with_overflow_instrinsic(bcx, "llvm.sadd.with.overflow.i16"),
-        "i32_add_with_overflow" => with_overflow_instrinsic(bcx, "llvm.sadd.with.overflow.i32"),
-        "i64_add_with_overflow" => with_overflow_instrinsic(bcx, "llvm.sadd.with.overflow.i64"),
-
-        "u8_add_with_overflow" => with_overflow_instrinsic(bcx, "llvm.uadd.with.overflow.i8"),
-        "u16_add_with_overflow" => with_overflow_instrinsic(bcx, "llvm.uadd.with.overflow.i16"),
-        "u32_add_with_overflow" => with_overflow_instrinsic(bcx, "llvm.uadd.with.overflow.i32"),
-        "u64_add_with_overflow" => with_overflow_instrinsic(bcx, "llvm.uadd.with.overflow.i64"),
-
-        "i8_sub_with_overflow" => with_overflow_instrinsic(bcx, "llvm.ssub.with.overflow.i8"),
-        "i16_sub_with_overflow" => with_overflow_instrinsic(bcx, "llvm.ssub.with.overflow.i16"),
-        "i32_sub_with_overflow" => with_overflow_instrinsic(bcx, "llvm.ssub.with.overflow.i32"),
-        "i64_sub_with_overflow" => with_overflow_instrinsic(bcx, "llvm.ssub.with.overflow.i64"),
-
-        "u8_sub_with_overflow" => with_overflow_instrinsic(bcx, "llvm.usub.with.overflow.i8"),
-        "u16_sub_with_overflow" => with_overflow_instrinsic(bcx, "llvm.usub.with.overflow.i16"),
-        "u32_sub_with_overflow" => with_overflow_instrinsic(bcx, "llvm.usub.with.overflow.i32"),
-        "u64_sub_with_overflow" => with_overflow_instrinsic(bcx, "llvm.usub.with.overflow.i64"),
-
-        "i8_mul_with_overflow" => with_overflow_instrinsic(bcx, "llvm.smul.with.overflow.i8"),
-        "i16_mul_with_overflow" => with_overflow_instrinsic(bcx, "llvm.smul.with.overflow.i16"),
-        "i32_mul_with_overflow" => with_overflow_instrinsic(bcx, "llvm.smul.with.overflow.i32"),
-        "i64_mul_with_overflow" => with_overflow_instrinsic(bcx, "llvm.smul.with.overflow.i64"),
-
-        "u8_mul_with_overflow" => with_overflow_instrinsic(bcx, "llvm.umul.with.overflow.i8"),
-        "u16_mul_with_overflow" => with_overflow_instrinsic(bcx, "llvm.umul.with.overflow.i16"),
-        "u32_mul_with_overflow" => with_overflow_instrinsic(bcx, "llvm.umul.with.overflow.i32"),
-        "u64_mul_with_overflow" => with_overflow_instrinsic(bcx, "llvm.umul.with.overflow.i64"),
-
-        _ => {
-            // Could we make this an enum rather than a string? does it get
-            // checked earlier?
-            ccx.sess.span_bug(item.span, "unknown intrinsic");
-        }
+pub fn trans_foreign_mod(ccx: @mut CrateContext,
+                         foreign_mod: &ast::foreign_mod) {
+    let _icx = push_ctxt("foreign::trans_foreign_mod");
+    for &foreign_item in foreign_mod.items.iter() {
+        let lname = link_name(ccx, foreign_item);
+        ccx.item_symbols.insert(foreign_item.id, lname.to_owned());
     }
-    fcx.cleanup();
 }
 
-/**
- * Translates a "crust" fn, meaning a Rust fn that can be called
- * from C code.  In this case, we have to perform some adaptation
- * to (1) switch back to the Rust stack and (2) adapt the C calling
- * convention to our own.
- *
- * Example: Given a crust fn F(x: X, y: Y) -> Z, we generate a
- * Rust function R as normal:
- *
- *    void R(Z* dest, void *env, X x, Y y) {...}
- *
- * and then we generate a wrapper function W that looks like:
- *
- *    Z W(X x, Y y) {
- *        struct { X x; Y y; Z *z; } args = { x, y, z };
- *        call_on_c_stack_shim(S, &args);
- *    }
- *
- * Note that the wrapper follows the foreign (typically "C") ABI.
- * The wrapper is the actual "value" of the foreign fn.  Finally,
- * we generate a shim function S that looks like:
- *
- *     void S(struct { X x; Y y; Z *z; } *args) {
- *         R(args->z, NULL, args->x, args->y);
- *     }
- */
-pub fn trans_foreign_fn(ccx: @mut CrateContext,
-                        path: ast_map::path,
-                        decl: &ast::fn_decl,
-                        body: &ast::Block,
-                        llwrapfn: ValueRef,
-                        id: ast::NodeId) {
+///////////////////////////////////////////////////////////////////////////
+// Rust functions with foreign ABIs
+//
+// These are normal Rust functions defined with foreign ABIs.  For
+// now, and perhaps forever, we translate these using a "layer of
+// indirection". That is, given a Rust declaration like:
+//
+//     extern "C" fn foo(i: u32) -> u32 { ... }
+//
+// we will generate a function like:
+//
+//     S foo(T i) {
+//         S r;
+//         foo0(&r, NULL, i);
+//         return r;
+//     }
+//
+//     #[inline_always]
+//     void foo0(uint32_t *r, void *env, uint32_t i) { ... }
+//
+// Here the (internal) `foo0` function follows the Rust ABI as normal,
+// where the `foo` function follows the C ABI. We rely on LLVM to
+// inline the one into the other. Of course we could just generate the
+// correct code in the first place, but this is much simpler.
+
+pub fn register_rust_fn_with_foreign_abi(ccx: @mut CrateContext,
+                                         sp: span,
+                                         sym: ~str,
+                                         node_id: ast::NodeId)
+                                         -> ValueRef {
+    let _icx = push_ctxt("foreign::register_foreign_fn");
+
+    let tys = foreign_types_for_id(ccx, node_id);
+    let llfn_ty = lltype_for_fn_from_foreign_types(&tys);
+    let llfn = base::register_fn_llvmty(ccx,
+                                        sp,
+                                        sym,
+                                        node_id,
+                                        lib::llvm::CCallConv,
+                                        llfn_ty);
+    add_argument_attributes(&tys, llfn);
+    debug!("register_rust_fn_with_foreign_abi(node_id=%?, llfn_ty=%s, llfn=%s)",
+           node_id, ccx.tn.type_to_str(llfn_ty), ccx.tn.val_to_str(llfn));
+    llfn
+}
+
+pub fn trans_rust_fn_with_foreign_abi(ccx: @mut CrateContext,
+                                      path: &ast_map::path,
+                                      decl: &ast::fn_decl,
+                                      body: &ast::Block,
+                                      llwrapfn: ValueRef,
+                                      id: ast::NodeId) {
     let _icx = push_ctxt("foreign::build_foreign_fn");
+    let tys = foreign_types_for_id(ccx, id);
+
+    unsafe { // unsafe because we call LLVM operations
+        // Build up the Rust function (`foo0` above).
+        let llrustfn = build_rust_fn(ccx, path, decl, body, id);
+
+        // Build up the foreign wrapper (`foo` above).
+        return build_wrap_fn(ccx, llrustfn, llwrapfn, &tys);
+    }
 
     fn build_rust_fn(ccx: @mut CrateContext,
                      path: &ast_map::path,
                      decl: &ast::fn_decl,
                      body: &ast::Block,
                      id: ast::NodeId)
-                  -> ValueRef {
+                     -> ValueRef {
         let _icx = push_ctxt("foreign::foreign::build_rust_fn");
-        let t = ty::node_id_to_type(ccx.tcx, id);
-        // XXX: Bad copy.
+        let tcx = ccx.tcx;
+        let t = ty::node_id_to_type(tcx, id);
         let ps = link::mangle_internal_name_by_path(
-                            ccx,
-                            vec::append_one((*path).clone(),
-                                            ast_map::path_name(
-                                            special_idents::clownshoe_abi)));
+            ccx, vec::append_one((*path).clone(), ast_map::path_name(
+                special_idents::clownshoe_abi
+            )));
         let llty = type_of_fn_from_ty(ccx, t);
-        let llfndecl = decl_internal_cdecl_fn(ccx.llmod, ps, llty);
-        trans_fn(ccx,
-                 (*path).clone(),
-                 decl,
-                 body,
-                 llfndecl,
-                 no_self,
-                 None,
-                 id,
-                 []);
+        let llfndecl = base::decl_internal_cdecl_fn(ccx.llmod, ps, llty);
+        base::trans_fn(ccx,
+                       (*path).clone(),
+                       decl,
+                       body,
+                       llfndecl,
+                       base::no_self,
+                       None,
+                       id,
+                       []);
         return llfndecl;
     }
 
-    fn build_shim_fn(ccx: @mut CrateContext,
-                     path: ast_map::path,
-                     llrustfn: ValueRef,
-                     tys: &ShimTypes)
-                     -> ValueRef {
-        /*!
-         *
-         * Generate the shim S:
-         *
-         *     void S(struct { X x; Y y; Z *z; } *args) {
-         *         R(args->z, NULL, &args->x, args->y);
-         *     }
-         *
-         * One complication is that we must adapt to the Rust
-         * calling convention, which introduces indirection
-         * in some cases.  To demonstrate this, I wrote one of the
-         * entries above as `&args->x`, because presumably `X` is
-         * one of those types that is passed by pointer in Rust.
-         */
-
-        let _icx = push_ctxt("foreign::foreign::build_shim_fn");
-
-        fn build_args(bcx: @mut Block, tys: &ShimTypes, llargbundle: ValueRef)
-                      -> ~[ValueRef] {
-            let _icx = push_ctxt("foreign::extern::shim::build_args");
-            let ccx = bcx.ccx();
-            let mut llargvals = ~[];
-            let mut i = 0u;
-            let n = tys.fn_sig.inputs.len();
-
-            if !ty::type_is_immediate(bcx.tcx(), tys.fn_sig.output) {
-                let llretptr = load_inbounds(bcx, llargbundle, [0u, n]);
-                llargvals.push(llretptr);
+    unsafe fn build_wrap_fn(ccx: @mut CrateContext,
+                            llrustfn: ValueRef,
+                            llwrapfn: ValueRef,
+                            tys: &ForeignTypes) {
+        let _icx = push_ctxt(
+            "foreign::trans_rust_fn_with_foreign_abi::build_wrap_fn");
+        let tcx = ccx.tcx;
+
+        debug!("build_wrap_fn(llrustfn=%s, llwrapfn=%s)",
+               ccx.tn.val_to_str(llrustfn),
+               ccx.tn.val_to_str(llwrapfn));
+
+        // Avoid all the Rust generation stuff and just generate raw
+        // LLVM here.
+        //
+        // We want to generate code like this:
+        //
+        //     S foo(T i) {
+        //         S r;
+        //         foo0(&r, NULL, i);
+        //         return r;
+        //     }
+
+        let the_block =
+            "the block".to_c_str().with_ref(
+                |s| llvm::LLVMAppendBasicBlockInContext(ccx.llcx, llwrapfn, s));
+
+        let builder = ccx.builder.B;
+        llvm::LLVMPositionBuilderAtEnd(builder, the_block);
+
+        // Array for the arguments we will pass to the rust function.
+        let mut llrust_args = ~[];
+        let mut next_foreign_arg_counter: c_uint = 0;
+        let next_foreign_arg: &fn() -> c_uint = {
+            || {
+                next_foreign_arg_counter += 1;
+                next_foreign_arg_counter - 1
             }
+        };
 
-            let llenvptr = C_null(Type::opaque_box(bcx.ccx()).ptr_to());
-            llargvals.push(llenvptr);
-            while i < n {
-                // Get a pointer to the argument:
-                let mut llargval = GEPi(bcx, llargbundle, [0u, i]);
+        // If there is an out pointer on the foreign function
+        let foreign_outptr = {
+            if tys.fn_ty.sret {
+                Some(llvm::LLVMGetParam(llwrapfn, next_foreign_arg()))
+            } else {
+                None
+            }
+        };
 
-                if !type_of::arg_is_indirect(ccx, &tys.fn_sig.inputs[i]) {
-                    // If Rust would pass this by value, load the value.
-                    llargval = Load(bcx, llargval);
+        // Push Rust return pointer, using null if it will be unused.
+        let rust_uses_outptr =
+            type_of::return_uses_outptr(tcx, tys.fn_sig.output);
+        let return_alloca: Option<ValueRef>;
+        let llrust_ret_ty = tys.llsig.llret_ty;
+        let llrust_retptr_ty = llrust_ret_ty.ptr_to();
+        if rust_uses_outptr {
+            // Rust expects to use an outpointer. If the foreign fn
+            // also uses an outpointer, we can reuse it, but the types
+            // may vary, so cast first to the Rust type. If the
+            // foriegn fn does NOT use an outpointer, we will have to
+            // alloca some scratch space on the stack.
+            match foreign_outptr {
+                Some(llforeign_outptr) => {
+                    debug!("out pointer, foreign=%s",
+                           ccx.tn.val_to_str(llforeign_outptr));
+                    let llrust_retptr =
+                        llvm::LLVMBuildBitCast(builder,
+                                               llforeign_outptr,
+                                               llrust_ret_ty.ptr_to().to_ref(),
+                                               noname());
+                    debug!("out pointer, foreign=%s (casted)",
+                           ccx.tn.val_to_str(llrust_retptr));
+                    llrust_args.push(llrust_retptr);
+                    return_alloca = None;
                 }
 
-                llargvals.push(llargval);
-                i += 1u;
+                None => {
+                    let slot = {
+                        "return_alloca".to_c_str().with_ref(
+                            |s| llvm::LLVMBuildAlloca(builder,
+                                                      llrust_ret_ty.to_ref(),
+                                                      s))
+                    };
+                    debug!("out pointer, \
+                            allocad=%s, \
+                            llrust_ret_ty=%s, \
+                            return_ty=%s",
+                           ccx.tn.val_to_str(slot),
+                           ccx.tn.type_to_str(llrust_ret_ty),
+                           tys.fn_sig.output.repr(tcx));
+                    llrust_args.push(slot);
+                    return_alloca = Some(slot);
+                }
+            }
+        } else {
+            // Rust does not expect an outpointer. If the foreign fn
+            // does use an outpointer, then we will do a store of the
+            // value that the Rust fn returns.
+            return_alloca = None;
+        };
+
+        // Push an (null) env pointer
+        let env_pointer = base::null_env_ptr(ccx);
+        debug!("env pointer=%s", 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.
+        for i in range(0, tys.fn_sig.inputs.len()) {
+            let rust_ty = tys.fn_sig.inputs[i];
+            let llrust_ty = tys.llsig.llarg_tys[i];
+            let foreign_index = next_foreign_arg();
+            let rust_indirect = type_of::arg_is_indirect(ccx, rust_ty);
+            let foreign_indirect = tys.fn_ty.attrs[foreign_index].is_some();
+            let mut llforeign_arg = llvm::LLVMGetParam(llwrapfn, foreign_index);
+
+            debug!("llforeign_arg #%u: %s",
+                   i, ccx.tn.val_to_str(llforeign_arg));
+            debug!("rust_indirect = %b, foreign_indirect = %b",
+                   rust_indirect, foreign_indirect);
+
+            // Ensure that the foreign argument is indirect (by
+            // pointer).  It makes adapting types easier, since we can
+            // always just bitcast pointers.
+            if !foreign_indirect {
+                let lltemp =
+                    llvm::LLVMBuildAlloca(
+                        builder, val_ty(llforeign_arg).to_ref(), noname());
+                llvm::LLVMBuildStore(
+                    builder, llforeign_arg, lltemp);
+                llforeign_arg = lltemp;
+            }
+
+            // If the types in the ABI and the Rust types don't match,
+            // bitcast the llforeign_arg pointer so it matches the types
+            // Rust expects.
+            if tys.fn_ty.arg_tys[foreign_index].cast {
+                assert!(!foreign_indirect);
+                llforeign_arg = llvm::LLVMBuildBitCast(
+                    builder, llforeign_arg,
+                    llrust_ty.ptr_to().to_ref(), noname());
             }
-            return llargvals;
-        }
 
-        fn build_ret(bcx: @mut Block,
-                     shim_types: &ShimTypes,
-                     llargbundle: ValueRef,
-                     llretval: ValueRef) {
-            if bcx.fcx.llretptr.is_some() &&
-                ty::type_is_immediate(bcx.tcx(), shim_types.fn_sig.output) {
-                // Write the value into the argument bundle.
-                let arg_count = shim_types.fn_sig.inputs.len();
-                let llretptr = load_inbounds(bcx,
-                                             llargbundle,
-                                             [0, arg_count]);
-                Store(bcx, llretval, llretptr);
+            let llrust_arg = if rust_indirect {
+                llforeign_arg
             } else {
-                // NB: The return pointer in the Rust ABI function is wired
-                // directly into the return slot in the shim struct.
+                llvm::LLVMBuildLoad(builder, llforeign_arg, noname())
+            };
+
+            debug!("llrust_arg #%u: %s",
+                   i, ccx.tn.val_to_str(llrust_arg));
+            llrust_args.push(llrust_arg);
+        }
+
+        // Perform the call itself
+        let llrust_ret_val = do llrust_args.as_imm_buf |ptr, len| {
+            debug!("calling llrustfn = %s", ccx.tn.val_to_str(llrustfn));
+            llvm::LLVMBuildCall(builder, llrustfn, ptr,
+                                len as c_uint, noname())
+        };
+
+        // Get the return value where the foreign fn expects it.
+        let llforeign_ret_ty = tys.fn_ty.ret_ty.ty;
+        match foreign_outptr {
+            None if !tys.ret_def => {
+                // Function returns `()` or `bot`, which in Rust is the LLVM
+                // type "{}" but in foreign ABIs is "Void".
+                llvm::LLVMBuildRetVoid(builder);
+            }
+
+            None if rust_uses_outptr => {
+                // Rust uses an outpointer, but the foreign ABI does not. Load.
+                let llrust_outptr = return_alloca.unwrap();
+                let llforeign_outptr_casted =
+                    llvm::LLVMBuildBitCast(builder,
+                                           llrust_outptr,
+                                           llforeign_ret_ty.ptr_to().to_ref(),
+                                           noname());
+                let llforeign_retval =
+                    llvm::LLVMBuildLoad(builder, llforeign_outptr_casted, noname());
+                llvm::LLVMBuildRet(builder, llforeign_retval);
+            }
+
+            None if llforeign_ret_ty != llrust_ret_ty => {
+                // Neither ABI uses an outpointer, but the types don't
+                // quite match. Must cast. Probably we should try and
+                // examine the types and use a concrete llvm cast, but
+                // right now we just use a temp memory location and
+                // bitcast the pointer, which is the same thing the
+                // old wrappers used to do.
+                let lltemp =
+                    llvm::LLVMBuildAlloca(
+                        builder, llforeign_ret_ty.to_ref(), noname());
+                let lltemp_casted =
+                    llvm::LLVMBuildBitCast(builder,
+                                           lltemp,
+                                           llrust_ret_ty.ptr_to().to_ref(),
+                                           noname());
+                llvm::LLVMBuildStore(
+                    builder, llrust_ret_val, lltemp_casted);
+                let llforeign_retval =
+                    llvm::LLVMBuildLoad(builder, lltemp, noname());
+                llvm::LLVMBuildRet(builder, llforeign_retval);
+            }
+
+            None => {
+                // Neither ABI uses an outpointer, and the types
+                // match. Easy peasy.
+                llvm::LLVMBuildRet(builder, llrust_ret_val);
+            }
+
+            Some(llforeign_outptr) if !rust_uses_outptr => {
+                // Foreign ABI requires an out pointer, but Rust doesn't.
+                // Store Rust return value.
+                let llforeign_outptr_casted =
+                    llvm::LLVMBuildBitCast(builder,
+                                           llforeign_outptr,
+                                           llrust_retptr_ty.to_ref(),
+                                           noname());
+                llvm::LLVMBuildStore(
+                    builder, llrust_ret_val, llforeign_outptr_casted);
+                llvm::LLVMBuildRetVoid(builder);
+            }
+
+            Some(_) => {
+                // Both ABIs use outpointers. Easy peasy.
+                llvm::LLVMBuildRetVoid(builder);
             }
         }
+    }
+}
 
-        let shim_name = link::mangle_internal_name_by_path(
-            ccx,
-            vec::append_one(path, ast_map::path_name(
-                special_idents::clownshoe_stack_shim
-            )));
-        build_shim_fn_(ccx,
-                       shim_name,
-                       llrustfn,
-                       tys,
-                       lib::llvm::CCallConv,
-                       build_args,
-                       build_ret)
+///////////////////////////////////////////////////////////////////////////
+// General ABI Support
+//
+// This code is kind of a confused mess and needs to be reworked given
+// the massive simplifications that have occurred.
+
+pub fn link_name(ccx: &CrateContext, i: @ast::foreign_item) -> @str {
+     match attr::first_attr_value_str_by_name(i.attrs, "link_name") {
+        None => ccx.sess.str_of(i.ident),
+        Some(ln) => ln,
     }
+}
 
-    fn build_wrap_fn(ccx: @mut CrateContext,
-                     llshimfn: ValueRef,
-                     llwrapfn: ValueRef,
-                     tys: &ShimTypes) {
-        /*!
-         *
-         * Generate the wrapper W:
-         *
-         *    Z W(X x, Y y) {
-         *        struct { X x; Y y; Z *z; } args = { x, y, z };
-         *        call_on_c_stack_shim(S, &args);
-         *    }
-         */
-
-        let _icx = push_ctxt("foreign::foreign::build_wrap_fn");
-
-        build_wrap_fn_(ccx,
-                       tys,
-                       llshimfn,
-                       llwrapfn,
-                       ccx.upcalls.call_shim_on_rust_stack,
-                       true,
-                       build_args,
-                       build_ret);
-
-        fn build_args(bcx: @mut Block,
-                      tys: &ShimTypes,
-                      llwrapfn: ValueRef,
-                      llargbundle: ValueRef) {
-            let _icx = push_ctxt("foreign::foreign::wrap::build_args");
-            tys.fn_ty.build_wrap_args(bcx,
-                                      tys.llsig.llret_ty,
-                                      llwrapfn,
-                                      llargbundle);
-        }
+fn foreign_signature(ccx: &mut CrateContext, fn_sig: &ty::FnSig)
+                     -> LlvmSignature {
+    /*!
+     * The ForeignSignature is the LLVM types of the arguments/return type
+     * of a function.  Note that these LLVM types are not quite the same
+     * as the LLVM types would be for a native Rust function because foreign
+     * functions just plain ignore modes.  They also don't pass aggregate
+     * values by pointer like we do.
+     */
 
-        fn build_ret(bcx: @mut Block, tys: &ShimTypes, llargbundle: ValueRef) {
-            let _icx = push_ctxt("foreign::foreign::wrap::build_ret");
-            tys.fn_ty.build_wrap_ret(bcx, tys.llsig.llarg_tys, llargbundle);
-        }
+    let llarg_tys = fn_sig.inputs.map(|&arg| type_of(ccx, arg));
+    let llret_ty = type_of::type_of(ccx, fn_sig.output);
+    LlvmSignature {
+        llarg_tys: llarg_tys,
+        llret_ty: llret_ty,
+        sret: type_of::return_uses_outptr(ccx.tcx, fn_sig.output),
     }
+}
 
-    let tys = shim_types(ccx, id);
-    // The internal Rust ABI function - runs on the Rust stack
-    // XXX: Bad copy.
-    let llrustfn = build_rust_fn(ccx, &path, decl, body, id);
-    // The internal shim function - runs on the Rust stack
-    let llshimfn = build_shim_fn(ccx, path, llrustfn, &tys);
-    // The foreign C function - runs on the C stack
-    build_wrap_fn(ccx, llshimfn, llwrapfn, &tys)
+fn foreign_types_for_id(ccx: &mut CrateContext,
+                        id: ast::NodeId) -> ForeignTypes {
+    foreign_types_for_fn_ty(ccx, ty::node_id_to_type(ccx.tcx, id))
 }
 
-pub fn register_foreign_fn(ccx: @mut CrateContext,
-                           sp: span,
-                           sym: ~str,
-                           node_id: ast::NodeId)
-                           -> ValueRef {
-    let _icx = push_ctxt("foreign::register_foreign_fn");
+fn foreign_types_for_fn_ty(ccx: &mut CrateContext,
+                           ty: ty::t) -> ForeignTypes {
+    let fn_sig = match ty::get(ty).sty {
+        ty::ty_bare_fn(ref fn_ty) => fn_ty.sig.clone(),
+        _ => ccx.sess.bug("foreign_types_for_fn_ty called on non-function type")
+    };
+    let llsig = foreign_signature(ccx, &fn_sig);
+    let ret_def = !ty::type_is_voidish(fn_sig.output);
+    let fn_ty = cabi::compute_abi_info(ccx,
+                                       llsig.llarg_tys,
+                                       llsig.llret_ty,
+                                       ret_def);
+    debug!("foreign_types_for_fn_ty(\
+           ty=%s, \
+           llsig=%s -> %s, \
+           fn_ty=%s -> %s, \
+           ret_def=%b",
+           ty.repr(ccx.tcx),
+           ccx.tn.types_to_str(llsig.llarg_tys),
+           ccx.tn.type_to_str(llsig.llret_ty),
+           ccx.tn.types_to_str(fn_ty.arg_tys.map(|t| t.ty)),
+           ccx.tn.type_to_str(fn_ty.ret_ty.ty),
+           ret_def);
+
+    ForeignTypes {
+        fn_sig: fn_sig,
+        llsig: llsig,
+        ret_def: ret_def,
+        fn_ty: fn_ty
+    }
+}
 
-    let sym = Cell::new(sym);
+fn lltype_for_fn_from_foreign_types(tys: &ForeignTypes) -> Type {
+    let llargument_tys: ~[Type] =
+        tys.fn_ty.arg_tys.iter().map(|t| t.ty).collect();
+    let llreturn_ty = tys.fn_ty.ret_ty.ty;
+    Type::func(llargument_tys, &llreturn_ty)
+}
+
+pub fn lltype_for_foreign_fn(ccx: &mut CrateContext, ty: ty::t) -> Type {
+    let fn_types = foreign_types_for_fn_ty(ccx, ty);
+    lltype_for_fn_from_foreign_types(&fn_types)
+}
 
-    let tys = shim_types(ccx, node_id);
-    do tys.fn_ty.decl_fn |fnty| {
-        register_fn_llvmty(ccx, sp, sym.take(), node_id, lib::llvm::CCallConv, fnty)
+fn add_argument_attributes(tys: &ForeignTypes,
+                           llfn: ValueRef) {
+    for (i, a) in tys.fn_ty.attrs.iter().enumerate() {
+        match *a {
+            Some(attr) => {
+                let llarg = get_param(llfn, i);
+                unsafe {
+                    llvm::LLVMAddAttribute(llarg, attr as c_uint);
+                }
+            }
+            None => ()
+        }
     }
 }
index 4f894deb1a1c19eed3d692569ea876997395a246..9acc3018046b3bf324559ed27675ea2ac27668fe 100644 (file)
@@ -673,7 +673,7 @@ pub fn declare_tydesc(ccx: &mut CrateContext, t: ty::t) -> @mut tydesc_info {
     let name = mangle_internal_name_by_type_and_seq(ccx, t, "tydesc").to_managed();
     note_unique_llvm_symbol(ccx, name);
     debug!("+++ declare_tydesc %s %s", ppaux::ty_to_str(ccx.tcx, t), name);
-    let gvar = do name.to_c_str().with_ref |buf| {
+    let gvar = do name.with_c_str |buf| {
         unsafe {
             llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type.to_ref(), buf)
         }
diff --git a/src/librustc/middle/trans/intrinsic.rs b/src/librustc/middle/trans/intrinsic.rs
new file mode 100644 (file)
index 0000000..2232b89
--- /dev/null
@@ -0,0 +1,503 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use back::{abi};
+use lib::llvm::{SequentiallyConsistent, Acquire, Release, Xchg};
+use lib::llvm::{ValueRef, Pointer};
+use lib;
+use middle::trans::base::*;
+use middle::trans::build::*;
+use middle::trans::callee::*;
+use middle::trans::common::*;
+use middle::trans::datum::*;
+use middle::trans::type_of::*;
+use middle::trans::type_of;
+use middle::trans::expr::Ignore;
+use middle::trans::machine;
+use middle::trans::glue;
+use middle::ty::FnSig;
+use middle::ty;
+use syntax::ast;
+use syntax::ast_map;
+use syntax::attr;
+use syntax::opt_vec;
+use util::ppaux::{ty_to_str};
+use middle::trans::machine::llsize_of;
+use middle::trans::type_::Type;
+
+pub fn trans_intrinsic(ccx: @mut CrateContext,
+                       decl: ValueRef,
+                       item: &ast::foreign_item,
+                       path: ast_map::path,
+                       substs: @param_substs,
+                       attributes: &[ast::Attribute],
+                       ref_id: Option<ast::NodeId>) {
+    debug!("trans_intrinsic(item.ident=%s)", ccx.sess.str_of(item.ident));
+
+    fn simple_llvm_intrinsic(bcx: @mut Block, name: &'static str, num_args: uint) {
+        assert!(num_args <= 4);
+        let mut args = [0 as ValueRef, ..4];
+        let first_real_arg = bcx.fcx.arg_pos(0u);
+        for i in range(0u, num_args) {
+            args[i] = get_param(bcx.fcx.llfn, first_real_arg + i);
+        }
+        let llfn = bcx.ccx().intrinsics.get_copy(&name);
+        Ret(bcx, Call(bcx, llfn, args.slice(0, num_args)));
+    }
+
+    fn with_overflow_instrinsic(bcx: @mut Block, name: &'static str) {
+        let first_real_arg = bcx.fcx.arg_pos(0u);
+        let a = get_param(bcx.fcx.llfn, first_real_arg);
+        let b = get_param(bcx.fcx.llfn, first_real_arg + 1);
+        let llfn = bcx.ccx().intrinsics.get_copy(&name);
+
+        // convert `i1` to a `bool`, and write to the out parameter
+        let val = Call(bcx, llfn, [a, b]);
+        let result = ExtractValue(bcx, val, 0);
+        let overflow = ZExt(bcx, ExtractValue(bcx, val, 1), Type::bool());
+        let retptr = get_param(bcx.fcx.llfn, bcx.fcx.out_arg_pos());
+        let ret = Load(bcx, retptr);
+        let ret = InsertValue(bcx, ret, result, 0);
+        let ret = InsertValue(bcx, ret, overflow, 1);
+        Store(bcx, ret, retptr);
+        RetVoid(bcx)
+    }
+
+    fn memcpy_intrinsic(bcx: @mut Block, name: &'static str, tp_ty: ty::t, sizebits: u8) {
+        let ccx = bcx.ccx();
+        let lltp_ty = type_of::type_of(ccx, tp_ty);
+        let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32);
+        let size = match sizebits {
+            32 => C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32),
+            64 => C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64),
+            _ => ccx.sess.fatal("Invalid value for sizebits")
+        };
+
+        let decl = bcx.fcx.llfn;
+        let first_real_arg = bcx.fcx.arg_pos(0u);
+        let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p());
+        let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p());
+        let count = get_param(decl, first_real_arg + 2);
+        let volatile = C_i1(false);
+        let llfn = bcx.ccx().intrinsics.get_copy(&name);
+        Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]);
+        RetVoid(bcx);
+    }
+
+    fn memset_intrinsic(bcx: @mut Block, name: &'static str, tp_ty: ty::t, sizebits: u8) {
+        let ccx = bcx.ccx();
+        let lltp_ty = type_of::type_of(ccx, tp_ty);
+        let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32);
+        let size = match sizebits {
+            32 => C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32),
+            64 => C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64),
+            _ => ccx.sess.fatal("Invalid value for sizebits")
+        };
+
+        let decl = bcx.fcx.llfn;
+        let first_real_arg = bcx.fcx.arg_pos(0u);
+        let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p());
+        let val = get_param(decl, first_real_arg + 1);
+        let count = get_param(decl, first_real_arg + 2);
+        let volatile = C_i1(false);
+        let llfn = bcx.ccx().intrinsics.get_copy(&name);
+        Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile]);
+        RetVoid(bcx);
+    }
+
+    fn count_zeros_intrinsic(bcx: @mut Block, name: &'static str) {
+        let x = get_param(bcx.fcx.llfn, bcx.fcx.arg_pos(0u));
+        let y = C_i1(false);
+        let llfn = bcx.ccx().intrinsics.get_copy(&name);
+        Ret(bcx, Call(bcx, llfn, [x, y]));
+    }
+
+    let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, item.id));
+
+    let fcx = new_fn_ctxt_w_id(ccx,
+                               path,
+                               decl,
+                               item.id,
+                               output_type,
+                               true,
+                               Some(substs),
+                               None,
+                               Some(item.span));
+
+    set_always_inline(fcx.llfn);
+
+    // Set the fixed stack segment flag if necessary.
+    if attr::contains_name(attributes, "fixed_stack_segment") {
+        set_fixed_stack_segment(fcx.llfn);
+    }
+
+    let mut bcx = fcx.entry_bcx.unwrap();
+    let first_real_arg = fcx.arg_pos(0u);
+
+    let nm = ccx.sess.str_of(item.ident);
+    let name = nm.as_slice();
+
+    // This requires that atomic intrinsics follow a specific naming pattern:
+    // "atomic_<operation>[_<ordering>], and no ordering means SeqCst
+    if name.starts_with("atomic_") {
+        let split : ~[&str] = name.split_iter('_').collect();
+        assert!(split.len() >= 2, "Atomic intrinsic not correct format");
+        let order = if split.len() == 2 {
+            lib::llvm::SequentiallyConsistent
+        } else {
+            match split[2] {
+                "relaxed" => lib::llvm::Monotonic,
+                "acq"     => lib::llvm::Acquire,
+                "rel"     => lib::llvm::Release,
+                "acqrel"  => lib::llvm::AcquireRelease,
+                _ => ccx.sess.fatal("Unknown ordering in atomic intrinsic")
+            }
+        };
+
+        match split[1] {
+            "cxchg" => {
+                let old = AtomicCmpXchg(bcx, get_param(decl, first_real_arg),
+                                        get_param(decl, first_real_arg + 1u),
+                                        get_param(decl, first_real_arg + 2u),
+                                        order);
+                Ret(bcx, old);
+            }
+            "load" => {
+                let old = AtomicLoad(bcx, get_param(decl, first_real_arg),
+                                     order);
+                Ret(bcx, old);
+            }
+            "store" => {
+                AtomicStore(bcx, get_param(decl, first_real_arg + 1u),
+                            get_param(decl, first_real_arg),
+                            order);
+                RetVoid(bcx);
+            }
+            "fence" => {
+                AtomicFence(bcx, order);
+                RetVoid(bcx);
+            }
+            op => {
+                // These are all AtomicRMW ops
+                let atom_op = match op {
+                    "xchg"  => lib::llvm::Xchg,
+                    "xadd"  => lib::llvm::Add,
+                    "xsub"  => lib::llvm::Sub,
+                    "and"   => lib::llvm::And,
+                    "nand"  => lib::llvm::Nand,
+                    "or"    => lib::llvm::Or,
+                    "xor"   => lib::llvm::Xor,
+                    "max"   => lib::llvm::Max,
+                    "min"   => lib::llvm::Min,
+                    "umax"  => lib::llvm::UMax,
+                    "umin"  => lib::llvm::UMin,
+                    _ => ccx.sess.fatal("Unknown atomic operation")
+                };
+
+                let old = AtomicRMW(bcx, atom_op, get_param(decl, first_real_arg),
+                                    get_param(decl, first_real_arg + 1u),
+                                    order);
+                Ret(bcx, old);
+            }
+        }
+
+        fcx.cleanup();
+        return;
+    }
+
+    match name {
+        "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)));
+        }
+        "move_val" => {
+            // Create a datum reflecting the value being moved.
+            // Use `appropriate_mode` so that the datum is by ref
+            // if the value is non-immediate. Note that, with
+            // intrinsics, there are no argument cleanups to
+            // concern ourselves with.
+            let tp_ty = substs.tys[0];
+            let mode = appropriate_mode(ccx.tcx, tp_ty);
+            let src = Datum {val: get_param(decl, first_real_arg + 1u),
+                             ty: tp_ty, mode: mode};
+            bcx = src.move_to(bcx, DROP_EXISTING,
+                              get_param(decl, first_real_arg));
+            RetVoid(bcx);
+        }
+        "move_val_init" => {
+            // See comments for `"move_val"`.
+            let tp_ty = substs.tys[0];
+            let mode = appropriate_mode(ccx.tcx, tp_ty);
+            let src = Datum {val: get_param(decl, first_real_arg + 1u),
+                             ty: tp_ty, mode: mode};
+            bcx = src.move_to(bcx, INIT, get_param(decl, first_real_arg));
+            RetVoid(bcx);
+        }
+        "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)));
+        }
+        "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)));
+        }
+        "get_tydesc" => {
+            let tp_ty = substs.tys[0];
+            let static_ti = get_tydesc(ccx, tp_ty);
+            glue::lazily_emit_all_tydesc_glue(ccx, static_ti);
+
+            // FIXME (#3730): ideally this shouldn't need a cast,
+            // but there's a circularity between translating rust types to llvm
+            // types and having a tydesc type available. So I can't directly access
+            // the llvm type of intrinsic::TyDesc struct.
+            let userland_tydesc_ty = type_of::type_of(ccx, output_type);
+            let td = PointerCast(bcx, static_ti.tydesc, userland_tydesc_ty);
+            Ret(bcx, td);
+        }
+        "init" => {
+            let tp_ty = substs.tys[0];
+            let lltp_ty = type_of::type_of(ccx, tp_ty);
+            match bcx.fcx.llretptr {
+                Some(ptr) => { Store(bcx, C_null(lltp_ty), ptr); RetVoid(bcx); }
+                None if ty::type_is_nil(tp_ty) => RetVoid(bcx),
+                None => Ret(bcx, C_null(lltp_ty)),
+            }
+        }
+        "uninit" => {
+            // Do nothing, this is effectively a no-op
+            let retty = substs.tys[0];
+            if ty::type_is_immediate(ccx.tcx, retty) && !ty::type_is_nil(retty) {
+                unsafe {
+                    Ret(bcx, lib::llvm::llvm::LLVMGetUndef(type_of(ccx, retty).to_ref()));
+                }
+            } else {
+                RetVoid(bcx)
+            }
+        }
+        "forget" => {
+            RetVoid(bcx);
+        }
+        "transmute" => {
+            let (in_type, out_type) = (substs.tys[0], substs.tys[1]);
+            let llintype = type_of::type_of(ccx, in_type);
+            let llouttype = type_of::type_of(ccx, out_type);
+
+            let in_type_size = machine::llbitsize_of_real(ccx, llintype);
+            let out_type_size = machine::llbitsize_of_real(ccx, llouttype);
+            if in_type_size != out_type_size {
+                let sp = match ccx.tcx.items.get_copy(&ref_id.unwrap()) {
+                    ast_map::node_expr(e) => e.span,
+                    _ => fail!("transmute has non-expr arg"),
+                };
+                let pluralize = |n| if 1u == n { "" } else { "s" };
+                ccx.sess.span_fatal(sp,
+                                    fmt!("transmute called on types with \
+                                          different sizes: %s (%u bit%s) to \
+                                          %s (%u bit%s)",
+                                         ty_to_str(ccx.tcx, in_type),
+                                         in_type_size,
+                                         pluralize(in_type_size),
+                                         ty_to_str(ccx.tcx, out_type),
+                                         out_type_size,
+                                         pluralize(out_type_size)));
+            }
+
+            if !ty::type_is_voidish(out_type) {
+                let llsrcval = get_param(decl, first_real_arg);
+                if ty::type_is_immediate(ccx.tcx, in_type) {
+                    match fcx.llretptr {
+                        Some(llretptr) => {
+                            Store(bcx, llsrcval, PointerCast(bcx, llretptr, llintype.ptr_to()));
+                            RetVoid(bcx);
+                        }
+                        None => match (llintype.kind(), llouttype.kind()) {
+                            (Pointer, other) | (other, Pointer) if other != Pointer => {
+                                let tmp = Alloca(bcx, llouttype, "");
+                                Store(bcx, llsrcval, PointerCast(bcx, tmp, llintype.ptr_to()));
+                                Ret(bcx, Load(bcx, tmp));
+                            }
+                            _ => Ret(bcx, BitCast(bcx, llsrcval, llouttype))
+                        }
+                    }
+                } else if ty::type_is_immediate(ccx.tcx, out_type) {
+                    let llsrcptr = PointerCast(bcx, llsrcval, llouttype.ptr_to());
+                    Ret(bcx, Load(bcx, llsrcptr));
+                } else {
+                    // NB: Do not use a Load and Store here. This causes massive
+                    // code bloat when `transmute` is used on large structural
+                    // types.
+                    let lldestptr = fcx.llretptr.unwrap();
+                    let lldestptr = PointerCast(bcx, lldestptr, Type::i8p());
+                    let llsrcptr = PointerCast(bcx, llsrcval, Type::i8p());
+
+                    let llsize = llsize_of(ccx, llintype);
+                    call_memcpy(bcx, lldestptr, llsrcptr, llsize, 1);
+                    RetVoid(bcx);
+                };
+            } else {
+                RetVoid(bcx);
+            }
+        }
+        "needs_drop" => {
+            let tp_ty = substs.tys[0];
+            Ret(bcx, C_bool(ty::type_needs_drop(ccx.tcx, tp_ty)));
+        }
+        "contains_managed" => {
+            let tp_ty = substs.tys[0];
+            Ret(bcx, C_bool(ty::type_contents(ccx.tcx, tp_ty).contains_managed()));
+        }
+        "visit_tydesc" => {
+            let td = get_param(decl, first_real_arg);
+            let visitor = get_param(decl, first_real_arg + 1u);
+            let td = PointerCast(bcx, td, ccx.tydesc_type.ptr_to());
+            glue::call_tydesc_glue_full(bcx, visitor, td,
+                                        abi::tydesc_field_visit_glue, None);
+            RetVoid(bcx);
+        }
+        "frame_address" => {
+            let frameaddress = ccx.intrinsics.get_copy(& &"llvm.frameaddress");
+            let frameaddress_val = Call(bcx, frameaddress, [C_i32(0i32)]);
+            let star_u8 = ty::mk_imm_ptr(
+                bcx.tcx(),
+                ty::mk_mach_uint(ast::ty_u8));
+            let fty = ty::mk_closure(bcx.tcx(), ty::ClosureTy {
+                purity: ast::impure_fn,
+                sigil: ast::BorrowedSigil,
+                onceness: ast::Many,
+                region: ty::re_bound(ty::br_anon(0)),
+                bounds: ty::EmptyBuiltinBounds(),
+                sig: FnSig {
+                    bound_lifetime_names: opt_vec::Empty,
+                    inputs: ~[ star_u8 ],
+                    output: ty::mk_nil()
+                }
+            });
+            let datum = Datum {val: get_param(decl, first_real_arg),
+                               mode: ByRef(ZeroMem), ty: fty};
+            let arg_vals = ~[frameaddress_val];
+            bcx = trans_call_inner(
+                bcx, None, fty, ty::mk_nil(),
+                |bcx| Callee {bcx: bcx, data: Closure(datum)},
+                ArgVals(arg_vals), Some(Ignore), DontAutorefArg).bcx;
+            RetVoid(bcx);
+        }
+        "morestack_addr" => {
+            // XXX 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(), [], ty::mk_nil());
+            let morestack_addr = decl_cdecl_fn(
+                bcx.ccx().llmod, "__morestack", llfty);
+            let morestack_addr = PointerCast(bcx, morestack_addr, Type::nil().ptr_to());
+            Ret(bcx, morestack_addr);
+        }
+        "offset" => {
+            let ptr = get_param(decl, first_real_arg);
+            let offset = get_param(decl, first_real_arg + 1);
+            Ret(bcx, GEP(bcx, ptr, [offset]));
+        }
+        "offset_inbounds" => {
+            let ptr = get_param(decl, first_real_arg);
+            let offset = get_param(decl, first_real_arg + 1);
+            Ret(bcx, InBoundsGEP(bcx, ptr, [offset]));
+        }
+        "memcpy32" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i32", substs.tys[0], 32),
+        "memcpy64" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i64", substs.tys[0], 64),
+        "memmove32" => memcpy_intrinsic(bcx, "llvm.memmove.p0i8.p0i8.i32", substs.tys[0], 32),
+        "memmove64" => memcpy_intrinsic(bcx, "llvm.memmove.p0i8.p0i8.i64", substs.tys[0], 64),
+        "memset32" => memset_intrinsic(bcx, "llvm.memset.p0i8.i32", substs.tys[0], 32),
+        "memset64" => memset_intrinsic(bcx, "llvm.memset.p0i8.i64", substs.tys[0], 64),
+        "sqrtf32" => simple_llvm_intrinsic(bcx, "llvm.sqrt.f32", 1),
+        "sqrtf64" => simple_llvm_intrinsic(bcx, "llvm.sqrt.f64", 1),
+        "powif32" => simple_llvm_intrinsic(bcx, "llvm.powi.f32", 2),
+        "powif64" => simple_llvm_intrinsic(bcx, "llvm.powi.f64", 2),
+        "sinf32" => simple_llvm_intrinsic(bcx, "llvm.sin.f32", 1),
+        "sinf64" => simple_llvm_intrinsic(bcx, "llvm.sin.f64", 1),
+        "cosf32" => simple_llvm_intrinsic(bcx, "llvm.cos.f32", 1),
+        "cosf64" => simple_llvm_intrinsic(bcx, "llvm.cos.f64", 1),
+        "powf32" => simple_llvm_intrinsic(bcx, "llvm.pow.f32", 2),
+        "powf64" => simple_llvm_intrinsic(bcx, "llvm.pow.f64", 2),
+        "expf32" => simple_llvm_intrinsic(bcx, "llvm.exp.f32", 1),
+        "expf64" => simple_llvm_intrinsic(bcx, "llvm.exp.f64", 1),
+        "exp2f32" => simple_llvm_intrinsic(bcx, "llvm.exp2.f32", 1),
+        "exp2f64" => simple_llvm_intrinsic(bcx, "llvm.exp2.f64", 1),
+        "logf32" => simple_llvm_intrinsic(bcx, "llvm.log.f32", 1),
+        "logf64" => simple_llvm_intrinsic(bcx, "llvm.log.f64", 1),
+        "log10f32" => simple_llvm_intrinsic(bcx, "llvm.log10.f32", 1),
+        "log10f64" => simple_llvm_intrinsic(bcx, "llvm.log10.f64", 1),
+        "log2f32" => simple_llvm_intrinsic(bcx, "llvm.log2.f32", 1),
+        "log2f64" => simple_llvm_intrinsic(bcx, "llvm.log2.f64", 1),
+        "fmaf32" => simple_llvm_intrinsic(bcx, "llvm.fma.f32", 3),
+        "fmaf64" => simple_llvm_intrinsic(bcx, "llvm.fma.f64", 3),
+        "fabsf32" => simple_llvm_intrinsic(bcx, "llvm.fabs.f32", 1),
+        "fabsf64" => simple_llvm_intrinsic(bcx, "llvm.fabs.f64", 1),
+        "floorf32" => simple_llvm_intrinsic(bcx, "llvm.floor.f32", 1),
+        "floorf64" => simple_llvm_intrinsic(bcx, "llvm.floor.f64", 1),
+        "ceilf32" => simple_llvm_intrinsic(bcx, "llvm.ceil.f32", 1),
+        "ceilf64" => simple_llvm_intrinsic(bcx, "llvm.ceil.f64", 1),
+        "truncf32" => simple_llvm_intrinsic(bcx, "llvm.trunc.f32", 1),
+        "truncf64" => simple_llvm_intrinsic(bcx, "llvm.trunc.f64", 1),
+        "ctpop8" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i8", 1),
+        "ctpop16" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i16", 1),
+        "ctpop32" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i32", 1),
+        "ctpop64" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i64", 1),
+        "ctlz8" => count_zeros_intrinsic(bcx, "llvm.ctlz.i8"),
+        "ctlz16" => count_zeros_intrinsic(bcx, "llvm.ctlz.i16"),
+        "ctlz32" => count_zeros_intrinsic(bcx, "llvm.ctlz.i32"),
+        "ctlz64" => count_zeros_intrinsic(bcx, "llvm.ctlz.i64"),
+        "cttz8" => count_zeros_intrinsic(bcx, "llvm.cttz.i8"),
+        "cttz16" => count_zeros_intrinsic(bcx, "llvm.cttz.i16"),
+        "cttz32" => count_zeros_intrinsic(bcx, "llvm.cttz.i32"),
+        "cttz64" => count_zeros_intrinsic(bcx, "llvm.cttz.i64"),
+        "bswap16" => simple_llvm_intrinsic(bcx, "llvm.bswap.i16", 1),
+        "bswap32" => simple_llvm_intrinsic(bcx, "llvm.bswap.i32", 1),
+        "bswap64" => simple_llvm_intrinsic(bcx, "llvm.bswap.i64", 1),
+
+        "i8_add_with_overflow" => with_overflow_instrinsic(bcx, "llvm.sadd.with.overflow.i8"),
+        "i16_add_with_overflow" => with_overflow_instrinsic(bcx, "llvm.sadd.with.overflow.i16"),
+        "i32_add_with_overflow" => with_overflow_instrinsic(bcx, "llvm.sadd.with.overflow.i32"),
+        "i64_add_with_overflow" => with_overflow_instrinsic(bcx, "llvm.sadd.with.overflow.i64"),
+
+        "u8_add_with_overflow" => with_overflow_instrinsic(bcx, "llvm.uadd.with.overflow.i8"),
+        "u16_add_with_overflow" => with_overflow_instrinsic(bcx, "llvm.uadd.with.overflow.i16"),
+        "u32_add_with_overflow" => with_overflow_instrinsic(bcx, "llvm.uadd.with.overflow.i32"),
+        "u64_add_with_overflow" => with_overflow_instrinsic(bcx, "llvm.uadd.with.overflow.i64"),
+
+        "i8_sub_with_overflow" => with_overflow_instrinsic(bcx, "llvm.ssub.with.overflow.i8"),
+        "i16_sub_with_overflow" => with_overflow_instrinsic(bcx, "llvm.ssub.with.overflow.i16"),
+        "i32_sub_with_overflow" => with_overflow_instrinsic(bcx, "llvm.ssub.with.overflow.i32"),
+        "i64_sub_with_overflow" => with_overflow_instrinsic(bcx, "llvm.ssub.with.overflow.i64"),
+
+        "u8_sub_with_overflow" => with_overflow_instrinsic(bcx, "llvm.usub.with.overflow.i8"),
+        "u16_sub_with_overflow" => with_overflow_instrinsic(bcx, "llvm.usub.with.overflow.i16"),
+        "u32_sub_with_overflow" => with_overflow_instrinsic(bcx, "llvm.usub.with.overflow.i32"),
+        "u64_sub_with_overflow" => with_overflow_instrinsic(bcx, "llvm.usub.with.overflow.i64"),
+
+        "i8_mul_with_overflow" => with_overflow_instrinsic(bcx, "llvm.smul.with.overflow.i8"),
+        "i16_mul_with_overflow" => with_overflow_instrinsic(bcx, "llvm.smul.with.overflow.i16"),
+        "i32_mul_with_overflow" => with_overflow_instrinsic(bcx, "llvm.smul.with.overflow.i32"),
+        "i64_mul_with_overflow" => with_overflow_instrinsic(bcx, "llvm.smul.with.overflow.i64"),
+
+        "u8_mul_with_overflow" => with_overflow_instrinsic(bcx, "llvm.umul.with.overflow.i8"),
+        "u16_mul_with_overflow" => with_overflow_instrinsic(bcx, "llvm.umul.with.overflow.i16"),
+        "u32_mul_with_overflow" => with_overflow_instrinsic(bcx, "llvm.umul.with.overflow.i32"),
+        "u64_mul_with_overflow" => with_overflow_instrinsic(bcx, "llvm.umul.with.overflow.i64"),
+
+        _ => {
+            // Could we make this an enum rather than a string? does it get
+            // checked earlier?
+            ccx.sess.span_bug(item.span, "unknown intrinsic");
+        }
+    }
+    fcx.cleanup();
+}
index f5b2ff755966e6cf3f29ff2f7b2cb2fe26202d19..9ffbafb706cd4ab8ce68d65c277a622af86e1a8e 100644 (file)
@@ -537,7 +537,7 @@ pub fn make_vtable(ccx: &mut CrateContext,
 
         let tbl = C_struct(components);
         let vtable = ccx.sess.str_of(gensym_name("vtable"));
-        let vt_gvar = do vtable.to_c_str().with_ref |buf| {
+        let vt_gvar = do vtable.with_c_str |buf| {
             llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl).to_ref(), buf)
         };
         llvm::LLVMSetInitializer(vt_gvar, tbl);
index 387a8ecc5eec60a6d39392bc4784b5104618281d..cf6d465cb820c50f230e222cac3b3f3d7f73091f 100644 (file)
@@ -35,6 +35,7 @@
 pub mod cabi_arm;
 pub mod cabi_mips;
 pub mod foreign;
+pub mod intrinsic;
 pub mod reflect;
 pub mod debuginfo;
 pub mod type_use;
index 21ef9058069ab3154c5a3a0be766166b92b56fa2..5249a2b9b7bb642443ed9b7659d2c5afeb8ce967 100644 (file)
 use middle::trans::base;
 use middle::trans::common::*;
 use middle::trans::datum;
-use middle::trans::foreign;
 use middle::trans::machine;
 use middle::trans::meth;
 use middle::trans::type_of::type_of_fn_from_ty;
 use middle::trans::type_of;
 use middle::trans::type_use;
+use middle::trans::intrinsic;
 use middle::ty;
 use middle::ty::{FnSig};
 use middle::typeck;
@@ -239,8 +239,8 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
       }
       ast_map::node_foreign_item(i, _, _, _) => {
           let d = mk_lldecl();
-          foreign::trans_intrinsic(ccx, d, i, pt, psubsts, i.attrs,
-                                ref_id);
+          intrinsic::trans_intrinsic(ccx, d, i, pt, psubsts, i.attrs,
+                                     ref_id);
           d
       }
       ast_map::node_variant(ref v, enum_item, _) => {
index fe5f8cd70ef19ba1d7f366c9373067b183634024..dd1b041ef80f1aae3d49dd4012a6b087986b3464 100644 (file)
@@ -284,7 +284,7 @@ pub fn visit_ty(&mut self, t: ty::t) {
                                                                sub_path,
                                                                "get_disr");
 
-                let llfty = type_of_fn(ccx, [opaqueptrty], ty::mk_int());
+                let llfty = type_of_rust_fn(ccx, [opaqueptrty], ty::mk_int());
                 let llfdecl = decl_internal_cdecl_fn(ccx.llmod, sym, llfty);
                 let fcx = new_fn_ctxt(ccx,
                                       ~[],
index 5b0e2fa18f240af3716c6604a6ae391512b18d5e..47d5b7ff3a53f9ae5b72793068a0b84f919b3fd8 100644 (file)
@@ -265,7 +265,7 @@ pub fn trans_lit_str(bcx: @mut Block,
         Ignore => bcx,
         SaveIn(lldest) => {
             unsafe {
-                let bytes = str_lit.len(); // count null-terminator too
+                let bytes = str_lit.len();
                 let llbytes = C_uint(bcx.ccx(), bytes);
                 let llcstr = C_cstr(bcx.ccx(), str_lit);
                 let llcstr = llvm::LLVMConstPointerCast(llcstr, Type::i8p().to_ref());
index 8d94a0d10d6fae3c71e2b5754b157886cd3fb334..f8f6f7b87ec6a9419208f6cf08bd98bde9b55226 100644 (file)
@@ -171,7 +171,7 @@ pub fn struct_(els: &[Type], packed: bool) -> Type {
 
     pub fn named_struct(name: &str) -> Type {
         let ctx = base::task_llcx();
-        ty!(name.to_c_str().with_ref(|s| llvm::LLVMStructCreateNamed(ctx, s)))
+        ty!(name.with_c_str(|s| llvm::LLVMStructCreateNamed(ctx, s)))
     }
 
     pub fn empty_struct() -> Type {
index 6a382cc1a5d1cc82b6682d6fc34a32683c5509c2..6a57827e6d1c60ab3a6f2599a4c62d6ee1e17e55 100644 (file)
@@ -11,6 +11,7 @@
 
 use middle::trans::adt;
 use middle::trans::common::*;
+use middle::trans::foreign;
 use middle::ty;
 use util::ppaux;
 
 use syntax::ast;
 use syntax::opt_vec;
 
-pub fn arg_is_indirect(ccx: &CrateContext, arg_ty: &ty::t) -> bool {
-    !ty::type_is_immediate(ccx.tcx, *arg_ty)
+pub fn arg_is_indirect(ccx: &CrateContext, arg_ty: ty::t) -> bool {
+    !ty::type_is_immediate(ccx.tcx, arg_ty)
 }
 
-pub fn type_of_explicit_arg(ccx: &mut CrateContext, arg_ty: &ty::t) -> Type {
-    let llty = type_of(ccx, *arg_ty);
+pub fn return_uses_outptr(tcx: ty::ctxt, ty: ty::t) -> bool {
+    !ty::type_is_immediate(tcx, ty)
+}
+
+pub fn type_of_explicit_arg(ccx: &mut CrateContext, arg_ty: ty::t) -> Type {
+    let llty = type_of(ccx, arg_ty);
     if arg_is_indirect(ccx, arg_ty) {
         llty.ptr_to()
     } else {
@@ -34,17 +39,19 @@ pub fn type_of_explicit_arg(ccx: &mut CrateContext, arg_ty: &ty::t) -> Type {
 
 pub fn type_of_explicit_args(ccx: &mut CrateContext,
                              inputs: &[ty::t]) -> ~[Type] {
-    inputs.map(|arg_ty| type_of_explicit_arg(ccx, arg_ty))
+    inputs.map(|&arg_ty| type_of_explicit_arg(ccx, arg_ty))
 }
 
-pub fn type_of_fn(cx: &mut CrateContext, inputs: &[ty::t], output: ty::t) -> Type {
+pub fn type_of_rust_fn(cx: &mut CrateContext,
+                       inputs: &[ty::t],
+                       output: ty::t) -> Type {
     let mut atys: ~[Type] = ~[];
 
     // Arg 0: Output pointer.
     // (if the output type is non-immediate)
-    let output_is_immediate = ty::type_is_immediate(cx.tcx, output);
+    let use_out_pointer = return_uses_outptr(cx.tcx, output);
     let lloutputtype = type_of(cx, output);
-    if !output_is_immediate {
+    if use_out_pointer {
         atys.push(lloutputtype.ptr_to());
     }
 
@@ -55,7 +62,7 @@ pub fn type_of_fn(cx: &mut CrateContext, inputs: &[ty::t], output: ty::t) -> Typ
     atys.push_all(type_of_explicit_args(cx, inputs));
 
     // Use the output as the actual return value if it's immediate.
-    if output_is_immediate && !ty::type_is_nil(output) {
+    if !use_out_pointer && !ty::type_is_voidish(output) {
         Type::func(atys, &lloutputtype)
     } else {
         Type::func(atys, &Type::void())
@@ -64,13 +71,21 @@ pub fn type_of_fn(cx: &mut CrateContext, inputs: &[ty::t], output: ty::t) -> Typ
 
 // Given a function type and a count of ty params, construct an llvm type
 pub fn type_of_fn_from_ty(cx: &mut CrateContext, fty: ty::t) -> Type {
-    match ty::get(fty).sty {
-        ty::ty_closure(ref f) => type_of_fn(cx, f.sig.inputs, f.sig.output),
-        ty::ty_bare_fn(ref f) => type_of_fn(cx, f.sig.inputs, f.sig.output),
+    return match ty::get(fty).sty {
+        ty::ty_closure(ref f) => {
+            type_of_rust_fn(cx, 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, f.sig.inputs, f.sig.output)
+            } else {
+                foreign::lltype_for_foreign_fn(cx, fty)
+            }
+        }
         _ => {
             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
@@ -250,7 +265,9 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type {
           Type::array(&type_of(cx, mt.ty), n as u64)
       }
 
-      ty::ty_bare_fn(_) => type_of_fn_from_ty(cx, t).ptr_to(),
+      ty::ty_bare_fn(_) => {
+          type_of_fn_from_ty(cx, t).ptr_to()
+      }
       ty::ty_closure(_) => {
           let ty = type_of_fn_from_ty(cx, t);
           Type::func_pair(cx, &ty)
index 80d6ce6ab080971f36967675ba5f299d92c1d671..685699f781900e741a98d3c44516ef5df2a8cc1e 100644 (file)
@@ -1545,6 +1545,11 @@ pub fn subst(cx: ctxt,
 
 // Type utilities
 
+pub fn type_is_voidish(ty: t) -> bool {
+    //! "nil" and "bot" are void types in that they represent 0 bits of information
+    type_is_nil(ty) || type_is_bot(ty)
+}
+
 pub fn type_is_nil(ty: t) -> bool { get(ty).sty == ty_nil }
 
 pub fn type_is_bot(ty: t) -> bool {
index 258802c2699ff6af0e923f95cdfd417c18a7b037..ad6bf69d55ad6c22a439223bf7ab86efc8be2569 100644 (file)
@@ -947,15 +947,7 @@ pub fn report_mismatched_return_types(&self,
         if ty::type_is_error(e) || ty::type_is_error(a) {
             return;
         }
-        match self.fn_kind {
-            DoBlock if ty::type_is_bool(e) && ty::type_is_nil(a) =>
-                // If we expected bool and got ()...
-                    self.tcx().sess.span_err(sp, fmt!("Do-block body must \
-                        return %s, but returns () here. Perhaps you meant \
-                        to write a `for`-loop?",
-                        ppaux::ty_to_str(self.tcx(), e))),
-            _ => self.infcx().report_mismatched_types(sp, e, a, err)
-        }
+        self.infcx().report_mismatched_types(sp, e, a, err)
     }
 
     pub fn report_mismatched_types(&self,
index b1492cac16e730213de27e1178a3a53e9da0f287..161d96d828b47c8830c1fd0f3406bb76cf7d1b28 100644 (file)
@@ -68,7 +68,7 @@
 use middle::typeck::infer::{TypeTrace};
 use util::common::indent;
 
-use std::result::{iter_vec2, map_vec2};
+use std::result;
 use std::vec;
 use syntax::ast::{Onceness, purity};
 use syntax::ast;
@@ -275,9 +275,9 @@ pub fn super_tps<C:Combine>(
     // variance.
 
     if vec::same_length(as_, bs) {
-        iter_vec2(as_, bs, |a, b| {
-            eq_tys(this, *a, *b)
-        }).then(|| Ok(as_.to_owned()) )
+        result::fold_(as_.iter().zip(bs.iter())
+                      .map(|(a, b)| eq_tys(this, *a, *b)))
+            .then(|| Ok(as_.to_owned()))
     } else {
         Err(ty::terr_ty_param_size(
             expected_found(this, as_.len(), bs.len())))
@@ -427,7 +427,8 @@ pub fn super_fn_sigs<C:Combine>(
 {
     fn argvecs<C:Combine>(this: &C, a_args: &[ty::t], b_args: &[ty::t]) -> cres<~[ty::t]> {
         if vec::same_length(a_args, b_args) {
-            map_vec2(a_args, b_args, |a, b| this.args(*a, *b))
+            result::collect(a_args.iter().zip(b_args.iter())
+                            .map(|(a, b)| this.args(*a, *b)))
         } else {
             Err(ty::terr_arg_count)
         }
@@ -586,8 +587,9 @@ pub fn super_tys<C:Combine>(
 
       (&ty::ty_tup(ref as_), &ty::ty_tup(ref bs)) => {
         if as_.len() == bs.len() {
-            map_vec2(*as_, *bs, |a, b| this.tys(*a, *b) )
-                .chain(|ts| Ok(ty::mk_tup(tcx, ts)) )
+            result::collect(as_.iter().zip(bs.iter())
+                            .map(|(a, b)| this.tys(*a, *b)))
+                    .chain(|ts| Ok(ty::mk_tup(tcx, ts)) )
         } else {
             Err(ty::terr_tuple_size(
                 expected_found(this, as_.len(), bs.len())))
index 195ff0dc6b695ed4e5ef5f20c5ced41bf7465bc7..f9cbab58211e6475296a4db16e6207c6fa6a49b6 100644 (file)
 #[license = "MIT/ASL2"];
 #[crate_type = "lib"];
 
+// Rustc tasks always run on a fixed_stack_segment, so code in this
+// module can call C functions (in particular, LLVM functions) with
+// impunity.
+#[allow(cstack)];
+
 extern mod extra;
 extern mod syntax;
 
@@ -68,6 +73,7 @@ pub mod middle {
     pub mod reachable;
     pub mod graph;
     pub mod cfg;
+    pub mod stack_check;
 }
 
 pub mod front {
@@ -252,7 +258,7 @@ pub fn run_compiler(args: &~[~str], demitter: diagnostic::Emitter) {
     let sess = build_session(sopts, demitter);
     let odir = getopts::opt_maybe_str(matches, "out-dir").map_move(|o| Path(o));
     let ofile = getopts::opt_maybe_str(matches, "o").map_move(|o| Path(o));
-    let cfg = build_configuration(sess, binary, &input);
+    let cfg = build_configuration(sess);
     let pretty = do getopts::opt_default(matches, "pretty", "normal").map_move |a| {
         parse_pretty(sess, a)
     };
@@ -359,7 +365,7 @@ impl Drop for finally {
                 let xs = [
                     ~"the compiler hit an unexpected failure path. \
                      this is a bug",
-                    ~"try running with RUST_LOG=rustc=1,::rt::backtrace \
+                    ~"try running with RUST_LOG=rustc=1 \
                      to get further details and report the results \
                      to github.com/mozilla/rust/issues"
                 ];
index 3bc0a7167e9bdd8a2ce7f59c3e466f59293c5ab0..5ba52326579e1b1d820218f1b83e0df5f663d3d1 100644 (file)
@@ -862,3 +862,15 @@ fn user_string(&self, tcx: ctxt) -> ~str {
         ty_to_str(tcx, *self)
     }
 }
+
+impl Repr for AbiSet {
+    fn repr(&self, _tcx: ctxt) -> ~str {
+        self.to_str()
+    }
+}
+
+impl UserString for AbiSet {
+    fn user_string(&self, _tcx: ctxt) -> ~str {
+        self.to_str()
+    }
+}
index c0e506774a371c3c787dc24001dfa59a4cbbf0bf..a8321dd95a1594276dbc35195b0af29cb2f855c4 100644 (file)
@@ -10,8 +10,6 @@
 
 //! AST-parsing helpers
 
-
-use rustc::driver::driver::{file_input, str_input};
 use rustc::driver::driver;
 use rustc::driver::session;
 use syntax::ast;
@@ -29,14 +27,15 @@ pub fn from_str(source: @str) -> @ast::Crate {
 
 pub fn from_file_sess(sess: session::Session, file: &Path) -> @ast::Crate {
     parse::parse_crate_from_file(
-        file, cfg(sess, file_input((*file).clone())), sess.parse_sess)
+        file, cfg(sess), sess.parse_sess)
 }
 
 pub fn from_str_sess(sess: session::Session, source: @str) -> @ast::Crate {
     parse::parse_crate_from_source_str(
-        @"-", source, cfg(sess, str_input(source)), sess.parse_sess)
+        @"-", source, cfg(sess), sess.parse_sess)
 }
 
-fn cfg(sess: session::Session, input: driver::input) -> ast::CrateConfig {
-    driver::build_configuration(sess, @"rustdoc", &input)
+fn cfg(sess: session::Session) -> ast::CrateConfig {
+    driver::build_configuration(sess)
 }
+
index 29ad9eb49a3b120526aff145cdd83f9172a50331..d4bee13aae7f97eb3a180a150eebfd59c5f52239 100644 (file)
@@ -142,7 +142,7 @@ fn run(mut program: ~Program, binary: ~str, lib_search_paths: ~[~str],
     // Stage 1: parse the input and filter it into the program (as necessary)
     //
     debug!("parsing: %s", input);
-    let crate = parse_input(sess, binary, input);
+    let crate = parse_input(sess, binary);
     let mut to_run = ~[];       // statements to run (emitted back into code)
     let new_locals = @mut ~[];  // new locals being defined
     let mut result = None;      // resultant expression (to print via pp)
@@ -222,7 +222,7 @@ fn run(mut program: ~Program, binary: ~str, lib_search_paths: ~[~str],
     let test = program.test_code(input, &result, *new_locals);
     debug!("testing with ^^^^^^ %?", (||{ println(test) })());
     let dinput = driver::str_input(test.to_managed());
-    let cfg = driver::build_configuration(sess, binary, &dinput);
+    let cfg = driver::build_configuration(sess);
 
     let crate = driver::phase_1_parse_input(sess, cfg.clone(), &dinput);
     let expanded_crate = driver::phase_2_configure_and_expand(sess, cfg, crate);
@@ -241,7 +241,7 @@ fn run(mut program: ~Program, binary: ~str, lib_search_paths: ~[~str],
     let code = program.code(input, &result);
     debug!("actually running ^^^^^^ %?", (||{ println(code) })());
     let input = driver::str_input(code.to_managed());
-    let cfg = driver::build_configuration(sess, binary, &input);
+    let cfg = driver::build_configuration(sess);
     let outputs = driver::build_output_filenames(&input, &None, &None, [], sess);
     let sess = driver::build_session(options, diagnostic::emit);
 
@@ -266,11 +266,10 @@ fn run(mut program: ~Program, binary: ~str, lib_search_paths: ~[~str],
     //
     return (program, jit::consume_engine());
 
-    fn parse_input(sess: session::Session, binary: @str,
-                   input: &str) -> @ast::Crate {
+    fn parse_input(sess: session::Session, input: &str) -> @ast::Crate {
         let code = fmt!("fn main() {\n %s \n}", input);
         let input = driver::str_input(code.to_managed());
-        let cfg = driver::build_configuration(sess, binary, &input);
+        let cfg = driver::build_configuration(sess);
         driver::phase_1_parse_input(sess, cfg.clone(), &input)
     }
 
@@ -308,7 +307,7 @@ fn compile_crate(src_filename: ~str, binary: ~str) -> Option<bool> {
         let input = driver::file_input(src_path.clone());
         let sess = driver::build_session(options, diagnostic::emit);
         *sess.building_library = true;
-        let cfg = driver::build_configuration(sess, binary, &input);
+        let cfg = driver::build_configuration(sess);
         let outputs = driver::build_output_filenames(
             &input, &None, &None, [], sess);
         // If the library already exists and is newer than the source
@@ -499,6 +498,8 @@ pub fn run_line(repl: &mut Repl, input: @io::Reader, out: @io::Writer, line: ~st
 }
 
 pub fn main() {
+    #[fixed_stack_segment]; #[inline(never)];
+
     let args = os::args();
     let input = io::stdin();
     let out = io::stdout();
index 3ae2ad3751ffb0ddda5b09c0e128d7c74e3d3744..9ef341e439a97e62b9e56953915046433a6dec71 100644 (file)
@@ -108,7 +108,7 @@ fn parse<'a>(script: Path, workspace: &Path, id: &'a PkgId) -> PkgScript<'a> {
         };
         let input = driver::file_input(script);
         let sess = driver::build_session(options, diagnostic::emit);
-        let cfg = driver::build_configuration(sess, binary, &input);
+        let cfg = driver::build_configuration(sess);
         let crate = driver::phase_1_parse_input(sess, cfg.clone(), &input);
         let crate = driver::phase_2_configure_and_expand(sess, cfg.clone(), crate);
         let work_dir = build_pkg_id_in_workspace(id, workspace);
index 121dcf40150211f56aea9e52f9036b227a5a42df..be3cb644edbaa3f3685ae978376ec3b42aac26de 100644 (file)
@@ -114,7 +114,7 @@ fn mk_temp_workspace(short_name: &Path, version: &Version) -> Path {
 fn run_git(args: &[~str], env: Option<~[(~str, ~str)]>, cwd: &Path, err_msg: &str) {
     let cwd = (*cwd).clone();
     let mut prog = run::Process::new("git", args, run::ProcessOptions {
-        env: env.map(|v| v.slice(0, v.len())),
+        env: env,
         dir: Some(&cwd),
         in_fd: None,
         out_fd: None,
@@ -222,7 +222,7 @@ fn command_line_test_with_env(args: &[~str], cwd: &Path, env: Option<~[(~str, ~s
     assert!(os::path_is_dir(&*cwd));
     let cwd = (*cwd).clone();
     let mut prog = run::Process::new(cmd, args, run::ProcessOptions {
-        env: env.map(|v| v.slice(0, v.len())),
+        env: env,
         dir: Some(&cwd),
         in_fd: None,
         out_fd: None,
@@ -757,7 +757,9 @@ fn rust_path_test() {
                                      // use command_line_test_with_env
     let mut prog = run::Process::new("rustpkg",
                                      [~"install", ~"foo"],
-                                     run::ProcessOptions { env: Some(&[(~"RUST_LOG",
+// This should actually extend the environment; then we can probably
+// un-ignore it
+                                     run::ProcessOptions { env: Some(~[(~"RUST_LOG",
                                                                         ~"rustpkg"),
                                                                        (~"RUST_PATH",
                                                                        dir_for_path.to_str())]),
@@ -1039,7 +1041,7 @@ fn test_extern_mod() {
                                                       ~"--sysroot", test_sysroot().to_str(),
                                                ~"-o", exec_file.to_str()],
                                      run::ProcessOptions {
-        env: env.map(|v| v.slice(0, v.len())),
+        env: env,
         dir: Some(&dir),
         in_fd: None,
         out_fd: None,
index afac9423fba66027da5112787412f681a96f3bb2..41c1c7e31aeff82eb7503c354e1ee3af0dc647c1 100644 (file)
@@ -225,7 +225,7 @@ pub fn compile_input(ctxt: &Ctx,
 
     // Infer dependencies that rustpkg needs to build, by scanning for
     // `extern mod` directives.
-    let cfg = driver::build_configuration(sess, binary, &input);
+    let cfg = driver::build_configuration(sess);
     let mut crate = driver::phase_1_parse_input(sess, cfg.clone(), &input);
     crate = driver::phase_2_configure_and_expand(sess, cfg, crate);
 
@@ -382,6 +382,8 @@ pub fn find_and_install_dependencies(ctxt: &Ctx,
 
 #[cfg(windows)]
 pub fn link_exe(_src: &Path, _dest: &Path) -> bool {
+    #[fixed_stack_segment]; #[inline(never)];
+
     /* FIXME (#1768): Investigate how to do this on win32
        Node wraps symlinks by having a .bat,
        but that won't work with minGW. */
@@ -394,12 +396,14 @@ pub fn link_exe(_src: &Path, _dest: &Path) -> bool {
 #[cfg(target_os = "freebsd")]
 #[cfg(target_os = "macos")]
 pub fn link_exe(src: &Path, dest: &Path) -> bool {
+    #[fixed_stack_segment]; #[inline(never)];
+
     use std::c_str::ToCStr;
     use std::libc;
 
     unsafe {
-        do src.to_c_str().with_ref |src_buf| {
-            do dest.to_c_str().with_ref |dest_buf| {
+        do src.with_c_str |src_buf| {
+            do dest.with_c_str |dest_buf| {
                 libc::link(src_buf, dest_buf) == 0 as libc::c_int &&
                     libc::chmod(dest_buf, 755) == 0 as libc::c_int
             }
index c948074990a36824c9c8e9c10b09ff4eeba34cc5..120946ad161e3b710038e32a7a8a61f66719ab13 100644 (file)
@@ -200,7 +200,7 @@ pub mod raw {
      * Sets the length of a vector
      *
      * This will explicitly set the size of the vector, without actually
-     * modifing its buffers, so it is up to the caller to ensure that
+     * modifying its buffers, so it is up to the caller to ensure that
      * the vector is actually the specified size.
      */
     #[inline]
@@ -308,6 +308,7 @@ pub unsafe fn reserve_at_least<T>(v: &mut @[T], n: uint) {
 mod test {
     use super::*;
     use prelude::*;
+    use bh = extra::test::BenchHarness;
 
     #[test]
     fn test() {
@@ -347,4 +348,84 @@ fn test_to_managed() {
         assert_eq!(to_managed([@"abc", @"123"]), @[@"abc", @"123"]);
         assert_eq!(to_managed([@[42]]), @[@[42]]);
     }
+
+    #[bench]
+    fn bench_capacity(b: &mut bh) {
+        let x = @[1, 2, 3];
+        do b.iter {
+            capacity(x);
+        }
+    }
+
+    #[bench]
+    fn bench_build_sized(b: &mut bh) {
+        let len = 64;
+        do b.iter {
+            build_sized(len, |push| for i in range(0, 1024) { push(i) });
+        }
+    }
+
+    #[bench]
+    fn bench_build(b: &mut bh) {
+        do b.iter {
+            for i in range(0, 95) {
+                build(|push| push(i));
+            }
+        }
+    }
+
+    #[bench]
+    fn bench_append(b: &mut bh) {
+        let lhs = @[7, ..128];
+        let rhs = range(0, 256).to_owned_vec();
+        do b.iter {
+            append(lhs, rhs);
+        }
+    }
+
+    #[bench]
+    fn bench_map(b: &mut bh) {
+        let elts = range(0, 256).to_owned_vec();
+        do b.iter {
+            map(elts, |x| x*2);
+        }
+    }
+
+    #[bench]
+    fn bench_from_fn(b: &mut bh) {
+        do b.iter {
+            from_fn(1024, |x| x);
+        }
+    }
+
+    #[bench]
+    fn bench_from_elem(b: &mut bh) {
+        do b.iter {
+            from_elem(1024, 0u64);
+        }
+    }
+
+    #[bench]
+    fn bench_to_managed_move(b: &mut bh) {
+        do b.iter {
+            let elts = range(0, 1024).to_owned_vec(); // yikes! can't move out of capture, though
+            to_managed_move(elts);
+        }
+    }
+
+    #[bench]
+    fn bench_to_managed(b: &mut bh) {
+        let elts = range(0, 1024).to_owned_vec();
+        do b.iter {
+            to_managed(elts);
+        }
+    }
+
+    #[bench]
+    fn bench_clone(b: &mut bh) {
+        let elts = to_managed(range(0, 1024).to_owned_vec());
+        do b.iter {
+            elts.clone();
+        }
+    }
 }
index 598e808061839f683c0fac6a3d8ec74afb54b4ac..b8175e43fb6695cee0dab8d25799df390eaebe06 100644 (file)
@@ -33,7 +33,7 @@
 
 Also, a few conversion functions: `to_bit` and `to_str`.
 
-Finally, some inquries into the nature of truth: `is_true` and `is_false`.
+Finally, some inquiries into the nature of truth: `is_true` and `is_false`.
 
 */
 
index 7e31354366084b061dffef714b178b0263badc03..98710c158e0d7f8d82e0719952ab13716a075e51 100644 (file)
@@ -9,14 +9,28 @@
 // except according to those terms.
 
 use cast;
-use iterator::Iterator;
+use iterator::{Iterator,range};
 use libc;
 use ops::Drop;
 use option::{Option, Some, None};
 use ptr::RawPtr;
 use ptr;
 use str::StrSlice;
-use vec::ImmutableVector;
+use vec::{ImmutableVector,CopyableVector};
+use container::Container;
+
+/// Resolution options for the `null_byte` condition
+pub enum NullByteResolution {
+    /// Truncate at the null byte
+    Truncate,
+    /// Use a replacement byte
+    ReplaceWith(libc::c_char)
+}
+
+condition! {
+    // this should be &[u8] but there's a lifetime issue
+    null_byte: (~[u8]) -> super::NullByteResolution;
+}
 
 /// The representation of a C String.
 ///
@@ -34,6 +48,7 @@ pub unsafe fn new(buf: *libc::c_char, owns_buffer: bool) -> CString {
     }
 
     /// Unwraps the wrapped `*libc::c_char` from the `CString` wrapper.
+    /// Any ownership of the buffer by the `CString` wrapper is forgotten.
     pub unsafe fn unwrap(self) -> *libc::c_char {
         let mut c_str = self;
         c_str.owns_buffer_ = false;
@@ -81,6 +96,7 @@ pub fn owns_buffer(&self) -> bool {
     ///
     /// Fails if the CString is null.
     pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
+        #[fixed_stack_segment]; #[inline(never)];
         if self.buf.is_null() { fail!("CString is null!"); }
         unsafe {
             let len = libc::strlen(self.buf) as uint;
@@ -89,7 +105,7 @@ pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
     }
 
     /// Return a CString iterator.
-    fn iter<'a>(&'a self) -> CStringIterator<'a> {
+    pub fn iter<'a>(&'a self) -> CStringIterator<'a> {
         CStringIterator {
             ptr: self.buf,
             lifetime: unsafe { cast::transmute(self.buf) },
@@ -99,6 +115,7 @@ fn iter<'a>(&'a self) -> CStringIterator<'a> {
 
 impl Drop for CString {
     fn drop(&self) {
+        #[fixed_stack_segment]; #[inline(never)];
         if self.owns_buffer_ {
             unsafe {
                 libc::free(self.buf as *libc::c_void)
@@ -109,8 +126,38 @@ fn drop(&self) {
 
 /// A generic trait for converting a value to a CString.
 pub trait ToCStr {
-    /// Create a C String.
+    /// Copy the receiver into a CString.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `null_byte` condition if the receiver has an interior null.
     fn to_c_str(&self) -> CString;
+
+    /// Unsafe variant of `to_c_str()` that doesn't check for nulls.
+    unsafe fn to_c_str_unchecked(&self) -> CString;
+
+    /// Work with a temporary CString constructed from the receiver.
+    /// The provided `*libc::c_char` will be freed immediately upon return.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let s = "PATH".with_c_str(|path| libc::getenv(path))
+    /// ~~~
+    ///
+    /// # Failure
+    ///
+    /// Raises the `null_byte` condition if the receiver has an interior null.
+    #[inline]
+    fn with_c_str<T>(&self, f: &fn(*libc::c_char) -> T) -> T {
+        self.to_c_str().with_ref(f)
+    }
+
+    /// Unsafe variant of `with_c_str()` that doesn't check for nulls.
+    #[inline]
+    unsafe fn with_c_str_unchecked<T>(&self, f: &fn(*libc::c_char) -> T) -> T {
+        self.to_c_str_unchecked().with_ref(f)
+    }
 }
 
 impl<'self> ToCStr for &'self str {
@@ -118,22 +165,45 @@ impl<'self> ToCStr for &'self str {
     fn to_c_str(&self) -> CString {
         self.as_bytes().to_c_str()
     }
+
+    #[inline]
+    unsafe fn to_c_str_unchecked(&self) -> CString {
+        self.as_bytes().to_c_str_unchecked()
+    }
 }
 
 impl<'self> ToCStr for &'self [u8] {
     fn to_c_str(&self) -> CString {
-        do self.as_imm_buf |self_buf, self_len| {
-            unsafe {
-                let buf = libc::malloc(self_len as libc::size_t + 1) as *mut u8;
-                if buf.is_null() {
-                    fail!("failed to allocate memory!");
+        #[fixed_stack_segment]; #[inline(never)];
+        let mut cs = unsafe { self.to_c_str_unchecked() };
+        do cs.with_mut_ref |buf| {
+            for i in range(0, self.len()) {
+                unsafe {
+                    let p = buf.offset_inbounds(i as int);
+                    if *p == 0 {
+                        match null_byte::cond.raise(self.to_owned()) {
+                            Truncate => break,
+                            ReplaceWith(c) => *p = c
+                        }
+                    }
                 }
+            }
+        }
+        cs
+    }
 
-                ptr::copy_memory(buf, self_buf, self_len);
-                *ptr::mut_offset(buf, self_len as int) = 0;
-
-                CString::new(buf as *libc::c_char, true)
+    unsafe fn to_c_str_unchecked(&self) -> CString {
+        #[fixed_stack_segment]; #[inline(never)];
+        do self.as_imm_buf |self_buf, self_len| {
+            let buf = libc::malloc(self_len as libc::size_t + 1) as *mut u8;
+            if buf.is_null() {
+                fail!("failed to allocate memory!");
             }
+
+            ptr::copy_memory(buf, self_buf, self_len);
+            *ptr::mut_offset(buf, self_len as int) = 0;
+
+            CString::new(buf as *libc::c_char, true)
         }
     }
 }
@@ -194,12 +264,16 @@ fn test_is_null() {
 
     #[test]
     fn test_unwrap() {
+        #[fixed_stack_segment]; #[inline(never)];
+
         let c_str = "hello".to_c_str();
         unsafe { libc::free(c_str.unwrap() as *libc::c_void) }
     }
 
     #[test]
     fn test_with_ref() {
+        #[fixed_stack_segment]; #[inline(never)];
+
         let c_str = "hello".to_c_str();
         let len = unsafe { c_str.with_ref(|buf| libc::strlen(buf)) };
         assert!(!c_str.is_null());
@@ -230,4 +304,49 @@ fn test_iterator() {
         assert_eq!(iter.next(), Some('o' as libc::c_char));
         assert_eq!(iter.next(), None);
     }
+
+    #[test]
+    #[ignore(cfg(windows))]
+    fn test_to_c_str_fail() {
+        use c_str::null_byte::cond;
+
+        let mut error_happened = false;
+        do cond.trap(|err| {
+            assert_eq!(err, bytes!("he", 0, "llo").to_owned())
+            error_happened = true;
+            Truncate
+        }).inside {
+            "he\x00llo".to_c_str()
+        };
+        assert!(error_happened);
+
+        do cond.trap(|_| {
+            ReplaceWith('?' as libc::c_char)
+        }).inside(|| "he\x00llo".to_c_str()).with_ref |buf| {
+            unsafe {
+                assert_eq!(*buf.offset(0), 'h' as libc::c_char);
+                assert_eq!(*buf.offset(1), 'e' as libc::c_char);
+                assert_eq!(*buf.offset(2), '?' as libc::c_char);
+                assert_eq!(*buf.offset(3), 'l' as libc::c_char);
+                assert_eq!(*buf.offset(4), 'l' as libc::c_char);
+                assert_eq!(*buf.offset(5), 'o' as libc::c_char);
+                assert_eq!(*buf.offset(6), 0);
+            }
+        }
+    }
+
+    #[test]
+    fn test_to_c_str_unchecked() {
+        unsafe {
+            do "he\x00llo".to_c_str_unchecked().with_ref |buf| {
+                assert_eq!(*buf.offset(0), 'h' as libc::c_char);
+                assert_eq!(*buf.offset(1), 'e' as libc::c_char);
+                assert_eq!(*buf.offset(2), 0);
+                assert_eq!(*buf.offset(3), 'l' as libc::c_char);
+                assert_eq!(*buf.offset(4), 'l' as libc::c_char);
+                assert_eq!(*buf.offset(5), 'o' as libc::c_char);
+                assert_eq!(*buf.offset(6), 0);
+            }
+        }
+    }
 }
index 132ebc72960117763498599345c2f41b9d632efe..5d988965e8cccc9ce61eb583530b63225b58caae 100644 (file)
@@ -16,7 +16,7 @@
 use clone::Clone;
 use container::Container;
 use cmp::Eq;
-use iterator::Iterator;
+use iterator::{Iterator, FilterMap};
 use result::Result;
 use result;
 use str::StrSlice;
@@ -116,40 +116,44 @@ pub fn unwrap_right(self) -> R {
     }
 }
 
-// FIXME: #8228 Replaceable by an external iterator?
-/// Extracts from a vector of either all the left values
-pub fn lefts<L: Clone, R>(eithers: &[Either<L, R>]) -> ~[L] {
-    do vec::build_sized(eithers.len()) |push| {
-        for elt in eithers.iter() {
-            match *elt {
-                Left(ref l) => { push((*l).clone()); }
-                _ => { /* fallthrough */ }
-            }
+/// An iterator yielding the `Left` values of its source
+pub type Lefts<L, R, Iter> = FilterMap<'static, Either<L, R>, L, Iter>;
+
+/// An iterator yielding the `Right` values of its source
+pub type Rights<L, R, Iter> = FilterMap<'static, Either<L, R>, R, Iter>;
+
+/// Extracts all the left values
+pub fn lefts<L, R, Iter: Iterator<Either<L, R>>>(eithers: Iter)
+    -> Lefts<L, R, Iter> {
+    do eithers.filter_map |elt| {
+        match elt {
+            Left(x) => Some(x),
+            _ => None,
         }
     }
 }
 
-// FIXME: #8228 Replaceable by an external iterator?
-/// Extracts from a vector of either all the right values
-pub fn rights<L, R: Clone>(eithers: &[Either<L, R>]) -> ~[R] {
-    do vec::build_sized(eithers.len()) |push| {
-        for elt in eithers.iter() {
-            match *elt {
-                Right(ref r) => { push((*r).clone()); }
-                _ => { /* fallthrough */ }
-            }
+/// Extracts all the right values
+pub fn rights<L, R, Iter: Iterator<Either<L, R>>>(eithers: Iter)
+    -> Rights<L, R, Iter> {
+    do eithers.filter_map |elt| {
+        match elt {
+            Right(x) => Some(x),
+            _ => None,
         }
     }
 }
 
+
 // FIXME: #8228 Replaceable by an external iterator?
 /// Extracts from a vector of either all the left values and right values
 ///
 /// Returns a structure containing a vector of left values and a vector of
 /// right values.
 pub fn partition<L, R>(eithers: ~[Either<L, R>]) -> (~[L], ~[R]) {
-    let mut lefts: ~[L] = ~[];
-    let mut rights: ~[R] = ~[];
+    let n_lefts = eithers.iter().count(|elt| elt.is_left());
+    let mut lefts = vec::with_capacity(n_lefts);
+    let mut rights = vec::with_capacity(eithers.len() - n_lefts);
     for elt in eithers.move_iter() {
         match elt {
             Left(l) => lefts.push(l),
@@ -182,42 +186,42 @@ fn f_right(x: &uint) -> bool { *x == 10u }
     #[test]
     fn test_lefts() {
         let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
-        let result = lefts(input);
+        let result = lefts(input.move_iter()).to_owned_vec();
         assert_eq!(result, ~[10, 12, 14]);
     }
 
     #[test]
     fn test_lefts_none() {
         let input: ~[Either<int, int>] = ~[Right(10), Right(10)];
-        let result = lefts(input);
+        let result = lefts(input.move_iter()).to_owned_vec();
         assert_eq!(result.len(), 0u);
     }
 
     #[test]
     fn test_lefts_empty() {
         let input: ~[Either<int, int>] = ~[];
-        let result = lefts(input);
+        let result = lefts(input.move_iter()).to_owned_vec();
         assert_eq!(result.len(), 0u);
     }
 
     #[test]
     fn test_rights() {
         let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
-        let result = rights(input);
+        let result = rights(input.move_iter()).to_owned_vec();
         assert_eq!(result, ~[11, 13]);
     }
 
     #[test]
     fn test_rights_none() {
         let input: ~[Either<int, int>] = ~[Left(10), Left(10)];
-        let result = rights(input);
+        let result = rights(input.move_iter()).to_owned_vec();
         assert_eq!(result.len(), 0u);
     }
 
     #[test]
     fn test_rights_empty() {
         let input: ~[Either<int, int>] = ~[];
-        let result = rights(input);
+        let result = rights(input.move_iter()).to_owned_vec();
         assert_eq!(result.len(), 0u);
     }
 
index 41e588934b72e00d1451e9e6b3f9f4300324a460..db8a17c0bd07099b52e702ef6a377e4f25ce6ef0 100644 (file)
@@ -93,7 +93,7 @@
 Because formatting is done via traits, there is no requirement that the
 `d` format actually takes an `int`, but rather it simply requires a type which
 ascribes to the `Signed` formatting trait. There are various parameters which do
-require a particular type, however. Namely if the sytnax `{:.*s}` is used, then
+require a particular type, however. Namely if the syntax `{:.*s}` is used, then
 the number of characters to print from the string precedes the actual string and
 must have the type `uint`. Although a `uint` can be printed with `{:u}`, it is
 illegal to reference an argument as such. For example, this is another invalid
 ## Internationalization
 
 The formatting syntax supported by the `ifmt!` extension supports
-internationalization by providing "methods" which execute various differnet
+internationalization by providing "methods" which execute various different
 outputs depending on the input. The syntax and methods provided are similar to
 other internationalization systems, so again nothing should seem alien.
 Currently two methods are supported by this extension: "select" and "plural".
@@ -356,28 +356,46 @@ pub struct Argument<'self> {
     priv value: &'self util::Void,
 }
 
+/// When a format is not otherwise specified, types are formatted by ascribing
+/// to this trait. There is not an explicit way of selecting this trait to be
+/// used for formatting, it is only if no other format is specified.
+#[allow(missing_doc)]
+pub trait Default { fn fmt(&Self, &mut Formatter); }
+
+/// Format trait for the `b` character
 #[allow(missing_doc)]
 pub trait Bool { fn fmt(&Self, &mut Formatter); }
+/// Format trait for the `c` character
 #[allow(missing_doc)]
 pub trait Char { fn fmt(&Self, &mut Formatter); }
+/// Format trait for the `i` and `d` characters
 #[allow(missing_doc)]
 pub trait Signed { fn fmt(&Self, &mut Formatter); }
+/// Format trait for the `u` character
 #[allow(missing_doc)]
 pub trait Unsigned { fn fmt(&Self, &mut Formatter); }
+/// Format trait for the `o` character
 #[allow(missing_doc)]
 pub trait Octal { fn fmt(&Self, &mut Formatter); }
+/// Format trait for the `b` character
 #[allow(missing_doc)]
 pub trait Binary { fn fmt(&Self, &mut Formatter); }
+/// Format trait for the `x` character
 #[allow(missing_doc)]
 pub trait LowerHex { fn fmt(&Self, &mut Formatter); }
+/// Format trait for the `X` character
 #[allow(missing_doc)]
 pub trait UpperHex { fn fmt(&Self, &mut Formatter); }
+/// Format trait for the `s` character
 #[allow(missing_doc)]
 pub trait String { fn fmt(&Self, &mut Formatter); }
+/// Format trait for the `?` character
 #[allow(missing_doc)]
 pub trait Poly { fn fmt(&Self, &mut Formatter); }
+/// Format trait for the `p` character
 #[allow(missing_doc)]
 pub trait Pointer { fn fmt(&Self, &mut Formatter); }
+/// Format trait for the `f` character
 #[allow(missing_doc)]
 pub trait Float { fn fmt(&Self, &mut Formatter); }
 
@@ -726,9 +744,9 @@ fn fmt(b: &bool, f: &mut Formatter) {
     }
 }
 
-impl<'self> String for &'self str {
-    fn fmt(s: & &'self str, f: &mut Formatter) {
-        f.pad(*s);
+impl<'self, T: str::Str> String for T {
+    fn fmt(s: &T, f: &mut Formatter) {
+        f.pad(s.as_slice());
     }
 }
 
@@ -855,5 +873,37 @@ fn fmt(t: &*const T, f: &mut Formatter) {
     }
 }
 
+// Implementation of Default for various core types
+
+macro_rules! delegate(($ty:ty to $other:ident) => {
+    impl<'self> Default for $ty {
+        fn fmt(me: &$ty, f: &mut Formatter) {
+            $other::fmt(me, f)
+        }
+    }
+})
+delegate!(int to Signed)
+delegate!( i8 to Signed)
+delegate!(i16 to Signed)
+delegate!(i32 to Signed)
+delegate!(i64 to Signed)
+delegate!(uint to Unsigned)
+delegate!(  u8 to Unsigned)
+delegate!( u16 to Unsigned)
+delegate!( u32 to Unsigned)
+delegate!( u64 to Unsigned)
+delegate!(@str to String)
+delegate!(~str to String)
+delegate!(&'self str to String)
+delegate!(bool to Bool)
+delegate!(char to Char)
+delegate!(float to Float)
+delegate!(f32 to Float)
+delegate!(f64 to Float)
+
+impl<T> Default for *const T {
+    fn fmt(me: &*const T, f: &mut Formatter) { Pointer::fmt(me, f) }
+}
+
 // If you expected tests to be here, look instead at the run-pass/ifmt.rs test,
 // it's a lot easier than creating all of the rt::Piece structures here.
index 0d39ae84a6057432a2887fee8a6ae4961ea52973..6448896a489419c4ac601e6a9b3529c88feabaad 100644 (file)
@@ -66,7 +66,7 @@ pub enum Position<'self> {
     ArgumentNext, ArgumentIs(uint), ArgumentNamed(&'self str)
 }
 
-/// Enum of alignments which are supoprted.
+/// Enum of alignments which are supported.
 #[deriving(Eq)]
 pub enum Alignment { AlignLeft, AlignRight, AlignUnknown }
 
@@ -339,7 +339,11 @@ fn format(&mut self) -> FormatSpec<'self> {
             }
         }
         // Finally the actual format specifier
-        spec.ty = self.word();
+        if self.consume('?') {
+            spec.ty = "?";
+        } else {
+            spec.ty = self.word();
+        }
         return spec;
     }
 
index c9d031ed1b1b05be141fa00d1694e21cf48c8b4f..f3df42f7a4386ae70a87be1f6f2daa7b03646031 100644 (file)
@@ -409,6 +409,14 @@ mod tests {
 
     use uint;
 
+    // Hash just the bytes of the slice, without length prefix
+    struct Bytes<'self>(&'self [u8]);
+    impl<'self> IterBytes for Bytes<'self> {
+        fn iter_bytes(&self, _lsb0: bool, f: &fn(&[u8]) -> bool) -> bool {
+            f(**self)
+        }
+    }
+
     #[test]
     fn test_siphash() {
         let vecs : [[u8, ..8], ..64] = [
@@ -496,7 +504,7 @@ fn to_hex_str(r: &[u8, ..8]) -> ~str {
         while t < 64 {
             debug!("siphash test %?", t);
             let vec = u8to64_le!(vecs[t], 0);
-            let out = buf.hash_keyed(k0, k1);
+            let out = Bytes(buf.as_slice()).hash_keyed(k0, k1);
             debug!("got %?, expected %?", out, vec);
             assert_eq!(vec, out);
 
@@ -587,4 +595,18 @@ fn test_float_hashes_differ() {
     fn test_float_hashes_of_zero() {
         assert_eq!(0.0.hash(), (-0.0).hash());
     }
+
+    #[test]
+    fn test_hash_no_concat_alias() {
+        let s = ("aa", "bb");
+        let t = ("aabb", "");
+        let u = ("a", "abb");
+
+        let v = (&[1u8], &[0u8, 0], &[0u8]);
+        let w = (&[1u8, 0, 0, 0], &[], &[]);
+
+        assert!(v != w);
+        assert!(s.hash() != t.hash() && s.hash() != u.hash());
+        assert!(v.hash() != w.hash());
+    }
 }
index 201d4692694650158124b87df403d610b5579591..50e59cf438d0c21b46446664d40998497fd9f66d 100644 (file)
@@ -605,8 +605,8 @@ fn next(&mut self) -> Option<K> {
     }
 }
 
-impl<K: Eq + Hash, V, T: Iterator<(K, V)>> FromIterator<(K, V), T> for HashMap<K, V> {
-    fn from_iterator(iter: &mut T) -> HashMap<K, V> {
+impl<K: Eq + Hash, V> FromIterator<(K, V)> for HashMap<K, V> {
+    fn from_iterator<T: Iterator<(K, V)>>(iter: &mut T) -> HashMap<K, V> {
         let (lower, _) = iter.size_hint();
         let mut map = HashMap::with_capacity(lower);
         map.extend(iter);
@@ -614,8 +614,8 @@ fn from_iterator(iter: &mut T) -> HashMap<K, V> {
     }
 }
 
-impl<K: Eq + Hash, V, T: Iterator<(K, V)>> Extendable<(K, V), T> for HashMap<K, V> {
-    fn extend(&mut self, iter: &mut T) {
+impl<K: Eq + Hash, V> Extendable<(K, V)> for HashMap<K, V> {
+    fn extend<T: Iterator<(K, V)>>(&mut self, iter: &mut T) {
         for (k, v) in *iter {
             self.insert(k, v);
         }
@@ -753,8 +753,8 @@ fn clone(&self) -> HashSet<T> {
     }
 }
 
-impl<K: Eq + Hash, T: Iterator<K>> FromIterator<K, T> for HashSet<K> {
-    fn from_iterator(iter: &mut T) -> HashSet<K> {
+impl<K: Eq + Hash> FromIterator<K> for HashSet<K> {
+    fn from_iterator<T: Iterator<K>>(iter: &mut T) -> HashSet<K> {
         let (lower, _) = iter.size_hint();
         let mut set = HashSet::with_capacity(lower);
         set.extend(iter);
@@ -762,8 +762,8 @@ fn from_iterator(iter: &mut T) -> HashSet<K> {
     }
 }
 
-impl<K: Eq + Hash, T: Iterator<K>> Extendable<K, T> for HashSet<K> {
-    fn extend(&mut self, iter: &mut T) {
+impl<K: Eq + Hash> Extendable<K> for HashSet<K> {
+    fn extend<T: Iterator<K>>(&mut self, iter: &mut T) {
         for k in *iter {
             self.insert(k);
         }
index 2c18bd272e81785cdc1379d708322cb0f0786918..8f5a3728e95b4845f2ce6de11e0fbf39ced394b8 100644 (file)
@@ -928,6 +928,8 @@ fn convert_whence(whence: SeekStyle) -> i32 {
 
 impl Reader for *libc::FILE {
     fn read(&self, bytes: &mut [u8], len: uint) -> uint {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             do bytes.as_mut_buf |buf_p, buf_len| {
                 assert!(buf_len >= len);
@@ -950,16 +952,22 @@ fn read(&self, bytes: &mut [u8], len: uint) -> uint {
         }
     }
     fn read_byte(&self) -> int {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             libc::fgetc(*self) as int
         }
     }
     fn eof(&self) -> bool {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             return libc::feof(*self) != 0 as c_int;
         }
     }
     fn seek(&self, offset: int, whence: SeekStyle) {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             assert!(libc::fseek(*self,
                                      offset as c_long,
@@ -967,6 +975,8 @@ fn seek(&self, offset: int, whence: SeekStyle) {
         }
     }
     fn tell(&self) -> uint {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             return libc::ftell(*self) as uint;
         }
@@ -1005,6 +1015,8 @@ pub fn new(f: *libc::FILE) -> FILERes {
 
 impl Drop for FILERes {
     fn drop(&self) {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             libc::fclose(self.f);
         }
@@ -1029,20 +1041,24 @@ pub fn FILE_reader(f: *libc::FILE, cleanup: bool) -> @Reader {
 * # Example
 *
 * ~~~ {.rust}
-* let stdin = core::io::stdin();
+* let stdin = std::io::stdin();
 * let line = stdin.read_line();
-* core::io::print(line);
+* std::io::print(line);
 * ~~~
 */
 pub fn stdin() -> @Reader {
+    #[fixed_stack_segment]; #[inline(never)];
+
     unsafe {
         @rustrt::rust_get_stdin() as @Reader
     }
 }
 
 pub fn file_reader(path: &Path) -> Result<@Reader, ~str> {
-    let f = do path.to_c_str().with_ref |pathbuf| {
-        do "rb".to_c_str().with_ref |modebuf| {
+    #[fixed_stack_segment]; #[inline(never)];
+
+    let f = do path.with_c_str |pathbuf| {
+        do "rb".with_c_str |modebuf| {
             unsafe { libc::fopen(pathbuf, modebuf as *libc::c_char) }
         }
     };
@@ -1162,6 +1178,8 @@ fn get_type(&self) -> WriterType { File }
 
 impl Writer for *libc::FILE {
     fn write(&self, v: &[u8]) {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             do v.as_imm_buf |vbuf, len| {
                 let nout = libc::fwrite(vbuf as *c_void,
@@ -1177,6 +1195,8 @@ fn write(&self, v: &[u8]) {
         }
     }
     fn seek(&self, offset: int, whence: SeekStyle) {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             assert!(libc::fseek(*self,
                                      offset as c_long,
@@ -1184,16 +1204,22 @@ fn seek(&self, offset: int, whence: SeekStyle) {
         }
     }
     fn tell(&self) -> uint {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             libc::ftell(*self) as uint
         }
     }
     fn flush(&self) -> int {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             libc::fflush(*self) as int
         }
     }
     fn get_type(&self) -> WriterType {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             let fd = libc::fileno(*self);
             if libc::isatty(fd) == 0 { File   }
@@ -1212,6 +1238,8 @@ pub fn FILE_writer(f: *libc::FILE, cleanup: bool) -> @Writer {
 
 impl Writer for fd_t {
     fn write(&self, v: &[u8]) {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             let mut count = 0u;
             do v.as_imm_buf |vbuf, len| {
@@ -1238,6 +1266,8 @@ fn tell(&self) -> uint {
     }
     fn flush(&self) -> int { 0 }
     fn get_type(&self) -> WriterType {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             if libc::isatty(*self) == 0 { File } else { Screen }
         }
@@ -1256,6 +1286,8 @@ pub fn new(fd: fd_t) -> FdRes {
 
 impl Drop for FdRes {
     fn drop(&self) {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             libc::close(self.fd);
         }
@@ -1273,6 +1305,8 @@ pub fn fd_writer(fd: fd_t, cleanup: bool) -> @Writer {
 
 pub fn mk_file_writer(path: &Path, flags: &[FileFlag])
                    -> Result<@Writer, ~str> {
+    #[fixed_stack_segment]; #[inline(never)];
+
     #[cfg(windows)]
     fn wb() -> c_int {
       (O_WRONLY | libc::consts::os::extra::O_BINARY) as c_int
@@ -1291,7 +1325,7 @@ fn wb() -> c_int { O_WRONLY as c_int }
         }
     }
     let fd = unsafe {
-        do path.to_c_str().with_ref |pathbuf| {
+        do path.with_c_str |pathbuf| {
             libc::open(pathbuf, fflags, (S_IRUSR | S_IWUSR) as c_int)
         }
     };
@@ -1462,7 +1496,7 @@ pub trait WriterUtil {
     /// (8 bytes).
     fn write_le_f64(&self, f: f64);
 
-    /// Write a litten-endian IEEE754 single-precision floating-point
+    /// Write a little-endian IEEE754 single-precision floating-point
     /// (4 bytes).
     fn write_le_f32(&self, f: f32);
 
@@ -1573,9 +1607,11 @@ pub fn file_writer(path: &Path, flags: &[FileFlag]) -> Result<@Writer, ~str> {
 
 // FIXME: fileflags // #2004
 pub fn buffered_file_writer(path: &Path) -> Result<@Writer, ~str> {
+    #[fixed_stack_segment]; #[inline(never)];
+
     unsafe {
-        let f = do path.to_c_str().with_ref |pathbuf| {
-            do "w".to_c_str().with_ref |modebuf| {
+        let f = do path.with_c_str |pathbuf| {
+            do "w".with_c_str |modebuf| {
                 libc::fopen(pathbuf, modebuf)
             }
         };
@@ -1598,7 +1634,7 @@ pub fn buffered_file_writer(path: &Path) -> Result<@Writer, ~str> {
 * # Example
 *
 * ~~~ {.rust}
-* let stdout = core::io::stdout();
+* let stdout = std::io::stdout();
 * stdout.write_str("hello\n");
 * ~~~
 */
@@ -1610,7 +1646,7 @@ pub fn stdout() -> @Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) }
 * # Example
 *
 * ~~~ {.rust}
-* let stderr = core::io::stderr();
+* let stderr = std::io::stderr();
 * stderr.write_str("hello\n");
 * ~~~
 */
@@ -1803,12 +1839,13 @@ pub fn FILE_res_sync(file: &FILERes, opt_level: Option<Level>,
                          blk: &fn(v: Res<*libc::FILE>)) {
         blk(Res::new(Arg {
             val: file.f, opt_level: opt_level,
-            fsync_fn: |file, l| {
-                unsafe {
-                    os::fsync_fd(libc::fileno(*file), l) as int
-                }
-            }
+            fsync_fn: |file, l| fsync_fd(fileno(*file), l)
         }));
+
+        fn fileno(stream: *libc::FILE) -> libc::c_int {
+            #[fixed_stack_segment]; #[inline(never)];
+            unsafe { libc::fileno(stream) }
+        }
     }
 
     // fsync fd after executing blk
@@ -1816,10 +1853,16 @@ pub fn fd_res_sync(fd: &FdRes, opt_level: Option<Level>,
                        blk: &fn(v: Res<fd_t>)) {
         blk(Res::new(Arg {
             val: fd.fd, opt_level: opt_level,
-            fsync_fn: |fd, l| os::fsync_fd(*fd, l) as int
+            fsync_fn: |fd, l| fsync_fd(*fd, l)
         }));
     }
 
+    fn fsync_fd(fd: libc::c_int, level: Level) -> int {
+        #[fixed_stack_segment]; #[inline(never)];
+
+        os::fsync_fd(fd, level) as int
+    }
+
     // Type of objects that may want to fsync
     pub trait FSyncable { fn fsync(&self, l: Level) -> int; }
 
index bd89c271a36b0a08d48ea12c4e6511c004e7ec6b..1d32c5df14ed9ea997996da300c8d3d121e494b1 100644 (file)
 use uint;
 
 /// Conversion from an `Iterator`
-pub trait FromIterator<A, T: Iterator<A>> {
+pub trait FromIterator<A> {
     /// Build a container with elements from an external iterator.
-    fn from_iterator(iterator: &mut T) -> Self;
+    fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> Self;
 }
 
 /// A type growable from an `Iterator` implementation
-pub trait Extendable<A, T: Iterator<A>>: FromIterator<A, T> {
+pub trait Extendable<A>: FromIterator<A> {
     /// Extend a container with the elements yielded by an iterator
-    fn extend(&mut self, iterator: &mut T);
+    fn extend<T: Iterator<A>>(&mut self, iterator: &mut T);
 }
 
 /// An interface for dealing with "external iterators". These types of iterators
@@ -174,6 +174,7 @@ fn enumerate(self) -> Enumerate<Self> {
     /// assert!(it.peek().is_none());
     /// assert!(it.next().is_none());
     /// ~~~
+    #[inline]
     fn peekable(self) -> Peekable<A, Self> {
         Peekable{iter: self, peeked: None}
     }
@@ -353,7 +354,7 @@ fn advance(&mut self, f: &fn(A) -> bool) -> bool {
     /// assert!(a == b);
     /// ~~~
     #[inline]
-    fn collect<B: FromIterator<A, Self>>(&mut self) -> B {
+    fn collect<B: FromIterator<A>>(&mut self) -> B {
         FromIterator::from_iterator(self)
     }
 
@@ -510,7 +511,8 @@ fn count(&mut self, predicate: &fn(A) -> bool) -> uint {
         i
     }
 
-    /// Return the element that gives the maximum value from the specfied function
+    /// Return the element that gives the maximum value from the
+    /// specified function.
     ///
     /// # Example
     ///
@@ -533,7 +535,8 @@ fn max_by<B: Ord>(&mut self, f: &fn(&A) -> B) -> Option<A> {
         }).map_move(|(x, _)| x)
     }
 
-    /// Return the element that gives the minimum value from the specfied function
+    /// Return the element that gives the minimum value from the
+    /// specified function.
     ///
     /// # Example
     ///
@@ -931,8 +934,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
-impl<'self, A, B, T: DoubleEndedIterator<A>> DoubleEndedIterator<B>
-for Map<'self, A, B, T> {
+impl<'self, A, B, T: DoubleEndedIterator<A>> DoubleEndedIterator<B> for Map<'self, A, B, T> {
     #[inline]
     fn next_back(&mut self) -> Option<B> {
         let next = self.iter.next_back();
@@ -940,8 +942,7 @@ fn next_back(&mut self) -> Option<B> {
     }
 }
 
-impl<'self, A, B, T: RandomAccessIterator<A>> RandomAccessIterator<B>
-for Map<'self, A, B, T> {
+impl<'self, A, B, T: RandomAccessIterator<A>> RandomAccessIterator<B> for Map<'self, A, B, T> {
     #[inline]
     fn indexable(&self) -> uint {
         self.iter.indexable()
@@ -1542,7 +1543,7 @@ pub struct Repeat<A> {
 }
 
 impl<A: Clone> Repeat<A> {
-    /// Create a new `Repeat` that enlessly repeats the element `elt`.
+    /// Create a new `Repeat` that endlessly repeats the element `elt`.
     #[inline]
     pub fn new(elt: A) -> Repeat<A> {
         Repeat{element: elt}
index 6b45ddddf7e9378611f59c1f869078c46a1efb42..6a48e18a3cc2a3340826c9eed45a0a5d23d112f4 100644 (file)
 They cannot be implemented by user code, but are instead implemented
 by the compiler automatically for the types to which they apply.
 
-The 2 kinds are
-
-* Send - owned types and types containing owned types.  These types
-  may be transferred across task boundaries.
-
-* Freeze - types that are deeply immutable.
-
 */
 
-#[allow(missing_doc)];
-
+/// Types able to be transferred across task boundaries.
 #[lang="send"]
 pub trait Send {
     // empty.
 }
 
+/// Types that are either immutable or have inherited mutability.
 #[lang="freeze"]
 pub trait Freeze {
     // empty.
 }
 
+/// Types with a constant size known at compile-time.
 #[lang="sized"]
 pub trait Sized {
     // Empty.
index 678704fe0983308ee45bd5a6afbc051f76834721..d3e0c88e5dff7e78bad2ed3543178ca89767ebd3 100644 (file)
@@ -2762,9 +2762,11 @@ pub mod dirent {
             // doesn't link it correctly on i686, so we're going
             // through a C function that mysteriously does work.
             pub unsafe fn opendir(dirname: *c_char) -> *DIR {
+                #[fixed_stack_segment]; #[inline(never)];
                 rust_opendir(dirname)
             }
             pub unsafe fn readdir(dirp: *DIR) -> *dirent_t {
+                #[fixed_stack_segment]; #[inline(never)];
                 rust_readdir(dirp)
             }
 
index a73809d202c44c7eb64a47be72c228bc159f7e47..4dbe61b0c49d79c6a8a60a995065ed6781c8d654 100644 (file)
@@ -24,8 +24,8 @@
 ~~~{.rust}
 use std::local_data;
 
-static key_int: local_data::Key<int> = &local_data::Key;
-static key_vector: local_data::Key<~[int]> = &local_data::Key;
+local_data_key!(key_int: int);
+local_data_key!(key_vector: ~[int]);
 
 local_data::set(key_int, 3);
 local_data::get(key_int, |opt| assert_eq!(opt, Some(&3)));
index faf9b2e2390dc65bcdb80603a6062f55403f120d..17175de9b929dafd3025c0ca6b57102b5046f7fc 100644 (file)
@@ -41,7 +41,7 @@ mod delegated {
             use unstable::intrinsics;
 
             $(
-                #[inline]
+                #[inline] #[fixed_stack_segment] #[inline(never)]
                 pub fn $name($( $arg : $arg_ty ),*) -> $rv {
                     unsafe {
                         $bound_name($( $arg ),*)
@@ -125,7 +125,7 @@ fn tgamma(n: c_float) -> c_float = c_float_utils::tgamma
 pub mod consts {
     // FIXME (requires Issue #1433 to fix): replace with mathematical
     // staticants from cmath.
-    /// Archimedes' staticant
+    /// Archimedes' constant
     pub static pi: f32 = 3.14159265358979323846264338327950288_f32;
 
     /// pi/2.0
index 60527905779f035296e8a126b7dfbe9b037677a0..91361a61c215137042e4607715c08415094f96b8 100644 (file)
@@ -43,7 +43,7 @@ mod delegated {
             use unstable::intrinsics;
 
             $(
-                #[inline]
+                #[inline] #[fixed_stack_segment] #[inline(never)]
                 pub fn $name($( $arg : $arg_ty ),*) -> $rv {
                     unsafe {
                         $bound_name($( $arg ),*)
index 41da9a6ccbe481a3a559e588a9bc4de5d642ca55..0144f926534d029ce008256b1b4b17bd43495c68 100644 (file)
@@ -17,7 +17,7 @@ macro_rules! int_module (($T:ty, $bits:expr) => (mod generated {
 #[allow(non_uppercase_statics)];
 
 use num::{ToStrRadix, FromStrRadix};
-use num::{Zero, One, strconv};
+use num::{CheckedDiv, Zero, One, strconv};
 use prelude::*;
 use str;
 
@@ -29,6 +29,17 @@ macro_rules! int_module (($T:ty, $bits:expr) => (mod generated {
 pub static min_value: $T = (-1 as $T) << (bits - 1);
 pub static max_value: $T = min_value - 1 as $T;
 
+impl CheckedDiv for $T {
+    #[inline]
+    fn checked_div(&self, v: &$T) -> Option<$T> {
+        if *v == 0 || (*self == min_value && *v == -1) {
+            None
+        } else {
+            Some(self / *v)
+        }
+    }
+}
+
 enum Range { Closed, HalfOpen }
 
 #[inline]
@@ -551,6 +562,7 @@ mod tests {
     use super::*;
     use prelude::*;
 
+    use int;
     use i16;
     use i32;
     use i64;
@@ -921,6 +933,13 @@ fn test_ranges() {
     fn test_range_step_zero_step() {
         do range_step(0,10,0) |_i| { true };
     }
+
+    #[test]
+    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);
+    }
 }
 
 }))
index 9e72b355bf9f96ae2d10f4a4c1b36893f0c96319..fbb8913fbfa89577e0acd368e1a9bd97e3a283ed 100644 (file)
@@ -468,55 +468,42 @@ fn is_zero(&self) -> bool { (**self).is_zero() }
 }
 
 /// Saturating math operations
-pub trait Saturating: Int {
+pub trait Saturating {
     /// Saturating addition operator.
     /// Returns a+b, saturating at the numeric bounds instead of overflowing.
+    fn saturating_add(self, v: Self) -> Self;
+
+    /// Saturating subtraction operator.
+    /// Returns a-b, saturating at the numeric bounds instead of overflowing.
+    fn saturating_sub(self, v: Self) -> Self;
+}
+
+impl<T: CheckedAdd+CheckedSub+Zero+Ord+Bounded> Saturating for T {
     #[inline]
-    fn saturating_add(self, v: Self) -> Self {
-        let x = self + v;
-        if v >= Zero::zero() {
-            if x < self {
-                // overflow
-                Bounded::max_value::<Self>()
-            } else { x }
-        } else {
-            if x > self {
-                // underflow
-                Bounded::min_value::<Self>()
-            } else { x }
+    fn saturating_add(self, v: T) -> T {
+        match self.checked_add(&v) {
+            Some(x) => x,
+            None => if v >= Zero::zero() {
+                Bounded::max_value::<T>()
+            } else {
+                Bounded::min_value::<T>()
+            }
         }
     }
 
-    /// Saturating subtraction operator.
-    /// Returns a-b, saturating at the numeric bounds instead of overflowing.
     #[inline]
-    fn saturating_sub(self, v: Self) -> Self {
-        let x = self - v;
-        if v >= Zero::zero() {
-            if x > self {
-                // underflow
-                Bounded::min_value::<Self>()
-            } else { x }
-        } else {
-            if x < self {
-                // overflow
-                Bounded::max_value::<Self>()
-            } else { x }
+    fn saturating_sub(self, v: T) -> T {
+        match self.checked_sub(&v) {
+            Some(x) => x,
+            None => if v >= Zero::zero() {
+                Bounded::min_value::<T>()
+            } else {
+                Bounded::max_value::<T>()
+            }
         }
     }
 }
 
-impl Saturating for int {}
-impl Saturating for i8 {}
-impl Saturating for i16 {}
-impl Saturating for i32 {}
-impl Saturating for i64 {}
-impl Saturating for uint {}
-impl Saturating for u8 {}
-impl Saturating for u16 {}
-impl Saturating for u32 {}
-impl Saturating for u64 {}
-
 pub trait CheckedAdd: Add<Self, Self> {
     fn checked_add(&self, v: &Self) -> Option<Self>;
 }
@@ -905,6 +892,10 @@ fn checked_mul(&self, v: &uint) -> Option<uint> {
     }
 }
 
+pub trait CheckedDiv: Div<Self, Self> {
+    fn checked_div(&self, v: &Self) -> Option<Self>;
+}
+
 /// Helper function for testing numeric operations
 #[cfg(test)]
 pub fn test_num<T:Num + NumCast>(ten: T, two: T) {
index 86b5b4ddfc09f4318f5fd94dc2f9ad859014c5ac..524b035c9f30928dff46665f948ae2050ea5278a 100644 (file)
@@ -18,7 +18,7 @@ macro_rules! uint_module (($T:ty, $T_SIGNED:ty, $bits:expr) => (mod generated {
 
 use num::BitCount;
 use num::{ToStrRadix, FromStrRadix};
-use num::{Zero, One, strconv};
+use num::{CheckedDiv, Zero, One, strconv};
 use prelude::*;
 use str;
 
@@ -30,6 +30,17 @@ macro_rules! uint_module (($T:ty, $T_SIGNED:ty, $bits:expr) => (mod generated {
 pub static min_value: $T = 0 as $T;
 pub static max_value: $T = 0 as $T - 1 as $T;
 
+impl CheckedDiv for $T {
+    #[inline]
+    fn checked_div(&self, v: &$T) -> Option<$T> {
+        if *v == 0 {
+            None
+        } else {
+            Some(self / *v)
+        }
+    }
+}
+
 enum Range { Closed, HalfOpen }
 
 #[inline]
@@ -694,6 +705,12 @@ fn test_range_step_zero_step_up() {
     fn test_range_step_zero_step_down() {
         do range_step(0,-10,0) |_i| { true };
     }
+
+    #[test]
+    fn test_unsigned_checked_div() {
+        assert_eq!(10u.checked_div(&2), Some(5));
+        assert_eq!(5u.checked_div(&0), None);
+    }
 }
 
 }))
index c916be79c53e5a3fa13c5e0d072c3139e3a149ad..4e5a0e9b9138a632beda8eeaa6e4689cd585cfe2 100644 (file)
@@ -51,6 +51,7 @@
 
 /// Delegates to the libc close() function, returning the same return value.
 pub fn close(fd: c_int) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
     unsafe {
         libc::close(fd)
     }
@@ -70,6 +71,7 @@ pub mod rustrt {
 static BUF_BYTES : uint = 2048u;
 
 pub fn getcwd() -> Path {
+    #[fixed_stack_segment]; #[inline(never)];
     let mut buf = [0 as libc::c_char, ..BUF_BYTES];
     do buf.as_mut_buf |buf, len| {
         unsafe {
@@ -109,6 +111,8 @@ pub mod win32 {
 
     pub fn fill_utf16_buf_and_decode(f: &fn(*mut u16, DWORD) -> DWORD)
         -> Option<~str> {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             let mut n = TMPBUF_SZ as DWORD;
             let mut res = None;
@@ -145,6 +149,18 @@ pub fn as_utf16_p<T>(s: &str, f: &fn(*u16) -> T) -> T {
     }
 }
 
+#[cfg(stage0)]
+mod macro_hack {
+#[macro_escape];
+macro_rules! externfn(
+    (fn $name:ident ()) => (
+        extern {
+            fn $name();
+        }
+    )
+)
+}
+
 /*
 Accessing environment variables is not generally threadsafe.
 Serialize access through a global lock.
@@ -161,12 +177,8 @@ fn with_env_lock<T>(f: &fn() -> T) -> T {
         };
     }
 
-    extern {
-        #[fast_ffi]
-        fn rust_take_env_lock();
-        #[fast_ffi]
-        fn rust_drop_env_lock();
-    }
+    externfn!(fn rust_take_env_lock());
+    externfn!(fn rust_drop_env_lock());
 }
 
 /// Returns a vector of (variable, value) pairs for all the environment
@@ -175,6 +187,8 @@ pub fn env() -> ~[(~str,~str)] {
     unsafe {
         #[cfg(windows)]
         unsafe fn get_env_pairs() -> ~[~str] {
+            #[fixed_stack_segment]; #[inline(never)];
+
             use libc::funcs::extra::kernel32::{
                 GetEnvironmentStringsA,
                 FreeEnvironmentStringsA
@@ -198,6 +212,8 @@ unsafe fn get_env_pairs() -> ~[~str] {
         }
         #[cfg(unix)]
         unsafe fn get_env_pairs() -> ~[~str] {
+            #[fixed_stack_segment]; #[inline(never)];
+
             extern {
                 fn rust_env_pairs() -> **libc::c_char;
             }
@@ -237,9 +253,10 @@ fn env_convert(input: ~[~str]) -> ~[(~str, ~str)] {
 /// Fetches the environment variable `n` from the current process, returning
 /// None if the variable isn't set.
 pub fn getenv(n: &str) -> Option<~str> {
+    #[fixed_stack_segment]; #[inline(never)];
     unsafe {
         do with_env_lock {
-            let s = do n.to_c_str().with_ref |buf| {
+            let s = do n.with_c_str |buf| {
                 libc::getenv(buf)
             };
             if s.is_null() {
@@ -255,6 +272,8 @@ pub fn getenv(n: &str) -> Option<~str> {
 /// Fetches the environment variable `n` from the current process, returning
 /// None if the variable isn't set.
 pub fn getenv(n: &str) -> Option<~str> {
+    #[fixed_stack_segment]; #[inline(never)];
+
     unsafe {
         do with_env_lock {
             use os::win32::{as_utf16_p, fill_utf16_buf_and_decode};
@@ -272,10 +291,11 @@ pub fn getenv(n: &str) -> Option<~str> {
 /// Sets the environment variable `n` to the value `v` for the currently running
 /// process
 pub fn setenv(n: &str, v: &str) {
+    #[fixed_stack_segment]; #[inline(never)];
     unsafe {
         do with_env_lock {
-            do n.to_c_str().with_ref |nbuf| {
-                do v.to_c_str().with_ref |vbuf| {
+            do n.with_c_str |nbuf| {
+                do v.with_c_str |vbuf| {
                     libc::funcs::posix01::unistd::setenv(nbuf, vbuf, 1);
                 }
             }
@@ -288,6 +308,8 @@ pub fn setenv(n: &str, v: &str) {
 /// Sets the environment variable `n` to the value `v` for the currently running
 /// process
 pub fn setenv(n: &str, v: &str) {
+    #[fixed_stack_segment]; #[inline(never)];
+
     unsafe {
         do with_env_lock {
             use os::win32::as_utf16_p;
@@ -304,9 +326,10 @@ pub fn setenv(n: &str, v: &str) {
 pub fn unsetenv(n: &str) {
     #[cfg(unix)]
     fn _unsetenv(n: &str) {
+        #[fixed_stack_segment]; #[inline(never)];
         unsafe {
             do with_env_lock {
-                do n.to_c_str().with_ref |nbuf| {
+                do n.with_c_str |nbuf| {
                     libc::funcs::posix01::unistd::unsetenv(nbuf);
                 }
             }
@@ -314,6 +337,7 @@ fn _unsetenv(n: &str) {
     }
     #[cfg(windows)]
     fn _unsetenv(n: &str) {
+        #[fixed_stack_segment]; #[inline(never)];
         unsafe {
             do with_env_lock {
                 use os::win32::as_utf16_p;
@@ -328,7 +352,8 @@ fn _unsetenv(n: &str) {
 }
 
 pub fn fdopen(fd: c_int) -> *FILE {
-    do "r".to_c_str().with_ref |modebuf| {
+    #[fixed_stack_segment]; #[inline(never)];
+    do "r".with_c_str |modebuf| {
         unsafe {
             libc::fdopen(fd, modebuf)
         }
@@ -340,6 +365,7 @@ pub fn fdopen(fd: c_int) -> *FILE {
 
 #[cfg(windows)]
 pub fn fsync_fd(fd: c_int, _level: io::fsync::Level) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
     unsafe {
         use libc::funcs::extra::msvcrt::*;
         return commit(fd);
@@ -349,6 +375,7 @@ pub fn fsync_fd(fd: c_int, _level: io::fsync::Level) -> c_int {
 #[cfg(target_os = "linux")]
 #[cfg(target_os = "android")]
 pub fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
     unsafe {
         use libc::funcs::posix01::unistd::*;
         match level {
@@ -361,6 +388,8 @@ pub fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int {
 
 #[cfg(target_os = "macos")]
 pub fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     unsafe {
         use libc::consts::os::extra::*;
         use libc::funcs::posix88::fcntl::*;
@@ -381,6 +410,8 @@ pub fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int {
 
 #[cfg(target_os = "freebsd")]
 pub fn fsync_fd(fd: c_int, _l: io::fsync::Level) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     unsafe {
         use libc::funcs::posix01::unistd::*;
         return fsync(fd);
@@ -394,6 +425,7 @@ pub struct Pipe {
 
 #[cfg(unix)]
 pub fn pipe() -> Pipe {
+    #[fixed_stack_segment]; #[inline(never)];
     unsafe {
         let mut fds = Pipe {input: 0 as c_int,
                             out: 0 as c_int };
@@ -406,12 +438,13 @@ pub fn pipe() -> Pipe {
 
 #[cfg(windows)]
 pub fn pipe() -> Pipe {
+    #[fixed_stack_segment]; #[inline(never)];
     unsafe {
         // Windows pipes work subtly differently than unix pipes, and their
         // inheritance has to be handled in a different way that I do not
         // fully understand. Here we explicitly make the pipe non-inheritable,
         // which means to pass it to a subprocess they need to be duplicated
-        // first, as in core::run.
+        // first, as in std::run.
         let mut fds = Pipe {input: 0 as c_int,
                     out: 0 as c_int };
         let res = libc::pipe(&mut fds.input, 1024 as ::libc::c_uint,
@@ -424,6 +457,7 @@ pub fn pipe() -> Pipe {
 }
 
 fn dup2(src: c_int, dst: c_int) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
     unsafe {
         libc::dup2(src, dst)
     }
@@ -440,6 +474,7 @@ pub fn self_exe_path() -> Option<Path> {
 
     #[cfg(target_os = "freebsd")]
     fn load_self() -> Option<~str> {
+        #[fixed_stack_segment]; #[inline(never)];
         unsafe {
             use libc::funcs::bsd44::*;
             use libc::consts::os::extra::*;
@@ -458,13 +493,14 @@ fn load_self() -> Option<~str> {
     #[cfg(target_os = "linux")]
     #[cfg(target_os = "android")]
     fn load_self() -> Option<~str> {
+        #[fixed_stack_segment]; #[inline(never)];
         unsafe {
             use libc::funcs::posix01::unistd::readlink;
 
             let mut path = [0 as c_char, .. TMPBUF_SZ];
 
             do path.as_mut_buf |buf, len| {
-                let len = do "/proc/self/exe".to_c_str().with_ref |proc_self_buf| {
+                let len = do "/proc/self/exe".with_c_str |proc_self_buf| {
                     readlink(proc_self_buf, buf, len as size_t) as uint
                 };
 
@@ -479,6 +515,7 @@ fn load_self() -> Option<~str> {
 
     #[cfg(target_os = "macos")]
     fn load_self() -> Option<~str> {
+        #[fixed_stack_segment]; #[inline(never)];
         unsafe {
             do fill_charp_buf() |buf, sz| {
                 let mut sz = sz as u32;
@@ -490,6 +527,7 @@ fn load_self() -> Option<~str> {
 
     #[cfg(windows)]
     fn load_self() -> Option<~str> {
+        #[fixed_stack_segment]; #[inline(never)];
         unsafe {
             use os::win32::fill_utf16_buf_and_decode;
             do fill_utf16_buf_and_decode() |buf, sz| {
@@ -592,8 +630,9 @@ pub fn walk_dir(p: &Path, f: &fn(&Path) -> bool) -> bool {
 
 /// Indicates whether a path represents a directory
 pub fn path_is_dir(p: &Path) -> bool {
+    #[fixed_stack_segment]; #[inline(never)];
     unsafe {
-        do p.to_c_str().with_ref |buf| {
+        do p.with_c_str |buf| {
             rustrt::rust_path_is_dir(buf) != 0 as c_int
         }
     }
@@ -601,8 +640,9 @@ pub fn path_is_dir(p: &Path) -> bool {
 
 /// Indicates whether a path exists
 pub fn path_exists(p: &Path) -> bool {
+    #[fixed_stack_segment]; #[inline(never)];
     unsafe {
-        do p.to_c_str().with_ref |buf| {
+        do p.with_c_str |buf| {
             rustrt::rust_path_exists(buf) != 0 as c_int
         }
     }
@@ -633,6 +673,7 @@ pub fn make_dir(p: &Path, mode: c_int) -> bool {
 
     #[cfg(windows)]
     fn mkdir(p: &Path, _mode: c_int) -> bool {
+        #[fixed_stack_segment]; #[inline(never)];
         unsafe {
             use os::win32::as_utf16_p;
             // FIXME: turn mode into something useful? #2623
@@ -645,7 +686,8 @@ fn mkdir(p: &Path, _mode: c_int) -> bool {
 
     #[cfg(unix)]
     fn mkdir(p: &Path, mode: c_int) -> bool {
-        do p.to_c_str().with_ref |buf| {
+        #[fixed_stack_segment]; #[inline(never)];
+        do p.with_c_str |buf| {
             unsafe {
                 libc::mkdir(buf, mode as libc::mode_t) == (0 as c_int)
             }
@@ -689,6 +731,7 @@ pub fn list_dir(p: &Path) -> ~[~str] {
         #[cfg(target_os = "freebsd")]
         #[cfg(target_os = "macos")]
         unsafe fn get_list(p: &Path) -> ~[~str] {
+            #[fixed_stack_segment]; #[inline(never)];
             use libc::{dirent_t};
             use libc::{opendir, readdir, closedir};
             extern {
@@ -697,7 +740,7 @@ unsafe fn get_list(p: &Path) -> ~[~str] {
             let mut strings = ~[];
             debug!("os::list_dir -- BEFORE OPENDIR");
 
-            let dir_ptr = do p.to_c_str().with_ref |buf| {
+            let dir_ptr = do p.with_c_str |buf| {
                 opendir(buf)
             };
 
@@ -721,6 +764,7 @@ unsafe fn get_list(p: &Path) -> ~[~str] {
         }
         #[cfg(windows)]
         unsafe fn get_list(p: &Path) -> ~[~str] {
+            #[fixed_stack_segment]; #[inline(never)];
             use libc::consts::os::extra::INVALID_HANDLE_VALUE;
             use libc::{wcslen, free};
             use libc::funcs::extra::kernel32::{
@@ -809,6 +853,7 @@ pub fn remove_dir(p: &Path) -> bool {
 
     #[cfg(windows)]
     fn rmdir(p: &Path) -> bool {
+        #[fixed_stack_segment]; #[inline(never)];
         unsafe {
             use os::win32::as_utf16_p;
             return do as_utf16_p(p.to_str()) |buf| {
@@ -819,7 +864,8 @@ fn rmdir(p: &Path) -> bool {
 
     #[cfg(unix)]
     fn rmdir(p: &Path) -> bool {
-        do p.to_c_str().with_ref |buf| {
+        #[fixed_stack_segment]; #[inline(never)];
+        do p.with_c_str |buf| {
             unsafe {
                 libc::rmdir(buf) == (0 as c_int)
             }
@@ -834,6 +880,7 @@ pub fn change_dir(p: &Path) -> bool {
 
     #[cfg(windows)]
     fn chdir(p: &Path) -> bool {
+        #[fixed_stack_segment]; #[inline(never)];
         unsafe {
             use os::win32::as_utf16_p;
             return do as_utf16_p(p.to_str()) |buf| {
@@ -844,7 +891,8 @@ fn chdir(p: &Path) -> bool {
 
     #[cfg(unix)]
     fn chdir(p: &Path) -> bool {
-        do p.to_c_str().with_ref |buf| {
+        #[fixed_stack_segment]; #[inline(never)];
+        do p.with_c_str |buf| {
             unsafe {
                 libc::chdir(buf) == (0 as c_int)
             }
@@ -858,6 +906,7 @@ pub fn copy_file(from: &Path, to: &Path) -> bool {
 
     #[cfg(windows)]
     fn do_copy_file(from: &Path, to: &Path) -> bool {
+        #[fixed_stack_segment]; #[inline(never)];
         unsafe {
             use os::win32::as_utf16_p;
             return do as_utf16_p(from.to_str()) |fromp| {
@@ -871,9 +920,10 @@ fn do_copy_file(from: &Path, to: &Path) -> bool {
 
     #[cfg(unix)]
     fn do_copy_file(from: &Path, to: &Path) -> bool {
+        #[fixed_stack_segment]; #[inline(never)];
         unsafe {
-            let istream = do from.to_c_str().with_ref |fromp| {
-                do "rb".to_c_str().with_ref |modebuf| {
+            let istream = do from.with_c_str |fromp| {
+                do "rb".with_c_str |modebuf| {
                     libc::fopen(fromp, modebuf)
                 }
             };
@@ -884,8 +934,8 @@ fn do_copy_file(from: &Path, to: &Path) -> bool {
             let from_mode = from.get_mode().expect("copy_file: couldn't get permissions \
                                                     for source file");
 
-            let ostream = do to.to_c_str().with_ref |top| {
-                do "w+b".to_c_str().with_ref |modebuf| {
+            let ostream = do to.with_c_str |top| {
+                do "w+b".with_c_str |modebuf| {
                     libc::fopen(top, modebuf)
                 }
             };
@@ -917,7 +967,7 @@ fn do_copy_file(from: &Path, to: &Path) -> bool {
             fclose(ostream);
 
             // Give the new file the old file's permissions
-            if do to.to_c_str().with_ref |to_buf| {
+            if do to.with_c_str |to_buf| {
                 libc::chmod(to_buf, from_mode as libc::mode_t)
             } != 0 {
                 return false; // should be a condition...
@@ -933,6 +983,7 @@ pub fn remove_file(p: &Path) -> bool {
 
     #[cfg(windows)]
     fn unlink(p: &Path) -> bool {
+        #[fixed_stack_segment]; #[inline(never)];
         unsafe {
             use os::win32::as_utf16_p;
             return do as_utf16_p(p.to_str()) |buf| {
@@ -943,8 +994,9 @@ fn unlink(p: &Path) -> bool {
 
     #[cfg(unix)]
     fn unlink(p: &Path) -> bool {
+        #[fixed_stack_segment]; #[inline(never)];
         unsafe {
-            do p.to_c_str().with_ref |buf| {
+            do p.with_c_str |buf| {
                 libc::unlink(buf) == (0 as c_int)
             }
         }
@@ -957,6 +1009,7 @@ pub fn errno() -> int {
     #[cfg(target_os = "macos")]
     #[cfg(target_os = "freebsd")]
     fn errno_location() -> *c_int {
+        #[fixed_stack_segment]; #[inline(never)];
         #[nolink]
         extern {
             fn __error() -> *c_int;
@@ -969,6 +1022,7 @@ fn errno_location() -> *c_int {
     #[cfg(target_os = "linux")]
     #[cfg(target_os = "android")]
     fn errno_location() -> *c_int {
+        #[fixed_stack_segment]; #[inline(never)];
         #[nolink]
         extern {
             fn __errno_location() -> *c_int;
@@ -986,6 +1040,7 @@ fn errno_location() -> *c_int {
 #[cfg(windows)]
 /// Returns the platform-specific value of errno
 pub fn errno() -> uint {
+    #[fixed_stack_segment]; #[inline(never)];
     use libc::types::os::arch::extra::DWORD;
 
     #[link_name = "kernel32"]
@@ -1008,6 +1063,8 @@ fn strerror() -> ~str {
         #[cfg(target_os = "freebsd")]
         fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t)
                       -> c_int {
+            #[fixed_stack_segment]; #[inline(never)];
+
             #[nolink]
             extern {
                 fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t)
@@ -1023,6 +1080,7 @@ fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t)
         // 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 {
+            #[fixed_stack_segment]; #[inline(never)];
             #[nolink]
             extern {
                 fn __xpg_strerror_r(errnum: c_int,
@@ -1050,6 +1108,8 @@ fn __xpg_strerror_r(errnum: c_int,
 
     #[cfg(windows)]
     fn strerror() -> ~str {
+        #[fixed_stack_segment]; #[inline(never)];
+
         use libc::types::os::arch::extra::DWORD;
         use libc::types::os::arch::extra::LPSTR;
         use libc::types::os::arch::extra::LPVOID;
@@ -1129,6 +1189,8 @@ unsafe fn load_argc_and_argv(argc: c_int, argv: **c_char) -> ~[~str] {
  */
 #[cfg(target_os = "macos")]
 pub fn real_args() -> ~[~str] {
+    #[fixed_stack_segment]; #[inline(never)];
+
     unsafe {
         let (argc, argv) = (*_NSGetArgc() as c_int,
                             *_NSGetArgv() as **c_char);
@@ -1150,6 +1212,8 @@ pub fn real_args() -> ~[~str] {
 
 #[cfg(windows)]
 pub fn real_args() -> ~[~str] {
+    #[fixed_stack_segment]; #[inline(never)];
+
     let mut nArgs: c_int = 0;
     let lpArgCount: *mut c_int = &mut nArgs;
     let lpCmdLine = unsafe { GetCommandLineW() };
@@ -1232,6 +1296,8 @@ pub fn set_args(new_args: ~[~str]) {
 #[cfg(target_os = "freebsd")]
 #[cfg(target_os = "macos")]
 pub fn glob(pattern: &str) -> ~[Path] {
+    #[fixed_stack_segment]; #[inline(never)];
+
     #[cfg(target_os = "linux")]
     #[cfg(target_os = "android")]
     fn default_glob_t () -> libc::glob_t {
@@ -1282,7 +1348,7 @@ fn default_glob_t () -> libc::glob_t {
     }
 
     let mut g = default_glob_t();
-    do pattern.to_c_str().with_ref |c_pattern| {
+    do pattern.with_c_str |c_pattern| {
         unsafe { libc::glob(c_pattern, 0, ptr::null(), &mut g) }
     };
     do(|| {
@@ -1326,6 +1392,8 @@ fn round_up(from: uint, to: uint) -> uint {
 
 #[cfg(unix)]
 pub fn page_size() -> uint {
+    #[fixed_stack_segment]; #[inline(never)];
+
     unsafe {
         libc::sysconf(libc::_SC_PAGESIZE) as uint
     }
@@ -1333,6 +1401,8 @@ pub fn page_size() -> uint {
 
 #[cfg(windows)]
 pub fn page_size() -> uint {
+    #[fixed_stack_segment]; #[inline(never)];
+
   unsafe {
     let mut info = libc::SYSTEM_INFO::new();
     libc::GetSystemInfo(&mut info);
@@ -1404,6 +1474,8 @@ fn to_str(&self) -> ~str {
 #[cfg(unix)]
 impl MemoryMap {
     pub fn new(min_len: uint, options: ~[MapOption]) -> Result<~MemoryMap, MapError> {
+        #[fixed_stack_segment]; #[inline(never)];
+
         use libc::off_t;
 
         let mut addr: *c_void = ptr::null();
@@ -1460,6 +1532,8 @@ pub fn new(min_len: uint, options: ~[MapOption]) -> Result<~MemoryMap, MapError>
 #[cfg(unix)]
 impl Drop for MemoryMap {
     fn drop(&self) {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             match libc::munmap(self.data as *c_void, self.len) {
                 0 => (),
@@ -1476,6 +1550,8 @@ fn drop(&self) {
 #[cfg(windows)]
 impl MemoryMap {
     pub fn new(min_len: uint, options: ~[MapOption]) -> Result<~MemoryMap, MapError> {
+        #[fixed_stack_segment]; #[inline(never)];
+
         use libc::types::os::arch::extra::{LPVOID, DWORD, SIZE_T, HANDLE};
 
         let mut lpAddress: LPVOID = ptr::mut_null();
@@ -1569,6 +1645,8 @@ pub fn new(min_len: uint, options: ~[MapOption]) -> Result<~MemoryMap, MapError>
 #[cfg(windows)]
 impl Drop for MemoryMap {
     fn drop(&self) {
+        #[fixed_stack_segment]; #[inline(never)];
+
         use libc::types::os::arch::extra::{LPCVOID, HANDLE};
 
         unsafe {
@@ -1921,6 +1999,8 @@ fn copy_file_does_not_exist() {
 
     #[test]
     fn copy_file_ok() {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             let tempdir = getcwd(); // would like to use $TMPDIR,
                                     // doesn't seem to work on Linux
@@ -1929,14 +2009,14 @@ fn copy_file_ok() {
             let out = tempdir.push("out.txt");
 
             /* Write the temp input file */
-            let ostream = do input.to_c_str().with_ref |fromp| {
-                do "w+b".to_c_str().with_ref |modebuf| {
+            let ostream = do input.with_c_str |fromp| {
+                do "w+b".with_c_str |modebuf| {
                     libc::fopen(fromp, modebuf)
                 }
             };
             assert!((ostream as uint != 0u));
             let s = ~"hello";
-            do "hello".to_c_str().with_ref |buf| {
+            do "hello".with_c_str |buf| {
                 let write_len = libc::fwrite(buf as *c_void,
                                              1u as size_t,
                                              (s.len() + 1u) as size_t,
@@ -1991,17 +2071,23 @@ fn memory_map_rw() {
 
     #[test]
     fn memory_map_file() {
+        #[fixed_stack_segment]; #[inline(never)];
+
         use result::{Ok, Err};
         use os::*;
         use libc::*;
 
         #[cfg(unix)]
+        #[fixed_stack_segment]
+        #[inline(never)]
         fn lseek_(fd: c_int, size: uint) {
             unsafe {
                 assert!(lseek(fd, size as off_t, SEEK_SET) == size as off_t);
             }
         }
         #[cfg(windows)]
+        #[fixed_stack_segment]
+        #[inline(never)]
         fn lseek_(fd: c_int, size: uint) {
            unsafe {
                assert!(lseek(fd, size as c_long, SEEK_SET) == size as c_long);
@@ -2013,11 +2099,11 @@ fn lseek_(fd: c_int, size: uint) {
         remove_file(&path);
 
         let fd = unsafe {
-            let fd = do path.to_c_str().with_ref |path| {
+            let fd = do path.with_c_str |path| {
                 open(path, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR)
             };
             lseek_(fd, size);
-            do "x".to_c_str().with_ref |x| {
+            do "x".with_c_str |x| {
                 assert!(write(fd, x as *c_void, 1) == 1);
             }
             fd
index 177f0efb6dad380677fef7b9d442ddbb5bf11411..858098409e90d7c8dd9f4ff76e185a38fb107f64 100644 (file)
@@ -381,7 +381,8 @@ pub fn default_stat() -> libc::stat {
 #[cfg(target_os = "win32")]
 impl WindowsPath {
     pub fn stat(&self) -> Option<libc::stat> {
-        do self.to_c_str().with_ref |buf| {
+        #[fixed_stack_segment]; #[inline(never)];
+        do self.with_c_str |buf| {
             let mut st = stat::arch::default_stat();
             match unsafe { libc::stat(buf, &mut st) } {
                 0 => Some(st),
@@ -415,7 +416,8 @@ pub fn get_mode(&self) -> Option<uint> {
 #[cfg(not(target_os = "win32"))]
 impl PosixPath {
     pub fn stat(&self) -> Option<libc::stat> {
-        do self.to_c_str().with_ref |buf| {
+        #[fixed_stack_segment]; #[inline(never)];
+        do self.with_c_str |buf| {
             let mut st = stat::arch::default_stat();
             match unsafe { libc::stat(buf as *libc::c_char, &mut st) } {
                 0 => Some(st),
@@ -493,7 +495,8 @@ pub fn get_ctime(&self) -> Option<(i64, int)> {
 #[cfg(unix)]
 impl PosixPath {
     pub fn lstat(&self) -> Option<libc::stat> {
-        do self.to_c_str().with_ref |buf| {
+        #[fixed_stack_segment]; #[inline(never)];
+        do self.with_c_str |buf| {
             let mut st = stat::arch::default_stat();
             match unsafe { libc::lstat(buf, &mut st) } {
                 0 => Some(st),
@@ -569,6 +572,10 @@ impl ToCStr for PosixPath {
     fn to_c_str(&self) -> c_str::CString {
         self.to_str().to_c_str()
     }
+
+    unsafe fn to_c_str_unchecked(&self) -> c_str::CString {
+        self.to_str().to_c_str_unchecked()
+    }
 }
 
 // FIXME (#3227): when default methods in traits are working, de-duplicate
@@ -781,6 +788,10 @@ impl c_str::ToCStr for WindowsPath {
     fn to_c_str(&self) -> c_str::CString {
         self.to_str().to_c_str()
     }
+
+    unsafe fn to_c_str_unchecked(&self) -> c_str::CString {
+        self.to_str().to_c_str_unchecked()
+    }
 }
 
 impl GenericPath for WindowsPath {
@@ -1093,6 +1104,8 @@ pub fn extract_unc_prefix(s: &str) -> Option<(~str,~str)> {
     }
 
     pub fn extract_drive_prefix(s: &str) -> Option<(~str,~str)> {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             if (s.len() > 1 &&
                 libc::isalpha(s[0] as libc::c_int) != 0 &&
index deee49bc47235af321a648a502fc1b23035d8725..63f73002009312c21ccf7204f4c4aebba73bf72a 100644 (file)
@@ -69,7 +69,7 @@
 pub use from_str::FromStr;
 pub use to_bytes::IterBytes;
 pub use to_str::{ToStr, ToStrConsume};
-pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps};
+pub use tuple::{CopyableTuple, ImmutableTuple};
 pub use tuple::{CloneableTuple1, ImmutableTuple1};
 pub use tuple::{CloneableTuple2, CloneableTuple3, CloneableTuple4, CloneableTuple5};
 pub use tuple::{CloneableTuple6, CloneableTuple7, CloneableTuple8, CloneableTuple9};
index b13d46d540d4adae771882066939ec0011ffe512..c11634034230b0471dc00a9b4993f9af32f90e38 100644 (file)
@@ -47,6 +47,7 @@ pub unsafe fn buf_len<T>(buf: **T) -> uint {
 }
 
 impl<T> Clone for *T {
+    #[inline]
     fn clone(&self) -> *T {
         *self
     }
@@ -253,7 +254,7 @@ pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: &fn(*T)) {
   passing to the provided callback function
 
   SAFETY NOTE: This will only work with a null-terminated
-  pointer array. Barely less-dodgey Pointer Arithmetic.
+  pointer array. Barely less-dodgy Pointer Arithmetic.
   Dragons be here.
 */
 pub unsafe fn array_each<T>(arr: **T, cb: &fn(*T)) {
@@ -481,7 +482,7 @@ struct Pair {
     fn test_position() {
         use libc::c_char;
 
-        do "hello".to_c_str().with_ref |p| {
+        do "hello".with_c_str |p| {
             unsafe {
                 assert!(2u == position(p, |c| *c == 'l' as c_char));
                 assert!(4u == position(p, |c| *c == 'o' as c_char));
@@ -492,9 +493,9 @@ fn test_position() {
 
     #[test]
     fn test_buf_len() {
-        do "hello".to_c_str().with_ref |p0| {
-            do "there".to_c_str().with_ref |p1| {
-                do "thing".to_c_str().with_ref |p2| {
+        do "hello".with_c_str |p0| {
+            do "there".with_c_str |p1| {
+                do "thing".with_c_str |p2| {
                     let v = ~[p0, p1, p2, null()];
                     do v.as_imm_buf |vp, len| {
                         assert_eq!(unsafe { buf_len(vp) }, 3u);
@@ -647,7 +648,7 @@ fn test_ptr_array_each() {
                 one, two, three
             ];
 
-            do arr.as_imm_buf |arr_ptr, arr_len| {
+            do arr.as_imm_buf |arr_ptr, _| {
                 let mut ctr = 0;
                 let mut iteration_count = 0;
                 do array_each(arr_ptr) |e| {
index 500278fddb0b16110bd329e42ebc62b7566b560c..7b10866207a4222a6f6426b044384673fa09a940 100644 (file)
@@ -461,6 +461,26 @@ fn choose_weighted_option<T:Clone>(&mut self, v: &[Weighted<T>])
      * ~~~
      */
     fn shuffle_mut<T>(&mut self, values: &mut [T]);
+
+    /**
+     * Sample up to `n` values from an iterator.
+     *
+     * # Example
+     *
+     * ~~~ {.rust}
+     *
+     * use std::rand;
+     * use std::rand::RngUtil;
+     *
+     * fn main() {
+     *     let mut rng = rand::rng();
+     *     let vals = range(1, 100).to_owned_vec();
+     *     let sample = rng.sample(vals.iter(), 5);
+     *     printfln!(sample);
+     * }
+     * ~~~
+     */
+    fn sample<A, T: Iterator<A>>(&mut self, iter: T, n: uint) -> ~[A];
 }
 
 /// Extension methods for random number generators
@@ -607,6 +627,23 @@ fn shuffle_mut<T>(&mut self, values: &mut [T]) {
             values.swap(i, self.gen_uint_range(0u, i + 1u));
         }
     }
+
+    /// Randomly sample up to `n` elements from an iterator
+    fn sample<A, T: Iterator<A>>(&mut self, iter: T, n: uint) -> ~[A] {
+        let mut reservoir : ~[A] = vec::with_capacity(n);
+        for (i, elem) in iter.enumerate() {
+            if i < n {
+                reservoir.push(elem);
+                loop
+            }
+
+            let k = self.gen_uint_range(0, i + 1);
+            if k < reservoir.len() {
+                reservoir[k] = elem
+            }
+        }
+        reservoir
+    }
 }
 
 /// Create a random number generator with a default algorithm and seed.
@@ -621,7 +658,7 @@ pub fn rng() -> IsaacRng {
 
 /// Create a weak random number generator with a default algorithm and seed.
 ///
-/// It returns the fatest `Rng` algorithm currently available in Rust without
+/// It returns the fastest `Rng` algorithm currently available in Rust without
 /// consideration for cryptography or security. If you require a specifically
 /// seeded `Rng` for consistency over time you should pick one algorithm and
 /// create the `Rng` yourself.
@@ -838,13 +875,24 @@ fn next(&mut self) -> u32 {
 }
 
 impl XorShiftRng {
-    /// Create an xor shift random number generator with a default seed.
+    /// Create an xor shift random number generator with a random seed.
     pub fn new() -> XorShiftRng {
-        // constants taken from http://en.wikipedia.org/wiki/Xorshift
-        XorShiftRng::new_seeded(123456789u32,
-                                362436069u32,
-                                521288629u32,
-                                88675123u32)
+        #[fixed_stack_segment]; #[inline(never)];
+
+        // generate seeds the same way as seed(), except we have a spceific size
+        let mut s = [0u8, ..16];
+        loop {
+            do s.as_mut_buf |p, sz| {
+                unsafe {
+                    rustrt::rand_gen_seed(p, sz as size_t);
+                }
+            }
+            if !s.iter().all(|x| *x == 0) {
+                break;
+            }
+        }
+        let s: &[u32, ..4] = unsafe { cast::transmute(&s) };
+        XorShiftRng::new_seeded(s[0], s[1], s[2], s[3])
     }
 
     /**
@@ -864,6 +912,8 @@ pub fn new_seeded(x: u32, y: u32, z: u32, w: u32) -> XorShiftRng {
 
 /// Create a new random seed.
 pub fn seed() -> ~[u8] {
+    #[fixed_stack_segment]; #[inline(never)];
+
     unsafe {
         let n = rustrt::rand_seed_size() as uint;
         let mut s = vec::from_elem(n, 0_u8);
@@ -914,6 +964,7 @@ pub fn random<T: Rand>() -> T {
 
 #[cfg(test)]
 mod test {
+    use iterator::{Iterator, range};
     use option::{Option, Some};
     use super::*;
 
@@ -1095,6 +1146,8 @@ fn test_random() {
 
     #[test]
     fn compare_isaac_implementation() {
+        #[fixed_stack_segment]; #[inline(never)];
+
         // This is to verify that the implementation of the ISAAC rng is
         // correct (i.e. matches the output of the upstream implementation,
         // which is in the runtime)
@@ -1130,6 +1183,24 @@ pub enum rust_rng {}
             }
         }
     }
+
+    #[test]
+    fn test_sample() {
+        let MIN_VAL = 1;
+        let MAX_VAL = 100;
+
+        let mut r = rng();
+        let vals = range(MIN_VAL, MAX_VAL).to_owned_vec();
+        let small_sample = r.sample(vals.iter(), 5);
+        let large_sample = r.sample(vals.iter(), vals.len() + 5);
+
+        assert_eq!(small_sample.len(), 5);
+        assert_eq!(large_sample.len(), vals.len());
+
+        assert!(small_sample.iter().all(|e| {
+            **e >= MIN_VAL && **e <= MAX_VAL
+        }));
+    }
 }
 
 #[cfg(test)]
index 56eae0428751eef99697c32e05b9d168dcd22ae4..67be7986c33d8a37fa340299d8e9615ba10d3358 100644 (file)
@@ -66,7 +66,7 @@ fn ziggurat<R:Rng>(rng: &mut R,
 /// # Example
 ///
 /// ~~~
-/// use core::rand::distributions::StandardNormal;
+/// use std::rand::distributions::StandardNormal;
 ///
 /// fn main() {
 ///     let normal = 2.0 + (*rand::random::<StandardNormal>()) * 3.0;
@@ -120,7 +120,7 @@ fn zero_case<R:Rng>(rng: &mut R, u: f64) -> f64 {
 /// # Example
 ///
 /// ~~~
-/// use core::rand::distributions::Exp1;
+/// use std::rand::distributions::Exp1;
 ///
 /// fn main() {
 ///     let exp2 = (*rand::random::<Exp1>()) * 0.5;
index 9de5e69148ae998cc39065e34844e0a4e3a0cdca..c7613ed3c2f1e0292106c34dc23bc3a24940c960 100644 (file)
 use iterator::Iterator;
 use option::{None, Option, Some, OptionIterator};
 use vec;
-use vec::{OwnedVector, ImmutableVector};
-use container::Container;
+use vec::OwnedVector;
 use to_str::ToStr;
 use str::StrSlice;
 
 /// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
 ///
-/// In order to provide informative error messages, `E` is reqired to implement `ToStr`.
+/// In order to provide informative error messages, `E` is required to implement `ToStr`.
 /// It is further recommended for `E` to be a descriptive error type, eg a `enum` for
 /// all possible errors cases.
 #[deriving(Clone, Eq)]
@@ -269,86 +268,76 @@ pub fn map_opt<T, U: ToStr, V>(o_t: &Option<T>,
     }
 }
 
-// FIXME: #8228 Replaceable by an external iterator?
-/// Maps each element in the vector `ts` using the operation `op`.  Should an
-/// error occur, no further mappings are performed and the error is returned.
-/// Should no error occur, a vector containing the result of each map is
-/// returned.
+/// Takes each element in the iterator: if it is an error, no further
+/// elements are taken, and the error is returned.
+/// Should no error occur, a vector containing the values of each Result
+/// is returned.
 ///
 /// Here is an example which increments every integer in a vector,
 /// checking for overflow:
 ///
-///     fn inc_conditionally(x: uint) -> result<uint,str> {
+///     fn inc_conditionally(x: uint) -> Result<uint, &'static str> {
 ///         if x == uint::max_value { return Err("overflow"); }
 ///         else { return Ok(x+1u); }
 ///     }
-///     map(~[1u, 2u, 3u], inc_conditionally).chain {|incd|
-///         assert!(incd == ~[2u, 3u, 4u]);
-///     }
+///     let v = [1u, 2, 3];
+///     let res = collect(v.iter().map(|&x| inc_conditionally(x)));
+///     assert!(res == Ok(~[2u, 3, 4]));
 #[inline]
-pub fn map_vec<T,U,V>(ts: &[T], op: &fn(&T) -> Result<V,U>)
-                      -> Result<~[V],U> {
-    let mut vs: ~[V] = vec::with_capacity(ts.len());
-    for t in ts.iter() {
-        match op(t) {
-          Ok(v) => vs.push(v),
-          Err(u) => return Err(u)
+pub fn collect<T, E, Iter: Iterator<Result<T, E>>>(mut iterator: Iter)
+    -> Result<~[T], E> {
+    let (lower, _) = iterator.size_hint();
+    let mut vs: ~[T] = vec::with_capacity(lower);
+    for t in iterator {
+        match t {
+            Ok(v) => vs.push(v),
+            Err(u) => return Err(u)
         }
     }
-    return Ok(vs);
+    Ok(vs)
 }
 
-// FIXME: #8228 Replaceable by an external iterator?
-/// Same as map, but it operates over two parallel vectors.
+/// Perform a fold operation over the result values from an iterator.
 ///
-/// A precondition is used here to ensure that the vectors are the same
-/// length.  While we do not often use preconditions in the standard
-/// library, a precondition is used here because result::t is generally
-/// used in 'careful' code contexts where it is both appropriate and easy
-/// to accommodate an error like the vectors being of different lengths.
+/// If an `Err` is encountered, it is immediately returned.
+/// Otherwise, the folded value is returned.
 #[inline]
-pub fn map_vec2<S, T, U: ToStr, V>(ss: &[S], ts: &[T],
-                                   op: &fn(&S,&T) -> Result<V,U>) -> Result<~[V],U> {
-    assert!(vec::same_length(ss, ts));
-    let n = ts.len();
-    let mut vs = vec::with_capacity(n);
-    let mut i = 0u;
-    while i < n {
-        match op(&ss[i],&ts[i]) {
-          Ok(v) => vs.push(v),
-          Err(u) => return Err(u)
+pub fn fold<T, V, E,
+            Iter: Iterator<Result<T, E>>>(
+            mut iterator: Iter,
+            mut init: V,
+            f: &fn(V, T) -> V)
+         -> Result<V, E> {
+    for t in iterator {
+        match t {
+            Ok(v) => init = f(init, v),
+            Err(u) => return Err(u)
         }
-        i += 1u;
     }
-    return Ok(vs);
+    Ok(init)
 }
 
-// FIXME: #8228 Replaceable by an external iterator?
-/// Applies op to the pairwise elements from `ss` and `ts`, aborting on
-/// error.  This could be implemented using `map_zip()` but it is more efficient
-/// on its own as no result vector is built.
+/// Perform a trivial fold operation over the result values
+/// from an iterator.
+///
+/// If an `Err` is encountered, it is immediately returned.
+/// Otherwise, a simple `Ok(())` is returned.
 #[inline]
-pub fn iter_vec2<S, T, U: ToStr>(ss: &[S], ts: &[T],
-                                 op: &fn(&S,&T) -> Result<(),U>) -> Result<(),U> {
-    assert!(vec::same_length(ss, ts));
-    let n = ts.len();
-    let mut i = 0u;
-    while i < n {
-        match op(&ss[i],&ts[i]) {
-          Ok(()) => (),
-          Err(u) => return Err(u)
-        }
-        i += 1u;
-    }
-    return Ok(());
+pub fn fold_<T, E, Iter: Iterator<Result<T, E>>>(
+             iterator: Iter)
+          -> Result<(), E> {
+    fold(iterator, (), |_, _| ())
 }
 
+
 #[cfg(test)]
 mod tests {
     use super::*;
 
     use either;
+    use iterator::range;
     use str::OwnedStr;
+    use vec::ImmutableVector;
 
     pub fn op1() -> Result<int, ~str> { Ok(666) }
 
@@ -431,4 +420,44 @@ pub fn test_to_either() {
         assert_eq!(r.to_either(), either::Right(100));
         assert_eq!(err.to_either(), either::Left(404));
     }
+
+    #[test]
+    fn test_collect() {
+        assert_eq!(collect(range(0, 0)
+                           .map(|_| Ok::<int, ()>(0))),
+                   Ok(~[]));
+        assert_eq!(collect(range(0, 3)
+                           .map(|x| Ok::<int, ()>(x))),
+                   Ok(~[0, 1, 2]));
+        assert_eq!(collect(range(0, 3)
+                           .map(|x| if x > 1 { Err(x) } else { Ok(x) })),
+                   Err(2));
+
+        // test that it does not take more elements than it needs
+        let functions = [|| Ok(()), || Err(1), || fail!()];
+
+        assert_eq!(collect(functions.iter().map(|f| (*f)())),
+                   Err(1));
+    }
+
+    #[test]
+    fn test_fold() {
+        assert_eq!(fold_(range(0, 0)
+                        .map(|_| Ok::<(), ()>(()))),
+                   Ok(()));
+        assert_eq!(fold(range(0, 3)
+                        .map(|x| Ok::<int, ()>(x)),
+                        0, |a, b| a + b),
+                   Ok(3));
+        assert_eq!(fold_(range(0, 3)
+                        .map(|x| if x > 1 { Err(x) } else { Ok(()) })),
+                   Err(2));
+
+        // test that it does not take more elements than it needs
+        let functions = [|| Ok(()), || Err(1), || fail!()];
+
+        assert_eq!(fold_(functions.iter()
+                        .map(|f| (*f)())),
+                   Err(1));
+    }
 }
index 6f26e3bd9efe8d76c934b06e32a8db27772176f3..71eae56c894b81842baf946b38ac56ad610c688c 100644 (file)
@@ -118,12 +118,22 @@ unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> ~[~str] {
         args
     }
 
-    extern {
-        fn rust_take_global_args_lock();
-        fn rust_drop_global_args_lock();
-        fn rust_get_global_args_ptr() -> *mut Option<~~[~str]>;
+    #[cfg(stage0)]
+    mod macro_hack {
+    #[macro_escape];
+    macro_rules! externfn(
+        (fn $name:ident () $(-> $ret_ty:ty),*) => (
+            extern {
+                fn $name() $(-> $ret_ty),*;
+            }
+        )
+    )
     }
 
+    externfn!(fn rust_take_global_args_lock())
+    externfn!(fn rust_drop_global_args_lock())
+    externfn!(fn rust_get_global_args_ptr() -> *mut Option<~~[~str]>)
+
     #[cfg(test)]
     mod tests {
         use option::{Some, None};
index f620a7347a4cd31bf403146bfa4c62c2ceff9a5e..6400c1b660d17f7421bac367c7d5eac0e5d34584 100644 (file)
@@ -52,7 +52,7 @@ unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) {
     match try_take_task_borrow_list() {
         None => { // not recording borrows
             let msg = "borrowed";
-            do msg.to_c_str().with_ref |msg_p| {
+            do msg.with_c_str |msg_p| {
                 sys::begin_unwind_(msg_p, file, line);
             }
         }
@@ -68,7 +68,7 @@ unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) {
                     sep = " and at ";
                 }
             }
-            do msg.to_c_str().with_ref |msg_p| {
+            do msg.with_c_str |msg_p| {
                 sys::begin_unwind_(msg_p, file, line)
             }
         }
@@ -136,6 +136,7 @@ fn write_hex(&self, mut i: uint) {
     }
 
     unsafe fn write_cstr(&self, p: *c_char) {
+        #[fixed_stack_segment]; #[inline(never)];
         use libc::strlen;
         use vec;
 
@@ -208,7 +209,7 @@ pub unsafe fn unrecord_borrow(a: *u8, old_ref_count: uint,
             let br = borrow_list.pop();
             if br.box != a || br.file != file || br.line != line {
                 let err = fmt!("wrong borrow found, br=%?", br);
-                do err.to_c_str().with_ref |msg_p| {
+                do err.with_c_str |msg_p| {
                     sys::begin_unwind_(msg_p, file, line)
                 }
             }
index 7488b08da42c5d9777f1158e452bb446ec9ebe85..7d3f5f917748732982753722828c78349eaee010 100644 (file)
@@ -35,8 +35,9 @@ fn align_to(size: uint, align: uint) -> uint {
 }
 
 /// A wrapper around libc::malloc, aborting on out-of-memory
-#[inline]
 pub unsafe fn malloc_raw(size: uint) -> *c_void {
+    #[fixed_stack_segment]; #[inline(never)];
+
     let p = malloc(size as size_t);
     if p.is_null() {
         // we need a non-allocating way to print an error here
@@ -46,8 +47,9 @@ pub unsafe fn malloc_raw(size: uint) -> *c_void {
 }
 
 /// A wrapper around libc::realloc, aborting on out-of-memory
-#[inline]
 pub unsafe fn realloc_raw(ptr: *mut c_void, size: uint) -> *mut c_void {
+    #[fixed_stack_segment]; #[inline(never)];
+
     let p = realloc(ptr, size as size_t);
     if p.is_null() {
         // we need a non-allocating way to print an error here
@@ -97,8 +99,9 @@ pub unsafe fn exchange_free_(ptr: *c_char) {
     exchange_free(ptr)
 }
 
-#[inline]
 pub unsafe fn exchange_free(ptr: *c_char) {
+    #[fixed_stack_segment]; #[inline(never)];
+
     free(ptr as *c_void);
 }
 
index 2d21bf0f9dcf3b32e05a9668b98ba002a58b7949..d136ddc0fdf1d8a0c026cd75d050ae1b4c054c1d 100644 (file)
@@ -262,7 +262,7 @@ pub trait WriterByteConversions {
     /// (8 bytes).
     fn write_le_f64(&mut self, f: f64);
 
-    /// Write a litten-endian IEEE754 single-precision floating-point
+    /// Write a little-endian IEEE754 single-precision floating-point
     /// (4 bytes).
     fn write_le_f32(&mut self, f: f32);
 
index c980dc9d73efdc6546cf216b0368de4e5eb7e845..9ec1b699b1d1f8f715d4b7d5b8d74fd6eb98f38d 100644 (file)
@@ -19,7 +19,7 @@
 Readers and Writers may be composed to add capabilities like string
 parsing, encoding, and compression.
 
-This will likely live in core::io, not core::rt::io.
+This will likely live in std::io, not std::rt::io.
 
 # Examples
 
@@ -93,7 +93,7 @@
 (continuation-passing) style popularised by node.js. Such systems rely
 on all computations being run inside an event loop which maintains a
 list of all pending I/O events; when one completes the registered
-callback is run and the code that made the I/O request continiues.
+callback is run and the code that made the I/O request continues.
 Such interfaces achieve non-blocking at the expense of being more
 difficult to reason about.
 
 while still providing feedback about errors. The basic strategy:
 
 * Errors are fatal by default, resulting in task failure
-* Errors raise the `io_error` conditon which provides an opportunity to inspect
+* Errors raise the `io_error` condition which provides an opportunity to inspect
   an IoError object containing details.
 * Return values must have a sensible null or zero value which is returned
   if a condition is handled successfully. This may be an `Option`, an empty
 * XXX: How should we use condition handlers that return values?
 * XXX: Should EOF raise default conditions when EOF is not an error?
 
-# Issues withi/o scheduler affinity, work stealing, task pinning
+# Issues with i/o scheduler affinity, work stealing, task pinning
 
 # Resource management
 
@@ -430,7 +430,7 @@ pub trait Reader {
     ///         println(reader.read_line());
     ///     }
     ///
-    /// # Failue
+    /// # Failure
     ///
     /// Returns `true` on failure.
     fn eof(&mut self) -> bool;
index 83bf34941dc705688f39f5ddaa3629fcf21107cd..1608d8cbc2c31fe81c28fbe71e6b4535ec26b4c6 100644 (file)
@@ -141,7 +141,7 @@ pub struct Death {
     on_exit:         Option<~fn(bool)>,
     // nesting level counter for task::unkillable calls (0 == killable).
     unkillable:      int,
-    // nesting level counter for unstable::atomically calls (0 == can yield).
+    // nesting level counter for unstable::atomically calls (0 == can deschedule).
     wont_sleep:      int,
     // A "spare" handle to the kill flag inside the kill handle. Used during
     // blocking/waking as an optimization to avoid two xadds on the refcount.
@@ -572,16 +572,16 @@ pub fn allow_kill(&mut self, already_failing: bool) {
     }
 
     /// Enter a possibly-nested "atomic" section of code. Just for assertions.
-    /// All calls must be paired with a subsequent call to allow_yield.
+    /// All calls must be paired with a subsequent call to allow_deschedule.
     #[inline]
-    pub fn inhibit_yield(&mut self) {
+    pub fn inhibit_deschedule(&mut self) {
         self.wont_sleep += 1;
     }
 
     /// Exit a possibly-nested "atomic" section of code. Just for assertions.
-    /// All calls must be paired with a preceding call to inhibit_yield.
+    /// All calls must be paired with a preceding call to inhibit_deschedule.
     #[inline]
-    pub fn allow_yield(&mut self) {
+    pub fn allow_deschedule(&mut self) {
         rtassert!(self.wont_sleep != 0);
         self.wont_sleep -= 1;
     }
index 8715e768e32767a72e960c7e08826a1cb6256716..bca1b4a70f4c933ba604d15f117255bb593251e3 100644 (file)
@@ -37,6 +37,7 @@ pub struct LocalHeap {
 }
 
 impl LocalHeap {
+    #[fixed_stack_segment] #[inline(never)]
     pub fn new() -> LocalHeap {
         unsafe {
             // Don't need synchronization for the single-threaded local heap
@@ -55,18 +56,21 @@ pub fn new() -> LocalHeap {
         }
     }
 
+    #[fixed_stack_segment] #[inline(never)]
     pub fn alloc(&mut self, td: *TypeDesc, size: uint) -> *OpaqueBox {
         unsafe {
             return rust_boxed_region_malloc(self.boxed_region, td, size as size_t);
         }
     }
 
+    #[fixed_stack_segment] #[inline(never)]
     pub fn realloc(&mut self, ptr: *OpaqueBox, size: uint) -> *OpaqueBox {
         unsafe {
             return rust_boxed_region_realloc(self.boxed_region, ptr, size as size_t);
         }
     }
 
+    #[fixed_stack_segment] #[inline(never)]
     pub fn free(&mut self, box: *OpaqueBox) {
         unsafe {
             return rust_boxed_region_free(self.boxed_region, box);
@@ -75,6 +79,7 @@ pub fn free(&mut self, box: *OpaqueBox) {
 }
 
 impl Drop for LocalHeap {
+    #[fixed_stack_segment] #[inline(never)]
     fn drop(&self) {
         unsafe {
             rust_delete_boxed_region(self.boxed_region);
index 2ec43980419c93ee88f1214fefa301bb13158783..77303cb8c06cf5b04759624bd6ffa03d1ee29f5a 100644 (file)
@@ -24,6 +24,8 @@
 use tls = rt::thread_local_storage;
 
 /// Initialize the TLS key. Other ops will fail if this isn't executed first.
+#[fixed_stack_segment]
+#[inline(never)]
 pub fn init_tls_key() {
     unsafe {
         rust_initialize_rt_tls_key();
@@ -124,6 +126,8 @@ fn tls_key() -> tls::Key {
     }
 }
 
+#[fixed_stack_segment]
+#[inline(never)]
 fn maybe_tls_key() -> Option<tls::Key> {
     unsafe {
         let key: *mut c_void = rust_get_rt_tls_key();
@@ -149,8 +153,6 @@ fn maybe_tls_key() -> Option<tls::Key> {
     }
 
     extern {
-        #[fast_ffi]
         fn rust_get_rt_tls_key() -> *mut c_void;
     }
-
 }
index 117795f6c90e0ab49860e92cd73c6277fceea12a..f35304865bb3d7297442f78b899698f707d05122 100644 (file)
@@ -57,6 +57,7 @@ fn print(s: &str) {
 
 /// Configure logging by traversing the crate map and setting the
 /// per-module global logging flags based on the logging spec
+#[fixed_stack_segment] #[inline(never)]
 pub fn init(crate_map: *u8) {
     use c_str::ToCStr;
     use os;
@@ -66,7 +67,7 @@ pub fn init(crate_map: *u8) {
     let log_spec = os::getenv("RUST_LOG");
     match log_spec {
         Some(spec) => {
-            do spec.to_c_str().with_ref |buf| {
+            do spec.with_c_str |buf| {
                 unsafe { rust_update_log_settings(crate_map, buf) }
             }
         }
@@ -78,8 +79,13 @@ pub fn init(crate_map: *u8) {
     }
 }
 
+#[fixed_stack_segment] #[inline(never)]
 pub fn console_on() { unsafe { rust_log_console_on() } }
+
+#[fixed_stack_segment] #[inline(never)]
 pub fn console_off() { unsafe { rust_log_console_off() } }
+
+#[fixed_stack_segment] #[inline(never)]
 fn should_log_console() -> bool { unsafe { rust_should_log_console() != 0 } }
 
 extern {
index 65214d0cea78a6d415a4fcc609e6c04b166909c1..db1bfdf1bf56cb0cba485736f00bd5f6d74d9f03 100644 (file)
 
 Several modules in `core` are clients of `rt`:
 
-* `core::task` - The user-facing interface to the Rust task model.
-* `core::task::local_data` - The interface to local data.
-* `core::gc` - The garbage collector.
-* `core::unstable::lang` - Miscellaneous lang items, some of which rely on `core::rt`.
-* `core::condition` - Uses local data.
-* `core::cleanup` - Local heap destruction.
-* `core::io` - In the future `core::io` will use an `rt` implementation.
-* `core::logging`
-* `core::pipes`
-* `core::comm`
-* `core::stackwalk`
+* `std::task` - The user-facing interface to the Rust task model.
+* `std::task::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`
 
 */
 
 /// scheduler and task context
 pub mod tube;
 
-/// Simple reimplementation of core::comm
+/// Simple reimplementation of std::comm
 pub mod comm;
 
 mod select;
@@ -200,6 +200,18 @@ pub fn start_on_main_thread(argc: int, argv: **u8, crate_map: *u8, main: ~fn())
     return exit_code;
 }
 
+#[cfg(stage0)]
+mod macro_hack {
+#[macro_escape];
+macro_rules! externfn(
+    (fn $name:ident ($($arg_name:ident : $arg_ty:ty),*) $(-> $ret_ty:ty),*) => (
+        extern {
+            fn $name($($arg_name : $arg_ty),*) $(-> $ret_ty),*;
+        }
+    )
+)
+}
+
 /// One-time runtime initialization.
 ///
 /// Initializes global state, including frobbing
@@ -215,9 +227,7 @@ pub fn init(argc: int, argv: **u8, crate_map: *u8) {
         rust_update_gc_metadata(crate_map);
     }
 
-    extern {
-        fn rust_update_gc_metadata(crate_map: *u8);
-    }
+    externfn!(fn rust_update_gc_metadata(crate_map: *u8));
 }
 
 /// One-time runtime cleanup.
index a126996892118074cafbb00753f8347cbf63177b..4b2a9b7a6cce40b418df65d081be82ac787a5ab9 100644 (file)
@@ -21,6 +21,8 @@ pub struct StackSegment {
 
 impl StackSegment {
     pub fn new(size: uint) -> StackSegment {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             // Crate a block of uninitialized values
             let mut stack = vec::with_capacity(size);
@@ -50,6 +52,8 @@ pub fn end(&self) -> *uint {
 
 impl Drop for StackSegment {
     fn drop(&self) {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             // XXX: Using the FFI to call a C macro. Slow
             rust_valgrind_stack_deregister(self.valgrind_id);
index 708166518bb89e406930dbcd07778b8dd8d50103..22d2600507836159db13e1d5d8f7a1d11cd4b954 100644 (file)
@@ -69,7 +69,7 @@ pub struct Coroutine {
     saved_context: Context
 }
 
-/// Some tasks have a deciated home scheduler that they must run on.
+/// Some tasks have a dedicated home scheduler that they must run on.
 pub enum SchedHome {
     AnySched,
     Sched(SchedHandle)
@@ -441,6 +441,8 @@ pub fn try(&mut self, f: &fn()) {
     }
 
     pub fn begin_unwind(&mut self) -> ! {
+        #[fixed_stack_segment]; #[inline(never)];
+
         self.unwinding = true;
         unsafe {
             rust_begin_unwind(UNWIND_TOKEN);
@@ -592,4 +594,3 @@ fn future_result() {
         }
     }
 }
-
index ca94468e1adaedbb670c421840a46fd9c2d6d108..a9331157749338123d784b36e8673ed77a012e41 100644 (file)
@@ -98,6 +98,8 @@ fn sysctl(name: *mut libc::c_int, namelen: libc::c_uint,
     static RLIMIT_NOFILE: libc::c_int = 8;
 
     pub unsafe fn raise_fd_limit() {
+        #[fixed_stack_segment]; #[inline(never)];
+
         // The strategy here is to fetch the current resource limits, read the kern.maxfilesperproc
         // sysctl value, and bump the soft resource limit for maxfiles up to the sysctl value.
         use ptr::{to_unsafe_ptr, to_mut_unsafe_ptr, mut_null};
@@ -305,6 +307,7 @@ pub fn cleanup_task(mut task: ~Task) {
 }
 
 /// Get a port number, starting at 9600, for use in tests
+#[fixed_stack_segment] #[inline(never)]
 pub fn next_test_port() -> u16 {
     unsafe {
         return rust_dbg_next_port(base_port() as libc::uintptr_t) as u16;
index 9f6cf68245eab59d8f521c720c1f715012626d10..61db08f4813ef5da516cd1d8ecc335cb43fc9a3d 100644 (file)
@@ -23,6 +23,8 @@ pub struct Thread {
 impl Thread {
     pub fn start(main: ~fn()) -> Thread {
         fn substart(main: &~fn()) -> *raw_thread {
+            #[fixed_stack_segment]; #[inline(never)];
+
             unsafe { rust_raw_thread_start(main) }
         }
         let raw = substart(&main);
@@ -34,6 +36,8 @@ fn substart(main: &~fn()) -> *raw_thread {
     }
 
     pub fn join(self) {
+        #[fixed_stack_segment]; #[inline(never)];
+
         assert!(!self.joined);
         let mut this = self;
         unsafe { rust_raw_thread_join(this.raw_thread); }
@@ -43,6 +47,8 @@ pub fn join(self) {
 
 impl Drop for Thread {
     fn drop(&self) {
+        #[fixed_stack_segment]; #[inline(never)];
+
         assert!(self.joined);
         unsafe { rust_raw_thread_delete(self.raw_thread) }
     }
index 5041b559ecbff8bb67b710f73012358920b19c08..a9cd29c18c9652d58a2fbe10704d236bf6650ccb 100644 (file)
 pub type Key = pthread_key_t;
 
 #[cfg(unix)]
+#[fixed_stack_segment]
+#[inline(never)]
 pub unsafe fn create(key: &mut Key) {
     assert_eq!(0, pthread_key_create(key, null()));
 }
 
 #[cfg(unix)]
+#[fixed_stack_segment]
+#[inline(never)]
 pub unsafe fn set(key: Key, value: *mut c_void) {
     assert_eq!(0, pthread_setspecific(key, value));
 }
 
 #[cfg(unix)]
+#[fixed_stack_segment]
+#[inline(never)]
 pub unsafe fn get(key: Key) -> *mut c_void {
     pthread_getspecific(key)
 }
@@ -58,6 +64,8 @@ pub unsafe fn get(key: Key) -> *mut c_void {
 pub type Key = DWORD;
 
 #[cfg(windows)]
+#[fixed_stack_segment]
+#[inline(never)]
 pub unsafe fn create(key: &mut Key) {
     static TLS_OUT_OF_INDEXES: DWORD = 0xFFFFFFFF;
     *key = TlsAlloc();
@@ -65,11 +73,15 @@ pub unsafe fn create(key: &mut Key) {
 }
 
 #[cfg(windows)]
+#[fixed_stack_segment]
+#[inline(never)]
 pub unsafe fn set(key: Key, value: *mut c_void) {
     assert!(0 != TlsSetValue(key, value))
 }
 
 #[cfg(windows)]
+#[fixed_stack_segment]
+#[inline(never)]
 pub unsafe fn get(key: Key) -> *mut c_void {
     TlsGetValue(key)
 }
index 6280b64ecf51c71742a22751ef64ba176d0a0860..b8c7c8761e85d72cd2ffaae9a5320b5946e74fce 100644 (file)
@@ -17,6 +17,8 @@
 
 /// Get the number of cores available
 pub fn num_cpus() -> uint {
+    #[fixed_stack_segment]; #[inline(never)];
+
     unsafe {
         return rust_get_num_cpus();
     }
@@ -94,11 +96,16 @@ pub fn abort(msg: &str) -> ! {
     rterrln!("%s", "");
     rterrln!("fatal runtime error: %s", msg);
 
-    unsafe { libc::abort(); }
+    abort();
+
+    fn abort() -> ! {
+        #[fixed_stack_segment]; #[inline(never)];
+        unsafe { libc::abort() }
+    }
 }
 
 pub fn set_exit_status(code: int) {
-
+    #[fixed_stack_segment]; #[inline(never)];
     unsafe {
         return rust_set_exit_status_newrt(code as libc::uintptr_t);
     }
@@ -109,7 +116,7 @@ pub fn set_exit_status(code: int) {
 }
 
 pub fn get_exit_status() -> int {
-
+    #[fixed_stack_segment]; #[inline(never)];
     unsafe {
         return rust_get_exit_status_newrt() as int;
     }
index 6c5a28b31b1e4e43568cb442ed5d06c35dc13900..9312efbf03e9ac4f0d9e3e66e7fc07bea31eca8d 100644 (file)
@@ -10,7 +10,7 @@
 
 /*!
 
-Bindings to libuv, along with the default implementation of `core::rt::rtio`.
+Bindings to libuv, along with the default implementation of `std::rt::rtio`.
 
 UV types consist of the event loop (Loop), Watchers, Requests and
 Callbacks.
@@ -310,6 +310,8 @@ pub fn slice_to_uv_buf(v: &[u8]) -> Buf {
 
 /// Transmute an owned vector to a Buf
 pub fn vec_to_uv_buf(v: ~[u8]) -> Buf {
+    #[fixed_stack_segment]; #[inline(never)];
+
     unsafe {
         let data = malloc(v.len() as size_t) as *u8;
         assert!(data.is_not_null());
@@ -323,6 +325,8 @@ pub fn vec_to_uv_buf(v: ~[u8]) -> Buf {
 
 /// Transmute a Buf that was once a ~[u8] back to ~[u8]
 pub fn vec_from_uv_buf(buf: Buf) -> Option<~[u8]> {
+    #[fixed_stack_segment]; #[inline(never)];
+
     if !(buf.len == 0 && buf.base.is_null()) {
         let v = unsafe { vec::from_buf(buf.base, buf.len as uint) };
         unsafe { free(buf.base as *c_void) };
index 038ebad3540aecd29657474dffaacaaf8a2ab365..d4794da9b0f2884f47d00a1a48f7c66826b66a71 100644 (file)
@@ -45,6 +45,7 @@ enum SocketNameKind {
 
 fn socket_name<T, U: Watcher + NativeHandle<*T>>(sk: SocketNameKind,
                                                  handle: U) -> Result<SocketAddr, IoError> {
+    #[fixed_stack_segment]; #[inline(never)];
 
     let getsockname = match sk {
         TcpPeer => uvll::rust_uv_tcp_getpeername,
@@ -406,6 +407,8 @@ fn accept(&mut self) -> Result<~RtioTcpStreamObject, IoError> {
     }
 
     fn accept_simultaneously(&mut self) -> Result<(), IoError> {
+        #[fixed_stack_segment]; #[inline(never)];
+
         let r = unsafe {
             uvll::rust_uv_tcp_simultaneous_accepts(self.watcher.native_handle(), 1 as c_int)
         };
@@ -417,6 +420,8 @@ fn accept_simultaneously(&mut self) -> Result<(), IoError> {
     }
 
     fn dont_accept_simultaneously(&mut self) -> Result<(), IoError> {
+        #[fixed_stack_segment]; #[inline(never)];
+
         let r = unsafe {
             uvll::rust_uv_tcp_simultaneous_accepts(self.watcher.native_handle(), 0 as c_int)
         };
@@ -524,6 +529,8 @@ fn peer_name(&mut self) -> Result<SocketAddr, IoError> {
     }
 
     fn control_congestion(&mut self) -> Result<(), IoError> {
+        #[fixed_stack_segment]; #[inline(never)];
+
         let r = unsafe {
             uvll::rust_uv_tcp_nodelay(self.native_handle(), 0 as c_int)
         };
@@ -535,6 +542,8 @@ fn control_congestion(&mut self) -> Result<(), IoError> {
     }
 
     fn nodelay(&mut self) -> Result<(), IoError> {
+        #[fixed_stack_segment]; #[inline(never)];
+
         let r = unsafe {
             uvll::rust_uv_tcp_nodelay(self.native_handle(), 1 as c_int)
         };
@@ -546,6 +555,8 @@ fn nodelay(&mut self) -> Result<(), IoError> {
     }
 
     fn keepalive(&mut self, delay_in_seconds: uint) -> Result<(), IoError> {
+        #[fixed_stack_segment]; #[inline(never)];
+
         let r = unsafe {
             uvll::rust_uv_tcp_keepalive(self.native_handle(), 1 as c_int,
                                         delay_in_seconds as c_uint)
@@ -558,6 +569,8 @@ fn keepalive(&mut self, delay_in_seconds: uint) -> Result<(), IoError> {
     }
 
     fn letdie(&mut self) -> Result<(), IoError> {
+        #[fixed_stack_segment]; #[inline(never)];
+
         let r = unsafe {
             uvll::rust_uv_tcp_keepalive(self.native_handle(), 0 as c_int, 0 as c_uint)
         };
@@ -654,7 +667,7 @@ fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> Result<(), IoError> {
 
     fn join_multicast(&mut self, multi: IpAddr) -> Result<(), IoError> {
         let r = unsafe {
-            do multi.to_str().to_c_str().with_ref |m_addr| {
+            do multi.to_str().with_c_str |m_addr| {
                 uvll::udp_set_membership(self.native_handle(), m_addr,
                                          ptr::null(), uvll::UV_JOIN_GROUP)
             }
@@ -668,7 +681,7 @@ fn join_multicast(&mut self, multi: IpAddr) -> Result<(), IoError> {
 
     fn leave_multicast(&mut self, multi: IpAddr) -> Result<(), IoError> {
         let r = unsafe {
-            do multi.to_str().to_c_str().with_ref |m_addr| {
+            do multi.to_str().with_c_str |m_addr| {
                 uvll::udp_set_membership(self.native_handle(), m_addr,
                                          ptr::null(), uvll::UV_LEAVE_GROUP)
             }
index e240395a495d36f02f60cc0daadd06c58353c773..65c0cffe5a073a57d607f0a1d93791b4233c0dd6 100644 (file)
@@ -23,7 +23,7 @@
  * There are also a collection of helper functions to ease interacting
  * with the low-level API.
  *
- * As new functionality, existant in uv.h, is added to the rust stdlib,
+ * As new functionality, existent in uv.h, is added to the rust stdlib,
  * the mappings should be added in this module.
  */
 
@@ -124,6 +124,8 @@ pub enum uv_membership {
 }
 
 pub unsafe fn malloc_handle(handle: uv_handle_type) -> *c_void {
+    #[fixed_stack_segment]; #[inline(never)];
+
     assert!(handle != UV_UNKNOWN_HANDLE && handle != UV_HANDLE_TYPE_MAX);
     let size = rust_uv_handle_size(handle as uint);
     let p = malloc(size);
@@ -132,10 +134,14 @@ pub unsafe fn malloc_handle(handle: uv_handle_type) -> *c_void {
 }
 
 pub unsafe fn free_handle(v: *c_void) {
+    #[fixed_stack_segment]; #[inline(never)];
+
     free(v)
 }
 
 pub unsafe fn malloc_req(req: uv_req_type) -> *c_void {
+    #[fixed_stack_segment]; #[inline(never)];
+
     assert!(req != UV_UNKNOWN_REQ && req != UV_REQ_TYPE_MAX);
     let size = rust_uv_req_size(req as uint);
     let p = malloc(size);
@@ -144,17 +150,22 @@ pub unsafe fn malloc_req(req: uv_req_type) -> *c_void {
 }
 
 pub unsafe fn free_req(v: *c_void) {
+    #[fixed_stack_segment]; #[inline(never)];
+
     free(v)
 }
 
 #[test]
 fn handle_sanity_check() {
+    #[fixed_stack_segment]; #[inline(never)];
     unsafe {
         assert_eq!(UV_HANDLE_TYPE_MAX as uint, rust_uv_handle_type_max());
     }
 }
 
 #[test]
+#[fixed_stack_segment]
+#[inline(never)]
 fn request_sanity_check() {
     unsafe {
         assert_eq!(UV_REQ_TYPE_MAX as uint, rust_uv_req_type_max());
@@ -162,59 +173,87 @@ fn request_sanity_check() {
 }
 
 pub unsafe fn loop_new() -> *c_void {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_loop_new();
 }
 
 pub unsafe fn loop_delete(loop_handle: *c_void) {
+    #[fixed_stack_segment]; #[inline(never)];
+
     rust_uv_loop_delete(loop_handle);
 }
 
 pub unsafe fn run(loop_handle: *c_void) {
+    #[fixed_stack_segment]; #[inline(never)];
+
     rust_uv_run(loop_handle);
 }
 
 pub unsafe fn close<T>(handle: *T, cb: *u8) {
+    #[fixed_stack_segment]; #[inline(never)];
+
     rust_uv_close(handle as *c_void, cb);
 }
 
 pub unsafe fn walk(loop_handle: *c_void, cb: *u8, arg: *c_void) {
+    #[fixed_stack_segment]; #[inline(never)];
+
     rust_uv_walk(loop_handle, cb, arg);
 }
 
 pub unsafe fn idle_new() -> *uv_idle_t {
+    #[fixed_stack_segment]; #[inline(never)];
+
     rust_uv_idle_new()
 }
 
 pub unsafe fn idle_delete(handle: *uv_idle_t) {
+    #[fixed_stack_segment]; #[inline(never)];
+
     rust_uv_idle_delete(handle)
 }
 
 pub unsafe fn idle_init(loop_handle: *uv_loop_t, handle: *uv_idle_t) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     rust_uv_idle_init(loop_handle, handle)
 }
 
 pub unsafe fn idle_start(handle: *uv_idle_t, cb: uv_idle_cb) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     rust_uv_idle_start(handle, cb)
 }
 
 pub unsafe fn idle_stop(handle: *uv_idle_t) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     rust_uv_idle_stop(handle)
 }
 
 pub unsafe fn udp_init(loop_handle: *uv_loop_t, handle: *uv_udp_t) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_udp_init(loop_handle, handle);
 }
 
 pub unsafe fn udp_bind(server: *uv_udp_t, addr: *sockaddr_in, flags: c_uint) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_udp_bind(server, addr, flags);
 }
 
 pub unsafe fn udp_bind6(server: *uv_udp_t, addr: *sockaddr_in6, flags: c_uint) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_udp_bind6(server, addr, flags);
 }
 
 pub unsafe fn udp_send<T>(req: *uv_udp_send_t, handle: *T, buf_in: &[uv_buf_t],
                           addr: *sockaddr_in, cb: uv_udp_send_cb) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     let buf_ptr = vec::raw::to_ptr(buf_in);
     let buf_cnt = buf_in.len() as i32;
     return rust_uv_udp_send(req, handle as *c_void, buf_ptr, buf_cnt, addr, cb);
@@ -222,6 +261,8 @@ pub unsafe fn udp_send<T>(req: *uv_udp_send_t, handle: *T, buf_in: &[uv_buf_t],
 
 pub unsafe fn udp_send6<T>(req: *uv_udp_send_t, handle: *T, buf_in: &[uv_buf_t],
                           addr: *sockaddr_in6, cb: uv_udp_send_cb) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     let buf_ptr = vec::raw::to_ptr(buf_in);
     let buf_cnt = buf_in.len() as i32;
     return rust_uv_udp_send6(req, handle as *c_void, buf_ptr, buf_cnt, addr, cb);
@@ -229,124 +270,184 @@ pub unsafe fn udp_send6<T>(req: *uv_udp_send_t, handle: *T, buf_in: &[uv_buf_t],
 
 pub unsafe fn udp_recv_start(server: *uv_udp_t, on_alloc: uv_alloc_cb,
                              on_recv: uv_udp_recv_cb) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_udp_recv_start(server, on_alloc, on_recv);
 }
 
 pub unsafe fn udp_recv_stop(server: *uv_udp_t) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_udp_recv_stop(server);
 }
 
 pub unsafe fn get_udp_handle_from_send_req(send_req: *uv_udp_send_t) -> *uv_udp_t {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_get_udp_handle_from_send_req(send_req);
 }
 
 pub unsafe fn udp_get_sockname(handle: *uv_udp_t, name: *sockaddr_storage) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_udp_getsockname(handle, name);
 }
 
 pub unsafe fn udp_set_membership(handle: *uv_udp_t, multicast_addr: *c_char,
                                  interface_addr: *c_char, membership: uv_membership) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_udp_set_membership(handle, multicast_addr, interface_addr, membership as c_int);
 }
 
 pub unsafe fn udp_set_multicast_loop(handle: *uv_udp_t, on: c_int) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_udp_set_multicast_loop(handle, on);
 }
 
 pub unsafe fn udp_set_multicast_ttl(handle: *uv_udp_t, ttl: c_int) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_udp_set_multicast_ttl(handle, ttl);
 }
 
 pub unsafe fn udp_set_ttl(handle: *uv_udp_t, ttl: c_int) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_udp_set_ttl(handle, ttl);
 }
 
 pub unsafe fn udp_set_broadcast(handle: *uv_udp_t, on: c_int) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_udp_set_broadcast(handle, on);
 }
 
 pub unsafe fn tcp_init(loop_handle: *c_void, handle: *uv_tcp_t) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_tcp_init(loop_handle, handle);
 }
 
 pub unsafe fn tcp_connect(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t,
                           addr_ptr: *sockaddr_in, after_connect_cb: *u8) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr, after_connect_cb, addr_ptr);
 }
 
 pub unsafe fn tcp_connect6(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t,
                            addr_ptr: *sockaddr_in6, after_connect_cb: *u8) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_tcp_connect6(connect_ptr, tcp_handle_ptr, after_connect_cb, addr_ptr);
 }
 
 pub unsafe fn tcp_bind(tcp_server_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_tcp_bind(tcp_server_ptr, addr_ptr);
 }
 
 pub unsafe fn tcp_bind6(tcp_server_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in6) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_tcp_bind6(tcp_server_ptr, addr_ptr);
 }
 
 pub unsafe fn tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, name: *sockaddr_storage) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_tcp_getpeername(tcp_handle_ptr, name);
 }
 
 pub unsafe fn tcp_getsockname(handle: *uv_tcp_t, name: *sockaddr_storage) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_tcp_getsockname(handle, name);
 }
 
 pub unsafe fn tcp_nodelay(handle: *uv_tcp_t, enable: c_int) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_tcp_nodelay(handle, enable);
 }
 
 pub unsafe fn tcp_keepalive(handle: *uv_tcp_t, enable: c_int, delay: c_uint) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_tcp_keepalive(handle, enable, delay);
 }
 
 pub unsafe fn tcp_simultaneous_accepts(handle: *uv_tcp_t, enable: c_int) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_tcp_simultaneous_accepts(handle, enable);
 }
 
 pub unsafe fn listen<T>(stream: *T, backlog: c_int, cb: *u8) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_listen(stream as *c_void, backlog, cb);
 }
 
 pub unsafe fn accept(server: *c_void, client: *c_void) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_accept(server as *c_void, client as *c_void);
 }
 
 pub unsafe fn write<T>(req: *uv_write_t, stream: *T, buf_in: &[uv_buf_t], cb: *u8) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     let buf_ptr = vec::raw::to_ptr(buf_in);
     let buf_cnt = buf_in.len() as i32;
     return rust_uv_write(req as *c_void, stream as *c_void, buf_ptr, buf_cnt, cb);
 }
 pub unsafe fn read_start(stream: *uv_stream_t, on_alloc: uv_alloc_cb, on_read: *u8) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_read_start(stream as *c_void, on_alloc, on_read);
 }
 
 pub unsafe fn read_stop(stream: *uv_stream_t) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_read_stop(stream as *c_void);
 }
 
 pub unsafe fn last_error(loop_handle: *c_void) -> uv_err_t {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_last_error(loop_handle);
 }
 
 pub unsafe fn strerror(err: *uv_err_t) -> *c_char {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_strerror(err);
 }
 pub unsafe fn err_name(err: *uv_err_t) -> *c_char {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_err_name(err);
 }
 
 pub unsafe fn async_init(loop_handle: *c_void, async_handle: *uv_async_t, cb: *u8) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_async_init(loop_handle, async_handle, cb);
 }
 
 pub unsafe fn async_send(async_handle: *uv_async_t) {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_async_send(async_handle);
 }
 pub unsafe fn buf_init(input: *u8, len: uint) -> uv_buf_t {
+    #[fixed_stack_segment]; #[inline(never)];
+
     let out_buf = uv_buf_t { base: ptr::null(), len: 0 as size_t };
     let out_buf_ptr = ptr::to_unsafe_ptr(&out_buf);
     rust_uv_buf_init(out_buf_ptr, input, len as size_t);
@@ -354,99 +455,149 @@ pub unsafe fn buf_init(input: *u8, len: uint) -> uv_buf_t {
 }
 
 pub unsafe fn timer_init(loop_ptr: *c_void, timer_ptr: *uv_timer_t) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_timer_init(loop_ptr, timer_ptr);
 }
 pub unsafe fn timer_start(timer_ptr: *uv_timer_t, cb: *u8, timeout: u64,
                           repeat: u64) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_timer_start(timer_ptr, cb, timeout, repeat);
 }
 pub unsafe fn timer_stop(timer_ptr: *uv_timer_t) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_timer_stop(timer_ptr);
 }
 
 pub unsafe fn is_ip4_addr(addr: *sockaddr) -> bool {
+    #[fixed_stack_segment]; #[inline(never)];
+
     match rust_uv_is_ipv4_sockaddr(addr) { 0 => false, _ => true }
 }
 
 pub unsafe fn is_ip6_addr(addr: *sockaddr) -> bool {
+    #[fixed_stack_segment]; #[inline(never)];
+
     match rust_uv_is_ipv6_sockaddr(addr) { 0 => false, _ => true }
 }
 
 pub unsafe fn malloc_ip4_addr(ip: &str, port: int) -> *sockaddr_in {
-    do ip.to_c_str().with_ref |ip_buf| {
+    #[fixed_stack_segment]; #[inline(never)];
+    do ip.with_c_str |ip_buf| {
         rust_uv_ip4_addrp(ip_buf as *u8, port as libc::c_int)
     }
 }
 pub unsafe fn malloc_ip6_addr(ip: &str, port: int) -> *sockaddr_in6 {
-    do ip.to_c_str().with_ref |ip_buf| {
+    #[fixed_stack_segment]; #[inline(never)];
+    do ip.with_c_str |ip_buf| {
         rust_uv_ip6_addrp(ip_buf as *u8, port as libc::c_int)
     }
 }
 
 pub unsafe fn malloc_sockaddr_storage() -> *sockaddr_storage {
+    #[fixed_stack_segment]; #[inline(never)];
+
     rust_uv_malloc_sockaddr_storage()
 }
 
 pub unsafe fn free_sockaddr_storage(ss: *sockaddr_storage) {
+    #[fixed_stack_segment]; #[inline(never)];
+
     rust_uv_free_sockaddr_storage(ss);
 }
 
 pub unsafe fn free_ip4_addr(addr: *sockaddr_in) {
+    #[fixed_stack_segment]; #[inline(never)];
+
     rust_uv_free_ip4_addr(addr);
 }
 
 pub unsafe fn free_ip6_addr(addr: *sockaddr_in6) {
+    #[fixed_stack_segment]; #[inline(never)];
+
     rust_uv_free_ip6_addr(addr);
 }
 
 pub unsafe fn ip4_name(addr: *sockaddr_in, dst: *u8, size: size_t) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_ip4_name(addr, dst, size);
 }
 
 pub unsafe fn ip6_name(addr: *sockaddr_in6, dst: *u8, size: size_t) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_ip6_name(addr, dst, size);
 }
 
 pub unsafe fn ip4_port(addr: *sockaddr_in) -> c_uint {
+    #[fixed_stack_segment]; #[inline(never)];
+
    return rust_uv_ip4_port(addr);
 }
 
 pub unsafe fn ip6_port(addr: *sockaddr_in6) -> c_uint {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_ip6_port(addr);
 }
 
 // data access helpers
 pub unsafe fn get_loop_for_uv_handle<T>(handle: *T) -> *c_void {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_get_loop_for_uv_handle(handle as *c_void);
 }
 pub unsafe fn get_stream_handle_from_connect_req(connect: *uv_connect_t) -> *uv_stream_t {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_get_stream_handle_from_connect_req(connect);
 }
 pub unsafe fn get_stream_handle_from_write_req(write_req: *uv_write_t) -> *uv_stream_t {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_get_stream_handle_from_write_req(write_req);
 }
 pub unsafe fn get_data_for_uv_loop(loop_ptr: *c_void) -> *c_void {
+    #[fixed_stack_segment]; #[inline(never)];
+
     rust_uv_get_data_for_uv_loop(loop_ptr)
 }
 pub unsafe fn set_data_for_uv_loop(loop_ptr: *c_void, data: *c_void) {
+    #[fixed_stack_segment]; #[inline(never)];
+
     rust_uv_set_data_for_uv_loop(loop_ptr, data);
 }
 pub unsafe fn get_data_for_uv_handle<T>(handle: *T) -> *c_void {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_get_data_for_uv_handle(handle as *c_void);
 }
 pub unsafe fn set_data_for_uv_handle<T, U>(handle: *T, data: *U) {
+    #[fixed_stack_segment]; #[inline(never)];
+
     rust_uv_set_data_for_uv_handle(handle as *c_void, data as *c_void);
 }
 pub unsafe fn get_data_for_req<T>(req: *T) -> *c_void {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_get_data_for_req(req as *c_void);
 }
 pub unsafe fn set_data_for_req<T, U>(req: *T, data: *U) {
+    #[fixed_stack_segment]; #[inline(never)];
+
     rust_uv_set_data_for_req(req as *c_void, data as *c_void);
 }
 pub unsafe fn get_base_from_buf(buf: uv_buf_t) -> *u8 {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_get_base_from_buf(buf);
 }
 pub unsafe fn get_len_from_buf(buf: uv_buf_t) -> size_t {
+    #[fixed_stack_segment]; #[inline(never)];
+
     return rust_uv_get_len_from_buf(buf);
 }
 pub unsafe fn get_last_err_info(uv_loop: *c_void) -> ~str {
index 31e317604c77e073ba75edde11acddec9d970e13..a43d448dae51f30a0bda7b6c7312c4df4ddd8d9a 100644 (file)
@@ -68,7 +68,7 @@ pub struct ProcessOptions<'self> {
      * If this is Some(vec-of-names-and-values) then the new process will
      * have an environment containing the given named values only.
      */
-    env: Option<&'self [(~str, ~str)]>,
+    env: Option<~[(~str, ~str)]>,
 
     /**
      * If this is None then the new process will use the same initial working
@@ -90,7 +90,7 @@ pub struct ProcessOptions<'self> {
     in_fd: Option<c_int>,
 
     /**
-     * If this is None then a new pipe will be created for the new progam's
+     * If this is None then a new pipe will be created for the new program's
      * output and Process.output() will provide a Reader to read from this pipe.
      *
      * If this is Some(file-descriptor) then the new process will write its output
@@ -100,7 +100,7 @@ pub struct ProcessOptions<'self> {
     out_fd: Option<c_int>,
 
     /**
-     * If this is None then a new pipe will be created for the new progam's
+     * If this is None then a new pipe will be created for the new program's
      * error stream and Process.error() will provide a Reader to read from this pipe.
      *
      * If this is Some(file-descriptor) then the new process will write its error output
@@ -147,8 +147,11 @@ impl Process {
      * * options - Options to configure the environment of the process,
      *             the working directory and the standard IO streams.
      */
-    pub fn new(prog: &str, args: &[~str], options: ProcessOptions)
+    pub fn new(prog: &str, args: &[~str],
+               options: ProcessOptions)
                -> Process {
+        #[fixed_stack_segment]; #[inline(never)];
+
         let (in_pipe, in_fd) = match options.in_fd {
             None => {
                 let pipe = os::pipe();
@@ -171,7 +174,7 @@ pub fn new(prog: &str, args: &[~str], options: ProcessOptions)
             Some(fd) => (None, fd)
         };
 
-        let res = spawn_process_os(prog, args, options.env, options.dir,
+        let res = spawn_process_os(prog, args, options.env.clone(), options.dir,
                                    in_fd, out_fd, err_fd);
 
         unsafe {
@@ -287,6 +290,7 @@ pub fn error(&mut self) -> @io::Reader {
      * method does nothing.
      */
     pub fn close_input(&mut self) {
+        #[fixed_stack_segment]; #[inline(never)];
         match self.input {
             Some(-1) | None => (),
             Some(fd) => {
@@ -299,10 +303,12 @@ pub fn close_input(&mut self) {
     }
 
     fn close_outputs(&mut self) {
+        #[fixed_stack_segment]; #[inline(never)];
         fclose_and_null(&mut self.output);
         fclose_and_null(&mut self.error);
 
         fn fclose_and_null(f_opt: &mut Option<*libc::FILE>) {
+            #[allow(cstack)]; // fixed_stack_segment declared on enclosing fn
             match *f_opt {
                 Some(f) if !f.is_null() => {
                     unsafe {
@@ -387,6 +393,7 @@ fn destroy_internal(&mut self, force: bool) {
 
         #[cfg(windows)]
         fn killpid(pid: pid_t, _force: bool) {
+            #[fixed_stack_segment]; #[inline(never)];
             unsafe {
                 libc::funcs::extra::kernel32::TerminateProcess(
                     cast::transmute(pid), 1);
@@ -395,6 +402,8 @@ fn killpid(pid: pid_t, _force: bool) {
 
         #[cfg(unix)]
         fn killpid(pid: pid_t, force: bool) {
+            #[fixed_stack_segment]; #[inline(never)];
+
             let signal = if force {
                 libc::consts::os::posix88::SIGKILL
             } else {
@@ -444,9 +453,10 @@ struct SpawnProcessResult {
 
 #[cfg(windows)]
 fn spawn_process_os(prog: &str, args: &[~str],
-                    env: Option<&[(~str, ~str)]>,
+                    env: Option<~[(~str, ~str)]>,
                     dir: Option<&Path>,
                     in_fd: c_int, out_fd: c_int, err_fd: c_int) -> SpawnProcessResult {
+    #[fixed_stack_segment]; #[inline(never)];
 
     use libc::types::os::arch::extra::{DWORD, HANDLE, STARTUPINFO};
     use libc::consts::os::extra::{
@@ -506,7 +516,7 @@ fn spawn_process_os(prog: &str, args: &[~str],
 
         do with_envp(env) |envp| {
             do with_dirp(dir) |dirp| {
-                do cmd.to_c_str().with_ref |cmdp| {
+                do cmd.with_c_str |cmdp| {
                     let created = CreateProcessA(ptr::null(), cast::transmute(cmdp),
                                                  ptr::mut_null(), ptr::mut_null(), TRUE,
                                                  0, envp, dirp, &mut si, &mut pi);
@@ -627,9 +637,10 @@ fn backslash_run_ends_in_quote(s: &str, mut i: uint) -> bool {
 
 #[cfg(unix)]
 fn spawn_process_os(prog: &str, args: &[~str],
-                    env: Option<&[(~str, ~str)]>,
+                    env: Option<~[(~str, ~str)]>,
                     dir: Option<&Path>,
                     in_fd: c_int, out_fd: c_int, err_fd: c_int) -> SpawnProcessResult {
+    #[fixed_stack_segment]; #[inline(never)];
 
     use libc::funcs::posix88::unistd::{fork, dup2, close, chdir, execvp};
     use libc::funcs::bsd44::getdtablesize;
@@ -717,7 +728,7 @@ fn with_argv<T>(prog: &str, args: &[~str], cb: &fn(**libc::c_char) -> T) -> T {
 }
 
 #[cfg(unix)]
-fn with_envp<T>(env: Option<&[(~str, ~str)]>, cb: &fn(*c_void) -> T) -> T {
+fn with_envp<T>(env: Option<~[(~str, ~str)]>, cb: &fn(*c_void) -> T) -> T {
     use vec;
 
     // On posixy systems we can pass a char** for envp, which is a
@@ -749,7 +760,7 @@ fn with_envp<T>(env: Option<&[(~str, ~str)]>, cb: &fn(*c_void) -> T) -> T {
 }
 
 #[cfg(windows)]
-fn with_envp<T>(env: Option<&[(~str, ~str)]>, cb: &fn(*mut c_void) -> T) -> T {
+fn with_envp<T>(env: Option<~[(~str, ~str)]>, cb: &fn(*mut c_void) -> T) -> T {
     // On win32 we pass an "environment block" which is not a char**, but
     // rather a concatenation of null-terminated k=v\0 sequences, with a final
     // \0 to terminate.
@@ -775,13 +786,14 @@ fn with_envp<T>(env: Option<&[(~str, ~str)]>, cb: &fn(*mut c_void) -> T) -> T {
 
 fn with_dirp<T>(d: Option<&Path>, cb: &fn(*libc::c_char) -> T) -> T {
     match d {
-      Some(dir) => dir.to_c_str().with_ref(|buf| cb(buf)),
+      Some(dir) => dir.with_c_str(|buf| cb(buf)),
       None => cb(ptr::null())
     }
 }
 
 #[cfg(windows)]
 fn free_handle(handle: *()) {
+    #[fixed_stack_segment]; #[inline(never)];
     unsafe {
         libc::funcs::extra::kernel32::CloseHandle(cast::transmute(handle));
     }
@@ -840,7 +852,7 @@ pub fn process_output(prog: &str, args: &[~str]) -> ProcessOutput {
  * Note that this is private to avoid race conditions on unix where if
  * a user calls waitpid(some_process.get_id()) then some_process.finish()
  * and some_process.destroy() and some_process.finalize() will then either
- * operate on a none-existant process or, even worse, on a newer process
+ * operate on a none-existent process or, even worse, on a newer process
  * with the same id.
  */
 fn waitpid(pid: pid_t) -> int {
@@ -848,6 +860,7 @@ fn waitpid(pid: pid_t) -> int {
 
     #[cfg(windows)]
     fn waitpid_os(pid: pid_t) -> int {
+        #[fixed_stack_segment]; #[inline(never)];
 
         use libc::types::os::arch::extra::DWORD;
         use libc::consts::os::extra::{
@@ -892,6 +905,7 @@ fn waitpid_os(pid: pid_t) -> int {
 
     #[cfg(unix)]
     fn waitpid_os(pid: pid_t) -> int {
+        #[fixed_stack_segment]; #[inline(never)];
 
         use libc::funcs::posix01::wait::*;
 
@@ -1069,6 +1083,8 @@ fn writeclose(fd: c_int, s: &str) {
     }
 
     fn readclose(fd: c_int) -> ~str {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             let file = os::fdopen(fd);
             let reader = io::FILE_reader(file, false);
@@ -1284,14 +1300,14 @@ fn test_change_working_directory() {
     }
 
     #[cfg(unix,not(target_os="android"))]
-    fn run_env(env: Option<&[(~str, ~str)]>) -> run::Process {
+    fn run_env(env: Option<~[(~str, ~str)]>) -> run::Process {
         run::Process::new("env", [], run::ProcessOptions {
             env: env,
             .. run::ProcessOptions::new()
         })
     }
     #[cfg(unix,target_os="android")]
-    fn run_env(env: Option<&[(~str, ~str)]>) -> run::Process {
+    fn run_env(env: Option<~[(~str, ~str)]>) -> run::Process {
         run::Process::new("/system/bin/sh", [~"-c",~"set"], run::ProcessOptions {
             env: env,
             .. run::ProcessOptions::new()
@@ -1299,7 +1315,7 @@ fn run_env(env: Option<&[(~str, ~str)]>) -> run::Process {
     }
 
     #[cfg(windows)]
-    fn run_env(env: Option<&[(~str, ~str)]>) -> run::Process {
+    fn run_env(env: Option<~[(~str, ~str)]>) -> run::Process {
         run::Process::new("cmd", [~"/c", ~"set"], run::ProcessOptions {
             env: env,
             .. run::ProcessOptions::new()
@@ -1344,13 +1360,14 @@ fn test_add_to_env() {
         let mut new_env = os::env();
         new_env.push((~"RUN_TEST_NEW_ENV", ~"123"));
 
-        let mut prog = run_env(Some(new_env.slice(0, new_env.len())));
+        let mut prog = run_env(Some(new_env));
         let output = str::from_bytes(prog.finish_with_output().output);
 
         assert!(output.contains("RUN_TEST_NEW_ENV=123"));
     }
 
     fn running_on_valgrind() -> bool {
+        #[fixed_stack_segment]; #[inline(never)];
         unsafe { rust_running_on_valgrind() != 0 }
     }
 
index a92339e2562443a325c50623203e4a3c31ac0759..f537a1f6c33a24289092b782bb7a258040cd7779 100644 (file)
@@ -20,6 +20,7 @@
 use rt::local::Local;
 use rt::rtio::EventLoop;
 use task;
+use unstable::finally::Finally;
 use vec::{OwnedVector, MutableVector};
 
 /// Trait for message-passing primitives that can be select()ed on.
@@ -57,28 +58,32 @@ pub fn select<A: Select>(ports: &mut [A]) -> uint {
     let p = Cell::new(p);
     let c = Cell::new(c);
 
-    let sched = Local::take::<Scheduler>();
-    do sched.deschedule_running_task_and_then |sched, task| {
-        let task_handles = task.make_selectable(ports.len());
-
-        for (index, (port, task_handle)) in
-                ports.mut_iter().zip(task_handles.move_iter()).enumerate() {
-            // If one of the ports has data by now, it will wake the handle.
-            if port.block_on(sched, task_handle) {
-                ready_index = index;
-                break;
+    do (|| {
+        let c = Cell::new(c.take());
+        let sched = Local::take::<Scheduler>();
+        do sched.deschedule_running_task_and_then |sched, task| {
+            let task_handles = task.make_selectable(ports.len());
+
+            for (index, (port, task_handle)) in
+                    ports.mut_iter().zip(task_handles.move_iter()).enumerate() {
+                // If one of the ports has data by now, it will wake the handle.
+                if port.block_on(sched, task_handle) {
+                    ready_index = index;
+                    break;
+                }
             }
-        }
 
-        let c = Cell::new(c.take());
-        do sched.event_loop.callback { c.take().send_deferred(()) }
+            let c = Cell::new(c.take());
+            do sched.event_loop.callback { c.take().send_deferred(()) }
+        }
+    }).finally {
+        let p = Cell::new(p.take());
+        // Unkillable is necessary not because getting killed is dangerous here,
+        // but to force the recv not to use the same kill-flag that we used for
+        // selecting. Otherwise a user-sender could spuriously wakeup us here.
+        do task::unkillable { p.take().recv(); }
     }
 
-    // Unkillable is necessary not because getting killed is dangerous here,
-    // but to force the recv not to use the same kill-flag that we used for
-    // selecting. Otherwise a user-sender could spuriously wakeup us here.
-    do task::unkillable { p.take().recv(); }
-
     // Task resumes. Now unblock ourselves from all the ports we blocked on.
     // If the success index wasn't reset, 'take' will just take all of them.
     // Iterate in reverse so the 'earliest' index that's ready gets returned.
@@ -250,7 +255,7 @@ fn select_blocking_helper(killable: bool) {
                     let (c2, p3, c4) = x.take();
                     p3.recv();   // handshake parent
                     c4.send(()); // normal receive
-                    task::yield();
+                    task::deschedule();
                     c2.send(()); // select receive
                 }
 
@@ -294,7 +299,7 @@ fn select_racing_senders_helper(killable: bool, send_on_chans: ~[uint]) {
                             if send_on_chans.contains(&i) {
                                 let c = Cell::new(c);
                                 do spawntask_random {
-                                    task::yield();
+                                    task::deschedule();
                                     c.take().send(());
                                 }
                             }
index 9370e7b0e84c9021f7d03be5b04ad0c5485d591b..7f22f44a6f87286ec101244bcf5953aff531cac2 100644 (file)
@@ -220,3 +220,4 @@ mod std {
     pub use fmt;
     pub use to_bytes;
 }
+
index 9148767851f52e99c1a701dceef9785aec8eb6e0..2a8a79fcb32923f8e058ea8db25f2c43482da409 100644 (file)
@@ -20,7 +20,7 @@
 use cast;
 use char;
 use char::Char;
-use clone::Clone;
+use clone::{Clone, DeepClone};
 use container::{Container, Mutable};
 use iter::Times;
 use iterator::{Iterator, FromIterator, Extendable};
@@ -382,7 +382,7 @@ fn next(&mut self) -> Option<&'self str> {
     }
 }
 
-/// An iterator over the start and end indicies of the matches of a
+/// An iterator over the start and end indices of the matches of a
 /// substring within a larger string
 #[deriving(Clone)]
 pub struct MatchesIndexIterator<'self> {
@@ -893,7 +893,7 @@ pub unsafe fn shift_byte(s: &mut ~str) -> u8 {
     /// Sets the length of a string
     ///
     /// This will explicitly set the size of the string, without actually
-    /// modifing its buffers, so it is up to the caller to ensure that
+    /// modifying its buffers, so it is up to the caller to ensure that
     /// the string is actually the specified size.
     #[inline]
     pub unsafe fn set_len(s: &mut ~str, new_len: uint) {
@@ -2104,6 +2104,13 @@ fn clone(&self) -> ~str {
     }
 }
 
+impl DeepClone for ~str {
+    #[inline]
+    fn deep_clone(&self) -> ~str {
+        self.to_owned()
+    }
+}
+
 impl Clone for @str {
     #[inline]
     fn clone(&self) -> @str {
@@ -2111,9 +2118,16 @@ fn clone(&self) -> @str {
     }
 }
 
-impl<T: Iterator<char>> FromIterator<char, T> for ~str {
+impl DeepClone for @str {
+    #[inline]
+    fn deep_clone(&self) -> @str {
+        *self
+    }
+}
+
+impl FromIterator<char> for ~str {
     #[inline]
-    fn from_iterator(iterator: &mut T) -> ~str {
+    fn from_iterator<T: Iterator<char>>(iterator: &mut T) -> ~str {
         let (lower, _) = iterator.size_hint();
         let mut buf = with_capacity(lower);
         buf.extend(iterator);
@@ -2121,9 +2135,9 @@ fn from_iterator(iterator: &mut T) -> ~str {
     }
 }
 
-impl<T: Iterator<char>> Extendable<char, T> for ~str {
+impl Extendable<char> for ~str {
     #[inline]
-    fn extend(&mut self, iterator: &mut T) {
+    fn extend<T: Iterator<char>>(&mut self, iterator: &mut T) {
         let (lower, _) = iterator.size_hint();
         let reserve = lower + self.len();
         self.reserve_at_least(reserve);
@@ -2894,6 +2908,7 @@ fn test_contains_char() {
 
     #[test]
     fn test_map() {
+        #[fixed_stack_segment]; #[inline(never)];
         assert_eq!(~"", "".map_chars(|c| unsafe {libc::toupper(c as c_char)} as char));
         assert_eq!(~"YMCA", "ymca".map_chars(|c| unsafe {libc::toupper(c as c_char)} as char));
     }
index e0068f5e53e141a1e666e13f6f1f4ddde1e86571..1cfbf841537c5504f30f365848bc202076fd5610 100644 (file)
@@ -376,7 +376,6 @@ fn map_bytes(string: &str, map: &'static [u8]) -> ~str {
 #[cfg(test)]
 mod tests {
     use super::*;
-    use to_bytes::ToBytes;
     use str::from_char;
 
     macro_rules! v2ascii (
@@ -445,7 +444,6 @@ fn test_ascii_into_str() {
 
     #[test]
     fn test_ascii_to_bytes() {
-        assert_eq!(v2ascii!(~[40, 32, 59]).to_bytes(false), ~[40u8, 32u8, 59u8]);
         assert_eq!(v2ascii!(~[40, 32, 59]).into_bytes(), ~[40u8, 32u8, 59u8]);
     }
 
index 03e6412fcb8c739fb8bcc562123a66bfdb1549de..bfb9bee78028c3d59755739f3021f64194d0c427 100644 (file)
@@ -105,8 +105,8 @@ pub trait FailWithCause {
 
 impl FailWithCause for ~str {
     fn fail_with(cause: ~str, file: &'static str, line: uint) -> ! {
-        do cause.to_c_str().with_ref |msg_buf| {
-            do file.to_c_str().with_ref |file_buf| {
+        do cause.with_c_str |msg_buf| {
+            do file.with_c_str |file_buf| {
                 begin_unwind_(msg_buf, file_buf, line as libc::size_t)
             }
         }
@@ -115,8 +115,8 @@ fn fail_with(cause: ~str, file: &'static str, line: uint) -> ! {
 
 impl FailWithCause for &'static str {
     fn fail_with(cause: &'static str, file: &'static str, line: uint) -> ! {
-        do cause.to_c_str().with_ref |msg_buf| {
-            do file.to_c_str().with_ref |file_buf| {
+        do cause.with_c_str |msg_buf| {
+            do file.with_c_str |file_buf| {
                 begin_unwind_(msg_buf, file_buf, line as libc::size_t)
             }
         }
index 3a11dee3138168fbb4a2c5303823d85746001601..8132bfe53778ba246c273019f2f674a94b6f51df 100644 (file)
@@ -147,7 +147,7 @@ pub unsafe fn local_pop<T: 'static>(handle: Handle,
                 // above.
                 let data = match util::replace(entry, None) {
                     Some((_, data, _)) => data,
-                    None => libc::abort(),
+                    None => abort(),
                 };
 
                 // Move `data` into transmute to get out the memory that it
@@ -252,7 +252,7 @@ unsafe fn local_get_with<T: 'static, U>(handle: Handle,
                         }
                     }
                 }
-                _ => libc::abort()
+                _ => abort()
             }
 
             // n.b. 'data' and 'loans' are both invalid pointers at the point
@@ -262,7 +262,7 @@ unsafe fn local_get_with<T: 'static, U>(handle: Handle,
             if return_loan {
                 match map[i] {
                     Some((_, _, ref mut loan)) => { *loan = NoLoan; }
-                    None => { libc::abort(); }
+                    None => { abort(); }
                 }
             }
             return ret;
@@ -270,6 +270,12 @@ unsafe fn local_get_with<T: 'static, U>(handle: Handle,
     }
 }
 
+fn abort() -> ! {
+    #[fixed_stack_segment]; #[inline(never)];
+
+    unsafe { libc::abort() }
+}
+
 pub unsafe fn local_set<T: 'static>(handle: Handle,
                                     key: local_data::Key<T>,
                                     data: T) {
index c38e6f233130b57cd6f0cfd9a28a28520c8b459a..0d2e62a77003e003e016033b5cb4bd2bae37d33c 100644 (file)
@@ -365,7 +365,7 @@ pub fn spawn(&mut self, f: ~fn()) {
         spawn::spawn_raw(opts, f);
     }
 
-    /// Runs a task, while transfering ownership of one argument to the child.
+    /// Runs a task, while transferring ownership of one argument to the child.
     pub fn spawn_with<A:Send>(&mut self, arg: A, f: ~fn(v: A)) {
         let arg = Cell::new(arg);
         do self.spawn {
@@ -474,10 +474,10 @@ pub fn spawn_indestructible(f: ~fn()) {
 
 pub fn spawn_with<A:Send>(arg: A, f: ~fn(v: A)) {
     /*!
-     * Runs a task, while transfering ownership of one argument to the
+     * Runs a task, while transferring ownership of one argument to the
      * child.
      *
-     * This is useful for transfering ownership of noncopyables to
+     * This is useful for transferring ownership of noncopyables to
      * another task.
      *
      * This function is equivalent to `task().spawn_with(arg, f)`.
@@ -537,7 +537,7 @@ pub fn with_task_name<U>(blk: &fn(Option<&str>) -> U) -> U {
     }
 }
 
-pub fn yield() {
+pub fn deschedule() {
     //! Yield control to the task scheduler
 
     use rt::local::Local;
@@ -568,10 +568,10 @@ pub fn failing() -> bool {
  *
  * ~~~
  * do task::unkillable {
- *     // detach / yield / destroy must all be called together
+ *     // detach / deschedule / destroy must all be called together
  *     rustrt::rust_port_detach(po);
  *     // This must not result in the current task being killed
- *     task::yield();
+ *     task::deschedule();
  *     rustrt::rust_port_destroy(po);
  * }
  * ~~~
@@ -689,7 +689,7 @@ fn test_spawn_unlinked_unsup_no_fail_down() { // grandchild sends on a port
             let ch = ch.clone();
             do spawn_unlinked {
                 // Give middle task a chance to fail-but-not-kill-us.
-                do 16.times { task::yield(); }
+                do 16.times { task::deschedule(); }
                 ch.send(()); // If killed first, grandparent hangs.
             }
             fail!(); // Shouldn't kill either (grand)parent or (grand)child.
@@ -712,7 +712,7 @@ fn test_spawn_unlinked_sup_no_fail_up() { // child unlinked fails
     do run_in_newsched_task {
         do spawn_supervised { fail!(); }
         // Give child a chance to fail-but-not-kill-us.
-        do 16.times { task::yield(); }
+        do 16.times { task::deschedule(); }
     }
 }
 #[ignore(reason = "linked failure")]
@@ -821,7 +821,7 @@ fn test_spawn_failure_propagate_grandchild() {
             do spawn_supervised {
                 do spawn_supervised { block_forever(); }
             }
-            do 16.times { task::yield(); }
+            do 16.times { task::deschedule(); }
             fail!();
         };
         assert!(result.is_err());
@@ -838,7 +838,7 @@ fn test_spawn_failure_propagate_secondborn() {
             do spawn_supervised {
                 do spawn { block_forever(); } // linked
             }
-            do 16.times { task::yield(); }
+            do 16.times { task::deschedule(); }
             fail!();
         };
         assert!(result.is_err());
@@ -855,7 +855,7 @@ fn test_spawn_failure_propagate_nephew_or_niece() {
             do spawn { // linked
                 do spawn_supervised { block_forever(); }
             }
-            do 16.times { task::yield(); }
+            do 16.times { task::deschedule(); }
             fail!();
         };
         assert!(result.is_err());
@@ -872,7 +872,7 @@ fn test_spawn_linked_sup_propagate_sibling() {
             do spawn { // linked
                 do spawn { block_forever(); } // linked
             }
-            do 16.times { task::yield(); }
+            do 16.times { task::deschedule(); }
             fail!();
         };
         assert!(result.is_err());
@@ -1045,15 +1045,12 @@ fn test_spawn_sched_childs_on_default_sched() {
 mod testrt {
     use libc;
 
-    #[nolink]
-    extern {
-        pub fn rust_dbg_lock_create() -> *libc::c_void;
-        pub fn rust_dbg_lock_destroy(lock: *libc::c_void);
-        pub fn rust_dbg_lock_lock(lock: *libc::c_void);
-        pub fn rust_dbg_lock_unlock(lock: *libc::c_void);
-        pub fn rust_dbg_lock_wait(lock: *libc::c_void);
-        pub fn rust_dbg_lock_signal(lock: *libc::c_void);
-    }
+    externfn!(fn rust_dbg_lock_create() -> *libc::c_void)
+    externfn!(fn rust_dbg_lock_destroy(lock: *libc::c_void))
+    externfn!(fn rust_dbg_lock_lock(lock: *libc::c_void))
+    externfn!(fn rust_dbg_lock_unlock(lock: *libc::c_void))
+    externfn!(fn rust_dbg_lock_wait(lock: *libc::c_void))
+    externfn!(fn rust_dbg_lock_signal(lock: *libc::c_void))
 }
 
 #[test]
@@ -1169,12 +1166,12 @@ fn test_unkillable() {
 
     // We want to do this after failing
     do spawn_unlinked {
-        do 10.times { yield() }
+        do 10.times { deschedule() }
         ch.send(());
     }
 
     do spawn {
-        yield();
+        deschedule();
         // We want to fail after the unkillable task
         // blocks on recv
         fail!();
@@ -1205,12 +1202,12 @@ fn test_unkillable_nested() {
 
     // We want to do this after failing
     do spawn_unlinked || {
-        do 10.times { yield() }
+        do 10.times { deschedule() }
         ch.send(());
     }
 
     do spawn {
-        yield();
+        deschedule();
         // We want to fail after the unkillable task
         // blocks on recv
         fail!();
@@ -1277,7 +1274,7 @@ fn test_spawn_watched() {
                 t.unlinked();
                 t.watched();
                 do t.spawn {
-                    task::yield();
+                    task::deschedule();
                     fail!();
                 }
             }
@@ -1313,7 +1310,7 @@ fn test_indestructible() {
                 t.unwatched();
                 do t.spawn {
                     p3.recv();
-                    task::yield();
+                    task::deschedule();
                     fail!();
                 }
                 c3.send(());
index f871f4ef6d6acad9db87970e8f40e271c15419ca..198c09964bb6ff274354d4f8b559afeaaaf5a1ac 100644 (file)
 */
 
 use cast;
+use container::Container;
 use io;
 use io::Writer;
 use iterator::Iterator;
 use option::{None, Option, Some};
-use str::StrSlice;
-use vec::ImmutableVector;
+use str::{Str, StrSlice};
+use vec::{Vector, ImmutableVector};
 
 pub type Cb<'self> = &'self fn(buf: &[u8]) -> bool;
 
-/**
- * A trait to implement in order to make a type hashable;
- * This works in combination with the trait `Hash::Hash`, and
- * may in the future be merged with that trait or otherwise
- * modified when default methods and trait inheritence are
- * completed.
- */
+///
+/// A trait to implement in order to make a type hashable;
+/// This works in combination with the trait `std::hash::Hash`, and
+/// may in the future be merged with that trait or otherwise
+/// modified when default methods and trait inheritance are
+/// completed.
+///
+/// IterBytes should be implemented so that the extent of the
+/// produced byte stream can be discovered, given the original
+/// type.
+/// For example, the IterBytes implementation for vectors emits
+/// its length first, and enums should emit their discriminant.
+///
 pub trait IterBytes {
-    /**
-     * Call the provided callback `f` one or more times with
-     * byte-slices that should be used when computing a hash
-     * value or otherwise "flattening" the structure into
-     * a sequence of bytes. The `lsb0` parameter conveys
-     * whether the caller is asking for little-endian bytes
-     * (`true`) or big-endian (`false`); this should only be
-     * relevant in implementations that represent a single
-     * multi-byte datum such as a 32 bit integer or 64 bit
-     * floating-point value. It can be safely ignored for
-     * larger structured types as they are usually processed
-     * left-to-right in declaration order, regardless of
-     * underlying memory endianness.
-     */
+    /// Call the provided callback `f` one or more times with
+    /// byte-slices that should be used when computing a hash
+    /// value or otherwise "flattening" the structure into
+    /// a sequence of bytes. The `lsb0` parameter conveys
+    /// whether the caller is asking for little-endian bytes
+    /// (`true`) or big-endian (`false`); this should only be
+    /// relevant in implementations that represent a single
+    /// multi-byte datum such as a 32 bit integer or 64 bit
+    /// floating-point value. It can be safely ignored for
+    /// larger structured types as they are usually processed
+    /// left-to-right in declaration order, regardless of
+    /// underlying memory endianness.
+    ///
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool;
 }
 
@@ -224,74 +230,76 @@ fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
 impl<'self,A:IterBytes> IterBytes for &'self [A] {
     #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
+        self.len().iter_bytes(lsb0, |b| f(b)) &&
         self.iter().advance(|elt| elt.iter_bytes(lsb0, |b| f(b)))
     }
 }
 
-impl<A:IterBytes,B:IterBytes> IterBytes for (A,B) {
-  #[inline]
-  fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
-    match *self {
-      (ref a, ref b) => { a.iter_bytes(lsb0, |b| f(b)) &&
-                          b.iter_bytes(lsb0, |b| f(b)) }
-    }
-  }
-}
-
-impl<A:IterBytes,B:IterBytes,C:IterBytes> IterBytes for (A,B,C) {
-  #[inline]
-  fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
-    match *self {
-      (ref a, ref b, ref c) => {
-        a.iter_bytes(lsb0, |b| f(b)) &&
-        b.iter_bytes(lsb0, |b| f(b)) &&
-        c.iter_bytes(lsb0, |b| f(b))
-      }
+impl<A: IterBytes> IterBytes for (A, ) {
+    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
+        match *self {
+            (ref a, ) => a.iter_bytes(lsb0, |b| f(b))
+        }
     }
-  }
 }
 
-// Move this to vec, probably.
-fn borrow<'x,A>(a: &'x [A]) -> &'x [A] {
-    a
-}
+macro_rules! iter_bytes_tuple(
+    ($($A:ident),+) => (
+        impl<$($A: IterBytes),+> IterBytes for ($($A),+) {
+            fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
+                match *self {
+                    ($(ref $A),+) => {
+                        $(
+                            $A .iter_bytes(lsb0, |b| f(b))
+                        )&&+
+                    }
+                }
+            }
+        }
+    )
+)
+
+iter_bytes_tuple!(A, B)
+iter_bytes_tuple!(A, B, C)
+iter_bytes_tuple!(A, B, C, D)
+iter_bytes_tuple!(A, B, C, D, E)
+iter_bytes_tuple!(A, B, C, D, E, F)
+iter_bytes_tuple!(A, B, C, D, E, F, G)
+iter_bytes_tuple!(A, B, C, D, E, F, G, H)
 
 impl<A:IterBytes> IterBytes for ~[A] {
     #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
-        borrow(*self).iter_bytes(lsb0, f)
+        self.as_slice().iter_bytes(lsb0, f)
     }
 }
 
 impl<A:IterBytes> IterBytes for @[A] {
     #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
-        borrow(*self).iter_bytes(lsb0, f)
+        self.as_slice().iter_bytes(lsb0, f)
     }
 }
 
 impl<'self> IterBytes for &'self str {
     #[inline]
     fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
-        f(self.as_bytes())
+        // Terminate the string with a byte that does not appear in UTF-8
+        f(self.as_bytes()) && f([0xFF])
     }
 }
 
 impl IterBytes for ~str {
     #[inline]
-    fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
-        // this should possibly include the null terminator, but that
-        // breaks .find_equiv on hashmaps.
-        f(self.as_bytes())
+    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
+        self.as_slice().iter_bytes(lsb0, f)
     }
 }
 
 impl IterBytes for @str {
     #[inline]
-    fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
-        // this should possibly include the null terminator, but that
-        // breaks .find_equiv on hashmaps.
-        f(self.as_bytes())
+    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
+        self.as_slice().iter_bytes(lsb0, f)
     }
 }
 
index 4649aac08b9e0aabc940e4b87720c201147d4d86..a8c450a0516128eef47e658bfbd0913e9c414faa 100644 (file)
@@ -31,7 +31,7 @@ pub trait ToStr {
 
 /// Trait for converting a type to a string, consuming it in the process.
 pub trait ToStrConsume {
-    /// Cosume and convert to a string.
+    /// Consume and convert to a string.
     fn into_str(self) -> ~str;
 }
 
index da1fb9abaeeb6aa0b9d158c3073d5bc9e8e758dc..f5c7b719c4f19bfba24cdd28755b15dba8e0ba96 100644 (file)
@@ -205,16 +205,16 @@ pub fn upper_bound_iter<'a>(&'a self, key: uint) -> TrieMapIterator<'a, T> {
     }
 }
 
-impl<T, Iter: Iterator<(uint, T)>> FromIterator<(uint, T), Iter> for TrieMap<T> {
-    fn from_iterator(iter: &mut Iter) -> TrieMap<T> {
+impl<T> FromIterator<(uint, T)> for TrieMap<T> {
+    fn from_iterator<Iter: Iterator<(uint, T)>>(iter: &mut Iter) -> TrieMap<T> {
         let mut map = TrieMap::new();
         map.extend(iter);
         map
     }
 }
 
-impl<T, Iter: Iterator<(uint, T)>> Extendable<(uint, T), Iter> for TrieMap<T> {
-    fn extend(&mut self, iter: &mut Iter) {
+impl<T> Extendable<(uint, T)> for TrieMap<T> {
+    fn extend<Iter: Iterator<(uint, T)>>(&mut self, iter: &mut Iter) {
         for (k, v) in *iter {
             self.insert(k, v);
         }
@@ -294,16 +294,16 @@ pub fn upper_bound_iter<'a>(&'a self, val: uint) -> TrieSetIterator<'a> {
     }
 }
 
-impl<Iter: Iterator<uint>> FromIterator<uint, Iter> for TrieSet {
-    fn from_iterator(iter: &mut Iter) -> TrieSet {
+impl FromIterator<uint> for TrieSet {
+    fn from_iterator<Iter: Iterator<uint>>(iter: &mut Iter) -> TrieSet {
         let mut set = TrieSet::new();
         set.extend(iter);
         set
     }
 }
 
-impl<Iter: Iterator<uint>> Extendable<uint, Iter> for TrieSet {
-    fn extend(&mut self, iter: &mut Iter) {
+impl Extendable<uint> for TrieSet {
+    fn extend<Iter: Iterator<uint>>(&mut self, iter: &mut Iter) {
         for elem in *iter {
             self.insert(elem);
         }
index 8a3c024ede50d253a323c9b02c9f0148503dc9d6..12073a1f4f0951e4db9d64ba54de5279a5bed565 100644 (file)
@@ -13,9 +13,6 @@
 #[allow(missing_doc)];
 
 use clone::Clone;
-use vec;
-use vec::ImmutableVector;
-use iterator::Iterator;
 
 pub use self::inner::*;
 
@@ -79,55 +76,6 @@ fn second_ref<'a>(&'a self) -> &'a U {
     }
 }
 
-pub trait ExtendedTupleOps<A,B> {
-    fn zip(&self) -> ~[(A, B)];
-    fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C];
-}
-
-impl<'self,
-     A:Clone,
-     B:Clone>
-     ExtendedTupleOps<A,B> for
-     (&'self [A], &'self [B]) {
-    #[inline]
-    fn zip(&self) -> ~[(A, B)] {
-        match *self {
-            (ref a, ref b) => {
-                vec::zip_slice(*a, *b)
-            }
-        }
-    }
-
-    #[inline]
-    fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] {
-        match *self {
-            (ref a, ref b) => {
-                a.iter().zip(b.iter()).map(|(aa, bb)| f(aa, bb)).collect()
-            }
-        }
-    }
-}
-
-impl<A:Clone, B:Clone> ExtendedTupleOps<A,B> for (~[A], ~[B]) {
-    #[inline]
-    fn zip(&self) -> ~[(A, B)] {
-        match *self {
-            (ref a, ref b) => {
-                vec::zip_slice(*a, *b)
-            }
-        }
-    }
-
-    #[inline]
-    fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] {
-        match *self {
-            (ref a, ref b) => {
-                a.iter().zip(b.iter()).map(|(aa, bb)| f(aa, bb)).collect()
-            }
-        }
-    }
-}
-
 // macro for implementing n-ary tuple functions and operations
 
 macro_rules! tuple_impls {
index 2cfe63d99266f97531c16f21781254cef0b92f72..f286235ca0e18b9694cf584c861bcb736e97ae60 100644 (file)
@@ -39,14 +39,14 @@ pub struct AtomicBool {
 }
 
 /**
- * A signed atomic integer type, supporting basic atomic aritmetic operations
+ * A signed atomic integer type, supporting basic atomic arithmetic operations
  */
 pub struct AtomicInt {
     priv v: int
 }
 
 /**
- * An unsigned atomic integer type, supporting basic atomic aritmetic operations
+ * An unsigned atomic integer type, supporting basic atomic arithmetic operations
  */
 pub struct AtomicUint {
     priv v: uint
@@ -497,7 +497,7 @@ pub unsafe fn atomic_xor<T>(dst: &mut T, val: T, order: Ordering) -> T {
  * A fence 'A' which has `Release` ordering semantics, synchronizes with a
  * fence 'B' with (at least) `Acquire` semantics, if and only if there exists
  * atomic operations X and Y, both operating on some atomic object 'M' such
- * that A is sequenced before X, Y is synchronized before B and Y obsevers
+ * that A is sequenced before X, Y is synchronized before B and Y observers
  * the change to M. This provides a happens-before dependence between A and B.
  *
  * Atomic operations with `Release` or `Acquire` semantics can also synchronize
index 49e3e0777df84e58356fe734fe07d3e37c36f34f..6dbe68200b3b7fe23d28c62b72dc39083e7ec993 100644 (file)
@@ -66,7 +66,7 @@ pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<T, ~str> {
         // T but that feature is still unimplemented
 
         let maybe_symbol_value = do dl::check_for_errors_in {
-            do symbol.to_c_str().with_ref |raw_string| {
+            do symbol.with_c_str |raw_string| {
                 dl::symbol(self.handle, raw_string)
             }
         };
@@ -145,16 +145,21 @@ mod dl {
     use result::*;
 
     pub unsafe fn open_external(filename: &path::Path) -> *libc::c_void {
-        do filename.to_c_str().with_ref |raw_name| {
+        #[fixed_stack_segment]; #[inline(never)];
+        do filename.with_c_str |raw_name| {
             dlopen(raw_name, Lazy as libc::c_int)
         }
     }
 
     pub unsafe fn open_internal() -> *libc::c_void {
+        #[fixed_stack_segment]; #[inline(never)];
+
         dlopen(ptr::null(), Lazy as libc::c_int)
     }
 
     pub fn check_for_errors_in<T>(f: &fn()->T) -> Result<T, ~str> {
+        #[fixed_stack_segment]; #[inline(never)];
+
         unsafe {
             do atomically {
                 let _old_error = dlerror();
@@ -172,9 +177,13 @@ pub fn check_for_errors_in<T>(f: &fn()->T) -> Result<T, ~str> {
     }
 
     pub unsafe fn symbol(handle: *libc::c_void, symbol: *libc::c_char) -> *libc::c_void {
+        #[fixed_stack_segment]; #[inline(never)];
+
         dlsym(handle, symbol)
     }
     pub unsafe fn close(handle: *libc::c_void) {
+        #[fixed_stack_segment]; #[inline(never)];
+
         dlclose(handle); ()
     }
 
@@ -204,18 +213,21 @@ mod dl {
     use result::*;
 
     pub unsafe fn open_external(filename: &path::Path) -> *libc::c_void {
+        #[fixed_stack_segment]; #[inline(never)];
         do os::win32::as_utf16_p(filename.to_str()) |raw_name| {
             LoadLibraryW(raw_name)
         }
     }
 
     pub unsafe fn open_internal() -> *libc::c_void {
+        #[fixed_stack_segment]; #[inline(never)];
         let handle = ptr::null();
         GetModuleHandleExW(0 as libc::DWORD, ptr::null(), &handle as **libc::c_void);
         handle
     }
 
     pub fn check_for_errors_in<T>(f: &fn()->T) -> Result<T, ~str> {
+        #[fixed_stack_segment]; #[inline(never)];
         unsafe {
             do atomically {
                 SetLastError(0);
@@ -232,9 +244,11 @@ pub fn check_for_errors_in<T>(f: &fn()->T) -> Result<T, ~str> {
         }
     }
     pub unsafe fn symbol(handle: *libc::c_void, symbol: *libc::c_char) -> *libc::c_void {
+        #[fixed_stack_segment]; #[inline(never)];
         GetProcAddress(handle, symbol)
     }
     pub unsafe fn close(handle: *libc::c_void) {
+        #[fixed_stack_segment]; #[inline(never)];
         FreeLibrary(handle); ()
     }
 
index 10db664450ebf788e3676ab4580ba65f34d63f34..7fbe9179f75aa49d575dfc1f29048b56b46c9d05 100644 (file)
@@ -18,7 +18,7 @@
 do || {
     ...
 }.finally {
-    alway_run_this();
+    always_run_this();
 }
 ~~~
 */
index 861b4f9a350dcb7c8c0c7c63a3360b44a55c24dc..0642bb1973745423c725e64e3ecabdd8d7942677 100644 (file)
@@ -22,7 +22,7 @@
 
 A quick refresher on memory ordering:
 
-* Acquire - a barrier for aquiring a lock. Subsequent reads and writes
+* Acquire - a barrier for acquiring a lock. Subsequent reads and writes
   take place after the barrier.
 * Release - a barrier for releasing a lock. Preceding reads and writes
   take place before the barrier.
index 956ffb82902de0addac7b55c8b0a33f9e22b2e7f..e47a3c49f96bfc6a101f9ae47b3ef4ac7f36d586 100644 (file)
@@ -29,7 +29,7 @@ pub fn fail_bounds_check(file: *c_char, line: size_t,
                          index: size_t, len: size_t) {
     let msg = fmt!("index out of bounds: the len is %d but the index is %d",
                     len as int, index as int);
-    do msg.to_c_str().with_ref |buf| {
+    do msg.with_c_str |buf| {
         fail_(buf, file, line);
     }
 }
@@ -92,11 +92,6 @@ pub unsafe fn check_not_borrowed(a: *u8,
     borrowck::check_not_borrowed(a, file, line)
 }
 
-#[lang="annihilate"]
-pub unsafe fn annihilate() {
-    ::cleanup::annihilate()
-}
-
 #[lang="start"]
 pub fn start(main: *u8, argc: int, argv: **c_char,
              crate_map: *u8) -> int {
index f721dd47a66a0f826027eb27fd3a7934c179d47e..6ad15bfc7c03939884be3590eaad06ffa789d946 100644 (file)
@@ -83,6 +83,8 @@ fn test_run_in_bare_thread_exchange() {
 /// can lead to deadlock. Calling change_dir_locked recursively will
 /// also deadlock.
 pub fn change_dir_locked(p: &Path, action: &fn()) -> bool {
+    #[fixed_stack_segment]; #[inline(never)];
+
     use os;
     use os::change_dir;
     use unstable::sync::atomically;
index adbf9fc757819092ca22f21091e4a7a273d8ba87..29be094121c3b6350bc64c61e7b4e585747730f1 100644 (file)
@@ -272,9 +272,9 @@ fn drop(&self) {
 
 /**
  * Enables a runtime assertion that no operation in the argument closure shall
- * use scheduler operations (yield, recv, spawn, etc). This is for use with
+ * use scheduler operations (deschedule, recv, spawn, etc). This is for use with
  * pthread mutexes, which may block the entire scheduler thread, rather than
- * just one task, and is hence prone to deadlocks if mixed with yielding.
+ * just one task, and is hence prone to deadlocks if mixed with descheduling.
  *
  * NOTE: THIS DOES NOT PROVIDE LOCKING, or any sort of critical-section
  * synchronization whatsoever. It only makes sense to use for CPU-local issues.
@@ -288,10 +288,10 @@ pub unsafe fn atomically<U>(f: &fn() -> U) -> U {
     if in_green_task_context() {
         let t = Local::unsafe_borrow::<Task>();
         do (|| {
-            (*t).death.inhibit_yield();
+            (*t).death.inhibit_deschedule();
             f()
         }).finally {
-            (*t).death.allow_yield();
+            (*t).death.allow_deschedule();
         }
     } else {
         f()
@@ -322,7 +322,6 @@ pub fn new() -> LittleLock {
         }
     }
 
-    #[inline]
     pub unsafe fn lock<T>(&self, f: &fn() -> T) -> T {
         do atomically {
             rust_lock_little_lock(self.l);
@@ -349,7 +348,7 @@ struct ExData<T> {
  * This uses a pthread mutex, not one that's aware of the userspace scheduler.
  * The user of an Exclusive must be careful not to invoke any functions that may
  * reschedule the task while holding the lock, or deadlock may result. If you
- * need to block or yield while accessing shared state, use extra::sync::RWArc.
+ * need to block or deschedule while accessing shared state, use extra::sync::RWArc.
  */
 pub struct Exclusive<T> {
     x: UnsafeAtomicRcBox<ExData<T>>
@@ -377,7 +376,7 @@ pub fn new(user_data: T) -> Exclusive<T> {
     // Exactly like std::arc::MutexArc,access(), but with the LittleLock
     // instead of a proper mutex. Same reason for being unsafe.
     //
-    // Currently, scheduling operations (i.e., yielding, receiving on a pipe,
+    // Currently, scheduling operations (i.e., descheduling, receiving on a pipe,
     // accessing the provided condition variable) are prohibited while inside
     // the Exclusive. Supporting that is a work in progress.
     #[inline]
@@ -410,13 +409,28 @@ pub fn unwrap(self) -> T {
     }
 }
 
-extern {
-    fn rust_create_little_lock() -> rust_little_lock;
-    fn rust_destroy_little_lock(lock: rust_little_lock);
-    fn rust_lock_little_lock(lock: rust_little_lock);
-    fn rust_unlock_little_lock(lock: rust_little_lock);
+#[cfg(stage0)]
+mod macro_hack {
+#[macro_escape];
+macro_rules! externfn(
+    (fn $name:ident () $(-> $ret_ty:ty),*) => (
+        extern {
+            fn $name() $(-> $ret_ty),*;
+        }
+    );
+    (fn $name:ident ($($arg_name:ident : $arg_ty:ty),*) $(-> $ret_ty:ty),*) => (
+        extern {
+            fn $name($($arg_name : $arg_ty),*) $(-> $ret_ty),*;
+        }
+    )
+)
 }
 
+externfn!(fn rust_create_little_lock() -> rust_little_lock)
+externfn!(fn rust_destroy_little_lock(lock: rust_little_lock))
+externfn!(fn rust_lock_little_lock(lock: rust_little_lock))
+externfn!(fn rust_unlock_little_lock(lock: rust_little_lock))
+
 #[cfg(test)]
 mod tests {
     use cell::Cell;
@@ -431,7 +445,7 @@ mod tests {
     fn test_atomically() {
         // NB. The whole runtime will abort on an 'atomic-sleep' violation,
         // so we can't really test for the converse behaviour.
-        unsafe { do atomically { } } task::yield(); // oughtn't fail
+        unsafe { do atomically { } } task::deschedule(); // oughtn't fail
     }
 
     #[test]
@@ -545,7 +559,7 @@ fn arclike_try_unwrap_unwrap_race() {
             c.send(());
         }
         p.recv();
-        task::yield(); // Try to make the unwrapper get blocked first.
+        task::deschedule(); // Try to make the unwrapper get blocked first.
         let left_x = x.try_unwrap();
         assert!(left_x.is_left());
         util::ignore(left_x);
@@ -566,7 +580,7 @@ fn exclusive_new_unwrap_contended() {
         do task::spawn {
             let x2 = x2.take();
             unsafe { do x2.with |_hello| { } }
-            task::yield();
+            task::deschedule();
         }
         assert!(x.unwrap() == ~~"hello");
 
@@ -612,7 +626,7 @@ fn exclusive_new_unwrap_deadlock() {
             let x = Exclusive::new(~~"hello");
             let x2 = x.clone();
             do task::spawn {
-                do 10.times { task::yield(); } // try to let the unwrapper go
+                do 10.times { task::deschedule(); } // try to let the unwrapper go
                 fail!(); // punt it awake from its deadlock
             }
             let _z = x.unwrap();
index 6d27c43def8c0dd5431287041476c0b0fe499e90..7c8046a64b2c2de942c172a42ef075e38828734e 100644 (file)
@@ -390,39 +390,6 @@ pub fn unzip<T,U>(v: ~[(T, U)]) -> (~[T], ~[U]) {
     (ts, us)
 }
 
-/**
- * Convert two vectors to a vector of pairs, by reference. As zip().
- */
-pub fn zip_slice<T:Clone,U:Clone>(v: &[T], u: &[U]) -> ~[(T, U)] {
-    let mut zipped = ~[];
-    let sz = v.len();
-    let mut i = 0u;
-    assert_eq!(sz, u.len());
-    while i < sz {
-        zipped.push((v[i].clone(), u[i].clone()));
-        i += 1u;
-    }
-    zipped
-}
-
-/**
- * Convert two vectors to a vector of pairs.
- *
- * Returns a vector of tuples, where the i-th tuple contains the
- * i-th elements from each of the input vectors.
- */
-pub fn zip<T, U>(mut v: ~[T], mut u: ~[U]) -> ~[(T, U)] {
-    let mut i = v.len();
-    assert_eq!(i, u.len());
-    let mut w = with_capacity(i);
-    while i > 0 {
-        w.push((v.pop(),u.pop()));
-        i -= 1;
-    }
-    w.reverse();
-    w
-}
-
 /**
  * Iterate over all permutations of vector `v`.
  *
@@ -501,7 +468,7 @@ fn next(&mut self) -> Option<&'self [T]> {
 /// elements at a time).
 ///
 /// When the vector len is not evenly divided by the chunk size,
-/// the last slice of the iteration will be the remainer.
+/// the last slice of the iteration will be the remainder.
 #[deriving(Clone)]
 pub struct ChunkIter<'self, T> {
     priv v: &'self [T],
@@ -724,12 +691,6 @@ impl<T> Vector<T> for @[T] {
 }
 
 impl<'self, T> Container for &'self [T] {
-    /// Returns true if a vector contains no elements
-    #[inline]
-    fn is_empty(&self) -> bool {
-        self.as_imm_buf(|_p, len| len == 0u)
-    }
-
     /// Returns the length of a vector
     #[inline]
     fn len(&self) -> uint {
@@ -738,12 +699,6 @@ fn len(&self) -> uint {
 }
 
 impl<T> Container for ~[T] {
-    /// Returns true if a vector contains no elements
-    #[inline]
-    fn is_empty(&self) -> bool {
-        self.as_imm_buf(|_p, len| len == 0u)
-    }
-
     /// Returns the length of a vector
     #[inline]
     fn len(&self) -> uint {
@@ -1975,7 +1930,7 @@ pub mod raw {
      * Sets the length of a vector
      *
      * This will explicitly set the size of the vector, without actually
-     * modifing its buffers, so it is up to the caller to ensure that
+     * modifying its buffers, so it is up to the caller to ensure that
      * the vector is actually the specified size.
      */
     #[inline]
@@ -2344,8 +2299,8 @@ fn next(&mut self) -> Option<T> {
     }
 }
 
-impl<A, T: Iterator<A>> FromIterator<A, T> for ~[A] {
-    fn from_iterator(iterator: &mut T) -> ~[A] {
+impl<A> FromIterator<A> for ~[A] {
+    fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> ~[A] {
         let (lower, _) = iterator.size_hint();
         let mut xs = with_capacity(lower);
         for x in *iterator {
@@ -2355,8 +2310,8 @@ fn from_iterator(iterator: &mut T) -> ~[A] {
     }
 }
 
-impl<A, T: Iterator<A>> Extendable<A, T> for ~[A] {
-    fn extend(&mut self, iterator: &mut T) {
+impl<A> Extendable<A> for ~[A] {
+    fn extend<T: Iterator<A>>(&mut self, iterator: &mut T) {
         let (lower, _) = iterator.size_hint();
         let len = self.len();
         self.reserve(len + lower);
@@ -2865,14 +2820,7 @@ fn test_each_permutation() {
 
     #[test]
     fn test_zip_unzip() {
-        let v1 = ~[1, 2, 3];
-        let v2 = ~[4, 5, 6];
-
-        let z1 = zip(v1, v2);
-
-        assert_eq!((1, 4), z1[0]);
-        assert_eq!((2, 5), z1[1]);
-        assert_eq!((3, 6), z1[2]);
+        let z1 = ~[(1, 4), (2, 5), (3, 6)];
 
         let (left, right) = unzip(z1);
 
index 17247222c3ff954783b8d5f67d39f2b29d12f5e0..b01c19a59c18630b00dc07762252e469f4e8a982 100644 (file)
@@ -100,7 +100,7 @@ pub struct Lifetime {
 }
 
 // a "Path" is essentially Rust's notion of a name;
-// for instance: core::cmp::Eq  .  It's represented
+// for instance: std::cmp::Eq  .  It's represented
 // as a sequence of identifiers, along with a bunch
 // of supporting information.
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
@@ -1093,8 +1093,8 @@ pub enum inlined_item {
 /* hold off on tests ... they appear in a later merge.
 #[cfg(test)]
 mod test {
-    use core::option::{None, Option, Some};
-    use core::uint;
+    use std::option::{None, Option, Some};
+    use std::uint;
     use extra;
     use codemap::*;
     use super::*;
index 65032642fda789d4b441697fa4854de1b5e96156..9f179672422cd7295fffcfbd8a006d6e9ee19eb5 100644 (file)
@@ -605,17 +605,29 @@ fn lambda(&self, span: span, ids: ~[ast::ident], blk: ast::Block) -> @ast::expr
 
         self.expr(span, ast::expr_fn_block(fn_decl, blk))
     }
+    #[cfg(stage0)]
     fn lambda0(&self, _span: span, blk: ast::Block) -> @ast::expr {
         let ext_cx = *self;
         let blk_e = self.expr(blk.span, ast::expr_block(blk.clone()));
         quote_expr!(|| $blk_e )
     }
+    #[cfg(not(stage0))]
+    fn lambda0(&self, _span: span, blk: ast::Block) -> @ast::expr {
+        let blk_e = self.expr(blk.span, ast::expr_block(blk.clone()));
+        quote_expr!(*self, || $blk_e )
+    }
 
+    #[cfg(stage0)]
     fn lambda1(&self, _span: span, blk: ast::Block, ident: ast::ident) -> @ast::expr {
         let ext_cx = *self;
         let blk_e = self.expr(blk.span, ast::expr_block(blk.clone()));
         quote_expr!(|$ident| $blk_e )
     }
+    #[cfg(not(stage0))]
+    fn lambda1(&self, _span: span, blk: ast::Block, ident: ast::ident) -> @ast::expr {
+        let blk_e = self.expr(blk.span, ast::expr_block(blk.clone()));
+        quote_expr!(*self, |$ident| $blk_e )
+    }
 
     fn lambda_expr(&self, span: span, ids: ~[ast::ident], expr: @ast::expr) -> @ast::expr {
         self.lambda(span, ids, self.block_expr(expr))
index cb2d4f8ba2432b5ae0ec588087ebd84fcbd1af2f..d906f8f45185847e0bdb525848c980dec174d1aa 100644 (file)
@@ -22,6 +22,7 @@
 
 use std::os;
 
+#[cfg(stage0)]
 pub fn expand_option_env(ext_cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
     -> base::MacResult {
     let var = get_single_str_from_tts(ext_cx, sp, tts, "option_env!");
@@ -32,25 +33,36 @@ pub fn expand_option_env(ext_cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
     };
     MRExpr(e)
 }
+#[cfg(not(stage0))]
+pub fn expand_option_env(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
+    -> base::MacResult {
+    let var = get_single_str_from_tts(cx, sp, tts, "option_env!");
+
+    let e = match os::getenv(var) {
+      None => quote_expr!(cx, ::std::option::None::<&'static str>),
+      Some(s) => quote_expr!(cx, ::std::option::Some($s))
+    };
+    MRExpr(e)
+}
 
-pub fn expand_env(ext_cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
+pub fn expand_env(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
     -> base::MacResult {
-    let exprs = get_exprs_from_tts(ext_cx, sp, tts);
+    let exprs = get_exprs_from_tts(cx, sp, tts);
 
     if exprs.len() == 0 {
-        ext_cx.span_fatal(sp, "env! takes 1 or 2 arguments");
+        cx.span_fatal(sp, "env! takes 1 or 2 arguments");
     }
 
-    let var = expr_to_str(ext_cx, exprs[0], "expected string literal");
+    let var = expr_to_str(cx, exprs[0], "expected string literal");
     let msg = match exprs.len() {
         1 => fmt!("Environment variable %s not defined", var).to_managed(),
-        2 => expr_to_str(ext_cx, exprs[1], "expected string literal"),
-        _ => ext_cx.span_fatal(sp, "env! takes 1 or 2 arguments")
+        2 => expr_to_str(cx, exprs[1], "expected string literal"),
+        _ => cx.span_fatal(sp, "env! takes 1 or 2 arguments")
     };
 
     let e = match os::getenv(var) {
-        None => ext_cx.span_fatal(sp, msg),
-        Some(s) => ext_cx.expr_str(sp, s.to_managed())
+        None => cx.span_fatal(sp, msg),
+        Some(s) => cx.expr_str(sp, s.to_managed())
     };
     MRExpr(e)
 }
index c188326a4f1b016641d6824734a6e269996d9731..4bea1dc23e737a0d4ae660130ec9358030ddcb9b 100644 (file)
@@ -957,6 +957,96 @@ macro_rules! printfln (
             println(fmt!($($arg),+))
         )
     )
+
+    // NOTE: use this after a snapshot lands to abstract the details
+    // of the TLS interface.
+    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;
+        )
+    )
+
+    // externfn! declares a wrapper for an external function.
+    // It is intended to be used like:
+    //
+    // externfn!(#[nolink]
+    //           #[abi = \"cdecl\"]
+    //           fn memcmp(cx: *u8, ct: *u8, n: u32) -> u32)
+    //
+    // Due to limitations in the macro parser, this pattern must be
+    // implemented with 4 distinct patterns (with attrs / without
+    // attrs CROSS with args / without ARGS).
+    //
+    // Also, this macro grammar allows for any number of return types
+    // because I couldn't figure out the syntax to specify at most one.
+    macro_rules! externfn(
+        (fn $name:ident () $(-> $ret_ty:ty),*) => (
+            pub unsafe fn $name() $(-> $ret_ty),* {
+                // Note: to avoid obscure bug in macros, keep these
+                // attributes *internal* to the fn
+                #[fixed_stack_segment];
+                #[inline(never)];
+                #[allow(missing_doc)];
+
+                return $name();
+
+                extern {
+                    fn $name() $(-> $ret_ty),*;
+                }
+            }
+        );
+        (fn $name:ident ($($arg_name:ident : $arg_ty:ty),*) $(-> $ret_ty:ty),*) => (
+            pub unsafe fn $name($($arg_name : $arg_ty),*) $(-> $ret_ty),* {
+                // Note: to avoid obscure bug in macros, keep these
+                // attributes *internal* to the fn
+                #[fixed_stack_segment];
+                #[inline(never)];
+                #[allow(missing_doc)];
+
+                return $name($($arg_name),*);
+
+                extern {
+                    fn $name($($arg_name : $arg_ty),*) $(-> $ret_ty),*;
+                }
+            }
+        );
+        ($($attrs:attr)* fn $name:ident () $(-> $ret_ty:ty),*) => (
+            pub unsafe fn $name() $(-> $ret_ty),* {
+                // Note: to avoid obscure bug in macros, keep these
+                // attributes *internal* to the fn
+                #[fixed_stack_segment];
+                #[inline(never)];
+                #[allow(missing_doc)];
+
+                return $name();
+
+                $($attrs)*
+                extern {
+                    fn $name() $(-> $ret_ty),*;
+                }
+            }
+        );
+        ($($attrs:attr)* fn $name:ident ($($arg_name:ident : $arg_ty:ty),*) $(-> $ret_ty:ty),*) => (
+            pub unsafe fn $name($($arg_name : $arg_ty),*) $(-> $ret_ty),* {
+                // Note: to avoid obscure bug in macros, keep these
+                // attributes *internal* to the fn
+                #[fixed_stack_segment];
+                #[inline(never)];
+                #[allow(missing_doc)];
+
+                return $name($($arg_name),*);
+
+                $($attrs)*
+                extern {
+                    fn $name($($arg_name : $arg_ty),*) $(-> $ret_ty),*;
+                }
+            }
+        )
+    )
+
 }";
 }
 
index 6999f046b7b7aeeee3f4bd442e7e62f44439d6f8..35be77b95c5f9ae1b850218a627dc175d621098d 100644 (file)
@@ -623,19 +623,16 @@ fn to_expr(&self) -> @ast::expr {
 
     fn format_arg(&self, sp: span, arg: Either<uint, @str>,
                   ident: ast::ident) -> @ast::expr {
-        let mut ty = match arg {
+        let ty = match arg {
             Left(i) => self.arg_types[i].unwrap(),
             Right(s) => *self.name_types.get(&s)
         };
-        // Default types to '?' if nothing else is specified.
-        if ty == Unknown {
-            ty = Known(@"?");
-        }
 
         let argptr = self.ecx.expr_addr_of(sp, self.ecx.expr_ident(sp, ident));
-        match ty {
+        let fmt_trait = match ty {
+            Unknown => "Default",
             Known(tyname) => {
-                let fmt_trait = match tyname.as_slice() {
+                match tyname.as_slice() {
                     "?" => "Poly",
                     "b" => "Bool",
                     "c" => "Char",
@@ -653,35 +650,35 @@ fn format_arg(&self, sp: span, arg: Either<uint, @str>,
                                                     `%s`", tyname));
                         "Dummy"
                     }
-                };
-                let format_fn = self.ecx.path_global(sp, ~[
-                        self.ecx.ident_of("std"),
-                        self.ecx.ident_of("fmt"),
-                        self.ecx.ident_of(fmt_trait),
-                        self.ecx.ident_of("fmt"),
-                    ]);
-                self.ecx.expr_call_global(sp, ~[
-                        self.ecx.ident_of("std"),
-                        self.ecx.ident_of("fmt"),
-                        self.ecx.ident_of("argument"),
-                    ], ~[self.ecx.expr_path(format_fn), argptr])
+                }
             }
             String => {
-                self.ecx.expr_call_global(sp, ~[
+                return self.ecx.expr_call_global(sp, ~[
                         self.ecx.ident_of("std"),
                         self.ecx.ident_of("fmt"),
                         self.ecx.ident_of("argumentstr"),
                     ], ~[argptr])
             }
             Unsigned => {
-                self.ecx.expr_call_global(sp, ~[
+                return self.ecx.expr_call_global(sp, ~[
                         self.ecx.ident_of("std"),
                         self.ecx.ident_of("fmt"),
                         self.ecx.ident_of("argumentuint"),
                     ], ~[argptr])
             }
-            Unknown => { fail!() }
-        }
+        };
+
+        let format_fn = self.ecx.path_global(sp, ~[
+                self.ecx.ident_of("std"),
+                self.ecx.ident_of("fmt"),
+                self.ecx.ident_of(fmt_trait),
+                self.ecx.ident_of("fmt"),
+            ]);
+        self.ecx.expr_call_global(sp, ~[
+                self.ecx.ident_of("std"),
+                self.ecx.ident_of("fmt"),
+                self.ecx.ident_of("argument"),
+            ], ~[self.ecx.expr_path(format_fn), argptr])
     }
 }
 
index 9d82bb9c4f8abf07357e0987ca06e6a7394a227b..fcc5a8c93fa5959a92eab9c8334b732246f889b8 100644 (file)
@@ -196,119 +196,45 @@ fn to_source(&self) -> @str {
 
     // Alas ... we write these out instead. All redundant.
 
-    impl ToTokens for ast::ident {
-        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
-            cx.parse_tts(self.to_source())
-        }
-    }
-
-    impl ToTokens for @ast::item {
-        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
-            cx.parse_tts(self.to_source())
-        }
-    }
-
-    impl<'self> ToTokens for &'self [@ast::item] {
-        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
-            cx.parse_tts(self.to_source())
-        }
-    }
-
-    impl ToTokens for ast::Ty {
-        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
-            cx.parse_tts(self.to_source())
-        }
-    }
-
-    impl<'self> ToTokens for &'self [ast::Ty] {
-        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
-            cx.parse_tts(self.to_source())
-        }
-    }
-
-    impl ToTokens for Generics {
-        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
-            cx.parse_tts(self.to_source())
-        }
-    }
-
-    impl ToTokens for @ast::expr {
-        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
-            cx.parse_tts(self.to_source())
-        }
-    }
-
-    impl ToTokens for ast::Block {
-        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
-            cx.parse_tts(self.to_source())
-        }
-    }
-
-    impl<'self> ToTokens for &'self str {
-        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
-            cx.parse_tts(self.to_source())
-        }
-    }
-
-    impl ToTokens for int {
-        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
-            cx.parse_tts(self.to_source())
-        }
-    }
-
-    impl ToTokens for i8 {
-        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
-            cx.parse_tts(self.to_source())
-        }
-    }
-
-    impl ToTokens for i16 {
-        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
-            cx.parse_tts(self.to_source())
-        }
-    }
-
-    impl ToTokens for i32 {
-        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
-            cx.parse_tts(self.to_source())
-        }
-    }
-
-    impl ToTokens for i64 {
-        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
-            cx.parse_tts(self.to_source())
-        }
-    }
-
-    impl ToTokens for uint {
-        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
-            cx.parse_tts(self.to_source())
-        }
-    }
-
-    impl ToTokens for u8 {
-        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
-            cx.parse_tts(self.to_source())
-        }
-    }
-
-    impl ToTokens for u16 {
-        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
-            cx.parse_tts(self.to_source())
-        }
-    }
-
-    impl ToTokens for u32 {
-        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
-            cx.parse_tts(self.to_source())
-        }
-    }
-
-    impl ToTokens for u64 {
-        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
-            cx.parse_tts(self.to_source())
-        }
-    }
+    macro_rules! impl_to_tokens(
+        ($t:ty) => (
+            impl ToTokens for $t {
+                fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
+                    cx.parse_tts(self.to_source())
+                }
+            }
+        )
+    )
+
+    macro_rules! impl_to_tokens_self(
+        ($t:ty) => (
+            impl<'self> ToTokens for $t {
+                fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
+                    cx.parse_tts(self.to_source())
+                }
+            }
+        )
+    )
+
+    impl_to_tokens!(ast::ident)
+    impl_to_tokens!(@ast::item)
+    impl_to_tokens_self!(&'self [@ast::item])
+    impl_to_tokens!(ast::Ty)
+    impl_to_tokens_self!(&'self [ast::Ty])
+    impl_to_tokens!(Generics)
+    impl_to_tokens!(@ast::expr)
+    impl_to_tokens!(ast::Block)
+    impl_to_tokens_self!(&'self str)
+    impl_to_tokens!(int)
+    impl_to_tokens!(i8)
+    impl_to_tokens!(i16)
+    impl_to_tokens!(i32)
+    impl_to_tokens!(i64)
+    impl_to_tokens!(uint)
+    impl_to_tokens!(u8)
+    impl_to_tokens!(u16)
+    impl_to_tokens!(u32)
+    impl_to_tokens!(u64)
 
     pub trait ExtParseUtils {
         fn parse_item(&self, s: @str) -> @ast::item;
@@ -366,7 +292,8 @@ fn parse_tts(&self, s: @str) -> ~[ast::token_tree] {
 pub fn expand_quote_tokens(cx: @ExtCtxt,
                            sp: span,
                            tts: &[ast::token_tree]) -> base::MacResult {
-    base::MRExpr(expand_tts(cx, sp, tts))
+    let (cx_expr, expr) = expand_tts(cx, sp, tts);
+    base::MRExpr(expand_wrapper(cx, sp, cx_expr, expr))
 }
 
 pub fn expand_quote_expr(cx: @ExtCtxt,
@@ -640,7 +567,7 @@ fn mk_tts(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
 
 fn expand_tts(cx: @ExtCtxt,
               sp: span,
-              tts: &[ast::token_tree]) -> @ast::expr {
+              tts: &[ast::token_tree]) -> (@ast::expr, @ast::expr) {
 
     // NB: It appears that the main parser loses its mind if we consider
     // $foo as a tt_nonterminal during the main parse, so we have to re-parse
@@ -654,17 +581,14 @@ fn expand_tts(cx: @ExtCtxt,
         tts.to_owned()
     );
     *p.quote_depth += 1u;
-    let tts = p.parse_all_token_trees();
-    p.abort_if_errors();
 
-    // We want to emit a block expression that does a sequence of 'use's to
-    // import the runtime module, followed by a tt-building expression.
+    let cx_expr = p.parse_expr();
+    if !p.eat(&token::COMMA) {
+        p.fatal("Expected token `,`");
+    }
 
-    let uses = ~[ cx.view_use_glob(sp, ast::public,
-                                   ids_ext(~[~"syntax",
-                                             ~"ext",
-                                             ~"quote",
-                                             ~"rt"])) ];
+    let tts = p.parse_all_token_trees();
+    p.abort_if_errors();
 
     // We also bind a single value, sp, to ext_cx.call_site()
     //
@@ -683,9 +607,9 @@ fn expand_tts(cx: @ExtCtxt,
     // the site the string literal occurred, which was in a source file
     // _other_ than the one the user has control over. For example, an
     // error in a quote from the protocol compiler, invoked in user code
-    // using macro_rules! for example, will be attributed to the macro_rules.rs file in
-    // libsyntax, which the user might not even have source to (unless they
-    // happen to have a compiler on hand). Over all, the phase distinction
+    // using macro_rules! for example, will be attributed to the macro_rules.rs
+    // file in libsyntax, which the user might not even have source to (unless
+    // they happen to have a compiler on hand). Over all, the phase distinction
     // just makes quotes "hard to attribute". Possibly this could be fixed
     // by recreating some of the original qq machinery in the tt regime
     // (pushing fake FileMaps onto the parser to account for original sites
@@ -705,11 +629,28 @@ fn expand_tts(cx: @ExtCtxt,
                                   id_ext("tt"),
                                   cx.expr_vec_uniq(sp, ~[]));
 
-    cx.expr_block(
-        cx.block_all(sp, uses,
-                     ~[stmt_let_sp,
-                       stmt_let_tt] + mk_tts(cx, sp, tts),
-                     Some(cx.expr_ident(sp, id_ext("tt")))))
+    let block = cx.expr_block(
+        cx.block_all(sp,
+                     ~[],
+                     ~[stmt_let_sp, stmt_let_tt] + mk_tts(cx, sp, tts),
+                     Some(cx.expr_ident(sp, id_ext("tt")))));
+
+    (cx_expr, block)
+}
+
+fn expand_wrapper(cx: @ExtCtxt,
+                  sp: span,
+                  cx_expr: @ast::expr,
+                  expr: @ast::expr) -> @ast::expr {
+    let uses = ~[ cx.view_use_glob(sp, ast::public,
+                                   ids_ext(~[~"syntax",
+                                             ~"ext",
+                                             ~"quote",
+                                             ~"rt"])) ];
+
+    let stmt_let_ext_cx = cx.stmt_let(sp, false, id_ext("ext_cx"), cx_expr);
+
+    cx.expr_block(cx.block_all(sp, uses, ~[stmt_let_ext_cx], Some(expr)))
 }
 
 fn expand_parse_call(cx: @ExtCtxt,
@@ -717,7 +658,7 @@ fn expand_parse_call(cx: @ExtCtxt,
                      parse_method: &str,
                      arg_exprs: ~[@ast::expr],
                      tts: &[ast::token_tree]) -> @ast::expr {
-    let tts_expr = expand_tts(cx, sp, tts);
+    let (cx_expr, tts_expr) = expand_tts(cx, sp, tts);
 
     let cfg_call = || cx.expr_method_call(
         sp, cx.expr_ident(sp, id_ext("ext_cx")),
@@ -728,17 +669,12 @@ fn expand_parse_call(cx: @ExtCtxt,
         id_ext("parse_sess"), ~[]);
 
     let new_parser_call =
-        cx.expr_call_global(sp,
-                            ids_ext(~[~"syntax",
-                                      ~"ext",
-                                      ~"quote",
-                                      ~"rt",
-                                      ~"new_parser_from_tts"]),
-                            ~[parse_sess_call(),
-                              cfg_call(),
-                              tts_expr]);
-
-    cx.expr_method_call(sp, new_parser_call,
-                        id_ext(parse_method),
-                        arg_exprs)
+        cx.expr_call(sp,
+                     cx.expr_ident(sp, id_ext("new_parser_from_tts")),
+                     ~[parse_sess_call(), cfg_call(), tts_expr]);
+
+    let expr = cx.expr_method_call(sp, new_parser_call, id_ext(parse_method),
+                                   arg_exprs);
+
+    expand_wrapper(cx, sp, cx_expr, expr)
 }
index f2489d80e1e69fe83681f1ea2be16c8af8a450a8..78fc1f0babc41c64c86056aeeb0796d0cd73b351 100644 (file)
@@ -10,7 +10,6 @@
 
 use ast;
 use codemap::{spanned, mk_sp};
-use codemap::BytePos;
 use parse::common::*; //resolve bug?
 use parse::token;
 use parse::parser::Parser;
index d0041021f7cc77158a8e1fa130a1c8bf4a361e75..c7b247f2dd24c6aa90fca24c2c987397030610f9 100644 (file)
@@ -782,7 +782,9 @@ fn binop(rdr: @mut StringReader, op: token::binop) -> token::Token {
       c => {
           // So the error span points to the unrecognized character
           rdr.peek_span = codemap::mk_sp(rdr.last_pos, rdr.pos);
-          rdr.fatal(fmt!("unknown start of token: %d", c as int));
+          let mut cs = ~"";
+          char::escape_default(c, |c| cs.push_char(c));
+          rdr.fatal(fmt!("unknown start of token: %s", cs));
       }
     }
 }
index b38de31c56a7ff8117836a1bf5ea5f6a9001021e..de7abb8d1f46d290738cf7c16c9d1ada65f15006 100644 (file)
@@ -953,7 +953,7 @@ pub fn parse_trait_methods(&self) -> ~[trait_method] {
               _ => {
                     p.fatal(
                         fmt!(
-                            "expected `;` or `}` but found `%s`",
+                            "expected `;` or `{` but found `%s`",
                             self.this_token_to_str()
                         )
                     );
@@ -3445,7 +3445,7 @@ pub fn parse_fn_decl(&self) -> fn_decl {
                 |p| p.parse_arg()
             );
 
-        let inputs = either::lefts(args_or_capture_items);
+        let inputs = either::lefts(args_or_capture_items.move_iter()).collect();
 
         let (ret_style, ret_ty) = self.parse_ret_ty();
         ast::fn_decl {
@@ -3608,7 +3608,7 @@ fn maybe_parse_borrowed_explicit_self(this: &Parser) -> ast::explicit_self_ {
 
         let hi = self.span.hi;
 
-        let inputs = either::lefts(args_or_capture_items);
+        let inputs = either::lefts(args_or_capture_items.move_iter()).collect();
         let (ret_style, ret_ty) = self.parse_ret_ty();
 
         let fn_decl = ast::fn_decl {
@@ -3641,7 +3641,7 @@ fn parse_fn_block_decl(&self) -> fn_decl {
         };
 
         ast::fn_decl {
-            inputs: either::lefts(inputs_captures),
+            inputs: either::lefts(inputs_captures.move_iter()).collect(),
             output: output,
             cf: return_val,
         }
index bdfd25ae644da2a85af997adc3b9bb922cebcd09..0d7def84003e4d27ee13962544995c5f47ebb139 100644 (file)
@@ -477,6 +477,7 @@ fn mk_fresh_ident_interner() -> @ident_interner {
 
         "be",                 // 64
         "pure",               // 65
+        "yield",              // 66
     ];
 
     @ident_interner {
@@ -585,7 +586,6 @@ pub enum Keyword {
         Once,
         Priv,
         Pub,
-        Pure,
         Ref,
         Return,
         Static,
@@ -601,6 +601,8 @@ pub enum Keyword {
 
         // Reserved keywords
         Be,
+        Pure,
+        Yield,
     }
 
     impl Keyword {
@@ -628,7 +630,6 @@ pub fn to_ident(&self) -> ident {
                 Once => ident { name: 50, ctxt: 0 },
                 Priv => ident { name: 51, ctxt: 0 },
                 Pub => ident { name: 52, ctxt: 0 },
-                Pure => ident { name: 65, ctxt: 0 },
                 Ref => ident { name: 53, ctxt: 0 },
                 Return => ident { name: 54, ctxt: 0 },
                 Static => ident { name: 27, ctxt: 0 },
@@ -642,6 +643,8 @@ pub fn to_ident(&self) -> ident {
                 Use => ident { name: 61, ctxt: 0 },
                 While => ident { name: 62, ctxt: 0 },
                 Be => ident { name: 64, ctxt: 0 },
+                Pure => ident { name: 65, ctxt: 0 },
+                Yield => ident { name: 66, ctxt: 0 },
             }
         }
     }
@@ -657,7 +660,7 @@ pub fn is_keyword(kw: keywords::Keyword, tok: &Token) -> bool {
 pub fn is_any_keyword(tok: &Token) -> bool {
     match *tok {
         token::IDENT(sid, false) => match sid.name {
-            8 | 27 | 32 .. 65 => true,
+            8 | 27 | 32 .. 66 => true,
             _ => false,
         },
         _ => false
@@ -677,7 +680,7 @@ pub fn is_strict_keyword(tok: &Token) -> bool {
 pub fn is_reserved_keyword(tok: &Token) -> bool {
     match *tok {
         token::IDENT(sid, false) => match sid.name {
-            64 .. 65 => true,
+            64 .. 66 => true,
             _ => false,
         },
         _ => false,
index 0d3d6c019f89f025a0e5aee8747ec94d40daf272..064648a9671a171d39b04696f7934a539f35524e 100644 (file)
@@ -11,7 +11,6 @@
 #include "memory_region.h"
 #include "boxed_region.h"
 #include "rust_globals.h"
-#include "rust_env.h"
 #include "rust_util.h"
 
 // #define DUMP_BOXED_REGION
index ddd452deef2cb59bad8834c259772af61c3789ea..c95a4737d17c255e7a65827b1f2a8a79569f23c1 100644 (file)
@@ -571,7 +571,47 @@ rust_running_on_valgrind() {
     return RUNNING_ON_VALGRIND;
 }
 
-extern int get_num_cpus();
+#if defined(__WIN32__)
+int
+get_num_cpus() {
+    SYSTEM_INFO sysinfo;
+    GetSystemInfo(&sysinfo);
+
+    return (int) sysinfo.dwNumberOfProcessors;
+}
+#elif defined(__BSD__)
+int
+get_num_cpus() {
+    /* swiped from http://stackoverflow.com/questions/150355/
+       programmatically-find-the-number-of-cores-on-a-machine */
+
+    unsigned int numCPU;
+    int mib[4];
+    size_t len = sizeof(numCPU);
+
+    /* set the mib for hw.ncpu */
+    mib[0] = CTL_HW;
+    mib[1] = HW_AVAILCPU;  // alternatively, try HW_NCPU;
+
+    /* get the number of CPUs from the system */
+    sysctl(mib, 2, &numCPU, &len, NULL, 0);
+
+    if( numCPU < 1 ) {
+        mib[1] = HW_NCPU;
+        sysctl( mib, 2, &numCPU, &len, NULL, 0 );
+
+        if( numCPU < 1 ) {
+            numCPU = 1;
+        }
+    }
+    return numCPU;
+}
+#elif defined(__GNUC__)
+int
+get_num_cpus() {
+    return sysconf(_SC_NPROCESSORS_ONLN);
+}
+#endif
 
 extern "C" CDECL uintptr_t
 rust_get_num_cpus() {
@@ -629,6 +669,28 @@ rust_get_task() {
     return 0;
 }
 
+static lock_and_signal env_lock;
+
+extern "C" CDECL void
+rust_take_env_lock() {
+    env_lock.lock();
+}
+
+extern "C" CDECL void
+rust_drop_env_lock() {
+    env_lock.unlock();
+}
+
+extern "C" CDECL unsigned int
+rust_valgrind_stack_register(void *start, void *end) {
+  return VALGRIND_STACK_REGISTER(start, end);
+}
+
+extern "C" CDECL void
+rust_valgrind_stack_deregister(unsigned int id) {
+  VALGRIND_STACK_DEREGISTER(id);
+}
+
 //
 // Local Variables:
 // mode: C++
diff --git a/src/rt/rust_env.cpp b/src/rt/rust_env.cpp
deleted file mode 100644 (file)
index 1a29cae..0000000
+++ /dev/null
@@ -1,163 +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.
-
-// The runtime wants to pull a number of variables out of the
-// environment but calling getenv is not threadsafe, so every value
-// that might come from the environment is loaded here, once, during
-// init.
-
-#include "sync/lock_and_signal.h"
-#include "rust_env.h"
-
-// The environment variables that the runtime knows about
-#define RUST_THREADS "RUST_THREADS"
-#define RUST_MIN_STACK "RUST_MIN_STACK"
-#define RUST_MAX_STACK "RUST_MAX_STACK"
-#define RUST_LOG "RUST_LOG"
-#define DETAILED_LEAKS "DETAILED_LEAKS"
-#define RUST_SEED "RUST_SEED"
-#define RUST_POISON_ON_FREE "RUST_POISON_ON_FREE"
-#define RUST_DEBUG_MEM "RUST_DEBUG_MEM"
-#define RUST_DEBUG_BORROW "RUST_DEBUG_BORROW"
-
-#define DEFAULT_RUST_MIN_STACK_32 0x300
-#define DEFAULT_RUST_MIN_STACK_64 0x400000
-
-static lock_and_signal env_lock;
-
-extern "C" CDECL void
-rust_take_env_lock() {
-    env_lock.lock();
-}
-
-extern "C" CDECL void
-rust_drop_env_lock() {
-    env_lock.unlock();
-}
-
-#if defined(__WIN32__)
-int
-get_num_cpus() {
-    SYSTEM_INFO sysinfo;
-    GetSystemInfo(&sysinfo);
-
-    return (int) sysinfo.dwNumberOfProcessors;
-}
-#elif defined(__BSD__)
-int
-get_num_cpus() {
-    /* swiped from http://stackoverflow.com/questions/150355/
-       programmatically-find-the-number-of-cores-on-a-machine */
-
-    unsigned int numCPU;
-    int mib[4];
-    size_t len = sizeof(numCPU);
-
-    /* set the mib for hw.ncpu */
-    mib[0] = CTL_HW;
-    mib[1] = HW_AVAILCPU;  // alternatively, try HW_NCPU;
-
-    /* get the number of CPUs from the system */
-    sysctl(mib, 2, &numCPU, &len, NULL, 0);
-
-    if( numCPU < 1 ) {
-        mib[1] = HW_NCPU;
-        sysctl( mib, 2, &numCPU, &len, NULL, 0 );
-
-        if( numCPU < 1 ) {
-            numCPU = 1;
-        }
-    }
-    return numCPU;
-}
-#elif defined(__GNUC__)
-int
-get_num_cpus() {
-    return sysconf(_SC_NPROCESSORS_ONLN);
-}
-#endif
-
-static int
-get_num_threads()
-{
-    char *env = getenv(RUST_THREADS);
-    if(env) {
-        int num = atoi(env);
-        if(num > 0)
-            return num;
-    }
-    return get_num_cpus();
-}
-
-static size_t
-get_min_stk_size() {
-    char *minsz = getenv(RUST_MIN_STACK);
-    if(minsz) {
-        return strtol(minsz, NULL, 0);
-    }
-    else if (sizeof(size_t) > 4) {
-        return DEFAULT_RUST_MIN_STACK_64;
-    } else {
-        return DEFAULT_RUST_MIN_STACK_32;
-    }
-}
-
-static size_t
-get_max_stk_size() {
-    char *maxsz = getenv(RUST_MAX_STACK);
-    if (maxsz) {
-        return strtol(maxsz, NULL, 0);
-    }
-    else {
-        return 1024*1024*1024;
-    }
-}
-
-static char*
-copyenv(const char* name) {
-    char *envvar = getenv(name);
-    if (!envvar) {
-        return NULL;
-    } else {
-        size_t slen = strlen(envvar);
-        size_t buflen = slen + 1;
-        char *var = (char*)malloc(buflen);
-        memset(var, 0, buflen);
-        strncpy(var, envvar, slen);
-        return var;
-    }
-}
-
-rust_env*
-load_env(int argc, char **argv) {
-    scoped_lock with(env_lock);
-
-    rust_env *env = (rust_env*)malloc(sizeof(rust_env));
-
-    env->num_sched_threads = (size_t)get_num_threads();
-    env->min_stack_size = get_min_stk_size();
-    env->max_stack_size = get_max_stk_size();
-    env->logspec = copyenv(RUST_LOG);
-    env->detailed_leaks = getenv(DETAILED_LEAKS) != NULL;
-    env->rust_seed = copyenv(RUST_SEED);
-    env->poison_on_free = getenv(RUST_POISON_ON_FREE) != NULL;
-    env->argc = argc;
-    env->argv = argv;
-    env->debug_mem = getenv(RUST_DEBUG_MEM) != NULL;
-    env->debug_borrow = getenv(RUST_DEBUG_BORROW) != NULL;
-    return env;
-}
-
-void
-free_env(rust_env *env) {
-    free(env->logspec);
-    free(env->rust_seed);
-    free(env);
-}
diff --git a/src/rt/rust_env.h b/src/rt/rust_env.h
deleted file mode 100644 (file)
index b897f0c..0000000
+++ /dev/null
@@ -1,37 +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.
-
-
-#ifndef RUST_ENV_H
-#define RUST_ENV_H
-
-#include "rust_globals.h"
-
-// Avoiding 'bool' type here since I'm not sure it has a standard size
-typedef uint8_t rust_bool;
-
-struct rust_env {
-    size_t num_sched_threads;
-    size_t min_stack_size;
-    size_t max_stack_size;
-    char* logspec;
-    rust_bool detailed_leaks;
-    char* rust_seed;
-    rust_bool poison_on_free;
-    int argc;
-    char **argv;
-    rust_bool debug_mem;
-    rust_bool debug_borrow;
-};
-
-rust_env* load_env(int argc, char **argv);
-void free_env(rust_env *rust_env);
-
-#endif
index 5a75ab5ea1b0bd51721e914a490d622bc3746734..9dc790b43f2593b9871722c23b3b2050a7194c04 100644 (file)
@@ -81,15 +81,12 @@ extern "C" {
 #define CDECL __cdecl
 #endif
 #ifndef FASTCALL
-#define FASTCALL __fastcall
 #endif
 #else
 #define CDECL __attribute__((cdecl))
-#define FASTCALL __attribute__((fastcall))
 #endif
 #else
 #define CDECL
-#define FASTCALL
 #endif
 
 #define CHECKED(call)                                               \
@@ -104,22 +101,4 @@ extern "C" {
         }                                                           \
     }
 
-#define MUST_CHECK __attribute__((warn_unused_result))
-
-#define PTR "0x%" PRIxPTR
-
-// This accounts for logging buffers.
-static size_t const BUF_BYTES = 2048;
-
-#define INIT_TASK_ID 1
-
-// The error status to use when the process fails
-#define PROC_FAIL_CODE 101
-
-// A cond(ition) is something we can block on. This can be a channel
-// (writing), a port (reading) or a task (waiting).
-struct rust_cond { };
-
-extern void* global_crate_map;
-
 #endif /* RUST_GLOBALS_H */
index 25b246c69f51a10a0877d9d72f0e781308f42495..97c1135fe01d2aa732f134596ff2af4232a9ee59 100644 (file)
@@ -13,7 +13,6 @@
  */
 
 
-#include "rust_log.h"
 #include "rust_crate_map.h"
 #include "util/array_list.h"
 #include "rust_util.h"
@@ -25,13 +24,19 @@ struct log_directive {
     size_t level;
 };
 
+
+const uint32_t log_err = 1;
+const uint32_t log_warn = 2;
+const uint32_t log_info = 3;
+const uint32_t log_debug = 4;
+
 const size_t max_log_directives = 255;
 const size_t max_log_level = 255;
 const size_t default_log_level = log_err;
 
 // This is a rather ugly parser for strings in the form
 // "crate1,crate2.mod3,crate3.x=1". Log levels are 0-255,
-// with the most likely ones being 0-3 (defined in core::).
+// with the most likely ones being 0-3 (defined in std::).
 size_t parse_logging_spec(char* spec, log_directive* dirs) {
     size_t dir = 0;
     while (dir < max_log_directives && *spec) {
@@ -84,12 +89,6 @@ static void update_entry(const mod_entry* entry, void *cookie) {
     }
 }
 
-void update_module_map(const mod_entry* map, log_directive* dirs,
-                       size_t n_dirs, size_t *n_matches) {
-    update_entry_args args = { dirs, n_dirs, n_matches };
-    iter_module_map(map, update_entry, &args);
-}
-
 void update_crate_map(const cratemap* map, log_directive* dirs,
                       size_t n_dirs, size_t *n_matches) {
     update_entry_args args = { dirs, n_dirs, n_matches };
@@ -104,40 +103,6 @@ void print_crate_log_map(const cratemap* map) {
     iter_crate_map(map, print_mod_name, NULL);
 }
 
-// These are pseudo-modules used to control logging in the runtime.
-
-uint32_t log_rt_mem;
-uint32_t log_rt_box;
-uint32_t log_rt_comm;
-uint32_t log_rt_task;
-uint32_t log_rt_dom;
-uint32_t log_rt_trace;
-uint32_t log_rt_cache;
-uint32_t log_rt_upcall;
-uint32_t log_rt_timer;
-uint32_t log_rt_gc;
-uint32_t log_rt_stdlib;
-uint32_t log_rt_kern;
-uint32_t log_rt_backtrace;
-uint32_t log_rt_callback;
-
-static const mod_entry _rt_module_map[] =
-    {{"::rt::mem", &log_rt_mem},
-     {"::rt::box", &log_rt_box},
-     {"::rt::comm", &log_rt_comm},
-     {"::rt::task", &log_rt_task},
-     {"::rt::dom", &log_rt_dom},
-     {"::rt::trace", &log_rt_trace},
-     {"::rt::cache", &log_rt_cache},
-     {"::rt::upcall", &log_rt_upcall},
-     {"::rt::timer", &log_rt_timer},
-     {"::rt::gc", &log_rt_gc},
-     {"::rt::stdlib", &log_rt_stdlib},
-     {"::rt::kern", &log_rt_kern},
-     {"::rt::backtrace", &log_rt_backtrace},
-     {"::rt::callback", &log_rt_callback},
-     {NULL, NULL}};
-
 void update_log_settings(void* crate_map, char* settings) {
     char* buffer = NULL;
     log_directive dirs[256];
@@ -160,7 +125,6 @@ void update_log_settings(void* crate_map, char* settings) {
     }
 
     size_t n_matches = 0;
-    update_module_map(_rt_module_map, &dirs[0], n_dirs, &n_matches);
     update_crate_map((const cratemap*)crate_map, &dirs[0],
                      n_dirs, &n_matches);
 
diff --git a/src/rt/rust_log.h b/src/rt/rust_log.h
deleted file mode 100644 (file)
index e3d61b8..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.
-
-#ifndef RUST_LOG_H
-#define RUST_LOG_H
-
-#include "rust_globals.h"
-
-const uint32_t log_err = 1;
-const uint32_t log_warn = 2;
-const uint32_t log_info = 3;
-const uint32_t log_debug = 4;
-
-void update_log_settings(void* crate_map, char* settings);
-
-extern uint32_t log_rt_mem;
-extern uint32_t log_rt_box;
-extern uint32_t log_rt_comm;
-extern uint32_t log_rt_task;
-extern uint32_t log_rt_dom;
-extern uint32_t log_rt_trace;
-extern uint32_t log_rt_cache;
-extern uint32_t log_rt_upcall;
-extern uint32_t log_rt_timer;
-extern uint32_t log_rt_gc;
-extern uint32_t log_rt_stdlib;
-extern uint32_t log_rt_kern;
-extern uint32_t log_rt_backtrace;
-extern uint32_t log_rt_callback;
-
-#endif /* RUST_LOG_H */
diff --git a/src/rt/rust_refcount.h b/src/rt/rust_refcount.h
deleted file mode 100644 (file)
index 1ed05ec..0000000
+++ /dev/null
@@ -1,31 +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.
-
-
-#ifndef RUST_REFCOUNT_H
-#define RUST_REFCOUNT_H
-
-#include "sync/sync.h"
-
-// Refcounting defines
-typedef unsigned long ref_cnt_t;
-
-#define RUST_ATOMIC_REFCOUNT()                                             \
-private:                                                                   \
-   intptr_t ref_count;                                                     \
-public:                                                                    \
-   void ref() {                                                            \
-       intptr_t old = sync::increment(ref_count);                          \
-       assert(old > 0);                                                    \
-   }                                                                       \
-   void deref() { if(0 == sync::decrement(ref_count)) { delete_this(); } } \
-   intptr_t get_ref_count() { return sync::read(ref_count); }
-
-#endif
diff --git a/src/rt/rust_signal.h b/src/rt/rust_signal.h
deleted file mode 100644 (file)
index 4281092..0000000
+++ /dev/null
@@ -1,27 +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.
-
-#ifndef RUST_SIGNAL_H
-#define RUST_SIGNAL_H
-
-// Just an abstract class that represents something that can be signalled
-class rust_signal {
-public:
-    virtual void signal() = 0;
-    virtual ~rust_signal() {}
-    rust_signal() {}
-
-private:
-    // private and undefined to disable copying
-    rust_signal(const rust_signal& rhs);
-    rust_signal& operator=(const rust_signal& rhs);
-};
-
-#endif /* RUST_SIGNAL_H */
diff --git a/src/rt/rust_stack.cpp b/src/rt/rust_stack.cpp
deleted file mode 100644 (file)
index a609ac5..0000000
+++ /dev/null
@@ -1,105 +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.
-
-
-#include "rust_stack.h"
-#include "vg/valgrind.h"
-#include "vg/memcheck.h"
-
-#include <cstdio>
-
-#ifdef _LP64
-const uintptr_t canary_value = 0xABCDABCDABCDABCD;
-#else
-const uintptr_t canary_value = 0xABCDABCD;
-#endif
-
-void
-register_valgrind_stack(stk_seg *stk) {
-    stk->valgrind_id =
-        VALGRIND_STACK_REGISTER(&stk->data[0],
-                                stk->end);
-}
-
-void
-reuse_valgrind_stack(stk_seg *stk, uint8_t *sp) {
-    // Establish that the stack is accessible.  This must be done when reusing
-    // old stack segments, since the act of popping the stack previously
-    // caused valgrind to consider the whole thing inaccessible.
-    assert(sp >= stk->data && sp <= (uint8_t*) stk->end
-           && "Stack pointer must be inside stack segment");
-    size_t sz = stk->end - (uintptr_t)sp;
-    (void) VALGRIND_MAKE_MEM_UNDEFINED(sp, sz);
-    (void) sz;
-}
-
-void
-deregister_valgrind_stack(stk_seg *stk) {
-    VALGRIND_STACK_DEREGISTER(stk->valgrind_id);
-}
-
-void
-add_stack_canary(stk_seg *stk) {
-    stk->canary = canary_value;
-}
-
-void
-check_stack_canary(stk_seg *stk) {
-    assert(stk->canary == canary_value && "Somebody killed the canary");
-}
-
-// XXX: Duplication here between the local and exchange heap constructors
-
-stk_seg *
-create_stack(memory_region *region, size_t sz) {
-    size_t total_sz = sizeof(stk_seg) + sz;
-    stk_seg *stk = (stk_seg *)region->malloc(total_sz, "stack");
-    memset(stk, 0, sizeof(stk_seg));
-    stk->end = (uintptr_t) &stk->data[sz];
-    stk->is_big = 0;
-    add_stack_canary(stk);
-    register_valgrind_stack(stk);
-    return stk;
-}
-
-void
-destroy_stack(memory_region *region, stk_seg *stk) {
-    deregister_valgrind_stack(stk);
-    region->free(stk);
-}
-
-stk_seg *
-create_exchange_stack(rust_exchange_alloc *exchange, size_t sz) {
-    size_t total_sz = sizeof(stk_seg) + sz;
-    stk_seg *stk = (stk_seg *)exchange->malloc(total_sz);
-    memset(stk, 0, sizeof(stk_seg));
-    stk->end = (uintptr_t) &stk->data[sz];
-    stk->is_big = 0;
-    add_stack_canary(stk);
-    register_valgrind_stack(stk);
-    return stk;
-}
-
-void
-destroy_exchange_stack(rust_exchange_alloc *exchange, stk_seg *stk) {
-    deregister_valgrind_stack(stk);
-    exchange->free(stk);
-}
-
-
-extern "C" CDECL unsigned int
-rust_valgrind_stack_register(void *start, void *end) {
-  return VALGRIND_STACK_REGISTER(start, end);
-}
-
-extern "C" CDECL void
-rust_valgrind_stack_deregister(unsigned int id) {
-  VALGRIND_STACK_DEREGISTER(id);
-}
diff --git a/src/rt/rust_stack.h b/src/rt/rust_stack.h
deleted file mode 100644 (file)
index 3b34b91..0000000
+++ /dev/null
@@ -1,54 +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.
-
-#ifndef RUST_STACK_H
-#define RUST_STACK_H
-
-#include "rust_globals.h"
-#include "rust_exchange_alloc.h"
-#include "memory_region.h"
-
-struct rust_task;
-
-struct stk_seg {
-    stk_seg *prev;
-    stk_seg *next;
-    uintptr_t end;
-    unsigned int valgrind_id;
-    uint8_t is_big;
-
-    rust_task *task;
-    uintptr_t canary;
-
-    uint8_t data[];
-};
-
-stk_seg *
-create_stack(memory_region *region, size_t sz);
-
-void
-destroy_stack(memory_region *region, stk_seg *stk);
-
-stk_seg *
-create_exchange_stack(rust_exchange_alloc *exchange, size_t sz);
-
-void
-destroy_exchange_stack(rust_exchange_alloc *exchange, stk_seg *stk);
-
-// Must be called before each time a stack is reused to tell valgrind
-// that the stack is accessible.
-void
-reuse_valgrind_stack(stk_seg *stk, uint8_t *sp);
-
-// Run a sanity check
-void
-check_stack_canary(stk_seg *stk);
-
-#endif /* RUST_STACK_H */
index 57538f1ec75dbf03c8e99c54b1f0bf02eaffce93..0ac9bc6abff98a58d77004f73dc73ecc837d8b1c 100644 (file)
@@ -13,7 +13,6 @@
 #define RUST_TYPE_H
 
 #include "rust_globals.h"
-#include "rust_refcount.h"
 
 struct rust_opaque_box;
 
@@ -28,6 +27,8 @@ struct type_desc;
 typedef void CDECL (glue_fn)(void *,
                              void *);
 
+typedef unsigned long ref_cnt_t;
+
 // Corresponds to the boxed data in the @ region.  The body follows the
 // header; you can obtain a ptr via box_body() below.
 struct rust_opaque_box {
@@ -61,8 +62,6 @@ struct type_desc {
     size_t borrow_offset;
 };
 
-extern "C" type_desc *rust_clone_type_desc(type_desc*);
-
 #endif
 
 //
index f1b31e89df8ca0c219810832b1d75a155a402220..21c0d219242613d91a75518af7b2ae391404115c 100644 (file)
@@ -17,7 +17,6 @@
  */
 
 #include "rust_globals.h"
-#include "rust_upcall.h"
 #include "rust_util.h"
 
 //Unwinding ABI declarations.
diff --git a/src/rt/rust_upcall.h b/src/rt/rust_upcall.h
deleted file mode 100644 (file)
index 0cd7aa1..0000000
+++ /dev/null
@@ -1,14 +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.
-
-#ifndef RUST_UPCALL_H
-#define RUST_UPCALL_H
-
-#endif
index 30d4fcbdc49664e7090f96c09a6ec988361d2528..7c531297ccddc4fc8e23e6e73d641a5b7a0accbd 100644 (file)
@@ -14,7 +14,6 @@
 #include <limits.h>
 #include "rust_exchange_alloc.h"
 #include "rust_type.h"
-#include "rust_env.h"
 
 extern struct type_desc str_body_tydesc;
 
index f537e866dfcabf0baec19051b2553cc3054c715c..0462789af9ff90daac3fdf7622b9bd01df7d9876 100644 (file)
 
 #include "rust_globals.h"
 
-// extern fn pointers
-typedef void (*extern_async_op_cb)(uv_loop_t* loop, void* data,
-        uv_async_t* op_handle);
-typedef void (*extern_simple_cb)(uint8_t* id_buf, void* loop_data);
-typedef void (*extern_close_cb)(uint8_t* id_buf, void* handle,
-        void* data);
-
-// data types
-#define RUST_UV_HANDLE_LEN 16
-
-struct handle_data {
-    uint8_t id_buf[RUST_UV_HANDLE_LEN];
-    extern_simple_cb cb;
-    extern_close_cb close_cb;
-};
-
-static void
-foreign_timer_cb(uv_timer_t* handle, int status) {
-    handle_data* handle_d = (handle_data*)handle->data;
-    void* loop_data = handle->loop->data;
-    handle_d->cb(handle_d->id_buf, loop_data);
-}
-
-static void
-foreign_close_cb(uv_handle_t* handle) {
-    handle_data* data = (handle_data*)handle->data;
-    data->close_cb(data->id_buf, handle, handle->loop->data);
-}
 extern "C" void*
 rust_uv_loop_new() {
     return (void*)uv_loop_new();
@@ -91,13 +63,6 @@ rust_uv_walk(uv_loop_t* loop, uv_walk_cb cb, void* arg) {
     uv_walk(loop, cb, arg);
 }
 
-extern "C" void
-rust_uv_hilvl_close(uv_handle_t* handle, extern_close_cb cb) {
-    handle_data* data = (handle_data*)handle->data;
-    data->close_cb = cb;
-    uv_close(handle, foreign_close_cb);
-}
-
 extern "C" void
 rust_uv_async_send(uv_async_t* handle) {
     uv_async_send(handle);
@@ -110,12 +75,6 @@ rust_uv_async_init(uv_loop_t* loop_handle,
     return uv_async_init(loop_handle, async_handle, cb);
 }
 
-extern "C" void
-rust_uv_hilvl_timer_start(uv_timer_t* the_timer, uint32_t timeout,
-        uint32_t repeat) {
-    uv_timer_start(the_timer, foreign_timer_cb, timeout, repeat);
-}
-
 extern "C" int
 rust_uv_timer_init(uv_loop_t* loop, uv_timer_t* timer) {
     return uv_timer_init(loop, timer);
@@ -301,58 +260,6 @@ rust_uv_accept(uv_stream_t* server, uv_stream_t* client) {
     return uv_accept(server, client);
 }
 
-extern "C" size_t
-rust_uv_helper_uv_tcp_t_size() {
-    return sizeof(uv_tcp_t);
-}
-extern "C" size_t
-rust_uv_helper_uv_connect_t_size() {
-    return sizeof(uv_connect_t);
-}
-extern "C" size_t
-rust_uv_helper_uv_buf_t_size() {
-    return sizeof(uv_buf_t);
-}
-extern "C" size_t
-rust_uv_helper_uv_write_t_size() {
-    return sizeof(uv_write_t);
-}
-extern "C" size_t
-rust_uv_helper_uv_err_t_size() {
-    return sizeof(uv_err_t);
-}
-extern "C" size_t
-rust_uv_helper_sockaddr_in_size() {
-    return sizeof(sockaddr_in);
-}
-extern "C" size_t
-rust_uv_helper_sockaddr_in6_size() {
-    return sizeof(sockaddr_in6);
-}
-extern "C" size_t
-rust_uv_helper_uv_async_t_size() {
-    return sizeof(uv_async_t);
-}
-extern "C" size_t
-rust_uv_helper_uv_timer_t_size() {
-    return sizeof(uv_timer_t);
-}
-extern "C" size_t
-rust_uv_helper_addr_in_size() {
-    return sizeof(sockaddr_in6);
-}
-extern "C" size_t
-rust_uv_helper_uv_getaddrinfo_t_size() {
-    return sizeof(uv_getaddrinfo_t);
-}
-extern "C" size_t
-rust_uv_helper_addrinfo_size() {
-    return sizeof(addrinfo);
-}
-extern "C" unsigned int
-rust_uv_helper_get_INADDR_NONE() {
-    return INADDR_NONE;
-}
 extern "C" uv_stream_t*
 rust_uv_get_stream_handle_from_connect_req(uv_connect_t* connect) {
     return connect->handle;
index b5ce0400c1e940514766f3e4c4142a5b571254a9..ecf22d72b128e9e1af36f067b9f4078b5be4eb6e 100644 (file)
@@ -40,10 +40,8 @@ rust_uv_walk
 rust_uv_loop_set_data
 rust_uv_run
 rust_uv_close
-rust_uv_hilvl_close
 rust_uv_async_send
 rust_uv_async_init
-rust_uv_hilvl_timer_start
 rust_uv_timer_init
 rust_uv_timer_start
 rust_uv_timer_stop
@@ -92,19 +90,6 @@ rust_uv_is_ipv6_addrinfo
 rust_uv_get_next_addrinfo
 rust_uv_addrinfo_as_sockaddr_in
 rust_uv_addrinfo_as_sockaddr_in6
-rust_uv_helper_uv_tcp_t_size
-rust_uv_helper_uv_connect_t_size
-rust_uv_helper_uv_buf_t_size
-rust_uv_helper_uv_write_t_size
-rust_uv_helper_uv_err_t_size
-rust_uv_helper_sockaddr_in_size
-rust_uv_helper_sockaddr_in6_size
-rust_uv_helper_addr_in_size
-rust_uv_helper_addrinfo_size
-rust_uv_helper_uv_getaddrinfo_t_size
-rust_uv_helper_get_INADDR_NONE
-rust_uv_helper_uv_async_t_size
-rust_uv_helper_uv_timer_t_size
 rust_uv_get_stream_handle_from_connect_req
 rust_uv_get_stream_handle_from_write_req
 rust_uv_get_loop_for_uv_handle
index 7f2e61092ee0d0d974f555438bd047c64b3e5e80..61ea0d549b3f02b0800e176aff9cef2c3b47f045 100644 (file)
@@ -838,3 +838,21 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateUnionType(
 extern "C" void LLVMSetUnnamedAddr(LLVMValueRef Value, LLVMBool Unnamed) {
     unwrap<GlobalValue>(Value)->setUnnamedAddr(Unnamed);
 }
+
+extern "C" LLVMValueRef LLVMDIBuilderCreateTemplateTypeParameter(
+    DIBuilderRef Builder,
+    LLVMValueRef Scope,
+    const char* Name,
+    LLVMValueRef Ty,
+    LLVMValueRef File = 0,
+    unsigned LineNo = 0,
+    unsigned ColumnNo = 0)
+{
+    return wrap(Builder->createTemplateTypeParameter(
+      unwrapDI<DIDescriptor>(Scope),
+      Name,
+      unwrapDI<DIType>(Ty),
+      unwrapDI<MDNode*>(File),
+      LineNo,
+      ColumnNo));
+}
index a2af7a18b4f8aca7b715fd4a6be00b30d5620cdd..0b777abfb87159c968b299c4e722d755a4ca6241 100644 (file)
@@ -613,4 +613,5 @@ LLVMDIBuilderInsertDeclareBefore
 LLVMDIBuilderCreateEnumerator
 LLVMDIBuilderCreateEnumerationType
 LLVMDIBuilderCreateUnionType
+LLVMDIBuilderCreateTemplateTypeParameter
 LLVMSetUnnamedAddr
index 987434b424e9cea4a4bfa2b1e552d88114f06c6a..ad170d9173f71b6909fcecd0713a8b209cec546d 100644 (file)
@@ -1,3 +1,11 @@
+S 2013-08-14 e7b5729
+  freebsd-x86_64 9de0b5583a5c4413f9e77df7071498385e936dd2
+  linux-i386 29119a9072f74c639c2bad998edc40e582da540e
+  linux-x86_64 319fb73727da9a8e4dd6debe37e7647e40ed361b
+  macos-i386 f74a0f02efec35e327a9c819c5c8347579d1b7fe
+  macos-x86_64 f44aba76e9d7a9a28b8a6dd78f14576e7c84fbf3
+  winnt-i386 49dd1f264e17e6cd929c827ccbe23ee09058c7fc
+
 S 2013-08-12 ecfc9a8
   freebsd-x86_64 ae903580d6328b8517dc64b013c1b0740bfa4e83
   linux-i386 3076bf032ce980157a894a0a4446902ba8b1783d
index 61a3ca1559c277827db1d366b1113b07a1efcb8e..a9c3e1d2b0f866053ad2d0b05abf7b13e1a169c7 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::comm::*;
 use std::task;
 
 pub fn foo<T:Send + Clone>(x: T) -> Port<T> {
index 5b8bebda9248eba37bfa25ec2f750990aaf2c4e5..63a7392fc70b91c806cd9c2bb118711f09965f41 100644 (file)
@@ -9,8 +9,6 @@
 // except according to those terms.
 
 pub mod kitties {
-    use std::uint;
-
     pub struct cat {
         priv meows : uint,
         how_hungry : int,
@@ -26,5 +24,4 @@ pub fn cat(in_x : uint, in_y : int) -> cat {
             how_hungry: in_y
         }
     }
-
 }
index c1e23f1f5c848ddd67d4f98a57a22d4bbb151330..8fac4a3f322af16db2df251e6a93ba677bf52bb9 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::to_str::*;
-
 pub mod kitty {
     pub struct cat {
       priv meows : uint,
index ea42a51ff11d98534194d0bc6ded7f25c18e2d18..d8e3c2a9054a0e2719ac31a6ae212d21838d6dab 100644 (file)
@@ -20,7 +20,7 @@ pub trait add {
     }
 
     impl add for name_pool {
-        fn add(&self, s: ~str) {
+        fn add(&self, _s: ~str) {
         }
     }
 }
index c120a971c6b90fdbbff6638a0860b38ebbbbb172..f20a143b658ba6fa9936bada1485a614f5610940 100644 (file)
@@ -25,7 +25,7 @@ pub enum e {
 
 pub fn nominal() -> e { e_val }
 
-pub fn nominal_eq(e1: e, e2: e) -> bool { true }
+pub fn nominal_eq(_e1: e, _e2: e) -> bool { true }
 
 impl Eq for e {
     fn eq(&self, other: &e) -> bool { nominal_eq(*self, *other) }
index 230fdad04689179b4658de72423fae8dac6a121f..10adc3381596a749d0c87ba5e9221f8ef1412134 100644 (file)
@@ -29,6 +29,6 @@ fn ne(&self, other: &e) -> bool { nominal_neq(*self, *other) }
 
 pub fn nominal() -> e { e_val }
 
-pub fn nominal_neq(e1: e, e2: e) -> bool { false }
+pub fn nominal_neq(_e1: e, _e2: e) -> bool { false }
 
 pub fn f() -> int { 20 }
index 4ec63d52251ec23b1dea5ffe9bc95c8bec2ed893..03cb96a3729af21dc9295d761534fde3f81f583c 100644 (file)
@@ -24,6 +24,7 @@ pub fn rust_dbg_call(cb: *u8, data: libc::uintptr_t)
     }
 }
 
+#[fixed_stack_segment] #[inline(never)]
 pub fn fact(n: uint) -> uint {
     unsafe {
         info!("n = %?", n);
diff --git a/src/test/auxiliary/iss.rs b/src/test/auxiliary/iss.rs
new file mode 100644 (file)
index 0000000..a3ead83
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[link(name="iss6919_3", vers="0.1")];
+
+// part of issue-6919.rs
+
+struct C<'self> {
+    k: &'self fn(),
+}
+
+fn no_op() { }
+pub static D : C<'static> = C {
+    k: no_op
+};
+
index 8c491a4dfc83b1eb07ce73bf8d8755ecf57c340d..cbdd6b56b7da49564b4da1c1f3680e2ccaa44570 100644 (file)
@@ -35,9 +35,7 @@ fn arc<T:Freeze>(_data: T) -> arc_destruct<T> {
 }
 
 fn init() -> arc_destruct<context_res> {
-    unsafe {
-        arc(context_res())
-    }
+    arc(context_res())
 }
 
 struct context_res {
index eed271c5499fe55ca98c90965fc40d8a6be35369..88439e32b0dda6f2179594ad8a9942cc949be540 100644 (file)
@@ -14,7 +14,7 @@
 enum maybe<T> { just(T), nothing }
 
 impl <T:Clone> Index<uint,T> for maybe<T> {
-    fn index(&self, idx: &uint) -> T {
+    fn index(&self, _idx: &uint) -> T {
         match self {
             &just(ref t) => (*t).clone(),
             &nothing => { fail!(); }
index 32283e5373ca6e82928881e9b1a5064a59672e1e..1c16e347b27be67e6a69fbae86527093f5648fa4 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(unused_imports)];
+
 extern mod issue_2316_a;
 
 pub mod cloth {
diff --git a/src/test/auxiliary/issue_3907.rs b/src/test/auxiliary/issue_3907.rs
new file mode 100644 (file)
index 0000000..2e254e5
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub trait Foo {
+    fn bar();
+}
+
diff --git a/src/test/auxiliary/issue_8401.rs b/src/test/auxiliary/issue_8401.rs
new file mode 100644 (file)
index 0000000..9e4d90e
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// for this issue, this code must be built in a library
+
+use std::cast;
+
+trait A {}
+struct B;
+impl A for B {}
+
+fn bar<T>(_: &mut A, _: &T) {}
+
+fn foo<T>(t: &T) {
+    let b = B;
+    bar(unsafe { cast::transmute(&b as &A) }, t)
+}
+
index cd72468511ea17418e8ba47d6ba623f079e39d3b..f45b80715953ef847c24208f00c2873c5f673c16 100644 (file)
@@ -23,5 +23,5 @@ fn drop(&self) {
 pub fn f() {
     let x = S { x: 1 };
     let y = x;
-    let z = y;
+    let _z = y;
 }
index 4d910385cd6833aedbc17bd28c212bca904831af..105d7f758f787a27f47a59f28493be304e46a863 100644 (file)
@@ -19,7 +19,7 @@ fn f(&self) -> int { 10 }
 
 trait B<T> {
     fn thing<U>(&self, x: T, y: U) -> (T, U) { (x, y) }
-    fn staticthing<U>(z: &Self, x: T, y: U) -> (T, U) { (x, y) }
+    fn staticthing<U>(_z: &Self, x: T, y: U) -> (T, U) { (x, y) }
 }
 
 impl<T> B<T> for int { }
index a0ceb654b526908b1a386fc3c72eb94e9cf5874a..6735d623e6cdf95bb376fddc4e94529165502263 100644 (file)
 extern mod extra;
 
 use extra::time::precise_time_s;
-use std::int;
 use std::io;
 use std::os;
 use std::rand::RngUtil;
 use std::rand;
-use std::result;
 use std::str;
-use std::uint;
 use std::util;
 use std::vec;
 
index 7de95f4d822c54613a3f72064c3efb9b0778d02e..a5311d5c831342dcc45454a4dc2ab9d8ad65df09 100644 (file)
@@ -21,7 +21,6 @@
 use extra::future;
 use extra::time;
 use std::cell::Cell;
-use std::io;
 use std::os;
 use std::uint;
 
index 1299e863db6b3f923274740bc443b65f5b802862..e25490bcd9ba88681b2224476ce5ef069408cdce 100644 (file)
@@ -21,7 +21,6 @@
 use extra::future;
 use extra::time;
 use std::cell::Cell;
-use std::io;
 use std::os;
 use std::uint;
 
index 8503b188b2f25a27dd7d21bc6d01e5d991373abd..e5fac5124990836f3b28d3b52257e4a61d6b13cb 100644 (file)
@@ -1,7 +1,6 @@
 // Perlin noise benchmark from https://gist.github.com/1170424
 
 use std::float;
-use std::int;
 use std::rand::{Rng, RngUtil};
 use std::rand;
 
index 3d38d61bc2eb6b6337705efd6396f6c8b4f31cfc..6c482c6d207291941d899d3a83100ce7384a2d80 100644 (file)
@@ -10,7 +10,6 @@
 
 extern mod extra;
 
-use std::task::spawn;
 use std::os;
 use std::uint;
 use std::rt::test::spawntask_later;
index 6669342f511a83944454c67cf5c942dcb9a4d970..32f0a592273f5ef93d467209f6a8eeb1b4017ebd 100644 (file)
@@ -10,7 +10,6 @@
 
 extern mod extra;
 
-use std::task::spawn;
 use std::os;
 use std::uint;
 use std::rt::test::spawntask_later;
index e8659ba26d4bc878bd686b5f873ba7365bfe4bc8..3ecb580874c4b33fed23afaac34dc8838c3d5863 100644 (file)
@@ -11,7 +11,6 @@
 extern mod extra;
 
 use std::int;
-use std::io;
 use std::os;
 
 fn ack(m: int, n: int) -> int {
index 4e2ab8b0a498dce2b444fad63f81717b4015dd48..9d47e7fed237bdd290b8262629231532973db718 100644 (file)
@@ -22,9 +22,7 @@
 use std::os;
 use std::rand::Rng;
 use std::rand;
-use std::result;
 use std::str;
-use std::uint;
 
 static LINE_LENGTH: uint = 60u;
 
index 9c07df36eb3c1be3bf84a94a2f34dc11dd416bd4..a367beface2173dd485e774bdb85633daa6271c4 100644 (file)
@@ -11,7 +11,6 @@
 extern mod extra;
 
 use std::int;
-use std::io;
 use std::os;
 
 fn fib(n: int) -> int {
index 66b9bdc0a42c9626924c5603c6b39c695a667b12..0a036696544e80fa86641b7cd428d3b916c20170 100644 (file)
@@ -22,7 +22,6 @@
 use std::io;
 use std::option;
 use std::os;
-use std::result;
 use std::str;
 use std::task;
 use std::util;
index 675735408953403b49d6fd622a2cd906c0cd7eaa..17fe1135fd985596c08296ab99c82967c8ba0406 100644 (file)
@@ -15,7 +15,6 @@
 use std::io::{ReaderUtil, WriterUtil};
 use std::io;
 use std::os;
-use std::u8;
 use std::uint;
 use std::unstable::intrinsics::cttz16;
 use std::vec;
index be7f9b5f43adfc22b75ad98e0e513408d9e3fb6e..0020a006e68d854a431f3a7767e2e8b6ba0a50d3 100644 (file)
@@ -31,7 +31,7 @@ fn child_generation(gens_left: uint, c: comm::Chan<()>) {
     do task::spawn_supervised {
         let c = c.take();
         if gens_left & 1 == 1 {
-            task::yield(); // shake things up a bit
+            task::deschedule(); // shake things up a bit
         }
         if gens_left > 0 {
             child_generation(gens_left - 1, c); // recurse
index e3631b73c022c4939c567fd9eaeea1e858351633..ca30fc2bd7b86cbf409e7821ca7349265060c789 100644 (file)
@@ -14,5 +14,5 @@ fn foo(x: int) -> int {
 
 #[no_mangle]
 fn test() {
-    let x = foo(10);
+    let _x = foo(10);
 }
index 576b1c452a5ecccb05d4e408203639022967512c..4f60391892da37439f1fe84fc20ddd15c086e6ed 100644 (file)
@@ -12,7 +12,7 @@
 
 use std::local_data;
 
-static key: local_data::Key<@&int> = &local_data::Key;
+local_data_key!(key: @&int)
 //~^ ERROR only 'static is allowed
 
 fn main() {}
diff --git a/src/test/compile-fail/issue-2817.rs b/src/test/compile-fail/issue-2817.rs
deleted file mode 100644 (file)
index 384b2cc..0000000
+++ /dev/null
@@ -1,27 +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::uint;
-
-fn uuid() -> uint { fail!(); }
-
-fn from_str(s: ~str) -> uint { fail!(); }
-fn to_str(u: uint) -> ~str { fail!(); }
-fn uuid_random() -> uint { fail!(); }
-
-fn main() {
-    do range(0u, 100000).advance |_i| { //~ ERROR Do-block body must return bool, but
-    };
-    // should get a more general message if the callback
-    // doesn't return nil
-    do range(0u, 100000).advance |_i| { //~ ERROR mismatched types
-        ~"str"
-    };
-}
diff --git a/src/test/compile-fail/issue-3651-2.rs b/src/test/compile-fail/issue-3651-2.rs
deleted file mode 100644 (file)
index bcd8e86..0000000
+++ /dev/null
@@ -1,14 +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() {
-    fn take_block(f: &fn() -> bool) -> bool { f() }
-    do take_block {}; //~ ERROR Do-block body must return bool, but returns () here. Perhaps
-}
diff --git a/src/test/compile-fail/issue-3907.rs b/src/test/compile-fail/issue-3907.rs
new file mode 100644 (file)
index 0000000..df18a5a
--- /dev/null
@@ -0,0 +1,30 @@
+// 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.
+
+// aux-build:issue_3907.rs
+extern mod issue_3907;
+
+type Foo = issue_3907::Foo; //~ ERROR: reference to trait
+
+struct S {
+    name: int
+}
+
+impl Foo for S { //~ ERROR: Foo is not a trait
+    fn bar() { }
+}
+
+fn main() {
+    let s = S {
+        name: 0
+    };
+    s.bar();
+}
+
diff --git a/src/test/compile-fail/issue-5439.rs b/src/test/compile-fail/issue-5439.rs
new file mode 100644 (file)
index 0000000..8bd9bb3
--- /dev/null
@@ -0,0 +1,29 @@
+// 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 Foo {
+    foo: int,
+}
+
+struct Bar {
+    bar: int,
+}
+
+impl Bar {
+    fn make_foo (&self, i: int) -> ~Foo {
+        return ~Foo { nonexistent: self, foo: i }; //~ ERROR: no field named
+    }
+}
+
+fn main () {
+    let bar = Bar { bar: 1 };
+    let foo = bar.make_foo(2);
+    println(fmt!("%d", foo.foo));
+}
index cad47eff01321553146ea9e594920f7cfd7e47c0..c2b15c2fd1bd4d7b9fb11960a2b15eb95581f640 100644 (file)
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 // xfail-test
-use core::io::ReaderUtil;
-use core::io::Reader;
+use std::io::ReaderUtil;
+use std::io::Reader;
 
 fn bar(r:@ReaderUtil) -> ~str { r.read_line() }
 
diff --git a/src/test/compile-fail/issue-6610.rs b/src/test/compile-fail/issue-6610.rs
new file mode 100644 (file)
index 0000000..f90833a
--- /dev/null
@@ -0,0 +1,13 @@
+// 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.
+
+trait Foo { fn a() } //~ ERROR expected `;` or `{` but found `}`
+
+fn main() {}
index 7c9fe73c974e2aa05db1a607d3d1c4a7a501908e..6f0c2f1de1ab45b1bb7f4cf7992a2e1e329d2cb3 100644 (file)
@@ -10,6 +10,7 @@
 
 // Exercise the unused_unsafe attribute in some positive and negative cases
 
+#[allow(cstack)];
 #[deny(unused_unsafe)];
 
 mod foo {
@@ -55,6 +56,7 @@ unsafe fn what() -> ~[~str] { fail!() }
         }
     }
 }
+
 unsafe fn good3() { foo::bar() }
 fn good4() { unsafe { foo::bar() } }
 
diff --git a/src/test/compile-fail/macro-local-data-key-priv.rs b/src/test/compile-fail/macro-local-data-key-priv.rs
new file mode 100644 (file)
index 0000000..a64c5c0
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::local_data;
+
+// check that the local data keys are private by default.
+
+mod bar {
+    local_data_key!(baz: float)
+}
+
+fn main() {
+    local_data::set(bar::baz, -10.0);
+    //~^ ERROR unresolved name `bar::baz`
+}
index 83f0dc71aa0f7cd3ae932ece171eec8db1e6ca33..0112c0adea298ddd9c263cb4207e66b999cb61ee 100644 (file)
@@ -53,12 +53,12 @@ fn mk_ctxt() -> fake_ext_ctxt {
 
 
 fn main() {
-    let ext_cx = mk_ctxt();
+    let cx = mk_ctxt();
 
-    let abc = quote_expr!(23);
+    let abc = quote_expr!(cx, 23);
     check_pp(abc,  pprust::print_expr, "23");
 
-    let expr3 = quote_expr!(2 - $abcd + 7); //~ ERROR unresolved name: abcd
+    let expr3 = quote_expr!(cx, 2 - $abcd + 7); //~ ERROR unresolved name: abcd
     check_pp(expr3,  pprust::print_expr, "2 - 23 + 7");
 }
 
index c9981f7b0319d530d85517ed8d40851d30cef899..57355885e2f46d1db79b46d746224300554a003a 100644 (file)
@@ -51,9 +51,9 @@ fn mk_ctxt() -> fake_ext_ctxt {
 
 
 fn main() {
-    let ext_cx = mk_ctxt();
+    let cx = mk_ctxt();
 
-    let stmt = quote_stmt!(let x int = 20;); //~ ERROR expected end-of-string
+    let stmt = quote_stmt!(cx, let x int = 20;); //~ ERROR expected end-of-string
     check_pp(*stmt,  pprust::print_stmt, "");
 }
 
diff --git a/src/test/compile-fail/static-vec-repeat-not-constant.rs b/src/test/compile-fail/static-vec-repeat-not-constant.rs
new file mode 100644 (file)
index 0000000..7721e18
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn foo() -> int { 23 }
+
+static a: [int, ..2] = [foo(), ..2]; //~ ERROR: function calls in constants are limited to struct and enum constructors
+
+fn main() {}
index 7b5e05a5671ab505d4b47f245c684f6f2fe6c8aa..be6871ae6ffa7657e2a96dd5d32d4302608b0480 100644 (file)
@@ -8,15 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//error-pattern:libc::c_int or libc::c_long should be used
+#[forbid(ctypes)];
+
 mod xx {
     extern {
-        pub fn strlen(str: *u8) -> uint;
-        pub fn foo(x: int, y: uint);
+        pub fn strlen(str: *u8) -> uint; //~ ERROR found rust type `uint`
+        pub fn foo(x: int, y: uint); //~ ERROR found rust type `int`
+        //~^ ERROR found rust type `uint`
     }
 }
 
 fn main() {
-  // let it fail to verify warning message
-  fail!()
 }
index 7125ebe8d564ca2001aa73aceed70383ac67dcaf..4e8f7d0d4aaa655b7aac2c5e5637956dd5e285f5 100644 (file)
@@ -51,6 +51,8 @@
 // debugger:print f64
 // check:$15 = 3.5
 
+#[allow(unused_variable)];
+
 fn main() {
     let b: bool = false;
     let i: int = -1;
index 7610301f6f0358baf940d2617d8a8e3f3c03d24b..9de460163f091c8a2333c71b19d4d610d675fa74 100644 (file)
@@ -62,6 +62,8 @@
 // debugger:print *f64_ref
 // check:$15 = 3.5
 
+#[allow(unused_variable)];
+
 fn main() {
     let bool_val: bool = true;
     let bool_ref: &bool = &bool_val;
@@ -110,4 +112,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index 70c85258c7921518cafd1d5dbc084472b004d15e..3b398201726c3b10e5f618ea4241dd6452f4cd28 100644 (file)
@@ -24,6 +24,8 @@
 // debugger:print *the_c_ref
 // check:$3 = TheC
 
+#[allow(unused_variable)];
+
 enum ABC { TheA, TheB, TheC }
 
 fn main() {
@@ -39,4 +41,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index 38aa9c38810006fd5caf7b9c9d64499c917cb596..2052ce3c93256e50a35c6dd6d32a07e425f9f9aa 100644 (file)
@@ -24,6 +24,8 @@
 // debugger:print *univariant_ref
 // check:$3 = {4820353753753434}
 
+#[allow(unused_variable)];
+
 // The first element is to ensure proper alignment, irrespective of the machines word size. Since
 // the size of the discriminant value is machine dependent, this has be taken into account when
 // datatype layout should be predictable as in this case.
@@ -59,4 +61,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index 9087bb36fa5d66d9171753bc0c8fbfc6a53403e4..bf0edef83a0aadd3e7362e147cf730427719de8b 100644 (file)
@@ -62,6 +62,7 @@
 // debugger:print *f64_ref
 // check:$15 = 3.5
 
+#[allow(unused_variable)];
 
 fn main() {
     let bool_box: @bool = @true;
@@ -111,4 +112,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index 8b6eca3e37f79d2338c7c66d15a274b304879424..77f8bd21fb3d40ad36c5aeaf42cb821ab7f4a751 100644 (file)
@@ -45,7 +45,7 @@
 // debugger:print *unique_val_interior_ref_2
 // check:$10 = 26.5
 
-
+#[allow(unused_variable)];
 
 struct SomeStruct {
     x: int,
@@ -72,4 +72,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index da199941c841975a8937fb8ef02afa485e6fb797..8810c493aed07e5fe771c4c9f270b839c831b102 100644 (file)
@@ -27,6 +27,8 @@
 // debugger:print *unique_val_ref
 // check:$4 = {-17, -22}
 
+#[allow(unused_variable)];
+
 fn main() {
     let stack_val: (i16, f32) = (-14, -19f32);
     let stack_val_ref: &(i16, f32) = &stack_val;
@@ -41,4 +43,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index 52f5a2cba1ebe721feeccffb3f23384b939408de..c62b05d13583a9cfa4c62bafa33f6676f8b908c3 100644 (file)
@@ -62,6 +62,8 @@
 // debugger:print *f64_ref
 // check:$15 = 3.5
 
+#[allow(unused_variable)];
+
 
 fn main() {
     let bool_box: ~bool = ~true;
@@ -111,4 +113,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index c63cffd7b74bb7311743f212380ea52b14e3d92b..cc41267e5c20255b02fd9be0a9e1920ca1b57345 100644 (file)
@@ -24,6 +24,8 @@
 // debugger:print d->val
 // check:$4 = false
 
+#[allow(unused_variable)];
+
 fn main() {
     let a = ~1;
     let b = ~(2, 3.5);
index 86162f0fa04cd4abbf92d09fe68d73363b49d26b..0e22980025be8d948d56b7a3a67669efa0810de2 100644 (file)
@@ -27,6 +27,8 @@
 // debugger:print managed_dtor->val
 // check:$4 = {x = 33, y = 333, z = 3333, w = 33333}
 
+#[allow(unused_variable)];
+
 struct StructWithSomePadding {
     x: i16,
     y: i32,
@@ -56,4 +58,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index 8abead6519697305a8148c9d938108235e205ff3..84b1ad44ebc1a174d02cfbe4b31868fb4a2d76a3 100644 (file)
@@ -25,6 +25,8 @@
 // debugger:print *((uint64_t[4]*)(unique->elements))
 // check:$4 = {10, 11, 12, 13}
 
+#[allow(unused_variable)];
+
 fn main() {
 
     let managed: @[i64] = @[7, 8, 9];
@@ -33,4 +35,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
diff --git a/src/test/debug-info/by-value-struct-argument.rs b/src/test/debug-info/by-value-struct-argument.rs
new file mode 100644 (file)
index 0000000..052b3c6
--- /dev/null
@@ -0,0 +1,37 @@
+// 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.
+
+// Does not work yet, see issue #8512
+// xfail-test
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// debugger:finish
+// debugger:print s
+// check:$1 = {a = 1, b = 2.5}
+// debugger:continue
+
+#[deriving(Clone)]
+struct Struct {
+    a: int,
+    b: float
+}
+
+fn fun(s: Struct) {
+    zzz();
+}
+
+fn main() {
+    fun(Struct { a: 1, b: 2.5 });
+}
+
+fn zzz() {()}
index 47e433ea814abef3eec95fca5e2c9201e815714a..def0a8275c07f4948f41ee59381370c92803d793 100644 (file)
@@ -36,6 +36,8 @@
 // debugger:print struct_with_drop
 // check:$7 = {{a = OneHundred, b = Vienna}, 9}
 
+#[allow(unused_variable)];
+
 enum AnEnum {
     OneHundred = 100,
     OneThousand = 1000,
@@ -116,4 +118,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index d7cce4e6f3fb54585cc9a0add5ccb94546b82e58..1b57ab0d447e1d96c409ead80f55ec5c3f241e2d 100644 (file)
@@ -36,6 +36,8 @@
 // debugger:print single_variant
 // check:$7 = TheOnlyVariant
 
+#[allow(unused_variable)];
+
 enum AutoDiscriminant {
     One,
     Two,
@@ -67,4 +69,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
diff --git a/src/test/debug-info/closure-in-generic-function.rs b/src/test/debug-info/closure-in-generic-function.rs
new file mode 100644 (file)
index 0000000..b6cf6af
--- /dev/null
@@ -0,0 +1,46 @@
+// 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.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// debugger:finish
+// debugger:print x
+// check:$1 = 0.5
+// debugger:print y
+// check:$2 = 10
+// debugger:continue
+
+// debugger:finish
+// debugger:print *x
+// check:$3 = 29
+// debugger:print *y
+// check:$4 = 110
+// debugger:continue
+
+fn some_generic_fun<T1, T2>(a: T1, b: T2) -> (T2, T1) {
+
+    let closure = |x, y| {
+        zzz();
+        (y, x)
+    };
+
+    closure(a, b)
+}
+
+fn main() {
+    some_generic_fun(0.5, 10);
+    some_generic_fun(&29, ~110);
+}
+
+fn zzz() {()}
index 05718ab48909f3d7a1775158e4ba5f518eec1559..0269d3f4155746117721bdf8bf3881ee4d75b35b 100644 (file)
 // check:$49 = 62
 // debugger:continue
 
+#[allow(unused_variable)];
 
 struct Struct {
     a: i64,
@@ -315,4 +316,4 @@ fn nested_function(rr: int, (ss, tt): (int, int)) {
 }
 
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index f8db7981c941bce78ce7d5b9585196e8e3722a46..bc78b6cd35e947d401c9d3b88bff6b51fadc79e3 100644 (file)
 // debugger:print *nn
 // check:$43 = 56
 
+#[allow(unused_variable)];
 
 struct Struct {
     a: i64,
@@ -206,4 +207,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index 7e42690548e70cfaa6ec17b92c3ad32fec961848..1594de4f5c05d6d057c2c637a7672d643cf674c0 100644 (file)
@@ -30,6 +30,8 @@
 // debugger:print struct_padded_at_end
 // check:$5 = {x = {22, 23}, y = {24, 25}}
 
+#[allow(unused_variable)];
+
 struct NoPadding1 {
     x: [u32, ..3],
     y: i32,
@@ -85,4 +87,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
diff --git a/src/test/debug-info/generic-function.rs b/src/test/debug-info/generic-function.rs
new file mode 100644 (file)
index 0000000..c3b48f2
--- /dev/null
@@ -0,0 +1,63 @@
+// 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.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// debugger:finish
+// debugger:print *t0
+// check:$1 = 1
+// debugger:print *t1
+// check:$2 = 2.5
+// debugger:print ret
+// check:$3 = {{1, 2.5}, {2.5, 1}}
+// debugger:continue
+
+// debugger:finish
+// debugger:print *t0
+// check:$4 = 3.5
+// debugger:print *t1
+// check:$5 = 4
+// debugger:print ret
+// check:$6 = {{3.5, 4}, {4, 3.5}}
+// debugger:continue
+
+// debugger:finish
+// debugger:print *t0
+// check:$7 = 5
+// debugger:print *t1
+// check:$8 = {a = 6, b = 7.5}
+// debugger:print ret
+// check:$9 = {{5, {a = 6, b = 7.5}}, {{a = 6, b = 7.5}, 5}}
+// debugger:continue
+
+#[deriving(Clone)]
+struct Struct {
+    a: int,
+    b: float
+}
+
+fn dup_tup<T0: Clone, T1: Clone>(t0: &T0, t1: &T1) -> ((T0, T1), (T1, T0)) {
+    let ret = ((t0.clone(), t1.clone()), (t1.clone(), t0.clone()));
+    zzz();
+    ret
+}
+
+fn main() {
+
+    let _ = dup_tup(&1, &2.5);
+    let _ = dup_tup(&3.5, &4_u16);
+    let _ = dup_tup(&5, &Struct { a: 6, b: 7.5 });
+}
+
+fn zzz() {()}
diff --git a/src/test/debug-info/generic-functions-nested.rs b/src/test/debug-info/generic-functions-nested.rs
new file mode 100644 (file)
index 0000000..1d883b5
--- /dev/null
@@ -0,0 +1,59 @@
+// 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.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// debugger:finish
+// debugger:print x
+// check:$1 = -1
+// debugger:print y
+// check:$2 = 1
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$3 = -1
+// debugger:print y
+// check:$4 = 2.5
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$5 = -2.5
+// debugger:print y
+// check:$6 = 1
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$7 = -2.5
+// debugger:print y
+// check:$8 = 2.5
+// debugger:continue
+
+fn outer<TA: Clone>(a: TA) {
+    inner(a.clone(), 1);
+    inner(a.clone(), 2.5);
+
+    fn inner<TX, TY>(x: TX, y: TY) {
+        zzz();
+    }
+}
+
+fn main() {
+    outer(-1);
+    outer(-2.5);
+}
+
+fn zzz() {()}
diff --git a/src/test/debug-info/generic-method-on-generic-struct.rs b/src/test/debug-info/generic-method-on-generic-struct.rs
new file mode 100644 (file)
index 0000000..2056969
--- /dev/null
@@ -0,0 +1,140 @@
+// 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.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// STACK BY REF
+// debugger:finish
+// debugger:print *self
+// check:$1 = {x = {8888, -8888}}
+// debugger:print arg1
+// check:$2 = -1
+// debugger:print/d arg2
+// check:$3 = -2
+// debugger:continue
+
+// STACK BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {x = {8888, -8888}}
+// debugger:print arg1
+// check:$4 = -3
+// debugger:print arg2
+// check:$5 = -4
+// debugger:continue
+
+// OWNED BY REF
+// debugger:finish
+// debugger:print *self
+// check:$6 = {x = 1234.5}
+// debugger:print arg1
+// check:$7 = -5
+// debugger:print arg2
+// check:$8 = -6
+// debugger:continue
+
+// OWNED BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {x = 1234.5}
+// debugger:print arg1
+// check:$9 = -7
+// debugger:print arg2
+// check:$10 = -8
+// debugger:continue
+
+// OWNED MOVED
+// debugger:finish
+// debugger:print *self
+// check:$11 = {x = 1234.5}
+// debugger:print arg1
+// check:$12 = -9
+// debugger:print arg2
+// check:$13 = -10.5
+// debugger:continue
+
+// MANAGED BY REF
+// debugger:finish
+// debugger:print *self
+// check:$14 = {x = -1}
+// debugger:print arg1
+// check:$15 = -11
+// debugger:print arg2
+// check:$16 = -12.5
+// debugger:continue
+
+// MANAGED BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {x = -1}
+// debugger:print arg1
+// check:$17 = -13
+// debugger:print *arg2
+// check:$18 = {-14, 14}
+// debugger:continue
+
+// MANAGED SELF
+// debugger:finish
+// debugger:print self->val
+// check:$19 = {x = -1}
+// debugger:print arg1
+// check:$20 = -15
+// debugger:print *arg2
+// check:$21 = {-16, 16.5}
+// debugger:continue
+
+struct Struct<T> {
+    x: T
+}
+
+impl<T1> Struct<T1> {
+
+    fn self_by_ref<T2>(&self, arg1: int, arg2: T2) -> int {
+        zzz();
+        arg1
+    }
+
+    fn self_by_val<T2>(self, arg1: int, arg2: T2) -> int {
+        zzz();
+        arg1
+    }
+
+    fn self_owned<T2>(~self, arg1: int, arg2: T2) -> int {
+        zzz();
+        arg1
+    }
+
+    fn self_managed<T2>(@self, arg1: int, arg2: T2) -> int {
+        zzz();
+        arg1
+    }
+}
+
+fn main() {
+    let stack = Struct { x: (8888_u32, -8888_i32) };
+    let _ = stack.self_by_ref(-1, -2_i8);
+    let _ = stack.self_by_val(-3, -4_i16);
+
+    let owned = ~Struct { x: 1234.5 };
+    let _ = owned.self_by_ref(-5, -6_i32);
+    let _ = owned.self_by_val(-7, -8_i64);
+    let _ = owned.self_owned(-9, -10.5_f32);
+
+    let managed = @Struct { x: -1_i16 };
+    let _ = managed.self_by_ref(-11, -12.5_f64);
+    let _ = managed.self_by_val(-13, &(-14, 14));
+    let _ = managed.self_managed(-15, &(-16, 16.5));
+}
+
+fn zzz() {()}
diff --git a/src/test/debug-info/generic-static-method-on-struct-and-enum.rs b/src/test/debug-info/generic-static-method-on-struct-and-enum.rs
new file mode 100644 (file)
index 0000000..3a5380b
--- /dev/null
@@ -0,0 +1,67 @@
+// 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.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// STRUCT
+// debugger:finish
+// debugger:print arg1
+// check:$1 = 1
+// debugger:print arg2
+// check:$2 = 2
+// debugger:continue
+
+// ENUM
+// debugger:finish
+// debugger:print arg1
+// check:$3 = -3
+// debugger:print arg2
+// check:$4 = 4.5
+// debugger:print arg3
+// check:$5 = 5
+// debugger:continue
+
+
+struct Struct {
+    x: int
+}
+
+impl Struct {
+
+    fn static_method<T1, T2>(arg1: T1, arg2: T2) -> int {
+        zzz();
+        return 0;
+    }
+}
+
+enum Enum {
+    Variant1 { x: int },
+    Variant2,
+    Variant3(float, int, char),
+}
+
+impl Enum {
+
+    fn static_method<T1, T2, T3>(arg1: T1, arg2: T2, arg3: T3) -> int {
+        zzz();
+        return 1;
+    }
+}
+
+fn main() {
+    Struct::static_method(1, 2);
+    Enum::static_method(-3, 4.5, 5);
+}
+
+fn zzz() {()}
diff --git a/src/test/debug-info/generic-struct-style-enum.rs b/src/test/debug-info/generic-struct-style-enum.rs
new file mode 100644 (file)
index 0000000..77ac789
--- /dev/null
@@ -0,0 +1,77 @@
+// 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.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:set print union on
+// debugger:break zzz
+// debugger:run
+// debugger:finish
+
+// debugger:print case1
+// check:$1 = {{Case1, a = 0, b = 31868, c = 31868, d = 31868, e = 31868}, {Case1, a = 0, b = 2088533116, c = 2088533116}, {Case1, a = 0, b = 8970181431921507452}}
+
+// debugger:print case2
+// check:$2 = {{Case2, a = 0, b = 4369, c = 4369, d = 4369, e = 4369}, {Case2, a = 0, b = 286331153, c = 286331153}, {Case2, a = 0, b = 1229782938247303441}}
+
+// debugger:print case3
+// check:$3 = {{Case3, a = 0, b = 22873, c = 22873, d = 22873, e = 22873}, {Case3, a = 0, b = 1499027801, c = 1499027801}, {Case3, a = 0, b = 6438275382588823897}}
+
+// debugger:print univariant
+// check:$4 = {a = -1}
+
+// NOTE: This is a copy of the non-generic test case. The `Txx` type parameters have to be
+// substituted with something of size `xx` bits and the same alignment as an integer type of the
+// same size.
+
+// The first element is to ensure proper alignment, irrespective of the machines word size. Since
+// the size of the discriminant value is machine dependent, this has be taken into account when
+// datatype layout should be predictable as in this case.
+enum Regular<T16, T32, T64> {
+    Case1 { a: T64, b: T16, c: T16, d: T16, e: T16},
+    Case2 { a: T64, b: T32, c: T32},
+    Case3 { a: T64, b: T64 }
+}
+
+enum Univariant<T> {
+    TheOnlyCase { a: T }
+}
+
+fn main() {
+
+    // In order to avoid endianess trouble all of the following test values consist of a single
+    // repeated byte. This way each interpretation of the union should look the same, no matter if
+    // this is a big or little endian machine.
+
+    // 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452
+    // 0b01111100011111000111110001111100 = 2088533116
+    // 0b0111110001111100 = 31868
+    // 0b01111100 = 124
+    let case1: Regular<u16, u32, i64> = Case1 { a: 0, b: 31868, c: 31868, d: 31868, e: 31868 };
+
+    // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
+    // 0b00010001000100010001000100010001 = 286331153
+    // 0b0001000100010001 = 4369
+    // 0b00010001 = 17
+    let case2: Regular<i16, u32, i64>  = Case2 { a: 0, b: 286331153, c: 286331153 };
+
+    // 0b0101100101011001010110010101100101011001010110010101100101011001 = 6438275382588823897
+    // 0b01011001010110010101100101011001 = 1499027801
+    // 0b0101100101011001 = 22873
+    // 0b01011001 = 89
+    let case3: Regular<u16, i32, u64>  = Case3 { a: 0, b: 6438275382588823897 };
+
+    let univariant = TheOnlyCase { a: -1 };
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debug-info/generic-struct.rs b/src/test/debug-info/generic-struct.rs
new file mode 100644 (file)
index 0000000..0044def
--- /dev/null
@@ -0,0 +1,42 @@
+// 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.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// debugger:finish
+// debugger:print int_int
+// check:$1 = {key = 0, value = 1}
+// debugger:print int_float
+// check:$2 = {key = 2, value = 3.5}
+// debugger:print float_int
+// check:$3 = {key = 4.5, value = 5}
+// debugger:print float_int_float
+// check:$4 = {key = 6.5, value = {key = 7, value = 8.5}}
+
+struct AGenericStruct<TKey, TValue> {
+    key: TKey,
+    value: TValue
+}
+
+fn main() {
+
+    let int_int = AGenericStruct { key: 0, value: 1 };
+    let int_float = AGenericStruct { key: 2, value: 3.5 };
+    let float_int = AGenericStruct { key: 4.5, value: 5 };
+    let float_int_float = AGenericStruct { key: 6.5, value: AGenericStruct { key: 7, value: 8.5 } };
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debug-info/generic-trait-generic-static-default-method.rs b/src/test/debug-info/generic-trait-generic-static-default-method.rs
new file mode 100644 (file)
index 0000000..ef75c93
--- /dev/null
@@ -0,0 +1,53 @@
+// 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.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// debugger:finish
+// debugger:print arg1
+// check:$1 = 1000
+// debugger:print *arg2
+// check:$2 = {1, 2.5}
+// debugger:continue
+
+// debugger:finish
+// debugger:print arg1
+// check:$3 = 2000
+// debugger:print *arg2
+// check:$4 = {3.5, {4, 5, 6}}
+// debugger:continue
+
+
+struct Struct {
+    x: int
+}
+
+trait Trait<T1> {
+    fn generic_static_default_method<T2>(arg1: int, arg2: &(T1, T2)) -> int {
+        zzz();
+        arg1
+    }
+}
+
+impl<T> Trait<T> for Struct;
+
+fn main() {
+
+    // Is this really how to use these?
+    Trait::generic_static_default_method::<int, Struct, float>(1000, &(1, 2.5));
+    Trait::generic_static_default_method::<float, Struct, (int, int, int)>(2000, &(3.5, (4, 5, 6)));
+
+}
+
+fn zzz() {()}
diff --git a/src/test/debug-info/generic-tuple-style-enum.rs b/src/test/debug-info/generic-tuple-style-enum.rs
new file mode 100644 (file)
index 0000000..d6350e0
--- /dev/null
@@ -0,0 +1,78 @@
+// 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.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:set print union on
+// debugger:break zzz
+// debugger:run
+// debugger:finish
+
+// debugger:print case1
+// check:$1 = {{Case1, 0, 31868, 31868, 31868, 31868}, {Case1, 0, 2088533116, 2088533116}, {Case1, 0, 8970181431921507452}}
+
+// debugger:print case2
+// check:$2 = {{Case2, 0, 4369, 4369, 4369, 4369}, {Case2, 0, 286331153, 286331153}, {Case2, 0, 1229782938247303441}}
+
+// debugger:print case3
+// check:$3 = {{Case3, 0, 22873, 22873, 22873, 22873}, {Case3, 0, 1499027801, 1499027801}, {Case3, 0, 6438275382588823897}}
+
+// debugger:print univariant
+// check:$4 = {-1}
+
+
+// NOTE: This is a copy of the non-generic test case. The `Txx` type parameters have to be
+// substituted with something of size `xx` bits and the same alignment as an integer type of the
+// same size.
+
+// The first element is to ensure proper alignment, irrespective of the machines word size. Since
+// the size of the discriminant value is machine dependent, this has be taken into account when
+// datatype layout should be predictable as in this case.
+enum Regular<T16, T32, T64> {
+    Case1(T64, T16, T16, T16, T16),
+    Case2(T64, T32, T32),
+    Case3(T64, T64)
+}
+
+enum Univariant<T64> {
+    TheOnlyCase(T64)
+}
+
+fn main() {
+
+    // In order to avoid endianess trouble all of the following test values consist of a single
+    // repeated byte. This way each interpretation of the union should look the same, no matter if
+    // this is a big or little endian machine.
+
+    // 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452
+    // 0b01111100011111000111110001111100 = 2088533116
+    // 0b0111110001111100 = 31868
+    // 0b01111100 = 124
+    let case1: Regular<u16, u32, u64> = Case1(0_u64, 31868_u16, 31868_u16, 31868_u16, 31868_u16);
+
+    // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
+    // 0b00010001000100010001000100010001 = 286331153
+    // 0b0001000100010001 = 4369
+    // 0b00010001 = 17
+    let case2: Regular<i16, i32, i64> = Case2(0_i64, 286331153_i32, 286331153_i32);
+
+    // 0b0101100101011001010110010101100101011001010110010101100101011001 = 6438275382588823897
+    // 0b01011001010110010101100101011001 = 1499027801
+    // 0b0101100101011001 = 22873
+    // 0b01011001 = 89
+    let case3: Regular<i16, i32, i64> = Case3(0_i64, 6438275382588823897_i64);
+
+    let univariant = TheOnlyCase(-1_i64);
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debug-info/lexical-scope-in-parameterless-closure.rs b/src/test/debug-info/lexical-scope-in-parameterless-closure.rs
new file mode 100644 (file)
index 0000000..11b142b
--- /dev/null
@@ -0,0 +1,21 @@
+// 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.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z debug-info
+// debugger:run
+
+// Nothing to do here really, just make sure it compiles. See issue #8513.
+fn main() {
+    let _ = ||();
+    let _ = range(1u,3).map(|_| 5);
+}
+
index 1a3600a7d8cb3a737bcb0e57eb9ce927e120853c..f2d753fc88d8f0b02a71a3cf7c6abbb7dbe87cb4 100644 (file)
@@ -24,6 +24,8 @@
 // debugger:print univariant->val
 // check:$3 = {-9747455}
 
+#[allow(unused_variable)];
+
 // The first element is to ensure proper alignment, irrespective of the machines word size. Since
 // the size of the discriminant value is machine dependent, this has be taken into account when
 // datatype layout should be predictable as in this case.
@@ -60,4 +62,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index e42631599a9b93ac82e57ec43b3945a13707f3e1..a0b6f0e2b4f513862282d0c27e13144ffec24339 100644 (file)
@@ -27,6 +27,8 @@
 // debugger:print unique->val.elements[3]->val
 // check:$4 = 13
 
+#[allow(unused_variable)];
+
 fn main() {
 
     let unique: ~[@i64] = ~[@10, @11, @12, @13];
@@ -34,4 +36,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index 3eb1c2ef01e55da2465f4e716842c3de473678c6..4acf8d6efc7da07de366cb3989e9c5d533201122 100644 (file)
@@ -25,6 +25,8 @@
 // debugger:print managed_within_unique.val->y->val
 // check:$3 = -4
 
+#[allow(unused_variable)];
+
 struct ContainsManaged
 {
        x: int,
@@ -44,4 +46,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
diff --git a/src/test/debug-info/method-on-enum.rs b/src/test/debug-info/method-on-enum.rs
new file mode 100644 (file)
index 0000000..0748101
--- /dev/null
@@ -0,0 +1,141 @@
+// 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.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// STACK BY REF
+// debugger:finish
+// debugger:print *self
+// check:$1 = {{Variant2, x = 1799, y = 1799}, {Variant2, 117901063}}
+// debugger:print arg1
+// check:$2 = -1
+// debugger:print arg2
+// check:$3 = -2
+// debugger:continue
+
+// STACK BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {{Variant2, x = 1799, y = 1799}, {Variant2, 117901063}}
+// debugger:print arg1
+// check:$4 = -3
+// debugger:print arg2
+// check:$5 = -4
+// debugger:continue
+
+// OWNED BY REF
+// debugger:finish
+// debugger:print *self
+// check:$6 = {{Variant1, x = 1799, y = 1799}, {Variant1, 117901063}}
+// debugger:print arg1
+// check:$7 = -5
+// debugger:print arg2
+// check:$8 = -6
+// debugger:continue
+
+// OWNED BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {{Variant1, x = 1799, y = 1799}, {Variant1, 117901063}}
+// debugger:print arg1
+// check:$9 = -7
+// debugger:print arg2
+// check:$10 = -8
+// debugger:continue
+
+// OWNED MOVED
+// debugger:finish
+// debugger:print *self
+// check:$11 = {{Variant1, x = 1799, y = 1799}, {Variant1, 117901063}}
+// debugger:print arg1
+// check:$12 = -9
+// debugger:print arg2
+// check:$13 = -10
+// debugger:continue
+
+// MANAGED BY REF
+// debugger:finish
+// debugger:print *self
+// check:$14 = {{Variant2, x = 1799, y = 1799}, {Variant2, 117901063}}
+// debugger:print arg1
+// check:$15 = -11
+// debugger:print arg2
+// check:$16 = -12
+// debugger:continue
+
+// MANAGED BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {{Variant2, x = 1799, y = 1799}, {Variant2, 117901063}}
+// debugger:print arg1
+// check:$17 = -13
+// debugger:print arg2
+// check:$18 = -14
+// debugger:continue
+
+// MANAGED SELF
+// debugger:finish
+// debugger:print self->val
+// check:$19 = {{Variant2, x = 1799, y = 1799}, {Variant2, 117901063}}
+// debugger:print arg1
+// check:$20 = -15
+// debugger:print arg2
+// check:$21 = -16
+// debugger:continue
+
+enum Enum {
+    Variant1 { x: u16, y: u16 },
+    Variant2 (u32)
+}
+
+impl Enum {
+
+    fn self_by_ref(&self, arg1: int, arg2: int) -> int {
+        zzz();
+        arg1 + arg2
+    }
+
+    fn self_by_val(self, arg1: int, arg2: int) -> int {
+        zzz();
+        arg1 + arg2
+    }
+
+    fn self_owned(~self, arg1: int, arg2: int) -> int {
+        zzz();
+        arg1 + arg2
+    }
+
+    fn self_managed(@self, arg1: int, arg2: int) -> int {
+        zzz();
+        arg1 + arg2
+    }
+}
+
+fn main() {
+    let stack = Variant2(117901063);
+    let _ = stack.self_by_ref(-1, -2);
+    let _ = stack.self_by_val(-3, -4);
+
+    let owned = ~Variant1{ x: 1799, y: 1799 };
+    let _ = owned.self_by_ref(-5, -6);
+    let _ = owned.self_by_val(-7, -8);
+    let _ = owned.self_owned(-9, -10);
+
+    let managed = @Variant2(117901063);
+    let _ = managed.self_by_ref(-11, -12);
+    let _ = managed.self_by_val(-13, -14);
+    let _ = managed.self_managed(-15, -16);
+}
+
+fn zzz() {()}
diff --git a/src/test/debug-info/method-on-generic-struct.rs b/src/test/debug-info/method-on-generic-struct.rs
new file mode 100644 (file)
index 0000000..f482846
--- /dev/null
@@ -0,0 +1,140 @@
+// 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.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// STACK BY REF
+// debugger:finish
+// debugger:print *self
+// check:$1 = {x = {8888, -8888}}
+// debugger:print arg1
+// check:$2 = -1
+// debugger:print arg2
+// check:$3 = -2
+// debugger:continue
+
+// STACK BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {x = {8888, -8888}}
+// debugger:print arg1
+// check:$4 = -3
+// debugger:print arg2
+// check:$5 = -4
+// debugger:continue
+
+// OWNED BY REF
+// debugger:finish
+// debugger:print *self
+// check:$6 = {x = 1234.5}
+// debugger:print arg1
+// check:$7 = -5
+// debugger:print arg2
+// check:$8 = -6
+// debugger:continue
+
+// OWNED BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {x = 1234.5}
+// debugger:print arg1
+// check:$9 = -7
+// debugger:print arg2
+// check:$10 = -8
+// debugger:continue
+
+// OWNED MOVED
+// debugger:finish
+// debugger:print *self
+// check:$11 = {x = 1234.5}
+// debugger:print arg1
+// check:$12 = -9
+// debugger:print arg2
+// check:$13 = -10
+// debugger:continue
+
+// MANAGED BY REF
+// debugger:finish
+// debugger:print *self
+// check:$14 = {x = -1}
+// debugger:print arg1
+// check:$15 = -11
+// debugger:print arg2
+// check:$16 = -12
+// debugger:continue
+
+// MANAGED BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {x = -1}
+// debugger:print arg1
+// check:$17 = -13
+// debugger:print arg2
+// check:$18 = -14
+// debugger:continue
+
+// MANAGED SELF
+// debugger:finish
+// debugger:print self->val
+// check:$19 = {x = -1}
+// debugger:print arg1
+// check:$20 = -15
+// debugger:print arg2
+// check:$21 = -16
+// debugger:continue
+
+struct Struct<T> {
+    x: T
+}
+
+impl<T> Struct<T> {
+
+    fn self_by_ref(&self, arg1: int, arg2: int) -> int {
+        zzz();
+        arg1 + arg2
+    }
+
+    fn self_by_val(self, arg1: int, arg2: int) -> int {
+        zzz();
+        arg1 + arg2
+    }
+
+    fn self_owned(~self, arg1: int, arg2: int) -> int {
+        zzz();
+        arg1 + arg2
+    }
+
+    fn self_managed(@self, arg1: int, arg2: int) -> int {
+        zzz();
+        arg1 + arg2
+    }
+}
+
+fn main() {
+    let stack = Struct { x: (8888_u32, -8888_i32) };
+    let _ = stack.self_by_ref(-1, -2);
+    let _ = stack.self_by_val(-3, -4);
+
+    let owned = ~Struct { x: 1234.5 };
+    let _ = owned.self_by_ref(-5, -6);
+    let _ = owned.self_by_val(-7, -8);
+    let _ = owned.self_owned(-9, -10);
+
+    let managed = @Struct { x: -1_i16 };
+    let _ = managed.self_by_ref(-11, -12);
+    let _ = managed.self_by_val(-13, -14);
+    let _ = managed.self_managed(-15, -16);
+}
+
+fn zzz() {()}
diff --git a/src/test/debug-info/method-on-struct.rs b/src/test/debug-info/method-on-struct.rs
new file mode 100644 (file)
index 0000000..211f83e
--- /dev/null
@@ -0,0 +1,140 @@
+// 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.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// STACK BY REF
+// debugger:finish
+// debugger:print *self
+// check:$1 = {x = 100}
+// debugger:print arg1
+// check:$2 = -1
+// debugger:print arg2
+// check:$3 = -2
+// debugger:continue
+
+// STACK BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {x = 100}
+// debugger:print arg1
+// check:$4 = -3
+// debugger:print arg2
+// check:$5 = -4
+// debugger:continue
+
+// OWNED BY REF
+// debugger:finish
+// debugger:print *self
+// check:$6 = {x = 200}
+// debugger:print arg1
+// check:$7 = -5
+// debugger:print arg2
+// check:$8 = -6
+// debugger:continue
+
+// OWNED BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {x = 200}
+// debugger:print arg1
+// check:$9 = -7
+// debugger:print arg2
+// check:$10 = -8
+// debugger:continue
+
+// OWNED MOVED
+// debugger:finish
+// debugger:print *self
+// check:$11 = {x = 200}
+// debugger:print arg1
+// check:$12 = -9
+// debugger:print arg2
+// check:$13 = -10
+// debugger:continue
+
+// MANAGED BY REF
+// debugger:finish
+// debugger:print *self
+// check:$14 = {x = 300}
+// debugger:print arg1
+// check:$15 = -11
+// debugger:print arg2
+// check:$16 = -12
+// debugger:continue
+
+// MANAGED BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {x = 300}
+// debugger:print arg1
+// check:$17 = -13
+// debugger:print arg2
+// check:$18 = -14
+// debugger:continue
+
+// MANAGED SELF
+// debugger:finish
+// debugger:print self->val
+// check:$19 = {x = 300}
+// debugger:print arg1
+// check:$20 = -15
+// debugger:print arg2
+// check:$21 = -16
+// debugger:continue
+
+struct Struct {
+    x: int
+}
+
+impl Struct {
+
+    fn self_by_ref(&self, arg1: int, arg2: int) -> int {
+        zzz();
+        self.x + arg1 + arg2
+    }
+
+    fn self_by_val(self, arg1: int, arg2: int) -> int {
+        zzz();
+        self.x + arg1 + arg2
+    }
+
+    fn self_owned(~self, arg1: int, arg2: int) -> int {
+        zzz();
+        self.x + arg1 + arg2
+    }
+
+    fn self_managed(@self, arg1: int, arg2: int) -> int {
+        zzz();
+        self.x + arg1 + arg2
+    }
+}
+
+fn main() {
+    let stack = Struct { x: 100 };
+    let _ = stack.self_by_ref(-1, -2);
+    let _ = stack.self_by_val(-3, -4);
+
+    let owned = ~Struct { x: 200 };
+    let _ = owned.self_by_ref(-5, -6);
+    let _ = owned.self_by_val(-7, -8);
+    let _ = owned.self_owned(-9, -10);
+
+    let managed = @Struct { x: 300 };
+    let _ = managed.self_by_ref(-11, -12);
+    let _ = managed.self_by_val(-13, -14);
+    let _ = managed.self_managed(-15, -16);
+}
+
+fn zzz() {()}
diff --git a/src/test/debug-info/method-on-trait.rs b/src/test/debug-info/method-on-trait.rs
new file mode 100644 (file)
index 0000000..ad6c9a1
--- /dev/null
@@ -0,0 +1,147 @@
+// 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.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// STACK BY REF
+// debugger:finish
+// debugger:print *self
+// check:$1 = {x = 100}
+// debugger:print arg1
+// check:$2 = -1
+// debugger:print arg2
+// check:$3 = -2
+// debugger:continue
+
+// STACK BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {x = 100}
+// debugger:print arg1
+// check:$4 = -3
+// debugger:print arg2
+// check:$5 = -4
+// debugger:continue
+
+// OWNED BY REF
+// debugger:finish
+// debugger:print *self
+// check:$6 = {x = 200}
+// debugger:print arg1
+// check:$7 = -5
+// debugger:print arg2
+// check:$8 = -6
+// debugger:continue
+
+// OWNED BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {x = 200}
+// debugger:print arg1
+// check:$9 = -7
+// debugger:print arg2
+// check:$10 = -8
+// debugger:continue
+
+// OWNED MOVED
+// debugger:finish
+// debugger:print *self
+// check:$11 = {x = 200}
+// debugger:print arg1
+// check:$12 = -9
+// debugger:print arg2
+// check:$13 = -10
+// debugger:continue
+
+// MANAGED BY REF
+// debugger:finish
+// debugger:print *self
+// check:$14 = {x = 300}
+// debugger:print arg1
+// check:$15 = -11
+// debugger:print arg2
+// check:$16 = -12
+// debugger:continue
+
+// MANAGED BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {x = 300}
+// debugger:print arg1
+// check:$17 = -13
+// debugger:print arg2
+// check:$18 = -14
+// debugger:continue
+
+// MANAGED SELF
+// debugger:finish
+// debugger:print self->val
+// check:$19 = {x = 300}
+// debugger:print arg1
+// check:$20 = -15
+// debugger:print arg2
+// check:$21 = -16
+// debugger:continue
+
+struct Struct {
+    x: int
+}
+
+trait Trait {
+    fn self_by_ref(&self, arg1: int, arg2: int) -> int;
+    fn self_by_val(self, arg1: int, arg2: int) -> int;
+    fn self_owned(~self, arg1: int, arg2: int) -> int;
+    fn self_managed(@self, arg1: int, arg2: int) -> int;
+}
+
+impl Trait for Struct {
+
+    fn self_by_ref(&self, arg1: int, arg2: int) -> int {
+        zzz();
+        self.x + arg1 + arg2
+    }
+
+    fn self_by_val(self, arg1: int, arg2: int) -> int {
+        zzz();
+        self.x + arg1 + arg2
+    }
+
+    fn self_owned(~self, arg1: int, arg2: int) -> int {
+        zzz();
+        self.x + arg1 + arg2
+    }
+
+    fn self_managed(@self, arg1: int, arg2: int) -> int {
+        zzz();
+        self.x + arg1 + arg2
+    }
+}
+
+fn main() {
+    let stack = Struct { x: 100 };
+    let _ = stack.self_by_ref(-1, -2);
+    let _ = stack.self_by_val(-3, -4);
+
+    let owned = ~Struct { x: 200 };
+    let _ = owned.self_by_ref(-5, -6);
+    let _ = owned.self_by_val(-7, -8);
+    let _ = owned.self_owned(-9, -10);
+
+    let managed = @Struct { x: 300 };
+    let _ = managed.self_by_ref(-11, -12);
+    let _ = managed.self_by_val(-13, -14);
+    let _ = managed.self_managed(-15, -16);
+}
+
+fn zzz() {()}
diff --git a/src/test/debug-info/method-on-tuple-struct.rs b/src/test/debug-info/method-on-tuple-struct.rs
new file mode 100644 (file)
index 0000000..03d7c44
--- /dev/null
@@ -0,0 +1,138 @@
+// 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.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// STACK BY REF
+// debugger:finish
+// debugger:print *self
+// check:$1 = {100, -100.5}
+// debugger:print arg1
+// check:$2 = -1
+// debugger:print arg2
+// check:$3 = -2
+// debugger:continue
+
+// STACK BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {100, -100.5}
+// debugger:print arg1
+// check:$4 = -3
+// debugger:print arg2
+// check:$5 = -4
+// debugger:continue
+
+// OWNED BY REF
+// debugger:finish
+// debugger:print *self
+// check:$6 = {200, -200.5}
+// debugger:print arg1
+// check:$7 = -5
+// debugger:print arg2
+// check:$8 = -6
+// debugger:continue
+
+// OWNED BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {200, -200.5}
+// debugger:print arg1
+// check:$9 = -7
+// debugger:print arg2
+// check:$10 = -8
+// debugger:continue
+
+// OWNED MOVED
+// debugger:finish
+// debugger:print *self
+// check:$11 = {200, -200.5}
+// debugger:print arg1
+// check:$12 = -9
+// debugger:print arg2
+// check:$13 = -10
+// debugger:continue
+
+// MANAGED BY REF
+// debugger:finish
+// debugger:print *self
+// check:$14 = {300, -300.5}
+// debugger:print arg1
+// check:$15 = -11
+// debugger:print arg2
+// check:$16 = -12
+// debugger:continue
+
+// MANAGED BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {300, -300.5}
+// debugger:print arg1
+// check:$17 = -13
+// debugger:print arg2
+// check:$18 = -14
+// debugger:continue
+
+// MANAGED SELF
+// debugger:finish
+// debugger:print self->val
+// check:$19 = {300, -300.5}
+// debugger:print arg1
+// check:$20 = -15
+// debugger:print arg2
+// check:$21 = -16
+// debugger:continue
+
+struct TupleStruct(int, float);
+
+impl TupleStruct {
+
+    fn self_by_ref(&self, arg1: int, arg2: int) -> int {
+        zzz();
+        arg1 + arg2
+    }
+
+    fn self_by_val(self, arg1: int, arg2: int) -> int {
+        zzz();
+        arg1 + arg2
+    }
+
+    fn self_owned(~self, arg1: int, arg2: int) -> int {
+        zzz();
+        arg1 + arg2
+    }
+
+    fn self_managed(@self, arg1: int, arg2: int) -> int {
+        zzz();
+        arg1 + arg2
+    }
+}
+
+fn main() {
+    let stack = TupleStruct(100, -100.5);
+    let _ = stack.self_by_ref(-1, -2);
+    let _ = stack.self_by_val(-3, -4);
+
+    let owned = ~TupleStruct(200, -200.5);
+    let _ = owned.self_by_ref(-5, -6);
+    let _ = owned.self_by_val(-7, -8);
+    let _ = owned.self_owned(-9, -10);
+
+    let managed = @TupleStruct(300, -300.5);
+    let _ = managed.self_by_ref(-11, -12);
+    let _ = managed.self_by_val(-13, -14);
+    let _ = managed.self_managed(-15, -16);
+}
+
+fn zzz() {()}
index 5b690b9d067c426585a82c2d5c1e1a2e641ef853..3f9dd1a0748fb7f15a8965e2c5385410c6ad5a68 100644 (file)
@@ -28,6 +28,8 @@
 // debugger:print abc
 // check:$3 = 30303
 
+#[allow(unused_variable)];
+
 fn function_one() {
        let abc = 10101;
        zzz();
index aaac723f1613eaf3941ef51851cbc40bd0d8a86a..4d709070763cdbd982a4f2f7f8b567a798c6be1c 100644 (file)
@@ -28,6 +28,8 @@
 // debugger:print c
 // check:$3 = 30303
 
+#[allow(unused_variable)];
+
 fn function_one() {
        let a = 10101;
        zzz();
index d3afd4b11f9cd1f5e84e5e477b69fc2018c8bac1..8622795ee90488fcd4d8ff205841ac96974c45e3 100644 (file)
@@ -21,6 +21,8 @@
 // debugger:print second
 // check:$2 = {<No data fields>}
 
+#[allow(unused_variable)];
+
 enum ANilEnum {}
 enum AnotherNilEnum {}
 
@@ -37,4 +39,4 @@ fn main() {
     }
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index 3bf3507faba779d02ca9d63b3db56832d7846158..02fd294a0bd5e555c12c9b31a177ef4fc7826aba 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
-// xfail-test broken in newrt?
 
 // compile-flags:-Z extra-debug-info
 // debugger:break zzz
 // debugger:print full
 // check:$3 = {454545, 0x87654321, 9988}
 
-// debugger:print empty
-// check:$4 = {0, 0x0, 0}
+// debugger:print empty->discr
+// check:$4 = (int *) 0x0
 
 // debugger:print droid
 // check:$5 = {id = 675675, range = 10000001, internals = 0x43218765}
 
-// debugger:print void_droid
-// check:$6 = {id = 0, range = 0, internals = 0x0}
+// debugger:print void_droid->internals
+// check:$6 = (int *) 0x0
 
+// debugger:continue
 
 // If a struct has exactly two variants, one of them is empty, and the other one
 // contains a non-nullable pointer, then this value is used as the discriminator.
 // The test cases in this file make sure that something readable is generated for
 // this kind of types.
+// Unfortunately (for these test cases) the content of the non-discriminant fields
+// in the null-case is not defined. So we just read the discriminator field in
+// this case (by casting the value to a memory-equivalent struct).
 
 enum MoreFields<'self> {
     Full(u32, &'self int, i16),
     Empty
 }
 
+struct MoreFieldsRepr<'self> {
+    a: u32,
+    discr: &'self int,
+    b: i16
+}
+
 enum NamedFields<'self> {
     Droid { id: i32, range: i64, internals: &'self int },
     Void
 }
 
+struct NamedFieldsRepr<'self> {
+    id: i32,
+    range: i64,
+    internals: &'self int
+}
+
 fn main() {
 
     let some: Option<&u32> = Some(unsafe { std::cast::transmute(0x12345678) });
@@ -58,15 +73,17 @@ fn main() {
     let full = Full(454545, unsafe { std::cast::transmute(0x87654321) }, 9988);
 
     let int_val = 0;
-    let mut empty = Full(0, &int_val, 0);
-    empty = Empty;
+    let empty: &MoreFieldsRepr = unsafe { std::cast::transmute(&Empty) };
 
-    let droid = Droid { id: 675675, range: 10000001, internals: unsafe { std::cast::transmute(0x43218765) } };
+    let droid = Droid {
+        id: 675675,
+        range: 10000001,
+        internals: unsafe { std::cast::transmute(0x43218765) }
+    };
 
-    let mut void_droid = Droid { id: 0, range: 0, internals: &int_val };
-    void_droid = Void;
+    let void_droid: &NamedFieldsRepr = unsafe { std::cast::transmute(&Void) };
 
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index 9ff91aa00d1c908a64bcda7ba6a161f9d63f6a5c..f36e8454da99e252e4362fd40ee0ef21da7ddec3 100644 (file)
@@ -41,6 +41,8 @@
 // debugger:print deeplyNested
 // check:$8 = {a = {a = 1, b = {x = 2, y = 3, z = 4}, c = 5, d = {x = 6, y = 7, z = 8}}, b = {a = 9, b = {x = 10, y = 11, z = 12}, c = {x = 13, y = 14, z = 15}, d = 16}, c = {a = 17, b = {x = 18, y = 19, z = 20}, c = 21, d = {x = 22, y = 23, z = 24}}, d = {a = 25, b = {x = 26, y = 27, z = 28}, c = 29, d = {x = 30, y = 31, z = 32}}, e = {a = 33, b = {x = 34, y = 35, z = 36}, c = {x = 37, y = 38, z = 39}, d = 40}, f = {a = 41, b = {x = 42, y = 43, z = 44}, c = 45, d = {x = 46, y = 47, z = 48}}}
 
+#[allow(unused_variable)];
+
 #[packed]
 struct Packed {
     x: i16,
@@ -216,4 +218,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index 859166cb023a3a6d424a70edd96e6ceac22c101a..93d3a9f2f116e8c070f5bc0cda6384f9e0cca023 100644 (file)
@@ -34,6 +34,8 @@
 // debugger:print sizeof(packedInPacked)
 // check:$6 = 40
 
+#[allow(unused_variable)];
+
 #[packed]
 struct Packed {
     x: i16,
@@ -101,4 +103,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
diff --git a/src/test/debug-info/self-in-default-method.rs b/src/test/debug-info/self-in-default-method.rs
new file mode 100644 (file)
index 0000000..cc7cab3
--- /dev/null
@@ -0,0 +1,141 @@
+// 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.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// STACK BY REF
+// debugger:finish
+// debugger:print *self
+// check:$1 = {x = 100}
+// debugger:print arg1
+// check:$2 = -1
+// debugger:print arg2
+// check:$3 = -2
+// debugger:continue
+
+// STACK BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {x = 100}
+// debugger:print arg1
+// check:$4 = -3
+// debugger:print arg2
+// check:$5 = -4
+// debugger:continue
+
+// OWNED BY REF
+// debugger:finish
+// debugger:print *self
+// check:$6 = {x = 200}
+// debugger:print arg1
+// check:$7 = -5
+// debugger:print arg2
+// check:$8 = -6
+// debugger:continue
+
+// OWNED BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {x = 200}
+// debugger:print arg1
+// check:$9 = -7
+// debugger:print arg2
+// check:$10 = -8
+// debugger:continue
+
+// OWNED MOVED
+// debugger:finish
+// debugger:print *self
+// check:$11 = {x = 200}
+// debugger:print arg1
+// check:$12 = -9
+// debugger:print arg2
+// check:$13 = -10
+// debugger:continue
+
+// MANAGED BY REF
+// debugger:finish
+// debugger:print *self
+// check:$14 = {x = 300}
+// debugger:print arg1
+// check:$15 = -11
+// debugger:print arg2
+// check:$16 = -12
+// debugger:continue
+
+// MANAGED BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {x = 300}
+// debugger:print arg1
+// check:$17 = -13
+// debugger:print arg2
+// check:$18 = -14
+// debugger:continue
+
+// MANAGED SELF
+// debugger:finish
+// debugger:print self->val
+// check:$19 = {x = 300}
+// debugger:print arg1
+// check:$20 = -15
+// debugger:print arg2
+// check:$21 = -16
+// debugger:continue
+
+struct Struct {
+    x: int
+}
+
+trait Trait {
+    fn self_by_ref(&self, arg1: int, arg2: int) -> int {
+        zzz();
+        arg1 + arg2
+    }
+
+    fn self_by_val(self, arg1: int, arg2: int) -> int {
+        zzz();
+        arg1 + arg2
+    }
+
+    fn self_owned(~self, arg1: int, arg2: int) -> int {
+        zzz();
+        arg1 + arg2
+    }
+
+    fn self_managed(@self, arg1: int, arg2: int) -> int {
+        zzz();
+        arg1 + arg2
+    }
+}
+
+impl Trait for Struct;
+
+fn main() {
+    let stack = Struct { x: 100 };
+    let _ = stack.self_by_ref(-1, -2);
+    let _ = stack.self_by_val(-3, -4);
+
+    let owned = ~Struct { x: 200 };
+    let _ = owned.self_by_ref(-5, -6);
+    let _ = owned.self_by_val(-7, -8);
+    let _ = owned.self_owned(-9, -10);
+
+    let managed = @Struct { x: 300 };
+    let _ = managed.self_by_ref(-11, -12);
+    let _ = managed.self_by_val(-13, -14);
+    let _ = managed.self_managed(-15, -16);
+}
+
+fn zzz() {()}
diff --git a/src/test/debug-info/self-in-generic-default-method.rs b/src/test/debug-info/self-in-generic-default-method.rs
new file mode 100644 (file)
index 0000000..57068df
--- /dev/null
@@ -0,0 +1,142 @@
+// 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.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// STACK BY REF
+// debugger:finish
+// debugger:print *self
+// check:$1 = {x = 987}
+// debugger:print arg1
+// check:$2 = -1
+// debugger:print/d arg2
+// check:$3 = -2
+// debugger:continue
+
+// STACK BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {x = 987}
+// debugger:print arg1
+// check:$4 = -3
+// debugger:print arg2
+// check:$5 = -4
+// debugger:continue
+
+// OWNED BY REF
+// debugger:finish
+// debugger:print *self
+// check:$6 = {x = 879}
+// debugger:print arg1
+// check:$7 = -5
+// debugger:print arg2
+// check:$8 = -6
+// debugger:continue
+
+// OWNED BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {x = 879}
+// debugger:print arg1
+// check:$9 = -7
+// debugger:print arg2
+// check:$10 = -8
+// debugger:continue
+
+// OWNED MOVED
+// debugger:finish
+// debugger:print *self
+// check:$11 = {x = 879}
+// debugger:print arg1
+// check:$12 = -9
+// debugger:print arg2
+// check:$13 = -10.5
+// debugger:continue
+
+// MANAGED BY REF
+// debugger:finish
+// debugger:print *self
+// check:$14 = {x = 897}
+// debugger:print arg1
+// check:$15 = -11
+// debugger:print arg2
+// check:$16 = -12.5
+// debugger:continue
+
+// MANAGED BY VAL
+// debugger:finish
+// d ebugger:print self -- ignored for now because of issue #8512
+// c heck:$X = {x = 897}
+// debugger:print arg1
+// check:$17 = -13
+// debugger:print *arg2
+// check:$18 = {-14, 14}
+// debugger:continue
+
+// MANAGED SELF
+// debugger:finish
+// debugger:print self->val
+// check:$19 = {x = 897}
+// debugger:print arg1
+// check:$20 = -15
+// debugger:print *arg2
+// check:$21 = {-16, 16.5}
+// debugger:continue
+
+struct Struct {
+    x: int
+}
+
+trait Trait {
+
+    fn self_by_ref<T>(&self, arg1: int, arg2: T) -> int {
+        zzz();
+        arg1
+    }
+
+    fn self_by_val<T>(self, arg1: int, arg2: T) -> int {
+        zzz();
+        arg1
+    }
+
+    fn self_owned<T>(~self, arg1: int, arg2: T) -> int {
+        zzz();
+        arg1
+    }
+
+    fn self_managed<T>(@self, arg1: int, arg2: T) -> int {
+        zzz();
+        arg1
+    }
+}
+
+impl Trait for Struct;
+
+fn main() {
+    let stack = Struct { x: 987 };
+    let _ = stack.self_by_ref(-1, -2_i8);
+    let _ = stack.self_by_val(-3, -4_i16);
+
+    let owned = ~Struct { x: 879 };
+    let _ = owned.self_by_ref(-5, -6_i32);
+    let _ = owned.self_by_val(-7, -8_i64);
+    let _ = owned.self_owned(-9, -10.5_f32);
+
+    let managed = @Struct { x: 897 };
+    let _ = managed.self_by_ref(-11, -12.5_f64);
+    let _ = managed.self_by_val(-13, &(-14, 14));
+    let _ = managed.self_managed(-15, &(-16, 16.5));
+}
+
+fn zzz() {()}
index 49e7bc255c10ffe2df5cd5981c56fc95eb719f85..6532a3841e5ef42581024eb3ab993b5a493f75ba 100644 (file)
@@ -34,6 +34,7 @@
 // debugger:print padding_at_end
 // check:$6 = {x = -10014, y = 10015}
 
+#[allow(unused_variable)];
 
 struct NoPadding16 {
     x: u16,
@@ -81,4 +82,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index f45294221af1686a84f4bf383e883ad95417aa3a..81a6c4a3ee56e1d7c9947cda0082a27e713e0d74 100644 (file)
@@ -33,6 +33,7 @@
 // debugger:print paddingAtEnd
 // check:$7 = {15, 16}
 
+#[allow(unused_variable)];
 
 fn main() {
     let noPadding8: (i8, u8) = (-100, 100);
@@ -48,4 +49,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
diff --git a/src/test/debug-info/static-method-on-struct-and-enum.rs b/src/test/debug-info/static-method-on-struct-and-enum.rs
new file mode 100644 (file)
index 0000000..ecc74e4
--- /dev/null
@@ -0,0 +1,67 @@
+// 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.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// STRUCT
+// debugger:finish
+// debugger:print arg1
+// check:$1 = 1
+// debugger:print arg2
+// check:$2 = 2
+// debugger:continue
+
+// ENUM
+// debugger:finish
+// debugger:print arg1
+// check:$3 = -3
+// debugger:print arg2
+// check:$4 = 4.5
+// debugger:print arg3
+// check:$5 = 5
+// debugger:continue
+
+
+struct Struct {
+    x: int
+}
+
+impl Struct {
+
+    fn static_method(arg1: int, arg2: int) -> int {
+        zzz();
+        arg1 + arg2
+    }
+}
+
+enum Enum {
+    Variant1 { x: int },
+    Variant2,
+    Variant3(float, int, char),
+}
+
+impl Enum {
+
+    fn static_method(arg1: int, arg2: float, arg3: uint) -> int {
+        zzz();
+        arg1
+    }
+}
+
+fn main() {
+    Struct::static_method(1, 2);
+    Enum::static_method(-3, 4.5, 5);
+}
+
+fn zzz() {()}
index 1002266a1a98539c8cf18ab7b9aefee74233d05c..c7879ac472092b726b25abd11f01cba13b018770 100644 (file)
@@ -25,6 +25,8 @@
 // debugger:print univariant
 // check:$3 = {{x = 123, y = 456, z = 789}}
 
+#[allow(unused_variable)];
+
 struct Struct {
        x: u32,
        y: i32,
index 04c5eec610b73599147aac068d015b7335a53172..ca02283de3788274b1c53aca09789100aa18b3de 100644 (file)
@@ -25,6 +25,7 @@
 // debugger:print padding_at_end_parent
 // check:$3 = {x = {x = 10, y = 11}, y = {x = 12, y = 13}, z = {x = 14, y = 15}}
 
+#[allow(unused_variable)];
 
 struct Simple {
     x: i32
@@ -142,4 +143,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index 61bbd2e215ff6933b138f9c40ac4b7a318e40a0e..30be3b845634d4695a54cf81ca955f4630574321 100644 (file)
@@ -28,6 +28,8 @@
 // debugger:print univariant
 // check:$4 = {a = -1}
 
+#[allow(unused_variable)];
+
 // The first element is to ensure proper alignment, irrespective of the machines word size. Since
 // the size of the discriminant value is machine dependent, this has be taken into account when
 // datatype layout should be predictable as in this case.
@@ -70,4 +72,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index 0719f64b2564f03803e711882c625b554b653307..09bb690988c3115770ee5e6381bfb1f4ecc1e383 100644 (file)
@@ -26,6 +26,8 @@
 // debugger:print nested
 // check:$4 = {a = {a = {x = 7890, y = 9870}}}
 
+#[allow(unused_variable)];
+
 struct NoDestructor {
     x: i32,
     y: i64
diff --git a/src/test/debug-info/trait-generic-static-default-method.rs b/src/test/debug-info/trait-generic-static-default-method.rs
new file mode 100644 (file)
index 0000000..33468c9
--- /dev/null
@@ -0,0 +1,53 @@
+// 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.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// debugger:finish
+// debugger:print arg1
+// check:$1 = 1000
+// debugger:print arg2
+// check:$2 = 0.5
+// debugger:continue
+
+// debugger:finish
+// debugger:print arg1
+// check:$3 = 2000
+// debugger:print *arg2
+// check:$4 = {1, 2, 3}
+// debugger:continue
+
+
+struct Struct {
+    x: int
+}
+
+trait Trait {
+    fn generic_static_default_method<T>(arg1: int, arg2: T) -> int {
+        zzz();
+        arg1
+    }
+}
+
+impl Trait for Struct;
+
+fn main() {
+
+    // Is this really how to use these?
+    Trait::generic_static_default_method::<Struct, float>(1000, 0.5);
+    Trait::generic_static_default_method::<Struct, &(int, int, int)>(2000, &(1, 2, 3));
+
+}
+
+fn zzz() {()}
index 369c9fd28ccdf23f55b39c6cca7e950c3d2d7bb8..b2611b3077d61a2c517a0f23003dd272de7ea529 100644 (file)
@@ -41,6 +41,8 @@
 // debugger:print mixed_padding
 // check:$10 = {x = {{40, 41, 42}, {43, 44}}, y = {45, 46, 47, 48}}
 
+#[allow(unused_variable)];
+
 struct NoPadding1 {
     x: (i32, i32),
     y: i32,
@@ -148,4 +150,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index 9c6805dae67d37721390fbf53ae8f0d7cf8d8265..940edd08975194584b5b9d3a558ebcda50f097f9 100644 (file)
@@ -33,6 +33,8 @@
 // debugger:print padding_at_end2
 // check:$7 = {{21, 22}, 23}
 
+#[allow(unused_variable)];
+
 fn main() {
     let no_padding1: ((u32, u32), u32, u32) = ((0, 1), 2, 3);
     let no_padding2: (u32, (u32, u32), u32) = (4, (5, 6), 7);
@@ -47,4 +49,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
diff --git a/src/test/debug-info/tuple-struct.rs b/src/test/debug-info/tuple-struct.rs
new file mode 100644 (file)
index 0000000..ada3802
--- /dev/null
@@ -0,0 +1,60 @@
+// 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.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:set print pretty off
+// debugger:break zzz
+// debugger:run
+// debugger:finish
+
+// debugger:print no_padding16
+// check:$1 = {10000, -10001}
+
+// debugger:print no_padding32
+// check:$2 = {-10002, -10003.5, 10004}
+
+// debugger:print no_padding64
+// check:$3 = {-10005.5, 10006, 10007}
+
+// debugger:print no_padding163264
+// check:$4 = {-10008, 10009, 10010, 10011}
+
+// debugger:print internal_padding
+// check:$5 = {10012, -10013}
+
+// debugger:print padding_at_end
+// check:$6 = {-10014, 10015}
+
+
+// This test case mainly makes sure that no field names are generated for tuple structs (as opposed
+// to all fields having the name "__field__"). Otherwise they are handled the same a normal structs.
+
+struct NoPadding16(u16, i16);
+struct NoPadding32(i32, f32, u32);
+struct NoPadding64(f64, i64, u64);
+struct NoPadding163264(i16, u16, i32, u64);
+struct InternalPadding(u16, i64);
+struct PaddingAtEnd(i64, u16);
+
+fn main() {
+    let no_padding16 = NoPadding16(10000, -10001);
+    let no_padding32 = NoPadding32(-10002, -10003.5, 10004);
+    let no_padding64 = NoPadding64(-10005.5, 10006, 10007);
+    let no_padding163264 = NoPadding163264(-10008, 10009, 10010, 10011);
+
+    let internal_padding = InternalPadding(10012, -10013);
+    let padding_at_end = PaddingAtEnd(-10014, 10015);
+
+    zzz();
+}
+
+fn zzz() {()}
index ba1d02bb62a3c6cbcbf7417a0af3057496750eb6..5dadfa84ba9671521ee8bd98af60359d09cfb51f 100644 (file)
@@ -28,6 +28,8 @@
 // debugger:print univariant
 // check:$4 = {-1}
 
+#[allow(unused_variable)];
+
 // The first element is to ensure proper alignment, irrespective of the machines word size. Since
 // the size of the discriminant value is machine dependent, this has be taken into account when
 // datatype layout should be predictable as in this case.
@@ -70,4 +72,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index 443f641a858592d10773597f7582b92f7b6a9dc3..84f7e817d2488018e1c5a781f2a9483238a4bd07 100644 (file)
@@ -24,6 +24,8 @@
 // debugger:print *univariant
 // check:$3 = {123234}
 
+#[allow(unused_variable)];
+
 // The first element is to ensure proper alignment, irrespective of the machines word size. Since
 // the size of the discriminant value is machine dependent, this has be taken into account when
 // datatype layout should be predictable as in this case.
@@ -60,4 +62,4 @@ fn main() {
     zzz();
 }
 
-fn zzz() {()}
\ No newline at end of file
+fn zzz() {()}
index 4691de049172136c9313c43dbb13ab7f2c2a5fe3..14ff159769d7076e4956064bd5759d4e897b4a86 100644 (file)
@@ -47,6 +47,8 @@
 // debugger:print padded_struct.data_ptr[1]
 // check:$13 = {x = 13, y = 14, z = 15}
 
+#[allow(unused_variable)];
+
 struct AStruct {
     x: i16,
     y: i32,
index 57130b45eae303be66e0f13aee07517150ff46fb..8387214b3bc62f75c55fc06b37c9ba8b473cf0b0 100644 (file)
@@ -18,6 +18,8 @@
 // debugger:print a
 // check:$1 = {1, 2, 3}
 
+#[allow(unused_variable)];
+
 fn main() {
     let a = [1, 2, 3];
 
index 9e6f053e4c2b9013b660438b953acbc711cdf5d6..c0f173a1a0d6a751d16c7bd7993aa1bbc58b481c 100644 (file)
@@ -8,5 +8,5 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn blk1(b: &fn()) -> @fn() { return || { }; }
+fn blk1(_b: &fn()) -> @fn() { return || { }; }
 fn test1() { (do blk1 { info!("hi"); })(); }
index a6266c6a5dd28c9f6611346a322738af94232372..f6787fa9c3d21a7aa7d67e6e0dbdabf397376cd4 100644 (file)
@@ -16,5 +16,5 @@
 
 fn id(f: &fn() -> int) -> int { f() }
 
-fn wsucc(n: int) -> int { (do id || { 1 }) - 0 }
+fn wsucc(_n: int) -> int { (do id || { 1 }) - 0 }
 fn main() { }
index b1f7828a2f425fd7368c42e6816c21508db3ea1e..0545e9ed166f26fb1f48350d602606b67989f804 100644 (file)
@@ -10,8 +10,8 @@
 
 // pp-exact
 
-fn from_foreign_fn(x: extern "Rust" fn()) { }
-fn from_stack_closure(x: &fn()) { }
-fn from_box_closure(x: @fn()) { }
-fn from_unique_closure(x: ~fn()) { }
+fn from_foreign_fn(_x: extern "Rust" fn()) { }
+fn from_stack_closure(_x: &fn()) { }
+fn from_box_closure(_x: @fn()) { }
+fn from_unique_closure(_x: ~fn()) { }
 fn main() { }
index 6b4e6a30d87f447ff4a61b6868146ec65a516e37..2318e783b69473ea6c09e2ee87b5941f5412275f 100644 (file)
 
 // pp-exact
 
-fn f(v: &[int]) {
+fn f(v: &[int]) -> int {
     let mut n = 0;
     for e in v.iter() {
         n = *e; // This comment once triggered pretty printer bug
     }
+
+    n
 }
index 66ad3d558201d27b027281233367e6d3251be3f1..75b42e8e59042ed9dda4568104f2520c85c519fd 100644 (file)
 
 fn main() {
     let x = Some(3);
-    let y =
+    let _y =
         match x {
             Some(_) =>
-            ~"some" + ~"very" + ~"very" + ~"very" + ~"very" + ~"very" +
-                ~"very" + ~"very" + ~"very" + ~"long" + ~"string",
+            ~"some" + "very" + "very" + "very" + "very" + "very" + "very" +
+                "very" + "very" + "long" + "string",
             None => ~"none"
         };
 }
index 15c49cd41157e180e3699459fbb3fb9e17c41f52..ac5ef5fcf5328333a78684b7ac940a4798d5d57f 100644 (file)
@@ -12,5 +12,5 @@
 
 fn main() {
     let x = Some(3);
-    let y = match x { Some(_) => ~"some(_)", None => ~"none" };
+    let _y = match x { Some(_) => ~"some(_)", None => ~"none" };
 }
index 0d54848a4a962016de32cbfa350da06967aa7535..20d1678ee4153324cc773bc56f34319fc29e977d 100644 (file)
@@ -5,6 +5,6 @@
 fn main() {
     struct Foo2;
     struct Bar2(int, int, int);
-    let a = Bar(5, 5);
-    let b = Foo;
+    let _a = Bar(5, 5);
+    let _b = Foo;
 }
index c41a4fd8e1da928c972a503ea5363a581209f602..a09e341a9402fb1c6265b0a7490a214e8a64fce2 100644 (file)
@@ -12,7 +12,7 @@
 // Testing that comments are correctly interleaved
 // pp-exact:vec-comments.pp
 fn main() {
-    let v1 =
+    let _v1 =
         ~[
           // Comment
           0,
@@ -20,11 +20,11 @@ fn main() {
           1,
           // Comment
           2];
-    let v2 =
+    let _v2 =
         ~[0, // Comment
           1, // Comment
           2]; // Comment
-    let v3 =
+    let _v3 =
         ~[
           /* Comment */
           0,
@@ -32,7 +32,7 @@ fn main() {
           1,
           /* Comment */
           2];
-    let v4 =
+    let _v4 =
         ~[0, /* Comment */
           1, /* Comment */
           2]; /* Comment */
index c41a4fd8e1da928c972a503ea5363a581209f602..a09e341a9402fb1c6265b0a7490a214e8a64fce2 100644 (file)
@@ -12,7 +12,7 @@
 // Testing that comments are correctly interleaved
 // pp-exact:vec-comments.pp
 fn main() {
-    let v1 =
+    let _v1 =
         ~[
           // Comment
           0,
@@ -20,11 +20,11 @@ fn main() {
           1,
           // Comment
           2];
-    let v2 =
+    let _v2 =
         ~[0, // Comment
           1, // Comment
           2]; // Comment
-    let v3 =
+    let _v3 =
         ~[
           /* Comment */
           0,
@@ -32,7 +32,7 @@ fn main() {
           1,
           /* Comment */
           2];
-    let v4 =
+    let _v4 =
         ~[0, /* Comment */
           1, /* Comment */
           2]; /* Comment */
index c0183bd9f2a752d5cfe2f5720542f6e485010fd1..d84f43d70050c4e75e6240dc94be7d83ad75883e 100644 (file)
@@ -10,6 +10,6 @@
 
 // pp-exact:vec-type.pp
 
-fn f1(x: ~[int]) { }
+fn f1(_x: ~[int]) { }
 
 fn g1() { f1(~[1, 2, 3]); }
index c0183bd9f2a752d5cfe2f5720542f6e485010fd1..d84f43d70050c4e75e6240dc94be7d83ad75883e 100644 (file)
@@ -10,6 +10,6 @@
 
 // pp-exact:vec-type.pp
 
-fn f1(x: ~[int]) { }
+fn f1(_x: ~[int]) { }
 
 fn g1() { f1(~[1, 2, 3]); }
index 911409b6898a3fb2a364705c938f32a6ff55049c..b803d7488b073aac578daa31b7a460c54a37f853 100644 (file)
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 // error-pattern:meep
-fn f(a: int, b: int, c: @int) { fail!("moop"); }
+fn f(_a: int, _b: int, _c: @int) { fail!("moop"); }
 
 fn main() { f(1, fail!("meep"), @42); }
index 2d3e7dd616d331fc99cb5d137da6a43ba6090331..6e15f6edddc8976b8857b0c4041a7f8e4b557268 100644 (file)
@@ -14,7 +14,7 @@ fn main() {
     let c = @mut b;
 
     // this should freeze `a` only
-    let x: &mut [int] = c[0];
+    let _x: &mut [int] = c[0];
 
     // hence this should fail
     a[0] = a[0];
index 59a5fecd3400368ba4878d8620763fd48201734f..24b928920c2b88ab07d545f7f9d4bcc7ca803e96 100644 (file)
@@ -9,7 +9,7 @@ struct S {
 
 fn main() {
     let x = @mut S { x: 3 };
-    let y: &S = x;
+    let _y: &S = x;
     let z = x;
     z.x = 5;
 }
index a40faa1ac6fc3dfa5c2e0d7832e4291d5aa07feb..8a72d2680d92f159165880ffecb615e601010b92 100644 (file)
@@ -5,7 +5,7 @@
 
 fn main() {
     let x = @mut 3;
-    let y: &mut int = x;
+    let _y: &mut int = x;
     let z = x;
     *z = 5;
 }
index c70d752ef303339bc735bcd700bfa50facc76fbf..1456f13733872cdd878f2f13c7356516137fe1dc 100644 (file)
@@ -10,7 +10,7 @@ fn foo(&self, x: @mut int) {
     }
 }
 
-fn it_takes_two(f: &Foo, g: &mut Foo) {
+fn it_takes_two(_f: &Foo, _g: &mut Foo) {
 }
 
 fn main() {
index e2c8a0b549c362efc821d663fa77e519b7714a07..fa82029855d70d4b81c6d61a184e6e442407bad3 100644 (file)
@@ -14,6 +14,6 @@ fn add2(_:&mut int)
 pub fn main()
 {
     let a = @mut 3;
-    let b = &*a; // freezes a
+    let _b = &*a; // freezes a
     add1(a);
 }
index 58b2a1d87beed70adad9d49e4bd845683b2372f0..9d6b95871133200bfee0615b41da30fb663e2fca 100644 (file)
@@ -14,6 +14,6 @@ fn add2(_:&int)
 pub fn main()
 {
     let a = @mut 3;
-    let b = &mut *a; // freezes a
+    let _b = &mut *a; // freezes a
     add1(a);
 }
index 992747187f6353e476451517af9b6b9301847fe7..2a256b9a4e384d8310e6b53d52b7033b41fb4b88 100644 (file)
@@ -19,6 +19,6 @@ struct chan_t<T> {
     port: port_id,
 }
 
-fn send<T:Send>(ch: chan_t<T>, data: T) { fail!(); }
+fn send<T:Send>(_ch: chan_t<T>, _data: T) { fail!(); }
 
 fn main() { fail!("quux"); }
index cf6f5a009d530abaa008b9d9f7c84075f571aac8..8ff62d5a43d108293327d964e90f8b95a6e9927a 100644 (file)
@@ -1,5 +1,5 @@
 // error-pattern:test
 
 fn main() {
-    let i: int = fail!("test");
+    let _i: int = fail!("test");
 }
index 9c996807ad8668e1fdf8e9cc87aac5c174b77da6..de69b7b9fa6705ed03afd7c07abd96ef49415334 100644 (file)
@@ -11,5 +11,5 @@
 // error-pattern:attempted to divide by zero
 fn main() {
     let y = 0;
-    let z = 1 / y;
+    let _z = 1 / y;
 }
index ccf7aa5701908b45e9c49aa0bdb153d40b3ed203..1ceeee1b6ed11a8520a0ed5ec104ada159e2e3b0 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(unreachable_code)];
+
 //error-pattern:One
 fn main() {
     fail!("One");
index 28fd9aff009b7f479a9e55fe4ec443747354b39a..ab8cea0a3051a3bc02520ec6bcf9b442ab628f91 100644 (file)
@@ -8,7 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(dead_assignment)];
+#[allow(unused_variable)];
+
 // error-pattern:wooooo
 fn main() {
-    let mut a = 1; if 1 == 1 { a = 2; } fail!(~"woooo" + "o");
+    let mut a = 1;
+    if 1 == 1 { a = 2; }
+    fail!(~"woooo" + "o");
 }
index c1663866519b77fe15b3ca6493b86fd6cfd8bf90..73259e6e140f549d57664a736d44a8f22ccbe89a 100644 (file)
@@ -12,4 +12,4 @@
 
 
 // error-pattern:explicit failure
-fn main() { let x = if false { 0 } else if true { fail!() } else { 10 }; }
+fn main() { let _x = if false { 0 } else if true { fail!() } else { 10 }; }
index e2bf6052a1038e876d962513187c9c953ac823e0..075f6f5b4b1908286d50cac779bb9876bf0b4a94 100644 (file)
@@ -12,4 +12,4 @@
 
 
 // error-pattern:explicit failure
-fn main() { let x = match true { false => { 0 } true => { fail!() } }; }
+fn main() { let _x = match true { false => { 0 } true => { fail!() } }; }
index a65db3ee51543db658e8db9dc155658e0a491f1c..ce5ea56502cc7bb1bdefe63bfb41958110e3001b 100644 (file)
@@ -35,7 +35,7 @@ pub fn rust_dbg_call(cb: *u8, data: libc::uintptr_t)
 
 fn count(n: uint) -> uint {
     unsafe {
-        task::yield();
+        task::deschedule();
         rustrt::rust_dbg_call(cb, n)
     }
 }
index 0e0bd81d659ace57deac2dfb339674e283d0e0a2..863663334f8ed444fda789b0d78c842c83dc31d7 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(unnecessary_allocation)];
+
 // error-pattern:explicit failure
 // Don't double free the string
 extern mod extra;
index 5e7c7cf519b05f2ce09fca6cb8ad5ee2e811b8f2..c1357988f7db59d0a8e58ac3367a1be2c969cd56 100644 (file)
@@ -18,5 +18,5 @@ enum e<T> { e(arc::Arc<T>) }
 fn foo() -> e<int> {fail!();}
 
 fn main() {
-   let f = foo();
+   let _f = foo();
 }
index caee00027883a58eb1088de5bf59e7183caca97e..44364007c067e80b44776c094fd36129cee787ff 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(unnecessary_allocation)];
+#[allow(unreachable_code)];
+#[allow(unused_variable)];
+
 // error-pattern:so long
 fn main() {
     let mut x = ~[];
index 1ad4422e1a943ac37407a9545b683e51f23cb999..db954bc59466ac5f8d7cdda590506f0bcb3c3293 100644 (file)
@@ -10,6 +10,8 @@
 
 // error-pattern:beep boop
 
+#[allow(unused_variable)];
+
 struct Point { x: int, y: int }
 
 fn main() {
index d4049f6753ee89204fd75c57be84b2dc9eac15c5..52a67872d4cffba35f640d1f5f7670ddd1fff922 100644 (file)
@@ -21,5 +21,5 @@
 fn main() {
     let (p, _c) = comm::stream::<()>();
     task::spawn(|| child() );
-    task::yield();
+    task::deschedule();
 }
index 2ba78e21374eaf77a5f390687a8edb898c716497..a54422ef8f535c4e6e9925c7c1cf1ff6d10b6a6b 100644 (file)
@@ -10,6 +10,9 @@
 
 // error-pattern:explicit failure
 
+#[allow(unreachable_code)];
+#[allow(unused_variable)];
+
 fn foo(s: ~str) { }
 
 fn main() {
index b3e083c77fb2350839f290820914a01b09a76c38..76d4de7ecb03ce907b987c4e16e705a4dc36373e 100644 (file)
@@ -11,5 +11,5 @@
 // error-pattern:attempted remainder with a divisor of zero
 fn main() {
     let y = 0;
-    let z = 1 % y;
+    let _z = 1 % y;
 }
index 444c899188fadd8424b5acd2f176cc3b6262ff68..ca267608025c30b0c8af8a2e32213a658a693115 100644 (file)
 // as a _|_-typed thing, not a str-typed thing
 // error-pattern:bye
 
+#[allow(unreachable_code)];
+#[allow(unused_variable)];
+
 struct T { t: ~str }
 
-fn main() { let pth = fail!("bye"); let rs: T = T {t: pth}; }
+fn main() {
+    let pth = fail!("bye");
+    let _rs: T = T {t: pth};
+}
index ee268f409a5e950fe58c0980822c2229b6972fff..d78dedfa39dc011f32096cde33f863eaaf02ccf9 100644 (file)
@@ -35,7 +35,7 @@ fn r(x:int) -> r {
 fn main() {
     error!(~"whatever");
     do task::spawn {
-      let i = r(5);
+      let _i = r(5);
     };
     fail!();
 }
index bd51ce38ec0e47bc03d38444eebc5d5437d1ec6a..fb2d90e99cf194d0411e2e8c6b6425ba9fe573b3 100644 (file)
@@ -15,7 +15,7 @@
 use std::task;
 
 fn goodfail() {
-    task::yield();
+    task::deschedule();
     fail!("goodfail");
 }
 
index 6e1af6ff7e095c184906c412e6a50d5d7413cbe6..75b50c4f6ed6fa3f95fdecbc867cf847482b5fa1 100644 (file)
@@ -10,7 +10,6 @@
 
 // error-pattern:Ensure that the child task runs by failing
 
-use std::str;
 use std::task;
 
 fn main() {
index 0e685a7a4693d13bac763f4dddcae5f880d72231..36954d2bad67e02d8b15ad8acf11de22748b5e33 100644 (file)
@@ -11,6 +11,6 @@
 // error-pattern:fail
 
 fn main() {
-    let a = @0;
+    let _a = @0;
     assert!(false);
 }
index b84ae2e94fcea48f2aa8a0b5bf03a35a281ee3f2..5ea71c94e14685b09b09d49fbb034309edf1f87d 100644 (file)
@@ -10,7 +10,7 @@
 
 // error-pattern:fail
 
-fn f(a: @int) {
+fn f(_a: @int) {
     fail!();
 }
 
index e7f8a866543105a4d2fb67760a5be1c2f764f594..fd1ab88ff964704ddb1626afaf6cbc436ef759af 100644 (file)
@@ -13,5 +13,5 @@
 fn f() -> @int { fail!(); }
 
 fn main() {
-    let a: @int = f();
+    let _a: @int = f();
 }
index 0293e5ba07e594a9a93ee26fafcb46058f7b8844..0d1584f3dc8dbaa82e8c684abd2787dfc47bb59c 100644 (file)
@@ -11,7 +11,7 @@
 // error-pattern:fail
 
 fn main() {
-    let a: @int = {
+    let _a: @int = {
         fail!();
     };
 }
index 142813bcc30b71b61d523a39b7e6463c77613049..365204d5c9e4d13d5c61d63dce2cad213979ea55 100644 (file)
@@ -15,8 +15,8 @@ fn a() { }
 fn b() { fail!(); }
 
 fn main() {
-    let x = ~[0];
+    let _x = ~[0];
     a();
-    let y = ~[0];
+    let _y = ~[0];
     b();
 }
index 1b28d2f6c6d63ee9d9eab7069020c83eb4833b74..51c6cb3adf318cc137df1099e0b9d92ad54cfc58 100644 (file)
@@ -10,6 +10,9 @@
 
 // error-pattern:fail
 
+#[allow(unreachable_code)];
+#[allow(unused_variable)];
+
 fn x(it: &fn(int)) {
     fail!();
     it(0);
index 286e5f4976430cf93c178f32790d99d742085762..17936df6959f2bb0423f3f32939e9f469cc9c204 100644 (file)
@@ -11,7 +11,7 @@
 // error-pattern:fail
 
 fn x(it: &fn(int)) {
-    let a = @0;
+    let _a = @0;
     it(1);
 }
 
index 640be6635ee293181b462a26d675f24e3c21ea1d..74d6ab00802e0e8a84e4b5d371bac80e1e260fc2 100644 (file)
@@ -21,7 +21,7 @@ fn main() {
         let mush = food + cheese;
         let cheese = cheese.clone();
         let f: &fn() = || {
-            let chew = mush + cheese;
+            let _chew = mush + cheese;
             fail!("so yummy")
         };
         f();
index 336c2d3c8ea70ce548f3067b709ecdaa72899f62..d215927c7d03fc28dbccf1caccd68878e0e2ecb4 100644 (file)
 // error-pattern:fail
 
 fn main() {
-    let count = @mut 0u;
+    let _count = @mut 0u;
     let mut map = std::hashmap::HashMap::new();
     let mut arr = ~[];
-    for i in range(0u, 10u) {
+    for _i in range(0u, 10u) {
         arr.push(@~"key stuff");
         map.insert(arr.clone(), arr + &[@~"value stuff"]);
         if arr.len() == 5 {
index ca9a761cfa1e1745278b5c03a665b8046382193a..f8a63be2e9ad0d127e7babc932bfbe44799a87c1 100644 (file)
@@ -11,9 +11,9 @@
 // error-pattern:fail
 
 fn main() {
-    let a = @0;
+    let _a = @0;
     {
-        let b = @0;
+        let _b = @0;
         {
             fail!();
         }
index d1e3b63698bc5f97efef028a42105cd12a2b6453..88f71a5ed7ceaafbe25af922d2100ce6b3a2ba4b 100644 (file)
@@ -19,7 +19,7 @@ fn prime() {
 }
 
 fn partial() {
-    let x = @f();
+    let _x = @f();
 }
 
 fn main() {
index 5976add8800a40706b8b5c433d6cfd2295abb6fc..e9bbbd46c03fffc76e263508253220162e90f49b 100644 (file)
@@ -19,7 +19,7 @@ fn prime() {
 }
 
 fn partial() {
-    let x = ~f();
+    let _x = ~f();
 }
 
 fn main() {
index d51c83a06d9c0b95bff0e4577466c7c7a50bf70a..3d6d26937dbacf59e69accfaeb88f02012924ce7 100644 (file)
@@ -19,7 +19,7 @@ fn prime() {
 }
 
 fn partial() {
-    let x = ~[~[0], f(), ~[0]];
+    let _x = ~[~[0], f(), ~[0]];
 }
 
 fn main() {
index 378816476e4ddd26bb0a87c98b6fbe6f42c9e090..016654500b4aca83e5dbd8425c7c6b54d08d4e35 100644 (file)
@@ -17,7 +17,7 @@ fn build() -> ~[int] {
 struct Blk { node: ~[int] }
 
 fn main() {
-    let blk = Blk {
+    let _blk = Blk {
         node: build()
     };
 }
index 1abf6d53600b9e170e9d16926937eb352c4e9a50..49a35181a8b2eb0b36460cd449603460be193e92 100644 (file)
@@ -21,7 +21,7 @@ fn build2() -> ~[int] {
 struct Blk { node: ~[int], span: ~[int] }
 
 fn main() {
-    let blk = Blk {
+    let _blk = Blk {
         node: build1(),
         span: build2()
     };
index b4b0150013a509186fdb2eedd3891f2c7d935f4b..d695caf7b5f974c7e85b55f8e6ba26d9cdb2c2be 100644 (file)
@@ -22,5 +22,5 @@ fn r(i: int) -> r { r { i: i } }
 
 fn main() {
     @0;
-    let r = r(0);
+    let _r = r(0);
 }
index a8faa550c8fbe346cd2a93378cfeac16606a16af..8249807af74ad51bfafd45d2989efe1e8d6c153d 100644 (file)
 // error-pattern:fail
 
 fn f() {
-    let a = @0;
+    let _a = @0;
     fail!();
 }
 
 fn g() {
-    let b = @0;
+    let _b = @0;
     f();
 }
 
 fn main() {
-    let a = @0;
+    let _a = @0;
     g();
 }
index b135b9f609b88d8d1c3adbc19193c5390bb69233..15fa3ceed5356a9ab3373d67b61e6df1476afac4 100644 (file)
@@ -15,5 +15,5 @@ fn fold_local() -> @~[int]{
 }
 
 fn main() {
-    let lss = (fold_local(), 0);
+    let _lss = (fold_local(), 0);
 }
index 5e299c52a2905a9697e8e08bddc435380221159c..236ff8172207bbc0a601fa3de41be9ae8662d80e 100644 (file)
@@ -19,5 +19,5 @@ fn fold_remote() -> @~[int]{
 }
 
 fn main() {
-    let lss = (fold_local(), fold_remote());
+    let _lss = (fold_local(), fold_remote());
 }
index e45c5c94ed4b12c0b2b4a1d7a470b0ecf7a3cce8..d5a06ffb9036b915e9084fe152bc10cd124a6052 100644 (file)
@@ -16,5 +16,5 @@ fn f() {
 
 fn main() {
     f();
-    let a = @0;
+    let _a = @0;
 }
index 836ed9c015586ef7caf0efe747db1183735aa5e1..32e1425b28c8af78c2c876ffdc050e799468ddaa 100644 (file)
@@ -8,5 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(while_true)];
+
 // error-pattern:quux
-fn main() { let x: int = { while true { fail!("quux"); } ; 8 } ; }
+fn main() { let _x: int = { while true { fail!("quux"); } ; 8 } ; }
index db04026ed9739288991da3e7c46141706b95df2d..a0b437814fd8d46867eac3f9cac8b08c588410b4 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(while_true)];
+
 // error-pattern:giraffe
 fn main() {
     fail!({ while true { fail!("giraffe") }; "clandestine" });
diff --git a/src/test/run-fail/zip-different-lengths.rs b/src/test/run-fail/zip-different-lengths.rs
deleted file mode 100644 (file)
index f31fea5..0000000
+++ /dev/null
@@ -1,44 +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.
-
-// In this case, the code should compile but
-// the assert should fail at runtime
-// error-pattern:assertion failed
-extern mod extra;
-use std::vec::{same_length, zip};
-
-fn enum_chars(start: u8, end: u8) -> ~[char] {
-    assert!(start < end);
-    let mut i = start;
-    let mut r = ~[];
-    while i <= end { r.push(i as char); i += 1 as u8; }
-    return r;
-}
-
-fn enum_uints(start: uint, end: uint) -> ~[uint] {
-    assert!(start < end);
-    let mut i = start;
-    let mut r = ~[];
-    while i <= end { r.push(i); i += 1; }
-    return r;
-}
-
-fn main() {
-    let a = 'a' as u8;
-    let j = 'j' as u8;
-    let k = 1;
-    let l = 9;
-    let chars = enum_chars(a, j);
-    let ints = enum_uints(k, l);
-
-    assert!(same_length(chars, ints));
-    let ps = zip(chars, ints);
-    fail!("the impossible happened");
-}
index 4ab3b8ea65a40ce435664561a756832dc3c1c98a..8951eff2fb9bd684636d316ed9672ec7fafe5225 100644 (file)
@@ -54,9 +54,9 @@ fn mk_ctxt() -> fake_ext_ctxt {
 
 
 fn main() {
-    let ext_cx = mk_ctxt();
-    let s = quote_expr!(__s);
-    let e = quote_expr!(__e);
-    let f = quote_expr!($s.foo {|__e| $e});
+    let cx = mk_ctxt();
+    let s = quote_expr!(cx, __s);
+    let e = quote_expr!(cx, __e);
+    let f = quote_expr!(cx, $s.foo {|__e| $e});
     log(error, pprust::expr_to_str(f));
 }
index ce5225055e2e173706d61f6ef76c2d2c03f59272..c39c32753679bc2afa69e875bc0f98b1751b1a9e 100644 (file)
@@ -52,22 +52,22 @@ fn mk_ctxt() -> fake_ext_ctxt {
 }
 
 fn main() {
-    let ext_cx = mk_ctxt();
+    let cx = mk_ctxt();
 
-    let abc = quote_expr!(23);
+    let abc = quote_expr!(cx, 23);
     check_pp(ext_cx, abc,  pprust::print_expr, ~"23");
 
 
-    let ty = quote_ty!(int);
+    let ty = quote_ty!(cx, int);
     check_pp(ext_cx, ty, pprust::print_type, ~"int");
 
-    let item = quote_item!(static x : int = 10;).get();
+    let item = quote_item!(cx, static x : int = 10;).get();
     check_pp(ext_cx, item, pprust::print_item, ~"static x: int = 10;");
 
-    let stmt = quote_stmt!(let x = 20;);
+    let stmt = quote_stmt!(cx, let x = 20;);
     check_pp(ext_cx, *stmt, pprust::print_stmt, ~"let x = 20;");
 
-    let pat = quote_pat!(Some(_));
+    let pat = quote_pat!(cx, Some(_));
     check_pp(ext_cx, pat, pprust::print_pat, ~"Some(_)");
 
 }
index 0a929e2d128180073b43343fc573aff52bc1edf0..62ce4e7c02c0901e984c949aaf7048b91fcabc35 100644 (file)
 
 use syntax::ext::base::ExtCtxt;
 
-fn syntax_extension(ext_cx: @ExtCtxt) {
-    let e_toks : ~[syntax::ast::token_tree] = quote_tokens!(1 + 2);
-    let p_toks : ~[syntax::ast::token_tree] = quote_tokens!((x, 1 .. 4, *));
+fn syntax_extension(cx: @ExtCtxt) {
+    let e_toks : ~[syntax::ast::token_tree] = quote_tokens!(cx, 1 + 2);
+    let p_toks : ~[syntax::ast::token_tree] = quote_tokens!(cx, (x, 1 .. 4, *));
 
-    let a: @syntax::ast::expr = quote_expr!(1 + 2);
-    let _b: Option<@syntax::ast::item> = quote_item!( static foo : int = $e_toks; );
-    let _c: @syntax::ast::pat = quote_pat!( (x, 1 .. 4, *) );
-    let _d: @syntax::ast::stmt = quote_stmt!( let x = $a; );
-    let _e: @syntax::ast::expr = quote_expr!( match foo { $p_toks => 10 } );
+    let a: @syntax::ast::expr = quote_expr!(cx, 1 + 2);
+    let _b: Option<@syntax::ast::item> = quote_item!(cx, static foo : int = $e_toks; );
+    let _c: @syntax::ast::pat = quote_pat!(cx, (x, 1 .. 4, *) );
+    let _d: @syntax::ast::stmt = quote_stmt!(cx, let x = $a; );
+    let _e: @syntax::ast::expr = quote_expr!(cx, match foo { $p_toks => 10 } );
 }
 
 fn main() {
index 3f1bd83046241bd4c5d9fe298887e1cb5fed214e..1a2c22889fd82d680fc6a993f9077c7ee0f16f7c 100644 (file)
@@ -14,6 +14,7 @@
 
 use anonexternmod::*;
 
+#[fixed_stack_segment]
 pub fn main() {
     unsafe {
         rust_get_test_int();
index b305007d8d24844be061292c9682bc417d26092b..ed9caa1f65e2f52223ea868d95d5d7ac54a7ba3c 100644 (file)
@@ -16,6 +16,7 @@
     fn rust_get_test_int() -> libc::intptr_t;
 }
 
+#[fixed_stack_segment]
 pub fn main() {
     unsafe {
         let _ = rust_get_test_int();
index 90a17625195739eb4b16b07147b537a74e4522e6..6d6ae3da62fef1b599524d7be3e24bdcc865b2a2 100644 (file)
@@ -26,10 +26,10 @@ fn f1(a: &mut X, b: &mut int, c: int) -> int {
 pub fn main() {
     let mut a = X {x: 1};
     let mut b = 2;
-    let mut c = 3;
+    let c = 3;
     assert_eq!(f1(&mut a, &mut b, c), 6);
     assert_eq!(a.x, 0);
     assert_eq!(b, 10);
-    assert_eq!(f2(a.x, |x| a.x = 50), 0);
+    assert_eq!(f2(a.x, |_| a.x = 50), 0);
     assert_eq!(a.x, 50);
 }
index 0eb4e7ad92e784c6d147c4ada91061f9e691e750..ae94ad379d01257d34ba66da107911fcd4389cf0 100644 (file)
@@ -8,8 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-
+#[allow(type_limits)];
 
 // Unsigned integer operations
 pub fn main() {
index 5fe2aa6cc7c0eb7b3da129eac759356db5cc38b6..0f5d27015fb747a7709a6b3b908eeccf5a11eecb 100644 (file)
 // Issue 483 - Assignment expressions result in nil
 fn test_assign() {
     let mut x: int;
-    let mut y: () = x = 10;
+    let y: () = x = 10;
     assert_eq!(x, 10);
+    assert_eq!(y, ());
     let mut z = x = 11;
     assert_eq!(x, 11);
+    assert_eq!(z, ());
     z = x = 12;
     assert_eq!(x, 12);
+    assert_eq!(z, ());
 }
 
 fn test_assign_op() {
     let mut x: int = 0;
-    let mut y: () = x += 10;
+    let y: () = x += 10;
     assert_eq!(x, 10);
+    assert_eq!(y, ());
     let mut z = x += 11;
     assert_eq!(x, 21);
+    assert_eq!(z, ());
     z = x += 12;
     assert_eq!(x, 33);
+    assert_eq!(z, ());
 }
 
 pub fn main() { test_assign(); test_assign_op(); }
index 933405bfc448d45fcfa8d23412084f260175a888..ba54e92ef997805472e7de6228546b7d4235ff56 100644 (file)
@@ -11,6 +11,6 @@
 //xfail-fast
 
 #[start]
-fn start(argc:int, argv: **u8, crate_map: *u8) -> int {
+fn start(_argc: int, _argv: **u8, _crate_map: *u8) -> int {
     return 0;
 }
index 9d808d19af2e9d9bcd3c45e751032a59c4d58fc1..a7a4aa9885e6e89f5bd6b8cb43dc9ac103dbfdf1 100644 (file)
@@ -11,7 +11,7 @@
 // xfail-fast
 extern mod extra;
 use extra::arc;
-fn dispose(_x: arc::Arc<bool>) { unsafe { } }
+fn dispose(_x: arc::Arc<bool>) { }
 
 pub fn main() {
     let p = arc::Arc::new(true);
index 4bfdb20d9f2b9f2884ab3e6cde5e826bda1c9b4e..eb0f04b8b7da1b37d43903128a255657963600a5 100644 (file)
@@ -10,8 +10,6 @@
 
 // Binop corner cases
 
-use std::libc;
-
 fn test_nil() {
     assert_eq!((), ());
     assert!((!(() != ())));
@@ -95,7 +93,7 @@ fn p(x: int, y: int) -> p {
 }
 
 fn test_class() {
-  let mut q = p(1, 2);
+  let q = p(1, 2);
   let mut r = p(1, 2);
 
   unsafe {
index 4bff3c6bb64e635c648d634f1ec1ee4383d34f20..fcd6a8d7c85e5fd1b6403e597a41d8fa7986b206 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::vec;
-
 fn w_semi(v: ~[int]) -> int {
     // the semicolon causes compiler not to
     // complain about the ignored return value:
index aabc005c57fb3af900b02214dcccb8761f8068ed..717093e9de7043aca2c67e5afe6f4b87aaba2961 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::vec;
-
 // Check usage and precedence of block arguments in expressions:
 pub fn main() {
     let v = ~[-1f, 0f, 1f, 2f, 3f];
index 20c9032fbd294a0757dd301881a49eb0bf881823..633e0f71b9e0b24ece778a5d1f92d15d55dc7c37 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::uint;
 use std::util;
 
 struct Ints {sum: ~int, values: ~[int]}
index d7551f792f3b79ad88d2d3b62570ca20cbd7c9ec..4ccbf6b5b0fedfb65a0a91ca3dc823a732917b90 100644 (file)
@@ -18,4 +18,5 @@ pub fn main() {
       }
       Some(_) => { }
     }
+    assert_eq!(x, Some(0));
 }
index 47bc6344bc2715f8dab428872c9e0e5444405a6f..a8e14b5297ff144f39c6c864d88c25e7862ad9ef 100644 (file)
@@ -13,9 +13,9 @@
 pub fn main() {
     let x: @mut @Option<~int> = @mut @None;
     match x {
-      @@Some(ref y) => {
+      @@Some(ref _y) => {
         // here, the refcount of `*x` is bumped so
-        // `y` remains valid even if `*x` is modified.
+        // `_y` remains valid even if `*x` is modified.
         *x = @None;
       }
       @@None => {
index 8fad933281118b8d470449169a4b43453a3e8406..c53b4b4e747d59e1b08646b6687efc7509ae8afb 100644 (file)
@@ -15,7 +15,7 @@
 struct F { f: ~int }
 
 pub fn main() {
-    let mut x = @mut @F {f: ~3};
+    let x = @mut @F {f: ~3};
     match x {
       @@F{f: ref b_x} => {
         assert_eq!(**b_x, 3);
index e3f8f98f4b6b1fdb1bb130a7e79b62838ccee0f6..3f3534ca43e27c32d6f06e1666dc5f49b91278a3 100644 (file)
 fn switcher(x: Option<@int>) {
     let mut x = x;
     match x {
-      Some(@y) => { y.clone(); x = None; }
-      None => { }
+        Some(@y) => { y.clone(); x = None; }
+        None => { }
     }
+    assert_eq!(x, None);
 }
 
 pub fn main() {
index e5cef1dbc059961acf94cfb6c7e5a1e25887a830..dc3718275fce9f3ab29dab9436e3978e65f3e9d1 100644 (file)
@@ -15,8 +15,8 @@ fn testfn(cond: bool) {
     let mut y = @4;
 
     // borrow x and y
-    let mut r_x = &*x;
-    let mut r_y = &*y;
+    let r_x = &*x;
+    let r_y = &*y;
     let mut r = r_x;
     let mut exp = 3;
 
@@ -33,6 +33,8 @@ fn testfn(cond: bool) {
 
     info!("*r = %d, exp = %d", *r, exp);
     assert_eq!(*r, exp);
+    assert_eq!(x, @5);
+    assert_eq!(y, @6);
 }
 
 pub fn main() {
index 22857aaefec5a8d37267f8ef457cf66e11e16a1a..315b69f3f2752a82bf6211a83c7c7adccbe5efd4 100644 (file)
@@ -8,4 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub fn main() { let i: (@int, int) = (@10, 10); let (a, _) = i; }
+pub fn main() {
+    let i: (@int, int) = (@10, 10);
+    let (_a, _) = i;
+}
index e9838ec17aeeb9bafda17b62251e9dc76947d18c..ea2b7d58a1112c136f2a1ee2c68a1d4bc9a0cf58 100644 (file)
 
 fn some_box(x: int) -> @int { return @x; }
 
-fn is_odd(n: int) -> bool { return true; }
+fn is_odd(_n: int) -> bool { return true; }
 
-fn length_is_even(vs: @int) -> bool { return true; }
+fn length_is_even(_vs: @int) -> bool { return true; }
 
-fn foo(acc: int, n: int) {
+fn foo(_acc: int, n: int) {
     if is_odd(n) && length_is_even(some_box(1)) { error!("bloop"); }
 }
 
index bcadc69bb0a2e94a4bc2bdbf2228eb424f26d86e..53b468470609156db30b8914b0f2a629abf2eb07 100644 (file)
 
 fn some_box(x: int) -> @int { return @x; }
 
-fn is_odd(n: int) -> bool { return true; }
+fn is_odd(_n: int) -> bool { return true; }
 
-fn length_is_even(vs: @int) -> bool { return true; }
+fn length_is_even(_vs: @int) -> bool { return true; }
 
-fn foo(acc: int, n: int) {
+fn foo(_acc: int, n: int) {
     if is_odd(n) || length_is_even(some_box(1)) { error!("bloop"); }
 }
 
index aff4b7bd26e0533b4fb4cc51bfdb4de5d4265b4a..5903e421465008af68bce0c980387fbcf318932b 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::vec;
-
 pub fn main() {
     let mut i = 0;
     while i < 20 { i += 1; if i == 10 { break; } }
index 85e22cfecb4286e287be8146243bd0d81de7d7b1..ac7b221cff81c181a9c2635ee9aba774c7e723e7 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::libc;
-
 mod rustrt {
     use std::libc;
 
@@ -20,7 +18,5 @@ mod rustrt {
 }
 
 pub fn main() {
-    unsafe {
-        let _foo = rustrt::rust_get_test_int;
-    }
+    let _foo = rustrt::rust_get_test_int;
 }
index e91c11f5cd0a703eea86f5080aec6051d1c52bf9..f140c4621aa27319cec5be3f064514d951d4b2b1 100644 (file)
@@ -8,29 +8,28 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::str;
-
 mod libc {
+    use std::libc::{c_char, c_long, c_longlong};
+
     #[abi = "cdecl"]
     #[nolink]
     extern {
-        pub fn atol(x: *u8) -> int;
-        pub fn atoll(x: *u8) -> i64;
+        pub fn atol(x: *c_char) -> c_long;
+        pub fn atoll(x: *c_char) -> c_longlong;
     }
 }
 
+#[fixed_stack_segment]
 fn atol(s: ~str) -> int {
-    s.to_c_str().with_ref(|x| unsafe { libc::atol(x as *u8) })
+    s.with_c_str(|x| unsafe { libc::atol(x) as int })
 }
 
+#[fixed_stack_segment]
 fn atoll(s: ~str) -> i64 {
-    s.to_c_str().with_ref(|x| unsafe { libc::atoll(x as *u8) })
+    s.with_c_str(|x| unsafe { libc::atoll(x) as i64 })
 }
 
 pub fn main() {
-    unsafe {
-        assert_eq!(atol(~"1024") * 10, atol(~"10240"));
-        assert!((atoll(~"11111111111111111") * 10i64)
-            == atoll(~"111111111111111110"));
-    }
+    assert_eq!(atol(~"1024") * 10, atol(~"10240"));
+    assert!((atoll(~"11111111111111111") * 10) == atoll(~"111111111111111110"));
 }
index 6182ec79a3ba92281b2a105039abadf08e6e252f..edd1a9cce65b4298d3480616340fb8f1eba84791 100644 (file)
@@ -24,7 +24,6 @@
 // course preferable, as the value itself is
 // irrelevant).
 
-use std::comm::*;
 use std::task;
 
 fn foo(x: ()) -> Port<()> {
index 4db0b1871d078d9d370cc8c0673df9f3e1961a1c..50afcac4e3ab3d95dd3050835ed3f53241ce7a49 100644 (file)
@@ -16,7 +16,7 @@
 pub fn main() {
     //let bt0 = sys::rusti::frame_address(1u32);
     //info!("%?", bt0);
-    do cci_iter_lib::iter(~[1, 2, 3]) |i| {
+    do cci_iter_lib::iter([1, 2, 3]) |i| {
         printf!("%d", *i);
         //assert!(bt0 == sys::rusti::frame_address(2u32));
     }
index 9232547dd8bd58996f4fe12d7717d7810181d6dc..233a43188468ffc13f310c728c9c2090b092990b 100644 (file)
@@ -12,8 +12,8 @@
 
 use std::task;
 
-fn child2(s: ~str) { }
+fn child2(_s: ~str) { }
 
 pub fn main() {
-    let x = task::spawn(|| child2(~"hi"));
+    let _x = task::spawn(|| child2(~"hi"));
 }
index a134ffe49fd02f4f1ee2e75808ae0a8c2fbff2c5..dd63d96907760dc1b77b27c7f52102d900100872 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::uint;
-
 trait noisy {
   fn speak(&self) -> int;
 }
@@ -83,7 +81,7 @@ fn cat(in_x : uint, in_y : int, in_name: ~str) -> cat {
 
 
 fn annoy_neighbors(critter: @noisy) {
-    for i in range(0u, 10) { critter.speak(); }
+    for _i in range(0u, 10) { critter.speak(); }
 }
 
 pub fn main() {
index d42c57c3b81a0ed1f2b7d9cfa83494dfa53736b7..01907da38ad9da818df8b0f3b5e1aebf6c02c2af 100644 (file)
@@ -11,8 +11,6 @@
 // xfail-fast
 
 use std::cmp;
-use std::int;
-use std::uint;
 
 enum cat_type { tuxedo, tabby, tortoiseshell }
 
index d4e1d438c94428e59ee13d1af9d842eba796be8b..9443904b46d2143f97908e2cab5685104f3402bd 100644 (file)
@@ -13,8 +13,6 @@
 extern mod cci_class_trait;
 use cci_class_trait::animals::*;
 
-use std::uint;
-
 struct cat {
   priv meows: uint,
 
index a064ce6769b823043e766342e11ad549b8ccb68c..433d7f7a22ff48089fe38ececa8174b57605088e 100644 (file)
@@ -10,8 +10,6 @@
 
 // xfail-fast
 
-use std::uint;
-
 trait noisy {
     fn speak(&mut self);
 }
index c5e37cab2b84a6975ded634cc06f21ccc75187ff..159a100e61aaf9ae335844de3a4d30a927be5d19 100644 (file)
@@ -15,7 +15,7 @@
 
 pub fn main() {
     let mut nyan : cat = cat(52u, 99);
-    let mut kitty = cat(1000u, 2);
+    let kitty = cat(1000u, 2);
     assert_eq!(nyan.how_hungry, 99);
     assert_eq!(kitty.how_hungry, 2);
     nyan.speak();
index fca128b9a97350e86cd18c0f92596fdd98055a6b..f5fa72e4ce5106f27668f0f32023ef5dd3ae618e 100644 (file)
@@ -28,7 +28,7 @@ fn cat(in_x: uint, in_y: int) -> cat {
 
 pub fn main() {
   let mut nyan: cat = cat(52u, 99);
-  let mut kitty = cat(1000u, 2);
+  let kitty = cat(1000u, 2);
   assert_eq!(nyan.how_hungry, 99);
   assert_eq!(kitty.how_hungry, 2);
   nyan.speak();
index fcce5a73cf853f225d0258bb38596a071cedc088..5555125a03b2263bfa3aec2df4028677768743b8 100644 (file)
@@ -52,10 +52,7 @@ fn cat(in_x : uint, in_y : int, in_name: ~str) -> cat {
 
 impl ToStr for cat {
     fn to_str(&self) -> ~str {
-        // FIXME #5384: this unsafe block is to work around purity
-        unsafe {
-            self.name.clone()
-        }
+        self.name.clone()
     }
 }
 
@@ -66,6 +63,6 @@ fn print_out(thing: @ToStr, expected: ~str) {
 }
 
 pub fn main() {
-  let mut nyan : @ToStr = @cat(0u, 2, ~"nyan") as @ToStr;
+  let nyan : @ToStr = @cat(0u, 2, ~"nyan") as @ToStr;
   print_out(nyan, ~"nyan");
 }
index db70d6e3b362cc82912ab12c12ed4682d28bd758..452242dd082af821e0b2ed02abcc232ee3a80cd2 100644 (file)
@@ -21,5 +21,5 @@ fn cat(in_name: ~str) -> cat {
 }
 
 pub fn main() {
-  let nyan = cat(~"nyan");
+  let _nyan = cat(~"nyan");
 }
index 8533add411949adc5cc9d6ce9674cf52023a7419..ab6a8b1597bf673ea9449b5538a104fe11385582 100644 (file)
@@ -28,6 +28,6 @@ fn cat<U>(in_x : uint, in_y : int) -> cat<U> {
 
 
 pub fn main() {
-  let mut _nyan : cat<int> = cat::<int>(52u, 99);
+  let _nyan : cat<int> = cat::<int>(52u, 99);
   //  let mut kitty = cat(1000u, 2);
 }
index e7848f3b960e42bfee3a42d64f362ed1fa63a259..4c7823b4107a05a992898d51f38f79975bf1aed0 100644 (file)
@@ -13,8 +13,6 @@
 extern mod cci_class_4;
 use cci_class_4::kitties::*;
 
-use std::uint;
-
 pub fn main() {
     let mut nyan = cat(0u, 2, ~"nyan");
     nyan.eat();
index f27738cf4216ee17eba5cd0a9a4ced7fd97230a2..6e08a4db14e944baad5400788f40298038312728 100644 (file)
@@ -27,7 +27,7 @@ fn cat(in_x : uint, in_y : int) -> cat {
 
 pub fn main() {
   let mut nyan : cat = cat(52u, 99);
-  let mut kitty = cat(1000u, 2);
+  let kitty = cat(1000u, 2);
   assert_eq!(nyan.how_hungry, 99);
   assert_eq!(kitty.how_hungry, 2);
   nyan.speak();
index 3d2b08d7a851dc1934faefe2890508c42f4a575d..49e8f5c04e36a0e32f43e107e8892f572820f40c 100644 (file)
@@ -22,8 +22,8 @@ fn cat(in_x : uint, in_y : int) -> cat {
 }
 
 pub fn main() {
-  let mut nyan : cat = cat(52u, 99);
-  let mut kitty = cat(1000u, 2);
+  let nyan : cat = cat(52u, 99);
+  let kitty = cat(1000u, 2);
   assert_eq!(nyan.how_hungry, 99);
   assert_eq!(kitty.how_hungry, 2);
 }
index 45375efe9d630a0d7e5e6a04d9fd867e7c66954c..d3b3c0c059178a583a1807be837445b091b51532 100644 (file)
@@ -10,7 +10,6 @@
 
 // xfail-win32
 
-use std::result;
 use std::task;
 
 fn adder(x: @int, y: @int) -> int { return *x + *y; }
index 438c70c6583f4956486cbef66133147e33d86e72..5525062581c1a6676b9caf575e1bebc750872ffe 100644 (file)
@@ -11,6 +11,6 @@ fn foo(speaker: &const SpeechMaker) -> uint {
 }
 
 pub fn main() {
-    let mut lincoln = SpeechMaker {speeches: 22};
+    let lincoln = SpeechMaker {speeches: 22};
     assert_eq!(foo(&const lincoln), 55);
 }
index b0bdfd598fb7937d691ab709af9a4068fc429a82..ac9501a71103a4d568da8d34151c938bd3d36f8d 100644 (file)
@@ -9,12 +9,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::comm::*;
 use std::task;
 
 pub fn main() {
     let (p, ch) = stream();
-    let t = task::spawn(|| child(&ch) );
+    let _t = task::spawn(|| child(&ch) );
     let y = p.recv();
     error!("received");
     error!(y);
index e01c7d32f85c6b8e2690a5118d8bb53640044291..7a085c5d3e2dd3ee1c9226684b00bfdd4fba9dfd 100644 (file)
@@ -16,9 +16,9 @@
 
 fn nothing() { }
 
-fn putstr(s: ~str) { }
+fn putstr(_s: ~str) { }
 
-fn putint(i: int) {
+fn putint(_i: int) {
     let mut i: int = 33;
     while i < 36 { putstr(~"hi"); i = i + 1; }
 }
index fdf8edc5861a4a2370f2866058e10c6c65583bcf..00be4cd26f43a7823f227f6fb182a6ec83d04abf 100644 (file)
@@ -89,8 +89,8 @@ pub fn main() {
     // Exercise some of the configured items in ways that wouldn't be possible
     // if they had the bogus definition
     assert!((b));
-    let x: t = true;
-    let y: tg = bar;
+    let _x: t = true;
+    let _y: tg = bar;
 
     test_in_fn_ctxt();
 }
index 6dca5d60f11114b1fc7952fd6eb8976048466999..b31dcc83428400c7c770aeaf29d44fefc711feb0 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::io;
-
 static x : [int, ..4] = [1,2,3,4];
 static p : int = x[2];
 static y : &'static [int] = &[1,2,3,4];
index c2103a40bfea7025d9ea561b033c690f26e91a31..3e79fad542e16b81d51bfafdd134a99df004acec 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::io;
-
 struct Pair<'self> { a: int, b: &'self int }
 
 static x: &'static int = &10;
index 684111c491730c4ceecb9a1b3434be94350caa48..111fe3870ba3bc0bdffe45909a7da6a374d94625 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 use std::cmp;
-use std::io;
 
 struct foo { a: int, b: int, c: int }
 
index 01ef3284e32f9eabdd94fc144449015de1d8ae11..8a1db762b440c52fe752a389600aae751b3a77fc 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::io;
-
 static x : [int, ..4] = [1,2,3,4];
 static y : &'static [int] = &[1,2,3,4];
 
index 64f9ecc9de220452b788174910f242af36ce3c2f..2551d1a5cfcba32455e421de89a3cae23a37c9b8 100644 (file)
@@ -16,7 +16,6 @@
 // instead of in std.
 
 use std::libc;
-use std::os;
 use std::run::*;
 use std::run;
 use std::str;
index ab08a538723e4505c0206d271b300a8459d48bce..b644d1a8b1f9db95f2bf73997af7e2c9017b0691 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 pub fn main() {
-    let x = ~[
+    let _x = ~[
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
index 01a7792ce8847eaeba85b5bbe4301a426b6e145e..9951531d2d171740bc435991b6033afb14b08e15 100644 (file)
@@ -10,4 +10,7 @@
 
 
 
-pub fn main() { let x: @int = @10; let y: int = *x; }
+pub fn main() {
+    let x: @int = @10;
+    let _y: int = *x;
+}
index f0b2d2ec827bb18cd5167543138746c869fabeb7..b17632e4ee7523fd3fc24a2418c9fea9a347b92a 100644 (file)
@@ -19,7 +19,7 @@ struct Foo {
 }
 
 pub fn main() {
-    use std::hash::{Hash, HashUtil}; // necessary for IterBytes check
+    use std::hash::HashUtil; // necessary for IterBytes check
 
     let a = Foo {bar: 4, baz: -3};
 
index aef671ba757aa6773fefd4e0f25f31aa52f49230..2fa77ee16356bd8682143a0ae771d0ebf667d7af 100644 (file)
@@ -17,7 +17,7 @@ struct Foo {
 }
 
 pub fn main() {
-    use std::hash::{Hash, HashUtil}; // necessary for IterBytes check
+    use std::hash::HashUtil; // necessary for IterBytes check
 
     let a = Foo {bar: 4, baz: -3};
 
index c4f5e2640ee1ded485aca713dc5865e3765de0dc..f08e5f054a9da75651f4def6d7f05aa9217a879c 100644 (file)
@@ -1,9 +1,11 @@
 // Just testing that fail!() type checks in statement or expr
 
+#[allow(unreachable_code)];
+
 fn f() {
     fail!();
 
-    let x: int = fail!();
+    let _x: int = fail!();
 }
 
 pub fn main() {
index b7c97392ec156e5917d62f3856d7c60a6c631d62..485d59da7d4b2af0672bd0e3f959162ade9d5919 100644 (file)
@@ -11,7 +11,7 @@
 // no-reformat
 // Testing various forms of `do` with empty arg lists
 
-fn f(f: &fn() -> bool) -> bool {
+fn f(_f: &fn() -> bool) -> bool {
     true
 }
 
index 2af441993225bcc5fc54a3159f94b32848d27a8b..6aef1f5f9e567b9d984c9303cb536756f08f7834 100644 (file)
@@ -10,9 +10,9 @@
 
 // Testing that we can drop the || in do exprs
 
-fn f(f: @fn() -> bool) -> bool { true }
+fn f(_f: @fn() -> bool) -> bool { true }
 
-fn d(f: @fn()) { }
+fn d(_f: @fn()) { }
 
 pub fn main() {
     do d { }
index 08056f59acd3f3e0bf000bd8fa03781b66824c3a..8a0509c177432d9284720e0ee80781925cf815d5 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn f(f: &fn()) {
+fn f(_f: &fn()) {
 }
 
 fn g() {
index 9f4c354b2bf05e4dc21134b59fe9a462248114ee..c6ea32ba29046a347b252bf335e5616b6158af5b 100644 (file)
@@ -12,7 +12,7 @@ struct Quux {
     bar: int
 }
 
-fn g(i: int) { }
+fn g(_i: int) { }
 fn f(foo: @@Quux) { g(foo.bar); }
 
 pub fn main() { }
index 246306e4c47a14af83151ed436a76b5803c63b20..07a73e0d8a9410d9af183b7a8b034998e05050cf 100644 (file)
@@ -12,4 +12,7 @@
 
 enum t { foo(@int), }
 
-pub fn main() { let tt = foo(@10); match tt { foo(z) => { } } }
+pub fn main() {
+    let tt = foo(@10);
+    match tt { foo(_z) => { } }
+}
index 932da027b70249141688d1cadbb4fb86820f1ae8..afc9e532ad8548e02d3837319a5b07e56b7f704e 100644 (file)
 
 
 // -*- rust -*-
-fn f() -> int { if true { let s: ~str = ~"should not leak"; return 1; } return 0; }
+fn f() -> int {
+    if true {
+        let _s: ~str = ~"should not leak";
+        return 1;
+    }
+    return 0;
+}
 
 pub fn main() { f(); }
index 557a153bce2395ba9e1c5054a37a9052100e1062..cb5a5294acf92d9cf0dc876f33a8b67de09247b3 100644 (file)
@@ -20,5 +20,5 @@ fn drop(&self) {
 }
 
 pub fn main() {
-    let x = S { x: 1 };
+    let _x = S { x: 1 };
 }
index 0ed5a27eb1948d5e2857584c4fcaac9fdaa107c5..35d59770d12e81e6bd8a18aee697d005e97a5af6 100644 (file)
@@ -19,5 +19,5 @@ fn drop(&self) {
 }
 
 pub fn main() {
-    let x: Foo = Foo { x: 3 };
+    let _x: Foo = Foo { x: 3 };
 }
index d7e649a8fb684e57d2ca22af113fead0c5c81678..6c90e011218c4a0a7f854ab891d94c38361694ad 100644 (file)
@@ -8,6 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(unused_mut)];
 
-
-pub fn main() { let mut v: ~[int] = ~[]; }
+pub fn main() { let mut _v: ~[int] = ~[]; }
index c23f02e1bedf726e24775505caafdab449f928c8..58a91d4dbce4bf96ad74be7e43f355d9c9d4742e 100644 (file)
@@ -14,7 +14,7 @@
 
 fn addr_of<T>(ptr: &T) -> uint {
     let ptr = ptr::to_unsafe_ptr(ptr);
-    unsafe { ptr as uint }
+    ptr as uint
 }
 
 fn is_aligned<T>(ptr: &T) -> bool {
index 2c61351cf44a5942342690be4b43938009d4ba05..083e851f9659a7072cb20adfadbf1bcb093520ef 100644 (file)
@@ -19,7 +19,7 @@ pub fn main() {
     test_color(imaginary, -1, ~"imaginary");
 }
 
-fn test_color(color: color, val: int, name: ~str) {
+fn test_color(color: color, val: int, _name: ~str) {
     assert!(color as int == val);
     assert!(color as float == val as float);
 }
index 49823155043f4a9bc3a0a587a85bfa455e32378c..09834269d0b7b74f2becc7fcb4aee59389708edb 100644 (file)
@@ -17,5 +17,5 @@ pub enum Foo {
 }
 
 pub fn main() {
-    let x = a::Bar;
+    let _x = a::Bar;
 }
index a8a0a72dd3cbd185b355f86a7eeb20ebd09b6a00..430823b295073096797ae8489fe988dcfbcd0477 100644 (file)
@@ -1,3 +1,6 @@
+#[allow(dead_assignment)];
+#[allow(unused_variable)];
+
 enum Animal {
     Dog (~str, float),
     Cat { name: ~str, weight: float }
@@ -7,5 +10,5 @@ pub fn main() {
     let mut a: Animal = Dog(~"Cocoa", 37.2);
     a = Cat{ name: ~"Spotty", weight: 2.7 };
     // permuting the fields should work too
-    let c = Cat { weight: 3.1, name: ~"Spreckles" };
+    let _c = Cat { weight: 3.1, name: ~"Spreckles" };
 }
index ae590ad7d1f71c06e038e34cdb000e265ed8a94e..d240e849ad049d8e58acda1826012d35db13f916 100644 (file)
@@ -16,9 +16,9 @@ enum Flopsy {
 static BAR2:uint = BAR;
 
 fn main() {
-    let v = [0, .. Bunny as uint];
-    let v = [0, .. BAR];
-    let v = [0, .. BAR2];
+    let _v = [0, .. Bunny as uint];
+    let _v = [0, .. BAR];
+    let _v = [0, .. BAR2];
     static BAR3:uint = BAR2;
-    let v = [0, .. BAR3];
-}
\ No newline at end of file
+    let _v = [0, .. BAR3];
+}
index 268b6974d7f6cf35572517b25e2f28ef760d5d13..ca2039fedede1abb3e2db049dd0851986d1a58c3 100644 (file)
@@ -12,7 +12,7 @@
 pub fn main() {
     let x = &"hello";
     let v = &"hello";
-    let mut y : &str = &"there";
+    let y : &str = &"there";
 
     info!(x);
     info!(y);
index a096a8456739e490fe1845ef146f9997b799d07f..7935886d39b3b5e60a7f1235ddc143dd32e5688e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(dead_assignment)];
+
 pub fn main() {
     let x : ~str = ~"hello";
     let _y : ~str = ~"there";
index 64c8a4caf80aee78197358ed1f63ed533046d3a9..c872ee5a9c58d60f7caa95c019be1a7bfb4c3142 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(dead_assignment)];
+
 pub fn main() {
     let x : [@int, ..5] = [@1,@2,@3,@4,@5];
     let _y : [@int, ..5] = [@1,@2,@3,@4,@5];
index 38891d35e8e6c6b61c2ac5d96c205e35cb8f8578..4a14faf1f84e17cb214c0256a66154e674f42733 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(dead_assignment)];
+
 pub fn main() {
     let x : &[int] = &[1,2,3,4,5];
     let mut z = &[1,2,3,4,5];
index 2437946a1f094540b210d0c27c532d3aa67217f9..735891b25d48c603e78c70d1737d58c54fe6ec99 100644 (file)
@@ -14,5 +14,5 @@
 use std::os;
 
 pub fn main() {
-    assert_eq!(os::getenv(~"TEST_EXEC_ENV"), Some(~"22"));
+    assert_eq!(os::getenv("TEST_EXEC_ENV"), Some(~"22"));
 }
index 209dbb3741a0601627698db8fa485515dde05449..adc4b553d095924a709bab47037120222ecbe133 100644 (file)
@@ -17,4 +17,4 @@ pub enum t { t1, }
     pub fn f() -> t { return t1; }
 }
 
-pub fn main() { let v: foo::t = foo::f(); }
+pub fn main() { let _v: foo::t = foo::f(); }
index 6b97c9031f0a9c9d95502262b154c3a9f52d1ebe..ab2750dc4af04343a8ffcadf271b036ea115b638 100644 (file)
@@ -21,7 +21,7 @@ pub mod bar {
         pub static a : int = 10;
     }
     pub fn zum() {
-        let b = a;
+        let _b = a;
     }
 }
 
index 47ac4bd4a9aceedc9860407078e311fef07fdee9..d0aa23e81fa1d8f1e73c7a1b760da6c6c14e32e7 100644 (file)
@@ -12,4 +12,4 @@ mod foo {
     pub enum t { t1, }
 }
 
-pub fn main() { let v = foo::t1; }
+pub fn main() { let _v = foo::t1; }
index a44afac80f44d461cc17d152682d14050f593f52..dbb1ac1f649895ac415d9285fafd09a0a5679b0f 100644 (file)
@@ -14,7 +14,7 @@ fn test_fn() {
     type t = @fn() -> int;
     fn ten() -> int { return 10; }
     let rs: t = { ten };
-    //assert!((rs() == 10));
+    assert!((rs() == 10));
 }
 
 pub fn main() { test_fn(); }
index 8b10bd7c51c2c0f0c16a05ee9a467505ef2ccb43..c77cad8858e009025418b3c1688a7b90015f8bb1 100644 (file)
@@ -9,4 +9,4 @@
 // except according to those terms.
 
 // Regression test for issue #388
-pub fn main() { let x = { { @10 } }; }
+pub fn main() { let _x = { { @10 } }; }
index b13f7ceba4bfe33618514e8c84205136edd8f6fb..669acf1feb45ac37a2d7e003b22a2ec19dd4cde9 100644 (file)
@@ -12,6 +12,6 @@
 // values from the else if branch
 pub fn main() {
     let y: @uint = @10u;
-    let x = if false { y } else if true { y } else { y };
+    let _x = if false { y } else if true { y } else { y };
     assert_eq!(*y, 10u);
 }
index 2832e4a760c1e10d4f7e299d382aa3d55d88f68a..96acaf43e3413a64e73e376ee0a8161db8dadb39 100644 (file)
@@ -9,4 +9,12 @@
 // except according to those terms.
 
 // Regression test for issue #388
-pub fn main() { let x = if false { @0u } else if true { @10u } else { @0u }; }
+pub fn main() {
+    let _x = if false {
+        @0u
+    } else if true {
+        @10u
+    } else {
+        @0u
+    };
+}
index fa84e81f775c1149a6d7a164e7f39e68a88ff42e..afc7dfaf9b441bcfd51a03a5cd0c4ec4fe3f5d14 100644 (file)
 
 // Issue #521
 
-fn f() { let x = match true { true => { 10 } false => { return } }; }
+fn f() {
+    let _x = match true {
+        true => { 10 }
+        false => { return }
+    };
+}
 
 pub fn main() { }
index 19a046fd27e0d421c6ce62970885d41ff9959db7..a34620d2e1be427f97afd9b03057e0b9c3e5b8ce 100644 (file)
 
 // When all branches of an if expression result in fail, the entire if
 // expression results in fail.
-pub fn main() { let x = if true { 10 } else { if true { fail!() } else { fail!() } }; }
+pub fn main() {
+    let _x = if true {
+        10
+    } else {
+        if true { fail!() } else { fail!() }
+    };
+}
index 5234f58578e9da56e1b35ace94a7b4c42d8a3459..aef11a78e0dbb6ae5c79deedd52dd821b87292b4 100644 (file)
@@ -14,7 +14,7 @@
 // When all branches of an match expression result in fail, the entire
 // match expression results in fail.
 pub fn main() {
-    let x =
+    let _x =
         match true {
           true => { 10 }
           false => { match true { true => { fail!() } false => { fail!() } } }
index a6324b98ebcaa429c248505425ec8b81255cf5e0..1e9ad5283d1ed4a17591c95259438cf1575c0ba6 100644 (file)
@@ -22,7 +22,7 @@ fn test_basic() {
 }
 
 fn test_inferrence() {
-    let mut rs = match true { true => { true } false => { false } };
+    let rs = match true { true => { true } false => { false } };
     assert!((rs));
 }
 
index de7aca88625d18407d8a9c3493e54678159d0065..27ad2fc46e07dab407a2c9e2b3b055917b7f696b 100644 (file)
@@ -27,6 +27,7 @@ pub fn rust_dbg_call(cb: *u8, data: libc::uintptr_t)
     }
 }
 
+#[fixed_stack_segment]
 fn count(n: uint) -> uint {
     unsafe {
         info!("n = %?", n);
index 518e48f29f7894dd0374109f17f325584201d3cb..6c90443636d3913cabe7008e469bdbf99697426f 100644 (file)
@@ -28,6 +28,7 @@ pub fn rust_dbg_call(cb: *u8, data: libc::uintptr_t)
     }
 }
 
+#[fixed_stack_segment] #[inline(never)]
 fn count(n: uint) -> uint {
     unsafe {
         info!("n = %?", n);
index e1db41a32f1ef0eca3679f2aa953817442ab0b5d..5abd3c7b9d918ce55865b555aaa1c6ebe4cfa5de 100644 (file)
@@ -32,6 +32,7 @@ pub fn rust_dbg_call(cb: *u8, data: libc::uintptr_t)
     }
 }
 
+#[fixed_stack_segment] #[inline(never)]
 fn count(n: uint) -> uint {
     unsafe {
         info!("n = %?", n);
index 66563a9a5fa671374ddddba2cf13321f216ff9fa..939487df174db1f1cf9059b746ab13179994b4d2 100644 (file)
@@ -27,6 +27,7 @@ pub fn rust_dbg_call(cb: *u8, data: libc::uintptr_t)
     }
 }
 
+#[fixed_stack_segment] #[inline(never)]
 fn fact(n: uint) -> uint {
     unsafe {
         info!("n = %?", n);
index 97bbd3478a1a56ade7700dff7f882757ac81874f..7db7b898c0e6d7e29e1f059eeddc84c882e239c7 100644 (file)
@@ -13,6 +13,7 @@
 
 extern mod externcallback(vers = "0.1");
 
+#[fixed_stack_segment] #[inline(never)]
 fn fact(n: uint) -> uint {
     unsafe {
         info!("n = %?", n);
index b78f607792b8fb5ff97a99af212ecbb623b97f80..4643c809961e7b7c10d1c98d70007516e6eb201a 100644 (file)
@@ -10,6 +10,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(unused_imports)];
+
 extern mod extra;
 use extra::json::Object;
 
index 3389c56c83bf00afd777789a2f270c409f0a8721..147db0c0b2b0d9eb1c33ccf6b16b67c2ce3d6245 100644 (file)
@@ -20,6 +20,7 @@ struct TwoU32s {
     pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s;
 }
 
+#[fixed_stack_segment] #[inline(never)]
 pub fn main() {
     unsafe {
         let x = TwoU32s {one: 22, two: 23};
index 983817b12debcab6521053d851ba30cf982a4fc5..1937c366831ffc795de87530dcb49eefd1790b34 100644 (file)
@@ -19,6 +19,7 @@ struct TwoU64s {
     pub fn rust_dbg_extern_identity_TwoU64s(u: TwoU64s) -> TwoU64s;
 }
 
+#[fixed_stack_segment] #[inline(never)]
 pub fn main() {
     unsafe {
         let x = TwoU64s {one: 22, two: 23};
index dd1110b59cdb0db7b02671b7cf0a55b60f27f8da..b543099b3b8f8f4990ecc508ef8d1ff20f9680d2 100644 (file)
@@ -24,6 +24,7 @@ struct TwoU64s {
     pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s;
 }
 
+#[fixed_stack_segment] #[inline(never)]
 pub fn main() {
     unsafe {
         let x = TwoU64s {one: 22, two: 23};
index 0cdfaf29a0582a44e9934eb12c26fa256ab508c8..f255746b75a8f683ca6ae60449866660904a0fcd 100644 (file)
@@ -14,6 +14,7 @@
     pub fn rust_dbg_extern_identity_u8(v: u8) -> u8;
 }
 
+#[fixed_stack_segment] #[inline(never)]
 pub fn main() {
     unsafe {
         assert_eq!(22_u8, rust_dbg_extern_identity_u8(22_u8));
index cb0a061a7abd831e2d42e185b43e5c3bf1834e50..c80a0cd502fd351905a863140af3f5b765a2b702 100644 (file)
@@ -12,6 +12,7 @@
     pub fn rust_dbg_extern_identity_double(v: f64) -> f64;
 }
 
+#[fixed_stack_segment] #[inline(never)]
 pub fn main() {
     unsafe {
         assert_eq!(22.0_f64, rust_dbg_extern_identity_double(22.0_f64));
index aa54f014046127c735d695d8d74b1fec1177af95..c6fdabeab3dea0bbf4ee0f39903531bd6426966f 100644 (file)
@@ -14,6 +14,7 @@
     pub fn rust_dbg_extern_identity_u32(v: u32) -> u32;
 }
 
+#[fixed_stack_segment] #[inline(never)]
 pub fn main() {
     unsafe {
         assert_eq!(22_u32, rust_dbg_extern_identity_u32(22_u32));
index 7c39080a5689732dc778d8554e015c0e12a31eee..09babc1109f8c3166bbd9058201c5b909fb8ec10 100644 (file)
@@ -14,6 +14,7 @@
     pub fn rust_dbg_extern_identity_u64(v: u64) -> u64;
 }
 
+#[fixed_stack_segment] #[inline(never)]
 pub fn main() {
     unsafe {
         assert_eq!(22_u64, rust_dbg_extern_identity_u64(22_u64));
index 0aa6b3cc83d52215ab1be144fe8269e6fda2a892..2b9f99ca0105cb06a620c519252e4d0139275b33 100644 (file)
@@ -8,9 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// xfail-win32 #5745
-// xfail-macos Broken on mac i686
-
 struct TwoU16s {
     one: u16, two: u16
 }
@@ -19,6 +16,7 @@ struct TwoU16s {
     pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s;
 }
 
+#[fixed_stack_segment] #[inline(never)]
 pub fn main() {
     unsafe {
         let y = rust_dbg_extern_return_TwoU16s();
index 90562f0f6b1cec5419f334d707acc5a6b9fdfbc7..f93a15bd80806c601aab3e1612346e939aff138c 100644 (file)
@@ -16,6 +16,7 @@ struct TwoU32s {
     pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s;
 }
 
+#[fixed_stack_segment] #[inline(never)]
 pub fn main() {
     unsafe {
         let y = rust_dbg_extern_return_TwoU32s();
index 9f878a90c142acdc923d0e8e44b6ff456ad71f2a..4dc31d715260b2707ffbd34521f941c198e31433 100644 (file)
@@ -16,6 +16,7 @@ struct TwoU64s {
     pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s;
 }
 
+#[fixed_stack_segment] #[inline(never)]
 pub fn main() {
     unsafe {
         let y = rust_dbg_extern_return_TwoU64s();
index c4d50d1766c5dc469ab2a304d3fea4a2d474e0be..aae8b8a8587d0d7d91addae7f5b4fd24135d47f1 100644 (file)
@@ -8,9 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// xfail-win32 #5745
-// xfail-macos Broken on mac i686
-
 struct TwoU8s {
     one: u8, two: u8
 }
@@ -19,6 +16,7 @@ struct TwoU8s {
     pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s;
 }
 
+#[fixed_stack_segment] #[inline(never)]
 pub fn main() {
     unsafe {
         let y = rust_dbg_extern_return_TwoU8s();
index 4574fbc1ff0cdbc0cf11a8ef2d06e847d57a15fa..4eda3f34b6c15198a9f78d15d7b7efc22542a9b7 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// This creates a bunch of yielding tasks that run concurrently
+// This creates a bunch of descheduling tasks that run concurrently
 // while holding onto C stacks
 
 use std::libc;
@@ -27,11 +27,12 @@ pub fn rust_dbg_call(cb: *u8, data: libc::uintptr_t)
     if data == 1u {
         data
     } else {
-        task::yield();
+        task::deschedule();
         count(data - 1u) + count(data - 1u)
     }
 }
 
+#[fixed_stack_segment] #[inline(never)]
 fn count(n: uint) -> uint {
     unsafe {
         rustrt::rust_dbg_call(cb, n)
index 4722eeea3d7ccfee718b23a595d8097fc32f02fb..ce51aafa9d80960160f663f1544535643ca5cb7f 100644 (file)
@@ -28,9 +28,10 @@ pub fn rust_dbg_call(cb: *u8, data: libc::uintptr_t)
     }
 }
 
+#[fixed_stack_segment] #[inline(never)]
 fn count(n: uint) -> uint {
     unsafe {
-        task::yield();
+        task::deschedule();
         rustrt::rust_dbg_call(cb, n)
     }
 }
index 39e4f52873a395e5c058bea4b06bae8f1ae48466..22aab1aa661911dde5774d18964afea037d19c23 100644 (file)
@@ -14,5 +14,5 @@ struct r {
 
 pub fn main() {
     fn f() {}
-    let i: r = r {field: f};
+    let _i: r = r {field: f};
 }
index 2754fdea4d4e8dddb4d2c65c030db0c24ca78413..b19708a971203ae36b39c8ce0b2b5779cb1a1c11 100644 (file)
@@ -12,7 +12,7 @@
 
 
 // -*- rust -*-
-fn foo(f: extern fn(int) -> int) { }
+fn foo(_f: extern fn(int) -> int) { }
 
 fn id(x: int) -> int { return x; }
 
index a753005069ff937393b1ef3be806fe2e6d67ddbe..bb9254589f7b3f935f92673713e21d1a024f7cf9 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(unused_variable)];
+
 pub fn main() {
     // We should be able to type infer inside of @fns.
-    let f = || {
+    let _f = || {
         let i = 10;
     };
 }
index e9bf17a037ae552fe169956f58478897c03c2a7b..c8acdbf44781c64bebe81228a742f753337d36ee 100644 (file)
@@ -2,17 +2,13 @@
 use std::libc;
 use std::unstable::run_in_bare_thread;
 
-extern {
-    pub fn rust_dbg_call(cb: *u8, data: libc::uintptr_t) -> libc::uintptr_t;
-}
+externfn!(fn rust_dbg_call(cb: *u8, data: libc::uintptr_t) -> libc::uintptr_t)
 
 pub fn main() {
     unsafe {
         do run_in_bare_thread() {
-            unsafe {
-                let i = &100;
-                rust_dbg_call(callback, cast::transmute(i));
-            }
+            let i = &100;
+            rust_dbg_call(callback, cast::transmute(i));
         }
     }
 }
index 574ef59f0b642f3dfb7cc06792c9396c981a506e..3ff1ebb57322cfa10e67d32a56ce2cecbcda5e9a 100644 (file)
@@ -31,6 +31,7 @@ mod rustrt2 {
     }
 }
 
+#[fixed_stack_segment] #[inline(never)]
 pub fn main() {
     unsafe {
         rustrt1::rust_get_test_int();
index b5a114ef22364e64dc2bea3f7ccf326b914afa50..57b59e4445e7718800ffe80de19a24fdda7b90a0 100644 (file)
 
 extern mod extra;
 
-use std::libc;
-use std::str;
-use std::vec;
-
 mod libc {
+    use std::libc::{c_char, size_t};
+
     #[nolink]
     #[abi = "cdecl"]
     extern {
         #[link_name = "strlen"]
-        pub fn my_strlen(str: *u8) -> uint;
+        pub fn my_strlen(str: *c_char) -> size_t;
     }
 }
 
+#[fixed_stack_segment] #[inline(never)]
 fn strlen(str: ~str) -> uint {
-    unsafe {
-        // C string is terminated with a zero
-        do str.to_c_str().with_ref |buf| {
-            libc::my_strlen(buf as *u8)
+    // C string is terminated with a zero
+    do str.with_c_str |buf| {
+        unsafe {
+            libc::my_strlen(buf) as uint
         }
     }
 }
index a1f6cf6988bf71926933819375ea21e428c1bf39..977488d4529af4ea7656afe4133e7ced789af585 100644 (file)
@@ -9,9 +9,11 @@
 // except according to those terms.
 
 mod foo {
+    use std::libc::c_int;
+
     #[nolink]
     extern {
-        pub static errno: int;
+        pub static errno: c_int;
     }
 }
 
index d914d52adf57da60012383a9b4dd182a4d0b0e1a..f9c2698eda499f882b5d6781718578db047c3f78 100644 (file)
@@ -18,6 +18,7 @@ mod rustrt {
     }
 }
 
+#[fixed_stack_segment] #[inline(never)]
 pub fn main() {
     unsafe {
         rustrt::rust_get_test_int();
index 72bdd5e2946b9d21a534b45f2791f4151417d61d..2cc7e2707728408f0ad754d64e48ce7f58b7b841 100644 (file)
@@ -21,11 +21,12 @@ mod zed {
 }
 
 mod libc {
+    use std::libc::{c_int, c_void, size_t, ssize_t};
+
     #[abi = "cdecl"]
     #[nolink]
     extern {
-        pub fn write(fd: int, buf: *u8, count: ::std::libc::size_t)
-                     -> ::std::libc::ssize_t;
+        pub fn write(fd: c_int, buf: *c_void, count: size_t) -> ssize_t;
     }
 }
 
index 9592f9ff73616335ef1d138eeeffd1cd8e5b18cd..9e0dbfba0e75f167e58d26afca9807eca32c507c 100644 (file)
@@ -11,6 +11,6 @@
 
 struct Pair { x: @int, y: @int }
 
-fn f<T>(t: T) { let t1: T = t; }
+fn f<T>(t: T) { let _t1: T = t; }
 
 pub fn main() { let x = Pair {x: @10, y: @12}; f(x); }
index 34fb22ea0f45bb915b9e9746270a0117a76b75ae..d14ee82e45eab8cd634279b35ac78699d95979c0 100644 (file)
@@ -8,8 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-
+#[allow(dead_assignment)];
 
 // -*- rust -*-
 fn id<T>(x: T) -> T { return x; }
index ac6e3e1a69a9937590d50cd788566d545411948c..17de964dd868e412b5c5e14f1b9f527922daf4ba 100644 (file)
@@ -10,4 +10,4 @@
 
 enum wrapper<T> { wrapped(T), }
 
-pub fn main() { let w = wrapped(~[1, 2, 3, 4, 5]); }
+pub fn main() { let _w = wrapped(~[1, 2, 3, 4, 5]); }
index 2a288c8abbf35910a44dca813a74b740b4a8a1a2..aac390dc6ec86a999b66c7ae8beae03e52143364 100644 (file)
@@ -8,5 +8,5 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn f<T>(v: @T) { }
+fn f<T>(_v: @T) { }
 pub fn main() { f(@~[1, 2, 3, 4, 5]); }
index af92bb4c8d86ae6bde2dc043b7f45d6d239e5eba..6111acfe42c7f25bc40458b212e320c4764344d4 100644 (file)
@@ -13,6 +13,6 @@
 enum list<T> { cons(@T, @list<T>), nil, }
 
 pub fn main() {
-    let a: list<int> =
+    let _a: list<int> =
         cons::<int>(@10, @cons::<int>(@12, @cons::<int>(@13, @nil::<int>)));
 }
index 5cf56b8083d2ad22a2f8ba079089e4c330fa7cf0..4fd8b73c8191878fdc7209db0b83f0a22c9f66f6 100644 (file)
@@ -14,4 +14,4 @@
 // This causes memory corruption in stage0.
 enum thing<K> { some(K), }
 
-pub fn main() { let x = some(~"hi"); }
+pub fn main() { let _x = some(~"hi"); }
index 21e113f40a5025e15ca5908a800cb13fbdb83d1d..fb8140790e3e9f940ae7a8adcdd80ae28597bc57 100644 (file)
@@ -12,4 +12,4 @@
 
 enum clam<T> { a(T), }
 
-pub fn main() { let c = a(3); }
+pub fn main() { let _c = a(3); }
index 55b527989de53b06ab798e5424fa63dc18b1a031..f740d8cb2d1591ef73233d5b392bd22d1efde466 100644 (file)
@@ -8,13 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
+#[allow(dead_assignment)];
 
 enum foo<T> { arm(T), }
 
 fn altfoo<T>(f: foo<T>) {
     let mut hit = false;
-    match f { arm::<T>(x) => { info!("in arm"); hit = true; } }
+    match f { arm::<T>(_x) => { info!("in arm"); hit = true; } }
     assert!((hit));
 }
 
index b38c494662f0b78c50501f27dcdca451893e172f..16836b0d7b83029aaa42fb9f81b502bea21b5c7a 100644 (file)
@@ -8,8 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
+#[allow(dead_assignment)];
+#[allow(unused_variable)];
 
 enum option<T> { some(@T), none, }
 
-pub fn main() { let mut a: option<int> = some::<int>(@10); a = none::<int>; }
+pub fn main() {
+    let mut a: option<int> = some::<int>(@10);
+    a = none::<int>;
+}
index f481797fb444c9dc7533186c3fa5e1f028c29304..a1cf581fe4a81eb35169e9d2052526949bdd5984 100644 (file)
@@ -16,6 +16,6 @@ struct Foo<T> {
 
 type Bar<T> = Foo<T>;
 
-fn takebar<T>(b: Bar<T>) { }
+fn takebar<T>(_b: Bar<T>) { }
 
 pub fn main() { }
index 161f37eb444e0a94664afcf1c24eb18c14f8cb79..cebd29100703616c6665c5ecaf2ea85000f43f41 100644 (file)
@@ -16,7 +16,7 @@
 
 pub fn main() {
     let args = ~[];
-    let opts = ~[optopt(~"b")];
+    let opts = ~[optopt("b")];
 
     match getopts(args, opts) {
         Ok(ref m)  =>
index 86bff013eefc6bebf5449114f554c5f78d507efd..bf29fa603c7ecd2f01c201e05fd432575e36bce3 100644 (file)
@@ -19,7 +19,7 @@ pub fn main() {
         match Pair {x: 10, y: 20} {
           x if x.x < 5 && x.y < 5 => { 1 }
           Pair {x: x, y: y} if x == 10 && y == 20 => { 2 }
-          Pair {x: x, y: y} => { 3 }
+          Pair {x: _x, y: _y} => { 3 }
         };
     assert_eq!(b, 2);
 }
index 42a4075d411a806ff98da4bd3f1e6ae53fdc0aa2..be0f9cd046b794fa7f20928cc83039409513f3dc 100644 (file)
@@ -85,7 +85,7 @@ macro_rules! parse_node (
 )
 
 pub fn main() {
-    let page = html! (
+    let _page = html! (
         <html>
             <head><title>This is the title.</title></head>
             <body>
index a0d3eb7d803287d3a6dcc1b2d97e6074e0992a4e..cba28463f990687f1a1854c9c376d92463e768c0 100644 (file)
@@ -25,16 +25,36 @@ pub fn main() {
     macro_rules! t(($a:expr, $b:expr) => { assert_eq!($a, $b.to_owned()) })
 
     // Make sure there's a poly formatter that takes anything
-    t!(ifmt!("{}", 1), "1");
-    t!(ifmt!("{}", A), "{}");
-    t!(ifmt!("{}", ()), "()");
-    t!(ifmt!("{}", @(~1, "foo")), "@(~1, \"foo\")");
+    t!(ifmt!("{:?}", 1), "1");
+    t!(ifmt!("{:?}", A), "{}");
+    t!(ifmt!("{:?}", ()), "()");
+    t!(ifmt!("{:?}", @(~1, "foo")), "@(~1, \"foo\")");
 
     // Various edge cases without formats
     t!(ifmt!(""), "");
     t!(ifmt!("hello"), "hello");
     t!(ifmt!("hello \\{"), "hello {");
 
+    // default formatters should work
+    t!(ifmt!("{}", 1i), "1");
+    t!(ifmt!("{}", 1i8), "1");
+    t!(ifmt!("{}", 1i16), "1");
+    t!(ifmt!("{}", 1i32), "1");
+    t!(ifmt!("{}", 1i64), "1");
+    t!(ifmt!("{}", 1u), "1");
+    t!(ifmt!("{}", 1u8), "1");
+    t!(ifmt!("{}", 1u16), "1");
+    t!(ifmt!("{}", 1u32), "1");
+    t!(ifmt!("{}", 1u64), "1");
+    t!(ifmt!("{}", 1.0f), "1");
+    t!(ifmt!("{}", 1.0f32), "1");
+    t!(ifmt!("{}", 1.0f64), "1");
+    t!(ifmt!("{}", "a"), "a");
+    t!(ifmt!("{}", ~"a"), "a");
+    t!(ifmt!("{}", @"a"), "a");
+    t!(ifmt!("{}", false), "false");
+    t!(ifmt!("{}", 'a'), "a");
+
     // At least exercise all the formats
     t!(ifmt!("{:b}", true), "true");
     t!(ifmt!("{:c}", '☃'), "☃");
@@ -45,6 +65,8 @@ macro_rules! t(($a:expr, $b:expr) => { assert_eq!($a, $b.to_owned()) })
     t!(ifmt!("{:x}", 10u), "a");
     t!(ifmt!("{:X}", 10u), "A");
     t!(ifmt!("{:s}", "foo"), "foo");
+    t!(ifmt!("{:s}", ~"foo"), "foo");
+    t!(ifmt!("{:s}", @"foo"), "foo");
     t!(ifmt!("{:p}", 0x1234 as *int), "0x1234");
     t!(ifmt!("{:p}", 0x1234 as *mut int), "0x1234");
     t!(ifmt!("{:d}", A), "aloha");
@@ -54,7 +76,7 @@ macro_rules! t(($a:expr, $b:expr) => { assert_eq!($a, $b.to_owned()) })
     t!(ifmt!("{foo} {bar}", foo=0, bar=1), "0 1");
     t!(ifmt!("{foo} {1} {bar} {0}", 0, 1, foo=2, bar=3), "2 1 3 0");
     t!(ifmt!("{} {0:s}", "a"), "a a");
-    t!(ifmt!("{} {0}", "a"), "\"a\" \"a\"");
+    t!(ifmt!("{} {0}", "a"), "a a");
 
     // Methods should probably work
     t!(ifmt!("{0, plural, =1{a#} =2{b#} zero{c#} other{d#}}", 0u), "c0");
index d09ef3bc25c3a45d3ecf1a4579f1a63dafafeff9..2f863d3da62ac957f1b83a314c35ac4ca71c21c0 100644 (file)
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(dead_assignment)];
 
 extern mod extra;
 use std::vec::*;
 
 pub fn main() {
     let mut v = from_elem(0u, 0);
-    v = append(v, ~[4, 2]);
+    v = append(v, [4, 2]);
     assert_eq!(from_fn(2, |i| 2*(i+1)), ~[2, 4]);
 }
index 8e53affd2dd3601df62348434040bd88ecc7a5d2..64d47bf22195f634822d497b834483193339b1d7 100644 (file)
@@ -10,6 +10,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(unused_imports)];
 
 use baz::zed;
 use baz::zed::bar;
index d52877fa11db9ae86bc0ca749dcc6a34bff5216d..d368ab2e993db4a7a5efa1364c8d9b3f8d5e9b42 100644 (file)
@@ -17,4 +17,4 @@ mod zed {
     pub fn bar() { info!("bar"); }
 }
 
-pub fn main() { let zed = 42; bar(); }
+pub fn main() { let _zed = 42; bar(); }
index 296b0c605d625a65c7d5924168d9026ea37990af..4f813247576c8fcfb2454366dda8a390e28efa45 100644 (file)
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(unused_imports)];
+
 use foo::zed;
 use bar::baz;
+
 mod foo {
     pub mod zed {
         pub fn baz() { info!("baz"); }
index 969d2b176cfb2d95f8379bdf7cf01ecf87d692de..63a30ccee2cebb0656b04aa372bd701833f77081 100644 (file)
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(unused_imports)];
+
 use foo::zed;
 use bar::baz;
+
 mod foo {
     pub mod zed {
         pub fn baz() { info!("baz"); }
index cad6661bbce1be62a45b8e5c1d7754a4414c1889..0b5e58526f6343e576dd6a9364cc5462c8d67059 100644 (file)
@@ -20,9 +20,7 @@ struct Box { x: r }
 #[unsafe_destructor]
 impl Drop for r {
     fn drop(&self) {
-        unsafe {
-            *(self.i) = *(self.i) + 1;
-        }
+        *(self.i) = *(self.i) + 1;
     }
 }
 
@@ -35,7 +33,7 @@ fn r(i: @mut int) -> r {
 fn test_box() {
     let i = @mut 0;
     {
-        let a = @r(i);
+        let _a = @r(i);
     }
     assert_eq!(*i, 1);
 }
@@ -43,7 +41,7 @@ fn test_box() {
 fn test_rec() {
     let i = @mut 0;
     {
-        let a = Box {x: r(i)};
+        let _a = Box {x: r(i)};
     }
     assert_eq!(*i, 1);
 }
@@ -55,7 +53,7 @@ enum t {
 
     let i = @mut 0;
     {
-        let a = t0(r(i));
+        let _a = t0(r(i));
     }
     assert_eq!(*i, 1);
 }
@@ -63,7 +61,7 @@ enum t {
 fn test_tup() {
     let i = @mut 0;
     {
-        let a = (r(i), 0);
+        let _a = (r(i), 0);
     }
     assert_eq!(*i, 1);
 }
@@ -71,7 +69,7 @@ fn test_tup() {
 fn test_unique() {
     let i = @mut 0;
     {
-        let a = ~r(i);
+        let _a = ~r(i);
     }
     assert_eq!(*i, 1);
 }
@@ -79,7 +77,7 @@ fn test_unique() {
 fn test_box_rec() {
     let i = @mut 0;
     {
-        let a = @Box {
+        let _a = @Box {
             x: r(i)
         };
     }
index 5415a6ad25812903c8f2f84b6de01da461389b57..41ddce7a96ee27a13bddee63499c7351d05c2f18 100644 (file)
@@ -17,5 +17,5 @@
 struct X { x: uint, nxt: *foo }
 
 pub fn main() {
-    let x = foo(X {x: 0, nxt: ptr::null()});
+    let _x = foo(X {x: 0, nxt: ptr::null()});
 }
index 33239a1441cc991458abd1e8ce6812f464b516cb..c6632f8cd6c32f5db80ad16d2f1b3691b6497e0c 100644 (file)
@@ -12,4 +12,4 @@
 
 
 // -*- rust -*-
-pub fn main() { let x: int = 10; }
+pub fn main() { let _x: int = 10; }
index ad285e9a85fb915f841cfbfdf416c0f0e715399b..a55149b7d036665173ed8880bc69f9b69281bf42 100644 (file)
@@ -15,9 +15,7 @@
 use cci_intrinsic::atomic_xchg;
 
 pub fn main() {
-    unsafe {
-        let mut x = 1;
-        atomic_xchg(&mut x, 5);
-        assert_eq!(x, 5);
-    }
+    let mut x = 1;
+    atomic_xchg(&mut x, 5);
+    assert_eq!(x, 5);
 }
index 18d63b32a1f770a77926537a039fbecdad590df0..90f352c845b5b742ad1cfaf8166361ee12108316 100644 (file)
@@ -18,7 +18,7 @@ mod rusti {
 
 pub fn main() {
     unsafe {
-        let mut x = @1;
+        let x = @1;
         let mut y = @2;
         rusti::move_val(&mut y, x);
         assert_eq!(*y, 1);
index fb58d8681a5399f28d2ca30497429cb5e89e7205..62a01613c206565c898431302e9bb837072d1a03 100644 (file)
@@ -10,8 +10,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::f64;
-
 mod rusti {
     #[abi = "rust-intrinsic"]
     extern "rust-intrinsic" {
index 4ccd5355987fbe6e1195acb6d96418059390995a..1736428affb36cc0844152bba85fa5ff4d47b008 100644 (file)
@@ -17,8 +17,9 @@
 
 extern mod foreign_lib;
 
+#[fixed_stack_segment] #[inline(never)]
 pub fn main() {
     unsafe {
-        let foo = foreign_lib::rustrt::rust_get_test_int();
+        let _foo = foreign_lib::rustrt::rust_get_test_int();
     }
 }
index 103679a13eff90e8eddf64ec6105017c99772ce0..d8023d2e7167db96b2297e26365e1d98782aa3a9 100644 (file)
@@ -11,7 +11,6 @@
 // except according to those terms.
 
 use std::hashmap::HashMap;
-use std::str;
 
 pub fn main() {
     let mut m = HashMap::new();
index 19785a49cd02d64686cc0930866ef1d33a272b74..1bb8a0008760b2ede0f90d6cdd9381ee03ce5259 100644 (file)
@@ -12,7 +12,6 @@
 
 use std::cast;
 use std::libc::{c_double, c_int};
-use std::f64::*;
 
 fn to_c_int(v: &mut int) -> &mut c_int {
     unsafe {
@@ -20,6 +19,7 @@ fn to_c_int(v: &mut int) -> &mut c_int {
     }
 }
 
+#[fixed_stack_segment] #[inline(never)]
 fn lgamma(n: c_double, value: &mut int) -> c_double {
     unsafe {
         return m::lgamma(n, to_c_int(value));
index e951eef37056381bd49cfb2393ae73a899d8b174..57d6fed041aafca0245ee647ec2aa17e4e31804f 100644 (file)
@@ -16,7 +16,7 @@ struct foo<A> {
 }
 
 impl<A> clam<A> for foo<A> {
-  fn chowder(&self, y: A) {
+  fn chowder(&self, _y: A) {
   }
 }
 
index df7c3b6e7d977c7c509f173e45c742fc457b5386..b03bfb958af1b2af92258db09dad4f7471aa6ba5 100644 (file)
@@ -14,7 +14,7 @@ struct foo<A> {
 }
 
 impl<A> foo<A> {
-   pub fn bar<B,C:clam<A>>(&self, c: C) -> B {
+   pub fn bar<B,C:clam<A>>(&self, _c: C) -> B {
      fail!();
    }
 }
index 59ca02f50fc3a57c454898504035b9781665de7c..14b5efe904db8c4b5036704f50bac4c728abec23 100644 (file)
@@ -15,7 +15,7 @@ trait clam<A> { }
 struct foo(int);
 
 impl foo {
-    pub fn bar<B,C:clam<B>>(&self, c: C) -> B { fail!(); }
+    pub fn bar<B,C:clam<B>>(&self, _c: C) -> B { fail!(); }
 }
 
 pub fn main() { }
index 548f06897966543dd3609cb528d788a989b10fa2..4e73be8d84e3a582abed7c04804cc5a01a8b84ef 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 pub fn main() {
-    let foo = 100;
+    let _foo = 100;
     static quux: int = 5;
 
     enum Stuff {
index 432e8c19d2a98d36c3348a948e146236f9027a5f..91f76fc5ae0610298b65e9b7b23241ee31e0c4d0 100644 (file)
@@ -13,7 +13,7 @@ struct c1<T> {
 }
 
 impl<T> c1<T> {
-    pub fn f1(&self, x: int) {
+    pub fn f1(&self, _x: int) {
     }
 }
 
@@ -24,7 +24,7 @@ fn c1<T>(x: T) -> c1<T> {
 }
 
 impl<T> c1<T> {
-    pub fn f2(&self, x: int) {
+    pub fn f2(&self, _x: int) {
     }
 }
 
index 3c0a9355b587820223004266b3b7e0605c6122e5..6356c87bfc9610d8a25695ab6517279d191302dd 100644 (file)
@@ -13,7 +13,7 @@ struct c1<T> {
 }
 
 impl<T> c1<T> {
-    pub fn f1(&self, x: T) {}
+    pub fn f1(&self, _x: T) {}
 }
 
 fn c1<T>(x: T) -> c1<T> {
@@ -23,7 +23,7 @@ fn c1<T>(x: T) -> c1<T> {
 }
 
 impl<T> c1<T> {
-    pub fn f2(&self, x: T) {}
+    pub fn f2(&self, _x: T) {}
 }
 
 
index 9b774ed52435e889d7ded8c06716130ad1df99a1..051ebd1ec045fbd7c526be391be553db1695a5d8 100644 (file)
@@ -17,13 +17,13 @@ pub fn main() {
         g: 0,
     };
 
-    let y = Pair {
+    let _y = Pair {
         f: 1,
         g: 1,
         .. x
     };
 
-    let z = Pair {
+    let _z = Pair {
         f: 1,
         .. x
     };
index 39ce74947e9977c60935a6bcec7d077c177f5595..851c27deaa080e7c02c1365bd2e5e05ce909df14 100644 (file)
@@ -11,6 +11,8 @@
 // xfail-fast
 // aux-build:issue-2526.rs
 
+#[allow(unused_imports)];
+
 extern mod issue_2526;
 use issue_2526::*;
 
index c86ce953de5e43e40ff2f39e1b7e7cc41161442e..e7da12861378b91267cd0edd2bd2e255504a8c36 100644 (file)
@@ -26,6 +26,6 @@ fn nyan(kitty: cat, _kitty_info: KittyInfo) {
 }
 
 pub fn main() {
-    let mut kitty = cat();
+    let kitty = cat();
     nyan(kitty, KittyInfo {kitty: kitty});
 }
index fbd06c5e9cea1da42ef55ef707859df5ec11d3fd..edfae096407b6f77d7e1da4bc5ccdd13feb515f9 100644 (file)
@@ -10,8 +10,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::util;
-
 pub type Task = int;
 
 // tjc: I don't know why
@@ -62,7 +60,7 @@ mod rusti {
     // We should consider moving this to ::std::unsafe, although I
     // suspect graydon would want us to use void pointers instead.
     pub unsafe fn uniquify<T>(x: *T) -> ~T {
-        unsafe { cast::transmute(x) }
+        cast::transmute(x)
     }
 
     pub fn swap_state_acq(dst: &mut state, src: state) -> state {
@@ -78,7 +76,7 @@ pub fn swap_state_rel(dst: &mut state, src: state) -> state {
     }
 
     pub fn send<T:Send>(mut p: send_packet<T>, payload: T) {
-        let mut p = p.unwrap();
+        let p = p.unwrap();
         let mut p = unsafe { uniquify(p) };
         assert!((*p).payload.is_none());
         (*p).payload = Some(payload);
@@ -104,13 +102,13 @@ pub fn send<T:Send>(mut p: send_packet<T>, payload: T) {
     }
 
     pub fn recv<T:Send>(mut p: recv_packet<T>) -> Option<T> {
-        let mut p = p.unwrap();
+        let p = p.unwrap();
         let mut p = unsafe { uniquify(p) };
         loop {
             let old_state = swap_state_acq(&mut (*p).state,
                                            blocked);
             match old_state {
-              empty | blocked => { task::yield(); }
+              empty | blocked => { task::deschedule(); }
               full => {
                 let payload = util::replace(&mut p.payload, None);
                 return Some(payload.unwrap())
@@ -123,7 +121,7 @@ pub fn recv<T:Send>(mut p: recv_packet<T>) -> Option<T> {
         }
     }
 
-    pub fn sender_terminate<T:Send>(mut p: *packet<T>) {
+    pub fn sender_terminate<T:Send>(p: *packet<T>) {
         let mut p = unsafe { uniquify(p) };
         match swap_state_rel(&mut (*p).state, terminated) {
           empty | blocked => {
@@ -140,7 +138,7 @@ pub fn sender_terminate<T:Send>(mut p: *packet<T>) {
         }
     }
 
-    pub fn receiver_terminate<T:Send>(mut p: *packet<T>) {
+    pub fn receiver_terminate<T:Send>(p: *packet<T>) {
         let mut p = unsafe { uniquify(p) };
         match swap_state_rel(&mut (*p).state, terminated) {
           empty => {
@@ -225,15 +223,13 @@ pub fn entangle<T:Send>() -> (send_packet<T>, recv_packet<T>) {
 
 pub mod pingpong {
     use std::cast;
-    use std::ptr;
-    use std::util;
 
     pub struct ping(::pipes::send_packet<pong>);
     pub struct pong(::pipes::send_packet<ping>);
 
     pub fn liberate_ping(p: ping) -> ::pipes::send_packet<pong> {
         unsafe {
-            let addr : *::pipes::send_packet<pong> = match &p {
+            let _addr : *::pipes::send_packet<pong> = match &p {
               &ping(ref x) => { cast::transmute(x) }
             };
             fail!()
@@ -242,7 +238,7 @@ pub fn liberate_ping(p: ping) -> ::pipes::send_packet<pong> {
 
     pub fn liberate_pong(p: pong) -> ::pipes::send_packet<ping> {
         unsafe {
-            let addr : *::pipes::send_packet<ping> = match &p {
+            let _addr : *::pipes::send_packet<ping> = match &p {
               &pong(ref x) => { cast::transmute(x) }
             };
             fail!()
@@ -254,7 +250,6 @@ pub fn init() -> (client::ping, server::ping) {
     }
 
     pub mod client {
-        use std::option;
         use pingpong;
 
         pub type ping = ::pipes::send_packet<pingpong::ping>;
index aa9be2203c6b2540b909ef9f118fbe0ae8f68323..37cf2658ebc8777d1c1d4ac30239931fb2f2e19b 100644 (file)
@@ -37,7 +37,7 @@ fn lookup(table: ~json::Object, key: ~str, default: ~str) -> ~str
     }
 }
 
-fn add_interface(store: int, managed_ip: ~str, data: extra::json::Json) -> (~str, object)
+fn add_interface(_store: int, managed_ip: ~str, data: extra::json::Json) -> (~str, object)
 {
     match &data {
         &extra::json::Object(ref interface) => {
index 3f86114796347ab752327cae3689f5ed692a77e8..978099be119bd523dd7b09aeeb6ee62c1116277a 100644 (file)
@@ -16,7 +16,6 @@
 
 use std::io::ReaderUtil;
 use std::io;
-use std::str;
 use std::to_str;
 
 enum square {
index f2ecd0413bd1c614955d88b76f7dc1281dbc63b6..d4470dc34ff0acd5eaf66536369dd040fba0f2d9 100644 (file)
@@ -10,7 +10,6 @@
 
 extern mod extra;
 
-use std::io;
 use std::vec;
 
 trait methods {
index 7d478bbabebbab24f8c44cb5766d1dbe10aff03c..c57257502e40a13d37d4fe20148f13ba3eb08ab2 100644 (file)
@@ -17,5 +17,5 @@
 
 pub fn main() {
     let fd: libc::c_int = 1 as libc::c_int;
-    let sock = @socket::socket_handle(fd);
+    let _sock = @socket::socket_handle(fd);
 }
index 7bfb928e86d7d3f794b8eb70a3fa2581c33ef9e1..abea01cefd339e78b2d6cdba1e1b8707983e6ec4 100644 (file)
@@ -11,5 +11,5 @@
 pub fn main() {
   let x = 1;
   let y: @fn() -> int = || x;
-  let z = y();
+  let _z = y();
 }
index 69cc7851cd9e0d93e0d530934a5f823008ee0bf3..e6429aa55082629613b8c3f8a558ef23ec027514 100644 (file)
@@ -20,7 +20,6 @@
 
 // Extern mod controls linkage. Use controls the visibility of names to modules that are
 // already linked in. Using WriterUtil allows us to use the write_line method.
-use std::int;
 use std::io::WriterUtil;
 use std::io;
 use std::str;
@@ -67,7 +66,7 @@ fn drop(&self) {}
 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 mut lines = do vec::build_sized(height) |push| {
+    let lines = do vec::build_sized(height) |push| {
             do height.times {
                 push(vec::from_elem(width, '.'));
             }
index dc1ce95cfae54d160faa0dd59fb5b443870e6346..eb59b3e12b61047c0d472296e3a14fb676eaffbf 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(unnecessary_allocation)];
+
 // rustc --test match_borrowed_str.rs.rs && ./match_borrowed_str.rs
 extern mod extra;
 
@@ -23,5 +25,6 @@ fn compare(x: &str, y: &str) -> bool
 pub fn main()
 {
     assert!(compare("foo", "foo"));
+    assert!(compare(~"foo", ~"foo"));
     assert!(compare(@"foo", @"foo"));
 }
index e42b70b5a5e0d8a8e0390605e8d86e7826702d3e..f666571c2add494d0121656c41743558848d4ba8 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::io;
-
 struct Vec2 {
     x: float,
     y: float
index 0a22e8bcfd07eac07ebd7edf8290a208936ba367..ee9516e552eff6aaffcce04afd2c9d2eb86e2fb1 100644 (file)
@@ -17,7 +17,7 @@ pub fn stuff<'a>(&'a mut self) -> &'a mut Foo {
 }
 
 pub fn main() {
-    let mut x = @mut Foo { x: 3 };
+    let x = @mut Foo { x: 3 };
     // Neither of the next two lines should cause an error
     let _ = x.stuff();
     x.stuff();
index a5791e3834351bdbcdc1994f6c88802582dd8e20..0db4e6eb24480c700d60c80dae718d0fc99b5bcd 100644 (file)
@@ -8,8 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub fn main()
-{
+#[allow(path_statement)];
+
+pub fn main() {
     let y = ~1;
     y;
 }
index 549d9cb734c0088327e25643935c7c767f6c0a55..f922857fb3f3f7f64819758880e4c82767c867e6 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 pub fn main() {
-    let id: &Mat2<float> = &Matrix::identity();
+    let _id: &Mat2<float> = &Matrix::identity();
 }
 
 pub trait Index<Index,Result> { }
index f6ad444f94a9c48b1b8410a40002ba2bc1cc06f2..f2973256199fa792a7db8127138a41ed06034fc5 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 pub fn main() {
-    let foo = [0, ..2*4];
+    let _foo = [0, ..2*4];
 }
diff --git a/src/test/run-pass/issue-4464.rs b/src/test/run-pass/issue-4464.rs
new file mode 100644 (file)
index 0000000..529f8ec
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn broken<'r>(v: &'r [u8], i: uint, j: uint) -> &'r [u8] { v.slice(i, j) }
+
+pub fn main() {}
index f12aa6c3356cac5c9e0beb4402d5ef4edbe15efb..e6a3d2fa3b2410c2d59985e91279877ff2ce5b9b 100644 (file)
@@ -14,7 +14,7 @@ pub fn main() {
     let x = os::args();
     for arg in x.iter() {
         match arg.clone() {
-            s => { }
+            _s => { }
         }
     }
 }
index 3da90ba1edcb369ce7f56be35ba57a442abf7def..c1ea98283b15cd678a22d5794eafdc78b2cea67c 100644 (file)
 impl Drop for NonCopyable {
     fn drop(&self) {
         let p = **self;
-        let v = unsafe { transmute::<*c_void, ~int>(p) };
+        let _v = unsafe { transmute::<*c_void, ~int>(p) };
     }
 }
 
 fn main() {
     let t = ~0;
     let p = unsafe { transmute::<~int, *c_void>(t) };
-    let z = NonCopyable(p);
+    let _z = NonCopyable(p);
 }
diff --git a/src/test/run-pass/issue-4759-1.rs b/src/test/run-pass/issue-4759-1.rs
new file mode 100644 (file)
index 0000000..ad8ee98
--- /dev/null
@@ -0,0 +1,13 @@
+// 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.
+
+trait U { fn f(self); }
+impl U for int { fn f(self) {} }
+pub fn main() { 4.f(); }
diff --git a/src/test/run-pass/issue-4759.rs b/src/test/run-pass/issue-4759.rs
new file mode 100644 (file)
index 0000000..4591203
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct T { a: ~int }
+
+trait U {
+    fn f(self);
+}
+
+impl U for ~int {
+    fn f(self) { }
+}
+
+pub fn main() {
+    let T { a: a } = T { a: ~0 };
+    a.f();
+}
+
index d5a1a779d45ede04466298a73ac97756c273d946..b9048257cfb5885429fbb112b2f0042be0f78bb2 100644 (file)
@@ -40,5 +40,5 @@ pub fn new(event_loop: ~EventLoop) -> Scheduler {
 }
 
 fn main() {
-    let mut sched = Scheduler::new(~UvEventLoop::new() as ~EventLoop);
+    let _sched = Scheduler::new(~UvEventLoop::new() as ~EventLoop);
 }
index 54abc85053298404cd110b5e9b1a077fa45343fc..c1875988dc666f64696b72efe4a006cbefb1b7a8 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(dead_assignment)];
+
 fn main() {
     let s: ~str = ~"foobar";
     let mut t: &str = s;
index 064413dd93cb5dc9be6e676579f5768faf7a09cd..daf5edd1d28b86338c951f1789c9caf7ff235ee7 100644 (file)
@@ -1,3 +1,3 @@
-fn foo<T: ::std::cmp::Eq>(t: T) { }
+fn foo<T: ::std::cmp::Eq>(_t: T) { }
 
 fn main() { }
diff --git a/src/test/run-pass/issue-5666.rs b/src/test/run-pass/issue-5666.rs
new file mode 100644 (file)
index 0000000..1be5d07
--- /dev/null
@@ -0,0 +1,35 @@
+// 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 Dog {
+    name : ~str
+}
+
+trait Barks {
+    fn bark(&self) -> ~str;
+}
+
+impl Barks for Dog {
+    fn bark(&self) -> ~str {
+        return fmt!("woof! (I'm %s)", self.name);
+    }
+}
+
+
+pub fn main() {
+    let snoopy = ~Dog{name: ~"snoopy"};
+    let bubbles = ~Dog{name: ~"bubbles"};
+    let barker = [snoopy as ~Barks, bubbles as ~Barks];
+
+    for pup in barker.iter() {
+        println(fmt!("%s", pup.bark()));
+    }
+}
+
index d6d09cb0510224872b20c973ab98a9cf0709fc52..039d9bcd16e25f77fa4a37888f65cf04bb4d2262 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(unreachable_code)];
+
 use std::io;
 
 fn main() {
diff --git a/src/test/run-pass/issue-5884.rs b/src/test/run-pass/issue-5884.rs
new file mode 100644 (file)
index 0000000..519211b
--- /dev/null
@@ -0,0 +1,24 @@
+// 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.
+
+pub struct Foo {
+    a: int,
+}
+
+struct Bar<'self> {
+    a: ~Option<int>,
+    b: &'self Foo,
+}
+
+fn check(a: @Foo) {
+    let _ic = Bar{ b: a, a: ~None };
+}
+
+pub fn main(){}
diff --git a/src/test/run-pass/issue-5917.rs b/src/test/run-pass/issue-5917.rs
new file mode 100644 (file)
index 0000000..fb6a068
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+// xfail-test
+
+use std::io;
+
+struct T (&'static [int]);
+static t : T = T (&'static [5, 4, 3]);
+fn main () {
+    assert_eq!(t[0], 5);
+}
\ No newline at end of file
diff --git a/src/test/run-pass/issue-5926.rs b/src/test/run-pass/issue-5926.rs
new file mode 100644 (file)
index 0000000..d941e63
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+#[allow(unused_mut)];
+
+pub fn main() {
+    let  mut your_favorite_numbers = @[1,2,3];
+    let  mut my_favorite_numbers = @[4,5,6];
+    let  f = your_favorite_numbers + my_favorite_numbers;
+    println(fmt!("The third favorite number is %?.", f))
+}
+
diff --git a/src/test/run-pass/issue-6318.rs b/src/test/run-pass/issue-6318.rs
new file mode 100644 (file)
index 0000000..00a94c0
--- /dev/null
@@ -0,0 +1,26 @@
+// 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.
+
+pub enum Thing {
+    A(~Foo)
+}
+
+pub trait Foo {}
+
+pub struct Struct;
+
+impl Foo for Struct {}
+
+pub fn main() {
+    match A(~Struct as ~Foo) {
+        A(_a) => 0,
+    };
+}
+
diff --git a/src/test/run-pass/issue-6470.rs b/src/test/run-pass/issue-6470.rs
new file mode 100644 (file)
index 0000000..73d0e18
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-test
+
+pub mod Bar {
+    pub struct Foo {
+        v: int,
+    }
+
+    extern {
+        #[rust_stack]
+        pub fn foo(v: *Foo) -> Foo;
+    }
+}
+
+fn main() { }
+
diff --git a/src/test/run-pass/issue-6557.rs b/src/test/run-pass/issue-6557.rs
new file mode 100644 (file)
index 0000000..5722461
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn foo(~(_x, _y): ~(int, int)) {}
+
+pub fn main() {}
diff --git a/src/test/run-pass/issue-6898.rs b/src/test/run-pass/issue-6898.rs
new file mode 100644 (file)
index 0000000..2d612bb
--- /dev/null
@@ -0,0 +1,40 @@
+// 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.
+
+use std::unstable::intrinsics;
+
+/// Returns the size of a type
+pub fn size_of<T>() -> uint {
+    TypeInfo::size_of::<T>()
+}
+
+/// Returns the size of the type that `val` points to
+pub fn size_of_val<T>(val: &T) -> uint {
+    val.size_of_val()
+}
+
+pub trait TypeInfo {
+    fn size_of() -> uint;
+    fn size_of_val(&self) -> uint;
+}
+
+impl<T> TypeInfo for T {
+    /// The size of the type in bytes.
+    fn size_of() -> uint {
+        unsafe { intrinsics::size_of::<T>() }
+    }
+
+    /// Returns the size of the type of `self` in bytes.
+    fn size_of_val(&self) -> uint {
+        TypeInfo::size_of::<T>()
+    }
+}
+
+pub fn main() {}
diff --git a/src/test/run-pass/issue-6919.rs b/src/test/run-pass/issue-6919.rs
new file mode 100644 (file)
index 0000000..f63811f
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+// aux-build:iss.rs
+// xfail-fast
+
+extern mod iss ( name = "iss6919_3" );
+
+pub fn main() {
+    iss::D.k;
+}
+
diff --git a/src/test/run-pass/issue-7222.rs b/src/test/run-pass/issue-7222.rs
new file mode 100644 (file)
index 0000000..98c0064
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+pub fn main() {
+    static FOO: float = 10.0;
+
+    match 0.0 {
+        0.0 .. FOO => (),
+        _ => ()
+    }
+}
+
diff --git a/src/test/run-pass/issue-8248.rs b/src/test/run-pass/issue-8248.rs
new file mode 100644 (file)
index 0000000..48f3480
--- /dev/null
@@ -0,0 +1,21 @@
+// 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.
+
+trait A {}
+struct B;
+impl A for B {}
+
+fn foo(_: &mut A) {}
+
+fn main() {
+    let mut b = B;
+    foo(&mut b as &mut A);
+}
+
diff --git a/src/test/run-pass/issue-8249.rs b/src/test/run-pass/issue-8249.rs
new file mode 100644 (file)
index 0000000..ad37196
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait A {}
+struct B;
+impl A for B {}
+
+struct C<'self> {
+    foo: &'self mut A,
+}
+
+fn foo(a: &mut A) {
+    C{ foo: a };
+}
+
+fn main() {
+}
+
diff --git a/src/test/run-pass/issue-8398.rs b/src/test/run-pass/issue-8398.rs
new file mode 100644 (file)
index 0000000..5e04c96
--- /dev/null
@@ -0,0 +1,18 @@
+// 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.
+
+use std::rt::io;
+
+fn foo(a: &mut io::Writer) {
+    a.write([])
+}
+
+fn main(){}
+
diff --git a/src/test/run-pass/issue-8401.rs b/src/test/run-pass/issue-8401.rs
new file mode 100644 (file)
index 0000000..cf78683
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:issue_8401.rs
+// xfail-fast
+
+extern mod issue_8401;
+
+pub fn main() {}
diff --git a/src/test/run-pass/issue-8498.rs b/src/test/run-pass/issue-8498.rs
new file mode 100644 (file)
index 0000000..40f9835
--- /dev/null
@@ -0,0 +1,44 @@
+// 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.
+
+// xfail-test
+use std::io;
+
+fn main() {
+// This is ok
+    match &[(~5,~7)] {
+        ps => {
+           let (ref y, _) = ps[0];
+           io::println(fmt!("1. y = %d", **y));
+           assert!(**y == 5);
+        }
+    }
+
+// This is not entirely ok
+    match Some(&[(~5,)]) {
+        Some(ps) => {
+           let (ref y,) = ps[0];
+           io::println(fmt!("2. y = %d", **y));
+           if **y != 5 { io::println("sadness"); }
+        }
+        None => ()
+    }
+
+// This is not ok
+    match Some(&[(~5,~7)]) {
+        Some(ps) => {
+           let (ref y, ref z) = ps[0];
+           io::println(fmt!("3. y = %d z = %d", **y, **z));
+           assert!(**y == 5);
+        }
+        None => ()
+    }
+}
+
index 34a9055ae83490670ad2fccc8cf58f67380c6fde..a68aaeb38a2972281a705f933cbcb8870f0c7672 100644 (file)
@@ -15,9 +15,7 @@ struct r {
 #[unsafe_destructor]
 impl Drop for r {
     fn drop(&self) {
-        unsafe {
-            *(self.b) += 1;
-        }
+        *(self.b) += 1;
     }
 }
 
@@ -30,7 +28,7 @@ fn r(b: @mut int) -> r {
 pub fn main() {
     let b = @mut 0;
     {
-        let p = Some(r(b));
+        let _p = Some(r(b));
     }
 
     assert_eq!(*b, 1);
index 66ad233866afa26c41cc053ac35663185fb5f83f..254954fbde975fb7b0adec0d223e9d20fb6bfec9 100644 (file)
@@ -30,33 +30,33 @@ fn test_heap_assign() {
 fn test_heap_log() { let s = ~"a big ol' string"; info!(s); }
 
 fn test_stack_add() {
-    assert_eq!(~"a" + ~"b", ~"ab");
+    assert_eq!(~"a" + "b", ~"ab");
     let s: ~str = ~"a";
     assert_eq!(s + s, ~"aa");
-    assert_eq!(~"" + ~"", ~"");
+    assert_eq!(~"" + "", ~"");
 }
 
-fn test_stack_heap_add() { assert!((~"a" + ~"bracadabra" == ~"abracadabra")); }
+fn test_stack_heap_add() { assert!((~"a" + "bracadabra" == ~"abracadabra")); }
 
 fn test_heap_add() {
-    assert_eq!(~"this should" + ~" totally work", ~"this should totally work");
+    assert_eq!(~"this should" + " totally work", ~"this should totally work");
 }
 
 fn test_append() {
     let mut s = ~"";
-    s.push_str(~"a");
+    s.push_str("a");
     assert_eq!(s, ~"a");
 
     let mut s = ~"a";
-    s.push_str(~"b");
+    s.push_str("b");
     info!(s.clone());
     assert_eq!(s, ~"ab");
 
     let mut s = ~"c";
-    s.push_str(~"offee");
+    s.push_str("offee");
     assert!(s == ~"coffee");
 
-    s.push_str(~"&tea");
+    s.push_str("&tea");
     assert!(s == ~"coffee&tea");
 }
 
index 2d2a82ddb1b18108f9890de2cf2b77c54c214091..29c1c630660474ab424eaa290f40eb6c771b6570 100644 (file)
@@ -151,7 +151,7 @@ mod test_distinguish_syntax_ext {
     extern mod extra;
 
     pub fn f() {
-        fmt!("test%s", ~"s");
+        fmt!("test%s", "s");
         #[attr = "val"]
         fn g() { }
     }
index 3a3b5746b9d6fa1d767ddf11b511f5d85ff24345..4a82e6844b979f96dbaf2e95617cbf61d26a527d 100644 (file)
@@ -8,5 +8,5 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn f(a: ~[int]) { }
+fn f(_a: ~[int]) { }
 pub fn main() { f(~[1, 2, 3, 4, 5]); }
index 8d87ff400614cb847249307f5600465708cc5070..4b76f2f3214d4cb0bee1513fe88d38db49fe44a6 100644 (file)
@@ -1,4 +1,3 @@
-use std::comm::*;
 use std::task;
 
 fn producer(c: &Chan<~[u8]>) {
@@ -9,7 +8,7 @@ fn producer(c: &Chan<~[u8]>) {
 
 pub fn main() {
     let (p, ch) = stream::<~[u8]>();
-    let prod = task::spawn(|| producer(&ch) );
+    let _prod = task::spawn(|| producer(&ch) );
 
-    let data: ~[u8] = p.recv();
+    let _data: ~[u8] = p.recv();
 }
index 056e3a4ff490f374d219130959e2eadf8f6fa47d..9eecc788a69c1660a10e015d27311853e8fb4f46 100644 (file)
@@ -16,6 +16,6 @@ struct Refs { refs: ~[int], n: int }
 
 pub fn main() {
     let e = @mut Refs{refs: ~[], n: 0};
-    let f: @fn() = || error!(e.n);
+    let _f: @fn() = || error!(e.n);
     e.refs.push(1);
 }
index 1ba5b10e9b7a7aa4c82d7fb68c90002f0469fe05..788d9cf03e0733ad1f51bb5e2f4505f813e1a891 100644 (file)
@@ -26,7 +26,7 @@ struct Large {a: int,
              k: int,
              l: int}
 fn f() {
-    let foo: Large =
+    let _foo: Large =
         Large {a: 0,
          b: 0,
          c: 0,
index 94bd54e5b7ca56e7e24a3b8fb081af66e504e73a..0e266c2818cdb24635b97c0a1a0773d71db982b6 100644 (file)
@@ -10,6 +10,6 @@
 
 
 
-fn leaky<T>(t: T) { }
+fn leaky<T>(_t: T) { }
 
 pub fn main() { let x = @10; leaky::<@int>(x); }
index 05b8e361ae72d5d242208a01730756ccec3d8a7b..93e2fcd82497426e9b4970f65d9fff7a1a6d5b3b 100644 (file)
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
+#[allow(dead_assignment)];
+#[allow(unused_variable)];
 
 enum t { a, b(@int), }
 
index 98c092a68c9681921816ef05d72ac49a8ffff7e6..ab186d935df36613f63daad308b77499d08c9560 100644 (file)
@@ -10,6 +10,6 @@
 
 
 
-fn leaky<T>(t: T) { }
+fn leaky<T>(_t: T) { }
 
 pub fn main() { let x = ~10; leaky::<~int>(x); }
index 2615396653d3a7f29e27fc91641d85ba10b916d4..13c12a77fd994705f8a4aa8d3bb9885e62903e82 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(dead_assignment)];
+
 struct X { x: int, y: @A }
 struct A { a: int }
 
index 5d59c4c14716f58fdaaf653cd5fbe98eb184b814..a2f0c81f1164a9dfc6f66b47a45c64cfa89ccbb4 100644 (file)
@@ -8,7 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn test(cond: bool) {
+#[allow(dead_assignment)];
+#[allow(unreachable_code)];
+#[allow(unused_variable)];
+
+fn test(_cond: bool) {
     let v: int;
     v = 1;
     loop { } // loop never terminates, so no error is reported
index e9c12277286d1babb5cf9a0da96fd52eb4df5f86..fe70573744ecbef92cb8810dd45cbc701d70c113 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(unreachable_code)];
+
 fn test() {
     let _v: int;
     _v = 1;
index 31c0c98fa962d2289b6454dbea9edc17ff80b15a..586a13771774d2a8362189148bb4819679cac2ce 100644 (file)
@@ -10,4 +10,4 @@
 
 
 
-pub fn main() { if false { error!(~"foo" + ~"bar"); } }
+pub fn main() { if false { error!(~"foo" + "bar"); } }
index d7897223d47107a19e21eff3b124c5f07867ad8d..5318e5ca348d379c3be39fc4d8e2aca61a564c95 100644 (file)
@@ -24,7 +24,7 @@ fn check_log<T>(exp: ~str, v: T) {
 }
 
 pub fn main() {
-    let x = list::from_vec(~[a(22u), b(~"hi")]);
+    let x = list::from_vec([a(22u), b(~"hi")]);
     let exp = ~"@Cons(a(22), @Cons(b(~\"hi\"), @Nil))";
     let act = fmt!("%?", x);
     assert!(act == exp);
index 97b8c77c31567ecbdded2ca33a3e5bf5cdeb7ede..a67eb282a142a6ed1a06e9225b55e4f94d2ef2ac 100644 (file)
@@ -20,12 +20,12 @@ struct Smallintmap<T> {v: ~[option<T>]}
 struct V<T> { v: ~[option<T>] }
 
 fn mk<T:'static>() -> @mut Smallintmap<T> {
-    let mut v: ~[option<T>] = ~[];
+    let v: ~[option<T>] = ~[];
     return @mut Smallintmap {v: v};
 }
 
 fn f<T,U:'static>() {
-    let mut sim = mk::<U>();
+    let sim = mk::<U>();
     error!(sim);
 }
 
index 3e4a33981d92f7d22e04f8b47778093d9387ac1b..2b1fb3b779ce97ecadcde1a5bc0e72a06c2f8858 100644 (file)
@@ -8,6 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(unused_variable)];
 
-
-pub fn main() { let mut i: int = 0; while i < 1000000 { i += 1; let x = 3; } }
+pub fn main() {
+    let mut i: int = 0;
+    while i < 1000000 {
+        i += 1;
+        let x = 3;
+    }
+}
index 7ed4a0ba5ce0b748026a3bd926e367624ba3e200..3b7e03ae58de47c00de426db30a7dde74cd24aa5 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 pub fn main() {
-  let i = 0u;
+  let _i = 0u;
   loop {
     break;
   }
diff --git a/src/test/run-pass/macro-local-data-key.rs b/src/test/run-pass/macro-local-data-key.rs
new file mode 100644 (file)
index 0000000..b53d7b3
--- /dev/null
@@ -0,0 +1,28 @@
+// 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.
+
+use std::local_data;
+
+local_data_key!(foo: int)
+
+mod bar {
+    local_data_key!(pub baz: float)
+}
+
+fn main() {
+    local_data::get(foo, |x| assert!(x.is_none()));
+    local_data::get(bar::baz, |y| assert!(y.is_none()));
+
+    local_data::set(foo, 3);
+    local_data::set(bar::baz, -10.0);
+
+    local_data::get(foo, |x| assert_eq!(*x.unwrap(), 3));
+    local_data::get(bar::baz, |y| assert_eq!(*y.unwrap(), -10.0));
+}
index 7a30f5152d01de5ef8ec72483375abe419e6f88c..a33c38d2428743ebaf825dfaec966d7eb09ae7dc 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(unnecessary_allocation)];
+
 fn f1(ref_string: &str) -> ~str {
     match ref_string {
         "a" => ~"found a",
index 0497f11202f3b9a71c8ddc58f9ce564b412583a8..23074894490d6c02a65c3bb1d918a54e2e1511a4 100644 (file)
@@ -13,7 +13,7 @@ struct Pair { a: ~int, b: ~int }
 pub fn main() {
     let mut x = ~Pair {a: ~10, b: ~20};
     match x {
-      ~Pair {a: ref mut a, b: ref mut b} => {
+      ~Pair {a: ref mut a, b: ref mut _b} => {
         assert!(**a == 10); *a = ~30; assert!(**a == 30);
       }
     }
index 649bdd202df10e997f5c49809795d6619ccac7cf..433cf23626bbfa8f17b146cca75132c506e5837d 100644 (file)
@@ -11,7 +11,7 @@
 struct X { x: int }
 
 pub fn main() {
-    let x = match 0 {
+    let _x = match 0 {
       _ => X {
         x: 0
       }.x
index 4d89fdc69104e3ea0859106f0822e27c6480dddb..fe12b7c1585681f23a182737ec57a6f373976723 100644 (file)
@@ -11,7 +11,7 @@
 struct X { x: int }
 
 pub fn main() {
-    let x = match 0 {
+    let _x = match 0 {
       _ => X {
         x: 0
       }
index feabf7a8f4d118e12d0eaf865fe37c986c23252c..2076f46e8ab7bbeab01b9732fff7513dd6a1849d 100644 (file)
 enum maybe<T> { nothing, just(T), }
 
 fn foo(x: maybe<int>) {
-    match x { nothing => { error!("A"); } just(a) => { error!("B"); } }
+    match x {
+        nothing => { error!("A"); }
+        just(_a) => { error!("B"); }
+    }
 }
 
 pub fn main() { }
index f40560081030f54e339999a1e5a401b96a63caa5..92a753902228d59f9838bff9960beca574238d45 100644 (file)
@@ -10,6 +10,6 @@
 
 
 
-fn altsimple(f: int) { match f { x => () } }
+fn altsimple(f: int) { match f { _x => () } }
 
 pub fn main() { }
index 40d215883500256bd51a97248f07623a365bd67a..c25f573e73bce131e51b0b47d87cb17e8468f3c5 100644 (file)
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
+#[allow(dead_assignment)];
+#[allow(unused_variable)];
 
 enum thing { a, b, c, }
 
diff --git a/src/test/run-pass/match-pipe-binding.rs b/src/test/run-pass/match-pipe-binding.rs
new file mode 100644 (file)
index 0000000..b493377
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn test1() {
+    // from issue 6338
+    match ((1, ~"a"), (2, ~"b")) {
+        ((1, a), (2, b)) | ((2, b), (1, a)) => {
+                assert_eq!(a, ~"a");
+                assert_eq!(b, ~"b");
+            },
+            _ => fail!(),
+    }
+}
+
+fn test2() {
+    match (1, 2, 3) {
+        (1, a, b) | (2, b, a) => {
+            assert_eq!(a, 2);
+            assert_eq!(b, 3);
+        },
+        _ => fail!(),
+    }
+}
+
+fn test3() {
+    match (1, 2, 3) {
+        (1, ref a, ref b) | (2, ref b, ref a) => {
+            assert_eq!(*a, 2);
+            assert_eq!(*b, 3);
+        },
+        _ => fail!(),
+    }
+}
+
+fn test4() {
+    match (1, 2, 3) {
+        (1, a, b) | (2, b, a) if a == 2 => {
+            assert_eq!(a, 2);
+            assert_eq!(b, 3);
+        },
+        _ => fail!(),
+    }
+}
+
+fn test5() {
+    match (1, 2, 3) {
+        (1, ref a, ref b) | (2, ref b, ref a) if *a == 2 => {
+            assert_eq!(*a, 2);
+            assert_eq!(*b, 3);
+        },
+        _ => fail!(),
+    }
+}
+
+fn main() {
+    test1();
+    test2();
+    test3();
+    test4();
+    test5();
+}
index fb85064bfdee56e7fbc557a2e58eba43f47aa74c..06d0b4a80ea01261a51e51679671a4f52840ecf8 100644 (file)
@@ -14,7 +14,7 @@ pub fn main() {
     // sometimes we have had trouble finding
     // the right type for f, as we unified
     // bot and u32 here
-    let f = match uint::from_str(~"1234") {
+    let f = match uint::from_str("1234") {
         None => return (),
         Some(num) => num as u32
     };
index 2fc2d4b3716050ace6c1f449d81a86cd21874d2c..21e841b1f60c83630b7477cf2c3ab037b4119630 100644 (file)
@@ -21,4 +21,4 @@ mod m {
     pub fn f() -> ~[int] { vec::from_elem(1u, 0) }
 }
 
-pub fn main() { let x = m::f(); }
+pub fn main() { let _x = m::f(); }
index 87c854d32be8ba584bb12550713f9aaedc5cd841..5655ff8ff2496ff0e87c519b0512d88f4e04834f 100644 (file)
@@ -17,5 +17,5 @@ pub struct S {
 
 pub fn main() {
     let x = m::S { x: 1, y: 2 };
-    let m::S { x: a, y: b } = x;
+    let m::S { x: _a, y: _b } = x;
 }
index eeac89f49669a3eff1c5f50b1b691415297822ca..4529ebf831fdd1d173a1d4d5e53bfe87da43cb54 100644 (file)
@@ -47,7 +47,7 @@ pub fn main() {
     assert_eq!(transform(Some(10)), Some(~"11"));
     assert_eq!(transform(None), None);
     assert!((~[~"hi"])
-        .bind(|x| ~[x.clone(), *x + ~"!"] )
-        .bind(|x| ~[x.clone(), *x + ~"?"] ) ==
+        .bind(|x| ~[x.clone(), *x + "!"] )
+        .bind(|x| ~[x.clone(), *x + "?"] ) ==
         ~[~"hi", ~"hi?", ~"hi!", ~"hi!?"]);
 }
index dbc7886adc99359fb6dadf474beaaa95173796c5..c9e480d3d71761e1b59c1f59128c51d608156a8d 100644 (file)
@@ -21,7 +21,7 @@ fn test(x: bool, foo: @Triple) -> int {
 
 pub fn main() {
     let x = @Triple{x: 1, y: 2, z: 3};
-    for i in range(0u, 10000u) {
+    for _i in range(0u, 10000u) {
         assert_eq!(test(true, x), 2);
     }
     assert_eq!(test(false, x), 5);
index ab66bb936354f406e57eb592fb8f9f5b8b2eb54d..464d915b2c43c60360b75474df7b9ea7e5b4cd03 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // Issue #922
-fn f2(thing: @fn()) { }
+fn f2(_thing: @fn()) { }
 
 fn f(thing: @fn()) {
     f2(thing);
index a3c2872803adce3cdb62aa6881d2f3b5c4954db7..93ea35e262956be5e8a3e22c59013afeabe006bc 100644 (file)
@@ -1,5 +1,3 @@
-use std::str;
-
 struct StringBuffer {
     s: ~str
 }
@@ -20,4 +18,4 @@ fn main() {
     sb.append("World!");
     let str = to_str(sb);
     assert_eq!(str, ~"Hello, World!");
-}
\ No newline at end of file
+}
index fa6dde5b3ef88313d9f93c55db396448da400325..a276e902fbcfca6172680ed17d0e94e7b18ff3c2 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 pub fn main() {
-    let x: &mut [int] = &mut [ 1, 2, 3 ];
+    let _x: &mut [int] = &mut [ 1, 2, 3 ];
 }
index da96e14695246d147fc51160786a69487cf19ce7..d8ea95be658ab674cb80df8f3c7aa7ce97dc665f 100644 (file)
@@ -11,8 +11,6 @@
 // -*- rust -*-
 extern mod extra;
 
-use std::vec;
-
 fn grow(v: &mut ~[int]) {
     v.push(1);
 }
index d807791027f5601fe33b55281d7ef5769d0ff558..5e05722053d4f53b069df23a183568fd48f3c758 100644 (file)
@@ -8,11 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(unused_mut)];
 
 struct Pair { a: int, b: int}
 
 pub fn main() {
     // This just tests whether the vec leaks its members.
-    let mut pvec: ~[@Pair] =
+    let mut _pvec: ~[@Pair] =
         ~[@Pair{a: 1, b: 2}, @Pair{a: 3, b: 4}, @Pair{a: 5, b: 6}];
 }
index 181ec238b0e714eb78164196a375a809784ba44e..cddbf60c382b0766624e4d12c1dd44328ba910a1 100644 (file)
@@ -13,7 +13,7 @@
 
 fn foo() {
     match Some::<int>(5) {
-      Some::<int>(x) => {
+      Some::<int>(_x) => {
         let mut bar;
         match None::<int> { None::<int> => { bar = 5; } _ => { baz(); } }
         info!(bar);
index eee2d18be8e33f350f3ec38bbe8203cb0b8bd5bc..0bc6280393cff82e85bf474c8591207dd68a9945 100644 (file)
@@ -16,8 +16,8 @@ enum t { foo(int, uint), bar(int, Option<int>), }
 
 fn nested(o: t) {
     match o {
-      bar(i, Some::<int>(_)) => { error!("wrong pattern matched"); fail!(); }
-      _ => { error!("succeeded"); }
+        bar(_i, Some::<int>(_)) => { error!("wrong pattern matched"); fail!(); }
+        _ => { error!("succeeded"); }
     }
 }
 
index bd9e4bdfd8724e969c7a72d45152c6e1cd9e3ed5..d901a625e1d1e4816ef80f01b7c3bd608f57eaf9 100644 (file)
@@ -16,7 +16,7 @@ struct C { c: int }
 pub fn main() {
     match A {a: 10, b: @20} {
         x@A {a, b: @20} => { assert!(x.a == 10); assert!(a == 10); }
-        A {b, _} => { fail!(); }
+        A {b: _b, _} => { fail!(); }
     }
     let mut x@B {b, _} = B {a: 10, b: C {c: 20}};
     x.b.c = 30;
index 63569c7198260dd3c8de19f153916ed48b763136..4792caf10c98c0666bd9c6c734edf2e3b34ab307 100644 (file)
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 pub fn main() {
-    let x: @mut [int] = @mut [ 1, 2, 3 ];
+    let _x: @mut [int] = @mut [ 1, 2, 3 ];
 
 }
index c6536c68a83366005fdbf627df0eb066b206db8c..9c2a223174ca1bc1edf59937919ee2f0034993cd 100644 (file)
@@ -12,7 +12,7 @@
 
 fn f(i: int, f: &fn(int) -> int) -> int { f(i) }
 
-fn g(g: &fn()) { }
+fn g(_g: &fn()) { }
 
 fn ff() -> @fn(int) -> int {
     return |x| x + 1;
index b7fdfabff9ab2959879fd62e133276319e92e822..b917bf0810b2d6da4dcadd5d9a673ae87e76f5a4 100644 (file)
@@ -22,7 +22,7 @@ fn drop(&self) {
 fn main() {
     let y = @mut 32;
     {
-        let x = Foo(y);
+        let _x = Foo(y);
     }
     assert_eq!(*y, 23);
 }
index 6062f3075e2024c197dd2a79240c9871fd291049..b58c8738295da925923dba8c2c9c40ce5cacae97 100644 (file)
@@ -4,6 +4,7 @@
 pub struct Fd(c_int);
 
 impl Drop for Fd {
+    #[fixed_stack_segment] #[inline(never)]
     fn drop(&self) {
         unsafe {
             libc::close(**self);
index f37f40935abe74ec82ea764952bd7a849f3d345f..343c4d77702fd3cba06c0c84a129d058f05505c6 100644 (file)
@@ -8,13 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::str;
-
 pub fn main() {
     let thing = ~"{{ f }}";
-    let f = thing.find_str(~"{{");
+    let f = thing.find_str("{{");
 
     if f.is_none() {
-        println(~"None!");
+        println("None!");
     }
 }
index 5c8cfd68240fb48a5f285cbb15d870aee68b15e0..a469e4b86ebcd27c8a76143aac9f5ebd526ca27a 100644 (file)
@@ -17,9 +17,7 @@ struct dtor {
 impl Drop for dtor {
     fn drop(&self) {
         // abuse access to shared mutable state to write this code
-        unsafe {
-            *self.x -= 1;
-        }
+        *self.x -= 1;
     }
 }
 
@@ -35,7 +33,7 @@ pub fn main() {
 
     {
         let b = Some(dtor { x:x });
-        let c = unwrap(b);
+        let _c = unwrap(b);
     }
 
     assert_eq!(*x, 0);
index e45d2280bf0732c1efb0e348b5d5b29cb561cc12..6939a4ab7b783e73477dd1607efb697cb4fec47b 100644 (file)
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(dead_assignment)];
+#[allow(unused_variable)];
+
 struct A { a: int, b: int }
 struct Abox { a: @int, b: @int }
 
index 4a2ff74d064de9612818d46e2c20dd2c63a0909d..cd5d089c361217c94712f20da93f2089284ce84a 100644 (file)
@@ -8,8 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-
+#[allow(unreachable_code)];
 
 // -*- rust -*-
 fn dont_call_me() { fail!(); info!(1); }
index ee90cdc253a715c2d86f1977edc40b537ad6e186..44953c44da327b38b6a6c1b44b63d2170bfadcdf 100644 (file)
@@ -11,7 +11,7 @@
 
 
 mod foo {
-    pub fn bar(offset: uint) { }
+    pub fn bar(_offset: uint) { }
 }
 
 pub fn main() { foo::bar(0u); }
index d3ae339acf27986ea6ff4a19b6b7f75de405e81a..fde1999e72d6a898246f62cec93729964efdad87 100644 (file)
@@ -16,7 +16,7 @@ fn foo(src: uint) {
 
     match Some(src) {
       Some(src_id) => {
-        for i in range(0u, 10u) {
+        for _i in range(0u, 10u) {
             let yyy = src_id;
             assert_eq!(yyy, 0u);
         }
index bee3583c6a496f1e90b291e6dd1c16975ac1530a..b6cb7f48c6d9eed5349840417da8f6b536de20f5 100644 (file)
@@ -15,7 +15,7 @@ struct Foo {
 
 pub fn main() {
     let f = |(x, _): (int, int)| println((x + 1).to_str());
-    let g = |Foo { x: x, y: y }: Foo| println((x + 1).to_str());
+    let g = |Foo { x: x, y: _y }: Foo| println((x + 1).to_str());
     f((2, 3));
     g(Foo { x: 1, y: 2 });
 }
index 127b845ad4ce4d9a89fef13a7787293a1dd22c61..15bf05fc0cbec3f56ade87a4229a776b0216dd87 100644 (file)
@@ -11,6 +11,6 @@
 // this checks that a pred with a non-bool return
 // type is rejected, even if the pred is never used
 
-fn bad(a: int) -> int { return 37; } //~ ERROR Non-boolean return type
+fn bad(_a: int) -> int { return 37; } //~ ERROR Non-boolean return type
 
 pub fn main() { }
index e0ac43f1f04fd0cd031947959aabf6791a6d1fc4..360ac75b3e75357381cc2aebc7fa15828f58b2af 100644 (file)
@@ -6,6 +6,7 @@ mod a {
     }
 }
 
+#[fixed_stack_segment] #[inline(never)]
 fn main() {
     unsafe {
         a::free(transmute(0));
index 74ae81e63e239cd0a52f88af14475a6055dbe569..ca1290d7f7522d600e18a69f721b33edc492a254 100644 (file)
@@ -17,7 +17,7 @@
 use pub_use_xcrate2::Foo;
 
 pub fn main() {
-    let foo: Foo = Foo {
+    let _foo: Foo = Foo {
         name: 0
     };
 }
index 953a99e1fd5be3f25207f09adaa5078dfa897132..ada6cac2eb66452766677013a1e63874ca39967d 100644 (file)
@@ -11,6 +11,8 @@
 // xfail-fast
 // aux-build:pub_use_mods_xcrate.rs
 
+#[allow(unused_imports)];
+
 extern mod pub_use_mods_xcrate;
 use pub_use_mods_xcrate::a::c;
 
index 5ea94020a22f063223bf1871d7da19ec700d1721..63fe744f253129695a027ea60ab83a280699b918 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::vec;
-
 trait sum {
     fn sum_(self) -> int;
 }
@@ -29,7 +27,7 @@ pub fn main() {
     info!("y==%d", y);
     assert_eq!(y, 6);
 
-    let mut x = ~[1, 2, 3];
+    let x = ~[1, 2, 3];
     let y = x.sum_();
     info!("y==%d", y);
     assert_eq!(y, 6);
index f5eb04dd83bfe3774c0466e33fd2820fdb9aac53..d8076f543ecc1436e9145357dd96ace3dafb29c4 100644 (file)
@@ -44,38 +44,38 @@ fn get_v3<'v>(a: &'v A, i: uint) -> &'v int {
     &foo.v3[i]
 }
 
-fn get_v4<'v>(a: &'v A, i: uint) -> &'v int {
+fn get_v4<'v>(a: &'v A, _i: uint) -> &'v int {
     let foo = &a.value;
     &foo.v4.f
 }
 
-fn get_v5<'v>(a: &'v A, i: uint) -> &'v int {
+fn get_v5<'v>(a: &'v A, _i: uint) -> &'v int {
     let foo = &a.value;
     &foo.v5.f
 }
 
-fn get_v6_a<'v>(a: &'v A, i: uint) -> &'v int {
+fn get_v6_a<'v>(a: &'v A, _i: uint) -> &'v int {
     match a.value.v6 {
         Some(ref v) => &v.f,
         None => fail!()
     }
 }
 
-fn get_v6_b<'v>(a: &'v A, i: uint) -> &'v int {
+fn get_v6_b<'v>(a: &'v A, _i: uint) -> &'v int {
     match *a {
         A { value: B { v6: Some(ref v), _ } } => &v.f,
         _ => fail!()
     }
 }
 
-fn get_v6_c<'v>(a: &'v A, i: uint) -> &'v int {
+fn get_v6_c<'v>(a: &'v A, _i: uint) -> &'v int {
     match a {
         &A { value: B { v6: Some(ref v), _ } } => &v.f,
         _ => fail!()
     }
 }
 
-fn get_v5_ref<'v>(a: &'v A, i: uint) -> &'v int {
+fn get_v5_ref<'v>(a: &'v A, _i: uint) -> &'v int {
     match &a.value {
         &B {v5: ~C {f: ref v}, _} => v
     }
index e587fa15f5ccde69395a68b31ddfefcef404cd64..2297277fdc067e2222cf4c8ebc2a514a98b252a4 100644 (file)
@@ -26,6 +26,8 @@ fn testfn(cond: bool) {
     x = @5;
     y = @6;
     assert_eq!(*a, exp);
+    assert_eq!(x, @5);
+    assert_eq!(y, @6);
 }
 
 pub fn main() {
index 96ae71f0ff3eea2ab0dd81733e1a411c0539c497..dbc5bf6626af1086d04f27562617a5f722c0681d 100644 (file)
@@ -12,7 +12,7 @@
 
 fn produce_static<T>() -> &'static T { fail!(); }
 
-fn foo<T>(x: &T) -> &uint { produce_static() }
+fn foo<T>(_x: &T) -> &uint { produce_static() }
 
 pub fn main() {
 }
index 1c8ed8a3dcd5b9f9d88399db0f1fdb193ea94c98..380e6800299139cc3c34db5a79d961edac0c74fa 100644 (file)
@@ -13,7 +13,7 @@ enum ast<'self> {
     add(&'self ast<'self>, &'self ast<'self>)
 }
 
-fn mk_add_ok<'a>(x: &'a ast<'a>, y: &'a ast<'a>, z: &ast) -> ast<'a> {
+fn mk_add_ok<'a>(x: &'a ast<'a>, y: &'a ast<'a>, _z: &ast) -> ast<'a> {
     add(x, y)
 }
 
index 652a7a33396176d28509b41fd30b4646f02e303e..a6b43df1f88a7a6e33f138d44ab4184b50369515 100644 (file)
@@ -10,6 +10,9 @@
 
 // Issue #2263.
 
+#[allow(dead_assignment)];
+#[allow(unused_variable)];
+
 // Should pass region checking.
 fn ok(f: @fn(x: &uint)) {
     // Here, g is a function that can accept a uint pointer with
index 56000d7471d59ee06b179d7996d39a13e7f29723..201584d48a58571231daf8ee855752e2a033359e 100644 (file)
@@ -27,6 +27,7 @@ struct Ccx {
     x: int
 }
 
+#[fixed_stack_segment] #[inline(never)]
 fn alloc<'a>(_bcx : &'a arena) -> &'a Bcx<'a> {
     unsafe {
         cast::transmute(libc::malloc(sys::size_of::<Bcx<'blk>>()
@@ -38,6 +39,7 @@ fn h<'a>(bcx : &'a Bcx<'a>) -> &'a Bcx<'a> {
     return alloc(bcx.fcx.arena);
 }
 
+#[fixed_stack_segment] #[inline(never)]
 fn g(fcx : &Fcx) {
     let bcx = Bcx { fcx: fcx };
     let bcx2 = h(&bcx);
diff --git a/src/test/run-pass/repeat-expr-in-static.rs b/src/test/run-pass/repeat-expr-in-static.rs
new file mode 100644 (file)
index 0000000..d060db2
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+static FOO: [int, ..4] = [32, ..4];
+static BAR: [int, ..4] = [32, 32, 32, 32];
+
+pub fn main() {
+    assert_eq!(FOO, BAR);
+}
index a9c4a114054fda816cb235afa1917a43816e0a35..0f6aaeb3861d4385f9a9e0faa30d10943f4e5ac3 100644 (file)
@@ -15,9 +15,7 @@ struct r {
 #[unsafe_destructor]
 impl Drop for r {
     fn drop(&self) {
-        unsafe {
-            *(self.i) += 1;
-        }
+        *(self.i) += 1;
     }
 }
 
index 1a82e321bd7cf1ec8cc272161d3d3f9ed6f3b72f..0cfd3a93e53506a1ed6df0a914d61d8462532033 100644 (file)
@@ -25,7 +25,7 @@ struct r {
 impl Drop for r {
     fn drop(&self) {
         unsafe {
-            let v2: ~int = cast::transmute(self.v.c);
+            let _v2: ~int = cast::transmute(self.v.c);
         }
     }
 }
index 7eac25535a8cfd76eeaabb8929e22220502a4097..08d56a930d26238697f1ffafa6182a0d0e7469fd 100644 (file)
@@ -15,9 +15,7 @@ struct shrinky_pointer {
 #[unsafe_destructor]
 impl Drop for shrinky_pointer {
     fn drop(&self) {
-        unsafe {
-            error!(~"Hello!"); **(self.i) -= 1;
-        }
+        error!(~"Hello!"); **(self.i) -= 1;
     }
 }
 
index 836b49f9a1520429a091dfb72d8dc52a1d413212..5fdda9dc0790900cfffb72fbb6666a41010befe0 100644 (file)
@@ -21,9 +21,7 @@ struct close_res {
 #[unsafe_destructor]
 impl Drop for close_res {
     fn drop(&self) {
-        unsafe {
-            *(self.i) = false;
-        }
+        *(self.i) = false;
     }
 }
 
@@ -35,7 +33,7 @@ fn close_res(i: closable) -> close_res {
 
 enum option<T> { none, some(T), }
 
-fn sink(res: option<close_res>) { }
+fn sink(_res: option<close_res>) { }
 
 pub fn main() {
     let c = @mut true;
index c86c63942284cd6b9fc1683bc002df6e6271a9ed..b5a81268a2dcf7a3c9332e35bc66feb92ceda939 100644 (file)
@@ -12,4 +12,4 @@
 
 fn f() { let x: () = (); return x; }
 
-pub fn main() { let x = f(); }
+pub fn main() { let _x = f(); }
index a647e5849a8ee4036ab9eb63f7dda69904271b22..4e4d3436fb0fd3b57faa0b96cc065cb4d638d30b 100644 (file)
@@ -23,13 +23,13 @@ fn iloop() {
     task::spawn(|| die() );
     let (p, c) = comm::stream::<()>();
     loop {
-        // Sending and receiving here because these actions yield,
+        // Sending and receiving here because these actions deschedule,
         // at which point our child can kill us.
         c.send(());
         p.recv();
         // The above comment no longer makes sense but I'm
         // reluctant to remove a linked failure test case.
-        task::yield();
+        task::deschedule();
     }
 }
 
index e450e1f48c0180160bcf476f9b18e0bec66eda4c..e3435fd547b189f7eb48521b7ca8759405ae99e2 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::comm::*;
 use std::task;
 
 struct test {
index 4fcbc789f57b25927fd959aaad183a28d80bc9ae..79b05915b016c5ed81846255a66d113f2839a125 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::comm::*;
-
 // tests that ctrl's type gets inferred properly
 struct Command<K, V> {
     key: K,
@@ -17,7 +15,7 @@ struct Command<K, V> {
 }
 
 fn cache_server<K:Send,V:Send>(c: Chan<Chan<Command<K, V>>>) {
-    let (ctrl_port, ctrl_chan) = stream();
+    let (_ctrl_port, ctrl_chan) = stream();
     c.send(ctrl_chan);
 }
 pub fn main() { }
index 5109f3c92f1f2af5b9aa40ec4e7ad54a1691616d..2d3b505dfa60aa4d878161810f25d5ea3e35244e 100644 (file)
@@ -16,7 +16,7 @@ fn foo(c: ~[int]) {
 
     match none::<int> {
         some::<int>(_) => {
-            for i in c.iter() {
+            for _i in c.iter() {
                 info!(a);
                 let a = 17;
                 b.push(a);
index 973c38438948a17fb53cf691c3243c444876d91f..7c9fef93943be5f30e0f598b8f6ac5787b196ce6 100644 (file)
@@ -16,7 +16,7 @@ enum clam<T> { a(T, int), b, }
 
 fn uhoh<T>(v: ~[clam<T>]) {
     match v[1] {
-      a::<T>(ref t, ref u) => { info!("incorrect"); info!(u); fail!(); }
+      a::<T>(ref _t, ref u) => { info!("incorrect"); info!(u); fail!(); }
       b::<T> => { info!("correct"); }
     }
 }
index bbd5857335db6eb019211e578d5b7fe3e081ee54..1e5ea7126e4403396c409eac4f34335c2457d53b 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// xfail-test - FIXME(#8538) some kind of problem linking induced by extern "C" fns that I do not understand
 // xfail-fast - windows doesn't like this
 
 // Smallest hello world with no runtime
index ca0c066043de0edc59f6c62bcefd2aae1cf9dca1..1825f1bcca339ed229e541c4749319f455180283 100644 (file)
@@ -21,5 +21,5 @@ pub fn main() {
     task::spawn(|| x(~"hello from second spawned fn", 66) );
     task::spawn(|| x(~"hello from third spawned fn", 67) );
     let mut i: int = 30;
-    while i > 0 { i = i - 1; info!("parent sleeping"); task::yield(); }
+    while i > 0 { i = i - 1; info!("parent sleeping"); task::deschedule(); }
 }
index f448d74c4bd5b52ca1045e939552e07ed431593b..111e0df1d6d5c85d74e0cd13c31933f711403053 100644 (file)
   Arnold.
  */
 
-use std::comm::*;
 use std::task;
 
 type ctx = Chan<int>;
 
-fn iotask(cx: &ctx, ip: ~str) {
+fn iotask(_cx: &ctx, ip: ~str) {
     assert_eq!(ip, ~"localhost");
 }
 
 pub fn main() {
-    let (p, ch) = stream::<int>();
+    let (_p, ch) = stream::<int>();
     task::spawn(|| iotask(&ch, ~"localhost") );
 }
index 057bc57269d19bea8e54668d67dc5571aeb6ad93..d0dde4ad3c479573568096be21e9b737fed03e83 100644 (file)
@@ -16,7 +16,6 @@
 use std::io::WriterUtil;
 use std::io;
 use std::os;
-use std::uint;
 
 pub fn main() {
     let dir = tempfile::mkdtemp(&Path("."), "").unwrap();
index 457c5a3352d124aef89396c8739c51bc277f4993..e2bf525df1a125ae0dcdbd7e4a70a38f6a0bb1b2 100644 (file)
@@ -11,7 +11,6 @@
 // xfail-fast
 
 use std::uint;
-use std::vec;
 
 pub trait plus {
     fn plus(&self) -> int;
index 7af143a1529203406e27fa9faeb67f672e2e54b1..429b49375e0daa0576e3f8c1405dff560eed200b 100644 (file)
@@ -26,6 +26,7 @@ fn static_bound_set(a: &'static mut libc::c_int) {
     *a = 3;
 }
 
+#[fixed_stack_segment] #[inline(never)]
 unsafe fn run() {
     assert!(debug_static_mut == 3);
     debug_static_mut = 4;
index 5ac3c0530af5a4af639b3a5c1e011b7599ad7ad5..331701107a8a2a493d756af2d1df654c303a8773 100644 (file)
@@ -24,8 +24,8 @@ fn test2() {
     // This tests for issue #163
 
     let ff: ~str = ~"abc";
-    let a: ~str = ff + ~"ABC" + ff;
-    let b: ~str = ~"ABC" + ff + ~"ABC";
+    let a: ~str = ff + "ABC" + ff;
+    let b: ~str = ~"ABC" + ff + "ABC";
     info!(a.clone());
     info!(b.clone());
     assert_eq!(a, ~"abcABCabc");
index e01b2a42f61392685a4870d05bc14eb49b6e0a34..b1b90468e94f0d8f3e6f881b5cb1d43f19966c92 100644 (file)
@@ -10,8 +10,6 @@
 
 extern mod extra;
 
-use std::str;
-
 pub fn main() {
     // Make sure we properly handle repeated self-appends.
     let mut a: ~str = ~"A";
index bc2dce680c956d815f18d7572f0993d4aa4c6c2a..4e16b5cb4cc114c44e547e161c94c092862f4107 100644 (file)
@@ -20,5 +20,5 @@ enum Foo {
 }
 
 pub fn main() {
-    let x = Bar { a: 2, b: 3 };
+    let _x = Bar { a: 2, b: 3 };
 }
index 42908a339d200dbea1210087747f71cbaeebfaa7..1b7089427580e7c8264a2a7b5eea4d424c50396d 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::str;
-
 struct S { f0: ~str, f1: int }
 
 pub fn main() {
index b6851a728882a94fe4fafe912ef436f7b7722505..a576e29578412a99a4cc1641ea935361f8ab3abd 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::str;
-
 struct S { f0: ~str, f1: ~str }
 
 pub fn main() {
index bf9d070c84ca68351377d5073ded89c677a8cbb2..1c39504ba717bc5cf5f7c9773983f049c753bcec 100644 (file)
@@ -21,6 +21,7 @@ mod rustrt {
     }
 }
 
+#[fixed_stack_segment] #[inline(never)]
 fn test1() {
     unsafe {
         let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa_u64,
@@ -40,6 +41,8 @@ fn test1() {
 }
 
 #[cfg(target_arch = "x86_64")]
+#[fixed_stack_segment]
+#[inline(never)]
 fn test2() {
     unsafe {
         let f = Floats { a: 1.234567890e-15_f64,
index 927ec6997273862603d2fadd1856e1e0a6b71b92..5349d0554b1b76811d6d8c68316afd72737538be 100644 (file)
@@ -11,7 +11,6 @@
 // Issue #5041 - avoid overlapping memcpy when src and dest of a swap are the same
 
 use std::ptr;
-use std::util;
 
 pub fn main() {
     let mut test = TestDescAndFn {
index 7c90b38bae1c9f6686c99216d51614cd25987c0b..8e5892b6db194afde2f8388699d18c45475ba3d7 100644 (file)
@@ -17,7 +17,7 @@ fn test(actual: ~str, expected: ~str) {
 }
 
 pub fn main() {
-    test(fmt!("hello %d friends and %s things", 10, ~"formatted"),
+    test(fmt!("hello %d friends and %s things", 10, "formatted"),
          ~"hello 10 friends and formatted things");
 
     test(fmt!("test"), ~"test");
@@ -42,7 +42,7 @@ fn part1() {
     test(fmt!("%i", 2), ~"2");
     test(fmt!("%i", -1), ~"-1");
     test(fmt!("%u", 10u), ~"10");
-    test(fmt!("%s", ~"test"), ~"test");
+    test(fmt!("%s", "test"), ~"test");
     test(fmt!("%b", true), ~"true");
     test(fmt!("%b", false), ~"false");
     test(fmt!("%c", 'A'), ~"A");
@@ -70,7 +70,7 @@ fn part2() {
     test(fmt!("%10d", 500), ~"       500");
     test(fmt!("%10d", -500), ~"      -500");
     test(fmt!("%10u", 500u), ~"       500");
-    test(fmt!("%10s", ~"test"), ~"      test");
+    test(fmt!("%10s", "test"), ~"      test");
     test(fmt!("%10b", true), ~"      true");
     test(fmt!("%10x", 0xff_u), ~"        ff");
     test(fmt!("%10X", 0xff_u), ~"        FF");
@@ -83,7 +83,7 @@ fn part2() {
     test(fmt!("%-10d", 500), ~"500       ");
     test(fmt!("%-10d", -500), ~"-500      ");
     test(fmt!("%-10u", 500u), ~"500       ");
-    test(fmt!("%-10s", ~"test"), ~"test      ");
+    test(fmt!("%-10s", "test"), ~"test      ");
     test(fmt!("%-10b", true), ~"true      ");
     test(fmt!("%-10x", 0xff_u), ~"ff        ");
     test(fmt!("%-10X", 0xff_u), ~"FF        ");
@@ -103,7 +103,7 @@ fn part3() {
     test(fmt!("%.d", 10), ~"10");
     test(fmt!("%.d", -10), ~"-10");
     test(fmt!("%.u", 10u), ~"10");
-    test(fmt!("%.s", ~"test"), ~"");
+    test(fmt!("%.s", "test"), ~"");
     test(fmt!("%.x", 127u), ~"7f");
     test(fmt!("%.o", 10u), ~"12");
     test(fmt!("%.t", 3u), ~"11");
@@ -116,7 +116,7 @@ fn part3() {
     test(fmt!("%.0d", 10), ~"10");
     test(fmt!("%.0d", -10), ~"-10");
     test(fmt!("%.0u", 10u), ~"10");
-    test(fmt!("%.0s", ~"test"), ~"");
+    test(fmt!("%.0s", "test"), ~"");
     test(fmt!("%.0x", 127u), ~"7f");
     test(fmt!("%.0o", 10u), ~"12");
     test(fmt!("%.0t", 3u), ~"11");
@@ -129,7 +129,7 @@ fn part3() {
     test(fmt!("%.1d", 10), ~"10");
     test(fmt!("%.1d", -10), ~"-10");
     test(fmt!("%.1u", 10u), ~"10");
-    test(fmt!("%.1s", ~"test"), ~"t");
+    test(fmt!("%.1s", "test"), ~"t");
     test(fmt!("%.1x", 127u), ~"7f");
     test(fmt!("%.1o", 10u), ~"12");
     test(fmt!("%.1t", 3u), ~"11");
@@ -144,7 +144,7 @@ fn part4() {
     test(fmt!("%.5d", 10), ~"00010");
     test(fmt!("%.5d", -10), ~"-00010");
     test(fmt!("%.5u", 10u), ~"00010");
-    test(fmt!("%.5s", ~"test"), ~"test");
+    test(fmt!("%.5s", "test"), ~"test");
     test(fmt!("%.5x", 127u), ~"0007f");
     test(fmt!("%.5o", 10u), ~"00012");
     test(fmt!("%.5t", 3u), ~"00011");
@@ -195,7 +195,7 @@ fn part5() {
     test(fmt!("%05f", 5.82), ~"05.82");
     // 0-padding a string is undefined but glibc does this:
 
-    test(fmt!("%05s", ~"test"), ~" test");
+    test(fmt!("%05s", "test"), ~" test");
     test(fmt!("%05c", 'A'), ~"    A");
     test(fmt!("%05b", true), ~" true");
     // Left-justify overrides 0-padding
@@ -208,7 +208,7 @@ fn part5() {
     test(fmt!("%-05X", 127u), ~"7F   ");
     test(fmt!("%-05o", 10u), ~"12   ");
     test(fmt!("%-05t", 3u), ~"11   ");
-    test(fmt!("%-05s", ~"test"), ~"test ");
+    test(fmt!("%-05s", "test"), ~"test ");
     test(fmt!("%-05c", 'A'), ~"A    ");
     test(fmt!("%-05b", true), ~"true ");
     test(fmt!("%-05f", 5.82), ~"5.82 ");
@@ -223,7 +223,7 @@ fn part6() {
     test(fmt!("%06.5d", 10), ~" 00010");
     test(fmt!("%06.5d", -10), ~"-00010");
     test(fmt!("%06.5u", 10u), ~" 00010");
-    test(fmt!("%06.5s", ~"test"), ~"  test");
+    test(fmt!("%06.5s", "test"), ~"  test");
     test(fmt!("%06.5c", 'A'), ~"     A");
     test(fmt!("%06.5x", 127u), ~" 0007f");
     test(fmt!("%06.5X", 127u), ~" 0007F");
index 497a55b7c78e29379040fad945003bee8f9e7730..819bcbf53f588bcce72e37ba78b6219c93805a34 100644 (file)
@@ -14,5 +14,5 @@ pub fn main() {
     assert_eq!(concat_idents!(asd, f_f, dsa), ~"<.<");
 
     assert!(stringify!(use_mention_distinction) ==
-                ~"use_mention_distinction");
+                "use_mention_distinction");
 }
index eceba6cf7b18ed85c7f754e802b71f3d2b27722e..91d10adfbfbaed0f937997c64e56121ac2de3613 100644 (file)
@@ -23,17 +23,17 @@ pub fn main() {
     assert_eq!(line!(), 23);
     //assert!((col!() == 11));
     assert_eq!(indirect_line!(), 25);
-    assert!((file!().to_owned().ends_with(~"syntax-extension-source-utils.rs")));
+    assert!((file!().to_owned().ends_with("syntax-extension-source-utils.rs")));
     assert_eq!(stringify!((2*3) + 5).to_owned(), ~"( 2 * 3 ) + 5");
     assert!(include!("syntax-extension-source-utils-files/includeme.fragment").to_owned()
            == ~"victory robot 6");
 
     assert!(
         include_str!("syntax-extension-source-utils-files/includeme.fragment").to_owned()
-        .starts_with(~"/* this is for "));
+        .starts_with("/* this is for "));
     assert!(
         include_bin!("syntax-extension-source-utils-files/includeme.fragment")
         [1] == (42 as u8)); // '*'
     // The Windows tests are wrapped in an extra module for some reason
-    assert!((m1::m2::where_am_i().ends_with(~"m1::m2")));
+    assert!((m1::m2::where_am_i().ends_with("m1::m2")));
 }
index b3f1d128843f15a8493272474fc303de86708076..99eacb54d17e45d5e407b0c37552265b518d9ad6 100644 (file)
@@ -11,7 +11,7 @@
 
 
 fn foo() {
-    fn zed(z: bar) { }
+    fn zed(_z: bar) { }
     enum bar { nil, }
     fn baz() { zed(nil); }
 }
index 686cafb0119081caa1fe30e1e2901d3b9e5d4bd0..7eb879782d1d7e41a56766588811d72aa52fa01a 100644 (file)
@@ -13,7 +13,6 @@
 extern mod extra;
 
 use std::comm::Chan;
-use std::comm::Port;
 use std::comm;
 use std::task;
 
index 15fbf8c07b80ca17bed40ab4332c6433c44b8cf6..fd0d9568845c147903baa1761f965f88aab1100d 100644 (file)
@@ -31,10 +31,10 @@ fn start(c: &comm::Chan<comm::Chan<~str>>) {
 
 pub fn main() {
     let (p, ch) = comm::stream();
-    let child = task::spawn(|| start(&ch) );
+    let _child = task::spawn(|| start(&ch) );
 
     let c = p.recv();
     c.send(~"A");
     c.send(~"B");
-    task::yield();
+    task::deschedule();
 }
index 8931531d5445ea504ceea1f6d773a98fca79fdde..5d1a68e6cc74b2d430f5eec84cc68e7e8d669b8a 100644 (file)
 use std::task;
 
 fn start(c: &comm::Chan<comm::Chan<int>>) {
-    let (p, ch) = comm::stream();
+    let (_p, ch) = comm::stream();
     c.send(ch);
 }
 
 pub fn main() {
     let (p, ch) = comm::stream();
-    let child = task::spawn(|| start(&ch) );
-    let c = p.recv();
+    let _child = task::spawn(|| start(&ch) );
+    let _c = p.recv();
 }
index fd2e81d062e8ebe3a011cf4d266c667d10a709da..7e741959a9c4fef35f05568a47a1d81203df71dd 100644 (file)
@@ -14,7 +14,7 @@
 
 pub fn main() { test00(); }
 
-fn start(task_number: int) { info!("Started / Finished task."); }
+fn start(_task_number: int) { info!("Started / Finished task."); }
 
 fn test00() {
     let i: int = 0;
@@ -28,7 +28,7 @@ fn test00() {
     // Sleep long enough for the task to finish.
     let mut i = 0;
     while i < 10000 {
-        task::yield();
+        task::deschedule();
         i += 1;
     }
 
index 3caf3464563983a61fe3d990b4f0975708c48353..b039f01bf0cd90f0efd714bd24a161203110d230 100644 (file)
@@ -22,7 +22,7 @@ fn start(c: &comm::Chan<int>, start: int, number_of_messages: int) {
 
 pub fn main() {
     info!("Check that we don't deadlock.");
-    let (p, ch) = comm::stream();
+    let (_p, ch) = comm::stream();
     task::try(|| start(&ch, 0, 10) );
     info!("Joined task");
 }
index b9083f289725d266de6333d6576dd3084064ac5d..ae6eb6acee417d13d64a875633f3d715101dd1a2 100644 (file)
@@ -55,7 +55,7 @@ fn test00() {
 
     // Read from spawned tasks...
     let mut sum = 0;
-    for r in results.iter() {
+    for _r in results.iter() {
         i = 0;
         while i < number_of_messages {
             let value = po.recv();
index 5b0ebb0fa2508456a54364bca662cdab4ecb5e21..ecc344e7ba6ac41d353470434da3fc0fa2d4dc4c 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(dead_assignment)];
+
 use std::comm;
 
 pub fn main() { test00(); }
index 472a7d7e3da7df81620685bdc3410af78ea302a4..40cc7ef49e9d2d6e23e8d05c5070ced88cfec937 100644 (file)
@@ -15,7 +15,7 @@
 pub fn main() { test00(); }
 
 fn test00() {
-    let r: int = 0;
+    let _r: int = 0;
     let mut sum: int = 0;
     let (p, c) = comm::stream();
     let number_of_messages: int = 1000;
index 0da0d5877229d1cc82ce5fbe0efd8c272ae267a2..b398ab41ed631f47a75917b8edf5e25c3b433506 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(dead_assignment)];
+
 use std::comm::SharedChan;
 use std::comm;
 
index 33d721f5f380646135ca364d84fd1f2bec3b46b7..c7c16af597cff02f1a236d765385f326b891bc57 100644 (file)
@@ -10,6 +10,8 @@
 
 // xfail-fast
 
+#[allow(dead_assignment)];
+
 extern mod extra;
 
 use std::comm;
index b8a1aa433a30a3e6492d7876dac1162a60168919..ac9b7a315f809055bdf26103985793ac8ce2453d 100644 (file)
@@ -69,11 +69,11 @@ fn join(port: Port<bool>) -> bool {
 }
 
 fn supervised() {
-    // Yield to make sure the supervisor joins before we
+    // Deschedule to make sure the supervisor joins before we
     // fail. This is currently not needed because the supervisor
     // runs first, but I can imagine that changing.
     error!("supervised task=%?", 0);
-    task::yield();
+    task::deschedule();
     fail!();
 }
 
index 5382ac77671392787232a58d60b1c4d8d1973f22..d995bd7e3a34ebc3afd82d496da3c5459d2ade24 100644 (file)
 use std::task;
 
 fn supervised() {
-    // Yield to make sure the supervisor joins before we fail. This is
+    // Deschedule to make sure the supervisor joins before we fail. This is
     // currently not needed because the supervisor runs first, but I can
     // imagine that changing.
-    task::yield();
+    task::deschedule();
     fail!();
 }
 
index 370971bd7b9019984f3d6e52b0e2f95fff47d967..b58fe2aad5805026e92c07659f0e94a6441ae185 100644 (file)
@@ -16,6 +16,6 @@ pub fn main() {
     task::spawn(|| child(~"Hello") );
 }
 
-fn child(s: ~str) {
+fn child(_s: ~str) {
 
 }
index f3a105e08527e1029e1fa75ad4579720a1f856f5..92697054be33b583cb4205bb6bddde240854a3fb 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::comm::*;
 use std::ptr;
 use std::task;
 
index 6d34f7a970198d83e9c025b7b2d6932a5f0d3c58..62543971cce74973dace94bfa28fa01a59f7bd77 100644 (file)
 
 use std::task;
 
-fn test_break() { loop { let x: @int = break; } }
+fn test_break() { loop { let _x: @int = break; } }
 
-fn test_cont() { let mut i = 0; while i < 1 { i += 1; let x: @int = loop; } }
+fn test_cont() { let mut i = 0; while i < 1 { i += 1; let _x: @int = loop; } }
 
-fn test_ret() { let x: @int = return; }
+fn test_ret() { let _x: @int = return; }
 
 fn test_fail() {
-    fn f() { let x: @int = fail!(); }
+    fn f() { let _x: @int = fail!(); }
     task::try(|| f() );
 }
 
 fn test_fail_indirect() {
     fn f() -> ! { fail!(); }
-    fn g() { let x: @int = f(); }
+    fn g() { let _x: @int = f(); }
     task::try(|| g() );
 }
 
index 38b386838a1b4816aa57228762006cc53b2df4e5..0c334909b259cc778be16b44cfbfb4df18dd911a 100644 (file)
@@ -10,7 +10,7 @@ fn f<T: aux::A>(i: T) {
     assert_eq!(i.g(), 10);
 }
 
-fn welp<T>(i: int, x: &T) -> int {
+fn welp<T>(i: int, _x: &T) -> int {
     i.g()
 }
 
index f56eca693ea53796e6126503ede3e2c600ab7752..aee954df4616bf890a173837b4c5331182ab5f1a 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::cmp::{Eq, Ord};
+use std::cmp::Eq;
 use std::num::NumCast;
 
 pub trait NumExt: Eq + Num + NumCast {}
index 1f5c33e2bc0973b39194de1947ea8718542af101..e95b80447e4812614a4e010910420a753b566443 100644 (file)
@@ -23,7 +23,7 @@ pub struct Foo {
 
     impl ::base::HasNew<Foo> for Foo {
         fn new() -> Foo {
-            unsafe { println("Foo"); }
+            println("Foo");
             Foo { dummy: () }
         }
     }
@@ -34,13 +34,13 @@ pub struct Bar {
 
     impl ::base::HasNew<Bar> for Bar {
         fn new() -> Bar {
-            unsafe { io::println("Bar"); }
+            io::println("Bar");
             Bar { dummy: () }
         }
     }
 }
 
 pub fn main() {
-    let f: base::Foo = base::HasNew::new::<base::Foo, base::Foo>();
-    let b: base::Bar = base::HasNew::new::<base::Bar, base::Bar>();
+    let _f: base::Foo = base::HasNew::new::<base::Foo, base::Foo>();
+    let _b: base::Bar = base::HasNew::new::<base::Bar, base::Bar>();
 }
index 493b810c10488592307665dace81dc2b45a282e5..8982b35ff33a63ad5816874956e14045720bb099 100644 (file)
@@ -38,7 +38,7 @@ pub fn main() {
     assert!((~[2, 3, 4]).to_str() == ~"[2, 3, 4]");
 
     fn indirect<T:to_str>(x: T) -> ~str {
-        x.to_str() + ~"!"
+        x.to_str() + "!"
     }
     assert!(indirect(~[10, 20]) == ~"[10, 20]!");
 
index fee766464582ce0e2ba7b55ec9ac701f22ae7e1f..0c5be72432c301288f8faf89b8c7cc3b363de4da 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(dead_assignment)];
+#[allow(unused_variable)];
 
 trait Foo {
     fn foo(&self, mut v: int) { v = 1; }
index e2ccee013c24f77c7fbbb8f294f83cad18d2bcef..f0b7ee072ea5eecae00270f7ea3795b45068ff71 100644 (file)
@@ -14,7 +14,7 @@ mod a {
     pub mod b {
         pub type t = int;
 
-        pub fn foo() { let x: t = 10; }
+        pub fn foo() { let _x: t = 10; }
     }
 }
 
index 8968fe49bc1d4ab0aa91439ff7f5a06e0d9c5497..4d6efc9772ce096a49b10ce0586863fd5b29b794 100644 (file)
@@ -10,9 +10,9 @@
 
 // xfail-fast
 
-fn p_foo<T>(pinned: T) { }
-fn s_foo<T>(shared: T) { }
-fn u_foo<T:Send>(unique: T) { }
+fn p_foo<T>(_pinned: T) { }
+fn s_foo<T>(_shared: T) { }
+fn u_foo<T:Send>(_unique: T) { }
 
 struct r {
   i: int,
index a0cecb3142775de21c941f8fb62359f0261df36b..a5a9075af7b247e0d9f1af8cdd50ef00a7d184fe 100644 (file)
@@ -18,8 +18,10 @@ fn range_(lo: uint, hi: uint, it: &fn(uint)) {
     while lo_ < hi { it(lo_); lo_ += 1u; }
 }
 
-fn create_index<T>(index: ~[S<T>], hash_fn: extern fn(T) -> uint) {
-    range_(0u, 256u, |_i| { let bucket: ~[T] = ~[]; } )
+fn create_index<T>(_index: ~[S<T>], _hash_fn: extern fn(T) -> uint) {
+    do range_(0u, 256u) |_i| {
+        let _bucket: ~[T] = ~[];
+    }
 }
 
 pub fn main() { }
index 997464ba50a786e00dfe5ee02d900f425afb27a1..6a2757c6b30026f64145a9a274762c0ddc319d0c 100644 (file)
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
+#[allow(dead_assignment)];
+#[allow(unused_variable)];
 
 fn f() {
     let x = 10; let mut y = 11;
index b865b302668bd8470cd49dea94af3bab57dd0dbf..9b645efb936cfe51bfcaf5b6e073004d028cbf12 100644 (file)
@@ -12,4 +12,4 @@
 
 
 // -*- rust -*-
-pub fn main() { let x: uint = 10 as uint; }
+pub fn main() { let _x: uint = 10 as uint; }
index 3277b878a414c55c9abac3248c44ad8705c077fa..7300ca989a31c81610a802b9b5dc9f5ee35234fd 100644 (file)
@@ -19,15 +19,15 @@ pub fn main() {
 
     let c = 1;
     let c_neg: i32 = -c;
-    error!(b_neg);
+    error!(c_neg);
 
     let d = 1;
     let d_neg: i64 = -d;
-    error!(b_neg);
+    error!(d_neg);
 
     let e = 1;
     let e_neg: int = -e;
-    error!(b_neg);
+    error!(e_neg);
 
     // intentional overflows
 
index 2205eaeb97cc9160454d687e8f46fa5be8887bfe..9144ecc74f98a39f47abea9a5b197123913e4633 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(dead_assignment)];
+
 pub fn main() {
     let i = ~1;
     let mut j = ~2;
index ba5627fee5229d93f3a8a1196085e44587eab198..1ebd584aa5fa764553f7d588c71c59e8231a2176 100644 (file)
@@ -11,7 +11,7 @@
 pub fn main() {
     enum t { t1(int), t2(int), }
 
-    let x = ~t1(10);
+    let _x = ~t1(10);
 
     /*alt *x {
       t1(a) {
index 3b3074b4a7d05e87433b1d5365a6e3c46537cc09..16fb4eba5ba089853902440695f489431627e6be 100644 (file)
@@ -8,16 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(unused_variable)];
+
 use std::sys;
 
 pub fn main() {
-    unsafe {
-        let i = ~@1;
-        let j = ~@2;
-        let rc1 = sys::refcount(*i);
-        let j = i.clone();
-        let rc2 = sys::refcount(*i);
-        error!("rc1: %u rc2: %u", rc1, rc2);
-        assert_eq!(rc1 + 1u, rc2);
-    }
+    let i = ~@1;
+    let j = ~@2;
+    let rc1 = sys::refcount(*i);
+    let j = i.clone();
+    let rc2 = sys::refcount(*i);
+    error!("rc1: %u rc2: %u", rc1, rc2);
+    assert_eq!(rc1 + 1u, rc2);
 }
index 31c1936b05a4cc1739245b54ff66e8d6147837e5..74b73d773699815329417acc2a2af41c6f1323a6 100644 (file)
@@ -12,6 +12,6 @@ pub fn main() {
     let _: ~int;
 }
 
-fn f(i: ~int) -> ~int {
+fn f(_i: ~int) -> ~int {
     fail!();
 }
index aabf6c7878efe2e9d0aab883c355c374e2aa9d5a..2090352f9ce08c756c05a61f5a72d08fb976de5a 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 pub fn main() {
-    let x = ~~[0,0,0,0,0];
+    let _x = ~~[0,0,0,0,0];
 }
index 55145255840008e2dfa80f1862878db3b5d19f6c..6a87dd30f7a78aff0894e6a1f42cc6289b263e0b 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 pub fn main() {
-    let i = ~100;
+    let _i = ~100;
 }
index 29267956a59f41df1c90e05b48018645056c6fcc..cbef0044f8cf888f0a868607cc819b65ec1fcd08 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(unused_variable)];
+
 pub fn main() {
     let i = ~100;
     let j = ~200;
index 540de1652138b3b8e7663ba734f961db9f9f2e27..f6a4674136671cc463cfdcbd81213c62c0e0d367 100644 (file)
@@ -20,5 +20,5 @@ impl EventLoop for UvEventLoop { }
 
 pub fn main() {
     let loop_: ~EventLoop = ~UvEventLoop { uvio: 0 } as ~EventLoop;
-    let loop2_ = loop_;
-}
\ No newline at end of file
+    let _loop2_ = loop_;
+}
index b0ad7f50420a17ddf54df768f78961c9e353cb7a..7b604bb7857c9455fd97a75427209f2874dbb96a 100644 (file)
@@ -15,9 +15,7 @@ struct r {
 #[unsafe_destructor]
 impl Drop for r {
     fn drop(&self) {
-        unsafe {
-            *(self.i) = *(self.i) + 1;
-        }
+        *(self.i) = *(self.i) + 1;
     }
 }
 
@@ -30,7 +28,7 @@ fn r(i: @mut int) -> r {
 pub fn main() {
     let i = @mut 0;
     {
-        let j = ~r(i);
+        let _j = ~r(i);
     }
     assert_eq!(*i, 1);
 }
index 05012f789c38fed83472193d05ab6607320432c4..a7d2f6a16a17663880df1c22d6a1a2052fc9c192 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::comm::*;
-
 pub fn main() {
     let (p, c) = stream();
     c.send(~100);
index 78510a574597564d187a6a5fab8eb70fbe0dc36e..a74bfc365e864876aa0d2f0107e6e5e6486ede2a 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-
+#[allow(unused_variable)];
+#[allow(dead_assignment)];
 
 // -*- rust -*-
 fn f(u: ()) { return u; }
index 649f424ec36bea8afc4447f97ca19dcf11782f78..c52658542f05b539a521ba3bcd805080df8301c8 100644 (file)
@@ -1,11 +1,11 @@
-fn good(a: &int) {
+fn good(_a: &int) {
 }
 
 // unnamed argument &int is now parse x: &int
 
-fn called(f: &fn(&int)) {
+fn called(_f: &fn(&int)) {
 }
 
 pub fn main() {
-called(good);
+    called(good);
 }
index 9c658fdc252760f55df4b26c62b00c1158f6cea4..d1896a258c63426a233c093366814085725b6120 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(unreachable_code)];
+#[allow(unused_variable)];
 
 fn id(x: bool) -> bool { x }
 
index 153df44e2ef3123dbc6c257069a3c3e6af9b5c2f..2c65e2283e8ed6ba1a39a0442773bdb9e6dbe6bf 100644 (file)
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(path_statement)];
+#[allow(unreachable_code)];
+#[allow(unused_variable)];
 
 fn id(x: bool) -> bool { x }
 
index 62023fdae53b5481fa7bd27270e700b60af73f63..dd70b7daa700516ea0d5217c592ef16b59fc8cbe 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 pub fn main() {
-    let x = ~1;
+    let _x = ~1;
     let lam_move: @fn() = || {};
     lam_move();
 }
index 69ce791c1a35aa56c8a93b08a5276b80ef2d39f0..375e8664781d97e265fd90f6148bf22e3ceb5b36 100644 (file)
@@ -12,6 +12,8 @@
 // Issue Name: Unused move causes a crash
 // Abstract: zero-fill to block after drop
 
+#[allow(path_statement)];
+
 pub fn main()
 {
     let y = ~1;
index 2d0967a6fa36009660f577ac9322a2fa7a89f7dc..2d21f7e8f98ee06734ebbab879074ff081bd9855 100644 (file)
@@ -14,7 +14,7 @@
 use std::task;
 
 fn f() {
-    let a = @0;
+    let _a = @0;
     fail!();
 }
 
index 841fb37d29d50a945d9593e66f595d61b9d6fa59..e2023bc5f21705dc8c750c9dff9b003fdf2d2487 100644 (file)
@@ -29,7 +29,7 @@ fn complainer(c: @int) -> complainer {
 }
 
 fn f() {
-    let c = complainer(@0);
+    let _c = complainer(@0);
     fail!();
 }
 
index ba75676298b4e96918c489c66169dc7ddf487d80..85b4c0b9b47edd233a695bbd4ec402e980592425 100644 (file)
@@ -14,7 +14,7 @@
 use std::task;
 
 fn f() {
-    let a = ~0;
+    let _a = ~0;
     fail!();
 }
 
index 3bfe7d76ce8b00aada48440987cacdbfb0d071c3..4e0e5347d4d22d8af5929035817e97aba91da2e9 100644 (file)
 
 fn foo<T>(o: myoption<T>) -> int {
     let mut x: int = 5;
-    match o { none::<T> => { } some::<T>(t) => { x += 1; } }
+    match o {
+        none::<T> => { }
+        some::<T>(_t) => { x += 1; }
+    }
     return x;
 }
 
index ea627a7c7602ba4521ee577733ea5e919d932658..46d3bef86b5c122a2b2b746756bf8fcc1a5b468d 100644 (file)
 
 fn foo<T>(o: myoption<T>) -> int {
     let mut x: int;
-    match o { none::<T> => { fail!(); } some::<T>(t) => { x = 5; } }
+    match o {
+        none::<T> => { fail!(); }
+        some::<T>(_t) => { x = 5; }
+    }
     return x;
 }
 
index e23fccb28f15117b09ce0c8c433112a51ff2d522..e84ed47333b736b11c6db848584cb4e5be948616 100644 (file)
@@ -10,6 +10,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(unused_imports)];
+
 #[no_std];
 extern mod std;
 extern mod zed(name = "std");
index 556d7dd521c96481f049eb824514297c9329571d..881606d673cbf002e20e5e7e8a0d0401046d80d9 100644 (file)
@@ -11,7 +11,6 @@
 extern mod extra;
 
 use std::str;
-use std::vec;
 
 pub fn main() {
     // Chars of 1, 2, 3, and 4 bytes
@@ -28,19 +27,19 @@ pub fn main() {
 
     assert!((str::is_utf8(s.as_bytes())));
     // invalid prefix
-    assert!((!str::is_utf8(~[0x80_u8])));
+    assert!((!str::is_utf8([0x80_u8])));
     // invalid 2 byte prefix
-    assert!((!str::is_utf8(~[0xc0_u8])));
-    assert!((!str::is_utf8(~[0xc0_u8, 0x10_u8])));
+    assert!((!str::is_utf8([0xc0_u8])));
+    assert!((!str::is_utf8([0xc0_u8, 0x10_u8])));
     // invalid 3 byte prefix
-    assert!((!str::is_utf8(~[0xe0_u8])));
-    assert!((!str::is_utf8(~[0xe0_u8, 0x10_u8])));
-    assert!((!str::is_utf8(~[0xe0_u8, 0xff_u8, 0x10_u8])));
+    assert!((!str::is_utf8([0xe0_u8])));
+    assert!((!str::is_utf8([0xe0_u8, 0x10_u8])));
+    assert!((!str::is_utf8([0xe0_u8, 0xff_u8, 0x10_u8])));
     // invalid 4 byte prefix
-    assert!((!str::is_utf8(~[0xf0_u8])));
-    assert!((!str::is_utf8(~[0xf0_u8, 0x10_u8])));
-    assert!((!str::is_utf8(~[0xf0_u8, 0xff_u8, 0x10_u8])));
-    assert!((!str::is_utf8(~[0xf0_u8, 0xff_u8, 0xff_u8, 0x10_u8])));
+    assert!((!str::is_utf8([0xf0_u8])));
+    assert!((!str::is_utf8([0xf0_u8, 0x10_u8])));
+    assert!((!str::is_utf8([0xf0_u8, 0xff_u8, 0x10_u8])));
+    assert!((!str::is_utf8([0xf0_u8, 0xff_u8, 0xff_u8, 0x10_u8])));
 
     let mut stack = ~"a×c€";
     assert_eq!(stack.pop_char(), '€');
index 16cca5cd6cf4dd56b6567412ee4f19f60527391a..d387d7820a4376807852758705948e191c04176a 100644 (file)
@@ -15,6 +15,6 @@ struct Pair { x: int, y: int }
 pub fn main() {
     // This just tests whether the vec leaks its members.
 
-    let pvec: ~[@Pair] =
+    let _pvec: ~[@Pair] =
         ~[@Pair{x: 1, y: 2}, @Pair{x: 3, y: 4}, @Pair{x: 5, y: 6}];
 }
index 8b6e037e8401383f40a2e48f7767c60ed14f194b..ccc7768469dd1c0516292da523849fa963ed495a 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(dead_assignment)];
+
 pub fn main() {
     let a = ~[1, 2, 3, 4, 5];
     let mut b = ~[a.clone(), a.clone()];
index 13a8e324d43062adf5efff02efbba031ff772b86..2ad21aba6cdd82e4f15397402805e98dd061b967 100644 (file)
@@ -17,6 +17,6 @@ pub fn main() {
             assert_eq!(b, 2);
             assert!(tail.is_empty());
         }
-        ([..tail], _) => fail!()
+        ([.._tail], _) => fail!()
     }
 }
index 54626e52d23e0cc5bf39a8bfb3b374ac26a18c85..85293405695e6a14570227dd8380b469005836c5 100644 (file)
@@ -16,9 +16,7 @@ struct foo {
 #[unsafe_destructor]
 impl Drop for foo {
     fn drop(&self) {
-        unsafe {
-            *self.x += 1;
-        }
+        *self.x += 1;
     }
 }
 
index 6a60308f2e70f0efec1e088a98cf925ddc411bb9..2785270569f3d8b7ae8a80fb726d3030d58a99da 100644 (file)
@@ -16,7 +16,7 @@ pub fn main() {
             assert!(tail[1].string == ~"baz");
 
             match tail {
-                [Foo { _ }, _, Foo { _ }, ..tail] => {
+                [Foo { _ }, _, Foo { _ }, .. _tail] => {
                     ::std::util::unreachable();
                 }
                 [Foo { string: ref a }, Foo { string: ref b }] => {
index f73b75b2f4ca68fb3738e343cca1d9b137123199..60124a79fcb4bae23770f090a8ca4857f23d429f 100644 (file)
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub fn main() { let quux: @~[uint] = @~[]; }
+pub fn main() { let _quux: @~[uint] = @~[]; }
index 565188829d6b978e2cfbe02f012d32ca0f71e58a..7c20f9823d9f0e3940ff604e9d6d6ed062cd671c 100644 (file)
@@ -71,7 +71,7 @@ fn angrydome() {
       break; }
 }
 
-fn evil_lincoln() { let evil = info!("lincoln"); }
+fn evil_lincoln() { let _evil = info!("lincoln"); }
 
 pub fn main() {
     strange();
index 2e9fb981be4bc0e1db0e213f07e7193ed56c7c3c..36d902dc2e0209e6e7412274e22de3ab44d915e0 100644 (file)
@@ -10,4 +10,4 @@
 
 
 
-pub fn main() { let x: int = 10; while x == 10 && x == 11 { let y = 0xf00; } }
+pub fn main() { let x: int = 10; while x == 10 && x == 11 { let _y = 0xf00; } }
index de87a40a61f7e94ac99ece6fae88a2ddc234563c..fb629a8deae2b0f8c34b9abae3130071450c8383 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub fn main() {
+#[allow(dead_assignment)];
+#[allow(unused_variable)];
 
+pub fn main() {
     let mut y: int = 42;
     let mut z: int = 42;
     let mut x: int;
index a7ab011f8e1432be5311b58aed38256c46696d9d..185b686c24ebdc1cc11b0aadcacbc569a36801ff 100644 (file)
@@ -8,7 +8,7 @@ pub fn main() {
         info!(i);
         i = i + 1;
         if i == 95 {
-            let v: ~[int] =
+            let _v: ~[int] =
                 ~[1, 2, 3, 4, 5]; // we check that it is freed by break
 
             info!("breaking");
index a0159e7413edcda94ca25f9cc912f9e638f94278..3722dccf94b94001c38914056d6220fe9f082c47 100644 (file)
 pub type LPVOID = uint;
 pub type BOOL = u8;
 
+#[cfg(target_os = "win32")]
 mod kernel32 {
     use super::{HANDLE, DWORD, SIZE_T, LPVOID, BOOL};
 
-    #[cfg(target_os = "win32")]
     #[abi = "stdcall"]
     extern "stdcall" {
         pub fn GetProcessHeap() -> HANDLE;
@@ -29,6 +29,7 @@ pub fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T)
 
 
 #[cfg(target_os = "win32")]
+#[fixed_stack_segment]
 pub fn main() {
     let heap = unsafe { kernel32::GetProcessHeap() };
     let mem = unsafe { kernel32::HeapAlloc(heap, 0u32, 100u32) };
index d6522231f65fadbb33bc356b34cf51bffbeb840e..79740c7b5a5b29e0c96334258a1177401f40c78a 100644 (file)
@@ -12,8 +12,6 @@
 // xfail-fast
 extern mod xcrate_unit_struct;
 
-use std::util;
-
 static s1: xcrate_unit_struct::Struct = xcrate_unit_struct::Struct;
 static s2: xcrate_unit_struct::Unit = xcrate_unit_struct::Unit;
 static s3: xcrate_unit_struct::Unit =
index 8beaee83864dbcd74be06ccd3f1d1df0e398b6fd..040084df911c794434824f6f49a97618f6c3192f 100644 (file)
@@ -17,13 +17,13 @@ pub fn main() {
     builder.future_result(|r| { result = Some(r); });
     builder.spawn(child);
     error!("1");
-    task::yield();
+    task::deschedule();
     error!("2");
-    task::yield();
+    task::deschedule();
     error!("3");
     result.unwrap().recv();
 }
 
 fn child() {
-    error!("4"); task::yield(); error!("5"); task::yield(); error!("6");
+    error!("4"); task::deschedule(); error!("5"); task::deschedule(); error!("6");
 }
index 37ec8af7e57c8128607b4d2d4e10fbce2a4ed256..cee7f5f4ef098ef3dd32ae56b845557264432c8a 100644 (file)
@@ -17,7 +17,7 @@ pub fn main() {
     builder.future_result(|r| { result = Some(r); });
     builder.spawn(child);
     error!("1");
-    task::yield();
+    task::deschedule();
     result.unwrap().recv();
 }
 
index a2b8ef0429d40523384c1f079f7df2a7f3d30136..5e3dde0257266293e973c2cdb5d244e2ba82a002 100644 (file)
@@ -13,5 +13,5 @@
 
 pub fn main() {
     let mut i: int = 0;
-    while i < 100 { i = i + 1; error!(i); task::yield(); }
+    while i < 100 { i = i + 1; error!(i); task::deschedule(); }
 }
diff --git a/src/test/run-pass/zip-same-length.rs b/src/test/run-pass/zip-same-length.rs
deleted file mode 100644 (file)
index d971487..0000000
+++ /dev/null
@@ -1,44 +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.
-
-// In this case, the code should compile and should
-// succeed at runtime
-
-use std::vec;
-
-fn enum_chars(start: u8, end: u8) -> ~[char] {
-    assert!(start < end);
-    let mut i = start;
-    let mut r = ~[];
-    while i <= end { r.push(i as char); i += 1u as u8; }
-    return r;
-}
-
-fn enum_uints(start: uint, end: uint) -> ~[uint] {
-    assert!(start < end);
-    let mut i = start;
-    let mut r = ~[];
-    while i <= end { r.push(i); i += 1u; }
-    return r;
-}
-
-pub fn main() {
-    let a = 'a' as u8;
-    let j = 'j' as u8;
-    let k = 1u;
-    let l = 10u;
-    let chars = enum_chars(a, j);
-    let ints = enum_uints(k, l);
-
-    let ps = vec::zip(chars, ints);
-
-    assert_eq!(ps.head(), &('a', 1u));
-    assert_eq!(ps.last(), &(j as char, 10u));
-}