]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #14019 : brson/rust/docs, r=alexcrichton
authorbors <bors@rust-lang.org>
Fri, 9 May 2014 06:01:40 +0000 (23:01 -0700)
committerbors <bors@rust-lang.org>
Fri, 9 May 2014 06:01:40 +0000 (23:01 -0700)
Just small bits of polish.

393 files changed:
configure
mk/crates.mk
mk/prepare.mk
mk/tests.mk
src/compiletest/common.rs
src/compiletest/compiletest.rs
src/compiletest/header.rs
src/compiletest/runtest.rs
src/doc/guide-container.md
src/doc/rust.md
src/doc/tutorial.md
src/etc/gedit/share/gtksourceview-3.0/language-specs/rust.lang
src/etc/kate/rust.xml
src/etc/lldb_batchmode.py [new file with mode: 0644]
src/etc/vim/syntax/rust.vim
src/libcollections/hashmap.rs
src/libcore/iter.rs
src/libcore/lib.rs
src/libcore/option.rs
src/libcore/result.rs
src/libcore/should_not_exist.rs
src/libcore/str.rs
src/libfmt_macros/lib.rs [new file with mode: 0644]
src/libgetopts/lib.rs
src/libgraphviz/lib.rs
src/liblibc/lib.rs
src/liblog/lib.rs
src/libnative/io/addrinfo.rs
src/libnative/io/c_unix.rs
src/libnative/io/c_win32.rs
src/libnative/io/file_unix.rs
src/libnative/io/file_win32.rs
src/libnative/io/mod.rs
src/libnative/io/net.rs
src/libnative/io/pipe_unix.rs
src/libnative/io/pipe_win32.rs
src/libnative/io/process.rs
src/libnative/io/util.rs
src/librand/lib.rs
src/librustc/back/link.rs
src/librustc/back/rpath.rs
src/librustc/driver/driver.rs
src/librustc/driver/session.rs
src/librustc/front/test.rs
src/librustc/lib.rs
src/librustc/metadata/creader.rs
src/librustc/metadata/csearch.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/encoder.rs
src/librustc/metadata/tydecode.rs
src/librustc/metadata/tyencode.rs
src/librustc/middle/dataflow.rs
src/librustc/middle/kind.rs
src/librustc/middle/privacy.rs
src/librustc/middle/reachable.rs
src/librustc/middle/resolve.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/callee.rs
src/librustc/middle/trans/common.rs
src/librustc/middle/trans/consts.rs
src/librustc/middle/trans/controlflow.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/monomorphize.rs
src/librustc/middle/trans/reflect.rs
src/librustc/middle/ty.rs
src/librustc/middle/ty_fold.rs
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/check/vtable.rs
src/librustc/middle/typeck/check/writeback.rs
src/librustc/middle/typeck/infer/glb.rs
src/librustc/middle/typeck/infer/lub.rs
src/librustc/util/common.rs
src/librustc/util/ppaux.rs
src/librustdoc/clean.rs
src/librustdoc/core.rs
src/librustdoc/html/format.rs
src/librustdoc/html/highlight.rs
src/librustdoc/html/markdown.rs
src/librustdoc/html/render.rs
src/librustdoc/lib.rs
src/librustdoc/passes.rs
src/librustdoc/test.rs
src/librustuv/access.rs
src/librustuv/addrinfo.rs
src/librustuv/lib.rs
src/librustuv/net.rs
src/librustuv/pipe.rs
src/librustuv/process.rs
src/librustuv/stream.rs
src/librustuv/timeout.rs [new file with mode: 0644]
src/librustuv/timer.rs
src/librustuv/tty.rs
src/librustuv/uvio.rs
src/libserialize/base64.rs
src/libserialize/hex.rs
src/libserialize/json.rs
src/libserialize/serialize.rs
src/libstd/ascii.rs
src/libstd/fmt/mod.rs
src/libstd/fmt/parse.rs [deleted file]
src/libstd/fmt/rt.rs
src/libstd/io/mod.rs
src/libstd/io/net/addrinfo.rs
src/libstd/io/net/tcp.rs
src/libstd/io/net/udp.rs
src/libstd/io/net/unix.rs
src/libstd/io/process.rs
src/libstd/io/util.rs
src/libstd/lib.rs
src/libstd/local_data.rs
src/libstd/macros.rs
src/libstd/num/i16.rs
src/libstd/num/i32.rs
src/libstd/num/i64.rs
src/libstd/num/i8.rs
src/libstd/num/int.rs
src/libstd/num/int_macros.rs
src/libstd/num/strconv.rs
src/libstd/num/u16.rs
src/libstd/num/u32.rs
src/libstd/num/u64.rs
src/libstd/num/u8.rs
src/libstd/num/uint.rs
src/libstd/num/uint_macros.rs
src/libstd/os.rs
src/libstd/rt/args.rs
src/libstd/rt/rtio.rs
src/libstd/rt/task.rs
src/libstd/slice.rs
src/libstd/str.rs
src/libstd/strbuf.rs
src/libstd/sync/arc.rs
src/libstd/sync/deque.rs
src/libstd/unstable/dynamic_lib.rs
src/libstd/vec.rs
src/libsyntax/ast.rs
src/libsyntax/ast_map.rs
src/libsyntax/ast_util.rs
src/libsyntax/attr.rs
src/libsyntax/codemap.rs
src/libsyntax/crateid.rs
src/libsyntax/diagnostic.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/deriving/generic.rs
src/libsyntax/ext/env.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/format.rs
src/libsyntax/ext/mtwt.rs
src/libsyntax/ext/quote.rs
src/libsyntax/ext/source_util.rs
src/libsyntax/ext/tt/macro_parser.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/ext/tt/transcribe.rs
src/libsyntax/fold.rs
src/libsyntax/lib.rs
src/libsyntax/parse/comments.rs
src/libsyntax/parse/lexer.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/obsolete.rs
src/libsyntax/parse/parser.rs
src/libsyntax/parse/token.rs
src/libsyntax/print/pp.rs
src/libsyntax/print/pprust.rs
src/libsyntax/util/interner.rs
src/libsyntax/util/parser_testing.rs
src/test/auxiliary/issue-11680.rs [new file with mode: 0644]
src/test/auxiliary/macro_crate_outlive_expansion_phase.rs
src/test/bench/core-map.rs
src/test/bench/core-set.rs
src/test/bench/core-std.rs
src/test/bench/rt-messaging-ping-pong.rs
src/test/bench/rt-parfib.rs
src/test/bench/rt-spawn-rate.rs
src/test/bench/shootout-binarytrees.rs
src/test/bench/shootout-chameneos-redux.rs
src/test/bench/shootout-fannkuch-redux.rs
src/test/bench/shootout-fasta-redux.rs
src/test/bench/shootout-fasta.rs
src/test/bench/shootout-k-nucleotide-pipes.rs
src/test/bench/shootout-mandelbrot.rs
src/test/bench/shootout-meteor.rs
src/test/bench/shootout-pidigits.rs
src/test/bench/shootout-spectralnorm.rs
src/test/bench/shootout-threadring.rs
src/test/compile-fail/core-tls-store-pointer.rs
src/test/compile-fail/issue-11493.rs [new file with mode: 0644]
src/test/compile-fail/issue-11680.rs [new file with mode: 0644]
src/test/compile-fail/macro-local-data-key-priv.rs
src/test/compile-fail/typeck_type_placeholder_mismatch.rs
src/test/debug-info/basic-types-globals-metadata.rs [deleted file]
src/test/debug-info/basic-types-globals.rs [deleted file]
src/test/debug-info/basic-types-metadata.rs [deleted file]
src/test/debug-info/basic-types-mut-globals.rs [deleted file]
src/test/debug-info/basic-types.rs [deleted file]
src/test/debug-info/borrowed-basic.rs [deleted file]
src/test/debug-info/borrowed-c-style-enum.rs [deleted file]
src/test/debug-info/borrowed-enum.rs [deleted file]
src/test/debug-info/borrowed-managed-basic.rs [deleted file]
src/test/debug-info/borrowed-struct.rs [deleted file]
src/test/debug-info/borrowed-tuple.rs [deleted file]
src/test/debug-info/borrowed-unique-basic.rs [deleted file]
src/test/debug-info/box.rs [deleted file]
src/test/debug-info/boxed-struct.rs [deleted file]
src/test/debug-info/by-value-non-immediate-argument.rs [deleted file]
src/test/debug-info/by-value-self-argument-in-trait-impl.rs [deleted file]
src/test/debug-info/c-style-enum-in-composite.rs [deleted file]
src/test/debug-info/c-style-enum.rs [deleted file]
src/test/debug-info/closure-in-generic-function.rs [deleted file]
src/test/debug-info/destructured-fn-argument.rs [deleted file]
src/test/debug-info/destructured-local.rs [deleted file]
src/test/debug-info/evec-in-struct.rs [deleted file]
src/test/debug-info/function-arg-initialization.rs [deleted file]
src/test/debug-info/function-arguments.rs [deleted file]
src/test/debug-info/function-prologue-stepping-no-split-stack.rs [deleted file]
src/test/debug-info/generic-function.rs [deleted file]
src/test/debug-info/generic-functions-nested.rs [deleted file]
src/test/debug-info/generic-method-on-generic-struct.rs [deleted file]
src/test/debug-info/generic-static-method-on-struct-and-enum.rs [deleted file]
src/test/debug-info/generic-struct-style-enum.rs [deleted file]
src/test/debug-info/generic-struct.rs [deleted file]
src/test/debug-info/generic-trait-generic-static-default-method.rs [deleted file]
src/test/debug-info/generic-tuple-style-enum.rs [deleted file]
src/test/debug-info/include_string.rs [deleted file]
src/test/debug-info/issue11600.rs [deleted file]
src/test/debug-info/issue12886.rs [deleted file]
src/test/debug-info/issue13213.rs [deleted file]
src/test/debug-info/issue7712.rs [deleted file]
src/test/debug-info/lexical-scope-in-for-loop.rs [deleted file]
src/test/debug-info/lexical-scope-in-if.rs [deleted file]
src/test/debug-info/lexical-scope-in-match.rs [deleted file]
src/test/debug-info/lexical-scope-in-parameterless-closure.rs [deleted file]
src/test/debug-info/lexical-scope-in-stack-closure.rs [deleted file]
src/test/debug-info/lexical-scope-in-unconditional-loop.rs [deleted file]
src/test/debug-info/lexical-scope-in-unique-closure.rs [deleted file]
src/test/debug-info/lexical-scope-in-while.rs [deleted file]
src/test/debug-info/lexical-scope-with-macro.rs [deleted file]
src/test/debug-info/lexical-scopes-in-block-expression.rs [deleted file]
src/test/debug-info/limited-debuginfo.rs [deleted file]
src/test/debug-info/managed-enum.rs [deleted file]
src/test/debug-info/managed-pointer-within-unique-vec.rs [deleted file]
src/test/debug-info/managed-pointer-within-unique.rs [deleted file]
src/test/debug-info/method-on-enum.rs [deleted file]
src/test/debug-info/method-on-generic-struct.rs [deleted file]
src/test/debug-info/method-on-struct.rs [deleted file]
src/test/debug-info/method-on-trait.rs [deleted file]
src/test/debug-info/method-on-tuple-struct.rs [deleted file]
src/test/debug-info/multiple-functions-equal-var-names.rs [deleted file]
src/test/debug-info/multiple-functions.rs [deleted file]
src/test/debug-info/name-shadowing-and-scope-nesting.rs [deleted file]
src/test/debug-info/nil-enum.rs [deleted file]
src/test/debug-info/option-like-enum.rs [deleted file]
src/test/debug-info/packed-struct-with-destructor.rs [deleted file]
src/test/debug-info/packed-struct.rs [deleted file]
src/test/debug-info/recursive-enum.rs [deleted file]
src/test/debug-info/recursive-struct.rs [deleted file]
src/test/debug-info/self-in-default-method.rs [deleted file]
src/test/debug-info/self-in-generic-default-method.rs [deleted file]
src/test/debug-info/shadowed-argument.rs [deleted file]
src/test/debug-info/shadowed-variable.rs [deleted file]
src/test/debug-info/simd.rs [deleted file]
src/test/debug-info/simple-lexical-scope.rs [deleted file]
src/test/debug-info/simple-struct.rs [deleted file]
src/test/debug-info/simple-tuple.rs [deleted file]
src/test/debug-info/static-method-on-struct-and-enum.rs [deleted file]
src/test/debug-info/struct-in-enum.rs [deleted file]
src/test/debug-info/struct-in-struct.rs [deleted file]
src/test/debug-info/struct-style-enum.rs [deleted file]
src/test/debug-info/struct-with-destructor.rs [deleted file]
src/test/debug-info/text-to-include-1.txt [deleted file]
src/test/debug-info/text-to-include-2.txt [deleted file]
src/test/debug-info/text-to-include-3.txt [deleted file]
src/test/debug-info/trait-generic-static-default-method.rs [deleted file]
src/test/debug-info/trait-pointers.rs [deleted file]
src/test/debug-info/tuple-in-struct.rs [deleted file]
src/test/debug-info/tuple-in-tuple.rs [deleted file]
src/test/debug-info/tuple-struct.rs [deleted file]
src/test/debug-info/tuple-style-enum.rs [deleted file]
src/test/debug-info/unique-enum.rs [deleted file]
src/test/debug-info/var-captured-in-nested-closure.rs [deleted file]
src/test/debug-info/var-captured-in-sendable-closure.rs [deleted file]
src/test/debug-info/var-captured-in-stack-closure.rs [deleted file]
src/test/debug-info/vec-slices.rs [deleted file]
src/test/debug-info/vec.rs [deleted file]
src/test/debuginfo/basic-types-globals-metadata.rs [new file with mode: 0644]
src/test/debuginfo/basic-types-globals.rs [new file with mode: 0644]
src/test/debuginfo/basic-types-metadata.rs [new file with mode: 0644]
src/test/debuginfo/basic-types-mut-globals.rs [new file with mode: 0644]
src/test/debuginfo/basic-types.rs [new file with mode: 0644]
src/test/debuginfo/borrowed-basic.rs [new file with mode: 0644]
src/test/debuginfo/borrowed-c-style-enum.rs [new file with mode: 0644]
src/test/debuginfo/borrowed-enum.rs [new file with mode: 0644]
src/test/debuginfo/borrowed-managed-basic.rs [new file with mode: 0644]
src/test/debuginfo/borrowed-struct.rs [new file with mode: 0644]
src/test/debuginfo/borrowed-tuple.rs [new file with mode: 0644]
src/test/debuginfo/borrowed-unique-basic.rs [new file with mode: 0644]
src/test/debuginfo/box.rs [new file with mode: 0644]
src/test/debuginfo/boxed-struct.rs [new file with mode: 0644]
src/test/debuginfo/by-value-non-immediate-argument.rs [new file with mode: 0644]
src/test/debuginfo/by-value-self-argument-in-trait-impl.rs [new file with mode: 0644]
src/test/debuginfo/c-style-enum-in-composite.rs [new file with mode: 0644]
src/test/debuginfo/c-style-enum.rs [new file with mode: 0644]
src/test/debuginfo/closure-in-generic-function.rs [new file with mode: 0644]
src/test/debuginfo/destructured-fn-argument.rs [new file with mode: 0644]
src/test/debuginfo/destructured-local.rs [new file with mode: 0644]
src/test/debuginfo/evec-in-struct.rs [new file with mode: 0644]
src/test/debuginfo/function-arg-initialization.rs [new file with mode: 0644]
src/test/debuginfo/function-arguments.rs [new file with mode: 0644]
src/test/debuginfo/function-prologue-stepping-no-split-stack.rs [new file with mode: 0644]
src/test/debuginfo/generic-function.rs [new file with mode: 0644]
src/test/debuginfo/generic-functions-nested.rs [new file with mode: 0644]
src/test/debuginfo/generic-method-on-generic-struct.rs [new file with mode: 0644]
src/test/debuginfo/generic-static-method-on-struct-and-enum.rs [new file with mode: 0644]
src/test/debuginfo/generic-struct-style-enum.rs [new file with mode: 0644]
src/test/debuginfo/generic-struct.rs [new file with mode: 0644]
src/test/debuginfo/generic-trait-generic-static-default-method.rs [new file with mode: 0644]
src/test/debuginfo/generic-tuple-style-enum.rs [new file with mode: 0644]
src/test/debuginfo/include_string.rs [new file with mode: 0644]
src/test/debuginfo/issue11600.rs [new file with mode: 0644]
src/test/debuginfo/issue12886.rs [new file with mode: 0644]
src/test/debuginfo/issue13213.rs [new file with mode: 0644]
src/test/debuginfo/issue7712.rs [new file with mode: 0644]
src/test/debuginfo/lexical-scope-in-for-loop.rs [new file with mode: 0644]
src/test/debuginfo/lexical-scope-in-if.rs [new file with mode: 0644]
src/test/debuginfo/lexical-scope-in-match.rs [new file with mode: 0644]
src/test/debuginfo/lexical-scope-in-parameterless-closure.rs [new file with mode: 0644]
src/test/debuginfo/lexical-scope-in-stack-closure.rs [new file with mode: 0644]
src/test/debuginfo/lexical-scope-in-unconditional-loop.rs [new file with mode: 0644]
src/test/debuginfo/lexical-scope-in-unique-closure.rs [new file with mode: 0644]
src/test/debuginfo/lexical-scope-in-while.rs [new file with mode: 0644]
src/test/debuginfo/lexical-scope-with-macro.rs [new file with mode: 0644]
src/test/debuginfo/lexical-scopes-in-block-expression.rs [new file with mode: 0644]
src/test/debuginfo/limited-debuginfo.rs [new file with mode: 0644]
src/test/debuginfo/managed-enum.rs [new file with mode: 0644]
src/test/debuginfo/managed-pointer-within-unique-vec.rs [new file with mode: 0644]
src/test/debuginfo/managed-pointer-within-unique.rs [new file with mode: 0644]
src/test/debuginfo/method-on-enum.rs [new file with mode: 0644]
src/test/debuginfo/method-on-generic-struct.rs [new file with mode: 0644]
src/test/debuginfo/method-on-struct.rs [new file with mode: 0644]
src/test/debuginfo/method-on-trait.rs [new file with mode: 0644]
src/test/debuginfo/method-on-tuple-struct.rs [new file with mode: 0644]
src/test/debuginfo/multiple-functions-equal-var-names.rs [new file with mode: 0644]
src/test/debuginfo/multiple-functions.rs [new file with mode: 0644]
src/test/debuginfo/name-shadowing-and-scope-nesting.rs [new file with mode: 0644]
src/test/debuginfo/nil-enum.rs [new file with mode: 0644]
src/test/debuginfo/option-like-enum.rs [new file with mode: 0644]
src/test/debuginfo/packed-struct-with-destructor.rs [new file with mode: 0644]
src/test/debuginfo/packed-struct.rs [new file with mode: 0644]
src/test/debuginfo/recursive-enum.rs [new file with mode: 0644]
src/test/debuginfo/recursive-struct.rs [new file with mode: 0644]
src/test/debuginfo/self-in-default-method.rs [new file with mode: 0644]
src/test/debuginfo/self-in-generic-default-method.rs [new file with mode: 0644]
src/test/debuginfo/shadowed-argument.rs [new file with mode: 0644]
src/test/debuginfo/shadowed-variable.rs [new file with mode: 0644]
src/test/debuginfo/simd.rs [new file with mode: 0644]
src/test/debuginfo/simple-lexical-scope.rs [new file with mode: 0644]
src/test/debuginfo/simple-struct.rs [new file with mode: 0644]
src/test/debuginfo/simple-tuple.rs [new file with mode: 0644]
src/test/debuginfo/static-method-on-struct-and-enum.rs [new file with mode: 0644]
src/test/debuginfo/struct-in-enum.rs [new file with mode: 0644]
src/test/debuginfo/struct-in-struct.rs [new file with mode: 0644]
src/test/debuginfo/struct-style-enum.rs [new file with mode: 0644]
src/test/debuginfo/struct-with-destructor.rs [new file with mode: 0644]
src/test/debuginfo/text-to-include-1.txt [new file with mode: 0644]
src/test/debuginfo/text-to-include-2.txt [new file with mode: 0644]
src/test/debuginfo/text-to-include-3.txt [new file with mode: 0644]
src/test/debuginfo/trait-generic-static-default-method.rs [new file with mode: 0644]
src/test/debuginfo/trait-pointers.rs [new file with mode: 0644]
src/test/debuginfo/tuple-in-struct.rs [new file with mode: 0644]
src/test/debuginfo/tuple-in-tuple.rs [new file with mode: 0644]
src/test/debuginfo/tuple-struct.rs [new file with mode: 0644]
src/test/debuginfo/tuple-style-enum.rs [new file with mode: 0644]
src/test/debuginfo/unique-enum.rs [new file with mode: 0644]
src/test/debuginfo/var-captured-in-nested-closure.rs [new file with mode: 0644]
src/test/debuginfo/var-captured-in-sendable-closure.rs [new file with mode: 0644]
src/test/debuginfo/var-captured-in-stack-closure.rs [new file with mode: 0644]
src/test/debuginfo/vec-slices.rs [new file with mode: 0644]
src/test/debuginfo/vec.rs [new file with mode: 0644]
src/test/run-make/unicode-input/multiple_files.rs
src/test/run-make/unicode-input/span_length.rs
src/test/run-pass/backtrace.rs
src/test/run-pass/cleanup-shortcircuit.rs
src/test/run-pass/issue-10025.rs [new file with mode: 0644]
src/test/run-pass/issue-10626.rs
src/test/run-pass/issue-13304.rs
src/test/run-pass/issue-4541.rs
src/test/run-pass/logging-separate-lines.rs
src/test/run-pass/macro-local-data-key.rs
src/test/run-pass/out-of-stack.rs
src/test/run-pass/send_str_treemap.rs
src/test/run-pass/signal-exit-status.rs
src/test/run-pass/sigpipe-should-be-ignored.rs
src/test/run-pass/trait-to-str.rs

index 0f3561dd7b5c95fc0154115fef2f11ae818ad4d4..d189c8cb6cd609622b12dbc129bcf8d66699d72e 100755 (executable)
--- a/configure
+++ b/configure
@@ -466,6 +466,26 @@ probe CFG_PDFLATEX         pdflatex
 probe CFG_XELATEX          xelatex
 probe CFG_LUALATEX         lualatex
 probe CFG_GDB              gdb
+probe CFG_LLDB             lldb
+
+if [ ! -z "$CFG_LLDB" ]
+then
+    # If CFG_LLDB_PYTHON_DIR is not already set from the outside and valid, try to read it from
+    # LLDB via the -P commandline options.
+    if [ -z "$CFG_LLDB_PYTHON_DIR" ] || [ ! -d "$CFG_LLDB_PYTHON_DIR" ]
+    then
+        CFG_LLDB_PYTHON_DIR=$($CFG_LLDB -P)
+
+        # If CFG_LLDB_PYTHON_DIR is not a valid directory, set it to something more readable
+        if [ ! -d "$CFG_LLDB_PYTHON_DIR" ]
+        then
+            CFG_LLDB_PYTHON_DIR="LLDB_PYTHON_DIRECTORY_NOT_FOUND"
+        fi
+
+        putvar CFG_LLDB_PYTHON_DIR
+    fi
+fi
+
 if [ "$CFG_OSTYPE" = "unknown-linux-gnu" ]
 then
     probe CFG_PAXCTL           paxctl /sbin/paxctl
@@ -807,7 +827,8 @@ do
     make_dir $h/test/bench
     make_dir $h/test/perf
     make_dir $h/test/pretty
-    make_dir $h/test/debug-info
+    make_dir $h/test/debuginfo-gdb
+    make_dir $h/test/debuginfo-lldb
     make_dir $h/test/codegen
     make_dir $h/test/doc-tutorial
     make_dir $h/test/doc-guide-ffi
index 9da80c2bc11c5453e7204bae893cdeee88fc14af..b75b5ba81e2bd7fb14a0aa850f53d19059c66b1c 100644 (file)
@@ -52,7 +52,7 @@
 TARGET_CRATES := libc std green rustuv native flate arena glob term semver \
                  uuid serialize sync getopts collections num test time rand \
                 workcache url log regex graphviz core
-HOST_CRATES := syntax rustc rustdoc fourcc hexfloat regex_macros
+HOST_CRATES := syntax rustc rustdoc fourcc hexfloat regex_macros fmt_macros
 CRATES := $(TARGET_CRATES) $(HOST_CRATES)
 TOOLS := compiletest rustdoc rustc
 
@@ -61,7 +61,7 @@ DEPS_std := core libc native:rustrt native:compiler-rt native:backtrace
 DEPS_green := std rand native:context_switch
 DEPS_rustuv := std native:uv native:uv_support
 DEPS_native := std
-DEPS_syntax := std term serialize collections log
+DEPS_syntax := std term serialize collections log fmt_macros
 DEPS_rustc := syntax native:rustllvm flate arena serialize sync getopts \
               collections time log
 DEPS_rustdoc := rustc native:hoedown serialize sync getopts collections \
@@ -88,6 +88,7 @@ DEPS_workcache := std serialize collections log
 DEPS_log := std sync
 DEPS_regex := std collections
 DEPS_regex_macros = syntax std regex
+DEPS_fmt_macros = std
 
 TOOL_DEPS_compiletest := test green rustuv getopts
 TOOL_DEPS_rustdoc := rustdoc native
index 096887056bf2a31f38aa30b106b393ea5279bb0e..5f4854994678103ca6e516c404112d17f29c2be4 100644 (file)
@@ -106,7 +106,8 @@ prepare-host-lib-$(1)-$(2)-$(3)-$(4): prepare-maybe-clean-$(4) \
                                  prepare-host-dirs-$(4)
        $$(if $$(findstring $(2), $$(PREPARE_STAGE)),\
       $$(if $$(findstring $(3), $$(PREPARE_HOST)),\
-        $$(call PREPARE_LIB,$$(call CFG_LIB_GLOB_$$(PREPARE_HOST),$(1))),),)
+        $$(if $$(findstring 1,$$(ONLY_RLIB_$(1))),,\
+          $$(call PREPARE_LIB,$$(call CFG_LIB_GLOB_$$(PREPARE_HOST),$(1)))),),)
 endef
 
 
@@ -133,7 +134,8 @@ prepare-target-$(2)-host-$(3)-$(1)-$(4): prepare-maybe-clean-$(4) \
         $$(if $$(findstring $(3), $$(PREPARE_HOST)),\
           $$(call PREPARE_DIR,$$(PREPARE_WORKING_DEST_LIB_DIR))\
           $$(foreach crate,$$(TARGET_CRATES),\
-            $$(call PREPARE_LIB,$$(call CFG_LIB_GLOB_$(2),$$(crate)))\
+           $$(if $$(findstring 1, $$(ONLY_RLIB_$$(crate))),,\
+              $$(call PREPARE_LIB,$$(call CFG_LIB_GLOB_$(2),$$(crate))))\
             $$(call PREPARE_LIB,$$(call CFG_RLIB_GLOB,$$(crate))))\
           $$(if $$(findstring $(2),$$(CFG_HOST)),\
             $$(foreach crate,$$(HOST_CRATES),\
index cb1bea39cee07f6bd6085be876fd765b11f65175..012ec0e862de5746ecb7e04ca6e4668f93b54c88 100644 (file)
@@ -293,7 +293,8 @@ check-stage$(1)-T-$(2)-H-$(3)-exec:                                 \
         check-stage$(1)-T-$(2)-H-$(3)-crates-exec                       \
         check-stage$(1)-T-$(2)-H-$(3)-doc-crates-exec                   \
        check-stage$(1)-T-$(2)-H-$(3)-bench-exec                        \
-       check-stage$(1)-T-$(2)-H-$(3)-debuginfo-exec \
+       check-stage$(1)-T-$(2)-H-$(3)-debuginfo-gdb-exec \
+       check-stage$(1)-T-$(2)-H-$(3)-debuginfo-lldb-exec \
        check-stage$(1)-T-$(2)-H-$(3)-codegen-exec \
        check-stage$(1)-T-$(2)-H-$(3)-doc-exec \
        check-stage$(1)-T-$(2)-H-$(3)-pretty-exec
@@ -460,7 +461,8 @@ CFAIL_RC := $(wildcard $(S)src/test/compile-fail/*.rc)
 CFAIL_RS := $(wildcard $(S)src/test/compile-fail/*.rs)
 BENCH_RS := $(wildcard $(S)src/test/bench/*.rs)
 PRETTY_RS := $(wildcard $(S)src/test/pretty/*.rs)
-DEBUGINFO_RS := $(wildcard $(S)src/test/debug-info/*.rs)
+DEBUGINFO_GDB_RS := $(wildcard $(S)src/test/debuginfo/*.rs)
+DEBUGINFO_LLDB_RS := $(wildcard $(S)src/test/debuginfo/*.rs)
 CODEGEN_RS := $(wildcard $(S)src/test/codegen/*.rs)
 CODEGEN_CC := $(wildcard $(S)src/test/codegen/*.cc)
 
@@ -476,7 +478,8 @@ CFAIL_TESTS := $(CFAIL_RC) $(CFAIL_RS)
 BENCH_TESTS := $(BENCH_RS)
 PERF_TESTS := $(PERF_RS)
 PRETTY_TESTS := $(PRETTY_RS)
-DEBUGINFO_TESTS := $(DEBUGINFO_RS)
+DEBUGINFO_GDB_TESTS := $(DEBUGINFO_GDB_RS)
+DEBUGINFO_LLDB_TESTS := $(DEBUGINFO_LLDB_RS)
 CODEGEN_TESTS := $(CODEGEN_RS) $(CODEGEN_CC)
 
 CTEST_SRC_BASE_rpass = run-pass
@@ -514,10 +517,15 @@ CTEST_BUILD_BASE_perf = perf
 CTEST_MODE_perf = run-pass
 CTEST_RUNTOOL_perf = $(CTEST_PERF_RUNTOOL)
 
-CTEST_SRC_BASE_debuginfo = debug-info
-CTEST_BUILD_BASE_debuginfo = debug-info
-CTEST_MODE_debuginfo = debug-info
-CTEST_RUNTOOL_debuginfo = $(CTEST_RUNTOOL)
+CTEST_SRC_BASE_debuginfo-gdb = debuginfo
+CTEST_BUILD_BASE_debuginfo-gdb = debuginfo-gdb
+CTEST_MODE_debuginfo-gdb = debuginfo-gdb
+CTEST_RUNTOOL_debuginfo-gdb = $(CTEST_RUNTOOL)
+
+CTEST_SRC_BASE_debuginfo-lldb = debuginfo
+CTEST_BUILD_BASE_debuginfo-lldb = debuginfo-lldb
+CTEST_MODE_debuginfo-lldb = debuginfo-lldb
+CTEST_RUNTOOL_debuginfo-lldb = $(CTEST_RUNTOOL)
 
 CTEST_SRC_BASE_codegen = codegen
 CTEST_BUILD_BASE_codegen = codegen
@@ -529,15 +537,22 @@ CTEST_RUNTOOL_codegen = $(CTEST_RUNTOOL)
 # during attempts to run those tests.
 
 ifeq ($(CFG_GDB),)
-CTEST_DISABLE_debuginfo = "no gdb found"
+CTEST_DISABLE_debuginfo-gdb = "no gdb found"
+endif
+
+ifeq ($(CFG_LLDB),)
+CTEST_DISABLE_debuginfo-lldb = "no lldb found"
 endif
 
+# Completely disable LLDB tests for now
+CTEST_DISABLE_debuginfo-lldb = "LLDB tests are not enabled yet"
+
 ifeq ($(CFG_CLANG),)
 CTEST_DISABLE_codegen = "no clang found"
 endif
 
 ifeq ($(CFG_OSTYPE),apple-darwin)
-CTEST_DISABLE_debuginfo = "gdb on darwing needs root"
+CTEST_DISABLE_debuginfo-gdb = "gdb on darwing needs root"
 endif
 
 # CTEST_DISABLE_NONSELFHOST_$(TEST_GROUP), if set, will cause that
@@ -587,6 +602,7 @@ CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3) :=                                              \
         --adb-path=$(CFG_ADB)                          \
         --adb-test-dir=$(CFG_ADB_TEST_DIR)                  \
         --host-rustcflags "$(RUSTC_FLAGS_$(3)) $$(CTEST_RUSTC_FLAGS) -L $$(RT_OUTPUT_DIR_$(3))" \
+        --lldb-python-dir=$(CFG_LLDB_PYTHON_DIR) \
         --target-rustcflags "$(RUSTC_FLAGS_$(2)) $$(CTEST_RUSTC_FLAGS) -L $$(RT_OUTPUT_DIR_$(2))" \
         $$(CTEST_TESTARGS)
 
@@ -597,7 +613,8 @@ CTEST_DEPS_rfail_$(1)-T-$(2)-H-$(3) = $$(RFAIL_TESTS)
 CTEST_DEPS_cfail_$(1)-T-$(2)-H-$(3) = $$(CFAIL_TESTS)
 CTEST_DEPS_bench_$(1)-T-$(2)-H-$(3) = $$(BENCH_TESTS)
 CTEST_DEPS_perf_$(1)-T-$(2)-H-$(3) = $$(PERF_TESTS)
-CTEST_DEPS_debuginfo_$(1)-T-$(2)-H-$(3) = $$(DEBUGINFO_TESTS)
+CTEST_DEPS_debuginfo-gdb_$(1)-T-$(2)-H-$(3) = $$(DEBUGINFO_GDB_TESTS)
+CTEST_DEPS_debuginfo-lldb_$(1)-T-$(2)-H-$(3) = $$(DEBUGINFO_LLDB_TESTS)
 CTEST_DEPS_codegen_$(1)-T-$(2)-H-$(3) = $$(CODEGEN_TESTS)
 
 endef
@@ -661,7 +678,7 @@ endif
 
 endef
 
-CTEST_NAMES = rpass rpass-full cfail-full rfail cfail bench perf debuginfo codegen
+CTEST_NAMES = rpass rpass-full cfail-full rfail cfail bench perf debuginfo-gdb debuginfo-lldb codegen
 
 $(foreach host,$(CFG_HOST), \
  $(eval $(foreach target,$(CFG_TARGET), \
@@ -810,7 +827,8 @@ TEST_GROUPS = \
        bench \
        perf \
        rmake \
-       debuginfo \
+       debuginfo-gdb \
+       debuginfo-lldb \
        codegen \
        doc \
        $(foreach docname,$(DOCS),doc-$(docname)) \
index ea6e98fafa7cdda73649d32ad9925f62c905ae84..ef8b48a053564fdfc15558a2d2fdf38abf90e5bc 100644 (file)
@@ -14,7 +14,8 @@ pub enum mode {
     mode_run_fail,
     mode_run_pass,
     mode_pretty,
-    mode_debug_info,
+    mode_debug_info_gdb,
+    mode_debug_info_lldb,
     mode_codegen
 }
 
@@ -101,6 +102,9 @@ pub struct config {
     // status whether android device available or not
     pub adb_device_status: bool,
 
+    // the path containing LLDB's Python module
+    pub lldb_python_dir: Option<~str>,
+
     // Explain what's going on
     pub verbose: bool
 
index 2e287135dc2643e321c490efa04bc44742929aee..f484ea5a8f1fdc237750944becf7af1f073e6f7a 100644 (file)
 use std::io;
 use std::io::fs;
 use getopts::{optopt, optflag, reqopt};
-use common::config;
-use common::mode_run_pass;
-use common::mode_run_fail;
-use common::mode_compile_fail;
-use common::mode_pretty;
-use common::mode_debug_info;
-use common::mode_codegen;
-use common::mode;
+use common::{config, mode_run_pass, mode_run_fail, mode_compile_fail, mode_pretty,
+             mode_debug_info_gdb, mode_debug_info_lldb, mode_codegen, mode};
 use util::logv;
 
 pub mod procsrv;
@@ -87,6 +81,7 @@ pub fn parse_config(args: Vec<~str> ) -> config {
           optopt("", "host", "the host to build for", "HOST"),
           optopt("", "adb-path", "path to the android debugger", "PATH"),
           optopt("", "adb-test-dir", "path to tests for the android debugger", "PATH"),
+          optopt("", "lldb-python-dir", "directory containing LLDB's python module", "PATH"),
           optopt("", "test-shard", "run shard A, of B shards, worth of the testsuite", "A.B"),
           optflag("h", "help", "show this message"));
 
@@ -154,6 +149,7 @@ fn opt_path(m: &getopts::Matches, nm: &str) -> Path {
             "arm-linux-androideabi" == opt_str2(matches.opt_str("target")) &&
             "(none)" != opt_str2(matches.opt_str("adb-test-dir")) &&
             !opt_str2(matches.opt_str("adb-test-dir")).is_empty(),
+        lldb_python_dir: matches.opt_str("lldb-python-dir"),
         test_shard: test::opt_shard(matches.opt_str("test-shard")),
         verbose: matches.opt_present("verbose")
     }
@@ -204,13 +200,14 @@ pub fn opt_str2(maybestr: Option<~str>) -> ~str {
 
 pub fn str_mode(s: ~str) -> mode {
     match s.as_slice() {
-      "compile-fail" => mode_compile_fail,
-      "run-fail" => mode_run_fail,
-      "run-pass" => mode_run_pass,
-      "pretty" => mode_pretty,
-      "debug-info" => mode_debug_info,
-      "codegen" => mode_codegen,
-      _ => fail!("invalid mode")
+        "compile-fail" => mode_compile_fail,
+        "run-fail" => mode_run_fail,
+        "run-pass" => mode_run_pass,
+        "pretty" => mode_pretty,
+        "debuginfo-gdb" => mode_debug_info_gdb,
+        "debuginfo-lldb" => mode_debug_info_lldb,
+        "codegen" => mode_codegen,
+        s => fail!("invalid mode: " + s)
     }
 }
 
@@ -220,7 +217,8 @@ pub fn mode_str(mode: mode) -> ~str {
       mode_run_fail => "run-fail".to_owned(),
       mode_run_pass => "run-pass".to_owned(),
       mode_pretty => "pretty".to_owned(),
-      mode_debug_info => "debug-info".to_owned(),
+      mode_debug_info_gdb => "debuginfo-gdb".to_owned(),
+      mode_debug_info_lldb => "debuginfo-lldb".to_owned(),
       mode_codegen => "codegen".to_owned(),
     }
 }
@@ -228,7 +226,7 @@ pub fn mode_str(mode: mode) -> ~str {
 pub fn run_tests(config: &config) {
     if config.target == "arm-linux-androideabi".to_owned() {
         match config.mode{
-            mode_debug_info => {
+            mode_debug_info_gdb => {
                 println!("arm-linux-androideabi debug-info \
                          test uses tcp 5039 port. please reserve it");
             }
index 28c7cfb88c9d61434b4969bd489e8a08388adf68..3d954a33a00292e41cf3ce34407baf412cba082a 100644 (file)
@@ -26,8 +26,6 @@ pub struct TestProps {
     pub aux_builds: Vec<~str> ,
     // Environment settings to use during execution
     pub exec_env: Vec<(~str,~str)> ,
-    // Commands to be given to the debugger, when testing debug info
-    pub debugger_cmds: Vec<~str> ,
     // Lines to check if they appear in the expected debugger output
     pub check_lines: Vec<~str> ,
     // Flag to force a crate to be built with the host architecture
@@ -46,7 +44,6 @@ pub fn load_props(testfile: &Path) -> TestProps {
     let mut compile_flags = None;
     let mut run_flags = None;
     let mut pp_exact = None;
-    let mut debugger_cmds = Vec::new();
     let mut check_lines = Vec::new();
     let mut force_host = false;
     let mut check_stdout = false;
@@ -91,11 +88,6 @@ pub fn load_props(testfile: &Path) -> TestProps {
             None => {}
         }
 
-        match parse_debugger_cmd(ln) {
-            Some(dc) => debugger_cmds.push(dc),
-            None => ()
-        };
-
         match parse_check_line(ln) {
             Some(cl) => check_lines.push(cl),
             None => ()
@@ -111,7 +103,6 @@ pub fn load_props(testfile: &Path) -> TestProps {
         pp_exact: pp_exact,
         aux_builds: aux_builds,
         exec_env: exec_env,
-        debugger_cmds: debugger_cmds,
         check_lines: check_lines,
         force_host: force_host,
         check_stdout: check_stdout,
@@ -173,10 +164,6 @@ fn parse_run_flags(line: &str) -> Option<~str> {
     parse_name_value_directive(line, "run-flags".to_owned())
 }
 
-fn parse_debugger_cmd(line: &str) -> Option<~str> {
-    parse_name_value_directive(line, "debugger".to_owned())
-}
-
 fn parse_check_line(line: &str) -> Option<~str> {
     parse_name_value_directive(line, "check".to_owned())
 }
@@ -226,7 +213,7 @@ fn parse_name_directive(line: &str, directive: &str) -> bool {
     line.contains(directive)
 }
 
-fn parse_name_value_directive(line: &str,
+pub fn parse_name_value_directive(line: &str,
                               directive: ~str) -> Option<~str> {
     let keycolon = directive + ":";
     match line.find_str(keycolon) {
index c1ca27c805cdb2b843e264dc4918328c1c6b4760..cea440afd9028592d728d41d504e05726f41dc70 100644 (file)
@@ -8,14 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use common::config;
-use common::mode_compile_fail;
-use common::mode_pretty;
-use common::mode_run_fail;
-use common::mode_run_pass;
+use common::{config, mode_compile_fail, mode_pretty, mode_run_fail, mode_run_pass};
 use errors;
 use header::TestProps;
-use header::load_props;
+use header;
 use procsrv;
 use util::logv;
 #[cfg(target_os = "win32")]
@@ -59,14 +55,15 @@ pub fn run_metrics(config: config, testfile: ~str, mm: &mut MetricMap) {
     }
     let testfile = Path::new(testfile);
     debug!("running {}", testfile.display());
-    let props = load_props(&testfile);
+    let props = header::load_props(&testfile);
     debug!("loaded props");
     match config.mode {
       mode_compile_fail => run_cfail_test(&config, &props, &testfile),
       mode_run_fail => run_rfail_test(&config, &props, &testfile),
       mode_run_pass => run_rpass_test(&config, &props, &testfile),
       mode_pretty => run_pretty_test(&config, &props, &testfile),
-      mode_debug_info => run_debuginfo_test(&config, &props, &testfile),
+      mode_debug_info_gdb => run_debuginfo_gdb_test(&config, &props, &testfile),
+      mode_debug_info_lldb => run_debuginfo_lldb_test(&config, &props, &testfile),
       mode_codegen => run_codegen_test(&config, &props, &testfile, mm)
     }
 }
@@ -259,7 +256,7 @@ fn make_typecheck_args(config: &config, props: &TestProps, testfile: &Path) -> P
     }
 }
 
-fn run_debuginfo_test(config: &config, props: &TestProps, testfile: &Path) {
+fn run_debuginfo_gdb_test(config: &config, props: &TestProps, testfile: &Path) {
     let mut config = config {
         target_rustcflags: cleanup_debug_info_options(&config.target_rustcflags),
         host_rustcflags: cleanup_debug_info_options(&config.host_rustcflags),
@@ -267,18 +264,19 @@ fn run_debuginfo_test(config: &config, props: &TestProps, testfile: &Path) {
     };
 
     let config = &mut config;
-    let check_lines = &props.check_lines;
-    let mut cmds = props.debugger_cmds.connect("\n");
+    let DebuggerCommands { commands, check_lines, .. } = parse_debugger_commands(testfile, "gdb");
+    let mut cmds = commands.connect("\n");
 
     // compile test file (it shoud have 'compile-flags:-g' in the header)
-    let mut proc_res = compile_test(config, props, testfile);
-    if !proc_res.status.success() {
-        fatal_ProcRes("compilation failed!".to_owned(), &proc_res);
+    let compiler_run_result = compile_test(config, props, testfile);
+    if !compiler_run_result.status.success() {
+        fatal_ProcRes("compilation failed!".to_owned(), &compiler_run_result);
     }
 
     let exe_file = make_exe_name(config, testfile);
 
     let mut proc_args;
+    let debugger_run_result;
     match config.target.as_slice() {
         "arm-linux-androideabi" => {
 
@@ -363,10 +361,12 @@ fn run_debuginfo_test(config: &config, props: &TestProps, testfile: &Path) {
                 cmdline
             };
 
-            proc_res = ProcRes {status: status,
-                               stdout: out,
-                               stderr: err,
-                               cmdline: cmdline};
+            debugger_run_result = ProcRes {
+                status: status,
+                stdout: out,
+                stderr: err,
+                cmdline: cmdline
+            };
             process.signal_kill().unwrap();
         }
 
@@ -391,25 +391,199 @@ fn debugger() -> ~str { "gdb".to_owned() }
                 "-command=" + debugger_script.as_str().unwrap().to_owned(),
                 exe_file.as_str().unwrap().to_owned());
             proc_args = ProcArgs {prog: debugger(), args: debugger_opts};
-            proc_res = compose_and_run(config, testfile, proc_args, Vec::new(), "", None);
+            debugger_run_result = compose_and_run(config,
+                                                  testfile,
+                                                  proc_args,
+                                                  Vec::new(),
+                                                  "",
+                                                  None);
         }
     }
 
-    if !proc_res.status.success() {
+    if !debugger_run_result.status.success() {
         fatal("gdb failed to execute".to_owned());
     }
+
+    check_debugger_output(&debugger_run_result, check_lines.as_slice());
+}
+
+fn run_debuginfo_lldb_test(config: &config, props: &TestProps, testfile: &Path) {
+    use std::io::process::{Process, ProcessConfig, ProcessOutput};
+
+    if config.lldb_python_dir.is_none() {
+        fatal("Can't run LLDB test because LLDB's python path is not set.".to_owned());
+    }
+
+    let mut config = config {
+        target_rustcflags: cleanup_debug_info_options(&config.target_rustcflags),
+        host_rustcflags: cleanup_debug_info_options(&config.host_rustcflags),
+        .. config.clone()
+    };
+
+    let config = &mut config;
+
+    // compile test file (it shoud have 'compile-flags:-g' in the header)
+    let compile_result = compile_test(config, props, testfile);
+    if !compile_result.status.success() {
+        fatal_ProcRes("compilation failed!".to_owned(), &compile_result);
+    }
+
+    let exe_file = make_exe_name(config, testfile);
+
+    // Parse debugger commands etc from test files
+    let DebuggerCommands {
+        commands,
+        check_lines,
+        breakpoint_lines
+    } = parse_debugger_commands(testfile, "lldb");
+
+    // Write debugger script:
+    // We don't want to hang when calling `quit` while the process is still running
+    let mut script_str = StrBuf::from_str("settings set auto-confirm true\n");
+
+    // Set breakpoints on every line that contains the string "#break"
+    for line in breakpoint_lines.iter() {
+        script_str.push_str(format!("breakpoint set --line {}\n", line));
+    }
+
+    // Append the other commands
+    for line in commands.iter() {
+        script_str.push_str(line.as_slice());
+        script_str.push_str("\n");
+    }
+
+    // Finally, quit the debugger
+    script_str.push_str("quit\n");
+
+    // Write the script into a file
+    debug!("script_str = {}", script_str);
+    dump_output_file(config, testfile, script_str.into_owned(), "debugger.script");
+    let debugger_script = make_out_name(config, testfile, "debugger.script");
+
+    // Let LLDB execute the script via lldb_batchmode.py
+    let debugger_run_result = run_lldb(config, &exe_file, &debugger_script);
+
+    if !debugger_run_result.status.success() {
+        fatal_ProcRes("Error while running LLDB".to_owned(), &debugger_run_result);
+    }
+
+    check_debugger_output(&debugger_run_result, check_lines.as_slice());
+
+    fn run_lldb(config: &config, test_executable: &Path, debugger_script: &Path) -> ProcRes {
+        // Prepare the lldb_batchmode which executes the debugger script
+        let lldb_batchmode_script = "./src/etc/lldb_batchmode.py".to_owned();
+        let test_executable_str = test_executable.as_str().unwrap().to_owned();
+        let debugger_script_str = debugger_script.as_str().unwrap().to_owned();
+        let commandline = format!("python {} {} {}",
+                                  lldb_batchmode_script.as_slice(),
+                                  test_executable_str.as_slice(),
+                                  debugger_script_str.as_slice());
+
+        let args = &[lldb_batchmode_script, test_executable_str, debugger_script_str];
+        let env = &[("PYTHONPATH".to_owned(), config.lldb_python_dir.clone().unwrap())];
+
+        let mut opt_process = Process::configure(ProcessConfig {
+            program: "python",
+            args: args,
+            env: Some(env),
+            .. ProcessConfig::new()
+        });
+
+        let (status, out, err) = match opt_process {
+            Ok(ref mut process) => {
+                let ProcessOutput { status, output, error } = process.wait_with_output();
+
+                (status,
+                 str::from_utf8(output.as_slice()).unwrap().to_owned(),
+                 str::from_utf8(error.as_slice()).unwrap().to_owned())
+            },
+            Err(e) => {
+                fatal(format!("Failed to setup Python process for LLDB script: {}", e))
+            }
+        };
+
+        dump_output(config, test_executable, out, err);
+        return ProcRes {
+            status: status,
+            stdout: out,
+            stderr: err,
+            cmdline: commandline
+        };
+    }
+}
+
+struct DebuggerCommands
+{
+    commands: Vec<~str>,
+    check_lines: Vec<~str>,
+    breakpoint_lines: Vec<uint>
+}
+
+fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str) -> DebuggerCommands {
+    use std::io::{BufferedReader, File};
+
+    let command_directive = debugger_prefix + "-command";
+    let check_directive = debugger_prefix + "-check";
+
+    let mut breakpoint_lines = vec!();
+    let mut commands = vec!();
+    let mut check_lines = vec!();
+    let mut counter = 1;
+    let mut reader = BufferedReader::new(File::open(file_path).unwrap());
+    for line in reader.lines() {
+        match line {
+            Ok(line) => {
+                if line.contains("#break") {
+                    breakpoint_lines.push(counter);
+                }
+
+                header::parse_name_value_directive(line, command_directive.clone())
+                    .map(|cmd| commands.push(cmd));
+
+                header::parse_name_value_directive(line, check_directive.clone())
+                    .map(|cmd| check_lines.push(cmd));
+            }
+            Err(e) => {
+                fatal(format!("Error while parsing debugger commands: {}", e))
+            }
+        }
+        counter += 1;
+    }
+
+    DebuggerCommands {
+        commands: commands,
+        check_lines: check_lines,
+        breakpoint_lines: breakpoint_lines
+    }
+}
+
+fn cleanup_debug_info_options(options: &Option<~str>) -> Option<~str> {
+    if options.is_none() {
+        return None;
+    }
+
+    // Remove options that are either unwanted (-O) or may lead to duplicates due to RUSTFLAGS.
+    let options_to_remove = ["-O".to_owned(), "-g".to_owned(), "--debuginfo".to_owned()];
+    let new_options = split_maybe_args(options).move_iter()
+                                               .filter(|x| !options_to_remove.contains(x))
+                                               .collect::<Vec<~str>>()
+                                               .connect(" ");
+    Some(new_options)
+}
+
+fn check_debugger_output(debugger_run_result: &ProcRes, check_lines: &[~str]) {
     let num_check_lines = check_lines.len();
     if num_check_lines > 0 {
         // Allow check lines to leave parts unspecified (e.g., uninitialized
         // bits in the wrong case of an enum) with the notation "[...]".
         let check_fragments: Vec<Vec<~str>> =
             check_lines.iter().map(|s| {
-                s.split_str("[...]").map(|x| x.to_str()).collect()
+                s.trim().split_str("[...]").map(|x| x.to_str()).collect()
             }).collect();
         // check if each line in props.check_lines appears in the
         // output (in order)
         let mut i = 0u;
-        for line in proc_res.stdout.lines() {
+        for line in debugger_run_result.stdout.lines() {
             let mut rest = line.trim();
             let mut first = true;
             let mut failed = false;
@@ -440,23 +614,9 @@ fn debugger() -> ~str { "gdb".to_owned() }
         }
         if i != num_check_lines {
             fatal_ProcRes(format!("line not found in debugger output: {}",
-                                  *check_lines.get(i)), &proc_res);
+                                  check_lines.get(i).unwrap()), debugger_run_result);
         }
     }
-
-    fn cleanup_debug_info_options(options: &Option<~str>) -> Option<~str> {
-        if options.is_none() {
-            return None;
-        }
-
-        // Remove options that are either unwanted (-O) or may lead to duplicates due to RUSTFLAGS.
-        let options_to_remove = ["-O".to_owned(), "-g".to_owned(), "--debuginfo".to_owned()];
-        let new_options = split_maybe_args(options).move_iter()
-                                                   .filter(|x| !options_to_remove.contains(x))
-                                                   .collect::<Vec<~str>>()
-                                                   .connect(" ");
-        Some(new_options)
-    }
 }
 
 fn check_error_patterns(props: &TestProps,
@@ -736,7 +896,7 @@ fn compose_and_run_compiler(
 
     for rel_ab in props.aux_builds.iter() {
         let abs_ab = config.aux_base.join(rel_ab.as_slice());
-        let aux_props = load_props(&abs_ab);
+        let aux_props = header::load_props(&abs_ab);
         let crate_type = if aux_props.no_prefer_dynamic {
             Vec::new()
         } else {
@@ -837,7 +997,7 @@ fn make_lib_name(config: &config, auxfile: &Path, testfile: &Path) -> Path {
 fn make_exe_name(config: &config, testfile: &Path) -> Path {
     let mut f = output_base_name(config, testfile);
     if !os::consts::EXE_SUFFIX.is_empty() {
-        match f.filename().map(|s| s + os::consts::EXE_SUFFIX.as_bytes()) {
+        match f.filename().map(|s| Vec::from_slice(s).append(os::consts::EXE_SUFFIX.as_bytes())) {
             Some(v) => f.set_filename(v),
             None => ()
         }
@@ -931,7 +1091,7 @@ fn make_out_name(config: &config, testfile: &Path, extension: &str) -> Path {
 
 fn aux_output_dir_name(config: &config, testfile: &Path) -> Path {
     let mut f = output_base_name(config, testfile);
-    match f.filename().map(|s| s + bytes!(".libaux")) {
+    match f.filename().map(|s| Vec::from_slice(s).append(bytes!(".libaux"))) {
         Some(v) => f.set_filename(v),
         None => ()
     }
@@ -1113,7 +1273,7 @@ fn append_suffix_to_stem(p: &Path, suffix: &str) -> Path {
         (*p).clone()
     } else {
         let stem = p.filestem().unwrap();
-        p.with_filename(stem + bytes!("-") + suffix.as_bytes())
+        p.with_filename(Vec::from_slice(stem).append(bytes!("-")).append(suffix.as_bytes()))
     }
 }
 
index 6a54dc7ea1809366d770d2ee03c7950b29889821..1ab92d453785e41f1fe4f2b80ea3edf801e22408 100644 (file)
@@ -266,8 +266,8 @@ Iterators offer generic conversion to containers with the `collect` adaptor:
 
 ~~~
 let xs = [0, 1, 1, 2, 3, 5, 8];
-let ys = xs.iter().rev().skip(1).map(|&x| x * 2).collect::<~[int]>();
-assert_eq!(ys, ~[10, 6, 4, 2, 2, 0]);
+let ys = xs.iter().rev().skip(1).map(|&x| x * 2).collect::<Vec<int>>();
+assert_eq!(ys, vec![10, 6, 4, 2, 2, 0]);
 ~~~
 
 The method requires a type hint for the container type, if the surrounding code
@@ -278,14 +278,14 @@ implementing the `FromIterator` trait. For example, the implementation for
 vectors is as follows:
 
 ~~~ {.ignore}
-impl<A> FromIterator<A> for ~[A] {
-    pub fn from_iter<T: Iterator<A>>(iterator: &mut T) -> ~[A] {
+impl<T> FromIterator<T> for Vec<T> {
+    fn from_iter<I:Iterator<A>>(mut iterator: I) -> Vec<T> {
         let (lower, _) = iterator.size_hint();
-        let mut xs = with_capacity(lower);
-        for x in iterator {
-            xs.push(x);
+        let mut vector = Vec::with_capacity(lower);
+        for element in iterator {
+            vector.push(element);
         }
-        xs
+        vector
     }
 }
 ~~~
index 44e7a304e671dfa1a98c55f194e97795ffaabd35..e4c95538d3012199035ed6530b8f5f212b31539e 100644 (file)
@@ -208,7 +208,7 @@ The keywords are the following strings:
 
 ~~~~ {.notrust .keyword}
 as
-break
+box break
 crate
 else enum extern
 false fn for
@@ -3598,18 +3598,18 @@ and the cast expression in `main`.
 Within the body of an item that has type parameter declarations, the names of its type parameters are types:
 
 ~~~~
-fn map<A: Clone, B: Clone>(f: |A| -> B, xs: &[A]) -> ~[B] {
+fn map<A: Clone, B: Clone>(f: |A| -> B, xs: &[A]) -> Vec<B> {
     if xs.len() == 0 {
-       return ~[];
+       return vec![];
     }
     let first: B = f(xs[0].clone());
-    let rest: ~[B] = map(f, xs.slice(1, xs.len()));
-    return ~[first] + rest;
+    let rest: Vec<B> = map(f, xs.slice(1, xs.len()));
+    return vec![first].append(rest.as_slice());
 }
 ~~~~
 
 Here, `first` has type `B`, referring to `map`'s `B` type parameter;
-and `rest` has type `~[B]`, a vector type with element type `B`.
+and `rest` has type `Vec<B>`, a vector type with element type `B`.
 
 ### Self types
 
index 56f9e8e5cbd7d7f3337396aa6ddbc85cefc99277..9b9153fe579462b47a9080e71c2743b9d6ebaa4c 100644 (file)
@@ -1588,8 +1588,8 @@ let mut numbers = vec![1, 2, 3];
 numbers.push(4);
 numbers.push(5);
 
-// The type of a unique vector is written as `~[int]`
-let more_numbers: ~[int] = numbers.move_iter().collect();
+// The type of a unique vector is written as `Vec<int>`
+let more_numbers: Vec<int> = numbers.move_iter().map(|i| i+1).collect();
 
 // The original `numbers` value can no longer be used, due to move semantics.
 
@@ -1633,7 +1633,7 @@ view[0] = 5;
 let ys: &mut [int] = &mut [1, 2, 3];
 ~~~
 
-Square brackets denote indexing into a vector:
+Square brackets denote indexing into a slice or fixed-size vector:
 
 ~~~~
 # enum Crayon { Almond, AntiqueBrass, Apricot,
@@ -1647,7 +1647,7 @@ match crayons[0] {
 }
 ~~~~
 
-A vector can be destructured using pattern matching:
+A slice or fixed-size vector can be destructured using pattern matching:
 
 ~~~~
 let numbers: &[int] = &[1, 2, 3];
@@ -1660,9 +1660,10 @@ let score = match numbers {
 ~~~~
 
 Both vectors and strings support a number of useful [methods](#methods),
-defined in [`std::vec`] and [`std::str`].
+defined in [`std::vec`], [`std::slice`], and [`std::str`].
 
 [`std::vec`]: std/vec/index.html
+[`std::slice`]: std/slice/index.html
 [`std::str`]: std/str/index.html
 
 # Ownership escape hatches
index 7ffa35b94e49118d37f090d86f21a406ba292526..7c9780456cf4763e5895d1c101cab31663586638 100644 (file)
@@ -38,6 +38,7 @@
                <keyword>as</keyword>
                <keyword>assert</keyword>
                <keyword>break</keyword>
+               <keyword>box</keyword>
                <keyword>const</keyword>
                <keyword>continue</keyword>
                <keyword>crate</keyword>
index 367d2738ab3c9cde3277e696c5972280d9e9ffdd..c28107fe9fa26fe2cffa28da011f2698eb5b307d 100644 (file)
@@ -18,6 +18,7 @@
        <list name="keywords">
                <item> as </item>
                <item> break </item>
+               <item> box </item>
                <item> continue </item>
                <item> crate </item>
                <item> do </item>
diff --git a/src/etc/lldb_batchmode.py b/src/etc/lldb_batchmode.py
new file mode 100644 (file)
index 0000000..85bfc42
--- /dev/null
@@ -0,0 +1,184 @@
+# Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+# file at the top-level directory of this distribution and at
+# http://rust-lang.org/COPYRIGHT.
+#
+# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+# option. This file may not be copied, modified, or distributed
+# except according to those terms.
+
+# This script allows to use LLDB in a way similar to GDB's batch mode. That is, given a text file
+# containing LLDB commands (one command per line), this script will execute the commands one after
+# the other.
+# LLDB also has the -s and -S commandline options which also execute a list of commands from a text
+# file. However, this command are execute `immediately`: a the command of a `run` or `continue`
+# command will be executed immediately after the `run` or `continue`, without waiting for the next
+# breakpoint to be hit. This a command sequence like the following will not yield reliable results:
+#
+#   break 11
+#   run
+#   print x
+#
+# Most of the time the `print` command will be executed while the program is still running will thus
+# fail. Using this Python script, the above will work as expected.
+
+from __future__ import print_function
+import lldb
+import os
+import sys
+import threading
+import re
+import atexit
+
+# Terminate the debugger
+atexit.register(lambda: lldb.SBDebugger.Terminate())
+
+# Set this to True for additional output
+DEBUG_OUTPUT = False
+
+def print_debug(s):
+  "Print something if DEBUG_OUTPUT is True"
+  global DEBUG_OUTPUT
+  if DEBUG_OUTPUT:
+    print("DEBUG: " + str(s))
+
+
+def normalize_whitespace(s):
+  "Replace newlines, tabs, multiple spaces, etc with exactly one space"
+  return re.sub("\s+", " ", s)
+
+
+# This callback is registered with every breakpoint and makes sure that the frame containing the
+# breakpoint location is selected
+def breakpoint_callback(frame, bp_loc, dict):
+  "Called whenever a breakpoint is hit"
+  print("Hit breakpoint " + str(bp_loc))
+
+  # Select the frame and the thread containing it
+  frame.thread.process.SetSelectedThread(frame.thread)
+  frame.thread.SetSelectedFrame(frame.idx)
+
+  # Returning True means that we actually want to stop at this breakpoint
+  return True
+
+
+# This is a list of breakpoints that are not registered with the breakpoint callback. The list is
+# populated by the breakpoint listener and checked/emptied whenever a command has been executed
+new_breakpoints = []
+
+# This set contains all breakpoint ids that have already been registered with a callback, and is
+# used to avoid hooking callbacks into breakpoints more than once
+registered_breakpoints = set()
+
+def execute_command(command_interpreter, command):
+  "Executes a single CLI command"
+  global new_breakpoints
+  global registered_breakpoints
+
+  res = lldb.SBCommandReturnObject()
+  print(command)
+  command_interpreter.HandleCommand(command, res)
+
+  if res.Succeeded():
+      if res.HasResult():
+          print(normalize_whitespace(res.GetOutput()), end = '\n')
+
+      # If the command introduced any breakpoints, make sure to register them with the breakpoint
+      # callback
+      while len(new_breakpoints) > 0:
+        res.Clear()
+        breakpoint_id = new_breakpoints.pop()
+
+        if breakpoint_id in registered_breakpoints:
+          print_debug("breakpoint with id %s is already registered. Ignoring." % str(breakpoint_id))
+        else:
+          print_debug("registering breakpoint callback, id = " + str(breakpoint_id))
+          callback_command = "breakpoint command add -F breakpoint_callback " + str(breakpoint_id)
+          command_interpreter.HandleCommand(callback_command, res)
+          if res.Succeeded():
+            print_debug("successfully registered breakpoint callback, id = " + str(breakpoint_id))
+            registered_breakpoints.add(breakpoint_id)
+          else:
+            print("Error while trying to register breakpoint callback, id = " + str(breakpoint_id))
+  else:
+      print(res.GetError())
+
+
+def start_breakpoint_listener(target):
+  "Listens for breakpoints being added and adds new ones to the callback registration list"
+  listener = lldb.SBListener("breakpoint listener")
+
+  def listen():
+    event = lldb.SBEvent()
+    try:
+      while True:
+        if listener.WaitForEvent(120, event):
+          if lldb.SBBreakpoint.EventIsBreakpointEvent(event) and \
+             lldb.SBBreakpoint.GetBreakpointEventTypeFromEvent(event) == \
+             lldb.eBreakpointEventTypeAdded:
+            global new_breakpoints
+            breakpoint = lldb.SBBreakpoint.GetBreakpointFromEvent(event)
+            print_debug("breakpoint added, id = " + str(breakpoint.id))
+            new_breakpoints.append(breakpoint.id)
+    except:
+      print_debug("breakpoint listener shutting down")
+
+  # Start the listener and let it run as a daemon
+  listener_thread = threading.Thread(target = listen)
+  listener_thread.daemon = True
+  listener_thread.start()
+
+  # Register the listener with the target
+  target.GetBroadcaster().AddListener(listener, lldb.SBTarget.eBroadcastBitBreakpointChanged)
+
+
+####################################################################################################
+# ~main
+####################################################################################################
+
+if len(sys.argv) != 3:
+  print("usage: python lldb_batchmode.py target-path script-path")
+  sys.exit(1)
+
+target_path = sys.argv[1]
+script_path = sys.argv[2]
+
+
+# Create a new debugger instance
+debugger = lldb.SBDebugger.Create()
+
+# When we step or continue, don't return from the function until the process
+# stops. We do this by setting the async mode to false.
+debugger.SetAsync(False)
+
+# Create a target from a file and arch
+print("Creating a target for '%s'" % target_path)
+target = debugger.CreateTargetWithFileAndArch(target_path, lldb.LLDB_ARCH_DEFAULT)
+
+if not target:
+  print("Could not create debugging target '" + target_path + "'. Aborting.", file=sys.stderr)
+  sys.exit(1)
+
+
+# Register the breakpoint callback for every breakpoint
+start_breakpoint_listener(target)
+
+command_interpreter = debugger.GetCommandInterpreter()
+
+try:
+  script_file = open(script_path, 'r')
+
+  for line in script_file:
+    command = line.strip()
+    if command != '':
+      execute_command(command_interpreter, command)
+
+except IOError as e:
+  print("Could not read debugging script '%s'." % script_path, file = sys.stderr)
+  print(e, file = sys.stderr)
+  print("Aborting.", file = sys.stderr)
+  sys.exit(1)
+finally:
+  script_file.close()
+
index f937fd8caa6f8aadee653e22942518d871b7de86..765096933d1c16874483a81fd42145d8581ac332 100644 (file)
@@ -18,7 +18,7 @@ syn keyword   rustOperator    as
 
 syn match     rustAssert      "\<assert\(\w\)*!" contained
 syn match     rustFail        "\<fail\(\w\)*!" contained
-syn keyword   rustKeyword     break continue
+syn keyword   rustKeyword     break box continue
 syn keyword   rustKeyword     extern nextgroup=rustExternCrate,rustObsoleteExternMod skipwhite
 syn keyword   rustKeyword     for in if impl let
 syn keyword   rustKeyword     loop once priv pub
index ce8e1474ee50b94d17be73e03606d1f2c90cbc35..2d1de87fe0665d221e698fdd615d72fb225040dc 100644 (file)
@@ -1617,8 +1617,7 @@ mod test_map {
     use std::cmp::Equiv;
     use std::hash::Hash;
     use std::iter::{Iterator,range_inclusive,range_step_inclusive};
-    use std::local_data;
-    use std::vec;
+    use std::cell::RefCell;
 
     struct KindaIntLike(int);
 
@@ -1657,7 +1656,7 @@ fn test_insert() {
         assert_eq!(*m.find(&2).unwrap(), 4);
     }
 
-    local_data_key!(drop_vector: vec::Vec<int>)
+    local_data_key!(drop_vector: RefCell<Vec<int>>)
 
     #[deriving(Hash, Eq, TotalEq)]
     struct Dropable {
@@ -1667,8 +1666,8 @@ struct Dropable {
 
     impl Dropable {
         fn new(k: uint) -> Dropable {
-            local_data::get_mut(drop_vector,
-                |v| { v.unwrap().as_mut_slice()[k] += 1; });
+            let v = drop_vector.get().unwrap();
+            v.borrow_mut().as_mut_slice()[k] += 1;
 
             Dropable { k: k }
         }
@@ -1676,23 +1675,23 @@ fn new(k: uint) -> Dropable {
 
     impl Drop for Dropable {
         fn drop(&mut self) {
-            local_data::get_mut(drop_vector, |v|
-                { v.unwrap().as_mut_slice()[self.k] -= 1; });
+            let v = drop_vector.get().unwrap();
+            v.borrow_mut().as_mut_slice()[self.k] -= 1;
         }
     }
 
     #[test]
     fn test_drops() {
-        local_data::set(drop_vector, vec::Vec::from_elem(200, 0));
+        drop_vector.replace(Some(RefCell::new(Vec::from_elem(200, 0))));
 
         {
             let mut m = HashMap::new();
 
-            local_data::get(drop_vector, |v| {
-                for i in range(0u, 200) {
-                    assert_eq!(v.unwrap().as_slice()[i], 0);
-                }
-            });
+            let v = drop_vector.get().unwrap();
+            for i in range(0u, 200) {
+                assert_eq!(v.borrow().as_slice()[i], 0);
+            }
+            drop(v);
 
             for i in range(0u, 100) {
                 let d1 = Dropable::new(i);
@@ -1700,11 +1699,11 @@ fn test_drops() {
                 m.insert(d1, d2);
             }
 
-            local_data::get(drop_vector, |v| {
-                for i in range(0u, 200) {
-                    assert_eq!(v.unwrap().as_slice()[i], 1);
-                }
-            });
+            let v = drop_vector.get().unwrap();
+            for i in range(0u, 200) {
+                assert_eq!(v.borrow().as_slice()[i], 1);
+            }
+            drop(v);
 
             for i in range(0u, 50) {
                 let k = Dropable::new(i);
@@ -1712,30 +1711,27 @@ fn test_drops() {
 
                 assert!(v.is_some());
 
-                local_data::get(drop_vector, |v| {
-                    assert_eq!(v.unwrap().as_slice()[i], 1);
-                    assert_eq!(v.unwrap().as_slice()[i+100], 1);
-                });
+                let v = drop_vector.get().unwrap();
+                assert_eq!(v.borrow().as_slice()[i], 1);
+                assert_eq!(v.borrow().as_slice()[i+100], 1);
             }
 
-            local_data::get(drop_vector, |v| {
-                for i in range(0u, 50) {
-                    assert_eq!(v.unwrap().as_slice()[i], 0);
-                    assert_eq!(v.unwrap().as_slice()[i+100], 0);
-                }
+            let v = drop_vector.get().unwrap();
+            for i in range(0u, 50) {
+                assert_eq!(v.borrow().as_slice()[i], 0);
+                assert_eq!(v.borrow().as_slice()[i+100], 0);
+            }
 
-                for i in range(50u, 100) {
-                    assert_eq!(v.unwrap().as_slice()[i], 1);
-                    assert_eq!(v.unwrap().as_slice()[i+100], 1);
-                }
-            });
+            for i in range(50u, 100) {
+                assert_eq!(v.borrow().as_slice()[i], 1);
+                assert_eq!(v.borrow().as_slice()[i+100], 1);
+            }
         }
 
-        local_data::get(drop_vector, |v| {
-            for i in range(0u, 200) {
-                assert_eq!(v.unwrap().as_slice()[i], 0);
-            }
-        });
+        let v = drop_vector.get().unwrap();
+        for i in range(0u, 200) {
+            assert_eq!(v.borrow().as_slice()[i], 0);
+        }
     }
 
     #[test]
index 5ee642cd8100d1a3f080ab7f0744e4e48c50545b..10ae30cf39d0cc08628657bd80f9269459492071 100644 (file)
@@ -455,8 +455,8 @@ fn advance(&mut self, f: |A| -> bool) -> bool {
     ///
     /// ```rust
     /// let a = [1, 2, 3, 4, 5];
-    /// let b: ~[int] = a.iter().map(|&x| x).collect();
-    /// assert!(a == b);
+    /// let b: Vec<int> = a.iter().map(|&x| x).collect();
+    /// assert!(a.as_slice() == b.as_slice());
     /// ```
     #[inline]
     fn collect<B: FromIterator<A>>(&mut self) -> B {
@@ -2340,8 +2340,8 @@ mod tests {
     #[test]
     fn test_counter_from_iter() {
         let it = count(0, 5).take(10);
-        let xs: ~[int] = FromIterator::from_iter(it);
-        assert_eq!(xs, box [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]);
+        let xs: Vec<int> = FromIterator::from_iter(it);
+        assert_eq!(xs, vec![0, 5, 10, 15, 20, 25, 30, 35, 40, 45]);
     }
 
     #[test]
@@ -2371,7 +2371,7 @@ fn test_iterator_chain() {
     fn test_filter_map() {
         let mut it = count(0u, 1u).take(10)
             .filter_map(|x| if x % 2 == 0 { Some(x*x) } else { None });
-        assert_eq!(it.collect::<~[uint]>(), box [0*0, 2*2, 4*4, 6*6, 8*8]);
+        assert_eq!(it.collect::<Vec<uint>>(), vec![0*0, 2*2, 4*4, 6*6, 8*8]);
     }
 
     #[test]
@@ -2493,7 +2493,7 @@ fn test_inspect() {
         let ys = xs.iter()
                    .map(|&x| x)
                    .inspect(|_| n += 1)
-                   .collect::<~[uint]>();
+                   .collect::<Vec<uint>>();
 
         assert_eq!(n, xs.len());
         assert_eq!(xs.as_slice(), ys.as_slice());
@@ -2628,8 +2628,8 @@ fn test_iterator_size_hint() {
 
     #[test]
     fn test_collect() {
-        let a = box [1, 2, 3, 4, 5];
-        let b: ~[int] = a.iter().map(|&x| x).collect();
+        let a = vec![1, 2, 3, 4, 5];
+        let b: Vec<int> = a.iter().map(|&x| x).collect();
         assert_eq!(a, b);
     }
 
@@ -2702,7 +2702,7 @@ fn test_rev() {
         let mut it = xs.iter();
         it.next();
         it.next();
-        assert_eq!(it.rev().map(|&x| x).collect::<~[int]>(), box [16, 14, 12, 10, 8, 6]);
+        assert_eq!(it.rev().map(|&x| x).collect::<Vec<int>>(), vec![16, 14, 12, 10, 8, 6]);
     }
 
     #[test]
@@ -2940,12 +2940,12 @@ fn test_random_access_cycle() {
 
     #[test]
     fn test_double_ended_range() {
-        assert_eq!(range(11i, 14).rev().collect::<~[int]>(), box [13i, 12, 11]);
+        assert_eq!(range(11i, 14).rev().collect::<Vec<int>>(), vec![13i, 12, 11]);
         for _ in range(10i, 0).rev() {
             fail!("unreachable");
         }
 
-        assert_eq!(range(11u, 14).rev().collect::<~[uint]>(), box [13u, 12, 11]);
+        assert_eq!(range(11u, 14).rev().collect::<Vec<uint>>(), vec![13u, 12, 11]);
         for _ in range(10u, 0).rev() {
             fail!("unreachable");
         }
@@ -2997,13 +2997,14 @@ fn one() -> Foo {
             }
         }
 
-        assert_eq!(range(0i, 5).collect::<~[int]>(), box [0i, 1, 2, 3, 4]);
-        assert_eq!(range(-10i, -1).collect::<~[int]>(), box [-10, -9, -8, -7, -6, -5, -4, -3, -2]);
-        assert_eq!(range(0i, 5).rev().collect::<~[int]>(), box [4, 3, 2, 1, 0]);
-        assert_eq!(range(200, -5).collect::<~[int]>(), box []);
-        assert_eq!(range(200, -5).rev().collect::<~[int]>(), box []);
-        assert_eq!(range(200, 200).collect::<~[int]>(), box []);
-        assert_eq!(range(200, 200).rev().collect::<~[int]>(), box []);
+        assert_eq!(range(0i, 5).collect::<Vec<int>>(), vec![0i, 1, 2, 3, 4]);
+        assert_eq!(range(-10i, -1).collect::<Vec<int>>(),
+                   vec![-10, -9, -8, -7, -6, -5, -4, -3, -2]);
+        assert_eq!(range(0i, 5).rev().collect::<Vec<int>>(), vec![4, 3, 2, 1, 0]);
+        assert_eq!(range(200, -5).collect::<Vec<int>>(), vec![]);
+        assert_eq!(range(200, -5).rev().collect::<Vec<int>>(), vec![]);
+        assert_eq!(range(200, 200).collect::<Vec<int>>(), vec![]);
+        assert_eq!(range(200, 200).rev().collect::<Vec<int>>(), vec![]);
 
         assert_eq!(range(0i, 100).size_hint(), (100, Some(100)));
         // this test is only meaningful when sizeof uint < sizeof u64
@@ -3014,32 +3015,32 @@ fn one() -> Foo {
 
     #[test]
     fn test_range_inclusive() {
-        assert_eq!(range_inclusive(0i, 5).collect::<~[int]>(), box [0i, 1, 2, 3, 4, 5]);
-        assert_eq!(range_inclusive(0i, 5).rev().collect::<~[int]>(), box [5i, 4, 3, 2, 1, 0]);
-        assert_eq!(range_inclusive(200, -5).collect::<~[int]>(), box []);
-        assert_eq!(range_inclusive(200, -5).rev().collect::<~[int]>(), box []);
-        assert_eq!(range_inclusive(200, 200).collect::<~[int]>(), box [200]);
-        assert_eq!(range_inclusive(200, 200).rev().collect::<~[int]>(), box [200]);
+        assert_eq!(range_inclusive(0i, 5).collect::<Vec<int>>(), vec![0i, 1, 2, 3, 4, 5]);
+        assert_eq!(range_inclusive(0i, 5).rev().collect::<Vec<int>>(), vec![5i, 4, 3, 2, 1, 0]);
+        assert_eq!(range_inclusive(200, -5).collect::<Vec<int>>(), vec![]);
+        assert_eq!(range_inclusive(200, -5).rev().collect::<Vec<int>>(), vec![]);
+        assert_eq!(range_inclusive(200, 200).collect::<Vec<int>>(), vec![200]);
+        assert_eq!(range_inclusive(200, 200).rev().collect::<Vec<int>>(), vec![200]);
     }
 
     #[test]
     fn test_range_step() {
-        assert_eq!(range_step(0i, 20, 5).collect::<~[int]>(), box [0, 5, 10, 15]);
-        assert_eq!(range_step(20i, 0, -5).collect::<~[int]>(), box [20, 15, 10, 5]);
-        assert_eq!(range_step(20i, 0, -6).collect::<~[int]>(), box [20, 14, 8, 2]);
-        assert_eq!(range_step(200u8, 255, 50).collect::<~[u8]>(), box [200u8, 250]);
-        assert_eq!(range_step(200, -5, 1).collect::<~[int]>(), box []);
-        assert_eq!(range_step(200, 200, 1).collect::<~[int]>(), box []);
+        assert_eq!(range_step(0i, 20, 5).collect::<Vec<int>>(), vec![0, 5, 10, 15]);
+        assert_eq!(range_step(20i, 0, -5).collect::<Vec<int>>(), vec![20, 15, 10, 5]);
+        assert_eq!(range_step(20i, 0, -6).collect::<Vec<int>>(), vec![20, 14, 8, 2]);
+        assert_eq!(range_step(200u8, 255, 50).collect::<Vec<u8>>(), vec![200u8, 250]);
+        assert_eq!(range_step(200, -5, 1).collect::<Vec<int>>(), vec![]);
+        assert_eq!(range_step(200, 200, 1).collect::<Vec<int>>(), vec![]);
     }
 
     #[test]
     fn test_range_step_inclusive() {
-        assert_eq!(range_step_inclusive(0i, 20, 5).collect::<~[int]>(), box [0, 5, 10, 15, 20]);
-        assert_eq!(range_step_inclusive(20i, 0, -5).collect::<~[int]>(), box [20, 15, 10, 5, 0]);
-        assert_eq!(range_step_inclusive(20i, 0, -6).collect::<~[int]>(), box [20, 14, 8, 2]);
-        assert_eq!(range_step_inclusive(200u8, 255, 50).collect::<~[u8]>(), box [200u8, 250]);
-        assert_eq!(range_step_inclusive(200, -5, 1).collect::<~[int]>(), box []);
-        assert_eq!(range_step_inclusive(200, 200, 1).collect::<~[int]>(), box [200]);
+        assert_eq!(range_step_inclusive(0i, 20, 5).collect::<Vec<int>>(), vec![0, 5, 10, 15, 20]);
+        assert_eq!(range_step_inclusive(20i, 0, -5).collect::<Vec<int>>(), vec![20, 15, 10, 5, 0]);
+        assert_eq!(range_step_inclusive(20i, 0, -6).collect::<Vec<int>>(), vec![20, 14, 8, 2]);
+        assert_eq!(range_step_inclusive(200u8, 255, 50).collect::<Vec<u8>>(), vec![200u8, 250]);
+        assert_eq!(range_step_inclusive(200, -5, 1).collect::<Vec<int>>(), vec![]);
+        assert_eq!(range_step_inclusive(200, 200, 1).collect::<Vec<int>>(), vec![200]);
     }
 
     #[test]
index 53de765b89c1d43569ef5d6f880f205325912f88..a771f30dfd197aabab3ea2d22c4d1304c9792b90 100644 (file)
@@ -111,4 +111,6 @@ mod std {
     #[cfg(test)] pub use realstd::rt;     // needed for fail!()
     #[cfg(test)] pub use realstd::option; // needed for assert!()
     #[cfg(test)] pub use realstd::os;     // needed for tests
+    #[cfg(test)] pub use realstd::slice;  // needed for tests
+    #[cfg(test)] pub use realstd::vec;    // needed for vec![]
 }
index c6884a8002f799a06f17efe7d9dbe52e8ce2280a..2f8457e93f671b31725370c3a520c308481ff724 100644 (file)
@@ -844,22 +844,22 @@ fn test_mutate() {
 
     #[test]
     fn test_collect() {
-        let v: Option<~[int]> = collect(range(0, 0)
-                                        .map(|_| Some(0)));
-        assert_eq!(v, Some(box []));
+        let v: Option<Vec<int>> = collect(range(0, 0)
+                                          .map(|_| Some(0)));
+        assert_eq!(v, Some(vec![]));
 
-        let v: Option<~[int]> = collect(range(0, 3)
-                                        .map(|x| Some(x)));
-        assert_eq!(v, Some(box [0, 1, 2]));
+        let v: Option<Vec<int>> = collect(range(0, 3)
+                                          .map(|x| Some(x)));
+        assert_eq!(v, Some(vec![0, 1, 2]));
 
-        let v: Option<~[int]> = collect(range(0, 3)
-                                        .map(|x| if x > 1 { None } else { Some(x) }));
+        let v: Option<Vec<int>> = collect(range(0, 3)
+                                          .map(|x| if x > 1 { None } else { Some(x) }));
         assert_eq!(v, None);
 
         // test that it does not take more elements than it needs
         let mut functions = [|| Some(()), || None, || fail!()];
 
-        let v: Option<~[()]> = collect(functions.mut_iter().map(|f| (*f)()));
+        let v: Option<Vec<()>> = collect(functions.mut_iter().map(|f| (*f)()));
 
         assert_eq!(v, None);
     }
index 337b2ac89dd7aacc61ac982df1358d959d8e6932..27ae2ad9946f5718ae2852e5ee3a69029b9152fe 100644 (file)
@@ -653,20 +653,20 @@ pub fn test_impl_map_err() {
 
     #[test]
     fn test_collect() {
-        let v: Result<~[int], ()> = collect(range(0, 0).map(|_| Ok::<int, ()>(0)));
-        assert_eq!(v, Ok(box []));
+        let v: Result<Vec<int>, ()> = collect(range(0, 0).map(|_| Ok::<int, ()>(0)));
+        assert_eq!(v, Ok(vec![]));
 
-        let v: Result<~[int], ()> = collect(range(0, 3).map(|x| Ok::<int, ()>(x)));
-        assert_eq!(v, Ok(box [0, 1, 2]));
+        let v: Result<Vec<int>, ()> = collect(range(0, 3).map(|x| Ok::<int, ()>(x)));
+        assert_eq!(v, Ok(vec![0, 1, 2]));
 
-        let v: Result<~[int], int> = collect(range(0, 3)
-                                             .map(|x| if x > 1 { Err(x) } else { Ok(x) }));
+        let v: Result<Vec<int>, int> = collect(range(0, 3)
+                                               .map(|x| if x > 1 { Err(x) } else { Ok(x) }));
         assert_eq!(v, Err(2));
 
         // test that it does not take more elements than it needs
         let mut functions = [|| Ok(()), || Err(1), || fail!()];
 
-        let v: Result<~[()], int> = collect(functions.mut_iter().map(|f| (*f)()));
+        let v: Result<Vec<()>, int> = collect(functions.mut_iter().map(|f| (*f)()));
         assert_eq!(v, Err(1));
     }
 
index 50447f0c5b375cb1e7a5591780106186cbce1e82..0e6baaa518a73e8aa20b1ed51c915949a20ecf70 100644 (file)
@@ -13,8 +13,9 @@
 use clone::Clone;
 use container::Container;
 use default::Default;
+use finally::try_finally;
 use intrinsics;
-use iter::{Iterator, FromIterator};
+use iter::{range, Iterator, FromIterator};
 use mem;
 use num::{CheckedMul, CheckedAdd};
 use option::{Some, None};
@@ -25,7 +26,6 @@
 use str::StrSlice;
 
 #[cfg(not(test))] use ops::Add;
-#[cfg(not(test))] use slice::Vector;
 
 #[allow(ctypes)]
 extern {
@@ -147,56 +147,34 @@ fn add(&self, rhs: & &'a str) -> ~str {
 impl<A: Clone> Clone for ~[A] {
     #[inline]
     fn clone(&self) -> ~[A] {
-        self.iter().map(|a| a.clone()).collect()
-    }
-}
-
-impl<A> FromIterator<A> for ~[A] {
-    fn from_iter<T: Iterator<A>>(mut iterator: T) -> ~[A] {
-        let (lower, _) = iterator.size_hint();
-        let cap = if lower == 0 {16} else {lower};
-        let mut cap = cap.checked_mul(&mem::size_of::<A>()).unwrap();
-        let mut len = 0;
+        let len = self.len();
+        let data_size = len.checked_mul(&mem::size_of::<A>()).unwrap();
+        let size = mem::size_of::<Vec<()>>().checked_add(&data_size).unwrap();
 
         unsafe {
-            let mut ptr = alloc(cap) as *mut Vec<A>;
-            let mut ret = cast::transmute(ptr);
-            for elt in iterator {
-                if len * mem::size_of::<A>() >= cap {
-                    cap = cap.checked_mul(&2).unwrap();
-                    let ptr2 = alloc(cap) as *mut Vec<A>;
-                    ptr::copy_nonoverlapping_memory(&mut (*ptr2).data,
-                                                    &(*ptr).data,
-                                                    len);
-                    free(ptr as *u8);
-                    cast::forget(ret);
-                    ret = cast::transmute(ptr2);
-                    ptr = ptr2;
-                }
-
-                let base = &mut (*ptr).data as *mut A;
-                intrinsics::move_val_init(&mut *base.offset(len as int), elt);
-                len += 1;
-                (*ptr).fill = len * mem::nonzero_size_of::<A>();
-            }
-            ret
+            let ret = alloc(size) as *mut Vec<A>;
+
+            (*ret).fill = len * mem::nonzero_size_of::<A>();
+            (*ret).alloc = len * mem::nonzero_size_of::<A>();
+
+            let mut i = 0;
+            let p = &mut (*ret).data as *mut _ as *mut A;
+            try_finally(
+                &mut i, (),
+                |i, ()| while *i < len {
+                    mem::move_val_init(
+                        &mut(*p.offset(*i as int)),
+                        self.unsafe_ref(*i).clone());
+                    *i += 1;
+                },
+                |i| if *i < len {
+                    // we must be failing, clean up after ourselves
+                    for j in range(0, *i as int) {
+                        ptr::read(&*p.offset(j));
+                    }
+                    free(ret as *u8);
+                });
+            cast::transmute(ret)
         }
     }
 }
-
-#[cfg(not(test))]
-impl<'a,T:Clone, V: Vector<T>> Add<V, ~[T]> for &'a [T] {
-    #[inline]
-    fn add(&self, rhs: &V) -> ~[T] {
-        let first = self.iter().map(|t| t.clone());
-        first.chain(rhs.as_slice().iter().map(|t| t.clone())).collect()
-    }
-}
-
-#[cfg(not(test))]
-impl<T:Clone, V: Vector<T>> Add<V, ~[T]> for ~[T] {
-    #[inline]
-    fn add(&self, rhs: &V) -> ~[T] {
-        self.as_slice() + rhs.as_slice()
-    }
-}
index 9d9e12d0ad594c52629bc5e34bf3c9680ab201e9..689f59b471c90402c7ec9298d15d8bc697f8e58d 100644 (file)
@@ -621,12 +621,12 @@ fn size_hint(&self) -> (uint, Option<uint>) {
 ///          0x0073, 0xDD1E, 0x0069, 0x0063,
 ///          0xD834];
 ///
-/// assert_eq!(str::utf16_items(v).collect::<~[_]>(),
-///            ~[ScalarValue('𝄞'),
-///              ScalarValue('m'), ScalarValue('u'), ScalarValue('s'),
-///              LoneSurrogate(0xDD1E),
-///              ScalarValue('i'), ScalarValue('c'),
-///              LoneSurrogate(0xD834)]);
+/// assert_eq!(str::utf16_items(v).collect::<Vec<_>>(),
+///            vec![ScalarValue('𝄞'),
+///                 ScalarValue('m'), ScalarValue('u'), ScalarValue('s'),
+///                 LoneSurrogate(0xDD1E),
+///                 ScalarValue('i'), ScalarValue('c'),
+///                 LoneSurrogate(0xD834)]);
 /// ```
 pub fn utf16_items<'a>(v: &'a [u16]) -> UTF16Items<'a> {
     UTF16Items { iter : v.iter() }
@@ -896,8 +896,8 @@ pub trait StrSlice<'a> {
     /// # Example
     ///
     /// ```rust
-    /// let v: ~[char] = "abc åäö".chars().collect();
-    /// assert_eq!(v, ~['a', 'b', 'c', ' ', 'å', 'ä', 'ö']);
+    /// let v: Vec<char> = "abc åäö".chars().collect();
+    /// assert_eq!(v, vec!['a', 'b', 'c', ' ', 'å', 'ä', 'ö']);
     /// ```
     fn chars(&self) -> Chars<'a>;
 
@@ -925,14 +925,14 @@ pub trait StrSlice<'a> {
     /// # Example
     ///
     /// ```rust
-    /// let v: ~[&str] = "Mary had a little lamb".split(' ').collect();
-    /// assert_eq!(v, ~["Mary", "had", "a", "little", "lamb"]);
+    /// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
+    /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]);
     ///
-    /// let v: ~[&str] = "abc1def2ghi".split(|c: char| c.is_digit()).collect();
-    /// assert_eq!(v, ~["abc", "def", "ghi"]);
+    /// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_digit()).collect();
+    /// assert_eq!(v, vec!["abc", "def", "ghi"]);
     ///
-    /// let v: ~[&str] = "lionXXtigerXleopard".split('X').collect();
-    /// assert_eq!(v, ~["lion", "", "tiger", "leopard"]);
+    /// let v: Vec<&str> = "lionXXtigerXleopard".split('X').collect();
+    /// assert_eq!(v, vec!["lion", "", "tiger", "leopard"]);
     /// ```
     fn split<Sep: CharEq>(&self, sep: Sep) -> CharSplits<'a, Sep>;
 
@@ -943,14 +943,14 @@ pub trait StrSlice<'a> {
     /// # Example
     ///
     /// ```rust
-    /// let v: ~[&str] = "Mary had a little lambda".splitn(' ', 2).collect();
-    /// assert_eq!(v, ~["Mary", "had", "a little lambda"]);
+    /// let v: Vec<&str> = "Mary had a little lambda".splitn(' ', 2).collect();
+    /// assert_eq!(v, vec!["Mary", "had", "a little lambda"]);
     ///
-    /// let v: ~[&str] = "abc1def2ghi".splitn(|c: char| c.is_digit(), 1).collect();
-    /// assert_eq!(v, ~["abc", "def2ghi"]);
+    /// let v: Vec<&str> = "abc1def2ghi".splitn(|c: char| c.is_digit(), 1).collect();
+    /// assert_eq!(v, vec!["abc", "def2ghi"]);
     ///
-    /// let v: ~[&str] = "lionXXtigerXleopard".splitn('X', 2).collect();
-    /// assert_eq!(v, ~["lion", "", "tigerXleopard"]);
+    /// let v: Vec<&str> = "lionXXtigerXleopard".splitn('X', 2).collect();
+    /// assert_eq!(v, vec!["lion", "", "tigerXleopard"]);
     /// ```
     fn splitn<Sep: CharEq>(&self, sep: Sep, count: uint) -> CharSplitsN<'a, Sep>;
 
@@ -963,20 +963,20 @@ pub trait StrSlice<'a> {
     /// # Example
     ///
     /// ```rust
-    /// let v: ~[&str] = "A.B.".split_terminator('.').collect();
-    /// assert_eq!(v, ~["A", "B"]);
+    /// let v: Vec<&str> = "A.B.".split_terminator('.').collect();
+    /// assert_eq!(v, vec!["A", "B"]);
     ///
-    /// let v: ~[&str] = "A..B..".split_terminator('.').collect();
-    /// assert_eq!(v, ~["A", "", "B", ""]);
+    /// let v: Vec<&str> = "A..B..".split_terminator('.').collect();
+    /// assert_eq!(v, vec!["A", "", "B", ""]);
     ///
-    /// let v: ~[&str] = "Mary had a little lamb".split(' ').rev().collect();
-    /// assert_eq!(v, ~["lamb", "little", "a", "had", "Mary"]);
+    /// let v: Vec<&str> = "Mary had a little lamb".split(' ').rev().collect();
+    /// assert_eq!(v, vec!["lamb", "little", "a", "had", "Mary"]);
     ///
-    /// let v: ~[&str] = "abc1def2ghi".split(|c: char| c.is_digit()).rev().collect();
-    /// assert_eq!(v, ~["ghi", "def", "abc"]);
+    /// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_digit()).rev().collect();
+    /// assert_eq!(v, vec!["ghi", "def", "abc"]);
     ///
-    /// let v: ~[&str] = "lionXXtigerXleopard".split('X').rev().collect();
-    /// assert_eq!(v, ~["leopard", "tiger", "", "lion"]);
+    /// let v: Vec<&str> = "lionXXtigerXleopard".split('X').rev().collect();
+    /// assert_eq!(v, vec!["leopard", "tiger", "", "lion"]);
     /// ```
     fn split_terminator<Sep: CharEq>(&self, sep: Sep) -> CharSplits<'a, Sep>;
 
@@ -991,14 +991,14 @@ pub trait StrSlice<'a> {
     /// # Example
     ///
     /// ```rust
-    /// let v: ~[&str] = "Mary had a little lamb".rsplitn(' ', 2).collect();
-    /// assert_eq!(v, ~["lamb", "little", "Mary had a"]);
+    /// let v: Vec<&str> = "Mary had a little lamb".rsplitn(' ', 2).collect();
+    /// assert_eq!(v, vec!["lamb", "little", "Mary had a"]);
     ///
-    /// let v: ~[&str] = "abc1def2ghi".rsplitn(|c: char| c.is_digit(), 1).collect();
-    /// assert_eq!(v, ~["ghi", "abc1def"]);
+    /// let v: Vec<&str> = "abc1def2ghi".rsplitn(|c: char| c.is_digit(), 1).collect();
+    /// assert_eq!(v, vec!["ghi", "abc1def"]);
     ///
-    /// let v: ~[&str] = "lionXXtigerXleopard".rsplitn('X', 2).collect();
-    /// assert_eq!(v, ~["leopard", "tiger", "lionX"]);
+    /// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn('X', 2).collect();
+    /// assert_eq!(v, vec!["leopard", "tiger", "lionX"]);
     /// ```
     fn rsplitn<Sep: CharEq>(&self, sep: Sep, count: uint) -> CharSplitsN<'a, Sep>;
 
@@ -1013,14 +1013,14 @@ pub trait StrSlice<'a> {
     /// # Example
     ///
     /// ```rust
-    /// let v: ~[(uint, uint)] = "abcXXXabcYYYabc".match_indices("abc").collect();
-    /// assert_eq!(v, ~[(0,3), (6,9), (12,15)]);
+    /// let v: Vec<(uint, uint)> = "abcXXXabcYYYabc".match_indices("abc").collect();
+    /// assert_eq!(v, vec![(0,3), (6,9), (12,15)]);
     ///
-    /// let v: ~[(uint, uint)] = "1abcabc2".match_indices("abc").collect();
-    /// assert_eq!(v, ~[(1,4), (4,7)]);
+    /// let v: Vec<(uint, uint)> = "1abcabc2".match_indices("abc").collect();
+    /// assert_eq!(v, vec![(1,4), (4,7)]);
     ///
-    /// let v: ~[(uint, uint)] = "ababa".match_indices("aba").collect();
-    /// assert_eq!(v, ~[(0, 3)]); // only the first `aba`
+    /// let v: Vec<(uint, uint)> = "ababa".match_indices("aba").collect();
+    /// assert_eq!(v, vec![(0, 3)]); // only the first `aba`
     /// ```
     fn match_indices(&self, sep: &'a str) -> MatchIndices<'a>;
 
@@ -1029,11 +1029,11 @@ pub trait StrSlice<'a> {
     /// # Example
     ///
     /// ```rust
-    /// let v: ~[&str] = "abcXXXabcYYYabc".split_str("abc").collect();
-    /// assert_eq!(v, ~["", "XXX", "YYY", ""]);
+    /// let v: Vec<&str> = "abcXXXabcYYYabc".split_str("abc").collect();
+    /// assert_eq!(v, vec!["", "XXX", "YYY", ""]);
     ///
-    /// let v: ~[&str] = "1abcabc2".split_str("abc").collect();
-    /// assert_eq!(v, ~["1", "", "2"]);
+    /// let v: Vec<&str> = "1abcabc2".split_str("abc").collect();
+    /// assert_eq!(v, vec!["1", "", "2"]);
     /// ```
     fn split_str(&self, &'a str) -> StrSplits<'a>;
 
@@ -1045,8 +1045,8 @@ pub trait StrSlice<'a> {
     ///
     /// ```rust
     /// let four_lines = "foo\nbar\n\nbaz\n";
-    /// let v: ~[&str] = four_lines.lines().collect();
-    /// assert_eq!(v, ~["foo", "bar", "", "baz"]);
+    /// let v: Vec<&str> = four_lines.lines().collect();
+    /// assert_eq!(v, vec!["foo", "bar", "", "baz"]);
     /// ```
     fn lines(&self) -> CharSplits<'a, char>;
 
@@ -1058,8 +1058,8 @@ pub trait StrSlice<'a> {
     ///
     /// ```rust
     /// let four_lines = "foo\r\nbar\n\r\nbaz\n";
-    /// let v: ~[&str] = four_lines.lines_any().collect();
-    /// assert_eq!(v, ~["foo", "bar", "", "baz"]);
+    /// let v: Vec<&str> = four_lines.lines_any().collect();
+    /// assert_eq!(v, vec!["foo", "bar", "", "baz"]);
     /// ```
     fn lines_any(&self) -> AnyLines<'a>;
 
@@ -1071,8 +1071,8 @@ pub trait StrSlice<'a> {
     ///
     /// ```rust
     /// let some_words = " Mary   had\ta little  \n\t lamb";
-    /// let v: ~[&str] = some_words.words().collect();
-    /// assert_eq!(v, ~["Mary", "had", "a", "little", "lamb"]);
+    /// let v: Vec<&str> = some_words.words().collect();
+    /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]);
     /// ```
     fn words(&self) -> Words<'a>;
 
@@ -1469,7 +1469,8 @@ pub trait StrSlice<'a> {
     ///
     /// ```rust
     /// let string = "a\nb\nc";
-    /// let lines: ~[&str] = string.lines().collect();
+    /// let lines: Vec<&str> = string.lines().collect();
+    /// let lines = lines.as_slice();
     ///
     /// assert!(string.subslice_offset(lines[0]) == 0); // &"a"
     /// assert!(string.subslice_offset(lines[1]) == 2); // &"b"
diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs
new file mode 100644 (file)
index 0000000..91b3fef
--- /dev/null
@@ -0,0 +1,989 @@
+// 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.
+
+//! Macro support for format strings
+//!
+//! These structures are used when parsing format strings for the compiler.
+//! Parsing does not happen at runtime: structures of `std::fmt::rt` are
+//! generated instead.
+
+#![crate_id = "fmt_macros#0.11-pre"]
+#![license = "MIT/ASL2"]
+#![crate_type = "rlib"]
+#![crate_type = "dylib"]
+#![feature(macro_rules, globs)]
+#![experimental]
+
+use std::char;
+use std::str;
+
+/// A piece is a portion of the format string which represents the next part
+/// to emit. These are emitted as a stream by the `Parser` class.
+#[deriving(Eq)]
+pub enum Piece<'a> {
+    /// A literal string which should directly be emitted
+    String(&'a str),
+    /// A back-reference to whatever the current argument is. This is used
+    /// inside of a method call to refer back to the original argument.
+    CurrentArgument,
+    /// This describes that formatting should process the next argument (as
+    /// specified inside) for emission.
+    Argument(Argument<'a>),
+}
+
+/// Representation of an argument specification.
+#[deriving(Eq)]
+pub struct Argument<'a> {
+    /// Where to find this argument
+    pub position: Position<'a>,
+    /// How to format the argument
+    pub format: FormatSpec<'a>,
+    /// If not `None`, what method to invoke on the argument
+    pub method: Option<Box<Method<'a>>>
+}
+
+/// Specification for the formatting of an argument in the format string.
+#[deriving(Eq)]
+pub struct FormatSpec<'a> {
+    /// Optionally specified character to fill alignment with
+    pub fill: Option<char>,
+    /// Optionally specified alignment
+    pub align: Alignment,
+    /// Packed version of various flags provided
+    pub flags: uint,
+    /// The integer precision to use
+    pub precision: Count<'a>,
+    /// The string width requested for the resulting format
+    pub width: Count<'a>,
+    /// The descriptor string representing the name of the format desired for
+    /// this argument, this can be empty or any number of characters, although
+    /// it is required to be one word.
+    pub ty: &'a str
+}
+
+/// Enum describing where an argument for a format can be located.
+#[deriving(Eq)]
+pub enum Position<'a> {
+    /// The argument will be in the next position. This is the default.
+    ArgumentNext,
+    /// The argument is located at a specific index.
+    ArgumentIs(uint),
+    /// The argument has a name.
+    ArgumentNamed(&'a str),
+}
+
+/// Enum of alignments which are supported.
+#[deriving(Eq)]
+pub enum Alignment {
+    /// The value will be aligned to the left.
+    AlignLeft,
+    /// The value will be aligned to the right.
+    AlignRight,
+    /// The value will take on a default alignment.
+    AlignUnknown,
+}
+
+/// Various flags which can be applied to format strings. The meaning of these
+/// flags is defined by the formatters themselves.
+#[deriving(Eq)]
+pub enum Flag {
+    /// A `+` will be used to denote positive numbers.
+    FlagSignPlus,
+    /// A `-` will be used to denote negative numbers. This is the default.
+    FlagSignMinus,
+    /// An alternate form will be used for the value. In the case of numbers,
+    /// this means that the number will be prefixed with the supplied string.
+    FlagAlternate,
+    /// For numbers, this means that the number will be padded with zeroes,
+    /// and the sign (`+` or `-`) will precede them.
+    FlagSignAwareZeroPad,
+}
+
+/// A count is used for the precision and width parameters of an integer, and
+/// can reference either an argument or a literal integer.
+#[deriving(Eq)]
+pub enum Count<'a> {
+    /// The count is specified explicitly.
+    CountIs(uint),
+    /// The count is specified by the argument with the given name.
+    CountIsName(&'a str),
+    /// The count is specified by the argument at the given index.
+    CountIsParam(uint),
+    /// The count is specified by the next parameter.
+    CountIsNextParam,
+    /// The count is implied and cannot be explicitly specified.
+    CountImplied,
+}
+
+/// Enum describing all of the possible methods which the formatting language
+/// currently supports.
+#[deriving(Eq)]
+pub enum Method<'a> {
+    /// A plural method selects on an integer over a list of either integer or
+    /// keyword-defined clauses. The meaning of the keywords is defined by the
+    /// current locale.
+    ///
+    /// An offset is optionally present at the beginning which is used to
+    /// match against keywords, but it is not matched against the literal
+    /// integers.
+    ///
+    /// The final element of this enum is the default "other" case which is
+    /// always required to be specified.
+    Plural(Option<uint>, Vec<PluralArm<'a>>, Vec<Piece<'a>>),
+
+    /// A select method selects over a string. Each arm is a different string
+    /// which can be selected for.
+    ///
+    /// As with `Plural`, a default "other" case is required as well.
+    Select(Vec<SelectArm<'a>>, Vec<Piece<'a>>),
+}
+
+/// A selector for what pluralization a plural method should take
+#[deriving(Eq, TotalEq, Hash)]
+pub enum PluralSelector {
+    /// One of the plural keywords should be used
+    Keyword(PluralKeyword),
+    /// A literal pluralization should be used
+    Literal(uint),
+}
+
+/// Structure representing one "arm" of the `plural` function.
+#[deriving(Eq)]
+pub struct PluralArm<'a> {
+    /// A selector can either be specified by a keyword or with an integer
+    /// literal.
+    pub selector: PluralSelector,
+    /// Array of pieces which are the format of this arm
+    pub result: Vec<Piece<'a>>,
+}
+
+/// Enum of the 5 CLDR plural keywords. There is one more, "other", but that
+/// is specially placed in the `Plural` variant of `Method`.
+///
+/// http://www.icu-project.org/apiref/icu4c/classicu_1_1PluralRules.html
+#[deriving(Eq, TotalEq, Hash, Show)]
+#[allow(missing_doc)]
+pub enum PluralKeyword {
+    /// The plural form for zero objects.
+    Zero,
+    /// The plural form for one object.
+    One,
+    /// The plural form for two objects.
+    Two,
+    /// The plural form for few objects.
+    Few,
+    /// The plural form for many objects.
+    Many,
+}
+
+/// Structure representing one "arm" of the `select` function.
+#[deriving(Eq)]
+pub struct SelectArm<'a> {
+    /// String selector which guards this arm
+    pub selector: &'a str,
+    /// Array of pieces which are the format of this arm
+    pub result: Vec<Piece<'a>>,
+}
+
+/// The parser structure for interpreting the input format string. This is
+/// modelled as an iterator over `Piece` structures to form a stream of tokens
+/// being output.
+///
+/// This is a recursive-descent parser for the sake of simplicity, and if
+/// necessary there's probably lots of room for improvement performance-wise.
+pub struct Parser<'a> {
+    input: &'a str,
+    cur: str::CharOffsets<'a>,
+    depth: uint,
+    /// Error messages accumulated during parsing
+    pub errors: Vec<~str>,
+}
+
+impl<'a> Iterator<Piece<'a>> for Parser<'a> {
+    fn next(&mut self) -> Option<Piece<'a>> {
+        match self.cur.clone().next() {
+            Some((_, '#')) => { self.cur.next(); Some(CurrentArgument) }
+            Some((_, '{')) => {
+                self.cur.next();
+                let ret = Some(Argument(self.argument()));
+                self.must_consume('}');
+                ret
+            }
+            Some((pos, '\\')) => {
+                self.cur.next();
+                self.escape(); // ensure it's a valid escape sequence
+                Some(String(self.string(pos + 1))) // skip the '\' character
+            }
+            Some((_, '}')) if self.depth == 0 => {
+                self.cur.next();
+                self.err("unmatched `}` found");
+                None
+            }
+            Some((_, '}')) | None => { None }
+            Some((pos, _)) => {
+                Some(String(self.string(pos)))
+            }
+        }
+    }
+}
+
+impl<'a> Parser<'a> {
+    /// Creates a new parser for the given format string
+    pub fn new<'a>(s: &'a str) -> Parser<'a> {
+        Parser {
+            input: s,
+            cur: s.char_indices(),
+            depth: 0,
+            errors: vec!(),
+        }
+    }
+
+    /// Notifies of an error. The message doesn't actually need to be of type
+    /// ~str, but I think it does when this eventually uses conditions so it
+    /// might as well start using it now.
+    fn err(&mut self, msg: &str) {
+        self.errors.push(msg.to_owned());
+    }
+
+    /// Optionally consumes the specified character. If the character is not at
+    /// the current position, then the current iterator isn't moved and false is
+    /// returned, otherwise the character is consumed and true is returned.
+    fn consume(&mut self, c: char) -> bool {
+        match self.cur.clone().next() {
+            Some((_, maybe)) if c == maybe => {
+                self.cur.next();
+                true
+            }
+            Some(..) | None => false,
+        }
+    }
+
+    /// Forces consumption of the specified character. If the character is not
+    /// found, an error is emitted.
+    fn must_consume(&mut self, c: char) {
+        self.ws();
+        match self.cur.clone().next() {
+            Some((_, maybe)) if c == maybe => {
+                self.cur.next();
+            }
+            Some((_, other)) => {
+                self.err(
+                    format!("expected `{}` but found `{}`", c, other));
+            }
+            None => {
+                self.err(
+                    format!("expected `{}` but string was terminated", c));
+            }
+        }
+    }
+
+    /// Attempts to consume any amount of whitespace followed by a character
+    fn wsconsume(&mut self, c: char) -> bool {
+        self.ws(); self.consume(c)
+    }
+
+    /// Consumes all whitespace characters until the first non-whitespace
+    /// character
+    fn ws(&mut self) {
+        loop {
+            match self.cur.clone().next() {
+                Some((_, c)) if char::is_whitespace(c) => { self.cur.next(); }
+                Some(..) | None => { return }
+            }
+        }
+    }
+
+    /// Consumes an escape sequence, failing if there is not a valid character
+    /// to be escaped.
+    fn escape(&mut self) -> char {
+        match self.cur.next() {
+            Some((_, c @ '#')) | Some((_, c @ '{')) |
+            Some((_, c @ '\\')) | Some((_, c @ '}')) => { c }
+            Some((_, c)) => {
+                self.err(format!("invalid escape character `{}`", c));
+                c
+            }
+            None => {
+                self.err("expected an escape sequence, but format string was \
+                           terminated");
+                ' '
+            }
+        }
+    }
+
+    /// Parses all of a string which is to be considered a "raw literal" in a
+    /// format string. This is everything outside of the braces.
+    fn string(&mut self, start: uint) -> &'a str {
+        loop {
+            // we may not consume the character, so clone the iterator
+            match self.cur.clone().next() {
+                Some((pos, '\\')) | Some((pos, '#')) |
+                Some((pos, '}')) | Some((pos, '{')) => {
+                    return self.input.slice(start, pos);
+                }
+                Some(..) => { self.cur.next(); }
+                None => {
+                    self.cur.next();
+                    return self.input.slice(start, self.input.len());
+                }
+            }
+        }
+    }
+
+    /// Parses an Argument structure, or what's contained within braces inside
+    /// the format string
+    fn argument(&mut self) -> Argument<'a> {
+        Argument {
+            position: self.position(),
+            format: self.format(),
+            method: self.method(),
+        }
+    }
+
+    /// Parses a positional argument for a format. This could either be an
+    /// integer index of an argument, a named argument, or a blank string.
+    fn position(&mut self) -> Position<'a> {
+        match self.integer() {
+            Some(i) => { ArgumentIs(i) }
+            None => {
+                match self.cur.clone().next() {
+                    Some((_, c)) if char::is_alphabetic(c) => {
+                        ArgumentNamed(self.word())
+                    }
+                    _ => ArgumentNext
+                }
+            }
+        }
+    }
+
+    /// Parses a format specifier at the current position, returning all of the
+    /// relevant information in the FormatSpec struct.
+    fn format(&mut self) -> FormatSpec<'a> {
+        let mut spec = FormatSpec {
+            fill: None,
+            align: AlignUnknown,
+            flags: 0,
+            precision: CountImplied,
+            width: CountImplied,
+            ty: self.input.slice(0, 0),
+        };
+        if !self.consume(':') { return spec }
+
+        // fill character
+        match self.cur.clone().next() {
+            Some((_, c)) => {
+                match self.cur.clone().skip(1).next() {
+                    Some((_, '>')) | Some((_, '<')) => {
+                        spec.fill = Some(c);
+                        self.cur.next();
+                    }
+                    Some(..) | None => {}
+                }
+            }
+            None => {}
+        }
+        // Alignment
+        if self.consume('<') {
+            spec.align = AlignLeft;
+        } else if self.consume('>') {
+            spec.align = AlignRight;
+        }
+        // Sign flags
+        if self.consume('+') {
+            spec.flags |= 1 << (FlagSignPlus as uint);
+        } else if self.consume('-') {
+            spec.flags |= 1 << (FlagSignMinus as uint);
+        }
+        // Alternate marker
+        if self.consume('#') {
+            spec.flags |= 1 << (FlagAlternate as uint);
+        }
+        // Width and precision
+        let mut havewidth = false;
+        if self.consume('0') {
+            // small ambiguity with '0$' as a format string. In theory this is a
+            // '0' flag and then an ill-formatted format string with just a '$'
+            // and no count, but this is better if we instead interpret this as
+            // no '0' flag and '0$' as the width instead.
+            if self.consume('$') {
+                spec.width = CountIsParam(0);
+                havewidth = true;
+            } else {
+                spec.flags |= 1 << (FlagSignAwareZeroPad as uint);
+            }
+        }
+        if !havewidth {
+            spec.width = self.count();
+        }
+        if self.consume('.') {
+            if self.consume('*') {
+                spec.precision = CountIsNextParam;
+            } else {
+                spec.precision = self.count();
+            }
+        }
+        // Finally the actual format specifier
+        if self.consume('?') {
+            spec.ty = "?";
+        } else {
+            spec.ty = self.word();
+        }
+        return spec;
+    }
+
+    /// Parses a method to be applied to the previously specified argument and
+    /// its format. The two current supported methods are 'plural' and 'select'
+    fn method(&mut self) -> Option<Box<Method<'a>>> {
+        if !self.wsconsume(',') {
+            return None;
+        }
+        self.ws();
+        match self.word() {
+            "select" => {
+                self.must_consume(',');
+                Some(self.select())
+            }
+            "plural" => {
+                self.must_consume(',');
+                Some(self.plural())
+            }
+            "" => {
+                self.err("expected method after comma");
+                return None;
+            }
+            method => {
+                self.err(format!("unknown method: `{}`", method));
+                return None;
+            }
+        }
+    }
+
+    /// Parses a 'select' statement (after the initial 'select' word)
+    fn select(&mut self) -> Box<Method<'a>> {
+        let mut other = None;
+        let mut arms = vec!();
+        // Consume arms one at a time
+        loop {
+            self.ws();
+            let selector = self.word();
+            if selector == "" {
+                self.err("cannot have an empty selector");
+                break
+            }
+            self.must_consume('{');
+            self.depth += 1;
+            let pieces = self.collect();
+            self.depth -= 1;
+            self.must_consume('}');
+            if selector == "other" {
+                if !other.is_none() {
+                    self.err("multiple `other` statements in `select");
+                }
+                other = Some(pieces);
+            } else {
+                arms.push(SelectArm { selector: selector, result: pieces });
+            }
+            self.ws();
+            match self.cur.clone().next() {
+                Some((_, '}')) => { break }
+                Some(..) | None => {}
+            }
+        }
+        // The "other" selector must be present
+        let other = match other {
+            Some(arm) => { arm }
+            None => {
+                self.err("`select` statement must provide an `other` case");
+                vec!()
+            }
+        };
+        box Select(arms, other)
+    }
+
+    /// Parses a 'plural' statement (after the initial 'plural' word)
+    fn plural(&mut self) -> Box<Method<'a>> {
+        let mut offset = None;
+        let mut other = None;
+        let mut arms = vec!();
+
+        // First, attempt to parse the 'offset:' field. We know the set of
+        // selector words which can appear in plural arms, and the only ones
+        // which start with 'o' are "other" and "offset", hence look two
+        // characters deep to see if we can consume the word "offset"
+        self.ws();
+        let mut it = self.cur.clone();
+        match it.next() {
+            Some((_, 'o')) => {
+                match it.next() {
+                    Some((_, 'f')) => {
+                        let word = self.word();
+                        if word != "offset" {
+                            self.err(format!("expected `offset`, found `{}`",
+                                             word));
+                        } else {
+                            self.must_consume(':');
+                            match self.integer() {
+                                Some(i) => { offset = Some(i); }
+                                None => {
+                                    self.err("offset must be an integer");
+                                }
+                            }
+                        }
+                    }
+                    Some(..) | None => {}
+                }
+            }
+            Some(..) | None => {}
+        }
+
+        // Next, generate all the arms
+        loop {
+            let mut isother = false;
+            let selector = if self.wsconsume('=') {
+                match self.integer() {
+                    Some(i) => Literal(i),
+                    None => {
+                        self.err("plural `=` selectors must be followed by an \
+                                  integer");
+                        Literal(0)
+                    }
+                }
+            } else {
+                let word = self.word();
+                match word {
+                    "other" => { isother = true; Keyword(Zero) }
+                    "zero"  => Keyword(Zero),
+                    "one"   => Keyword(One),
+                    "two"   => Keyword(Two),
+                    "few"   => Keyword(Few),
+                    "many"  => Keyword(Many),
+                    word    => {
+                        self.err(format!("unexpected plural selector `{}`",
+                                         word));
+                        if word == "" {
+                            break
+                        } else {
+                            Keyword(Zero)
+                        }
+                    }
+                }
+            };
+            self.must_consume('{');
+            self.depth += 1;
+            let pieces = self.collect();
+            self.depth -= 1;
+            self.must_consume('}');
+            if isother {
+                if !other.is_none() {
+                    self.err("multiple `other` statements in `select");
+                }
+                other = Some(pieces);
+            } else {
+                arms.push(PluralArm { selector: selector, result: pieces });
+            }
+            self.ws();
+            match self.cur.clone().next() {
+                Some((_, '}')) => { break }
+                Some(..) | None => {}
+            }
+        }
+
+        let other = match other {
+            Some(arm) => { arm }
+            None => {
+                self.err("`plural` statement must provide an `other` case");
+                vec!()
+            }
+        };
+        box Plural(offset, arms, other)
+    }
+
+    /// Parses a Count parameter at the current position. This does not check
+    /// for 'CountIsNextParam' because that is only used in precision, not
+    /// width.
+    fn count(&mut self) -> Count<'a> {
+        match self.integer() {
+            Some(i) => {
+                if self.consume('$') {
+                    CountIsParam(i)
+                } else {
+                    CountIs(i)
+                }
+            }
+            None => {
+                let tmp = self.cur.clone();
+                match self.word() {
+                    word if word.len() > 0 && self.consume('$') => {
+                        CountIsName(word)
+                    }
+                    _ => {
+                        self.cur = tmp;
+                        CountImplied
+                    }
+                }
+            }
+        }
+    }
+
+    /// Parses a word starting at the current position. A word is considered to
+    /// be an alphabetic character followed by any number of alphanumeric
+    /// characters.
+    fn word(&mut self) -> &'a str {
+        let start = match self.cur.clone().next() {
+            Some((pos, c)) if char::is_XID_start(c) => {
+                self.cur.next();
+                pos
+            }
+            Some(..) | None => { return self.input.slice(0, 0); }
+        };
+        let mut end;
+        loop {
+            match self.cur.clone().next() {
+                Some((_, c)) if char::is_XID_continue(c) => {
+                    self.cur.next();
+                }
+                Some((pos, _)) => { end = pos; break }
+                None => { end = self.input.len(); break }
+            }
+        }
+        self.input.slice(start, end)
+    }
+
+    /// Optionally parses an integer at the current position. This doesn't deal
+    /// with overflow at all, it's just accumulating digits.
+    fn integer(&mut self) -> Option<uint> {
+        let mut cur = 0;
+        let mut found = false;
+        loop {
+            match self.cur.clone().next() {
+                Some((_, c)) => {
+                    match char::to_digit(c, 10) {
+                        Some(i) => {
+                            cur = cur * 10 + i;
+                            found = true;
+                            self.cur.next();
+                        }
+                        None => { break }
+                    }
+                }
+                None => { break }
+            }
+        }
+        if found {
+            return Some(cur);
+        } else {
+            return None;
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    fn same(fmt: &'static str, p: &[Piece<'static>]) {
+        let mut parser = Parser::new(fmt);
+        assert!(p == parser.collect::<Vec<Piece<'static>>>().as_slice());
+    }
+
+    fn fmtdflt() -> FormatSpec<'static> {
+        return FormatSpec {
+            fill: None,
+            align: AlignUnknown,
+            flags: 0,
+            precision: CountImplied,
+            width: CountImplied,
+            ty: "",
+        }
+    }
+
+    fn musterr(s: &str) {
+        let mut p = Parser::new(s);
+        p.next();
+        assert!(p.errors.len() != 0);
+    }
+
+    #[test]
+    fn simple() {
+        same("asdf", [String("asdf")]);
+        same("a\\{b", [String("a"), String("{b")]);
+        same("a\\#b", [String("a"), String("#b")]);
+        same("a\\}b", [String("a"), String("}b")]);
+        same("a\\}", [String("a"), String("}")]);
+        same("\\}", [String("}")]);
+    }
+
+    #[test] fn invalid01() { musterr("{") }
+    #[test] fn invalid02() { musterr("\\") }
+    #[test] fn invalid03() { musterr("\\a") }
+    #[test] fn invalid04() { musterr("{3a}") }
+    #[test] fn invalid05() { musterr("{:|}") }
+    #[test] fn invalid06() { musterr("{:>>>}") }
+
+    #[test]
+    fn format_nothing() {
+        same("{}", [Argument(Argument {
+            position: ArgumentNext,
+            format: fmtdflt(),
+            method: None,
+        })]);
+    }
+    #[test]
+    fn format_position() {
+        same("{3}", [Argument(Argument {
+            position: ArgumentIs(3),
+            format: fmtdflt(),
+            method: None,
+        })]);
+    }
+    #[test]
+    fn format_position_nothing_else() {
+        same("{3:}", [Argument(Argument {
+            position: ArgumentIs(3),
+            format: fmtdflt(),
+            method: None,
+        })]);
+    }
+    #[test]
+    fn format_type() {
+        same("{3:a}", [Argument(Argument {
+            position: ArgumentIs(3),
+            format: FormatSpec {
+                fill: None,
+                align: AlignUnknown,
+                flags: 0,
+                precision: CountImplied,
+                width: CountImplied,
+                ty: "a",
+            },
+            method: None,
+        })]);
+    }
+    #[test]
+    fn format_align_fill() {
+        same("{3:>}", [Argument(Argument {
+            position: ArgumentIs(3),
+            format: FormatSpec {
+                fill: None,
+                align: AlignRight,
+                flags: 0,
+                precision: CountImplied,
+                width: CountImplied,
+                ty: "",
+            },
+            method: None,
+        })]);
+        same("{3:0<}", [Argument(Argument {
+            position: ArgumentIs(3),
+            format: FormatSpec {
+                fill: Some('0'),
+                align: AlignLeft,
+                flags: 0,
+                precision: CountImplied,
+                width: CountImplied,
+                ty: "",
+            },
+            method: None,
+        })]);
+        same("{3:*<abcd}", [Argument(Argument {
+            position: ArgumentIs(3),
+            format: FormatSpec {
+                fill: Some('*'),
+                align: AlignLeft,
+                flags: 0,
+                precision: CountImplied,
+                width: CountImplied,
+                ty: "abcd",
+            },
+            method: None,
+        })]);
+    }
+    #[test]
+    fn format_counts() {
+        same("{:10s}", [Argument(Argument {
+            position: ArgumentNext,
+            format: FormatSpec {
+                fill: None,
+                align: AlignUnknown,
+                flags: 0,
+                precision: CountImplied,
+                width: CountIs(10),
+                ty: "s",
+            },
+            method: None,
+        })]);
+        same("{:10$.10s}", [Argument(Argument {
+            position: ArgumentNext,
+            format: FormatSpec {
+                fill: None,
+                align: AlignUnknown,
+                flags: 0,
+                precision: CountIs(10),
+                width: CountIsParam(10),
+                ty: "s",
+            },
+            method: None,
+        })]);
+        same("{:.*s}", [Argument(Argument {
+            position: ArgumentNext,
+            format: FormatSpec {
+                fill: None,
+                align: AlignUnknown,
+                flags: 0,
+                precision: CountIsNextParam,
+                width: CountImplied,
+                ty: "s",
+            },
+            method: None,
+        })]);
+        same("{:.10$s}", [Argument(Argument {
+            position: ArgumentNext,
+            format: FormatSpec {
+                fill: None,
+                align: AlignUnknown,
+                flags: 0,
+                precision: CountIsParam(10),
+                width: CountImplied,
+                ty: "s",
+            },
+            method: None,
+        })]);
+        same("{:a$.b$s}", [Argument(Argument {
+            position: ArgumentNext,
+            format: FormatSpec {
+                fill: None,
+                align: AlignUnknown,
+                flags: 0,
+                precision: CountIsName("b"),
+                width: CountIsName("a"),
+                ty: "s",
+            },
+            method: None,
+        })]);
+    }
+    #[test]
+    fn format_flags() {
+        same("{:-}", [Argument(Argument {
+            position: ArgumentNext,
+            format: FormatSpec {
+                fill: None,
+                align: AlignUnknown,
+                flags: (1 << FlagSignMinus as uint),
+                precision: CountImplied,
+                width: CountImplied,
+                ty: "",
+            },
+            method: None,
+        })]);
+        same("{:+#}", [Argument(Argument {
+            position: ArgumentNext,
+            format: FormatSpec {
+                fill: None,
+                align: AlignUnknown,
+                flags: (1 << FlagSignPlus as uint) | (1 << FlagAlternate as uint),
+                precision: CountImplied,
+                width: CountImplied,
+                ty: "",
+            },
+            method: None,
+        })]);
+    }
+    #[test]
+    fn format_mixture() {
+        same("abcd {3:a} efg", [String("abcd "), Argument(Argument {
+            position: ArgumentIs(3),
+            format: FormatSpec {
+                fill: None,
+                align: AlignUnknown,
+                flags: 0,
+                precision: CountImplied,
+                width: CountImplied,
+                ty: "a",
+            },
+            method: None,
+        }), String(" efg")]);
+    }
+
+    #[test]
+    fn select_simple() {
+        same("{, select, other { haha } }", [Argument(Argument{
+            position: ArgumentNext,
+            format: fmtdflt(),
+            method: Some(box Select(vec![], vec![String(" haha ")]))
+        })]);
+        same("{1, select, other { haha } }", [Argument(Argument{
+            position: ArgumentIs(1),
+            format: fmtdflt(),
+            method: Some(box Select(vec![], vec![String(" haha ")]))
+        })]);
+        same("{1, select, other {#} }", [Argument(Argument{
+            position: ArgumentIs(1),
+            format: fmtdflt(),
+            method: Some(box Select(vec![], vec![CurrentArgument]))
+        })]);
+        same("{1, select, other {{2, select, other {lol}}} }", [Argument(Argument{
+            position: ArgumentIs(1),
+            format: fmtdflt(),
+            method: Some(box Select(vec![], vec![Argument(Argument{
+                position: ArgumentIs(2),
+                format: fmtdflt(),
+                method: Some(box Select(vec![], vec![String("lol")]))
+            })])) // wat
+        })]);
+    }
+
+    #[test]
+    fn select_cases() {
+        same("{1, select, a{1} b{2} c{3} other{4} }", [Argument(Argument{
+            position: ArgumentIs(1),
+            format: fmtdflt(),
+            method: Some(box Select(vec![
+                SelectArm{ selector: "a", result: vec![String("1")] },
+                SelectArm{ selector: "b", result: vec![String("2")] },
+                SelectArm{ selector: "c", result: vec![String("3")] },
+            ], vec![String("4")]))
+        })]);
+    }
+
+    #[test] fn badselect01() { musterr("{select, }") }
+    #[test] fn badselect02() { musterr("{1, select}") }
+    #[test] fn badselect03() { musterr("{1, select, }") }
+    #[test] fn badselect04() { musterr("{1, select, a {}}") }
+    #[test] fn badselect05() { musterr("{1, select, other }}") }
+    #[test] fn badselect06() { musterr("{1, select, other {}") }
+    #[test] fn badselect07() { musterr("{select, other {}") }
+    #[test] fn badselect08() { musterr("{1 select, other {}") }
+    #[test] fn badselect09() { musterr("{:d select, other {}") }
+    #[test] fn badselect10() { musterr("{1:d select, other {}") }
+
+    #[test]
+    fn plural_simple() {
+        same("{, plural, other { haha } }", [Argument(Argument{
+            position: ArgumentNext,
+            format: fmtdflt(),
+            method: Some(box Plural(None, vec![], vec![String(" haha ")]))
+        })]);
+        same("{:, plural, other { haha } }", [Argument(Argument{
+            position: ArgumentNext,
+            format: fmtdflt(),
+            method: Some(box Plural(None, vec![], vec![String(" haha ")]))
+        })]);
+        same("{, plural, offset:1 =2{2} =3{3} many{yes} other{haha} }",
+        [Argument(Argument{
+            position: ArgumentNext,
+            format: fmtdflt(),
+            method: Some(box Plural(Some(1), vec![
+                PluralArm{ selector: Literal(2), result: vec![String("2")] },
+                PluralArm{ selector: Literal(3), result: vec![String("3")] },
+                PluralArm{ selector: Keyword(Many), result: vec![String("yes")] }
+            ], vec![String("haha")]))
+        })]);
+    }
+}
index 78c2b6c99e955000a83673924d01aeab9ce7ae7c..3de1dde240c9722ae81f48d72997bda6f29cffe6 100644 (file)
@@ -51,7 +51,7 @@
 //! fn main() {
 //!     let args = os::args();
 //!
-//!     let program = args[0].clone();
+//!     let program = args.get(0).clone();
 //!
 //!     let opts = [
 //!         optopt("o", "", "set output file name", "NAME"),
index afe29ea2e070db19f8561807be706bccba63d989..f2d4d84f601f5142889c6254d097a6d6e8c007ce 100644 (file)
 type Ed = (int,int);
 struct Edges(Vec<Ed>);
 
-pub fn main() {
-    use std::io::File;
+pub fn render_to<W:Writer>(output: &mut W) {
     let edges = Edges(vec!((0,1), (0,2), (1,3), (2,3), (3,4), (4,4)));
-    let mut f = File::create(&Path::new("example1.dot"));
-    dot::render(&edges, &mut f).unwrap()
+    dot::render(&edges, output).unwrap()
 }
 
 impl<'a> dot::Labeller<'a, Nd, Ed> for Edges {
@@ -91,6 +89,17 @@ fn edges(&'a self) -> dot::Edges<'a,Ed> {
 
     fn target(&self, e: &Ed) -> Nd { let &(_,t) = e; t }
 }
+
+# pub fn main() { use std::io::MemWriter; render_to(&mut MemWriter::new()) }
+```
+
+```no_run
+# pub fn render_to<W:Writer>(output: &mut W) { unimplemented!() }
+pub fn main() {
+    use std::io::File;
+    let mut f = File::create(&Path::new("example1.dot"));
+    render_to(&mut f)
+}
 ```
 
 Output from first example (in `example1.dot`):
@@ -140,19 +149,17 @@ fn edges(&'a self) -> dot::Edges<'a,Ed> {
 ```rust
 use dot = graphviz;
 use std::str;
-use std::io::File;
 
 type Nd = uint;
 type Ed<'a> = &'a (uint, uint);
 struct Graph { nodes: Vec<&'static str>, edges: Vec<(uint,uint)> }
 
-pub fn main() {
+pub fn render_to<W:Writer>(output: &mut W) {
     let nodes = vec!("{x,y}","{x}","{y}","{}");
     let edges = vec!((0,1), (0,2), (1,3), (2,3));
     let graph = Graph { nodes: nodes, edges: edges };
 
-    let mut f = File::create(&Path::new("example2.dot"));
-    dot::render(&graph, &mut f).unwrap()
+    dot::render(&graph, output).unwrap()
 }
 
 impl<'a> dot::Labeller<'a, Nd, Ed<'a>> for Graph {
@@ -174,6 +181,17 @@ fn edges(&'a self) -> dot::Edges<'a,Ed<'a>> { self.edges.iter().collect() }
     fn source(&self, e: &Ed) -> Nd { let & &(s,_) = e; s }
     fn target(&self, e: &Ed) -> Nd { let & &(_,t) = e; t }
 }
+
+# pub fn main() { use std::io::MemWriter; render_to(&mut MemWriter::new()) }
+```
+
+```no_run
+# pub fn render_to<W:Writer>(output: &mut W) { unimplemented!() }
+pub fn main() {
+    use std::io::File;
+    let mut f = File::create(&Path::new("example2.dot"));
+    render_to(&mut f)
+}
 ```
 
 The third example is similar to the second, except now each node and
@@ -187,19 +205,17 @@ fn edges(&'a self) -> dot::Edges<'a,Ed<'a>> { self.edges.iter().collect() }
 ```rust
 use dot = graphviz;
 use std::str;
-use std::io::File;
 
 type Nd<'a> = (uint, &'a str);
 type Ed<'a> = (Nd<'a>, Nd<'a>);
 struct Graph { nodes: Vec<&'static str>, edges: Vec<(uint,uint)> }
 
-pub fn main() {
+pub fn render_to<W:Writer>(output: &mut W) {
     let nodes = vec!("{x,y}","{x}","{y}","{}");
     let edges = vec!((0,1), (0,2), (1,3), (2,3));
     let graph = Graph { nodes: nodes, edges: edges };
 
-    let mut f = File::create(&Path::new("example3.dot"));
-    dot::render(&graph, &mut f).unwrap()
+    dot::render(&graph, output).unwrap()
 }
 
 impl<'a> dot::Labeller<'a, Nd<'a>, Ed<'a>> for Graph {
@@ -229,6 +245,17 @@ fn edges(&'a self) -> dot::Edges<'a,Ed<'a>> {
     fn source(&self, e: &Ed<'a>) -> Nd<'a> { let &(s,_) = e; s }
     fn target(&self, e: &Ed<'a>) -> Nd<'a> { let &(_,t) = e; t }
 }
+
+# pub fn main() { use std::io::MemWriter; render_to(&mut MemWriter::new()) }
+```
+
+```no_run
+# pub fn render_to<W:Writer>(output: &mut W) { unimplemented!() }
+pub fn main() {
+    use std::io::File;
+    let mut f = File::create(&Path::new("example3.dot"));
+    render_to(&mut f)
+}
 ```
 
 # References
index a4593c1cb5afc745b804ded01209c90633b38f04..5f67be22068dbd6b94d489e3b8964864228344f4 100644 (file)
 pub use consts::os::bsd44::{SO_REUSEADDR, SO_BROADCAST, SHUT_WR, IP_MULTICAST_LOOP};
 pub use consts::os::bsd44::{IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP};
 pub use consts::os::bsd44::{IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP};
-pub use consts::os::bsd44::{IP_MULTICAST_TTL, IP_TTL};
+pub use consts::os::bsd44::{IP_MULTICAST_TTL, IP_TTL, SHUT_RD};
 
 pub use funcs::c95::ctype::{isalnum, isalpha, iscntrl, isdigit};
 pub use funcs::c95::ctype::{islower, isprint, ispunct, isspace};
 #[cfg(windows)] pub use consts::os::extra::{FILE_WRITE_ATTRIBUTES, FILE_READ_ATTRIBUTES};
 #[cfg(windows)] pub use consts::os::extra::{ERROR_PIPE_BUSY, ERROR_IO_PENDING};
 #[cfg(windows)] pub use consts::os::extra::{ERROR_PIPE_CONNECTED, WAIT_OBJECT_0};
+#[cfg(windows)] pub use consts::os::extra::{ERROR_NOT_FOUND};
+#[cfg(windows)] pub use consts::os::extra::{ERROR_OPERATION_ABORTED};
 #[cfg(windows)] pub use types::os::common::bsd44::{SOCKET};
 #[cfg(windows)] pub use types::os::common::posix01::{stat, utimbuf};
 #[cfg(windows)] pub use types::os::arch::extra::{HANDLE, BOOL, LPSECURITY_ATTRIBUTES};
@@ -1740,8 +1742,10 @@ pub mod extra {
             pub static ERROR_NO_DATA: c_int = 232;
             pub static ERROR_INVALID_ADDRESS : c_int = 487;
             pub static ERROR_PIPE_CONNECTED: c_int = 535;
+            pub static ERROR_OPERATION_ABORTED: c_int = 995;
             pub static ERROR_IO_PENDING: c_int = 997;
             pub static ERROR_FILE_INVALID : c_int = 1006;
+            pub static ERROR_NOT_FOUND: c_int = 1168;
             pub static INVALID_HANDLE_VALUE : c_int = -1;
 
             pub static DELETE : DWORD = 0x00010000;
index 035a81f414369c03e696e26027b99429c3441faf..09e9cd83f3d4fdbe20db7c14bfeb4a4cd7426231 100644 (file)
@@ -122,7 +122,6 @@ fn main() {
 use std::fmt;
 use std::io::LineBufferedWriter;
 use std::io;
-use std::local_data;
 use std::os;
 use std::rt;
 use std::slice;
@@ -228,7 +227,7 @@ pub fn log(level: u32, loc: &'static LogLocation, args: &fmt::Arguments) {
     // Completely remove the local logger from TLS in case anyone attempts to
     // frob the slot while we're doing the logging. This will destroy any logger
     // set during logging.
-    let mut logger = local_data::pop(local_logger).unwrap_or_else(|| {
+    let mut logger = local_logger.replace(None).unwrap_or_else(|| {
         box DefaultLogger { handle: io::stderr() } as Box<Logger:Send>
     });
     logger.log(&LogRecord {
@@ -238,7 +237,7 @@ pub fn log(level: u32, loc: &'static LogLocation, args: &fmt::Arguments) {
         module_path: loc.module_path,
         line: loc.line,
     });
-    local_data::set(local_logger, logger);
+    local_logger.replace(Some(logger));
 }
 
 /// Getter for the global log level. This is a function so that it can be called
@@ -250,9 +249,7 @@ pub fn log_level() -> u32 { unsafe { LOG_LEVEL } }
 /// Replaces the task-local logger with the specified logger, returning the old
 /// logger.
 pub fn set_logger(logger: Box<Logger:Send>) -> Option<Box<Logger:Send>> {
-    let prev = local_data::pop(local_logger);
-    local_data::set(local_logger, logger);
-    return prev;
+    local_logger.replace(Some(logger))
 }
 
 /// A LogRecord is created by the logging macros, and passed as the only
index 71944202205ffcd47118e3f6e524f3c8ad739fcd..57b87f21521e8221844e230b806f2888fcf12f45 100644 (file)
@@ -22,7 +22,7 @@
 
 impl GetAddrInfoRequest {
     pub fn run(host: Option<&str>, servname: Option<&str>,
-               hint: Option<ai::Hint>) -> Result<~[ai::Info], IoError> {
+               hint: Option<ai::Hint>) -> Result<Vec<ai::Info>, IoError> {
         assert!(host.is_some() || servname.is_some());
 
         let c_host = host.map_or(unsafe { CString::new(null(), true) }, |x| x.to_c_str());
@@ -80,7 +80,7 @@ pub fn run(host: Option<&str>, servname: Option<&str>,
 
         unsafe { freeaddrinfo(res); }
 
-        Ok(addrs.move_iter().collect())
+        Ok(addrs)
     }
 }
 
index e2bf515a1e52301130fbb247fa82569181027977..abb22476e5240f4dd0da44aa2e5664fb1acf3b63 100644 (file)
 #[cfg(target_os = "android")]
 pub static FIOCLEX: libc::c_ulong = 0x5451;
 
+#[cfg(target_os = "macos")]
+#[cfg(target_os = "freebsd")]
+pub static MSG_DONTWAIT: libc::c_int = 0x80;
+#[cfg(target_os = "linux")]
+#[cfg(target_os = "android")]
+pub static MSG_DONTWAIT: libc::c_int = 0x40;
+
 extern {
     pub fn gettimeofday(timeval: *mut libc::timeval,
                         tzp: *libc::c_void) -> libc::c_int;
index 6c84424e97a0df4fa0c25e74fc97eaa379fc25dd..151111af3dfede70c89da99ece05772f6926325a 100644 (file)
@@ -18,6 +18,7 @@
 pub static WSASYS_STATUS_LEN: uint = 128;
 pub static FIONBIO: libc::c_long = 0x8004667e;
 static FD_SETSIZE: uint = 64;
+pub static MSG_DONTWAIT: libc::c_int = 0;
 
 pub struct WSADATA {
     pub wVersion: libc::WORD,
@@ -61,4 +62,6 @@ pub fn getsockopt(sockfd: libc::SOCKET,
                       optlen: *mut libc::c_int) -> libc::c_int;
 
     pub fn CancelIo(hFile: libc::HANDLE) -> libc::BOOL;
+    pub fn CancelIoEx(hFile: libc::HANDLE,
+                      lpOverlapped: libc::LPOVERLAPPED) -> libc::BOOL;
 }
index 2727f9a0b095a012834496859ac8a1425247cc21..87225a10e76d50cfda0ae3626cf7c47933a8b236 100644 (file)
 
 use libc::{c_int, c_void};
 use libc;
-use std::sync::arc::UnsafeArc;
 use std::c_str::CString;
 use std::io::IoError;
 use std::io;
 use std::mem;
 use std::rt::rtio;
+use std::sync::arc::UnsafeArc;
 
 use io::{IoResult, retry, keep_going};
 
@@ -178,6 +178,20 @@ fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
     fn clone(&self) -> Box<rtio::RtioPipe:Send> {
         box FileDesc { inner: self.inner.clone() } as Box<rtio::RtioPipe:Send>
     }
+
+    // Only supported on named pipes currently. Note that this doesn't have an
+    // impact on the std::io primitives, this is never called via
+    // std::io::PipeStream. If the functionality is exposed in the future, then
+    // these methods will need to be implemented.
+    fn close_read(&mut self) -> Result<(), IoError> {
+        Err(io::standard_error(io::InvalidInput))
+    }
+    fn close_write(&mut self) -> Result<(), IoError> {
+        Err(io::standard_error(io::InvalidInput))
+    }
+    fn set_timeout(&mut self, _t: Option<u64>) {}
+    fn set_read_timeout(&mut self, _t: Option<u64>) {}
+    fn set_write_timeout(&mut self, _t: Option<u64>) {}
 }
 
 impl rtio::RtioTTY for FileDesc {
index 018907303b84e351944bd6311355cdc39d39196b..42e5ad062ee84b078fc6372c351da52c71f84c85 100644 (file)
@@ -22,7 +22,7 @@
 use std::rt::rtio;
 use std::str;
 use std::sync::arc::UnsafeArc;
-use std::slice;
+use std::vec;
 
 use io::IoResult;
 
@@ -210,6 +210,20 @@ fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
     fn clone(&self) -> Box<rtio::RtioPipe:Send> {
         box FileDesc { inner: self.inner.clone() } as Box<rtio::RtioPipe:Send>
     }
+
+    // Only supported on named pipes currently. Note that this doesn't have an
+    // impact on the std::io primitives, this is never called via
+    // std::io::PipeStream. If the functionality is exposed in the future, then
+    // these methods will need to be implemented.
+    fn close_read(&mut self) -> IoResult<()> {
+        Err(io::standard_error(io::InvalidInput))
+    }
+    fn close_write(&mut self) -> IoResult<()> {
+        Err(io::standard_error(io::InvalidInput))
+    }
+    fn set_timeout(&mut self, _t: Option<u64>) {}
+    fn set_read_timeout(&mut self, _t: Option<u64>) {}
+    fn set_write_timeout(&mut self, _t: Option<u64>) {}
 }
 
 impl rtio::RtioTTY for FileDesc {
@@ -354,8 +368,8 @@ fn prune(root: &CString, dirs: Vec<Path>) -> Vec<Path> {
                 if fp_buf as uint == 0 {
                     fail!("os::list_dir() failure: got null ptr from wfd");
                 } else {
-                    let fp_vec = slice::from_buf(fp_buf, libc::wcslen(fp_buf) as uint);
-                    let fp_trimmed = str::truncate_utf16_at_nul(fp_vec);
+                    let fp_vec = vec::raw::from_buf(fp_buf, libc::wcslen(fp_buf) as uint);
+                    let fp_trimmed = str::truncate_utf16_at_nul(fp_vec.as_slice());
                     let fp_str = str::from_utf16(fp_trimmed)
                             .expect("rust_list_dir_wfd_fp_buf returned invalid UTF-16");
                     paths.push(Path::new(fp_str));
index 58fcd60f13815495f7ba58b4ff9e34269f31b467..f2c2c66e1425fe521be0ff897e2a17c10b98b567 100644 (file)
@@ -194,7 +194,7 @@ fn unix_connect(&mut self, path: &CString,
         })
     }
     fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
-                          hint: Option<ai::Hint>) -> IoResult<~[ai::Info]> {
+                          hint: Option<ai::Hint>) -> IoResult<Vec<ai::Info>> {
         addrinfo::GetAddrInfoRequest::run(host, servname, hint)
     }
 
@@ -260,7 +260,7 @@ fn timer_init(&mut self) -> IoResult<Box<RtioTimer:Send>> {
     }
     fn spawn(&mut self, config: ProcessConfig)
             -> IoResult<(Box<RtioProcess:Send>,
-                         ~[Option<Box<RtioPipe:Send>>])> {
+                         Vec<Option<Box<RtioPipe:Send>>>)> {
         process::Process::spawn(config).map(|(p, io)| {
             (box p as Box<RtioProcess:Send>,
              io.move_iter().map(|p| p.map(|p| {
index 880cbaabaf80e6f90535feefdd2ac3ca77a61a4f..63d57756e5dfd02f45be05fd88ee0781774997a4 100644 (file)
@@ -15,6 +15,7 @@
 use std::mem;
 use std::rt::rtio;
 use std::sync::arc::UnsafeArc;
+use std::unstable::mutex;
 
 use super::{IoResult, retry, keep_going};
 use super::c;
@@ -236,22 +237,36 @@ pub fn init() {
 
 pub struct TcpStream {
     inner: UnsafeArc<Inner>,
+    read_deadline: u64,
+    write_deadline: u64,
 }
 
 struct Inner {
     fd: sock_t,
+    lock: mutex::NativeMutex,
+}
+
+pub struct Guard<'a> {
+    pub fd: sock_t,
+    pub guard: mutex::LockGuard<'a>,
+}
+
+impl Inner {
+    fn new(fd: sock_t) -> Inner {
+        Inner { fd: fd, lock: unsafe { mutex::NativeMutex::new() } }
+    }
 }
 
 impl TcpStream {
     pub fn connect(addr: ip::SocketAddr,
                    timeout: Option<u64>) -> IoResult<TcpStream> {
         let fd = try!(socket(addr, libc::SOCK_STREAM));
-        let (addr, len) = addr_to_sockaddr(addr);
-        let inner = Inner { fd: fd };
-        let ret = TcpStream { inner: UnsafeArc::new(inner) };
+        let ret = TcpStream::new(Inner::new(fd));
 
-        let len = len as libc::socklen_t;
+        let (addr, len) = addr_to_sockaddr(addr);
         let addrp = &addr as *_ as *libc::sockaddr;
+        let len = len as libc::socklen_t;
+
         match timeout {
             Some(timeout) => {
                 try!(util::connect_timeout(fd, addrp, len, timeout));
@@ -266,6 +281,14 @@ pub fn connect(addr: ip::SocketAddr,
         }
     }
 
+    fn new(inner: Inner) -> TcpStream {
+        TcpStream {
+            inner: UnsafeArc::new(inner),
+            read_deadline: 0,
+            write_deadline: 0,
+        }
+    }
+
     pub fn fd(&self) -> sock_t {
         // This unsafety is fine because it's just a read-only arc
         unsafe { (*self.inner.get()).fd }
@@ -299,6 +322,19 @@ fn set_tcp_keepalive(&mut self, seconds: uint) -> IoResult<()> {
     fn set_tcp_keepalive(&mut self, _seconds: uint) -> IoResult<()> {
         Ok(())
     }
+
+    #[cfg(target_os = "linux")]
+    fn lock_nonblocking(&self) {}
+
+    #[cfg(not(target_os = "linux"))]
+    fn lock_nonblocking<'a>(&'a self) -> Guard<'a> {
+        let ret = Guard {
+            fd: self.fd(),
+            guard: unsafe { (*self.inner.get()).lock.lock() },
+        };
+        assert!(util::set_nonblocking(self.fd(), true).is_ok());
+        ret
+    }
 }
 
 #[cfg(windows)] type wrlen = libc::c_int;
@@ -306,33 +342,31 @@ fn set_tcp_keepalive(&mut self, _seconds: uint) -> IoResult<()> {
 
 impl rtio::RtioTcpStream for TcpStream {
     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
-        let ret = retry(|| {
-            unsafe {
-                libc::recv(self.fd(),
-                           buf.as_mut_ptr() as *mut libc::c_void,
-                           buf.len() as wrlen,
-                           0) as libc::c_int
-            }
-        });
-        if ret == 0 {
-            Err(io::standard_error(io::EndOfFile))
-        } else if ret < 0 {
-            Err(last_error())
-        } else {
-            Ok(ret as uint)
-        }
+        let fd = self.fd();
+        let dolock = || self.lock_nonblocking();
+        let doread = |nb| unsafe {
+            let flags = if nb {c::MSG_DONTWAIT} else {0};
+            libc::recv(fd,
+                       buf.as_mut_ptr() as *mut libc::c_void,
+                       buf.len() as wrlen,
+                       flags) as libc::c_int
+        };
+        read(fd, self.read_deadline, dolock, doread)
     }
+
     fn write(&mut self, buf: &[u8]) -> IoResult<()> {
-        let ret = keep_going(buf, |buf, len| unsafe {
-            libc::send(self.fd(),
+        let fd = self.fd();
+        let dolock = || self.lock_nonblocking();
+        let dowrite = |nb: bool, buf: *u8, len: uint| unsafe {
+            let flags = if nb {c::MSG_DONTWAIT} else {0};
+            libc::send(fd,
                        buf as *mut libc::c_void,
                        len as wrlen,
-                       0) as i64
-        });
-        if ret < 0 {
-            Err(super::last_error())
-        } else {
-            Ok(())
+                       flags) as i64
+        };
+        match write(fd, self.write_deadline, buf, true, dolock, dowrite) {
+            Ok(_) => Ok(()),
+            Err(e) => Err(e)
         }
     }
     fn peer_name(&mut self) -> IoResult<ip::SocketAddr> {
@@ -354,12 +388,28 @@ fn letdie(&mut self) -> IoResult<()> {
     fn clone(&self) -> Box<rtio::RtioTcpStream:Send> {
         box TcpStream {
             inner: self.inner.clone(),
+            read_deadline: 0,
+            write_deadline: 0,
         } as Box<rtio::RtioTcpStream:Send>
     }
+
     fn close_write(&mut self) -> IoResult<()> {
-        super::mkerr_libc(unsafe {
-            libc::shutdown(self.fd(), libc::SHUT_WR)
-        })
+        super::mkerr_libc(unsafe { libc::shutdown(self.fd(), libc::SHUT_WR) })
+    }
+    fn close_read(&mut self) -> IoResult<()> {
+        super::mkerr_libc(unsafe { libc::shutdown(self.fd(), libc::SHUT_RD) })
+    }
+
+    fn set_timeout(&mut self, timeout: Option<u64>) {
+        let deadline = timeout.map(|a| ::io::timer::now() + a).unwrap_or(0);
+        self.read_deadline = deadline;
+        self.write_deadline = deadline;
+    }
+    fn set_read_timeout(&mut self, timeout: Option<u64>) {
+        self.read_deadline = timeout.map(|a| ::io::timer::now() + a).unwrap_or(0);
+    }
+    fn set_write_timeout(&mut self, timeout: Option<u64>) {
+        self.write_deadline = timeout.map(|a| ::io::timer::now() + a).unwrap_or(0);
     }
 }
 
@@ -373,6 +423,13 @@ impl Drop for Inner {
     fn drop(&mut self) { unsafe { close(self.fd); } }
 }
 
+#[unsafe_destructor]
+impl<'a> Drop for Guard<'a> {
+    fn drop(&mut self) {
+        assert!(util::set_nonblocking(self.fd, false).is_ok());
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // TCP listeners
 ////////////////////////////////////////////////////////////////////////////////
@@ -383,29 +440,24 @@ pub struct TcpListener {
 
 impl TcpListener {
     pub fn bind(addr: ip::SocketAddr) -> IoResult<TcpListener> {
-        unsafe {
-            socket(addr, libc::SOCK_STREAM).and_then(|fd| {
-                let (addr, len) = addr_to_sockaddr(addr);
-                let addrp = &addr as *libc::sockaddr_storage;
-                let inner = Inner { fd: fd };
-                let ret = TcpListener { inner: inner };
-                // On platforms with Berkeley-derived sockets, this allows
-                // to quickly rebind a socket, without needing to wait for
-                // the OS to clean up the previous one.
-                if cfg!(unix) {
-                    match setsockopt(fd, libc::SOL_SOCKET,
-                                     libc::SO_REUSEADDR,
-                                     1 as libc::c_int) {
-                        Err(n) => { return Err(n); },
-                        Ok(..) => { }
-                    }
-                }
-                match libc::bind(fd, addrp as *libc::sockaddr,
-                                 len as libc::socklen_t) {
-                    -1 => Err(last_error()),
-                    _ => Ok(ret),
-                }
-            })
+        let fd = try!(socket(addr, libc::SOCK_STREAM));
+        let ret = TcpListener { inner: Inner::new(fd) };
+
+        let (addr, len) = addr_to_sockaddr(addr);
+        let addrp = &addr as *_ as *libc::sockaddr;
+        let len = len as libc::socklen_t;
+
+        // On platforms with Berkeley-derived sockets, this allows
+        // to quickly rebind a socket, without needing to wait for
+        // the OS to clean up the previous one.
+        if cfg!(unix) {
+            try!(setsockopt(fd, libc::SOL_SOCKET, libc::SO_REUSEADDR,
+                            1 as libc::c_int));
+        }
+
+        match unsafe { libc::bind(fd, addrp, len) } {
+            -1 => Err(last_error()),
+            _ => Ok(ret),
         }
     }
 
@@ -443,7 +495,7 @@ pub fn fd(&self) -> sock_t { self.listener.fd() }
 
     pub fn native_accept(&mut self) -> IoResult<TcpStream> {
         if self.deadline != 0 {
-            try!(util::accept_deadline(self.fd(), self.deadline));
+            try!(util::await(self.fd(), Some(self.deadline), util::Readable));
         }
         unsafe {
             let mut storage: libc::sockaddr_storage = mem::init();
@@ -456,7 +508,7 @@ pub fn native_accept(&mut self) -> IoResult<TcpStream> {
                              &mut size as *mut libc::socklen_t) as libc::c_int
             }) as sock_t {
                 -1 => Err(last_error()),
-                fd => Ok(TcpStream { inner: UnsafeArc::new(Inner { fd: fd })})
+                fd => Ok(TcpStream::new(Inner::new(fd))),
             }
         }
     }
@@ -486,22 +538,26 @@ fn set_timeout(&mut self, timeout: Option<u64>) {
 
 pub struct UdpSocket {
     inner: UnsafeArc<Inner>,
+    read_deadline: u64,
+    write_deadline: u64,
 }
 
 impl UdpSocket {
     pub fn bind(addr: ip::SocketAddr) -> IoResult<UdpSocket> {
-        unsafe {
-            socket(addr, libc::SOCK_DGRAM).and_then(|fd| {
-                let (addr, len) = addr_to_sockaddr(addr);
-                let addrp = &addr as *libc::sockaddr_storage;
-                let inner = Inner { fd: fd };
-                let ret = UdpSocket { inner: UnsafeArc::new(inner) };
-                match libc::bind(fd, addrp as *libc::sockaddr,
-                                 len as libc::socklen_t) {
-                    -1 => Err(last_error()),
-                    _ => Ok(ret),
-                }
-            })
+        let fd = try!(socket(addr, libc::SOCK_DGRAM));
+        let ret = UdpSocket {
+            inner: UnsafeArc::new(Inner::new(fd)),
+            read_deadline: 0,
+            write_deadline: 0,
+        };
+
+        let (addr, len) = addr_to_sockaddr(addr);
+        let addrp = &addr as *_ as *libc::sockaddr;
+        let len = len as libc::socklen_t;
+
+        match unsafe { libc::bind(fd, addrp, len) } {
+            -1 => Err(last_error()),
+            _ => Ok(ret),
         }
     }
 
@@ -540,6 +596,19 @@ pub fn set_membership(&mut self, addr: ip::IpAddr,
             }
         }
     }
+
+    #[cfg(target_os = "linux")]
+    fn lock_nonblocking(&self) {}
+
+    #[cfg(not(target_os = "linux"))]
+    fn lock_nonblocking<'a>(&'a self) -> Guard<'a> {
+        let ret = Guard {
+            fd: self.fd(),
+            guard: unsafe { (*self.inner.get()).lock.lock() },
+        };
+        assert!(util::set_nonblocking(self.fd(), true).is_ok());
+        ret
+    }
 }
 
 impl rtio::RtioSocket for UdpSocket {
@@ -553,48 +622,54 @@ fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
 
 impl rtio::RtioUdpSocket for UdpSocket {
     fn recvfrom(&mut self, buf: &mut [u8]) -> IoResult<(uint, ip::SocketAddr)> {
-        unsafe {
-            let mut storage: libc::sockaddr_storage = mem::init();
-            let storagep = &mut storage as *mut libc::sockaddr_storage;
-            let mut addrlen: libc::socklen_t =
-                    mem::size_of::<libc::sockaddr_storage>() as libc::socklen_t;
-            let ret = retry(|| {
-                libc::recvfrom(self.fd(),
-                               buf.as_ptr() as *mut libc::c_void,
-                               buf.len() as msglen_t,
-                               0,
-                               storagep as *mut libc::sockaddr,
-                               &mut addrlen) as libc::c_int
-            });
-            if ret < 0 { return Err(last_error()) }
-            sockaddr_to_addr(&storage, addrlen as uint).and_then(|addr| {
-                Ok((ret as uint, addr))
-            })
-        }
+        let fd = self.fd();
+        let mut storage: libc::sockaddr_storage = unsafe { mem::init() };
+        let storagep = &mut storage as *mut _ as *mut libc::sockaddr;
+        let mut addrlen: libc::socklen_t =
+                mem::size_of::<libc::sockaddr_storage>() as libc::socklen_t;
+
+        let dolock = || self.lock_nonblocking();
+        let doread = |nb| unsafe {
+            let flags = if nb {c::MSG_DONTWAIT} else {0};
+            libc::recvfrom(fd,
+                           buf.as_mut_ptr() as *mut libc::c_void,
+                           buf.len() as msglen_t,
+                           flags,
+                           storagep,
+                           &mut addrlen) as libc::c_int
+        };
+        let n = try!(read(fd, self.read_deadline, dolock, doread));
+        sockaddr_to_addr(&storage, addrlen as uint).and_then(|addr| {
+            Ok((n as uint, addr))
+        })
     }
+
     fn sendto(&mut self, buf: &[u8], dst: ip::SocketAddr) -> IoResult<()> {
-        let (dst, len) = addr_to_sockaddr(dst);
-        let dstp = &dst as *libc::sockaddr_storage;
-        unsafe {
-            let ret = retry(|| {
-                libc::sendto(self.fd(),
-                             buf.as_ptr() as *libc::c_void,
-                             buf.len() as msglen_t,
-                             0,
-                             dstp as *libc::sockaddr,
-                             len as libc::socklen_t) as libc::c_int
-            });
-            match ret {
-                -1 => Err(last_error()),
-                n if n as uint != buf.len() => {
-                    Err(io::IoError {
-                        kind: io::OtherIoError,
-                        desc: "couldn't send entire packet at once",
-                        detail: None,
-                    })
-                }
-                _ => Ok(())
-            }
+        let (dst, dstlen) = addr_to_sockaddr(dst);
+        let dstp = &dst as *_ as *libc::sockaddr;
+        let dstlen = dstlen as libc::socklen_t;
+
+        let fd = self.fd();
+        let dolock = || self.lock_nonblocking();
+        let dowrite = |nb, buf: *u8, len: uint| unsafe {
+            let flags = if nb {c::MSG_DONTWAIT} else {0};
+            libc::sendto(fd,
+                         buf as *libc::c_void,
+                         len as msglen_t,
+                         flags,
+                         dstp,
+                         dstlen) as i64
+        };
+
+        let n = try!(write(fd, self.write_deadline, buf, false, dolock, dowrite));
+        if n != buf.len() {
+            Err(io::IoError {
+                kind: io::ShortWrite(n),
+                desc: "couldn't send entire packet at once",
+                detail: None,
+            })
+        } else {
+            Ok(())
         }
     }
 
@@ -644,6 +719,179 @@ fn ignore_broadcasts(&mut self) -> IoResult<()> {
     fn clone(&self) -> Box<rtio::RtioUdpSocket:Send> {
         box UdpSocket {
             inner: self.inner.clone(),
+            read_deadline: 0,
+            write_deadline: 0,
         } as Box<rtio::RtioUdpSocket:Send>
     }
+
+    fn set_timeout(&mut self, timeout: Option<u64>) {
+        let deadline = timeout.map(|a| ::io::timer::now() + a).unwrap_or(0);
+        self.read_deadline = deadline;
+        self.write_deadline = deadline;
+    }
+    fn set_read_timeout(&mut self, timeout: Option<u64>) {
+        self.read_deadline = timeout.map(|a| ::io::timer::now() + a).unwrap_or(0);
+    }
+    fn set_write_timeout(&mut self, timeout: Option<u64>) {
+        self.write_deadline = timeout.map(|a| ::io::timer::now() + a).unwrap_or(0);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Timeout helpers
+//
+// The read/write functions below are the helpers for reading/writing a socket
+// with a possible deadline specified. This is generally viewed as a timed out
+// I/O operation.
+//
+// From the application's perspective, timeouts apply to the I/O object, not to
+// the underlying file descriptor (it's one timeout per object). This means that
+// we can't use the SO_RCVTIMEO and corresponding send timeout option.
+//
+// The next idea to implement timeouts would be to use nonblocking I/O. An
+// invocation of select() would wait (with a timeout) for a socket to be ready.
+// Once its ready, we can perform the operation. Note that the operation *must*
+// be nonblocking, even though select() says the socket is ready. This is
+// because some other thread could have come and stolen our data (handles can be
+// cloned).
+//
+// To implement nonblocking I/O, the first option we have is to use the
+// O_NONBLOCK flag. Remember though that this is a global setting, affecting all
+// I/O objects, so this was initially viewed as unwise.
+//
+// It turns out that there's this nifty MSG_DONTWAIT flag which can be passed to
+// send/recv, but the niftiness wears off once you realize it only works well on
+// linux [1] [2]. This means that it's pretty easy to get a nonblocking
+// operation on linux (no flag fidding, no affecting other objects), but not on
+// other platforms.
+//
+// To work around this constraint on other platforms, we end up using the
+// original strategy of flipping the O_NONBLOCK flag. As mentioned before, this
+// could cause other objects' blocking operations to suddenly become
+// nonblocking. To get around this, a "blocking operation" which returns EAGAIN
+// falls back to using the same code path as nonblocking operations, but with an
+// infinite timeout (select + send/recv). This helps emulate blocking
+// reads/writes despite the underlying descriptor being nonblocking, as well as
+// optimizing the fast path of just hitting one syscall in the good case.
+//
+// As a final caveat, this implementation uses a mutex so only one thread is
+// doing a nonblocking operation at at time. This is the operation that comes
+// after the select() (at which point we think the socket is ready). This is
+// done for sanity to ensure that the state of the O_NONBLOCK flag is what we
+// expect (wouldn't want someone turning it on when it should be off!). All
+// operations performed in the lock are *nonblocking* to avoid holding the mutex
+// forever.
+//
+// So, in summary, linux uses MSG_DONTWAIT and doesn't need mutexes, everyone
+// else uses O_NONBLOCK and mutexes with some trickery to make sure blocking
+// reads/writes are still blocking.
+//
+// Fun, fun!
+//
+// [1] http://twistedmatrix.com/pipermail/twisted-commits/2012-April/034692.html
+// [2] http://stackoverflow.com/questions/19819198/does-send-msg-dontwait
+
+pub fn read<T>(fd: sock_t,
+               deadline: u64,
+               lock: || -> T,
+               read: |bool| -> libc::c_int) -> IoResult<uint> {
+    let mut ret = -1;
+    if deadline == 0 {
+        ret = retry(|| read(false));
+    }
+
+    if deadline != 0 || (ret == -1 && util::wouldblock()) {
+        let deadline = match deadline {
+            0 => None,
+            n => Some(n),
+        };
+        loop {
+            // With a timeout, first we wait for the socket to become
+            // readable using select(), specifying the relevant timeout for
+            // our previously set deadline.
+            try!(util::await(fd, deadline, util::Readable));
+
+            // At this point, we're still within the timeout, and we've
+            // determined that the socket is readable (as returned by
+            // select). We must still read the socket in *nonblocking* mode
+            // because some other thread could come steal our data. If we
+            // fail to read some data, we retry (hence the outer loop) and
+            // wait for the socket to become readable again.
+            let _guard = lock();
+            match retry(|| read(deadline.is_some())) {
+                -1 if util::wouldblock() => { assert!(deadline.is_some()); }
+                -1 => return Err(last_error()),
+               n => { ret = n; break }
+            }
+        }
+    }
+
+    match ret {
+        0 => Err(io::standard_error(io::EndOfFile)),
+        n if n < 0 => Err(last_error()),
+        n => Ok(n as uint)
+    }
+}
+
+pub fn write<T>(fd: sock_t,
+                deadline: u64,
+                buf: &[u8],
+                write_everything: bool,
+                lock: || -> T,
+                write: |bool, *u8, uint| -> i64) -> IoResult<uint> {
+    let mut ret = -1;
+    let mut written = 0;
+    if deadline == 0 {
+        if write_everything {
+            ret = keep_going(buf, |inner, len| {
+                written = buf.len() - len;
+                write(false, inner, len)
+            });
+        } else {
+            ret = retry(|| {
+                write(false, buf.as_ptr(), buf.len()) as libc::c_int
+            }) as i64;
+            if ret > 0 { written = ret as uint; }
+        }
+    }
+
+    if deadline != 0 || (ret == -1 && util::wouldblock()) {
+        let deadline = match deadline {
+            0 => None,
+            n => Some(n),
+        };
+        while written < buf.len() && (write_everything || written == 0) {
+            // As with read(), first wait for the socket to be ready for
+            // the I/O operation.
+            match util::await(fd, deadline, util::Writable) {
+                Err(ref e) if e.kind == io::TimedOut && written > 0 => {
+                    assert!(deadline.is_some());
+                    return Err(io::IoError {
+                        kind: io::ShortWrite(written),
+                        desc: "short write",
+                        detail: None,
+                    })
+                }
+                Err(e) => return Err(e),
+                Ok(()) => {}
+            }
+
+            // Also as with read(), we use MSG_DONTWAIT to guard ourselves
+            // against unforseen circumstances.
+            let _guard = lock();
+            let ptr = buf.slice_from(written).as_ptr();
+            let len = buf.len() - written;
+            match retry(|| write(deadline.is_some(), ptr, len) as libc::c_int) {
+                -1 if util::wouldblock() => {}
+                -1 => return Err(last_error()),
+                n => { written += n as uint; }
+            }
+        }
+        ret = 0;
+    }
+    if ret < 0 {
+        Err(last_error())
+    } else {
+        Ok(written)
+    }
 }
index 65e9c7448c2d51f33049f548c9db14f847651bf3..36ae2ba06d52b562a14e4f9853bc776a1aabbf66 100644 (file)
 use std::mem;
 use std::rt::rtio;
 use std::sync::arc::UnsafeArc;
+use std::unstable::mutex;
 
-use super::{IoResult, retry, keep_going};
+use super::{IoResult, retry};
+use super::net;
 use super::util;
+use super::c;
 use super::file::fd_t;
 
 fn unix_socket(ty: libc::c_int) -> IoResult<fd_t> {
@@ -55,6 +58,13 @@ fn addr_to_sockaddr_un(addr: &CString) -> IoResult<(libc::sockaddr_storage, uint
 
 struct Inner {
     fd: fd_t,
+    lock: mutex::NativeMutex,
+}
+
+impl Inner {
+    fn new(fd: fd_t) -> Inner {
+        Inner { fd: fd, lock: unsafe { mutex::NativeMutex::new() } }
+    }
 }
 
 impl Drop for Inner {
@@ -64,7 +74,7 @@ impl Drop for Inner {
 fn connect(addr: &CString, ty: libc::c_int,
            timeout: Option<u64>) -> IoResult<Inner> {
     let (addr, len) = try!(addr_to_sockaddr_un(addr));
-    let inner = Inner { fd: try!(unix_socket(ty)) };
+    let inner = Inner::new(try!(unix_socket(ty)));
     let addrp = &addr as *_ as *libc::sockaddr;
     let len = len as libc::socklen_t;
 
@@ -84,7 +94,7 @@ fn connect(addr: &CString, ty: libc::c_int,
 
 fn bind(addr: &CString, ty: libc::c_int) -> IoResult<Inner> {
     let (addr, len) = try!(addr_to_sockaddr_un(addr));
-    let inner = Inner { fd: try!(unix_socket(ty)) };
+    let inner = Inner::new(try!(unix_socket(ty)));
     let addrp = &addr as *libc::sockaddr_storage;
     match unsafe {
         libc::bind(inner.fd, addrp as *libc::sockaddr, len as libc::socklen_t)
@@ -100,54 +110,92 @@ fn bind(addr: &CString, ty: libc::c_int) -> IoResult<Inner> {
 
 pub struct UnixStream {
     inner: UnsafeArc<Inner>,
+    read_deadline: u64,
+    write_deadline: u64,
 }
 
 impl UnixStream {
     pub fn connect(addr: &CString,
                    timeout: Option<u64>) -> IoResult<UnixStream> {
         connect(addr, libc::SOCK_STREAM, timeout).map(|inner| {
-            UnixStream { inner: UnsafeArc::new(inner) }
+            UnixStream::new(UnsafeArc::new(inner))
         })
     }
 
+    fn new(inner: UnsafeArc<Inner>) -> UnixStream {
+        UnixStream {
+            inner: inner,
+            read_deadline: 0,
+            write_deadline: 0,
+        }
+    }
+
     fn fd(&self) -> fd_t { unsafe { (*self.inner.get()).fd } }
+
+    #[cfg(target_os = "linux")]
+    fn lock_nonblocking(&self) {}
+
+    #[cfg(not(target_os = "linux"))]
+    fn lock_nonblocking<'a>(&'a self) -> net::Guard<'a> {
+        let ret = net::Guard {
+            fd: self.fd(),
+            guard: unsafe { (*self.inner.get()).lock.lock() },
+        };
+        assert!(util::set_nonblocking(self.fd(), true).is_ok());
+        ret
+    }
 }
 
 impl rtio::RtioPipe for UnixStream {
     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
-        let ret = retry(|| unsafe {
-            libc::recv(self.fd(),
-                       buf.as_ptr() as *mut libc::c_void,
+        let fd = self.fd();
+        let dolock = || self.lock_nonblocking();
+        let doread = |nb| unsafe {
+            let flags = if nb {c::MSG_DONTWAIT} else {0};
+            libc::recv(fd,
+                       buf.as_mut_ptr() as *mut libc::c_void,
                        buf.len() as libc::size_t,
-                       0) as libc::c_int
-        });
-        if ret == 0 {
-            Err(io::standard_error(io::EndOfFile))
-        } else if ret < 0 {
-            Err(super::last_error())
-        } else {
-            Ok(ret as uint)
-        }
+                       flags) as libc::c_int
+        };
+        net::read(fd, self.read_deadline, dolock, doread)
     }
 
     fn write(&mut self, buf: &[u8]) -> IoResult<()> {
-        let ret = keep_going(buf, |buf, len| unsafe {
-            libc::send(self.fd(),
+        let fd = self.fd();
+        let dolock = || self.lock_nonblocking();
+        let dowrite = |nb: bool, buf: *u8, len: uint| unsafe {
+            let flags = if nb {c::MSG_DONTWAIT} else {0};
+            libc::send(fd,
                        buf as *mut libc::c_void,
                        len as libc::size_t,
-                       0) as i64
-        });
-        if ret < 0 {
-            Err(super::last_error())
-        } else {
-            Ok(())
+                       flags) as i64
+        };
+        match net::write(fd, self.write_deadline, buf, true, dolock, dowrite) {
+            Ok(_) => Ok(()),
+            Err(e) => Err(e)
         }
     }
 
     fn clone(&self) -> Box<rtio::RtioPipe:Send> {
-        box UnixStream {
-            inner: self.inner.clone(),
-        } as Box<rtio::RtioPipe:Send>
+        box UnixStream::new(self.inner.clone()) as Box<rtio::RtioPipe:Send>
+    }
+
+    fn close_write(&mut self) -> IoResult<()> {
+        super::mkerr_libc(unsafe { libc::shutdown(self.fd(), libc::SHUT_WR) })
+    }
+    fn close_read(&mut self) -> IoResult<()> {
+        super::mkerr_libc(unsafe { libc::shutdown(self.fd(), libc::SHUT_RD) })
+    }
+    fn set_timeout(&mut self, timeout: Option<u64>) {
+        let deadline = timeout.map(|a| ::io::timer::now() + a).unwrap_or(0);
+        self.read_deadline = deadline;
+        self.write_deadline = deadline;
+    }
+    fn set_read_timeout(&mut self, timeout: Option<u64>) {
+        self.read_deadline = timeout.map(|a| ::io::timer::now() + a).unwrap_or(0);
+    }
+    fn set_write_timeout(&mut self, timeout: Option<u64>) {
+        self.write_deadline = timeout.map(|a| ::io::timer::now() + a).unwrap_or(0);
     }
 }
 
@@ -195,7 +243,7 @@ fn fd(&self) -> fd_t { self.listener.fd() }
 
     pub fn native_accept(&mut self) -> IoResult<UnixStream> {
         if self.deadline != 0 {
-            try!(util::accept_deadline(self.fd(), self.deadline));
+            try!(util::await(self.fd(), Some(self.deadline), util::Readable));
         }
         let mut storage: libc::sockaddr_storage = unsafe { intrinsics::init() };
         let storagep = &mut storage as *mut libc::sockaddr_storage;
@@ -207,7 +255,7 @@ pub fn native_accept(&mut self) -> IoResult<UnixStream> {
                          &mut size as *mut libc::socklen_t) as libc::c_int
         }) {
             -1 => Err(super::last_error()),
-            fd => Ok(UnixStream { inner: UnsafeArc::new(Inner { fd: fd }) })
+            fd => Ok(UnixStream::new(UnsafeArc::new(Inner::new(fd))))
         }
     }
 }
index f1239285434faa8bb36af080050d20cc3bf98d21..af80c7174f21cba3c3c413ee2ca41dc1e85c9b47 100644 (file)
 //! the test suite passing (the suite is in libstd), and that's good enough for
 //! me!
 
-use std::c_str::CString;
 use libc;
+use std::c_str::CString;
+use std::intrinsics;
+use std::io;
 use std::os::win32::as_utf16_p;
+use std::os;
 use std::ptr;
 use std::rt::rtio;
 use std::sync::arc::UnsafeArc;
-use std::intrinsics;
+use std::sync::atomics;
+use std::unstable::mutex;
 
 use super::IoResult;
 use super::c;
@@ -124,6 +128,20 @@ fn drop(&mut self) {
 
 struct Inner {
     handle: libc::HANDLE,
+    lock: mutex::NativeMutex,
+    read_closed: atomics::AtomicBool,
+    write_closed: atomics::AtomicBool,
+}
+
+impl Inner {
+    fn new(handle: libc::HANDLE) -> Inner {
+        Inner {
+            handle: handle,
+            lock: unsafe { mutex::NativeMutex::new() },
+            read_closed: atomics::AtomicBool::new(false),
+            write_closed: atomics::AtomicBool::new(false),
+        }
+    }
 }
 
 impl Drop for Inner {
@@ -151,6 +169,27 @@ unsafe fn pipe(name: *u16, init: bool) -> libc::HANDLE {
     )
 }
 
+pub fn await(handle: libc::HANDLE, deadline: u64,
+             overlapped: &mut libc::OVERLAPPED) -> bool {
+    if deadline == 0 { return true }
+
+    // If we've got a timeout, use WaitForSingleObject in tandem with CancelIo
+    // to figure out if we should indeed get the result.
+    let now = ::io::timer::now();
+    let timeout = deadline < now || unsafe {
+        let ms = (deadline - now) as libc::DWORD;
+        let r = libc::WaitForSingleObject(overlapped.hEvent,
+                                          ms);
+        r != libc::WAIT_OBJECT_0
+    };
+    if timeout {
+        unsafe { let _ = c::CancelIo(handle); }
+        false
+    } else {
+        true
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Unix Streams
 ////////////////////////////////////////////////////////////////////////////////
@@ -159,6 +198,8 @@ pub struct UnixStream {
     inner: UnsafeArc<Inner>,
     write: Option<Event>,
     read: Option<Event>,
+    read_deadline: u64,
+    write_deadline: u64,
 }
 
 impl UnixStream {
@@ -218,7 +259,7 @@ pub fn connect(addr: &CString, timeout: Option<u64>) -> IoResult<UnixStream> {
             loop {
                 match UnixStream::try_connect(p) {
                     Some(handle) => {
-                        let inner = Inner { handle: handle };
+                        let inner = Inner::new(handle);
                         let mut mode = libc::PIPE_TYPE_BYTE |
                                        libc::PIPE_READMODE_BYTE |
                                        libc::PIPE_WAIT;
@@ -235,6 +276,8 @@ pub fn connect(addr: &CString, timeout: Option<u64>) -> IoResult<UnixStream> {
                                 inner: UnsafeArc::new(inner),
                                 read: None,
                                 write: None,
+                                read_deadline: 0,
+                                write_deadline: 0,
                             })
                         }
                     }
@@ -275,6 +318,24 @@ pub fn connect(addr: &CString, timeout: Option<u64>) -> IoResult<UnixStream> {
     }
 
     fn handle(&self) -> libc::HANDLE { unsafe { (*self.inner.get()).handle } }
+
+    fn read_closed(&self) -> bool {
+        unsafe { (*self.inner.get()).read_closed.load(atomics::SeqCst) }
+    }
+
+    fn write_closed(&self) -> bool {
+        unsafe { (*self.inner.get()).write_closed.load(atomics::SeqCst) }
+    }
+
+    fn cancel_io(&self) -> IoResult<()> {
+        match unsafe { c::CancelIoEx(self.handle(), ptr::mut_null()) } {
+            0 if os::errno() == libc::ERROR_NOT_FOUND as uint => {
+                Ok(())
+            }
+            0 => Err(super::last_error()),
+            _ => Ok(())
+        }
+    }
 }
 
 impl rtio::RtioPipe for UnixStream {
@@ -287,6 +348,18 @@ fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
         let mut overlapped: libc::OVERLAPPED = unsafe { intrinsics::init() };
         overlapped.hEvent = self.read.get_ref().handle();
 
+        // Pre-flight check to see if the reading half has been closed. This
+        // must be done before issuing the ReadFile request, but after we
+        // acquire the lock.
+        //
+        // See comments in close_read() about why this lock is necessary.
+        let guard = unsafe { (*self.inner.get()).lock.lock() };
+        if self.read_closed() {
+            return Err(io::standard_error(io::EndOfFile))
+        }
+
+        // Issue a nonblocking requests, succeeding quickly if it happened to
+        // succeed.
         let ret = unsafe {
             libc::ReadFile(self.handle(),
                            buf.as_ptr() as libc::LPVOID,
@@ -294,24 +367,48 @@ fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
                            &mut bytes_read,
                            &mut overlapped)
         };
-        if ret == 0 {
-            let err = unsafe { libc::GetLastError() };
-            if err == libc::ERROR_IO_PENDING as libc::DWORD {
-                let ret = unsafe {
-                    libc::GetOverlappedResult(self.handle(),
-                                              &mut overlapped,
-                                              &mut bytes_read,
-                                              libc::TRUE)
-                };
-                if ret == 0 {
-                    return Err(super::last_error())
-                }
-            } else {
+        if ret != 0 { return Ok(bytes_read as uint) }
+
+        // If our errno doesn't say that the I/O is pending, then we hit some
+        // legitimate error and reeturn immediately.
+        if os::errno() != libc::ERROR_IO_PENDING as uint {
+            return Err(super::last_error())
+        }
+
+        // Now that we've issued a successful nonblocking request, we need to
+        // wait for it to finish. This can all be done outside the lock because
+        // we'll see any invocation of CancelIoEx. We also call this in a loop
+        // because we're woken up if the writing half is closed, we just need to
+        // realize that the reading half wasn't closed and we go right back to
+        // sleep.
+        drop(guard);
+        loop {
+            // Process a timeout if one is pending
+            let succeeded = await(self.handle(), self.read_deadline,
+                                  &mut overlapped);
+
+            let ret = unsafe {
+                libc::GetOverlappedResult(self.handle(),
+                                          &mut overlapped,
+                                          &mut bytes_read,
+                                          libc::TRUE)
+            };
+            // If we succeeded, or we failed for some reason other than
+            // CancelIoEx, return immediately
+            if ret != 0 { return Ok(bytes_read as uint) }
+            if os::errno() != libc::ERROR_OPERATION_ABORTED as uint {
                 return Err(super::last_error())
             }
-        }
 
-        Ok(bytes_read as uint)
+            // If the reading half is now closed, then we're done. If we woke up
+            // because the writing half was closed, keep trying.
+            if !succeeded {
+                return Err(io::standard_error(io::TimedOut))
+            }
+            if self.read_closed() {
+                return Err(io::standard_error(io::EndOfFile))
+            }
+        }
     }
 
     fn write(&mut self, buf: &[u8]) -> IoResult<()> {
@@ -325,6 +422,17 @@ fn write(&mut self, buf: &[u8]) -> IoResult<()> {
 
         while offset < buf.len() {
             let mut bytes_written = 0;
+
+            // This sequence below is quite similar to the one found in read().
+            // Some careful looping is done to ensure that if close_write() is
+            // invoked we bail out early, and if close_read() is invoked we keep
+            // going after we woke up.
+            //
+            // See comments in close_read() about why this lock is necessary.
+            let guard = unsafe { (*self.inner.get()).lock.lock() };
+            if self.write_closed() {
+                return Err(io::standard_error(io::BrokenPipe))
+            }
             let ret = unsafe {
                 libc::WriteFile(self.handle(),
                                 buf.slice_from(offset).as_ptr() as libc::LPVOID,
@@ -332,20 +440,45 @@ fn write(&mut self, buf: &[u8]) -> IoResult<()> {
                                 &mut bytes_written,
                                 &mut overlapped)
             };
+            let err = os::errno();
+            drop(guard);
+
             if ret == 0 {
-                let err = unsafe { libc::GetLastError() };
-                if err == libc::ERROR_IO_PENDING as libc::DWORD {
-                    let ret = unsafe {
-                        libc::GetOverlappedResult(self.handle(),
-                                                  &mut overlapped,
-                                                  &mut bytes_written,
-                                                  libc::TRUE)
-                    };
-                    if ret == 0 {
+                if err != libc::ERROR_IO_PENDING as uint {
+                    return Err(io::IoError::from_errno(err, true));
+                }
+                // Process a timeout if one is pending
+                let succeeded = await(self.handle(), self.write_deadline,
+                                      &mut overlapped);
+                let ret = unsafe {
+                    libc::GetOverlappedResult(self.handle(),
+                                              &mut overlapped,
+                                              &mut bytes_written,
+                                              libc::TRUE)
+                };
+                // If we weren't aborted, this was a legit error, if we were
+                // aborted, then check to see if the write half was actually
+                // closed or whether we woke up from the read half closing.
+                if ret == 0 {
+                    if os::errno() != libc::ERROR_OPERATION_ABORTED as uint {
                         return Err(super::last_error())
                     }
-                } else {
-                    return Err(super::last_error())
+                    if !succeeded {
+                        let amt = offset + bytes_written as uint;
+                        return if amt > 0 {
+                            Err(io::IoError {
+                                kind: io::ShortWrite(amt),
+                                desc: "short write during write",
+                                detail: None,
+                            })
+                        } else {
+                            Err(util::timeout("write timed out"))
+                        }
+                    }
+                    if self.write_closed() {
+                        return Err(io::standard_error(io::BrokenPipe))
+                    }
+                    continue // retry
                 }
             }
             offset += bytes_written as uint;
@@ -358,8 +491,52 @@ fn clone(&self) -> Box<rtio::RtioPipe:Send> {
             inner: self.inner.clone(),
             read: None,
             write: None,
+            read_deadline: 0,
+            write_deadline: 0,
         } as Box<rtio::RtioPipe:Send>
     }
+
+    fn close_read(&mut self) -> IoResult<()> {
+        // On windows, there's no actual shutdown() method for pipes, so we're
+        // forced to emulate the behavior manually at the application level. To
+        // do this, we need to both cancel any pending requests, as well as
+        // prevent all future requests from succeeding. These two operations are
+        // not atomic with respect to one another, so we must use a lock to do
+        // so.
+        //
+        // The read() code looks like:
+        //
+        //      1. Make sure the pipe is still open
+        //      2. Submit a read request
+        //      3. Wait for the read request to finish
+        //
+        // The race this lock is preventing is if another thread invokes
+        // close_read() between steps 1 and 2. By atomically executing steps 1
+        // and 2 with a lock with respect to close_read(), we're guaranteed that
+        // no thread will erroneously sit in a read forever.
+        let _guard = unsafe { (*self.inner.get()).lock.lock() };
+        unsafe { (*self.inner.get()).read_closed.store(true, atomics::SeqCst) }
+        self.cancel_io()
+    }
+
+    fn close_write(&mut self) -> IoResult<()> {
+        // see comments in close_read() for why this lock is necessary
+        let _guard = unsafe { (*self.inner.get()).lock.lock() };
+        unsafe { (*self.inner.get()).write_closed.store(true, atomics::SeqCst) }
+        self.cancel_io()
+    }
+
+    fn set_timeout(&mut self, timeout: Option<u64>) {
+        let deadline = timeout.map(|a| ::io::timer::now() + a).unwrap_or(0);
+        self.read_deadline = deadline;
+        self.write_deadline = deadline;
+    }
+    fn set_read_timeout(&mut self, timeout: Option<u64>) {
+        self.read_deadline = timeout.map(|a| ::io::timer::now() + a).unwrap_or(0);
+    }
+    fn set_write_timeout(&mut self, timeout: Option<u64>) {
+        self.write_deadline = timeout.map(|a| ::io::timer::now() + a).unwrap_or(0);
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -462,22 +639,8 @@ pub fn native_accept(&mut self) -> IoResult<UnixStream> {
             let mut err = unsafe { libc::GetLastError() };
 
             if err == libc::ERROR_IO_PENDING as libc::DWORD {
-                // If we've got a timeout, use WaitForSingleObject in tandem
-                // with CancelIo to figure out if we should indeed get the
-                // result.
-                if self.deadline != 0 {
-                    let now = ::io::timer::now();
-                    let timeout = self.deadline < now || unsafe {
-                        let ms = (self.deadline - now) as libc::DWORD;
-                        let r = libc::WaitForSingleObject(overlapped.hEvent,
-                                                          ms);
-                        r != libc::WAIT_OBJECT_0
-                    };
-                    if timeout {
-                        unsafe { let _ = c::CancelIo(handle); }
-                        return Err(util::timeout("accept timed out"))
-                    }
-                }
+                // Process a timeout if one is pending
+                let _ = await(handle, self.deadline, &mut overlapped);
 
                 // This will block until the overlapped I/O is completed. The
                 // timeout was previously handled, so this will either block in
@@ -520,9 +683,11 @@ pub fn native_accept(&mut self) -> IoResult<UnixStream> {
 
         // Transfer ownership of our handle into this stream
         Ok(UnixStream {
-            inner: UnsafeArc::new(Inner { handle: handle }),
+            inner: UnsafeArc::new(Inner::new(handle)),
             read: None,
             write: None,
+            read_deadline: 0,
+            write_deadline: 0,
         })
     }
 }
index efdab990d18223f1e73bd4daf5d7227cab089ff6..c83af20d1d84eac884ed7dd2b83372f2500f40a8 100644 (file)
@@ -67,7 +67,7 @@ impl Process {
     ///     os pipe instead. This process takes ownership of these file
     ///     descriptors, closing them upon destruction of the process.
     pub fn spawn(config: p::ProcessConfig)
-        -> Result<(Process, ~[Option<file::FileDesc>]), io::IoError>
+        -> Result<(Process, Vec<Option<file::FileDesc>>), io::IoError>
     {
         // right now we only handle stdin/stdout/stderr.
         if config.extra_io.len() > 0 {
@@ -117,7 +117,7 @@ fn get_io(io: p::StdioContainer, ret: &mut Vec<Option<file::FileDesc>>)
                         exit_code: None,
                         exit_signal: None,
                     },
-                    ret_io.move_iter().collect()))
+                    ret_io))
             }
             Err(e) => Err(e)
         }
index 0aaac8f8ad81e41b8e733caaf779c307e09d874d..0d032f9f4bcda7dd09abf9ec1712f79ad0e2371c 100644 (file)
 use std::io::IoResult;
 use std::io;
 use std::mem;
+use std::os;
 use std::ptr;
 
 use super::c;
 use super::net;
 use super::{retry, last_error};
 
+#[deriving(Show)]
+pub enum SocketStatus {
+    Readable,
+    Writable,
+}
+
 pub fn timeout(desc: &'static str) -> io::IoError {
     io::IoError {
         kind: io::TimedOut,
@@ -33,6 +40,34 @@ pub fn ms_to_timeval(ms: u64) -> libc::timeval {
     }
 }
 
+#[cfg(unix)]
+pub fn wouldblock() -> bool {
+    let err = os::errno();
+    err == libc::EWOULDBLOCK as int || err == libc::EAGAIN as int
+}
+
+#[cfg(windows)]
+pub fn wouldblock() -> bool {
+    let err = os::errno();
+    err == libc::WSAEWOULDBLOCK as uint
+}
+
+#[cfg(unix)]
+pub fn set_nonblocking(fd: net::sock_t, nb: bool) -> IoResult<()> {
+    let set = nb as libc::c_int;
+    super::mkerr_libc(retry(|| unsafe { c::ioctl(fd, c::FIONBIO, &set) }))
+}
+
+#[cfg(windows)]
+pub fn set_nonblocking(fd: net::sock_t, nb: bool) -> IoResult<()> {
+    let mut set = nb as libc::c_ulong;
+    if unsafe { c::ioctlsocket(fd, c::FIONBIO, &mut set) != 0 } {
+        Err(last_error())
+    } else {
+        Ok(())
+    }
+}
+
 // See http://developerweb.net/viewtopic.php?id=3196 for where this is
 // derived from.
 pub fn connect_timeout(fd: net::sock_t,
@@ -79,22 +114,6 @@ pub fn connect_timeout(fd: net::sock_t,
     try!(set_nonblocking(fd, false));
     return ret;
 
-    #[cfg(unix)]
-    fn set_nonblocking(fd: net::sock_t, nb: bool) -> IoResult<()> {
-        let set = nb as libc::c_int;
-        super::mkerr_libc(retry(|| unsafe { c::ioctl(fd, c::FIONBIO, &set) }))
-    }
-
-    #[cfg(windows)]
-    fn set_nonblocking(fd: net::sock_t, nb: bool) -> IoResult<()> {
-        let mut set = nb as libc::c_ulong;
-        if unsafe { c::ioctlsocket(fd, c::FIONBIO, &mut set) != 0 } {
-            Err(last_error())
-        } else {
-            Ok(())
-        }
-    }
-
     #[cfg(unix)]
     fn await(fd: net::sock_t, set: &mut c::fd_set,
              timeout: u64) -> libc::c_int {
@@ -116,21 +135,34 @@ fn await(_fd: net::sock_t, set: &mut c::fd_set,
     }
 }
 
-pub fn accept_deadline(fd: net::sock_t, deadline: u64) -> IoResult<()> {
+pub fn await(fd: net::sock_t, deadline: Option<u64>,
+             status: SocketStatus) -> IoResult<()> {
     let mut set: c::fd_set = unsafe { mem::init() };
     c::fd_set(&mut set, fd);
+    let (read, write) = match status {
+        Readable => (&set as *_, ptr::null()),
+        Writable => (ptr::null(), &set as *_),
+    };
+    let mut tv: libc::timeval = unsafe { mem::init() };
 
     match retry(|| {
-        // If we're past the deadline, then pass a 0 timeout to select() so
-        // we can poll the status of the socket.
         let now = ::io::timer::now();
-        let ms = if deadline < now {0} else {deadline - now};
-        let tv = ms_to_timeval(ms);
+        let tvp = match deadline {
+            None => ptr::null(),
+            Some(deadline) => {
+                // If we're past the deadline, then pass a 0 timeout to
+                // select() so we can poll the status
+                let ms = if deadline < now {0} else {deadline - now};
+                tv = ms_to_timeval(ms);
+                &tv as *_
+            }
+        };
         let n = if cfg!(windows) {1} else {fd as libc::c_int + 1};
-        unsafe { c::select(n, &set, ptr::null(), ptr::null(), &tv) }
+        let r = unsafe { c::select(n, read, write, ptr::null(), tvp) };
+        r
     }) {
         -1 => Err(last_error()),
-        0 => Err(timeout("accept timed out")),
-        _ => return Ok(()),
+        0 => Err(timeout("timed out")),
+        _ => Ok(()),
     }
 }
index d5a2c163a90d104da87e2ac1fdf9056e22c174b7..cb27f2f0ff82166eca0f770cb954272d48ace3f6 100644 (file)
@@ -79,7 +79,6 @@
 use std::cast;
 use std::io::IoResult;
 use std::kinds::marker;
-use std::local_data;
 use std::strbuf::StrBuf;
 
 pub use isaac::{IsaacRng, Isaac64Rng};
@@ -581,9 +580,6 @@ pub struct TaskRng {
     marker: marker::NoSend,
 }
 
-// used to make space in TLS for a random number generator
-local_data_key!(TASK_RNG_KEY: Box<TaskRngInner>)
-
 /// Retrieve the lazily-initialized task-local random number
 /// generator, seeded by the system. Intended to be used in method
 /// chaining style, e.g. `task_rng().gen::<int>()`.
@@ -596,7 +592,10 @@ pub struct TaskRng {
 /// the same sequence always. If absolute consistency is required,
 /// explicitly select an RNG, e.g. `IsaacRng` or `Isaac64Rng`.
 pub fn task_rng() -> TaskRng {
-    local_data::get_mut(TASK_RNG_KEY, |rng| match rng {
+    // used to make space in TLS for a random number generator
+    local_data_key!(TASK_RNG_KEY: Box<TaskRngInner>)
+
+    match TASK_RNG_KEY.get() {
         None => {
             let r = match StdRng::new() {
                 Ok(r) => r,
@@ -607,12 +606,15 @@ pub fn task_rng() -> TaskRng {
                                                         TaskRngReseeder);
             let ptr = &mut *rng as *mut TaskRngInner;
 
-            local_data::set(TASK_RNG_KEY, rng);
+            TASK_RNG_KEY.replace(Some(rng));
 
             TaskRng { rng: ptr, marker: marker::NoSend }
         }
-        Some(rng) => TaskRng { rng: &mut **rng, marker: marker::NoSend }
-    })
+        Some(rng) => TaskRng {
+            rng: &**rng as *_ as *mut TaskRngInner,
+            marker: marker::NoSend
+        }
+    }
 }
 
 impl Rng for TaskRng {
index ac6bb12e410bb9ef1a890aab09564a7e2677eda2..9fa3553cbfc9d8f382735219da4f0759aa6089d9 100644 (file)
@@ -536,7 +536,7 @@ pub fn crate_id_hash(crate_id: &CrateId) -> ~str {
     // the crate id in the hash because lookups are only done by (name/vers),
     // not by path.
     let mut s = Sha256::new();
-    s.input_str(crate_id.short_name_with_version());
+    s.input_str(crate_id.short_name_with_version().as_slice());
     truncated_hash_result(&mut s).slice_to(8).to_owned()
 }
 
@@ -566,7 +566,7 @@ fn symbol_hash(tcx: &ty::ctxt,
     // to be independent of one another in the crate.
 
     symbol_hasher.reset();
-    symbol_hasher.input_str(link_meta.crateid.name);
+    symbol_hasher.input_str(link_meta.crateid.name.as_slice());
     symbol_hasher.input_str("-");
     symbol_hasher.input_str(link_meta.crate_hash.as_str());
     symbol_hasher.input_str("-");
index 8c0aa494d6f80b30b9ee7cb8c2a5b280d6b3c60b..c49adce904a5199b8c8aa6fffaa3bc35f5d4d904 100644 (file)
@@ -45,9 +45,9 @@ pub fn get_rpath_flags(sess: &Session, out_filename: &Path) -> Vec<~str> {
     let libs = sess.cstore.get_used_crates(cstore::RequireDynamic);
     let libs = libs.move_iter().filter_map(|(_, l)| {
         l.map(|p| p.clone())
-    }).collect::<~[_]>();
+    }).collect::<Vec<_>>();
 
-    let rpaths = get_rpaths(os, sysroot, output, libs,
+    let rpaths = get_rpaths(os, sysroot, output, libs.as_slice(),
                             sess.opts.target_triple);
     flags.push_all(rpaths_to_flags(rpaths.as_slice()).as_slice());
     flags
index fc903db6d041ad3655b3e4671ba51dfceb4ae7e3..701117edb478330e9abdacbe5215b2de1d0fc5f2 100644 (file)
@@ -143,8 +143,8 @@ pub fn build_configuration(sess: &Session) -> ast::CrateConfig {
 fn parse_cfgspecs(cfgspecs: Vec<~str> )
                   -> ast::CrateConfig {
     cfgspecs.move_iter().map(|s| {
-        parse::parse_meta_from_source_str("cfgspec".to_str(),
-                                          s,
+        parse::parse_meta_from_source_str("cfgspec".to_strbuf(),
+                                          s.to_strbuf(),
                                           Vec::new(),
                                           &parse::new_parse_sess())
     }).collect::<ast::CrateConfig>()
@@ -175,8 +175,8 @@ pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input)
                 parse::parse_crate_from_file(&(*file), cfg.clone(), &sess.parse_sess)
             }
             StrInput(ref src) => {
-                parse::parse_crate_from_source_str(anon_src(),
-                                                   (*src).clone(),
+                parse::parse_crate_from_source_str(anon_src().to_strbuf(),
+                                                   src.to_strbuf(),
                                                    cfg.clone(),
                                                    &sess.parse_sess)
             }
@@ -528,7 +528,7 @@ fn write_out_deps(sess: &Session,
         // write Makefile-compatible dependency rules
         let files: Vec<~str> = sess.codemap().files.borrow()
                                    .iter().filter(|fmap| fmap.is_real_file())
-                                   .map(|fmap| fmap.name.clone())
+                                   .map(|fmap| fmap.name.to_owned())
                                    .collect();
         let mut file = try!(io::File::create(&deps_filename));
         for path in out_filenames.iter() {
@@ -604,20 +604,20 @@ fn post(&self,
         match node {
             pprust::NodeItem(item) => {
                 try!(pp::space(&mut s.s));
-                s.synth_comment(item.id.to_str())
+                s.synth_comment(item.id.to_str().to_strbuf())
             }
             pprust::NodeBlock(blk) => {
                 try!(pp::space(&mut s.s));
-                s.synth_comment("block ".to_owned() + blk.id.to_str())
+                s.synth_comment((format!("block {}", blk.id)).to_strbuf())
             }
             pprust::NodeExpr(expr) => {
                 try!(pp::space(&mut s.s));
-                try!(s.synth_comment(expr.id.to_str()));
+                try!(s.synth_comment(expr.id.to_str().to_strbuf()));
                 s.pclose()
             }
             pprust::NodePat(pat) => {
                 try!(pp::space(&mut s.s));
-                s.synth_comment("pat ".to_owned() + pat.id.to_str())
+                s.synth_comment((format!("pat {}", pat.id)).to_strbuf())
             }
         }
     }
@@ -692,7 +692,7 @@ pub fn pretty_print_input(sess: Session,
             pprust::print_crate(sess.codemap(),
                                 sess.diagnostic(),
                                 &krate,
-                                src_name,
+                                src_name.to_strbuf(),
                                 &mut rdr,
                                 out,
                                 &IdentifiedAnnotation,
@@ -707,7 +707,7 @@ pub fn pretty_print_input(sess: Session,
             pprust::print_crate(annotation.analysis.ty_cx.sess.codemap(),
                                 annotation.analysis.ty_cx.sess.diagnostic(),
                                 &krate,
-                                src_name,
+                                src_name.to_strbuf(),
                                 &mut rdr,
                                 out,
                                 &annotation,
@@ -717,7 +717,7 @@ pub fn pretty_print_input(sess: Session,
             pprust::print_crate(sess.codemap(),
                                 sess.diagnostic(),
                                 &krate,
-                                src_name,
+                                src_name.to_strbuf(),
                                 &mut rdr,
                                 out,
                                 &pprust::NoAnn,
index 285a977ad6e265ced48abd9b583847b6b73c8a0a..859647b1beb47c7d8bcf827351450cdc52489d6b 100644 (file)
@@ -471,7 +471,8 @@ fn parse_list(slot: &mut Vec<~str>, v: Option<&str>)
 )
 
 // Seems out of place, but it uses session, so I'm putting it here
-pub fn expect<T:Clone>(sess: &Session, opt: Option<T>, msg: || -> ~str) -> T {
+pub fn expect<T:Clone>(sess: &Session, opt: Option<T>, msg: || -> StrBuf)
+              -> T {
     diagnostic::expect(sess.diagnostic(), opt, msg)
 }
 
index d7f4173b529c4164ea5445ccb28f44a3a883b49b..eaf6527ea829b9264852a17a56d20c98024e2dfd 100644 (file)
@@ -168,7 +168,7 @@ fn generate_test_harness(sess: &Session, krate: ast::Crate)
     cx.ext_cx.bt_push(ExpnInfo {
         call_site: DUMMY_SP,
         callee: NameAndSpan {
-            name: "test".to_owned(),
+            name: "test".to_strbuf(),
             format: MacroAttribute,
             span: None
         }
@@ -282,7 +282,7 @@ mod __test {
   #![!resolve_unexported]
   extern crate test (name = "test", vers = "...");
   fn main() {
-    test::test_main_static(::os::args(), tests)
+    test::test_main_static(::os::args().as_slice(), tests)
   }
 
   static tests : &'static [test::TestDescAndFn] = &[
@@ -326,8 +326,8 @@ fn mk_test_module(cx: &TestCtxt) -> @ast::Item {
     let mainfn = (quote_item!(&cx.ext_cx,
         pub fn main() {
             #![main]
-            #![allow(deprecated_owned_vector)]
-            test::test_main_static(::std::os::args(), TESTS);
+            use std::slice::Vector;
+            test::test_main_static(::std::os::args().as_slice(), TESTS);
         }
     )).unwrap();
 
@@ -398,7 +398,7 @@ fn mk_tests(cx: &TestCtxt) -> @ast::Item {
 
 fn is_test_crate(krate: &ast::Crate) -> bool {
     match attr::find_crateid(krate.attrs.as_slice()) {
-        Some(ref s) if "test" == s.name => true,
+        Some(ref s) if "test" == s.name.as_slice() => true,
         _ => false
     }
 }
@@ -427,7 +427,7 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> @ast::Expr {
 
     let name_lit: ast::Lit =
         nospan(ast::LitStr(token::intern_and_get_ident(
-                    ast_util::path_name_i(path.as_slice())),
+                    ast_util::path_name_i(path.as_slice()).as_slice()),
                     ast::CookedStr));
 
     let name_expr = @ast::Expr {
index 2dca3ff3c7a43bb4b8992d56a7725ecb49f02ce6..0962acd0a2ebf23acf34db153c955d69e708e15e 100644 (file)
@@ -352,10 +352,11 @@ fn parse_crate_attrs(sess: &session::Session, input: &d::Input) ->
                                                &sess.parse_sess)
         }
         d::StrInput(ref src) => {
-            parse::parse_crate_attrs_from_source_str(d::anon_src(),
-                                                     (*src).clone(),
-                                                     Vec::new(),
-                                                     &sess.parse_sess)
+            parse::parse_crate_attrs_from_source_str(
+                d::anon_src().to_strbuf(),
+                src.to_strbuf(),
+                Vec::new(),
+                &sess.parse_sess)
         }
     };
     result.move_iter().collect()
@@ -433,7 +434,7 @@ pub fn monitor(f: proc():Send) {
 }
 
 pub fn main() {
-    std::os::set_exit_status(main_args(std::os::args()));
+    std::os::set_exit_status(main_args(std::os::args().as_slice()));
 }
 
 pub fn main_args(args: &[~str]) -> int {
index 916d2a6f07ca28f27517651b37989b95e85ce640..a5675f52671feb011c036fcf6298118c5888478f 100644 (file)
@@ -428,11 +428,11 @@ fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate {
         };
         let macros = decoder::get_exported_macros(library.metadata.as_slice());
         let registrar = decoder::get_macro_registrar_fn(library.metadata.as_slice()).map(|id| {
-            decoder::get_symbol(library.metadata.as_slice(), id)
+            decoder::get_symbol(library.metadata.as_slice(), id).to_strbuf()
         });
         let mc = MacroCrate {
             lib: library.dylib.clone(),
-            macros: macros.move_iter().collect(),
+            macros: macros.move_iter().map(|x| x.to_strbuf()).collect(),
             registrar_symbol: registrar,
         };
         if should_link {
index ea764f132b72dd8c02b03127e870a062476a4c70..5906312b51523ea371ab0ff59784a4a421c8f757 100644 (file)
@@ -207,12 +207,17 @@ pub fn get_field_type(tcx: &ty::ctxt, class_id: ast::DefId,
     let all_items = reader::get_doc(reader::Doc(cdata.data()), tag_items);
     let class_doc = expect(tcx.sess.diagnostic(),
                            decoder::maybe_find_item(class_id.node, all_items),
-                           || format!("get_field_type: class ID {:?} not found",
-                                   class_id) );
+                           || {
+        (format!("get_field_type: class ID {:?} not found",
+                 class_id)).to_strbuf()
+    });
     let the_field = expect(tcx.sess.diagnostic(),
         decoder::maybe_find_item(def.node, class_doc),
-        || format!("get_field_type: in class {:?}, field ID {:?} not found",
-                 class_id, def) );
+        || {
+            (format!("get_field_type: in class {:?}, field ID {:?} not found",
+                    class_id,
+                    def)).to_strbuf()
+        });
     let ty = decoder::item_type(def, the_field, tcx, &*cdata);
     ty::ty_param_bounds_and_ty {
         generics: ty::Generics {type_param_defs: Rc::new(Vec::new()),
index 302bba2f56b6c3eac2bec66725084c5c8791a42a..39700f91b5fed5be65b4927408f82f3dd7fb5144 100644 (file)
@@ -110,7 +110,6 @@ enum Family {
     UnsafeFn,              // u
     StaticMethod,          // F
     UnsafeStaticMethod,    // U
-    ForeignFn,             // e
     Type,                  // y
     ForeignType,           // T
     Mod,                   // m
@@ -134,7 +133,6 @@ fn item_family(item: ebml::Doc) -> Family {
       'u' => UnsafeFn,
       'F' => StaticMethod,
       'U' => UnsafeStaticMethod,
-      'e' => ForeignFn,
       'y' => Type,
       'T' => ForeignType,
       'm' => Mod,
@@ -339,7 +337,6 @@ fn item_to_def_like(item: ebml::Doc, did: ast::DefId, cnum: ast::CrateNum)
         Struct    => DlDef(ast::DefStruct(did)),
         UnsafeFn  => DlDef(ast::DefFn(did, ast::UnsafeFn)),
         Fn        => DlDef(ast::DefFn(did, ast::NormalFn)),
-        ForeignFn => DlDef(ast::DefFn(did, ast::ExternFn)),
         StaticMethod | UnsafeStaticMethod => {
             let fn_style = if fam == UnsafeStaticMethod { ast::UnsafeFn } else
                 { ast::NormalFn };
index 684745daa3cfae95137c304a59a43cd143ec23b1..5faae72791d7e784bd20c5027d90839d5258b987 100644 (file)
@@ -788,7 +788,6 @@ fn style_fn_family(s: FnStyle) -> char {
     match s {
         UnsafeFn => 'u',
         NormalFn => 'f',
-        ExternFn => 'e'
     }
 }
 
@@ -796,7 +795,6 @@ fn fn_style_static_method_family(s: FnStyle) -> char {
     match s {
         UnsafeFn => 'U',
         NormalFn => 'F',
-        _ => fail!("extern fn can't be static")
     }
 }
 
@@ -1565,7 +1563,7 @@ fn visit_item(&mut self, item: &Item, _: ()) {
                 let def = self.ecx.tcx.sess.codemap().span_to_snippet(item.span)
                     .expect("Unable to find source for macro");
                 self.ebml_w.start_tag(tag_macro_def);
-                self.ebml_w.wr_str(def);
+                self.ebml_w.wr_str(def.as_slice());
                 self.ebml_w.end_tag();
             }
             _ => {}
index d0501c01aae50bf0498d8fc8ecd46f3ff63cdfb2..76621cfd09f84c3a9d086255d099607ebd8af127 100644 (file)
@@ -441,7 +441,6 @@ fn parse_fn_style(c: char) -> FnStyle {
     match c {
         'u' => UnsafeFn,
         'n' => NormalFn,
-        'c' => ExternFn,
         _ => fail!("parse_fn_style: bad fn_style {}", c)
     }
 }
index 900fba831d9c187e32fcd89d2e730c2a0f9d3d75..fd41d219b417a320c40ded7cb13945b17bea63e4 100644 (file)
@@ -298,7 +298,6 @@ fn enc_fn_style(w: &mut MemWriter, p: FnStyle) {
     match p {
         NormalFn => mywrite!(w, "n"),
         UnsafeFn => mywrite!(w, "u"),
-        ExternFn => mywrite!(w, "c")
     }
 }
 
index 169a7d32032bc81d8b75c4157b006df261ef87bd..48c6d2a53d756b181c1891854d4581fc43c11bbe 100644 (file)
@@ -112,8 +112,8 @@ fn pre(&self,
                 "".to_owned()
             };
 
-            try!(ps.synth_comment(format!("id {}: {}{}{}", id, entry_str,
-                                          gens_str, kills_str)));
+            try!(ps.synth_comment((format!("id {}: {}{}{}", id, entry_str,
+                                          gens_str, kills_str)).to_strbuf()));
             try!(pp::space(&mut ps.s));
         }
         Ok(())
index 402fe822661541bebac03d98a1fa5be26e777128..e63711f0a575a2b10e4806106ec3f5e81f6b1921 100644 (file)
@@ -569,7 +569,7 @@ fn check_sized(tcx: &ty::ctxt, ty: ty::t, name: ~str, sp: Span) {
 fn check_pat(cx: &mut Context, pat: &Pat) {
     let var_name = match pat.node {
         PatWild => Some("_".to_owned()),
-        PatIdent(_, ref path, _) => Some(path_to_str(path)),
+        PatIdent(_, ref path, _) => Some(path_to_str(path).to_owned()),
         _ => None
     };
 
index 6d79fe1f3be0fd87d4f45ec3dc3c4d4e894aad29..a08028f374283839a963382e19f5ef730620f9d5 100644 (file)
@@ -357,7 +357,7 @@ enum FieldName {
 impl<'a> PrivacyVisitor<'a> {
     // used when debugging
     fn nodestr(&self, id: ast::NodeId) -> ~str {
-        self.tcx.map.node_to_str(id)
+        self.tcx.map.node_to_str(id).to_owned()
     }
 
     // Determines whether the given definition is public from the point of view
index bb7a5d2a24d2ea91f222e2a6c8c158804e00e4fb..7dad6473478c13250ac705f660c9055fe46fb047 100644 (file)
@@ -22,6 +22,7 @@
 use util::nodemap::NodeSet;
 
 use collections::HashSet;
+use syntax::abi;
 use syntax::ast;
 use syntax::ast_map;
 use syntax::ast_util::{def_id_of_def, is_local};
@@ -250,8 +251,10 @@ fn propagate_node(&mut self, node: &ast_map::Node,
             match *node {
                 ast_map::NodeItem(item) => {
                     match item.node {
-                        ast::ItemFn(_, ast::ExternFn, _, _, _) => {
-                            self.reachable_symbols.insert(search_item);
+                        ast::ItemFn(_, _, abi, _, _) => {
+                            if abi != abi::Rust {
+                                self.reachable_symbols.insert(search_item);
+                            }
                         }
                         _ => {}
                     }
index 95f18b75bec4ac1eef70a2667c960143bfe63398..1abdca7cb9f7b560489c5e27ce93770864613e55 100644 (file)
@@ -1620,18 +1620,20 @@ fn handle_external_def(&mut self,
 
         match def {
           DefMod(_) | DefForeignMod(_) => {}
-          DefVariant(_, variant_id, is_struct) => {
+          DefVariant(enum_did, variant_id, is_struct) => {
             debug!("(building reduced graph for external crate) building \
                     variant {}",
                    final_ident);
-            // We assume the parent is visible, or else we wouldn't have seen
-            // it. Also variants are public-by-default if the parent was also
-            // public.
+            // If this variant is public, then it was publicly reexported,
+            // otherwise we need to inherit the visibility of the enum
+            // definition.
+            let is_exported = is_public ||
+                              self.external_exports.contains(&enum_did);
             if is_struct {
-                child_name_bindings.define_type(def, DUMMY_SP, true);
+                child_name_bindings.define_type(def, DUMMY_SP, is_exported);
                 self.structs.insert(variant_id);
             } else {
-                child_name_bindings.define_value(def, DUMMY_SP, true);
+                child_name_bindings.define_value(def, DUMMY_SP, is_exported);
             }
           }
           DefFn(..) | DefStaticMethod(..) | DefStatic(..) => {
@@ -3167,12 +3169,12 @@ fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
                          .codemap()
                          .span_to_snippet(imports.get(index).span)
                          .unwrap();
-            if sn.contains("::") {
+            if sn.as_slice().contains("::") {
                 self.resolve_error(imports.get(index).span,
                                    "unresolved import");
             } else {
                 let err = format!("unresolved import (maybe you meant `{}::*`?)",
-                               sn.slice(0, sn.len()));
+                                  sn.as_slice().slice(0, sn.len()));
                 self.resolve_error(imports.get(index).span, err);
             }
         }
index c002c47d35dba644d7507af5afebc7c3b6b015de..400aa83a615143a04092b8c38428290c468c947c 100644 (file)
@@ -74,7 +74,6 @@
 use libc::c_uint;
 use std::c_str::ToCStr;
 use std::cell::{Cell, RefCell};
-use std::local_data;
 use std::rc::Rc;
 use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic};
 use syntax::ast_util::{local_def, is_local};
 
 use time;
 
-local_data_key!(task_local_insn_key: Vec<&'static str> )
+local_data_key!(task_local_insn_key: RefCell<Vec<&'static str>>)
 
 pub fn with_insn_ctxt(blk: |&[&'static str]|) {
-    local_data::get(task_local_insn_key, |c| {
-        match c {
-            Some(ctx) => blk(ctx.as_slice()),
-            None => ()
-        }
-    })
+    match task_local_insn_key.get() {
+        Some(ctx) => blk(ctx.borrow().as_slice()),
+        None => ()
+    }
 }
 
 pub fn init_insn_ctxt() {
-    local_data::set(task_local_insn_key, Vec::new());
+    task_local_insn_key.replace(Some(RefCell::new(Vec::new())));
 }
 
 pub struct _InsnCtxt { _x: () }
@@ -108,23 +105,19 @@ pub struct _InsnCtxt { _x: () }
 #[unsafe_destructor]
 impl Drop for _InsnCtxt {
     fn drop(&mut self) {
-        local_data::modify(task_local_insn_key, |c| {
-            c.map(|mut ctx| {
-                ctx.pop();
-                ctx
-            })
-        })
+        match task_local_insn_key.get() {
+            Some(ctx) => { ctx.borrow_mut().pop(); }
+            None => {}
+        }
     }
 }
 
 pub fn push_ctxt(s: &'static str) -> _InsnCtxt {
     debug!("new InsnCtxt: {}", s);
-    local_data::modify(task_local_insn_key, |c| {
-        c.map(|mut ctx| {
-            ctx.push(s);
-            ctx
-        })
-    });
+    match task_local_insn_key.get() {
+        Some(ctx) => ctx.borrow_mut().push(s),
+        None => {}
+    }
     _InsnCtxt { _x: () }
 }
 
@@ -233,7 +226,8 @@ fn get_extern_rust_fn(ccx: &CrateContext, inputs: &[ty::t], output: ty::t,
 
     let f = decl_rust_fn(ccx, false, inputs, output, name);
     csearch::get_item_attrs(&ccx.sess().cstore, did, |meta_items| {
-        set_llvm_fn_attrs(meta_items.iter().map(|&x| attr::mk_attr(x)).collect::<~[_]>(), f)
+        set_llvm_fn_attrs(meta_items.iter().map(|&x| attr::mk_attr(x))
+                                    .collect::<Vec<_>>().as_slice(), f)
     });
 
     ccx.externs.borrow_mut().insert(name.to_owned(), f);
@@ -1152,7 +1146,11 @@ pub fn new_fn_ctxt<'a>(ccx: &'a CrateContext,
     for p in param_substs.iter() { p.validate(); }
 
     debug!("new_fn_ctxt(path={}, id={}, param_substs={})",
-           if id == -1 { "".to_owned() } else { ccx.tcx.map.path_to_str(id) },
+           if id == -1 {
+               "".to_owned()
+           } else {
+               ccx.tcx.map.path_to_str(id).to_owned()
+           },
            id, param_substs.map(|s| s.repr(ccx.tcx())));
 
     let substd_output_type = match param_substs {
@@ -1465,7 +1463,7 @@ pub fn trans_fn(ccx: &CrateContext,
                 param_substs: Option<&param_substs>,
                 id: ast::NodeId,
                 attrs: &[ast::Attribute]) {
-    let _s = StatRecorder::new(ccx, ccx.tcx.map.path_to_str(id));
+    let _s = StatRecorder::new(ccx, ccx.tcx.map.path_to_str(id).to_owned());
     debug!("trans_fn(param_substs={})", param_substs.map(|s| s.repr(ccx.tcx())));
     let _icx = push_ctxt("trans_fn");
     let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx(), id));
@@ -1594,8 +1592,8 @@ fn visit_item(&mut self, i: &ast::Item, _:()) {
 pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
     let _icx = push_ctxt("trans_item");
     match item.node {
-      ast::ItemFn(decl, fn_style, _abi, ref generics, body) => {
-        if fn_style == ast::ExternFn  {
+      ast::ItemFn(decl, _fn_style, abi, ref generics, body) => {
+        if abi != Rust  {
             let llfndecl = get_item_val(ccx, item.id);
             foreign::trans_rust_fn_with_foreign_abi(
                 ccx, decl, body, item.attrs.as_slice(), llfndecl, item.id);
@@ -1939,8 +1937,8 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
                     }
                 }
 
-                ast::ItemFn(_, fn_style, _, _, _) => {
-                    let llfn = if fn_style != ast::ExternFn {
+                ast::ItemFn(_, _, abi, _, _) => {
+                    let llfn = if abi == Rust {
                         register_fn(ccx, i.span, sym, i.id, ty)
                     } else {
                         foreign::register_rust_fn_with_foreign_abi(ccx,
@@ -2112,12 +2110,12 @@ pub fn write_metadata(cx: &CrateContext, krate: &ast::Crate) -> Vec<u8> {
 
     let encode_parms = crate_ctxt_to_encode_parms(cx, encode_inlined_item);
     let metadata = encoder::encode_metadata(encode_parms, krate);
-    let compressed = encoder::metadata_encoding_version +
-                        match flate::deflate_bytes(metadata.as_slice()) {
-                            Some(compressed) => compressed,
-                            None => cx.sess().fatal(format!("failed to compress metadata", ))
-                        }.as_slice();
-    let llmeta = C_bytes(cx, compressed);
+    let compressed = Vec::from_slice(encoder::metadata_encoding_version)
+                     .append(match flate::deflate_bytes(metadata.as_slice()) {
+                         Some(compressed) => compressed,
+                         None => cx.sess().fatal(format!("failed to compress metadata"))
+                     }.as_slice());
+    let llmeta = C_bytes(cx, compressed.as_slice());
     let llconst = C_struct(cx, [llmeta], false);
     let name = format!("rust_metadata_{}_{}_{}", cx.link_meta.crateid.name,
                        cx.link_meta.crateid.version_or_default(), cx.link_meta.crate_hash);
@@ -2168,9 +2166,10 @@ pub fn trans_crate(krate: ast::Crate,
     // crashes if the module identifer is same as other symbols
     // such as a function name in the module.
     // 1. http://llvm.org/bugs/show_bug.cgi?id=11479
-    let llmod_id = link_meta.crateid.name + ".rs";
+    let mut llmod_id = link_meta.crateid.name.clone();
+    llmod_id.push_str(".rs");
 
-    let ccx = CrateContext::new(llmod_id, tcx, exp_map2,
+    let ccx = CrateContext::new(llmod_id.as_slice(), tcx, exp_map2,
                                 Sha256::new(), link_meta, reachable);
     {
         let _icx = push_ctxt("text");
index 37281113978e82ffb02ed15c6dffe2bd9b0012b0..e1763ab3ff16481c7d0d73721fa89ff8d9045747 100644 (file)
@@ -364,7 +364,7 @@ pub fn trans_fn_ref_with_vtables(
         let map_node = session::expect(
             ccx.sess(),
             tcx.map.find(def_id.node),
-            || format!("local item should be in ast map"));
+            || "local item should be in ast map".to_strbuf());
 
         match map_node {
             ast_map::NodeForeignItem(_) => {
index 93baeb71b4307810992e37ff51a5bc9dd74c0ea4..24abf1fd3f1bb8d3d2fef46c98c8d1d55b94cfe3 100644 (file)
@@ -426,7 +426,7 @@ pub fn ident(&self, ident: Ident) -> ~str {
     }
 
     pub fn node_id_to_str(&self, id: ast::NodeId) -> ~str {
-        self.tcx().map.node_to_str(id)
+        self.tcx().map.node_to_str(id).to_owned()
     }
 
     pub fn expr_to_str(&self, e: &ast::Expr) -> ~str {
@@ -839,7 +839,10 @@ pub fn filename_and_line_num_from_span(bcx: &Block, span: Span)
                                        -> (ValueRef, ValueRef) {
     let loc = bcx.sess().codemap().lookup_char_pos(span.lo);
     let filename_cstr = C_cstr(bcx.ccx(),
-                               token::intern_and_get_ident(loc.file.name), true);
+                               token::intern_and_get_ident(loc.file
+                                                              .name
+                                                              .as_slice()),
+                               true);
     let filename = build::PointerCast(bcx, filename_cstr, Type::i8p(bcx.ccx()));
     let line = C_int(bcx.ccx(), loc.line as int);
     (filename, line)
index eae9da84a1fe6727885965175662132655890edb..548746362cf238bb1ff0f8c5d12b77697956650a 100644 (file)
@@ -33,7 +33,7 @@
 use util::ppaux::{Repr, ty_to_str};
 
 use std::c_str::ToCStr;
-use std::slice;
+use std::vec;
 use std::vec::Vec;
 use libc::c_uint;
 use syntax::{ast, ast_util};
@@ -94,12 +94,12 @@ fn const_vec(cx: &CrateContext, e: &ast::Expr,
     let vec_ty = ty::expr_ty(cx.tcx(), e);
     let unit_ty = ty::sequence_element_type(cx.tcx(), vec_ty);
     let llunitty = type_of::type_of(cx, unit_ty);
-    let (vs, inlineable) = slice::unzip(es.iter().map(|e| const_expr(cx, *e, is_local)));
+    let (vs, inlineable) = vec::unzip(es.iter().map(|e| const_expr(cx, *e, is_local)));
     // If the vector contains enums, an LLVM array won't work.
     let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
-        C_struct(cx, vs, false)
+        C_struct(cx, vs.as_slice(), false)
     } else {
-        C_array(llunitty, vs)
+        C_array(llunitty, vs.as_slice())
     };
     (v, llunitty, inlineable.iter().fold(true, |a, &b| a && b))
 }
@@ -539,7 +539,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
               };
 
               expr::with_field_tys(tcx, ety, Some(e.id), |discr, field_tys| {
-                  let (cs, inlineable) = slice::unzip(field_tys.iter().enumerate()
+                  let (cs, inlineable) = vec::unzip(field_tys.iter().enumerate()
                       .map(|(ix, &field_ty)| {
                       match fs.iter().find(|f| field_ty.ident.name == f.ident.node.name) {
                           Some(f) => const_expr(cx, (*f).expr, is_local),
@@ -554,7 +554,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
                           }
                       }
                   }));
-                  (adt::trans_const(cx, &*repr, discr, cs),
+                  (adt::trans_const(cx, &*repr, discr, cs.as_slice()),
                    inlineable.iter().fold(true, |a, &b| a && b))
               })
           }
index 7905436a7a3ada32afd78b2bdca56cbc03c43762..a165549dacabb34dd64e8cdd6637a8169287d8cb 100644 (file)
@@ -345,7 +345,11 @@ pub fn trans_fail<'a>(
     let v_fail_str = C_cstr(ccx, fail_str, true);
     let _icx = push_ctxt("trans_fail_value");
     let loc = bcx.sess().codemap().lookup_char_pos(sp.lo);
-    let v_filename = C_cstr(ccx, token::intern_and_get_ident(loc.file.name), true);
+    let v_filename = C_cstr(ccx,
+                            token::intern_and_get_ident(loc.file
+                                                           .name
+                                                           .as_slice()),
+                            true);
     let v_line = loc.line as int;
     let v_str = PointerCast(bcx, v_fail_str, Type::i8p(ccx));
     let v_filename = PointerCast(bcx, v_filename, Type::i8p(ccx));
index 049a6930ab9fc832150c16154d72e375c7d5472b..fe92105118936d0f061da3d33340a5394e8f34f8 100644 (file)
@@ -330,7 +330,7 @@ pub fn create_global_var_metadata(cx: &CrateContext,
     };
 
     let filename = span_start(cx, span).file.name.clone();
-    let file_metadata = file_metadata(cx, filename);
+    let file_metadata = file_metadata(cx, filename.as_slice());
 
     let is_local_to_unit = is_node_local_to_unit(cx, node_id);
     let loc = span_start(cx, span);
@@ -700,7 +700,7 @@ pub fn create_function_debug_context(cx: &CrateContext,
     }
 
     let loc = span_start(cx, span);
-    let file_metadata = file_metadata(cx, loc.file.name);
+    let file_metadata = file_metadata(cx, loc.file.name.as_slice());
 
     let function_type_metadata = unsafe {
         let fn_signature = get_function_signature(cx, fn_ast_id, fn_decl, param_substs, span);
@@ -1011,7 +1011,7 @@ fn compile_unit_metadata(cx: &CrateContext) {
     });
 
     fn fallback_path(cx: &CrateContext) -> CString {
-        cx.link_meta.crateid.name.to_c_str()
+        cx.link_meta.crateid.name.as_slice().to_c_str()
     }
 }
 
@@ -1025,7 +1025,7 @@ fn declare_local(bcx: &Block,
     let cx: &CrateContext = bcx.ccx();
 
     let filename = span_start(cx, span).file.name.clone();
-    let file_metadata = file_metadata(cx, filename);
+    let file_metadata = file_metadata(cx, filename.as_slice());
 
     let name = token::get_ident(variable_ident);
     let loc = span_start(cx, span);
@@ -1277,7 +1277,7 @@ fn prepare_struct_metadata(cx: &CrateContext,
     let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx, def_id);
 
     let file_name = span_start(cx, definition_span).file.name.clone();
-    let file_metadata = file_metadata(cx, file_name);
+    let file_metadata = file_metadata(cx, file_name.as_slice());
 
     let struct_metadata_stub = create_struct_stub(cx,
                                                   struct_llvm_type,
@@ -1371,7 +1371,7 @@ fn prepare_tuple_metadata(cx: &CrateContext,
     let tuple_llvm_type = type_of::type_of(cx, tuple_type);
 
     let loc = span_start(cx, span);
-    let file_metadata = file_metadata(cx, loc.file.name);
+    let file_metadata = file_metadata(cx, loc.file.name.as_slice());
 
     UnfinishedMetadata {
         cache_id: cache_id_for_type(tuple_type),
@@ -1533,7 +1533,7 @@ fn prepare_enum_metadata(cx: &CrateContext,
 
     let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx, enum_def_id);
     let loc = span_start(cx, definition_span);
-    let file_metadata = file_metadata(cx, loc.file.name);
+    let file_metadata = file_metadata(cx, loc.file.name.as_slice());
 
     // For empty enums there is an early exit. Just describe it as an empty struct with the
     // appropriate type name
@@ -1903,7 +1903,7 @@ fn boxed_type_metadata(cx: &CrateContext,
     ];
 
     let loc = span_start(cx, span);
-    let file_metadata = file_metadata(cx, loc.file.name);
+    let file_metadata = file_metadata(cx, loc.file.name.as_slice());
 
     return composite_type_metadata(
         cx,
@@ -2004,7 +2004,7 @@ fn vec_metadata(cx: &CrateContext,
     assert!(member_descriptions.len() == member_llvm_types.len());
 
     let loc = span_start(cx, span);
-    let file_metadata = file_metadata(cx, loc.file.name);
+    let file_metadata = file_metadata(cx, loc.file.name.as_slice());
 
     composite_type_metadata(
         cx,
@@ -2055,7 +2055,7 @@ fn vec_slice_metadata(cx: &CrateContext,
     assert!(member_descriptions.len() == member_llvm_types.len());
 
     let loc = span_start(cx, span);
-    let file_metadata = file_metadata(cx, loc.file.name);
+    let file_metadata = file_metadata(cx, loc.file.name.as_slice());
 
     return composite_type_metadata(
         cx,
@@ -2081,7 +2081,7 @@ fn subroutine_type_metadata(cx: &CrateContext,
                             span: Span)
                          -> DICompositeType {
     let loc = span_start(cx, span);
-    let file_metadata = file_metadata(cx, loc.file.name);
+    let file_metadata = file_metadata(cx, loc.file.name.as_slice());
 
     let mut signature_metadata: Vec<DIType> =
         Vec::with_capacity(signature.inputs.len() + 1);
@@ -2126,7 +2126,7 @@ fn trait_metadata(cx: &CrateContext,
     let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx, def_id);
 
     let file_name = span_start(cx, definition_span).file.name.clone();
-    let file_metadata = file_metadata(cx, file_name);
+    let file_metadata = file_metadata(cx, file_name.as_slice());
 
     let trait_llvm_type = type_of::type_of(cx, trait_type);
 
@@ -2420,7 +2420,7 @@ fn with_new_scope(cx: &CrateContext,
                                    &mut HashMap<ast::NodeId, DIScope>|) {
         // Create a new lexical scope and push it onto the stack
         let loc = cx.sess().codemap().lookup_char_pos(scope_span.lo);
-        let file_metadata = file_metadata(cx, loc.file.name);
+        let file_metadata = file_metadata(cx, loc.file.name.as_slice());
         let parent_scope = scope_stack.last().unwrap().scope_metadata;
 
         let scope_metadata = unsafe {
@@ -2538,7 +2538,10 @@ fn walk_pattern(cx: &CrateContext,
                     if need_new_scope {
                         // Create a new lexical scope and push it onto the stack
                         let loc = cx.sess().codemap().lookup_char_pos(pat.span.lo);
-                        let file_metadata = file_metadata(cx, loc.file.name);
+                        let file_metadata = file_metadata(cx,
+                                                          loc.file
+                                                             .name
+                                                             .as_slice());
                         let parent_scope = scope_stack.last().unwrap().scope_metadata;
 
                         let scope_metadata = unsafe {
@@ -2860,7 +2863,10 @@ fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTree
     ty::with_path(cx.tcx(), def_id, |path| {
         // prepend crate name if not already present
         let krate = if def_id.krate == ast::LOCAL_CRATE {
-            let crate_namespace_ident = token::str_to_ident(cx.link_meta.crateid.name);
+            let crate_namespace_ident = token::str_to_ident(cx.link_meta
+                                                              .crateid
+                                                              .name
+                                                              .as_slice());
             Some(ast_map::PathMod(crate_namespace_ident.name))
         } else {
             None
index aa6e2dafd835ee9373d29c51b11f6baea8d797fb..4fd4f2f9d6ef0e635a147e737f71e85984127df1 100644 (file)
@@ -109,9 +109,11 @@ pub fn monomorphic_fn(ccx: &CrateContext,
     let map_node = session::expect(
         ccx.sess(),
         ccx.tcx.map.find(fn_id.node),
-        || format!("while monomorphizing {:?}, couldn't find it in the \
-                    item map (may have attempted to monomorphize an item \
-                    defined in a different crate?)", fn_id));
+        || {
+            (format!("while monomorphizing {:?}, couldn't find it in the \
+                      item map (may have attempted to monomorphize an item \
+                      defined in a different crate?)", fn_id)).to_strbuf()
+        });
 
     match map_node {
         ast_map::NodeForeignItem(_) => {
@@ -155,12 +157,13 @@ pub fn monomorphic_fn(ccx: &CrateContext,
             // This is a bit unfortunate.
 
             let idx = real_substs.tps.len() - num_method_ty_params;
-            let substs = real_substs.tps.slice(0, idx) +
-            &[real_substs.self_ty.unwrap()] + real_substs.tps.tailn(idx);
+            let substs = Vec::from_slice(real_substs.tps.slice(0, idx))
+                         .append([real_substs.self_ty.unwrap()])
+                         .append(real_substs.tps.tailn(idx));
             debug!("static default: changed substitution to {}",
                    substs.repr(ccx.tcx()));
 
-            ty::subst_tps(ccx.tcx(), substs, None, llitem_ty)
+            ty::subst_tps(ccx.tcx(), substs.as_slice(), None, llitem_ty)
         }
     };
 
index e54a24af9605911e02534ac8dfa682915c8a72a9..307654f1d96993bb64f0dfe18c4111d515955d77 100644 (file)
@@ -403,6 +403,5 @@ pub fn ast_fn_style_constant(fn_style: ast::FnStyle) -> uint {
     match fn_style {
         ast::UnsafeFn => 1u,
         ast::NormalFn => 2u,
-        ast::ExternFn => 3u
     }
 }
index 461d39240e8f73b2e7b7a5eb7bfbe8b7cb4b2921..7067ce888368bccca1da038c7ad7746c7a98f125 100644 (file)
@@ -3709,7 +3709,7 @@ pub fn substd_enum_variants(cx: &ctxt,
 }
 
 pub fn item_path_str(cx: &ctxt, id: ast::DefId) -> ~str {
-    with_path(cx, id, |path| ast_map::path_to_str(path))
+    with_path(cx, id, |path| ast_map::path_to_str(path)).to_owned()
 }
 
 pub enum DtorKind {
index 4b0153b67fff493d1804f0275e44e0627af33c3d..86291a7d6cb3e6a98d9743182d35442ee9573725 100644 (file)
@@ -71,6 +71,10 @@ fn fold_region(&mut self, r: ty::Region) -> ty::Region {
     fn fold_trait_store(&mut self, s: ty::TraitStore) -> ty::TraitStore {
         super_fold_trait_store(self, s)
     }
+
+    fn fold_autoref(&mut self, ar: &ty::AutoRef) -> ty::AutoRef {
+        super_fold_autoref(self, ar)
+    }
 }
 
 pub fn fold_opt_ty<T:TypeFolder>(this: &mut T,
@@ -200,6 +204,19 @@ pub fn super_fold_trait_store<T:TypeFolder>(this: &mut T,
     }
 }
 
+pub fn super_fold_autoref<T:TypeFolder>(this: &mut T,
+                                        autoref: &ty::AutoRef)
+                                        -> ty::AutoRef
+{
+    match *autoref {
+        ty::AutoPtr(r, m) => ty::AutoPtr(this.fold_region(r), m),
+        ty::AutoBorrowVec(r, m) => ty::AutoBorrowVec(this.fold_region(r), m),
+        ty::AutoBorrowVecRef(r, m) => ty::AutoBorrowVecRef(this.fold_region(r), m),
+        ty::AutoUnsafe(m) => ty::AutoUnsafe(m),
+        ty::AutoBorrowObj(r, m) => ty::AutoBorrowObj(this.fold_region(r), m),
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // Some sample folders
 
index c352ba7e3a5c81defc73fb691566a75e3bf950ac..bf5874e133661f7b0a0aaddb3a0dc715d7b92043 100644 (file)
@@ -221,6 +221,10 @@ enum IsBinopAssignment{
 
 #[deriving(Clone)]
 pub struct FnCtxt<'a> {
+    // This flag is set to true if, during the writeback phase, we encounter
+    // a type error in this function.
+    writeback_errors: Cell<bool>,
+
     // Number of errors that had been reported when we started
     // checking this function. On exit, if we find that *more* errors
     // have been reported, we will skip regionck and other work that
@@ -280,6 +284,7 @@ fn blank_fn_ctxt<'a>(ccx: &'a CrateCtxt<'a>,
                      region_bnd: ast::NodeId)
                      -> FnCtxt<'a> {
     FnCtxt {
+        writeback_errors: Cell::new(false),
         err_count_on_creation: ccx.tcx.sess.err_count(),
         ret_ty: rty,
         ps: RefCell::new(FnStyleState::function(ast::NormalFn, 0)),
@@ -469,6 +474,7 @@ fn check_fn<'a>(ccx: &'a CrateCtxt<'a>,
     // Create the function context.  This is either derived from scratch or,
     // in the case of function expressions, based on the outer context.
     let fcx = FnCtxt {
+        writeback_errors: Cell::new(false),
         err_count_on_creation: err_count_on_creation,
         ret_ty: ret_ty,
         ps: RefCell::new(FnStyleState::function(fn_style, id)),
@@ -1198,11 +1204,10 @@ pub fn method_ty_substs(&self, id: ast::NodeId) -> ty::substs {
 
     pub fn opt_node_ty_substs(&self,
                               id: ast::NodeId,
-                              f: |&ty::substs| -> bool)
-                              -> bool {
+                              f: |&ty::substs|) {
         match self.inh.node_type_substs.borrow().find(&id) {
-            Some(s) => f(s),
-            None => true
+            Some(s) => { f(s) }
+            None => { }
         }
     }
 
index 192c67eb8d1d9cfc7beae210f926e132f6b7119d..f2d6171cc639265465f6ef6efc15d72c29585efd 100644 (file)
@@ -644,7 +644,6 @@ fn mutability_allowed(a_mutbl: ast::Mutability,
                     insert_vtables(fcx, MethodCall::expr(ex.id), vtbls);
                 }
             }
-            true
         });
       }
 
index 3843c38fd180029ca63ecdbc24b5a89ad1589386..77429118a2c457cced57ab82c64f8aa3e0f10033 100644 (file)
 
 use middle::pat_util;
 use middle::ty;
+use middle::ty_fold::TypeFolder;
 use middle::typeck::astconv::AstConv;
 use middle::typeck::check::FnCtxt;
 use middle::typeck::infer::{force_all, resolve_all, resolve_region};
 use middle::typeck::infer::resolve_type;
 use middle::typeck::infer;
 use middle::typeck::{MethodCall, MethodCallee};
-use middle::typeck::{vtable_res, vtable_static, vtable_param};
+use middle::typeck::{vtable_origin, vtable_static, vtable_param};
 use middle::typeck::write_substs_to_tcx;
 use middle::typeck::write_ty_to_tcx;
-use util::ppaux;
 use util::ppaux::Repr;
 
 use syntax::ast;
 use syntax::visit;
 use syntax::visit::Visitor;
 
-fn resolve_type_vars_in_type(fcx: &FnCtxt, sp: Span, typ: ty::t)
-                          -> Option<ty::t> {
-    if !ty::type_needs_infer(typ) { return Some(typ); }
-    match resolve_type(fcx.infcx(), typ, resolve_all | force_all) {
-        Ok(new_type) => return Some(new_type),
-        Err(e) => {
-            if !fcx.ccx.tcx.sess.has_errors() {
-                fcx.ccx.tcx.sess.span_err(
-                    sp,
-                    format!("cannot determine a type \
-                          for this expression: {}",
-                         infer::fixup_err_to_str(e)))
-            }
-            return None;
+///////////////////////////////////////////////////////////////////////////
+// Entry point functions
+
+pub fn resolve_type_vars_in_expr(fcx: &FnCtxt, e: &ast::Expr) {
+    assert_eq!(fcx.writeback_errors.get(), false);
+    let mut wbcx = WritebackCx::new(fcx);
+    wbcx.visit_expr(e, ());
+    wbcx.visit_upvar_borrow_map();
+}
+
+pub fn resolve_type_vars_in_fn(fcx: &FnCtxt,
+                               decl: &ast::FnDecl,
+                               blk: &ast::Block) {
+    assert_eq!(fcx.writeback_errors.get(), false);
+    let mut wbcx = WritebackCx::new(fcx);
+    wbcx.visit_block(blk, ());
+    for arg in decl.inputs.iter() {
+        wbcx.visit_pat(arg.pat, ());
+
+        // Privacy needs the type for the whole pattern, not just each binding
+        if !pat_util::pat_is_binding(&fcx.tcx().def_map, arg.pat) {
+            wbcx.visit_node_id(ResolvingPattern(arg.pat.span),
+                               arg.pat.id);
         }
     }
+    wbcx.visit_upvar_borrow_map();
 }
 
-fn resolve_method_map_entry(wbcx: &mut WbCtxt, sp: Span, method_call: MethodCall) {
-    let fcx = wbcx.fcx;
-    let tcx = fcx.ccx.tcx;
-
-    // Resolve any method map entry
-    match fcx.inh.method_map.borrow_mut().pop(&method_call) {
-        Some(method) => {
-            debug!("writeback::resolve_method_map_entry(call={:?}, entry={:?})",
-                   method_call, method.repr(tcx));
-            let new_method = MethodCallee {
-                origin: method.origin,
-                ty: match resolve_type_vars_in_type(fcx, sp, method.ty) {
-                    Some(t) => t,
-                    None => {
-                        wbcx.success = false;
-                        return;
-                    }
-                },
-                substs: ty::substs {
-                    tps: method.substs.tps.move_iter().map(|subst| {
-                        match resolve_type_vars_in_type(fcx, sp, subst) {
-                            Some(t) => t,
-                            None => { wbcx.success = false; ty::mk_err() }
-                        }
-                    }).collect(),
-                    regions: ty::ErasedRegions,
-                    self_ty: None
-                }
-            };
-            tcx.method_map.borrow_mut().insert(method_call, new_method);
-        }
-        None => {}
+///////////////////////////////////////////////////////////////////////////
+// The Writerback context. This visitor walks the AST, checking the
+// fn-specific tables to find references to types or regions. It
+// resolves those regions to remove inference variables and writes the
+// final result back into the master tables in the tcx. Here and
+// there, it applies a few ad-hoc checks that were not convenient to
+// do elsewhere.
+
+struct WritebackCx<'cx> {
+    fcx: &'cx FnCtxt<'cx>,
+}
+
+impl<'cx> WritebackCx<'cx> {
+    fn new(fcx: &'cx FnCtxt) -> WritebackCx<'cx> {
+        WritebackCx { fcx: fcx }
+    }
+
+    fn tcx(&self) -> &'cx ty::ctxt {
+        self.fcx.tcx()
     }
 }
 
-fn resolve_vtable_map_entry(fcx: &FnCtxt, sp: Span, vtable_key: MethodCall) {
-    // Resolve any vtable map entry
-    match fcx.inh.vtable_map.borrow_mut().pop(&vtable_key) {
-        Some(origins) => {
-            let r_origins = resolve_origins(fcx, sp, origins);
-            debug!("writeback::resolve_vtable_map_entry(vtable_key={}, vtables={:?})",
-                    vtable_key, r_origins.repr(fcx.tcx()));
-            fcx.tcx().vtable_map.borrow_mut().insert(vtable_key, r_origins);
+///////////////////////////////////////////////////////////////////////////
+// Impl of Visitor for Resolver
+//
+// This is the master code which walks the AST. It delegates most of
+// the heavy lifting to the generic visit and resolve functions
+// below. In general, a function is made into a `visitor` if it must
+// traffic in node-ids or update tables in the type context etc.
+
+impl<'cx> Visitor<()> for WritebackCx<'cx> {
+    fn visit_item(&mut self, _: &ast::Item, _: ()) {
+        // Ignore items
+    }
+
+    fn visit_stmt(&mut self, s: &ast::Stmt, _: ()) {
+        if self.fcx.writeback_errors.get() {
+            return;
         }
-        None => {}
+
+        self.visit_node_id(ResolvingExpr(s.span), ty::stmt_node_id(s));
+        visit::walk_stmt(self, s, ());
     }
 
-    fn resolve_origins(fcx: &FnCtxt, sp: Span,
-                       vtbls: vtable_res) -> vtable_res {
-        vtbls.move_iter().map(|os| os.move_iter().map(|origin| {
-            match origin {
-                vtable_static(def_id, tys, origins) => {
-                    let r_tys = tys.move_iter().map(|t| {
-                        match resolve_type_vars_in_type(fcx, sp, t) {
-                            Some(t1) => t1,
-                            None => ty::mk_err()
-                        }
-                    }).collect();
-                    let r_origins = resolve_origins(fcx, sp, origins);
-                    vtable_static(def_id, r_tys, r_origins)
+    fn visit_expr(&mut self, e:&ast::Expr, _: ()) {
+        if self.fcx.writeback_errors.get() {
+            return;
+        }
+
+        self.visit_node_id(ResolvingExpr(e.span), e.id);
+        self.visit_method_map_entry(ResolvingExpr(e.span),
+                                    MethodCall::expr(e.id));
+        self.visit_vtable_map_entry(ResolvingExpr(e.span),
+                                    MethodCall::expr(e.id));
+
+        match e.node {
+            ast::ExprFnBlock(ref decl, _) | ast::ExprProc(ref decl, _) => {
+                for input in decl.inputs.iter() {
+                    let _ = self.visit_node_id(ResolvingExpr(e.span),
+                                               input.id);
                 }
-                vtable_param(n, b) => vtable_param(n, b)
             }
-        }).collect()).collect()
+            _ => {}
+        }
+
+        visit::walk_expr(self, e, ());
     }
-}
 
-fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId) {
-    let fcx = wbcx.fcx;
-    let tcx = fcx.ccx.tcx;
-
-    // Resolve any borrowings for the node with id `id`
-    let resolved_adj = match fcx.inh.adjustments.borrow_mut().pop(&id) {
-        None => None,
-
-        Some(adjustment) => {
-            Some(match adjustment {
-                ty::AutoAddEnv(store) => {
-                    let r = match store {
-                        ty::RegionTraitStore(r, _) => r,
-                        ty::UniqTraitStore => ty::ReStatic
-                    };
-                    match resolve_region(fcx.infcx(),
-                                         r,
-                                         resolve_all | force_all) {
-                        Err(e) => {
-                            // This should not, I think, happen:
-                            tcx.sess.span_err(
-                                sp,
-                                format!("cannot resolve bound for closure: \
-                                         {}",
-                                        infer::fixup_err_to_str(e)));
-                            wbcx.success = false;
-                            return;
-                        }
-                        Ok(r1) => {
-                            // FIXME(eddyb) #2190 Allow only statically resolved
-                            // bare functions to coerce to a closure to avoid
-                            // constructing (slower) indirect call wrappers.
-                            match tcx.def_map.borrow().find(&id) {
-                                Some(&ast::DefFn(..)) |
-                                Some(&ast::DefStaticMethod(..)) |
-                                Some(&ast::DefVariant(..)) |
-                                Some(&ast::DefStruct(_)) => {}
-                                _ => tcx.sess.span_err(sp,
-                                        "cannot coerce non-statically resolved bare fn")
-                            }
+    fn visit_block(&mut self, b: &ast::Block, _: ()) {
+        if self.fcx.writeback_errors.get() {
+            return;
+        }
 
-                            ty::AutoAddEnv(match store {
-                                ty::RegionTraitStore(..) => {
-                                    ty::RegionTraitStore(r1, ast::MutMutable)
-                                }
-                                ty::UniqTraitStore => ty::UniqTraitStore
-                            })
-                        }
-                    }
-                }
+        self.visit_node_id(ResolvingExpr(b.span), b.id);
+        visit::walk_block(self, b, ());
+    }
 
-                ty::AutoDerefRef(adj) => {
-                    for autoderef in range(0, adj.autoderefs) {
-                        let method_call = MethodCall::autoderef(id, autoderef as u32);
-                        resolve_method_map_entry(wbcx, sp, method_call);
-                        resolve_vtable_map_entry(wbcx.fcx, sp, method_call);
-                    }
+    fn visit_pat(&mut self, p: &ast::Pat, _: ()) {
+        if self.fcx.writeback_errors.get() {
+            return;
+        }
 
-                    ty::AutoDerefRef(ty::AutoDerefRef {
-                        autoderefs: adj.autoderefs,
-                        autoref: adj.autoref.map(|r| r.map_region(|r| {
-                            match resolve_region(fcx.infcx(), r,
-                                                resolve_all | force_all) {
-                                Ok(r1) => r1,
-                                Err(e) => {
-                                    // This should not, I think, happen.
-                                    tcx.sess.span_err(
-                                        sp,
-                                        format!("cannot resolve scope of borrow: \
-                                                {}",
-                                                infer::fixup_err_to_str(e)));
-                                    r
-                                }
-                            }
-                        })),
-                    })
-                }
+        self.visit_node_id(ResolvingPattern(p.span), p.id);
+
+        debug!("Type for pattern binding {} (id {}) resolved to {}",
+               pat_to_str(p),
+               p.id,
+               ty::node_id_to_type(self.tcx(), p.id).repr(self.tcx()));
+
+        visit::walk_pat(self, p, ());
+    }
 
-                adjustment => adjustment
-            })
+    fn visit_local(&mut self, l: &ast::Local, _: ()) {
+        if self.fcx.writeback_errors.get() {
+            return;
         }
-    };
 
-    debug!("Adjustments for node {}: {:?}",
-           id, resolved_adj);
-    match resolved_adj {
-        Some(adj) => {
-            tcx.adjustments.borrow_mut().insert(id, adj);
+        let var_ty = self.fcx.local_ty(l.span, l.id);
+        let var_ty = var_ty.resolve(self.fcx, ResolvingLocal(l.span));
+        write_ty_to_tcx(self.tcx(), l.id, var_ty);
+        visit::walk_local(self, l, ());
+    }
+
+    fn visit_ty(&mut self, _t: &ast::Ty, _: ()) {
+        // ignore
+    }
+}
+
+impl<'cx> WritebackCx<'cx> {
+    fn visit_upvar_borrow_map(&self) {
+        if self.fcx.writeback_errors.get() {
+            return;
+        }
+
+        for (upvar_id, upvar_borrow) in self.fcx.inh.upvar_borrow_map.borrow().iter() {
+            let r = upvar_borrow.region;
+            let r = r.resolve(self.fcx, ResolvingUpvar(*upvar_id));
+            let new_upvar_borrow = ty::UpvarBorrow { kind: upvar_borrow.kind,
+                                                     region: r };
+            debug!("Upvar borrow for {} resolved to {}",
+                   upvar_id.repr(self.tcx()),
+                   new_upvar_borrow.repr(self.tcx()));
+            self.fcx.tcx().upvar_borrow_map.borrow_mut().insert(
+                *upvar_id, new_upvar_borrow);
         }
-        None => {}
     }
 
-    // Resolve the type of the node with id `id`
-    let n_ty = fcx.node_ty(id);
-    match resolve_type_vars_in_type(fcx, sp, n_ty) {
-      None => {
-        wbcx.success = false;
-      }
-
-      Some(t) => {
-        debug!("resolve_type_vars_for_node(id={}, n_ty={}, t={})",
-               id, ppaux::ty_to_str(tcx, n_ty), ppaux::ty_to_str(tcx, t));
-        write_ty_to_tcx(tcx, id, t);
-        fcx.opt_node_ty_substs(id, |substs| {
-          let mut new_tps = Vec::new();
-          for subst in substs.tps.iter() {
-              match resolve_type_vars_in_type(fcx, sp, *subst) {
-                Some(t) => new_tps.push(t),
-                None => { wbcx.success = false; break }
-              }
-          }
-          write_substs_to_tcx(tcx, id, new_tps);
-          wbcx.success
+    fn visit_node_id(&self, reason: ResolveReason, id: ast::NodeId) {
+        // Resolve any borrowings for the node with id `id`
+        self.visit_adjustments(reason, id);
+
+        // Resolve the type of the node with id `id`
+        let n_ty = self.fcx.node_ty(id);
+        let n_ty = n_ty.resolve(self.fcx, reason);
+        write_ty_to_tcx(self.tcx(), id, n_ty);
+        debug!("Node {} has type {}", id, n_ty.repr(self.tcx()));
+
+        // Resolve any substitutions
+        self.fcx.opt_node_ty_substs(id, |node_substs| {
+            let mut new_tps = Vec::new();
+            for subst in node_substs.tps.iter() {
+                new_tps.push(subst.resolve(self.fcx, reason));
+            }
+            write_substs_to_tcx(self.tcx(), id, new_tps);
         });
-      }
     }
-}
 
-struct WbCtxt<'a> {
-    fcx: &'a FnCtxt<'a>,
+    fn visit_adjustments(&self, reason: ResolveReason, id: ast::NodeId) {
+        match self.fcx.inh.adjustments.borrow_mut().pop(&id) {
+            None => {
+                debug!("No adjustments for node {}", id);
+            }
 
-    // As soon as we hit an error we have to stop resolving
-    // the entire function.
-    success: bool,
-}
+            Some(adjustment) => {
+                let resolved_adjustment = match adjustment {
+                    ty::AutoAddEnv(store) => {
+                        // FIXME(eddyb) #2190 Allow only statically resolved
+                        // bare functions to coerce to a closure to avoid
+                        // constructing (slower) indirect call wrappers.
+                        match self.tcx().def_map.borrow().find(&id) {
+                            Some(&ast::DefFn(..)) |
+                            Some(&ast::DefStaticMethod(..)) |
+                            Some(&ast::DefVariant(..)) |
+                            Some(&ast::DefStruct(_)) => {
+                            }
+                            _ => {
+                                self.tcx().sess.span_err(
+                                    reason.span(self.fcx),
+                                    "cannot coerce non-statically resolved bare fn")
+                            }
+                        }
 
-fn visit_stmt(s: &ast::Stmt, wbcx: &mut WbCtxt) {
-    if !wbcx.success { return; }
-    resolve_type_vars_for_node(wbcx, s.span, ty::stmt_node_id(s));
-    visit::walk_stmt(wbcx, s, ());
-}
+                        ty::AutoAddEnv(store.resolve(self.fcx, reason))
+                    }
+
+                    ty::AutoDerefRef(adj) => {
+                        for autoderef in range(0, adj.autoderefs) {
+                            let method_call = MethodCall::autoderef(id, autoderef as u32);
+                            self.visit_method_map_entry(reason, method_call);
+                            self.visit_vtable_map_entry(reason, method_call);
+                        }
 
-fn visit_expr(e: &ast::Expr, wbcx: &mut WbCtxt) {
-    if !wbcx.success {
-        return;
+                        ty::AutoDerefRef(ty::AutoDerefRef {
+                            autoderefs: adj.autoderefs,
+                            autoref: adj.autoref.resolve(self.fcx, reason),
+                        })
+                    }
+
+                    adjustment => adjustment
+                };
+                debug!("Adjustments for node {}: {:?}", id, resolved_adjustment);
+                self.tcx().adjustments.borrow_mut().insert(
+                    id, resolved_adjustment);
+            }
+        }
     }
 
-    resolve_type_vars_for_node(wbcx, e.span, e.id);
-    resolve_method_map_entry(wbcx, e.span, MethodCall::expr(e.id));
-    resolve_vtable_map_entry(wbcx.fcx, e.span, MethodCall::expr(e.id));
+    fn visit_method_map_entry(&self,
+                              reason: ResolveReason,
+                              method_call: MethodCall) {
+        // Resolve any method map entry
+        match self.fcx.inh.method_map.borrow_mut().pop(&method_call) {
+            Some(method) => {
+                debug!("writeback::resolve_method_map_entry(call={:?}, entry={})",
+                       method_call,
+                       method.repr(self.tcx()));
+                let mut new_method = MethodCallee {
+                    origin: method.origin,
+                    ty: method.ty.resolve(self.fcx, reason),
+                    substs: method.substs.resolve(self.fcx, reason),
+                };
+
+                // Wack. For some reason I don't quite know, we always
+                // hard-code the self-ty and regions to these
+                // values. Changing this causes downstream errors I
+                // don't feel like investigating right now (in
+                // particular, self_ty is set to mk_err in some cases,
+                // probably for invocations on objects, and this
+                // causes encoding failures). -nmatsakis
+                new_method.substs.self_ty = None;
+                new_method.substs.regions = ty::ErasedRegions;
+
+                self.tcx().method_map.borrow_mut().insert(
+                    method_call,
+                    new_method);
+            }
+            None => {}
+        }
+    }
 
-    match e.node {
-        ast::ExprFnBlock(ref decl, _) | ast::ExprProc(ref decl, _) => {
-            for input in decl.inputs.iter() {
-                let _ = resolve_type_vars_for_node(wbcx, e.span, input.id);
+    fn visit_vtable_map_entry(&self,
+                              reason: ResolveReason,
+                              vtable_key: MethodCall) {
+        // Resolve any vtable map entry
+        match self.fcx.inh.vtable_map.borrow_mut().pop(&vtable_key) {
+            Some(origins) => {
+                let r_origins = origins.resolve(self.fcx, reason);
+                debug!("writeback::resolve_vtable_map_entry(\
+                        vtable_key={}, vtables={:?})",
+                       vtable_key, r_origins.repr(self.tcx()));
+                self.tcx().vtable_map.borrow_mut().insert(vtable_key, r_origins);
             }
+            None => {}
         }
-        _ => {}
     }
+}
+
+///////////////////////////////////////////////////////////////////////////
+// Resolution reason.
 
-    visit::walk_expr(wbcx, e, ());
+enum ResolveReason {
+    ResolvingExpr(Span),
+    ResolvingLocal(Span),
+    ResolvingPattern(Span),
+    ResolvingUpvar(ty::UpvarId)
 }
 
-fn visit_block(b: &ast::Block, wbcx: &mut WbCtxt) {
-    if !wbcx.success {
-        return;
+impl ResolveReason {
+    fn span(&self, fcx: &FnCtxt) -> Span {
+        match *self {
+            ResolvingExpr(s) => s,
+            ResolvingLocal(s) => s,
+            ResolvingPattern(s) => s,
+            ResolvingUpvar(upvar_id) => {
+                ty::expr_span(fcx.tcx(), upvar_id.closure_expr_id)
+            }
+        }
     }
+}
+
+///////////////////////////////////////////////////////////////////////////
+// Convenience methods for resolving different kinds of things.
 
-    resolve_type_vars_for_node(wbcx, b.span, b.id);
-    visit::walk_block(wbcx, b, ());
+trait Resolve {
+    fn resolve(&self, fcx: &FnCtxt, reason: ResolveReason) -> Self;
 }
 
-fn visit_pat(p: &ast::Pat, wbcx: &mut WbCtxt) {
-    if !wbcx.success {
-        return;
+impl<T:Resolve> Resolve for Option<T> {
+    fn resolve(&self, fcx: &FnCtxt, reason: ResolveReason) -> Option<T> {
+        self.as_ref().map(|t| t.resolve(fcx, reason))
     }
+}
 
-    resolve_type_vars_for_node(wbcx, p.span, p.id);
-    debug!("Type for pattern binding {} (id {}) resolved to {}",
-           pat_to_str(p), p.id,
-           wbcx.fcx.infcx().ty_to_str(
-               ty::node_id_to_type(wbcx.fcx.ccx.tcx,
-                                   p.id)));
-    visit::walk_pat(wbcx, p, ());
+impl<T:Resolve> Resolve for Vec<T> {
+    fn resolve(&self, fcx: &FnCtxt, reason: ResolveReason) -> Vec<T> {
+        self.iter().map(|t| t.resolve(fcx, reason)).collect()
+    }
 }
 
-fn visit_local(l: &ast::Local, wbcx: &mut WbCtxt) {
-    if !wbcx.success { return; }
-    let var_ty = wbcx.fcx.local_ty(l.span, l.id);
-    match resolve_type(wbcx.fcx.infcx(), var_ty, resolve_all | force_all) {
-        Ok(lty) => {
-            debug!("Type for local {} (id {}) resolved to {}",
-                   pat_to_str(l.pat),
-                   l.id,
-                   wbcx.fcx.infcx().ty_to_str(lty));
-            write_ty_to_tcx(wbcx.fcx.ccx.tcx, l.id, lty);
-        }
-        Err(e) => {
-            wbcx.fcx.ccx.tcx.sess.span_err(
-                l.span,
-                format!("cannot determine a type \
-                      for this local variable: {}",
-                     infer::fixup_err_to_str(e)));
-            wbcx.success = false;
-        }
+impl Resolve for ty::TraitStore {
+    fn resolve(&self, fcx: &FnCtxt, reason: ResolveReason) -> ty::TraitStore {
+        Resolver::new(fcx, reason).fold_trait_store(*self)
     }
-    visit::walk_local(wbcx, l, ());
 }
-fn visit_item(_item: &ast::Item, _wbcx: &mut WbCtxt) {
-    // Ignore items
+
+impl Resolve for ty::t {
+    fn resolve(&self, fcx: &FnCtxt, reason: ResolveReason) -> ty::t {
+        Resolver::new(fcx, reason).fold_ty(*self)
+    }
 }
 
-impl<'a> Visitor<()> for WbCtxt<'a> {
-    fn visit_item(&mut self, i: &ast::Item, _: ()) { visit_item(i, self); }
-    fn visit_stmt(&mut self, s: &ast::Stmt, _: ()) { visit_stmt(s, self); }
-    fn visit_expr(&mut self, ex:&ast::Expr, _: ()) { visit_expr(ex, self); }
-    fn visit_block(&mut self, b: &ast::Block, _: ()) { visit_block(b, self); }
-    fn visit_pat(&mut self, p: &ast::Pat, _: ()) { visit_pat(p, self); }
-    fn visit_local(&mut self, l: &ast::Local, _: ()) { visit_local(l, self); }
-    // FIXME(#10894) should continue recursing
-    fn visit_ty(&mut self, _t: &ast::Ty, _: ()) {}
+impl Resolve for ty::Region {
+    fn resolve(&self, fcx: &FnCtxt, reason: ResolveReason) -> ty::Region {
+        Resolver::new(fcx, reason).fold_region(*self)
+    }
 }
 
-fn resolve_upvar_borrow_map(wbcx: &mut WbCtxt) {
-    if !wbcx.success {
-        return;
+impl Resolve for ty::substs {
+    fn resolve(&self, fcx: &FnCtxt, reason: ResolveReason) -> ty::substs {
+        Resolver::new(fcx, reason).fold_substs(self)
     }
+}
 
-    let fcx = wbcx.fcx;
-    let tcx = fcx.tcx();
-    for (upvar_id, upvar_borrow) in fcx.inh.upvar_borrow_map.borrow().iter() {
-        let r = upvar_borrow.region;
-        match resolve_region(fcx.infcx(), r, resolve_all | force_all) {
-            Ok(r) => {
-                let new_upvar_borrow = ty::UpvarBorrow {
-                    kind: upvar_borrow.kind,
-                    region: r
-                };
-                debug!("Upvar borrow for {} resolved to {}",
-                       upvar_id.repr(tcx), new_upvar_borrow.repr(tcx));
-                tcx.upvar_borrow_map.borrow_mut().insert(*upvar_id,
-                                                         new_upvar_borrow);
+impl Resolve for ty::AutoRef {
+    fn resolve(&self, fcx: &FnCtxt, reason: ResolveReason) -> ty::AutoRef {
+        Resolver::new(fcx, reason).fold_autoref(self)
+    }
+}
+
+impl Resolve for vtable_origin {
+    fn resolve(&self, fcx: &FnCtxt, reason: ResolveReason) -> vtable_origin {
+        match *self {
+            vtable_static(def_id, ref tys, ref origins) => {
+                let r_tys = tys.resolve(fcx, reason);
+                let r_origins = origins.resolve(fcx, reason);
+                vtable_static(def_id, r_tys, r_origins)
             }
-            Err(e) => {
-                let span = ty::expr_span(tcx, upvar_id.closure_expr_id);
-                fcx.ccx.tcx.sess.span_err(
-                    span, format!("cannot resolve lifetime for \
-                                  captured variable `{}`: {}",
-                                  ty::local_var_name_str(tcx, upvar_id.var_id).get().to_str(),
-                                  infer::fixup_err_to_str(e)));
-                wbcx.success = false;
+            vtable_param(n, b) => {
+                vtable_param(n, b)
             }
-        };
+        }
     }
 }
 
-pub fn resolve_type_vars_in_expr(fcx: &FnCtxt, e: &ast::Expr) -> bool {
-    let mut wbcx = WbCtxt { fcx: fcx, success: true };
-    let wbcx = &mut wbcx;
-    wbcx.visit_expr(e, ());
-    resolve_upvar_borrow_map(wbcx);
-    return wbcx.success;
+///////////////////////////////////////////////////////////////////////////
+// The Resolver. This is the type folding engine that detects
+// unresolved types and so forth.
+
+struct Resolver<'cx> {
+    fcx: &'cx FnCtxt<'cx>,
+    reason: ResolveReason,
 }
 
-pub fn resolve_type_vars_in_fn(fcx: &FnCtxt, decl: &ast::FnDecl,
-                               blk: &ast::Block) -> bool {
-    let mut wbcx = WbCtxt { fcx: fcx, success: true };
-    let wbcx = &mut wbcx;
-    wbcx.visit_block(blk, ());
-    for arg in decl.inputs.iter() {
-        wbcx.visit_pat(arg.pat, ());
-        // Privacy needs the type for the whole pattern, not just each binding
-        if !pat_util::pat_is_binding(&fcx.tcx().def_map, arg.pat) {
-            resolve_type_vars_for_node(wbcx, arg.pat.span, arg.pat.id);
+impl<'cx> Resolver<'cx> {
+    fn new(fcx: &'cx FnCtxt<'cx>,
+           reason: ResolveReason)
+           -> Resolver<'cx>
+    {
+        Resolver { fcx: fcx, reason: reason }
+    }
+
+    fn report_error(&self, e: infer::fixup_err) {
+        self.fcx.writeback_errors.set(true);
+        if !self.tcx().sess.has_errors() {
+            match self.reason {
+                ResolvingExpr(span) => {
+                    self.tcx().sess.span_err(
+                        span,
+                        format!("cannot determine a type for \
+                                 this expression: {}",
+                                infer::fixup_err_to_str(e)))
+                }
+
+                ResolvingLocal(span) => {
+                    self.tcx().sess.span_err(
+                        span,
+                        format!("cannot determine a type for \
+                                 this local variable: {}",
+                                infer::fixup_err_to_str(e)))
+                }
+
+                ResolvingPattern(span) => {
+                    self.tcx().sess.span_err(
+                        span,
+                        format!("cannot determine a type for \
+                                 this pattern binding: {}",
+                                infer::fixup_err_to_str(e)))
+                }
+
+                ResolvingUpvar(upvar_id) => {
+                    let span = self.reason.span(self.fcx);
+                    self.tcx().sess.span_err(
+                        span,
+                        format!("cannot resolve lifetime for \
+                                 captured variable `{}`: {}",
+                                ty::local_var_name_str(
+                                    self.tcx(),
+                                    upvar_id.var_id).get().to_str(),
+                                infer::fixup_err_to_str(e)));
+                }
+            }
+        }
+    }
+}
+
+impl<'cx> TypeFolder for Resolver<'cx> {
+    fn tcx<'a>(&'a self) -> &'a ty::ctxt {
+        self.fcx.tcx()
+    }
+
+    fn fold_ty(&mut self, t: ty::t) -> ty::t {
+        if !ty::type_needs_infer(t) {
+            return t;
+        }
+
+        match resolve_type(self.fcx.infcx(), t, resolve_all | force_all) {
+            Ok(t) => t,
+            Err(e) => {
+                self.report_error(e);
+                ty::mk_err()
+            }
+        }
+    }
+
+    fn fold_region(&mut self, r: ty::Region) -> ty::Region {
+        match resolve_region(self.fcx.infcx(), r, resolve_all | force_all) {
+            Ok(r) => r,
+            Err(e) => {
+                self.report_error(e);
+                ty::ReStatic
+            }
         }
     }
-    resolve_upvar_borrow_map(wbcx);
-    return wbcx.success;
 }
index 32bc7eedf2fcf3141a55b22e5739ef2680b29486..42b0321e67d5884709ea6f1dfe1a1d88a999bf38 100644 (file)
@@ -22,7 +22,7 @@
 use middle::typeck::infer::{TypeTrace, Subtype};
 use middle::typeck::infer::fold_regions_in_sig;
 use syntax::ast::{Many, Once, MutImmutable, MutMutable};
-use syntax::ast::{ExternFn, NormalFn, UnsafeFn, NodeId};
+use syntax::ast::{NormalFn, UnsafeFn, NodeId};
 use syntax::ast::{Onceness, FnStyle};
 use collections::HashMap;
 use util::common::{indenter};
@@ -83,7 +83,6 @@ fn contratys(&self, a: ty::t, b: ty::t) -> cres<ty::t> {
 
     fn fn_styles(&self, a: FnStyle, b: FnStyle) -> cres<FnStyle> {
         match (a, b) {
-          (ExternFn, _) | (_, ExternFn) => Ok(ExternFn),
           (NormalFn, _) | (_, NormalFn) => Ok(NormalFn),
           (UnsafeFn, UnsafeFn) => Ok(UnsafeFn)
         }
index d09bbc4253ba93a81ed340ca55492d4145e22a67..804c71da730325814ab0b8badad5854c70d0c5bf 100644 (file)
@@ -23,7 +23,7 @@
 use middle::typeck::infer::{TypeTrace, Subtype};
 use collections::HashMap;
 use syntax::ast::{Many, Once, NodeId};
-use syntax::ast::{ExternFn, NormalFn, UnsafeFn};
+use syntax::ast::{NormalFn, UnsafeFn};
 use syntax::ast::{Onceness, FnStyle};
 use util::ppaux::mt_to_str;
 
@@ -78,8 +78,7 @@ fn contratys(&self, a: ty::t, b: ty::t) -> cres<ty::t> {
     fn fn_styles(&self, a: FnStyle, b: FnStyle) -> cres<FnStyle> {
         match (a, b) {
           (UnsafeFn, _) | (_, UnsafeFn) => Ok(UnsafeFn),
-          (NormalFn, _) | (_, NormalFn) => Ok(NormalFn),
-          (ExternFn, ExternFn) => Ok(ExternFn),
+          (NormalFn, NormalFn) => Ok(NormalFn),
         }
     }
 
index 0d14c036ba7f1cb2cc414829ca9b602cf110b11a..5ddae0c1bfef6358a43eb3d1d547e15e52a308a7 100644 (file)
 use syntax::visit;
 use syntax::visit::Visitor;
 
-use std::local_data;
-
 use time;
 
 pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T {
     local_data_key!(depth: uint);
     if !do_it { return f(u); }
 
-    let old = local_data::get(depth, |d| d.map(|a| *a).unwrap_or(0));
-    local_data::set(depth, old + 1);
+    let old = depth.get().map(|d| *d).unwrap_or(0);
+    depth.replace(Some(old + 1));
 
     let start = time::precise_time_s();
     let rv = f(u);
     let end = time::precise_time_s();
 
     println!("{}time: {:3.3f} s\t{}", "  ".repeat(old), end - start, what);
-    local_data::set(depth, old);
+    depth.replace(Some(old));
 
     rv
 }
index cf6466faba6f9ac3006a7172f1e4f104c08bbff2..1808c0209b754c1e39e62b503753380643b45b7c 100644 (file)
@@ -341,9 +341,9 @@ fn push_sig_to_str(cx: &ctxt,
       ty_bot => "!".to_owned(),
       ty_bool => "bool".to_owned(),
       ty_char => "char".to_owned(),
-      ty_int(t) => ast_util::int_ty_to_str(t, None),
-      ty_uint(t) => ast_util::uint_ty_to_str(t, None),
-      ty_float(t) => ast_util::float_ty_to_str(t),
+      ty_int(t) => ast_util::int_ty_to_str(t, None).to_owned(),
+      ty_uint(t) => ast_util::uint_ty_to_str(t, None).to_owned(),
+      ty_float(t) => ast_util::float_ty_to_str(t).to_owned(),
       ty_box(typ) => "@".to_owned() + ty_to_str(cx, typ),
       ty_uniq(typ) => "~".to_owned() + ty_to_str(cx, typ),
       ty_ptr(ref tm) => "*".to_owned() + mt_to_str(cx, tm),
@@ -870,7 +870,7 @@ fn repr(&self, tcx: &ctxt) -> ~str {
 
 impl Repr for Span {
     fn repr(&self, tcx: &ctxt) -> ~str {
-        tcx.sess.codemap().span_to_str(*self)
+        tcx.sess.codemap().span_to_str(*self).to_owned()
     }
 }
 
index 79fc0fbeadac30404d29264be0fadbf40db0063e..14a27a607823c1d5b4cb9c0951a1863cce4614b5 100644 (file)
@@ -26,7 +26,6 @@
 use rustc::metadata::csearch;
 use rustc::metadata::decoder;
 
-use std::local_data;
 use std::strbuf::StrBuf;
 
 use core;
@@ -77,7 +76,7 @@ pub struct Crate {
 
 impl<'a> Clean<Crate> for visit_ast::RustdocVisitor<'a> {
     fn clean(&self) -> Crate {
-        let cx = local_data::get(super::ctxtkey, |x| *x.unwrap());
+        let cx = super::ctxtkey.get().unwrap();
 
         let mut externs = Vec::new();
         cx.sess().cstore.iter_crate_data(|n, meta| {
@@ -93,7 +92,7 @@ fn clean(&self) -> Crate {
         let id = link::find_crate_id(self.attrs.as_slice(),
                                      t_outputs.out_filestem);
         Crate {
-            name: id.name,
+            name: id.name.to_owned(),
             module: Some(self.module.clean()),
             externs: externs,
         }
@@ -251,7 +250,7 @@ fn clean(&self) -> Item {
         // determine if we should display the inner contents or
         // the outer `mod` item for the source code.
         let where = {
-            let ctxt = local_data::get(super::ctxtkey, |x| *x.unwrap());
+            let ctxt = super::ctxtkey.get().unwrap();
             let cm = ctxt.sess().codemap();
             let outer = cm.lookup_char_pos(self.where_outer.lo);
             let inner = cm.lookup_char_pos(self.where_inner.lo);
@@ -726,7 +725,7 @@ impl Clean<Type> for ast::Ty {
     fn clean(&self) -> Type {
         use syntax::ast::*;
         debug!("cleaning type `{:?}`", self);
-        let ctxt = local_data::get(super::ctxtkey, |x| *x.unwrap());
+        let ctxt = super::ctxtkey.get().unwrap();
         let codemap = ctxt.sess().codemap();
         debug!("span corresponds to `{}`", codemap.span_to_str(self.span));
         match self.node {
@@ -909,7 +908,7 @@ pub struct Span {
 
 impl Clean<Span> for syntax::codemap::Span {
     fn clean(&self) -> Span {
-        let ctxt = local_data::get(super::ctxtkey, |x| *x.unwrap());
+        let ctxt = super::ctxtkey.get().unwrap();
         let cm = ctxt.sess().codemap();
         let filename = cm.span_to_filename(*self);
         let lo = cm.lookup_char_pos(self.lo);
@@ -1206,7 +1205,7 @@ fn clean(&self) -> Item {
                 ForeignFunctionItem(Function {
                     decl: decl.clean(),
                     generics: generics.clean(),
-                    fn_style: ast::ExternFn,
+                    fn_style: ast::NormalFn,
                 })
             }
             ast::ForeignItemStatic(ref ty, mutbl) => {
@@ -1237,10 +1236,10 @@ trait ToSource {
 impl ToSource for syntax::codemap::Span {
     fn to_src(&self) -> ~str {
         debug!("converting span {:?} to snippet", self.clean());
-        let ctxt = local_data::get(super::ctxtkey, |x| x.unwrap().clone());
+        let ctxt = super::ctxtkey.get().unwrap();
         let cm = ctxt.sess().codemap().clone();
         let sn = match cm.span_to_snippet(*self) {
-            Some(x) => x,
+            Some(x) => x.to_owned(),
             None    => "".to_owned()
         };
         debug!("got snippet {}", sn);
@@ -1292,7 +1291,7 @@ fn name_from_pat(p: &ast::Pat) -> ~str {
 /// Given a Type, resolve it using the def_map
 fn resolve_type(path: Path, tpbs: Option<Vec<TyParamBound> >,
                 id: ast::NodeId) -> Type {
-    let cx = local_data::get(super::ctxtkey, |x| *x.unwrap());
+    let cx = super::ctxtkey.get().unwrap();
     let tycx = match cx.maybe_typed {
         core::Typed(ref tycx) => tycx,
         // If we're extracting tests, this return value doesn't matter.
@@ -1351,7 +1350,7 @@ fn resolve_use_source(path: Path, id: ast::NodeId) -> ImportSource {
 }
 
 fn resolve_def(id: ast::NodeId) -> Option<ast::DefId> {
-    let cx = local_data::get(super::ctxtkey, |x| *x.unwrap());
+    let cx = super::ctxtkey.get().unwrap();
     match cx.maybe_typed {
         core::Typed(ref tcx) => {
             tcx.def_map.borrow().find(&id).map(|&d| ast_util::def_id_of_def(d))
index 9f89da563cc7550b646eb3ccf0b2df302a92b410..1916e053e98a1336d397a6f0327fe266721b5d86 100644 (file)
@@ -20,7 +20,6 @@
 
 use std::cell::RefCell;
 use std::os;
-use std::local_data;
 use collections::HashSet;
 
 use visit_ast::RustdocVisitor;
@@ -109,7 +108,7 @@ pub fn run_core(libs: HashSet<Path>, cfgs: Vec<~str>, path: &Path)
                 -> (clean::Crate, CrateAnalysis) {
     let (ctxt, analysis) = get_ast_and_resolve(path, libs, cfgs);
     let ctxt = @ctxt;
-    local_data::set(super::ctxtkey, ctxt);
+    super::ctxtkey.replace(Some(ctxt));
 
     let krate = {
         let mut v = RustdocVisitor::new(ctxt, Some(&analysis));
index 1e2f89659cd7dbcee3ab874906f101c518f09535..06996df169254e2dd5d478b767b8963dcc439870 100644 (file)
@@ -17,7 +17,6 @@
 
 use std::fmt;
 use std::io;
-use std::local_data;
 use std::strbuf::StrBuf;
 
 use syntax::ast;
@@ -206,78 +205,72 @@ fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool,
         generics.push_str("&gt;");
     }
 
-    // Did someone say rightward-drift?
-    local_data::get(current_location_key, |loc| {
-        let loc = loc.unwrap();
-
-        local_data::get(cache_key, |cache| {
-            let cache = cache.unwrap();
-            let abs_root = root(&**cache, loc.as_slice());
-            let rel_root = match path.segments.get(0).name.as_slice() {
-                "self" => Some("./".to_owned()),
-                _ => None,
-            };
-
-            if print_all {
-                let amt = path.segments.len() - 1;
-                match rel_root {
-                    Some(root) => {
-                        let mut root = StrBuf::from_str(root);
-                        for seg in path.segments.slice_to(amt).iter() {
-                            if "super" == seg.name || "self" == seg.name {
-                                try!(write!(w, "{}::", seg.name));
-                            } else {
-                                root.push_str(seg.name);
-                                root.push_str("/");
-                                try!(write!(w, "<a class='mod'
-                                                    href='{}index.html'>{}</a>::",
-                                              root.as_slice(),
-                                              seg.name));
-                            }
-                        }
-                    }
-                    None => {
-                        for seg in path.segments.slice_to(amt).iter() {
-                            try!(write!(w, "{}::", seg.name));
-                        }
+    let loc = current_location_key.get().unwrap();
+    let cache = cache_key.get().unwrap();
+    let abs_root = root(&**cache, loc.as_slice());
+    let rel_root = match path.segments.get(0).name.as_slice() {
+        "self" => Some("./".to_owned()),
+        _ => None,
+    };
+
+    if print_all {
+        let amt = path.segments.len() - 1;
+        match rel_root {
+            Some(root) => {
+                let mut root = StrBuf::from_str(root);
+                for seg in path.segments.slice_to(amt).iter() {
+                    if "super" == seg.name || "self" == seg.name {
+                        try!(write!(w, "{}::", seg.name));
+                    } else {
+                        root.push_str(seg.name);
+                        root.push_str("/");
+                        try!(write!(w, "<a class='mod'
+                                            href='{}index.html'>{}</a>::",
+                                      root.as_slice(),
+                                      seg.name));
                     }
                 }
             }
-
-            match info(&**cache) {
-                // This is a documented path, link to it!
-                Some((ref fqp, shortty)) if abs_root.is_some() => {
-                    let mut url = StrBuf::from_str(abs_root.unwrap());
-                    let to_link = fqp.slice_to(fqp.len() - 1);
-                    for component in to_link.iter() {
-                        url.push_str(*component);
-                        url.push_str("/");
-                    }
-                    match shortty {
-                        item_type::Module => {
-                            url.push_str(*fqp.last().unwrap());
-                            url.push_str("/index.html");
-                        }
-                        _ => {
-                            url.push_str(shortty.to_static_str());
-                            url.push_str(".");
-                            url.push_str(*fqp.last().unwrap());
-                            url.push_str(".html");
-                        }
-                    }
-
-                    try!(write!(w, "<a class='{}' href='{}' title='{}'>{}</a>",
-                                  shortty, url, fqp.connect("::"), last.name));
+            None => {
+                for seg in path.segments.slice_to(amt).iter() {
+                    try!(write!(w, "{}::", seg.name));
                 }
+            }
+        }
+    }
 
+    match info(&**cache) {
+        // This is a documented path, link to it!
+        Some((ref fqp, shortty)) if abs_root.is_some() => {
+            let mut url = StrBuf::from_str(abs_root.unwrap());
+            let to_link = fqp.slice_to(fqp.len() - 1);
+            for component in to_link.iter() {
+                url.push_str(*component);
+                url.push_str("/");
+            }
+            match shortty {
+                item_type::Module => {
+                    url.push_str(*fqp.last().unwrap());
+                    url.push_str("/index.html");
+                }
                 _ => {
-                    try!(write!(w, "{}", last.name));
+                    url.push_str(shortty.to_static_str());
+                    url.push_str(".");
+                    url.push_str(*fqp.last().unwrap());
+                    url.push_str(".html");
                 }
             }
-            try!(write!(w, "{}", generics.as_slice()));
-            Ok(())
-        })
-    })
+
+            try!(write!(w, "<a class='{}' href='{}' title='{}'>{}</a>",
+                          shortty, url, fqp.connect("::"), last.name));
+        }
+
+        _ => {
+            try!(write!(w, "{}", last.name));
+        }
+    }
+    try!(write!(w, "{}", generics.as_slice()));
+    Ok(())
 }
 
 /// Helper to render type parameters
@@ -302,10 +295,8 @@ impl fmt::Show for clean::Type {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             clean::TyParamBinder(id) | clean::Generic(id) => {
-                local_data::get(cache_key, |cache| {
-                    let m = cache.unwrap();
-                    f.buf.write(m.typarams.get(&id).as_bytes())
-                })
+                let m = cache_key.get().unwrap();
+                f.buf.write(m.typarams.get(&id).as_bytes())
             }
             clean::ResolvedPath{id, typarams: ref tp, path: ref path} => {
                 try!(resolved_path(f.buf, id, path, false));
@@ -389,7 +380,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                            "".to_owned()
                        } else {
                            let mut m = decl.bounds.iter().map(|s| s.to_str());
-                           ": " + m.collect::<~[~str]>().connect(" + ")
+                           ": " + m.collect::<Vec<~str>>().connect(" + ")
                        },
                        arrow = match decl.decl.output { clean::Unit => "no", _ => "yes" },
                        ret = decl.decl.output)
@@ -397,10 +388,10 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             clean::BareFunction(ref decl) => {
                 write!(f.buf, "{}{}fn{}{}",
                        FnStyleSpace(decl.fn_style),
-                       match decl.abi {
-                           ref x if "" == *x => "".to_owned(),
-                           ref x if "\"Rust\"" == *x => "".to_owned(),
-                           ref s => " " + *s + " ",
+                       match decl.abi.as_slice() {
+                           "" => " extern ".to_owned(),
+                           "\"Rust\"" => "".to_owned(),
+                           s => format!(" extern {} ", s)
                        },
                        decl.generics,
                        decl.decl)
@@ -517,7 +508,6 @@ impl fmt::Show for FnStyleSpace {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self.get() {
             ast::UnsafeFn => write!(f.buf, "unsafe "),
-            ast::ExternFn => write!(f.buf, "extern "),
             ast::NormalFn => Ok(())
         }
     }
index f452be3277871776a95345742747a87933707514..bddf857534424716f0cea6e98e895e9bde6333fe 100644 (file)
@@ -27,7 +27,9 @@
 /// Highlights some source code, returning the HTML output.
 pub fn highlight(src: &str, class: Option<&str>) -> ~str {
     let sess = parse::new_parse_sess();
-    let fm = parse::string_to_filemap(&sess, src.to_owned(), "<stdin>".to_owned());
+    let fm = parse::string_to_filemap(&sess,
+                                      src.to_strbuf(),
+                                      "<stdin>".to_strbuf());
 
     let mut out = io::MemWriter::new();
     doit(&sess,
@@ -70,11 +72,11 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader, class: Option<&
                 hi: test,
                 expn_info: None,
             }).unwrap();
-            if snip.contains("/") {
+            if snip.as_slice().contains("/") {
                 try!(write!(out, "<span class='comment'>{}</span>",
-                              Escape(snip)));
+                              Escape(snip.as_slice())));
             } else {
-                try!(write!(out, "{}", Escape(snip)));
+                try!(write!(out, "{}", Escape(snip.as_slice())));
             }
         }
         last = next.sp.hi;
@@ -171,10 +173,10 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader, class: Option<&
         // stringifying this token
         let snip = sess.span_diagnostic.cm.span_to_snippet(next.sp).unwrap();
         if klass == "" {
-            try!(write!(out, "{}", Escape(snip)));
+            try!(write!(out, "{}", Escape(snip.as_slice())));
         } else {
             try!(write!(out, "<span class='{}'>{}</span>", klass,
-                          Escape(snip)));
+                          Escape(snip.as_slice())));
         }
     }
 
index 9d6b0ec55170e28ad34c8d4773044fa05f3f7375..0141df34a6c229986e552b79abbb52ff32efa390 100644 (file)
 #![allow(non_camel_case_types)]
 
 use libc;
+use std::cell::RefCell;
 use std::fmt;
 use std::io;
-use std::local_data;
-use std::str;
 use std::slice;
+use std::str;
 use collections::HashMap;
 
 use html::toc::TocBuilder;
@@ -139,7 +139,7 @@ fn stripped_filtered_line<'a>(s: &'a str) -> Option<&'a str> {
     }
 }
 
-local_data_key!(used_header_map: HashMap<~str, uint>)
+local_data_key!(used_header_map: RefCell<HashMap<~str, uint>>)
 
 pub fn render(w: &mut io::Writer, s: &str, print_toc: bool) -> fmt::Result {
     extern fn block(ob: *mut hoedown_buffer, text: *hoedown_buffer,
@@ -216,15 +216,12 @@ pub fn render(w: &mut io::Writer, s: &str, print_toc: bool) -> fmt::Result {
         let opaque = unsafe { &mut *((*opaque).opaque as *mut MyOpaque) };
 
         // Make sure our hyphenated ID is unique for this page
-        let id = local_data::get_mut(used_header_map, |map| {
-            let map = map.unwrap();
-            match map.find_mut(&id) {
-                None => {}
-                Some(a) => { *a += 1; return format!("{}-{}", id, *a - 1) }
-            }
-            map.insert(id.clone(), 1);
-            id.clone()
-        });
+        let map = used_header_map.get().unwrap();
+        let id = match map.borrow_mut().find_mut(&id) {
+            None => id,
+            Some(a) => { *a += 1; format!("{}-{}", id, *a - 1) }
+        };
+        map.borrow_mut().insert(id.clone(), 1);
 
         let sec = match opaque.toc_builder {
             Some(ref mut builder) => {
@@ -348,7 +345,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
 /// used at the beginning of rendering an entire HTML page to reset from the
 /// previous state (if any).
 pub fn reset_headers() {
-    local_data::set(used_header_map, HashMap::new())
+    used_header_map.replace(Some(RefCell::new(HashMap::new())));
 }
 
 impl<'a> fmt::Show for Markdown<'a> {
index a0d21bbf1497a035bedc9bf58b85e7e0164e63d0..0bdf0818c8e82ab780d47bc522e69f9747c86936 100644 (file)
@@ -37,7 +37,6 @@
 use std::fmt;
 use std::io::{fs, File, BufferedWriter, MemWriter, BufferedReader};
 use std::io;
-use std::local_data;
 use std::str;
 use std::strbuf::StrBuf;
 
@@ -243,24 +242,22 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
     }
 
     // Crawl the crate to build various caches used for the output
-    let mut cache = local_data::get(::analysiskey, |analysis| {
-        let public_items = analysis.map(|a| a.public_items.clone());
-        let public_items = public_items.unwrap_or(NodeSet::new());
-        Cache {
-            impls: HashMap::new(),
-            typarams: HashMap::new(),
-            paths: HashMap::new(),
-            traits: HashMap::new(),
-            implementors: HashMap::new(),
-            stack: Vec::new(),
-            parent_stack: Vec::new(),
-            search_index: Vec::new(),
-            extern_locations: HashMap::new(),
-            privmod: false,
-            public_items: public_items,
-            orphan_methods: Vec::new(),
-        }
-    });
+    let public_items = ::analysiskey.get().map(|a| a.public_items.clone());
+    let public_items = public_items.unwrap_or(NodeSet::new());
+    let mut cache = Cache {
+        impls: HashMap::new(),
+        typarams: HashMap::new(),
+        paths: HashMap::new(),
+        traits: HashMap::new(),
+        implementors: HashMap::new(),
+        stack: Vec::new(),
+        parent_stack: Vec::new(),
+        search_index: Vec::new(),
+        extern_locations: HashMap::new(),
+        privmod: false,
+        public_items: public_items,
+        orphan_methods: Vec::new(),
+    };
     cache.stack.push(krate.name.clone());
     krate = cache.fold_crate(krate);
 
@@ -552,7 +549,8 @@ fn emit_source(&mut self, filename: &str) -> io::IoResult<()> {
             root_path.push_str("../");
         });
 
-        cur.push(p.filename().expect("source has no filename") + bytes!(".html"));
+        cur.push(Vec::from_slice(p.filename().expect("source has no filename"))
+                 .append(bytes!(".html")));
         let mut w = BufferedWriter::new(try!(File::create(&cur)));
 
         let title = format!("{} -- source", cur.filename_display());
@@ -833,7 +831,7 @@ fn krate(self, mut krate: clean::Crate, cache: Cache) -> io::IoResult<()> {
         item.name = Some(krate.name);
 
         // using a rwarc makes this parallelizable in the future
-        local_data::set(cache_key, Arc::new(cache));
+        cache_key.replace(Some(Arc::new(cache)));
 
         let mut work = vec!((self, item));
         loop {
@@ -859,7 +857,7 @@ fn render(w: io::File, cx: &mut Context, it: &clean::Item,
             info!("Rendering an item to {}", w.path().display());
             // A little unfortunate that this is done like this, but it sure
             // does make formatting *a lot* nicer.
-            local_data::set(current_location_key, cx.current.clone());
+            current_location_key.replace(Some(cx.current.clone()));
 
             let mut title = StrBuf::from_str(cx.current.connect("::"));
             if pushname {
@@ -1299,31 +1297,28 @@ fn meth(w: &mut Writer, m: &clean::TraitMethod) -> fmt::Result {
         try!(write!(w, "</div>"));
     }
 
-    local_data::get(cache_key, |cache| {
-        let cache = cache.unwrap();
-        match cache.implementors.find(&it.id) {
-            Some(implementors) => {
-                try!(write!(w, "
-                    <h2 id='implementors'>Implementors</h2>
-                    <ul class='item-list'>
-                "));
-                for i in implementors.iter() {
-                    match *i {
-                        PathType(ref ty) => {
-                            try!(write!(w, "<li><code>{}</code></li>", *ty));
-                        }
-                        OtherType(ref generics, ref trait_, ref for_) => {
-                            try!(write!(w, "<li><code>impl{} {} for {}</code></li>",
-                                          *generics, *trait_, *for_));
-                        }
+    match cache_key.get().unwrap().implementors.find(&it.id) {
+        Some(implementors) => {
+            try!(write!(w, "
+                <h2 id='implementors'>Implementors</h2>
+                <ul class='item-list'>
+            "));
+            for i in implementors.iter() {
+                match *i {
+                    PathType(ref ty) => {
+                        try!(write!(w, "<li><code>{}</code></li>", *ty));
+                    }
+                    OtherType(ref generics, ref trait_, ref for_) => {
+                        try!(write!(w, "<li><code>impl{} {} for {}</code></li>",
+                                      *generics, *trait_, *for_));
                     }
                 }
-                try!(write!(w, "</ul>"));
             }
-            None => {}
+            try!(write!(w, "</ul>"));
         }
-        Ok(())
-    })
+        None => {}
+    }
+    Ok(())
 }
 
 fn render_method(w: &mut Writer, meth: &clean::Item) -> fmt::Result {
@@ -1550,51 +1545,48 @@ fn render_struct(w: &mut Writer, it: &clean::Item,
 }
 
 fn render_methods(w: &mut Writer, it: &clean::Item) -> fmt::Result {
-    local_data::get(cache_key, |cache| {
-        let c = cache.unwrap();
-        match c.impls.find(&it.id) {
-            Some(v) => {
-                let mut non_trait = v.iter().filter(|p| {
-                    p.ref0().trait_.is_none()
-                });
-                let non_trait = non_trait.collect::<Vec<&(clean::Impl, Option<~str>)>>();
-                let mut traits = v.iter().filter(|p| {
-                    p.ref0().trait_.is_some()
-                });
-                let traits = traits.collect::<Vec<&(clean::Impl, Option<~str>)>>();
-
-                if non_trait.len() > 0 {
-                    try!(write!(w, "<h2 id='methods'>Methods</h2>"));
-                    for &(ref i, ref dox) in non_trait.move_iter() {
+    match cache_key.get().unwrap().impls.find(&it.id) {
+        Some(v) => {
+            let mut non_trait = v.iter().filter(|p| {
+                p.ref0().trait_.is_none()
+            });
+            let non_trait = non_trait.collect::<Vec<&(clean::Impl, Option<~str>)>>();
+            let mut traits = v.iter().filter(|p| {
+                p.ref0().trait_.is_some()
+            });
+            let traits = traits.collect::<Vec<&(clean::Impl, Option<~str>)>>();
+
+            if non_trait.len() > 0 {
+                try!(write!(w, "<h2 id='methods'>Methods</h2>"));
+                for &(ref i, ref dox) in non_trait.move_iter() {
+                    try!(render_impl(w, i, dox));
+                }
+            }
+            if traits.len() > 0 {
+                try!(write!(w, "<h2 id='implementations'>Trait \
+                                  Implementations</h2>"));
+                let mut any_derived = false;
+                for & &(ref i, ref dox) in traits.iter() {
+                    if !i.derived {
                         try!(render_impl(w, i, dox));
+                    } else {
+                        any_derived = true;
                     }
                 }
-                if traits.len() > 0 {
-                    try!(write!(w, "<h2 id='implementations'>Trait \
-                                      Implementations</h2>"));
-                    let mut any_derived = false;
-                    for & &(ref i, ref dox) in traits.iter() {
-                        if !i.derived {
+                if any_derived {
+                    try!(write!(w, "<h3 id='derived_implementations'>Derived Implementations \
+                                </h3>"));
+                    for &(ref i, ref dox) in traits.move_iter() {
+                        if i.derived {
                             try!(render_impl(w, i, dox));
-                        } else {
-                            any_derived = true;
-                        }
-                    }
-                    if any_derived {
-                        try!(write!(w, "<h3 id='derived_implementations'>Derived Implementations \
-                                    </h3>"));
-                        for &(ref i, ref dox) in traits.move_iter() {
-                            if i.derived {
-                                try!(render_impl(w, i, dox));
-                            }
                         }
                     }
                 }
             }
-            None => {}
         }
-        Ok(())
-    })
+        None => {}
+    }
+    Ok(())
 }
 
 fn render_impl(w: &mut Writer, i: &clean::Impl,
@@ -1644,9 +1636,8 @@ fn docmeth(w: &mut Writer, item: &clean::Item,
     match trait_id {
         None => {}
         Some(id) => {
-            try!(local_data::get(cache_key, |cache| {
-                let cache = cache.unwrap();
-                match cache.traits.find(&id) {
+            try!({
+                match cache_key.get().unwrap().traits.find(&id) {
                     Some(t) => {
                         for method in t.methods.iter() {
                             let n = method.item().name.clone();
@@ -1661,7 +1652,7 @@ fn docmeth(w: &mut Writer, item: &clean::Item,
                     None => {}
                 }
                 Ok(())
-            }))
+            })
         }
     }
     try!(write!(w, "</div>"));
index 24b3e1128ea5fd328f35ee5e6189e39961d8fe52..72b474147335c7002c5fc1f67ca46ea2f01537be 100644 (file)
@@ -28,7 +28,6 @@
 extern crate log;
 extern crate libc;
 
-use std::local_data;
 use std::io;
 use std::io::{File, MemWriter};
 use std::str;
@@ -86,7 +85,7 @@ pub mod html {
 type Output = (clean::Crate, Vec<plugins::PluginJson> );
 
 pub fn main() {
-    std::os::set_exit_status(main_args(std::os::args()));
+    std::os::set_exit_status(main_args(std::os::args().as_slice()));
 }
 
 pub fn opts() -> Vec<getopts::OptGroup> {
@@ -276,7 +275,7 @@ fn rust_input(cratefile: &str, matches: &getopts::Matches) -> Output {
                        &cr)
     }).unwrap();
     info!("finished with rustc");
-    local_data::set(analysiskey, analysis);
+    analysiskey.replace(Some(analysis));
 
     // Process all of the crate attributes, extracting plugin metadata along
     // with the passes which we are supposed to run.
index f8a2382c0282625a4424b7bc1dc4db92950434dd..38d1b2a14e10482203d044cbc07cd9ab26548d44 100644 (file)
@@ -11,7 +11,6 @@
 use collections::HashSet;
 use rustc::util::nodemap::NodeSet;
 use std::cmp;
-use std::local_data;
 use std::strbuf::StrBuf;
 use std::uint;
 use syntax::ast;
@@ -86,13 +85,11 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
 
 /// Strip private items from the point of view of a crate or externally from a
 /// crate, specified by the `xcrate` flag.
-pub fn strip_private(krate: clean::Crate) -> plugins::PluginResult {
+pub fn strip_private(mut krate: clean::Crate) -> plugins::PluginResult {
     // This stripper collects all *retained* nodes.
     let mut retained = HashSet::new();
-    let exported_items = local_data::get(super::analysiskey, |analysis| {
-        analysis.unwrap().exported_items.clone()
-    });
-    let mut krate = krate;
+    let analysis = super::analysiskey.get().unwrap();
+    let exported_items = analysis.exported_items.clone();
 
     // strip all private items
     {
index 0b8434d7d17957c8afdc7b382bba9c5b19493999..898f5856694353f06f556dc3ce39140312715497 100644 (file)
@@ -12,7 +12,6 @@
 use std::char;
 use std::io;
 use std::io::{Process, TempDir};
-use std::local_data;
 use std::os;
 use std::str;
 use std::strbuf::StrBuf;
@@ -75,7 +74,7 @@ pub fn run(input: &str,
         maybe_typed: core::NotTyped(sess),
         src: input_path,
     };
-    local_data::set(super::ctxtkey, ctx);
+    super::ctxtkey.replace(Some(ctx));
 
     let mut v = RustdocVisitor::new(ctx, None);
     v.visit(&ctx.krate);
index fbacf1ca314fcd0446b23f798a5c822f6b674015..433073b43c44a2e681fe77a02f24e308704c07df 100644 (file)
@@ -31,8 +31,9 @@ pub struct Guard<'a> {
 }
 
 struct Inner {
-    queue: Vec<BlockedTask>,
+    queue: Vec<(BlockedTask, uint)>,
     held: bool,
+    closed: bool,
 }
 
 impl Access {
@@ -41,20 +42,22 @@ pub fn new() -> Access {
             inner: UnsafeArc::new(Inner {
                 queue: vec![],
                 held: false,
+                closed: false,
             })
         }
     }
 
-    pub fn grant<'a>(&'a mut self, missile: HomingMissile) -> Guard<'a> {
+    pub fn grant<'a>(&'a mut self, token: uint,
+                     missile: HomingMissile) -> Guard<'a> {
         // This unsafety is actually OK because the homing missile argument
         // guarantees that we're on the same event loop as all the other objects
         // attempting to get access granted.
-        let inner: &mut Inner = unsafe { cast::transmute(self.inner.get()) };
+        let inner: &mut Inner = unsafe { &mut *self.inner.get() };
 
         if inner.held {
             let t: Box<Task> = Local::take();
             t.deschedule(1, |task| {
-                inner.queue.push(task);
+                inner.queue.push((task, token));
                 Ok(())
             });
             assert!(inner.held);
@@ -64,6 +67,26 @@ pub fn grant<'a>(&'a mut self, missile: HomingMissile) -> Guard<'a> {
 
         Guard { access: self, missile: Some(missile) }
     }
+
+    pub fn close(&self, _missile: &HomingMissile) {
+        // This unsafety is OK because with a homing missile we're guaranteed to
+        // be the only task looking at the `closed` flag (and are therefore
+        // allowed to modify it). Additionally, no atomics are necessary because
+        // everyone's running on the same thread and has already done the
+        // necessary synchronization to be running on this thread.
+        unsafe { (*self.inner.get()).closed = true; }
+    }
+
+    // Dequeue a blocked task with a specified token. This is unsafe because it
+    // is only safe to invoke while on the home event loop, and there is no
+    // guarantee that this i being invoked on the home event loop.
+    pub unsafe fn dequeue(&mut self, token: uint) -> Option<BlockedTask> {
+        let inner: &mut Inner = &mut *self.inner.get();
+        match inner.queue.iter().position(|&(_, t)| t == token) {
+            Some(i) => Some(inner.queue.remove(i).unwrap().val0()),
+            None => None,
+        }
+    }
 }
 
 impl Clone for Access {
@@ -72,6 +95,14 @@ fn clone(&self) -> Access {
     }
 }
 
+impl<'a> Guard<'a> {
+    pub fn is_closed(&self) -> bool {
+        // See above for why this unsafety is ok, it just applies to the read
+        // instead of the write.
+        unsafe { (*self.access.inner.get()).closed }
+    }
+}
+
 #[unsafe_destructor]
 impl<'a> Drop for Guard<'a> {
     fn drop(&mut self) {
@@ -92,9 +123,9 @@ fn drop(&mut self) {
             // scheduled on this scheduler. Because we might be woken up on some
             // other scheduler, we drop our homing missile before we reawaken
             // the task.
-            Some(task) => {
+            Some((task, _)) => {
                 drop(self.missile.take());
-                let _ = task.wake().map(|t| t.reawaken());
+                task.reawaken();
             }
             None => { inner.held = false; }
         }
index 94a084fe055aefee17ba157532e4188b4de35219..4766630b0f421ecd05024a2377a398fa786c9c6a 100644 (file)
@@ -33,7 +33,7 @@ struct Ctx {
 
 impl GetAddrInfoRequest {
     pub fn run(loop_: &Loop, node: Option<&str>, service: Option<&str>,
-               hints: Option<ai::Hint>) -> Result<~[ai::Info], UvError> {
+               hints: Option<ai::Hint>) -> Result<Vec<ai::Info>, UvError> {
         assert!(node.is_some() || service.is_some());
         let (_c_node, c_node_ptr) = match node {
             Some(n) => {
@@ -134,7 +134,7 @@ fn each_ai_flag(_f: |c_int, ai::Flag|) {
 }
 
 // Traverse the addrinfo linked list, producing a vector of Rust socket addresses
-pub fn accum_addrinfo(addr: &Addrinfo) -> ~[ai::Info] {
+pub fn accum_addrinfo(addr: &Addrinfo) -> Vec<ai::Info> {
     unsafe {
         let mut addr = addr.handle;
 
@@ -180,6 +180,6 @@ pub fn accum_addrinfo(addr: &Addrinfo) -> ~[ai::Info] {
             }
         }
 
-        return addrs.move_iter().collect();
+        addrs
     }
 }
index 84d4b6b4702c3de93ba82fab9f4e6c60d3583489..968029a6edc8cebbe765e866044d5bcb9b0463bd 100644 (file)
@@ -84,6 +84,7 @@ fn start(argc: int, argv: **u8) -> int {
 mod macros;
 
 mod access;
+mod timeout;
 mod homing;
 mod queue;
 mod rc;
index a2701a57ca91753caf57de8753d1ddc3a556390c..999da1cfda718f7fa3a1c456a30f6797e6a12db2 100644 (file)
 use libc::{size_t, ssize_t, c_int, c_void, c_uint};
 use libc;
 use std::cast;
-use std::io::{IoError, IoResult};
+use std::io;
+use std::io::IoError;
 use std::io::net::ip;
 use std::mem;
 use std::ptr;
 use std::rt::rtio;
 use std::rt::task::BlockedTask;
 
-use access::Access;
 use homing::{HomingIO, HomeHandle};
 use rc::Refcount;
 use stream::StreamWatcher;
 use super::{Loop, Request, UvError, Buf, status_to_io_result,
             uv_error_to_io_error, UvHandle, slice_to_uv_buf,
             wait_until_woken_after, wakeup};
-use timer::TimerWatcher;
+use timeout::{AccessTimeout, AcceptTimeout, ConnectCtx};
 use uvio::UvIoFactory;
 use uvll;
 
@@ -145,190 +145,6 @@ fn socket_name(sk: SocketNameKind,
         n => Err(uv_error_to_io_error(UvError(n)))
     }
 }
-////////////////////////////////////////////////////////////////////////////////
-// Helpers for handling timeouts, shared for pipes/tcp
-////////////////////////////////////////////////////////////////////////////////
-
-pub struct ConnectCtx {
-    pub status: c_int,
-    pub task: Option<BlockedTask>,
-    pub timer: Option<Box<TimerWatcher>>,
-}
-
-pub struct AcceptTimeout {
-    timer: Option<TimerWatcher>,
-    timeout_tx: Option<Sender<()>>,
-    timeout_rx: Option<Receiver<()>>,
-}
-
-impl ConnectCtx {
-    pub fn connect<T>(
-        mut self, obj: T, timeout: Option<u64>, io: &mut UvIoFactory,
-        f: |&Request, &T, uvll::uv_connect_cb| -> libc::c_int
-    ) -> Result<T, UvError> {
-        let mut req = Request::new(uvll::UV_CONNECT);
-        let r = f(&req, &obj, connect_cb);
-        return match r {
-            0 => {
-                req.defuse(); // uv callback now owns this request
-                match timeout {
-                    Some(t) => {
-                        let mut timer = TimerWatcher::new(io);
-                        timer.start(timer_cb, t, 0);
-                        self.timer = Some(timer);
-                    }
-                    None => {}
-                }
-                wait_until_woken_after(&mut self.task, &io.loop_, || {
-                    let data = &self as *_;
-                    match self.timer {
-                        Some(ref mut timer) => unsafe { timer.set_data(data) },
-                        None => {}
-                    }
-                    req.set_data(data);
-                });
-                // Make sure an erroneously fired callback doesn't have access
-                // to the context any more.
-                req.set_data(0 as *int);
-
-                // If we failed because of a timeout, drop the TcpWatcher as
-                // soon as possible because it's data is now set to null and we
-                // want to cancel the callback ASAP.
-                match self.status {
-                    0 => Ok(obj),
-                    n => { drop(obj); Err(UvError(n)) }
-                }
-            }
-            n => Err(UvError(n))
-        };
-
-        extern fn timer_cb(handle: *uvll::uv_timer_t) {
-            // Don't close the corresponding tcp request, just wake up the task
-            // and let RAII take care of the pending watcher.
-            let cx: &mut ConnectCtx = unsafe {
-                &mut *(uvll::get_data_for_uv_handle(handle) as *mut ConnectCtx)
-            };
-            cx.status = uvll::ECANCELED;
-            wakeup(&mut cx.task);
-        }
-
-        extern fn connect_cb(req: *uvll::uv_connect_t, status: c_int) {
-            // This callback can be invoked with ECANCELED if the watcher is
-            // closed by the timeout callback. In that case we just want to free
-            // the request and be along our merry way.
-            let req = Request::wrap(req);
-            if status == uvll::ECANCELED { return }
-
-            // Apparently on windows when the handle is closed this callback may
-            // not be invoked with ECANCELED but rather another error code.
-            // Either ways, if the data is null, then our timeout has expired
-            // and there's nothing we can do.
-            let data = unsafe { uvll::get_data_for_req(req.handle) };
-            if data.is_null() { return }
-
-            let cx: &mut ConnectCtx = unsafe { &mut *(data as *mut ConnectCtx) };
-            cx.status = status;
-            match cx.timer {
-                Some(ref mut t) => t.stop(),
-                None => {}
-            }
-            // Note that the timer callback doesn't cancel the connect request
-            // (that's the job of uv_close()), so it's possible for this
-            // callback to get triggered after the timeout callback fires, but
-            // before the task wakes up. In that case, we did indeed
-            // successfully connect, but we don't need to wake someone up. We
-            // updated the status above (correctly so), and the task will pick
-            // up on this when it wakes up.
-            if cx.task.is_some() {
-                wakeup(&mut cx.task);
-            }
-        }
-    }
-}
-
-impl AcceptTimeout {
-    pub fn new() -> AcceptTimeout {
-        AcceptTimeout { timer: None, timeout_tx: None, timeout_rx: None }
-    }
-
-    pub fn accept<T: Send>(&mut self, c: &Receiver<IoResult<T>>) -> IoResult<T> {
-        match self.timeout_rx {
-            None => c.recv(),
-            Some(ref rx) => {
-                use std::comm::Select;
-
-                // Poll the incoming channel first (don't rely on the order of
-                // select just yet). If someone's pending then we should return
-                // them immediately.
-                match c.try_recv() {
-                    Ok(data) => return data,
-                    Err(..) => {}
-                }
-
-                // Use select to figure out which channel gets ready first. We
-                // do some custom handling of select to ensure that we never
-                // actually drain the timeout channel (we'll keep seeing the
-                // timeout message in the future).
-                let s = Select::new();
-                let mut timeout = s.handle(rx);
-                let mut data = s.handle(c);
-                unsafe {
-                    timeout.add();
-                    data.add();
-                }
-                if s.wait() == timeout.id() {
-                    Err(uv_error_to_io_error(UvError(uvll::ECANCELED)))
-                } else {
-                    c.recv()
-                }
-            }
-        }
-    }
-
-    pub fn clear(&mut self) {
-        // Clear any previous timeout by dropping the timer and transmission
-        // channels
-        drop((self.timer.take(),
-              self.timeout_tx.take(),
-              self.timeout_rx.take()))
-    }
-
-    pub fn set_timeout<U, T: UvHandle<U> + HomingIO>(
-        &mut self, ms: u64, t: &mut T
-    ) {
-        // If we have a timeout, lazily initialize the timer which will be used
-        // to fire when the timeout runs out.
-        if self.timer.is_none() {
-            let _m = t.fire_homing_missile();
-            let loop_ = Loop::wrap(unsafe {
-                uvll::get_loop_for_uv_handle(t.uv_handle())
-            });
-            let mut timer = TimerWatcher::new_home(&loop_, t.home().clone());
-            unsafe {
-                timer.set_data(self as *mut _ as *AcceptTimeout);
-            }
-            self.timer = Some(timer);
-        }
-
-        // Once we've got a timer, stop any previous timeout, reset it for the
-        // current one, and install some new channels to send/receive data on
-        let timer = self.timer.get_mut_ref();
-        timer.stop();
-        timer.start(timer_cb, ms, 0);
-        let (tx, rx) = channel();
-        self.timeout_tx = Some(tx);
-        self.timeout_rx = Some(rx);
-
-        extern fn timer_cb(timer: *uvll::uv_timer_t) {
-            let acceptor: &mut AcceptTimeout = unsafe {
-                &mut *(uvll::get_data_for_uv_handle(timer) as *mut AcceptTimeout)
-            };
-            // This send can never fail because if this timer is active then the
-            // receiving channel is guaranteed to be alive
-            acceptor.timeout_tx.get_ref().send(());
-        }
-    }
-}
 
 ////////////////////////////////////////////////////////////////////////////////
 /// TCP implementation
@@ -344,8 +160,8 @@ pub struct TcpWatcher {
     // stream object, so we use these access guards in order to arbitrate among
     // multiple concurrent reads and writes. Note that libuv *can* read and
     // write simultaneously, it just can't read and read simultaneously.
-    read_access: Access,
-    write_access: Access,
+    read_access: AccessTimeout,
+    write_access: AccessTimeout,
 }
 
 pub struct TcpListener {
@@ -379,8 +195,8 @@ fn new_home(loop_: &Loop, home: HomeHandle) -> TcpWatcher {
             handle: handle,
             stream: StreamWatcher::new(handle),
             refcount: Refcount::new(),
-            read_access: Access::new(),
-            write_access: Access::new(),
+            read_access: AccessTimeout::new(),
+            write_access: AccessTimeout::new(),
         }
     }
 
@@ -411,14 +227,20 @@ fn socket_name(&mut self) -> Result<ip::SocketAddr, IoError> {
 impl rtio::RtioTcpStream for TcpWatcher {
     fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> {
         let m = self.fire_homing_missile();
-        let _g = self.read_access.grant(m);
+        let guard = try!(self.read_access.grant(m));
+
+        // see comments in close_read about this check
+        if guard.access.is_closed() {
+            return Err(io::standard_error(io::EndOfFile))
+        }
+
         self.stream.read(buf).map_err(uv_error_to_io_error)
     }
 
     fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
         let m = self.fire_homing_missile();
-        let _g = self.write_access.grant(m);
-        self.stream.write(buf).map_err(uv_error_to_io_error)
+        let guard = try!(self.write_access.grant(m));
+        self.stream.write(buf, guard.can_timeout).map_err(uv_error_to_io_error)
     }
 
     fn peer_name(&mut self) -> Result<ip::SocketAddr, IoError> {
@@ -461,40 +283,53 @@ fn clone(&self) -> Box<rtio::RtioTcpStream:Send> {
             stream: StreamWatcher::new(self.handle),
             home: self.home.clone(),
             refcount: self.refcount.clone(),
-            write_access: self.write_access.clone(),
             read_access: self.read_access.clone(),
+            write_access: self.write_access.clone(),
         } as Box<rtio::RtioTcpStream:Send>
     }
 
+    fn close_read(&mut self) -> Result<(), IoError> {
+        // see comments in PipeWatcher::close_read
+        let task = {
+            let m = self.fire_homing_missile();
+            self.read_access.access.close(&m);
+    self.stream.cancel_read(uvll::EOF as libc::ssize_t)
+        };
+        let _ = task.map(|t| t.reawaken());
+        Ok(())
+    }
+
     fn close_write(&mut self) -> Result<(), IoError> {
-        struct Ctx {
-            slot: Option<BlockedTask>,
-            status: c_int,
-        }
-        let mut req = Request::new(uvll::UV_SHUTDOWN);
+        let _m = self.fire_homing_missile();
+        shutdown(self.handle, &self.uv_loop())
+    }
 
-        return match unsafe {
-            uvll::uv_shutdown(req.handle, self.handle, shutdown_cb)
-        } {
-            0 => {
-                req.defuse(); // uv callback now owns this request
-                let mut cx = Ctx { slot: None, status: 0 };
+    fn set_timeout(&mut self, timeout: Option<u64>) {
+        self.set_read_timeout(timeout);
+        self.set_write_timeout(timeout);
+    }
 
-                wait_until_woken_after(&mut cx.slot, &self.uv_loop(), || {
-                    req.set_data(&cx);
-                });
+    fn set_read_timeout(&mut self, ms: Option<u64>) {
+        let _m = self.fire_homing_missile();
+        let loop_ = self.uv_loop();
+        self.read_access.set_timeout(ms, &self.home, &loop_, cancel_read,
+                                     &self.stream as *_ as uint);
 
-                status_to_io_result(cx.status)
-            }
-            n => Err(uv_error_to_io_error(UvError(n)))
-        };
+        fn cancel_read(stream: uint) -> Option<BlockedTask> {
+            let stream: &mut StreamWatcher = unsafe { cast::transmute(stream) };
+            stream.cancel_read(uvll::ECANCELED as ssize_t)
+        }
+    }
 
-        extern fn shutdown_cb(req: *uvll::uv_shutdown_t, status: libc::c_int) {
-            let req = Request::wrap(req);
-            assert!(status != uvll::ECANCELED);
-            let cx: &mut Ctx = unsafe { req.get_data() };
-            cx.status = status;
-            wakeup(&mut cx.slot);
+    fn set_write_timeout(&mut self, ms: Option<u64>) {
+        let _m = self.fire_homing_missile();
+        let loop_ = self.uv_loop();
+        self.write_access.set_timeout(ms, &self.home, &loop_, cancel_write,
+                                      &self.stream as *_ as uint);
+
+        fn cancel_write(stream: uint) -> Option<BlockedTask> {
+            let stream: &mut StreamWatcher = unsafe { cast::transmute(stream) };
+            stream.cancel_write()
         }
     }
 }
@@ -630,6 +465,7 @@ fn dont_accept_simultaneously(&mut self) -> Result<(), IoError> {
     }
 
     fn set_timeout(&mut self, ms: Option<u64>) {
+        let _m = self.fire_homing_missile();
         match ms {
             None => self.timeout.clear(),
             Some(ms) => self.timeout.set_timeout(ms, &mut *self.listener),
@@ -647,8 +483,22 @@ pub struct UdpWatcher {
 
     // See above for what these fields are
     refcount: Refcount,
-    read_access: Access,
-    write_access: Access,
+    read_access: AccessTimeout,
+    write_access: AccessTimeout,
+
+    blocked_sender: Option<BlockedTask>,
+}
+
+struct UdpRecvCtx {
+    task: Option<BlockedTask>,
+    buf: Option<Buf>,
+    result: Option<(ssize_t, Option<ip::SocketAddr>)>,
+}
+
+struct UdpSendCtx {
+    result: c_int,
+    data: Option<Vec<u8>>,
+    udp: *mut UdpWatcher,
 }
 
 impl UdpWatcher {
@@ -658,8 +508,9 @@ pub fn bind(io: &mut UvIoFactory, address: ip::SocketAddr)
             handle: unsafe { uvll::malloc_handle(uvll::UV_UDP) },
             home: io.make_handle(),
             refcount: Refcount::new(),
-            read_access: Access::new(),
-            write_access: Access::new(),
+            read_access: AccessTimeout::new(),
+            write_access: AccessTimeout::new(),
+            blocked_sender: None,
         };
         assert_eq!(unsafe {
             uvll::uv_udp_init(io.uv_loop(), udp.handle)
@@ -695,20 +546,15 @@ impl rtio::RtioUdpSocket for UdpWatcher {
     fn recvfrom(&mut self, buf: &mut [u8])
         -> Result<(uint, ip::SocketAddr), IoError>
     {
-        struct Ctx {
-            task: Option<BlockedTask>,
-            buf: Option<Buf>,
-            result: Option<(ssize_t, Option<ip::SocketAddr>)>,
-        }
         let loop_ = self.uv_loop();
         let m = self.fire_homing_missile();
-        let _g = self.read_access.grant(m);
+        let _guard = try!(self.read_access.grant(m));
 
-        let a = match unsafe {
+        return match unsafe {
             uvll::uv_udp_recv_start(self.handle, alloc_cb, recv_cb)
         } {
             0 => {
-                let mut cx = Ctx {
+                let mut cx = UdpRecvCtx {
                     task: None,
                     buf: Some(slice_to_uv_buf(buf)),
                     result: None,
@@ -725,14 +571,13 @@ struct Ctx {
             }
             n => Err(uv_error_to_io_error(UvError(n)))
         };
-        return a;
 
         extern fn alloc_cb(handle: *uvll::uv_udp_t,
                            _suggested_size: size_t,
                            buf: *mut Buf) {
             unsafe {
-                let cx: &mut Ctx =
-                    cast::transmute(uvll::get_data_for_uv_handle(handle));
+                let cx = uvll::get_data_for_uv_handle(handle);
+                let cx = &mut *(cx as *mut UdpRecvCtx);
                 *buf = cx.buf.take().expect("recv alloc_cb called more than once")
             }
         }
@@ -740,8 +585,8 @@ struct Ctx {
         extern fn recv_cb(handle: *uvll::uv_udp_t, nread: ssize_t, buf: *Buf,
                           addr: *libc::sockaddr, _flags: c_uint) {
             assert!(nread != uvll::ECANCELED as ssize_t);
-            let cx: &mut Ctx = unsafe {
-                cast::transmute(uvll::get_data_for_uv_handle(handle))
+            let cx = unsafe {
+                &mut *(uvll::get_data_for_uv_handle(handle) as *mut UdpRecvCtx)
             };
 
             // When there's no data to read the recv callback can be a no-op.
@@ -752,13 +597,7 @@ struct Ctx {
                 return
             }
 
-            unsafe {
-                assert_eq!(uvll::uv_udp_recv_stop(handle), 0)
-            }
-
-            let cx: &mut Ctx = unsafe {
-                cast::transmute(uvll::get_data_for_uv_handle(handle))
-            };
+            unsafe { assert_eq!(uvll::uv_udp_recv_stop(handle), 0) }
             let addr = if addr == ptr::null() {
                 None
             } else {
@@ -771,42 +610,68 @@ struct Ctx {
     }
 
     fn sendto(&mut self, buf: &[u8], dst: ip::SocketAddr) -> Result<(), IoError> {
-        struct Ctx { task: Option<BlockedTask>, result: c_int }
-
         let m = self.fire_homing_missile();
         let loop_ = self.uv_loop();
-        let _g = self.write_access.grant(m);
+        let guard = try!(self.write_access.grant(m));
 
         let mut req = Request::new(uvll::UV_UDP_SEND);
-        let buf = slice_to_uv_buf(buf);
         let (addr, _len) = addr_to_sockaddr(dst);
-        let result = unsafe {
-            let addr_p = &addr as *libc::sockaddr_storage;
-            uvll::uv_udp_send(req.handle, self.handle, [buf],
-                              addr_p as *libc::sockaddr, send_cb)
+        let addr_p = &addr as *_ as *libc::sockaddr;
+
+        // see comments in StreamWatcher::write for why we may allocate a buffer
+        // here.
+        let data = if guard.can_timeout {Some(Vec::from_slice(buf))} else {None};
+        let uv_buf = if guard.can_timeout {
+            slice_to_uv_buf(data.get_ref().as_slice())
+        } else {
+            slice_to_uv_buf(buf)
         };
 
-        return match result {
+        return match unsafe {
+            uvll::uv_udp_send(req.handle, self.handle, [uv_buf], addr_p, send_cb)
+        } {
             0 => {
                 req.defuse(); // uv callback now owns this request
-                let mut cx = Ctx { task: None, result: 0 };
-                wait_until_woken_after(&mut cx.task, &loop_, || {
+                let mut cx = UdpSendCtx {
+                    result: uvll::ECANCELED, data: data, udp: self as *mut _
+                };
+                wait_until_woken_after(&mut self.blocked_sender, &loop_, || {
                     req.set_data(&cx);
                 });
-                match cx.result {
-                    0 => Ok(()),
-                    n => Err(uv_error_to_io_error(UvError(n)))
+
+                if cx.result != uvll::ECANCELED {
+                    return match cx.result {
+                        0 => Ok(()),
+                        n => Err(uv_error_to_io_error(UvError(n)))
+                    }
+                }
+                let new_cx = box UdpSendCtx {
+                    result: 0,
+                    udp: 0 as *mut UdpWatcher,
+                    data: cx.data.take(),
+                };
+                unsafe {
+                    req.set_data(&*new_cx);
+                    cast::forget(new_cx);
                 }
+                Err(uv_error_to_io_error(UvError(cx.result)))
             }
             n => Err(uv_error_to_io_error(UvError(n)))
         };
 
+        // This function is the same as stream::write_cb, but adapted for udp
+        // instead of streams.
         extern fn send_cb(req: *uvll::uv_udp_send_t, status: c_int) {
             let req = Request::wrap(req);
-            assert!(status != uvll::ECANCELED);
-            let cx: &mut Ctx = unsafe { req.get_data() };
+            let cx: &mut UdpSendCtx = unsafe { req.get_data() };
             cx.result = status;
-            wakeup(&mut cx.task);
+
+            if cx.udp as uint != 0 {
+                let udp: &mut UdpWatcher = unsafe { &mut *cx.udp };
+                wakeup(&mut udp.blocked_sender);
+            } else {
+                let _cx: Box<UdpSendCtx> = unsafe { cast::transmute(cx) };
+            }
         }
     }
 
@@ -886,8 +751,48 @@ fn clone(&self) -> Box<rtio::RtioUdpSocket:Send> {
             refcount: self.refcount.clone(),
             write_access: self.write_access.clone(),
             read_access: self.read_access.clone(),
+            blocked_sender: None,
         } as Box<rtio::RtioUdpSocket:Send>
     }
+
+    fn set_timeout(&mut self, timeout: Option<u64>) {
+        self.set_read_timeout(timeout);
+        self.set_write_timeout(timeout);
+    }
+
+    fn set_read_timeout(&mut self, ms: Option<u64>) {
+        let _m = self.fire_homing_missile();
+        let loop_ = self.uv_loop();
+        self.read_access.set_timeout(ms, &self.home, &loop_, cancel_read,
+                                     self.handle as uint);
+
+        fn cancel_read(stream: uint) -> Option<BlockedTask> {
+            // This method is quite similar to StreamWatcher::cancel_read, see
+            // there for more information
+            let handle = stream as *uvll::uv_udp_t;
+            assert_eq!(unsafe { uvll::uv_udp_recv_stop(handle) }, 0);
+            let data = unsafe {
+                let data = uvll::get_data_for_uv_handle(handle);
+                if data.is_null() { return None }
+                uvll::set_data_for_uv_handle(handle, 0 as *int);
+                &mut *(data as *mut UdpRecvCtx)
+            };
+            data.result = Some((uvll::ECANCELED as ssize_t, None));
+            data.task.take()
+        }
+    }
+
+    fn set_write_timeout(&mut self, ms: Option<u64>) {
+        let _m = self.fire_homing_missile();
+        let loop_ = self.uv_loop();
+        self.write_access.set_timeout(ms, &self.home, &loop_, cancel_write,
+                                      self as *mut _ as uint);
+
+        fn cancel_write(stream: uint) -> Option<BlockedTask> {
+            let stream: &mut UdpWatcher = unsafe { cast::transmute(stream) };
+            stream.blocked_sender.take()
+        }
+    }
 }
 
 impl Drop for UdpWatcher {
@@ -900,6 +805,40 @@ fn drop(&mut self) {
     }
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// Shutdown helper
+////////////////////////////////////////////////////////////////////////////////
+
+pub fn shutdown(handle: *uvll::uv_stream_t, loop_: &Loop) -> Result<(), IoError> {
+    struct Ctx {
+        slot: Option<BlockedTask>,
+        status: c_int,
+    }
+    let mut req = Request::new(uvll::UV_SHUTDOWN);
+
+    return match unsafe { uvll::uv_shutdown(req.handle, handle, shutdown_cb) } {
+        0 => {
+            req.defuse(); // uv callback now owns this request
+            let mut cx = Ctx { slot: None, status: 0 };
+
+            wait_until_woken_after(&mut cx.slot, loop_, || {
+                req.set_data(&cx);
+            });
+
+            status_to_io_result(cx.status)
+        }
+        n => Err(uv_error_to_io_error(UvError(n)))
+    };
+
+    extern fn shutdown_cb(req: *uvll::uv_shutdown_t, status: libc::c_int) {
+        let req = Request::wrap(req);
+        assert!(status != uvll::ECANCELED);
+        let cx: &mut Ctx = unsafe { req.get_data() };
+        cx.status = status;
+        wakeup(&mut cx.slot);
+    }
+}
+
 #[cfg(test)]
 mod test {
     use std::rt::rtio::{RtioTcpStream, RtioTcpListener, RtioTcpAcceptor,
index 0edc13afcf538f43cc2e64935e89e889b442d324..76bf92bd5557ca8e08788bac0621161f98917457 100644 (file)
 
 use libc;
 use std::c_str::CString;
+use std::cast;
 use std::io::IoError;
+use std::io;
 use std::rt::rtio::{RtioPipe, RtioUnixListener, RtioUnixAcceptor};
+use std::rt::task::BlockedTask;
 
-use access::Access;
 use homing::{HomingIO, HomeHandle};
 use net;
 use rc::Refcount;
 use stream::StreamWatcher;
 use super::{Loop, UvError, UvHandle, uv_error_to_io_error};
+use timeout::{AcceptTimeout, ConnectCtx, AccessTimeout};
 use uvio::UvIoFactory;
 use uvll;
 
@@ -29,8 +32,8 @@ pub struct PipeWatcher {
     refcount: Refcount,
 
     // see comments in TcpWatcher for why these exist
-    write_access: Access,
-    read_access: Access,
+    write_access: AccessTimeout,
+    read_access: AccessTimeout,
 }
 
 pub struct PipeListener {
@@ -42,7 +45,7 @@ pub struct PipeListener {
 
 pub struct PipeAcceptor {
     listener: Box<PipeListener>,
-    timeout: net::AcceptTimeout,
+    timeout: AcceptTimeout,
 }
 
 // PipeWatcher implementation and traits
@@ -69,8 +72,8 @@ pub fn new_home(loop_: &Loop, home: HomeHandle, ipc: bool) -> PipeWatcher {
             home: home,
             defused: false,
             refcount: Refcount::new(),
-            read_access: Access::new(),
-            write_access: Access::new(),
+            read_access: AccessTimeout::new(),
+            write_access: AccessTimeout::new(),
         }
     }
 
@@ -88,7 +91,7 @@ pub fn connect(io: &mut UvIoFactory, name: &CString, timeout: Option<u64>)
         -> Result<PipeWatcher, UvError>
     {
         let pipe = PipeWatcher::new(io, false);
-        let cx = net::ConnectCtx { status: -1, task: None, timer: None };
+        let cx = ConnectCtx { status: -1, task: None, timer: None };
         cx.connect(pipe, timeout, io, |req, pipe, cb| {
             unsafe {
                 uvll::uv_pipe_connect(req.handle, pipe.handle(),
@@ -111,14 +114,20 @@ fn unwrap(mut self) -> *uvll::uv_pipe_t {
 impl RtioPipe for PipeWatcher {
     fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> {
         let m = self.fire_homing_missile();
-        let _g = self.read_access.grant(m);
+        let guard = try!(self.read_access.grant(m));
+
+        // see comments in close_read about this check
+        if guard.access.is_closed() {
+            return Err(io::standard_error(io::EndOfFile))
+        }
+
         self.stream.read(buf).map_err(uv_error_to_io_error)
     }
 
     fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
         let m = self.fire_homing_missile();
-        let _g = self.write_access.grant(m);
-        self.stream.write(buf).map_err(uv_error_to_io_error)
+        let guard = try!(self.write_access.grant(m));
+        self.stream.write(buf, guard.can_timeout).map_err(uv_error_to_io_error)
     }
 
     fn clone(&self) -> Box<RtioPipe:Send> {
@@ -131,6 +140,67 @@ fn clone(&self) -> Box<RtioPipe:Send> {
             write_access: self.write_access.clone(),
         } as Box<RtioPipe:Send>
     }
+
+    fn close_read(&mut self) -> Result<(), IoError> {
+        // The current uv_shutdown method only shuts the writing half of the
+        // connection, and no method is provided to shut down the reading half
+        // of the connection. With a lack of method, we emulate shutting down
+        // the reading half of the connection by manually returning early from
+        // all future calls to `read`.
+        //
+        // Note that we must be careful to ensure that *all* cloned handles see
+        // the closing of the read half, so we stored the "is closed" bit in the
+        // Access struct, not in our own personal watcher. Additionally, the
+        // homing missile is used as a locking mechanism to ensure there is no
+        // contention over this bit.
+        //
+        // To shutdown the read half, we must first flag the access as being
+        // closed, and then afterwards we cease any pending read. Note that this
+        // ordering is crucial because we could in theory be rescheduled during
+        // the uv_read_stop which means that another read invocation could leak
+        // in before we set the flag.
+        let task = {
+            let m = self.fire_homing_missile();
+            self.read_access.access.close(&m);
+            self.stream.cancel_read(uvll::EOF as libc::ssize_t)
+        };
+        let _ = task.map(|t| t.reawaken());
+        Ok(())
+    }
+
+    fn close_write(&mut self) -> Result<(), IoError> {
+        let _m = self.fire_homing_missile();
+        net::shutdown(self.stream.handle, &self.uv_loop())
+    }
+
+    fn set_timeout(&mut self, timeout: Option<u64>) {
+        self.set_read_timeout(timeout);
+        self.set_write_timeout(timeout);
+    }
+
+    fn set_read_timeout(&mut self, ms: Option<u64>) {
+        let _m = self.fire_homing_missile();
+        let loop_ = self.uv_loop();
+        self.read_access.set_timeout(ms, &self.home, &loop_, cancel_read,
+                                     &self.stream as *_ as uint);
+
+        fn cancel_read(stream: uint) -> Option<BlockedTask> {
+            let stream: &mut StreamWatcher = unsafe { cast::transmute(stream) };
+            stream.cancel_read(uvll::ECANCELED as libc::ssize_t)
+        }
+    }
+
+    fn set_write_timeout(&mut self, ms: Option<u64>) {
+        let _m = self.fire_homing_missile();
+        let loop_ = self.uv_loop();
+        self.write_access.set_timeout(ms, &self.home, &loop_, cancel_write,
+                                      &self.stream as *_ as uint);
+
+        fn cancel_write(stream: uint) -> Option<BlockedTask> {
+            let stream: &mut StreamWatcher = unsafe { cast::transmute(stream) };
+            stream.cancel_write()
+        }
+    }
 }
 
 impl HomingIO for PipeWatcher {
@@ -183,7 +253,7 @@ fn listen(~self) -> Result<Box<RtioUnixAcceptor:Send>, IoError> {
         // create the acceptor object from ourselves
         let mut acceptor = box PipeAcceptor {
             listener: self,
-            timeout: net::AcceptTimeout::new(),
+            timeout: AcceptTimeout::new(),
         };
 
         let _m = acceptor.fire_homing_missile();
index d744607050fc6583d750c8ea40517258f53bd10e..d671e20868c5c39d64b80193fbad4f416c1f1d57 100644 (file)
@@ -40,7 +40,8 @@ impl Process {
     /// Returns either the corresponding process object or an error which
     /// occurred.
     pub fn spawn(io_loop: &mut UvIoFactory, config: process::ProcessConfig)
-                -> Result<(Box<Process>, ~[Option<PipeWatcher>]), UvError> {
+                -> Result<(Box<Process>, Vec<Option<PipeWatcher>>), UvError>
+    {
         let cwd = config.cwd.map(|s| s.to_c_str());
         let mut io = vec![config.stdin, config.stdout, config.stderr];
         for slot in config.extra_io.iter() {
@@ -102,7 +103,7 @@ pub fn spawn(io_loop: &mut UvIoFactory, config: process::ProcessConfig)
         });
 
         match ret {
-            Ok(p) => Ok((p, ret_io.move_iter().collect())),
+            Ok(p) => Ok((p, ret_io)),
             Err(e) => Err(e),
         }
     }
index 1fb61c15b830b11addcd0ce15e6e6969287f3f42..36b6ed09ca5668033c1e9bdf35adc48b3ea4fea1 100644 (file)
@@ -30,6 +30,8 @@ pub struct StreamWatcher {
     // structure, but currently we don't have mappings for all the structures
     // defined in libuv, so we're foced to malloc this.
     last_write_req: Option<Request>,
+
+    blocked_writer: Option<BlockedTask>,
 }
 
 struct ReadContext {
@@ -40,7 +42,8 @@ struct ReadContext {
 
 struct WriteContext {
     result: c_int,
-    task: Option<BlockedTask>,
+    stream: *mut StreamWatcher,
+    data: Option<Vec<u8>>,
 }
 
 impl StreamWatcher {
@@ -57,9 +60,11 @@ impl StreamWatcher {
     // Wrappers should ensure to always reset the field to an appropriate value
     // if they rely on the field to perform an action.
     pub fn new(stream: *uvll::uv_stream_t) -> StreamWatcher {
+        unsafe { uvll::set_data_for_uv_handle(stream, 0 as *int) }
         StreamWatcher {
             handle: stream,
             last_write_req: None,
+            blocked_writer: None,
         }
     }
 
@@ -70,6 +75,8 @@ pub fn read(&mut self, buf: &mut [u8]) -> Result<uint, UvError> {
 
         let mut rcx = ReadContext {
             buf: Some(slice_to_uv_buf(buf)),
+            // if the read is canceled, we'll see eof, otherwise this will get
+            // overwritten
             result: 0,
             task: None,
         };
@@ -78,13 +85,11 @@ pub fn read(&mut self, buf: &mut [u8]) -> Result<uint, UvError> {
         // we must be ready for this to happen (by setting the data in the uv
         // handle). In theory this otherwise doesn't need to happen until after
         // the read is succesfully started.
-        unsafe {
-            uvll::set_data_for_uv_handle(self.handle, &rcx)
-        }
+        unsafe { uvll::set_data_for_uv_handle(self.handle, &rcx) }
 
         // Send off the read request, but don't block until we're sure that the
         // read request is queued.
-        match unsafe {
+        let ret = match unsafe {
             uvll::uv_read_start(self.handle, alloc_cb, read_cb)
         } {
             0 => {
@@ -96,10 +101,28 @@ pub fn read(&mut self, buf: &mut [u8]) -> Result<uint, UvError> {
                 }
             }
             n => Err(UvError(n))
-        }
+        };
+        // Make sure a read cancellation sees that there's no pending read
+        unsafe { uvll::set_data_for_uv_handle(self.handle, 0 as *int) }
+        return ret;
+    }
+
+    pub fn cancel_read(&mut self, reason: ssize_t) -> Option<BlockedTask> {
+        // When we invoke uv_read_stop, it cancels the read and alloc
+        // callbacks. We need to manually wake up a pending task (if one was
+        // present).
+        assert_eq!(unsafe { uvll::uv_read_stop(self.handle) }, 0);
+        let data = unsafe {
+            let data = uvll::get_data_for_uv_handle(self.handle);
+            if data.is_null() { return None }
+            uvll::set_data_for_uv_handle(self.handle, 0 as *int);
+            &mut *(data as *mut ReadContext)
+        };
+        data.result = reason;
+        data.task.take()
     }
 
-    pub fn write(&mut self, buf: &[u8]) -> Result<(), UvError> {
+    pub fn write(&mut self, buf: &[u8], may_timeout: bool) -> Result<(), UvError> {
         // The ownership of the write request is dubious if this function
         // unwinds. I believe that if the write_cb fails to re-schedule the task
         // then the write request will be leaked.
@@ -112,30 +135,94 @@ pub fn write(&mut self, buf: &[u8]) -> Result<(), UvError> {
         };
         req.set_data(ptr::null::<()>());
 
+        // And here's where timeouts get a little interesting. Currently, libuv
+        // does not support canceling an in-flight write request. Consequently,
+        // when a write timeout expires, there's not much we can do other than
+        // detach the sleeping task from the write request itself. Semantically,
+        // this means that the write request will complete asynchronously, but
+        // the calling task will return error (because the write timed out).
+        //
+        // There is special wording in the documentation of set_write_timeout()
+        // indicating that this is a plausible failure scenario, and this
+        // function is why that wording exists.
+        //
+        // Implementation-wise, we must be careful when passing a buffer down to
+        // libuv. Most of this implementation avoids allocations becuase of the
+        // blocking guarantee (all stack local variables are valid for the
+        // entire read/write request). If our write request can be timed out,
+        // however, we must heap allocate the data and pass that to the libuv
+        // functions instead. The reason for this is that if we time out and
+        // return, there's no guarantee that `buf` is a valid buffer any more.
+        //
+        // To do this, the write context has an optionally owned vector of
+        // bytes.
+        let data = if may_timeout {Some(Vec::from_slice(buf))} else {None};
+        let uv_buf = if may_timeout {
+            slice_to_uv_buf(data.get_ref().as_slice())
+        } else {
+            slice_to_uv_buf(buf)
+        };
+
         // Send off the request, but be careful to not block until we're sure
         // that the write reqeust is queued. If the reqeust couldn't be queued,
         // then we should return immediately with an error.
         match unsafe {
-            uvll::uv_write(req.handle, self.handle, [slice_to_uv_buf(buf)],
-                           write_cb)
+            uvll::uv_write(req.handle, self.handle, [uv_buf], write_cb)
         } {
             0 => {
-                let mut wcx = WriteContext { result: 0, task: None, };
+                let mut wcx = WriteContext {
+                    result: uvll::ECANCELED,
+                    stream: self as *mut _,
+                    data: data,
+                };
                 req.defuse(); // uv callback now owns this request
 
                 let loop_ = unsafe { uvll::get_loop_for_uv_handle(self.handle) };
-                wait_until_woken_after(&mut wcx.task, &Loop::wrap(loop_), || {
+                wait_until_woken_after(&mut self.blocked_writer,
+                                       &Loop::wrap(loop_), || {
                     req.set_data(&wcx);
                 });
-                self.last_write_req = Some(Request::wrap(req.handle));
-                match wcx.result {
-                    0 => Ok(()),
-                    n => Err(UvError(n)),
+
+                if wcx.result != uvll::ECANCELED {
+                    self.last_write_req = Some(Request::wrap(req.handle));
+                    return match wcx.result {
+                        0 => Ok(()),
+                        n => Err(UvError(n)),
+                    }
+                }
+
+                // This is the second case where canceling an in-flight write
+                // gets interesting. If we've been canceled (no one reset our
+                // result), then someone still needs to free the request, and
+                // someone still needs to free the allocate buffer.
+                //
+                // To take care of this, we swap out the stack-allocated write
+                // context for a heap-allocated context, transferring ownership
+                // of everything to the write_cb. Libuv guarantees that this
+                // callback will be invoked at some point, and the callback will
+                // be responsible for deallocating these resources.
+                //
+                // Note that we don't cache this write request back in the
+                // stream watcher because we no longer have ownership of it, and
+                // we never will.
+                let new_wcx = box WriteContext {
+                    result: 0,
+                    stream: 0 as *mut StreamWatcher,
+                    data: wcx.data.take(),
+                };
+                unsafe {
+                    req.set_data(&*new_wcx);
+                    cast::forget(new_wcx);
                 }
+                Err(UvError(wcx.result))
             }
             n => Err(UvError(n)),
         }
     }
+
+    pub fn cancel_write(&mut self) -> Option<BlockedTask> {
+        self.blocked_writer.take()
+    }
 }
 
 // This allocation callback expects to be invoked once and only once. It will
@@ -173,12 +260,18 @@ pub fn write(&mut self, buf: &[u8]) -> Result<(), UvError> {
 // away the error code as a result.
 extern fn write_cb(req: *uvll::uv_write_t, status: c_int) {
     let mut req = Request::wrap(req);
-    assert!(status != uvll::ECANCELED);
     // Remember to not free the request because it is re-used between writes on
     // the same stream.
     let wcx: &mut WriteContext = unsafe { req.get_data() };
     wcx.result = status;
-    req.defuse();
 
-    wakeup(&mut wcx.task);
+    // If the stream is present, we haven't timed out, otherwise we acquire
+    // ownership of everything and then deallocate it all at once.
+    if wcx.stream as uint != 0 {
+        req.defuse();
+        let stream: &mut StreamWatcher = unsafe { &mut *wcx.stream };
+        wakeup(&mut stream.blocked_writer);
+    } else {
+        let _wcx: Box<WriteContext> = unsafe { cast::transmute(wcx) };
+    }
 }
diff --git a/src/librustuv/timeout.rs b/src/librustuv/timeout.rs
new file mode 100644 (file)
index 0000000..3dbb34b
--- /dev/null
@@ -0,0 +1,394 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use libc::c_int;
+use std::cast;
+use std::io::IoResult;
+use std::mem;
+use std::rt::task::BlockedTask;
+
+use access;
+use homing::{HomeHandle, HomingMissile, HomingIO};
+use timer::TimerWatcher;
+use uvll;
+use uvio::UvIoFactory;
+use {Loop, UvError, uv_error_to_io_error, Request, wakeup};
+use {UvHandle, wait_until_woken_after};
+
+/// Managment of a timeout when gaining access to a portion of a duplex stream.
+pub struct AccessTimeout {
+    state: TimeoutState,
+    timer: Option<Box<TimerWatcher>>,
+    pub access: access::Access,
+}
+
+pub struct Guard<'a> {
+    state: &'a mut TimeoutState,
+    pub access: access::Guard<'a>,
+    pub can_timeout: bool,
+}
+
+#[deriving(Eq)]
+enum TimeoutState {
+    NoTimeout,
+    TimeoutPending(ClientState),
+    TimedOut,
+}
+
+#[deriving(Eq)]
+enum ClientState {
+    NoWaiter,
+    AccessPending,
+    RequestPending,
+}
+
+struct TimerContext {
+    timeout: *mut AccessTimeout,
+    callback: fn(uint) -> Option<BlockedTask>,
+    payload: uint,
+}
+
+impl AccessTimeout {
+    pub fn new() -> AccessTimeout {
+        AccessTimeout {
+            state: NoTimeout,
+            timer: None,
+            access: access::Access::new(),
+        }
+    }
+
+    /// Grants access to half of a duplex stream, timing out if necessary.
+    ///
+    /// On success, Ok(Guard) is returned and access has been granted to the
+    /// stream. If a timeout occurs, then Err is returned with an appropriate
+    /// error.
+    pub fn grant<'a>(&'a mut self, m: HomingMissile) -> IoResult<Guard<'a>> {
+        // First, flag that we're attempting to acquire access. This will allow
+        // us to cancel the pending grant if we timeout out while waiting for a
+        // grant.
+        match self.state {
+            NoTimeout => {},
+            TimeoutPending(ref mut client) => *client = AccessPending,
+            TimedOut => return Err(uv_error_to_io_error(UvError(uvll::ECANCELED)))
+        }
+        let access = self.access.grant(self as *mut _ as uint, m);
+
+        // After acquiring the grant, we need to flag ourselves as having a
+        // pending request so the timeout knows to cancel the request.
+        let can_timeout = match self.state {
+            NoTimeout => false,
+            TimeoutPending(ref mut client) => { *client = RequestPending; true }
+            TimedOut => return Err(uv_error_to_io_error(UvError(uvll::ECANCELED)))
+        };
+
+        Ok(Guard {
+            access: access,
+            state: &mut self.state,
+            can_timeout: can_timeout
+        })
+    }
+
+    /// Sets the pending timeout to the value specified.
+    ///
+    /// The home/loop variables are used to construct a timer if one has not
+    /// been previously constructed.
+    ///
+    /// The callback will be invoked if the timeout elapses, and the data of
+    /// the time will be set to `data`.
+    pub fn set_timeout(&mut self, ms: Option<u64>,
+                       home: &HomeHandle,
+                       loop_: &Loop,
+                       cb: fn(uint) -> Option<BlockedTask>,
+                       data: uint) {
+        self.state = NoTimeout;
+        let ms = match ms {
+            Some(ms) => ms,
+            None => return match self.timer {
+                Some(ref mut t) => t.stop(),
+                None => {}
+            }
+        };
+
+        // If we have a timeout, lazily initialize the timer which will be used
+        // to fire when the timeout runs out.
+        if self.timer.is_none() {
+            let mut timer = box TimerWatcher::new_home(loop_, home.clone());
+            let cx = box TimerContext {
+                timeout: self as *mut _,
+                callback: cb,
+                payload: data,
+            };
+            unsafe {
+                timer.set_data(&*cx);
+                cast::forget(cx);
+            }
+            self.timer = Some(timer);
+        }
+
+        let timer = self.timer.get_mut_ref();
+        unsafe {
+            let cx = uvll::get_data_for_uv_handle(timer.handle);
+            let cx = cx as *mut TimerContext;
+            (*cx).callback = cb;
+            (*cx).payload = data;
+        }
+        timer.stop();
+        timer.start(timer_cb, ms, 0);
+        self.state = TimeoutPending(NoWaiter);
+
+        extern fn timer_cb(timer: *uvll::uv_timer_t) {
+            let cx: &TimerContext = unsafe {
+                &*(uvll::get_data_for_uv_handle(timer) as *TimerContext)
+            };
+            let me = unsafe { &mut *cx.timeout };
+
+            match mem::replace(&mut me.state, TimedOut) {
+                TimedOut | NoTimeout => unreachable!(),
+                TimeoutPending(NoWaiter) => {}
+                TimeoutPending(AccessPending) => {
+                    match unsafe { me.access.dequeue(me as *mut _ as uint) } {
+                        Some(task) => task.reawaken(),
+                        None => unreachable!(),
+                    }
+                }
+                TimeoutPending(RequestPending) => {
+                    match (cx.callback)(cx.payload) {
+                        Some(task) => task.reawaken(),
+                        None => unreachable!(),
+                    }
+                }
+            }
+        }
+    }
+}
+
+impl Clone for AccessTimeout {
+    fn clone(&self) -> AccessTimeout {
+        AccessTimeout {
+            access: self.access.clone(),
+            state: NoTimeout,
+            timer: None,
+        }
+    }
+}
+
+#[unsafe_destructor]
+impl<'a> Drop for Guard<'a> {
+    fn drop(&mut self) {
+        match *self.state {
+            TimeoutPending(NoWaiter) | TimeoutPending(AccessPending) =>
+                unreachable!(),
+
+            NoTimeout | TimedOut => {}
+            TimeoutPending(RequestPending) => {
+                *self.state = TimeoutPending(NoWaiter);
+            }
+        }
+    }
+}
+
+impl Drop for AccessTimeout {
+    fn drop(&mut self) {
+        match self.timer {
+            Some(ref timer) => unsafe {
+                let data = uvll::get_data_for_uv_handle(timer.handle);
+                let _data: Box<TimerContext> = cast::transmute(data);
+            },
+            None => {}
+        }
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Connect timeouts
+////////////////////////////////////////////////////////////////////////////////
+
+pub struct ConnectCtx {
+    pub status: c_int,
+    pub task: Option<BlockedTask>,
+    pub timer: Option<Box<TimerWatcher>>,
+}
+
+pub struct AcceptTimeout {
+    timer: Option<TimerWatcher>,
+    timeout_tx: Option<Sender<()>>,
+    timeout_rx: Option<Receiver<()>>,
+}
+
+impl ConnectCtx {
+    pub fn connect<T>(
+        mut self, obj: T, timeout: Option<u64>, io: &mut UvIoFactory,
+        f: |&Request, &T, uvll::uv_connect_cb| -> c_int
+    ) -> Result<T, UvError> {
+        let mut req = Request::new(uvll::UV_CONNECT);
+        let r = f(&req, &obj, connect_cb);
+        return match r {
+            0 => {
+                req.defuse(); // uv callback now owns this request
+                match timeout {
+                    Some(t) => {
+                        let mut timer = TimerWatcher::new(io);
+                        timer.start(timer_cb, t, 0);
+                        self.timer = Some(timer);
+                    }
+                    None => {}
+                }
+                wait_until_woken_after(&mut self.task, &io.loop_, || {
+                    let data = &self as *_;
+                    match self.timer {
+                        Some(ref mut timer) => unsafe { timer.set_data(data) },
+                        None => {}
+                    }
+                    req.set_data(data);
+                });
+                // Make sure an erroneously fired callback doesn't have access
+                // to the context any more.
+                req.set_data(0 as *int);
+
+                // If we failed because of a timeout, drop the TcpWatcher as
+                // soon as possible because it's data is now set to null and we
+                // want to cancel the callback ASAP.
+                match self.status {
+                    0 => Ok(obj),
+                    n => { drop(obj); Err(UvError(n)) }
+                }
+            }
+            n => Err(UvError(n))
+        };
+
+        extern fn timer_cb(handle: *uvll::uv_timer_t) {
+            // Don't close the corresponding tcp request, just wake up the task
+            // and let RAII take care of the pending watcher.
+            let cx: &mut ConnectCtx = unsafe {
+                &mut *(uvll::get_data_for_uv_handle(handle) as *mut ConnectCtx)
+            };
+            cx.status = uvll::ECANCELED;
+            wakeup(&mut cx.task);
+        }
+
+        extern fn connect_cb(req: *uvll::uv_connect_t, status: c_int) {
+            // This callback can be invoked with ECANCELED if the watcher is
+            // closed by the timeout callback. In that case we just want to free
+            // the request and be along our merry way.
+            let req = Request::wrap(req);
+            if status == uvll::ECANCELED { return }
+
+            // Apparently on windows when the handle is closed this callback may
+            // not be invoked with ECANCELED but rather another error code.
+            // Either ways, if the data is null, then our timeout has expired
+            // and there's nothing we can do.
+            let data = unsafe { uvll::get_data_for_req(req.handle) };
+            if data.is_null() { return }
+
+            let cx: &mut ConnectCtx = unsafe { &mut *(data as *mut ConnectCtx) };
+            cx.status = status;
+            match cx.timer {
+                Some(ref mut t) => t.stop(),
+                None => {}
+            }
+            // Note that the timer callback doesn't cancel the connect request
+            // (that's the job of uv_close()), so it's possible for this
+            // callback to get triggered after the timeout callback fires, but
+            // before the task wakes up. In that case, we did indeed
+            // successfully connect, but we don't need to wake someone up. We
+            // updated the status above (correctly so), and the task will pick
+            // up on this when it wakes up.
+            if cx.task.is_some() {
+                wakeup(&mut cx.task);
+            }
+        }
+    }
+}
+
+impl AcceptTimeout {
+    pub fn new() -> AcceptTimeout {
+        AcceptTimeout { timer: None, timeout_tx: None, timeout_rx: None }
+    }
+
+    pub fn accept<T: Send>(&mut self, c: &Receiver<IoResult<T>>) -> IoResult<T> {
+        match self.timeout_rx {
+            None => c.recv(),
+            Some(ref rx) => {
+                use std::comm::Select;
+
+                // Poll the incoming channel first (don't rely on the order of
+                // select just yet). If someone's pending then we should return
+                // them immediately.
+                match c.try_recv() {
+                    Ok(data) => return data,
+                    Err(..) => {}
+                }
+
+                // Use select to figure out which channel gets ready first. We
+                // do some custom handling of select to ensure that we never
+                // actually drain the timeout channel (we'll keep seeing the
+                // timeout message in the future).
+                let s = Select::new();
+                let mut timeout = s.handle(rx);
+                let mut data = s.handle(c);
+                unsafe {
+                    timeout.add();
+                    data.add();
+                }
+                if s.wait() == timeout.id() {
+                    Err(uv_error_to_io_error(UvError(uvll::ECANCELED)))
+                } else {
+                    c.recv()
+                }
+            }
+        }
+    }
+
+    pub fn clear(&mut self) {
+        match self.timeout_rx {
+            Some(ref t) => { let _ = t.try_recv(); }
+            None => {}
+        }
+        match self.timer {
+            Some(ref mut t) => t.stop(),
+            None => {}
+        }
+    }
+
+    pub fn set_timeout<U, T: UvHandle<U> + HomingIO>(
+        &mut self, ms: u64, t: &mut T
+    ) {
+        // If we have a timeout, lazily initialize the timer which will be used
+        // to fire when the timeout runs out.
+        if self.timer.is_none() {
+            let loop_ = Loop::wrap(unsafe {
+                uvll::get_loop_for_uv_handle(t.uv_handle())
+            });
+            let mut timer = TimerWatcher::new_home(&loop_, t.home().clone());
+            unsafe {
+                timer.set_data(self as *mut _ as *AcceptTimeout);
+            }
+            self.timer = Some(timer);
+        }
+
+        // Once we've got a timer, stop any previous timeout, reset it for the
+        // current one, and install some new channels to send/receive data on
+        let timer = self.timer.get_mut_ref();
+        timer.stop();
+        timer.start(timer_cb, ms, 0);
+        let (tx, rx) = channel();
+        self.timeout_tx = Some(tx);
+        self.timeout_rx = Some(rx);
+
+        extern fn timer_cb(timer: *uvll::uv_timer_t) {
+            let acceptor: &mut AcceptTimeout = unsafe {
+                &mut *(uvll::get_data_for_uv_handle(timer) as *mut AcceptTimeout)
+            };
+            // This send can never fail because if this timer is active then the
+            // receiving channel is guaranteed to be alive
+            acceptor.timeout_tx.get_ref().send(());
+        }
+    }
+}
index 216eb6001305e8d33a6e666881fbe1fb7d8c8dae..525539f8b36f9965699cd11f07676170499994f0 100644 (file)
@@ -18,7 +18,7 @@
 use uvll;
 
 pub struct TimerWatcher {
-    handle: *uvll::uv_timer_t,
+    pub handle: *uvll::uv_timer_t,
     home: HomeHandle,
     action: Option<NextAction>,
     blocker: Option<BlockedTask>,
index 4f3e12b6974d592f98793f8843e09a3776802f42..f70c3b4c1bd7528bf8d8388a75ddfe0c013bc743 100644 (file)
@@ -87,7 +87,7 @@ fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> {
 
     fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
         let _m = self.fire_homing_missile();
-        self.stream.write(buf).map_err(uv_error_to_io_error)
+        self.stream.write(buf, false).map_err(uv_error_to_io_error)
     }
 
     fn set_raw(&mut self, raw: bool) -> Result<(), IoError> {
index 17a64fdb51760740e729a079d2642251fdb37819..50258c2583c65c33d169e4e31c36e4df8ff62071 100644 (file)
@@ -178,7 +178,7 @@ fn timer_init(&mut self) -> Result<Box<rtio::RtioTimer:Send>, IoError> {
     }
 
     fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
-                          hint: Option<ai::Hint>) -> Result<~[ai::Info], IoError> {
+                          hint: Option<ai::Hint>) -> Result<Vec<ai::Info>, IoError> {
         let r = GetAddrInfoRequest::run(&self.loop_, host, servname, hint);
         r.map_err(uv_error_to_io_error)
     }
@@ -272,7 +272,7 @@ fn fs_utime(&mut self, path: &CString, atime: u64, mtime: u64)
 
     fn spawn(&mut self, config: ProcessConfig)
             -> Result<(Box<rtio::RtioProcess:Send>,
-                       ~[Option<Box<rtio::RtioPipe:Send>>]),
+                       Vec<Option<Box<rtio::RtioPipe:Send>>>),
                       IoError>
     {
         match Process::spawn(self, config) {
index 426894aeff7dd8eb914d28128edb291f2b5193d3..4709365ebff533fe7d0647fbfee3f2720c40cb85 100644 (file)
@@ -146,7 +146,7 @@ fn to_base64(&self, config: Config) -> ~str {
         }
 
         unsafe {
-            str::raw::from_utf8_owned(v.move_iter().collect())
+            str::raw::from_utf8(v.as_slice()).to_owned()
         }
     }
 }
@@ -155,7 +155,7 @@ fn to_base64(&self, config: Config) -> ~str {
 pub trait FromBase64 {
     /// Converts the value of `self`, interpreted as base64 encoded data, into
     /// an owned vector of bytes, returning the vector.
-    fn from_base64(&self) -> Result<~[u8], FromBase64Error>;
+    fn from_base64(&self) -> Result<Vec<u8>, FromBase64Error>;
 }
 
 /// Errors that can occur when decoding a base64 encoded string
@@ -192,14 +192,13 @@ impl<'a> FromBase64 for &'a str {
      * ```rust
      * extern crate serialize;
      * use serialize::base64::{ToBase64, FromBase64, STANDARD};
-     * use std::str;
      *
      * fn main () {
      *     let hello_str = bytes!("Hello, World").to_base64(STANDARD);
      *     println!("base64 output: {}", hello_str);
      *     let res = hello_str.from_base64();
      *     if res.is_ok() {
-     *       let opt_bytes = str::from_utf8_owned(res.unwrap());
+     *       let opt_bytes = StrBuf::from_utf8(res.unwrap());
      *       if opt_bytes.is_some() {
      *         println!("decoded from base64: {}", opt_bytes.unwrap());
      *       }
@@ -207,7 +206,7 @@ impl<'a> FromBase64 for &'a str {
      * }
      * ```
      */
-    fn from_base64(&self) -> Result<~[u8], FromBase64Error> {
+    fn from_base64(&self) -> Result<Vec<u8>, FromBase64Error> {
         let mut r = Vec::new();
         let mut buf: u32 = 0;
         let mut modulus = 0;
@@ -256,7 +255,7 @@ fn from_base64(&self) -> Result<~[u8], FromBase64Error> {
             _ => return Err(InvalidBase64Length),
         }
 
-        Ok(r.move_iter().collect())
+        Ok(r)
     }
 }
 
@@ -301,21 +300,21 @@ fn test_to_base64_url_safe() {
 
     #[test]
     fn test_from_base64_basic() {
-        assert_eq!("".from_base64().unwrap(), "".as_bytes().to_owned());
-        assert_eq!("Zg==".from_base64().unwrap(), "f".as_bytes().to_owned());
-        assert_eq!("Zm8=".from_base64().unwrap(), "fo".as_bytes().to_owned());
-        assert_eq!("Zm9v".from_base64().unwrap(), "foo".as_bytes().to_owned());
-        assert_eq!("Zm9vYg==".from_base64().unwrap(), "foob".as_bytes().to_owned());
-        assert_eq!("Zm9vYmE=".from_base64().unwrap(), "fooba".as_bytes().to_owned());
-        assert_eq!("Zm9vYmFy".from_base64().unwrap(), "foobar".as_bytes().to_owned());
+        assert_eq!("".from_base64().unwrap().as_slice(), "".as_bytes());
+        assert_eq!("Zg==".from_base64().unwrap().as_slice(), "f".as_bytes());
+        assert_eq!("Zm8=".from_base64().unwrap().as_slice(), "fo".as_bytes());
+        assert_eq!("Zm9v".from_base64().unwrap().as_slice(), "foo".as_bytes());
+        assert_eq!("Zm9vYg==".from_base64().unwrap().as_slice(), "foob".as_bytes());
+        assert_eq!("Zm9vYmE=".from_base64().unwrap().as_slice(), "fooba".as_bytes());
+        assert_eq!("Zm9vYmFy".from_base64().unwrap().as_slice(), "foobar".as_bytes());
     }
 
     #[test]
     fn test_from_base64_newlines() {
-        assert_eq!("Zm9v\r\nYmFy".from_base64().unwrap(),
-                   "foobar".as_bytes().to_owned());
-        assert_eq!("Zm9vYg==\r\n".from_base64().unwrap(),
-                   "foob".as_bytes().to_owned());
+        assert_eq!("Zm9v\r\nYmFy".from_base64().unwrap().as_slice(),
+                   "foobar".as_bytes());
+        assert_eq!("Zm9vYg==\r\n".from_base64().unwrap().as_slice(),
+                   "foob".as_bytes());
     }
 
     #[test]
@@ -341,8 +340,8 @@ fn test_base64_random() {
         for _ in range(0, 1000) {
             let times = task_rng().gen_range(1u, 100);
             let v = Vec::from_fn(times, |_| random::<u8>());
-            assert_eq!(v.as_slice().to_base64(STANDARD).from_base64().unwrap(),
-                       v.as_slice().to_owned());
+            assert_eq!(v.as_slice().to_base64(STANDARD).from_base64().unwrap().as_slice(),
+                       v.as_slice());
         }
     }
 
index cbed0656e4de285a8e141f11bdf43731060314e8..c463d97dba4d48fe960b36f79c1621615de10852 100644 (file)
@@ -45,7 +45,7 @@ fn to_hex(&self) -> ~str {
         }
 
         unsafe {
-            str::raw::from_utf8_owned(v.move_iter().collect())
+            str::raw::from_utf8(v.as_slice()).to_owned()
         }
     }
 }
@@ -54,7 +54,7 @@ fn to_hex(&self) -> ~str {
 pub trait FromHex {
     /// Converts the value of `self`, interpreted as hexadecimal encoded data,
     /// into an owned vector of bytes, returning the vector.
-    fn from_hex(&self) -> Result<~[u8], FromHexError>;
+    fn from_hex(&self) -> Result<Vec<u8>, FromHexError>;
 }
 
 /// Errors that can occur when decoding a hex encoded string
@@ -91,19 +91,18 @@ impl<'a> FromHex for &'a str {
      * ```rust
      * extern crate serialize;
      * use serialize::hex::{FromHex, ToHex};
-     * use std::str;
      *
      * fn main () {
      *     let hello_str = "Hello, World".as_bytes().to_hex();
      *     println!("{}", hello_str);
      *     let bytes = hello_str.from_hex().unwrap();
      *     println!("{:?}", bytes);
-     *     let result_str = str::from_utf8_owned(bytes).unwrap();
+     *     let result_str = StrBuf::from_utf8(bytes).unwrap();
      *     println!("{}", result_str);
      * }
      * ```
      */
-    fn from_hex(&self) -> Result<~[u8], FromHexError> {
+    fn from_hex(&self) -> Result<Vec<u8>, FromHexError> {
         // This may be an overestimate if there is any whitespace
         let mut b = Vec::with_capacity(self.len() / 2);
         let mut modulus = 0;
@@ -150,10 +149,10 @@ pub fn test_to_hex() {
 
     #[test]
     pub fn test_from_hex_okay() {
-        assert_eq!("666f6f626172".from_hex().unwrap(),
-                   "foobar".as_bytes().to_owned());
-        assert_eq!("666F6F626172".from_hex().unwrap(),
-                   "foobar".as_bytes().to_owned());
+        assert_eq!("666f6f626172".from_hex().unwrap().as_slice(),
+                   "foobar".as_bytes());
+        assert_eq!("666F6F626172".from_hex().unwrap().as_slice(),
+                   "foobar".as_bytes());
     }
 
     #[test]
@@ -169,8 +168,8 @@ pub fn test_from_hex_invalid_char() {
 
     #[test]
     pub fn test_from_hex_ignores_whitespace() {
-        assert_eq!("666f 6f6\r\n26172 ".from_hex().unwrap(),
-                   "foobar".as_bytes().to_owned());
+        assert_eq!("666f 6f6\r\n26172 ".from_hex().unwrap().as_slice(),
+                   "foobar".as_bytes());
     }
 
     #[test]
@@ -183,8 +182,8 @@ pub fn test_to_hex_all_bytes() {
     #[test]
     pub fn test_from_hex_all_bytes() {
         for i in range(0, 256) {
-            assert_eq!(format!("{:02x}", i as uint).from_hex().unwrap(), ~[i as u8]);
-            assert_eq!(format!("{:02X}", i as uint).from_hex().unwrap(), ~[i as u8]);
+            assert_eq!(format!("{:02x}", i as uint).from_hex().unwrap().as_slice(), &[i as u8]);
+            assert_eq!(format!("{:02X}", i as uint).from_hex().unwrap().as_slice(), &[i as u8]);
         }
     }
 
index 29315c458108fa20ff8d3c2b71788843d14f986e..2e4d7696c44d0b42a53fea7e5793af7b6adf690b 100644 (file)
@@ -166,14 +166,14 @@ fn main() {
  pub struct TestStruct1  {
     data_int: u8,
     data_str: ~str,
-    data_vector: ~[u8],
+    data_vector: Vec<u8>,
  }
 
 // To serialize use the `json::str_encode` to encode an object in a string.
 // It calls the generated `Encodable` impl.
 fn main() {
     let to_encode_object = TestStruct1
-         {data_int: 1, data_str:"toto".to_owned(), data_vector:~[2,3,4,5]};
+         {data_int: 1, data_str:"toto".to_owned(), data_vector:vec![2,3,4,5]};
     let encoded_str: ~str = json::Encoder::str_encode(&to_encode_object);
 
     // To deserialize use the `json::from_str` and `json::Decoder`
@@ -201,7 +201,7 @@ fn main() {
 pub struct TestStruct1  {
     data_int: u8,
     data_str: ~str,
-    data_vector: ~[u8],
+    data_vector: Vec<u8>,
 }
 
 impl ToJson for TestStruct1 {
@@ -218,7 +218,7 @@ fn main() {
     // Serialization using our impl of to_json
 
     let test2: TestStruct1 = TestStruct1 {data_int: 1, data_str:"toto".to_owned(),
-                                          data_vector:~[2,3,4,5]};
+                                          data_vector:vec![2,3,4,5]};
     let tjson: json::Json = test2.to_json();
     let json_str: ~str = tjson.to_str();
 
@@ -258,7 +258,7 @@ pub enum Json {
     Null,
 }
 
-pub type List = ~[Json];
+pub type List = Vec<Json>;
 pub type Object = TreeMap<~str, Json>;
 
 /// The errors that can arise while parsing a JSON stream.
@@ -2211,7 +2211,7 @@ impl<A:ToJson,B:ToJson> ToJson for (A, B) {
     fn to_json(&self) -> Json {
         match *self {
           (ref a, ref b) => {
-            List(box [a.to_json(), b.to_json()])
+            List(vec![a.to_json(), b.to_json()])
           }
         }
     }
@@ -2221,7 +2221,7 @@ impl<A:ToJson,B:ToJson,C:ToJson> ToJson for (A, B, C) {
     fn to_json(&self) -> Json {
         match *self {
           (ref a, ref b, ref c) => {
-            List(box [a.to_json(), b.to_json(), c.to_json()])
+            List(vec![a.to_json(), b.to_json(), c.to_json()])
           }
         }
     }
@@ -2298,12 +2298,12 @@ enum Animal {
     struct Inner {
         a: (),
         b: uint,
-        c: ~[~str],
+        c: Vec<~str>,
     }
 
     #[deriving(Eq, Encodable, Decodable, Show)]
     struct Outer {
-        inner: ~[Inner],
+        inner: Vec<Inner>,
     }
 
     fn mk_object(items: &[(~str, Json)]) -> Json {
@@ -2360,22 +2360,22 @@ fn test_write_bool() {
 
     #[test]
     fn test_write_list() {
-        assert_eq!(List(~[]).to_str(), "[]".to_owned());
-        assert_eq!(List(~[]).to_pretty_str(), "[]".to_owned());
+        assert_eq!(List(vec![]).to_str(), "[]".to_owned());
+        assert_eq!(List(vec![]).to_pretty_str(), "[]".to_owned());
 
-        assert_eq!(List(~[Boolean(true)]).to_str(), "[true]".to_owned());
+        assert_eq!(List(vec![Boolean(true)]).to_str(), "[true]".to_owned());
         assert_eq!(
-            List(~[Boolean(true)]).to_pretty_str(),
+            List(vec![Boolean(true)]).to_pretty_str(),
             "\
             [\n  \
                 true\n\
             ]".to_owned()
         );
 
-        let long_test_list = List(box [
+        let long_test_list = List(vec![
             Boolean(false),
             Null,
-            List(box [String("foo\nbar".to_owned()), Number(3.5)])]);
+            List(vec![String("foo\nbar".to_owned()), Number(3.5)])]);
 
         assert_eq!(long_test_list.to_str(),
             "[false,null,[\"foo\\nbar\",3.5]]".to_owned());
@@ -2411,7 +2411,7 @@ fn test_write_object() {
         );
 
         let complex_obj = mk_object([
-                ("b".to_owned(), List(box [
+                ("b".to_owned(), List(vec![
                     mk_object([("c".to_owned(), String("\x0c\r".to_owned()))]),
                     mk_object([("d".to_owned(), String("".to_owned()))])
                 ]))
@@ -2443,7 +2443,7 @@ fn test_write_object() {
 
         let a = mk_object([
             ("a".to_owned(), Boolean(true)),
-            ("b".to_owned(), List(box [
+            ("b".to_owned(), List(vec![
                 mk_object([("c".to_owned(), String("\x0c\r".to_owned()))]),
                 mk_object([("d".to_owned(), String("".to_owned()))])
             ]))
@@ -2678,44 +2678,44 @@ fn test_read_list() {
         assert_eq!(from_str("[1,]"),  Err(SyntaxError(InvalidSyntax,        1, 4)));
         assert_eq!(from_str("[6 7]"), Err(SyntaxError(InvalidSyntax,        1, 4)));
 
-        assert_eq!(from_str("[]"), Ok(List(~[])));
-        assert_eq!(from_str("[ ]"), Ok(List(~[])));
-        assert_eq!(from_str("[true]"), Ok(List(~[Boolean(true)])));
-        assert_eq!(from_str("[ false ]"), Ok(List(~[Boolean(false)])));
-        assert_eq!(from_str("[null]"), Ok(List(~[Null])));
+        assert_eq!(from_str("[]"), Ok(List(vec![])));
+        assert_eq!(from_str("[ ]"), Ok(List(vec![])));
+        assert_eq!(from_str("[true]"), Ok(List(vec![Boolean(true)])));
+        assert_eq!(from_str("[ false ]"), Ok(List(vec![Boolean(false)])));
+        assert_eq!(from_str("[null]"), Ok(List(vec![Null])));
         assert_eq!(from_str("[3, 1]"),
-                     Ok(List(~[Number(3.0), Number(1.0)])));
+                     Ok(List(vec![Number(3.0), Number(1.0)])));
         assert_eq!(from_str("\n[3, 2]\n"),
-                     Ok(List(~[Number(3.0), Number(2.0)])));
+                     Ok(List(vec![Number(3.0), Number(2.0)])));
         assert_eq!(from_str("[2, [4, 1]]"),
-               Ok(List(~[Number(2.0), List(~[Number(4.0), Number(1.0)])])));
+               Ok(List(vec![Number(2.0), List(vec![Number(4.0), Number(1.0)])])));
     }
 
     #[test]
     fn test_decode_list() {
         let mut decoder = Decoder::new(from_str("[]").unwrap());
-        let v: ~[()] = Decodable::decode(&mut decoder).unwrap();
-        assert_eq!(v, ~[]);
+        let v: Vec<()> = Decodable::decode(&mut decoder).unwrap();
+        assert_eq!(v, vec![]);
 
         let mut decoder = Decoder::new(from_str("[null]").unwrap());
-        let v: ~[()] = Decodable::decode(&mut decoder).unwrap();
-        assert_eq!(v, ~[()]);
+        let v: Vec<()> = Decodable::decode(&mut decoder).unwrap();
+        assert_eq!(v, vec![()]);
 
         let mut decoder = Decoder::new(from_str("[true]").unwrap());
-        let v: ~[bool] = Decodable::decode(&mut decoder).unwrap();
-        assert_eq!(v, ~[true]);
+        let v: Vec<bool> = Decodable::decode(&mut decoder).unwrap();
+        assert_eq!(v, vec![true]);
 
         let mut decoder = Decoder::new(from_str("[true]").unwrap());
-        let v: ~[bool] = Decodable::decode(&mut decoder).unwrap();
-        assert_eq!(v, ~[true]);
+        let v: Vec<bool> = Decodable::decode(&mut decoder).unwrap();
+        assert_eq!(v, vec![true]);
 
         let mut decoder = Decoder::new(from_str("[3, 1]").unwrap());
-        let v: ~[int] = Decodable::decode(&mut decoder).unwrap();
-        assert_eq!(v, ~[3, 1]);
+        let v: Vec<int> = Decodable::decode(&mut decoder).unwrap();
+        assert_eq!(v, vec![3, 1]);
 
         let mut decoder = Decoder::new(from_str("[[3], [1, 2]]").unwrap());
-        let v: ~[~[uint]] = Decodable::decode(&mut decoder).unwrap();
-        assert_eq!(v, ~[~[3], ~[1, 2]]);
+        let v: Vec<Vec<uint>> = Decodable::decode(&mut decoder).unwrap();
+        assert_eq!(v, vec![vec![3], vec![1, 2]]);
     }
 
     #[test]
@@ -2750,7 +2750,7 @@ fn test_read_object() {
                       "{\"a\" : 1.0 ,\"b\": [ true ]}").unwrap(),
                   mk_object([
                       ("a".to_owned(), Number(1.0)),
-                      ("b".to_owned(), List(~[Boolean(true)]))
+                      ("b".to_owned(), List(vec![Boolean(true)]))
                   ]));
         assert_eq!(from_str(
                       "{".to_owned() +
@@ -2763,7 +2763,7 @@ fn test_read_object() {
                       "}").unwrap(),
                   mk_object([
                       ("a".to_owned(), Number(1.0)),
-                      ("b".to_owned(), List(~[
+                      ("b".to_owned(), List(vec![
                           Boolean(true),
                           String("foo\nbar".to_owned()),
                           mk_object([
@@ -2785,8 +2785,8 @@ fn test_decode_struct() {
         assert_eq!(
             v,
             Outer {
-                inner: ~[
-                    Inner { a: (), b: 2, c: ~["abc".to_owned(), "xyz".to_owned()] }
+                inner: vec![
+                    Inner { a: (), b: 2, c: vec!["abc".to_owned(), "xyz".to_owned()] }
                 ]
             }
         );
@@ -2837,7 +2837,7 @@ struct DecodeStruct {
         x: f64,
         y: bool,
         z: ~str,
-        w: ~[DecodeStruct]
+        w: Vec<DecodeStruct>
     }
     #[deriving(Decodable)]
     enum DecodeEnum {
index 9d68705fca73f643ffe8c1fadcc94c053e67b1c6..7914dd8c7d2aaf1269fc8288ae86e2f0aa724ba8 100644 (file)
@@ -453,12 +453,14 @@ fn encode(&self, s: &mut S) -> Result<(), E> {
 
 impl<E, D:Decoder<E>,T:Decodable<D, E>> Decodable<D, E> for ~[T] {
     fn decode(d: &mut D) -> Result<~[T], E> {
+        use std::vec::FromVec;
+
         d.read_seq(|d, len| {
             let mut v: Vec<T> = Vec::with_capacity(len);
             for i in range(0, len) {
                 v.push(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
             }
-            let k = v.move_iter().collect::<~[T]>();
+            let k: ~[T] = FromVec::from_vec(v);
             Ok(k)
         })
     }
@@ -557,7 +559,7 @@ fn encode(&self, e: &mut S) -> Result<(), E> {
 
 impl<E, D: Decoder<E>> Decodable<D, E> for path::posix::Path {
     fn decode(d: &mut D) -> Result<path::posix::Path, E> {
-        let bytes: ~[u8] = try!(Decodable::decode(d));
+        let bytes: Vec<u8> = try!(Decodable::decode(d));
         Ok(path::posix::Path::new(bytes))
     }
 }
@@ -570,7 +572,7 @@ fn encode(&self, e: &mut S) -> Result<(), E> {
 
 impl<E, D: Decoder<E>> Decodable<D, E> for path::windows::Path {
     fn decode(d: &mut D) -> Result<path::windows::Path, E> {
-        let bytes: ~[u8] = try!(Decodable::decode(d));
+        let bytes: Vec<u8> = try!(Decodable::decode(d));
         Ok(path::windows::Path::new(bytes))
     }
 }
@@ -600,17 +602,17 @@ fn emit_from_vec<T>(&mut self, v: &[T], f: |&mut S, &T| -> Result<(), E>) -> Res
 }
 
 pub trait DecoderHelpers<E> {
-    fn read_to_vec<T>(&mut self, f: |&mut Self| -> Result<T, E>) -> Result<~[T], E>;
+    fn read_to_vec<T>(&mut self, f: |&mut Self| -> Result<T, E>) -> Result<Vec<T>, E>;
 }
 
 impl<E, D:Decoder<E>> DecoderHelpers<E> for D {
-    fn read_to_vec<T>(&mut self, f: |&mut D| -> Result<T, E>) -> Result<~[T], E> {
+    fn read_to_vec<T>(&mut self, f: |&mut D| -> Result<T, E>) -> Result<Vec<T>, E> {
         self.read_seq(|this, len| {
             let mut v = Vec::with_capacity(len);
             for i in range(0, len) {
                 v.push(try!(this.read_seq_elt(i, |this| f(this))));
             }
-            Ok(v.move_iter().collect())
+            Ok(v)
         })
     }
 }
index 5b4400593b483af65a7b4864f0a700d5dcecef90..f45ec8a6742a23585695e0f4c21b4d7fba6b0b63 100644 (file)
@@ -13,7 +13,7 @@
 use to_str::{IntoStr};
 use str;
 use str::Str;
-use str::StrSlice;
+use str::{StrAllocating, StrSlice};
 use str::OwnedStr;
 use container::Container;
 use cast;
@@ -217,14 +217,14 @@ pub trait OwnedAsciiCast {
 
     /// Take ownership and cast to an ascii vector. Fail on non-ASCII input.
     #[inline]
-    fn into_ascii(self) -> ~[Ascii] {
+    fn into_ascii(self) -> Vec<Ascii> {
         assert!(self.is_ascii());
         unsafe {self.into_ascii_nocheck()}
     }
 
     /// Take ownership and cast to an ascii vector. Return None on non-ASCII input.
     #[inline]
-    fn into_ascii_opt(self) -> Option<~[Ascii]> {
+    fn into_ascii_opt(self) -> Option<Vec<Ascii>> {
         if self.is_ascii() {
             Some(unsafe { self.into_ascii_nocheck() })
         } else {
@@ -234,7 +234,7 @@ fn into_ascii_opt(self) -> Option<~[Ascii]> {
 
     /// Take ownership and cast to an ascii vector.
     /// Does not perform validation checks.
-    unsafe fn into_ascii_nocheck(self) -> ~[Ascii];
+    unsafe fn into_ascii_nocheck(self) -> Vec<Ascii>;
 }
 
 impl OwnedAsciiCast for ~[u8] {
@@ -244,8 +244,8 @@ fn is_ascii(&self) -> bool {
     }
 
     #[inline]
-    unsafe fn into_ascii_nocheck(self) -> ~[Ascii] {
-        cast::transmute(self)
+    unsafe fn into_ascii_nocheck(self) -> Vec<Ascii> {
+        cast::transmute(Vec::from_slice(self.as_slice()))
     }
 }
 
@@ -256,7 +256,20 @@ fn is_ascii(&self) -> bool {
     }
 
     #[inline]
-    unsafe fn into_ascii_nocheck(self) -> ~[Ascii] {
+    unsafe fn into_ascii_nocheck(self) -> Vec<Ascii> {
+        let v: ~[u8] = cast::transmute(self);
+        v.into_ascii_nocheck()
+    }
+}
+
+impl OwnedAsciiCast for Vec<u8> {
+    #[inline]
+    fn is_ascii(&self) -> bool {
+        self.as_slice().is_ascii()
+    }
+
+    #[inline]
+    unsafe fn into_ascii_nocheck(self) -> Vec<Ascii> {
         cast::transmute(self)
     }
 }
@@ -268,10 +281,10 @@ pub trait AsciiStr {
     fn as_str_ascii<'a>(&'a self) -> &'a str;
 
     /// Convert to vector representing a lower cased ascii string.
-    fn to_lower(&self) -> ~[Ascii];
+    fn to_lower(&self) -> Vec<Ascii>;
 
     /// Convert to vector representing a upper cased ascii string.
-    fn to_upper(&self) -> ~[Ascii];
+    fn to_upper(&self) -> Vec<Ascii>;
 
     /// Compares two Ascii strings ignoring case.
     fn eq_ignore_case(self, other: &[Ascii]) -> bool;
@@ -284,12 +297,12 @@ fn as_str_ascii<'a>(&'a self) -> &'a str {
     }
 
     #[inline]
-    fn to_lower(&self) -> ~[Ascii] {
+    fn to_lower(&self) -> Vec<Ascii> {
         self.iter().map(|a| a.to_lower()).collect()
     }
 
     #[inline]
-    fn to_upper(&self) -> ~[Ascii] {
+    fn to_upper(&self) -> Vec<Ascii> {
         self.iter().map(|a| a.to_upper()).collect()
     }
 
@@ -309,19 +322,21 @@ fn into_str(self) -> ~str {
 impl IntoStr for Vec<Ascii> {
     #[inline]
     fn into_str(self) -> ~str {
-        let v: ~[Ascii] = self.move_iter().collect();
-        unsafe { cast::transmute(v) }
+        unsafe {
+            let s: &str = cast::transmute(self.as_slice());
+            s.to_owned()
+        }
     }
 }
 
-/// Trait to convert to an owned byte array by consuming self
+/// Trait to convert to an owned byte vector by consuming self
 pub trait IntoBytes {
-    /// Converts to an owned byte array by consuming self
-    fn into_bytes(self) -> ~[u8];
+    /// Converts to an owned byte vector by consuming self
+    fn into_bytes(self) -> Vec<u8>;
 }
 
-impl IntoBytes for ~[Ascii] {
-    fn into_bytes(self) -> ~[u8] {
+impl IntoBytes for Vec<Ascii> {
+    fn into_bytes(self) -> Vec<u8> {
         unsafe { cast::transmute(self) }
     }
 }
@@ -404,9 +419,11 @@ unsafe fn str_map_bytes(string: ~str, map: &'static [u8]) -> ~str {
 
 #[inline]
 unsafe fn str_copy_map_bytes(string: &str, map: &'static [u8]) -> ~str {
-    let bytes = string.bytes().map(|b| map[b as uint]).collect::<~[_]>();
-
-    str::raw::from_utf8_owned(bytes)
+    let mut s = string.to_owned();
+    for b in str::raw::as_owned_vec(&mut s).mut_iter() {
+        *b = map[*b as uint];
+    }
+    s
 }
 
 static ASCII_LOWER_MAP: &'static [u8] = &[
@@ -492,7 +509,6 @@ mod tests {
     macro_rules! v2ascii (
         ( [$($e:expr),*]) => (&[$(Ascii{chr:$e}),*]);
         (&[$($e:expr),*]) => (&[$(Ascii{chr:$e}),*]);
-        (~[$($e:expr),*]) => (box [$(Ascii{chr:$e}),*]);
     )
 
     macro_rules! vec2ascii (
@@ -556,20 +572,17 @@ fn test_ascii_vec() {
 
     #[test]
     fn test_ascii_vec_ng() {
-        assert_eq!(Vec::from_slice("abCDef&?#".to_ascii().to_lower()).into_str(),
-                   "abcdef&?#".to_owned());
-        assert_eq!(Vec::from_slice("abCDef&?#".to_ascii().to_upper()).into_str(),
-                   "ABCDEF&?#".to_owned());
-        assert_eq!(Vec::from_slice("".to_ascii().to_lower()).into_str(), "".to_owned());
-        assert_eq!(Vec::from_slice("YMCA".to_ascii().to_lower()).into_str(), "ymca".to_owned());
-        assert_eq!(Vec::from_slice("abcDEFxyz:.;".to_ascii().to_upper()).into_str(),
-                   "ABCDEFXYZ:.;".to_owned());
+        assert_eq!("abCDef&?#".to_ascii().to_lower().into_str(), "abcdef&?#".to_owned());
+        assert_eq!("abCDef&?#".to_ascii().to_upper().into_str(), "ABCDEF&?#".to_owned());
+        assert_eq!("".to_ascii().to_lower().into_str(), "".to_owned());
+        assert_eq!("YMCA".to_ascii().to_lower().into_str(), "ymca".to_owned());
+        assert_eq!("abcDEFxyz:.;".to_ascii().to_upper().into_str(), "ABCDEFXYZ:.;".to_owned());
     }
 
     #[test]
     fn test_owned_ascii_vec() {
-        assert_eq!(("( ;".to_owned()).into_ascii(), v2ascii!(~[40, 32, 59]));
-        assert_eq!((box [40u8, 32u8, 59u8]).into_ascii(), v2ascii!(~[40, 32, 59]));
+        assert_eq!(("( ;".to_owned()).into_ascii(), vec2ascii![40, 32, 59]);
+        assert_eq!((box [40u8, 32u8, 59u8]).into_ascii(), vec2ascii![40, 32, 59]);
     }
 
     #[test]
@@ -580,13 +593,13 @@ fn test_ascii_as_str() {
 
     #[test]
     fn test_ascii_into_str() {
-        assert_eq!(v2ascii!(~[40, 32, 59]).into_str(), "( ;".to_owned());
+        assert_eq!(vec2ascii![40, 32, 59].into_str(), "( ;".to_owned());
         assert_eq!(vec2ascii!(40, 32, 59).into_str(), "( ;".to_owned());
     }
 
     #[test]
     fn test_ascii_to_bytes() {
-        assert_eq!(v2ascii!(~[40, 32, 59]).into_bytes(), box [40u8, 32u8, 59u8]);
+        assert_eq!(vec2ascii![40, 32, 59].into_bytes(), vec![40u8, 32u8, 59u8]);
     }
 
     #[test] #[should_fail]
@@ -625,10 +638,10 @@ fn test_opt() {
         assert_eq!(v.to_ascii_opt(), Some(v2));
         assert_eq!("zoä华".to_ascii_opt(), None);
 
-        assert_eq!((box [40u8, 32u8, 59u8]).into_ascii_opt(), Some(v2ascii!(~[40, 32, 59])));
-        assert_eq!((box [127u8, 128u8, 255u8]).into_ascii_opt(), None);
+        assert_eq!((vec![40u8, 32u8, 59u8]).into_ascii_opt(), Some(vec2ascii![40, 32, 59]));
+        assert_eq!((vec![127u8, 128u8, 255u8]).into_ascii_opt(), None);
 
-        assert_eq!(("( ;".to_owned()).into_ascii_opt(), Some(v2ascii!(~[40, 32, 59])));
+        assert_eq!(("( ;".to_owned()).into_ascii_opt(), Some(vec2ascii![40, 32, 59]));
         assert_eq!(("zoä华".to_owned()).into_ascii_opt(), None);
     }
 
index 74ab874d3194c0bfa24c073a82dfdff2ebdfe0d2..8846fa3f6f384389e686e60bfbe46bbb06987531 100644 (file)
@@ -510,9 +510,34 @@ fn my_fmt_fn(args: &fmt::Arguments) {
 pub use self::num::RadixFmt;
 
 mod num;
-pub mod parse;
 pub mod rt;
 
+#[cfg(stage0)]
+#[allow(missing_doc)]
+pub mod parse {
+    #[deriving(Eq)]
+    pub enum Alignment {
+        AlignLeft,
+        AlignRight,
+        AlignUnknown,
+    }
+
+    pub enum PluralKeyword {
+        Zero,
+        One,
+        Two,
+        Few,
+        Many,
+    }
+
+    pub enum Flag {
+        FlagSignPlus,
+        FlagSignMinus,
+        FlagAlternate,
+        FlagSignAwareZeroPad,
+    }
+}
+
 pub type Result = io::IoResult<()>;
 
 /// A struct to represent both where to emit formatting strings to and how they
@@ -524,7 +549,7 @@ pub struct Formatter<'a> {
     /// Character used as 'fill' whenever there is alignment
     pub fill: char,
     /// Boolean indication of whether the output should be left-aligned
-    pub align: parse::Alignment,
+    pub align: rt::Alignment,
     /// Optionally specified integer width that the output should be
     pub width: Option<uint>,
     /// Optionally specified precision for numeric types
@@ -757,7 +782,7 @@ pub unsafe fn write_unsafe(output: &mut io::Writer,
         width: None,
         precision: None,
         buf: output,
-        align: parse::AlignUnknown,
+        align: rt::AlignUnknown,
         fill: ' ',
         args: args,
         curarg: args.iter(),
@@ -890,15 +915,15 @@ fn execute(&mut self, method: &rt::Method, arg: Argument) -> Result {
                 let value = value - match offset { Some(i) => i, None => 0 };
                 for s in selectors.iter() {
                     let run = match s.selector {
-                        rt::Keyword(parse::Zero) => value == 0,
-                        rt::Keyword(parse::One) => value == 1,
-                        rt::Keyword(parse::Two) => value == 2,
+                        rt::Keyword(rt::Zero) => value == 0,
+                        rt::Keyword(rt::One) => value == 1,
+                        rt::Keyword(rt::Two) => value == 2,
 
                         // FIXME: Few/Many should have a user-specified boundary
                         //      One possible option would be in the function
                         //      pointer of the 'arg: Argument' struct.
-                        rt::Keyword(parse::Few) => value < 8,
-                        rt::Keyword(parse::Many) => value >= 8,
+                        rt::Keyword(rt::Few) => value < 8,
+                        rt::Keyword(rt::Many) => value >= 8,
 
                         rt::Literal(..) => false
                     };
@@ -960,7 +985,7 @@ fn runplural(&mut self, value: uint, pieces: &[rt::Piece]) -> Result {
     /// This function will correctly account for the flags provided as well as
     /// the minimum width. It will not take precision into account.
     pub fn pad_integral(&mut self, is_positive: bool, prefix: &str, buf: &[u8]) -> Result {
-        use fmt::parse::{FlagAlternate, FlagSignPlus, FlagSignAwareZeroPad};
+        use fmt::rt::{FlagAlternate, FlagSignPlus, FlagSignAwareZeroPad};
 
         let mut width = buf.len();
 
@@ -1000,11 +1025,11 @@ pub fn pad_integral(&mut self, is_positive: bool, prefix: &str, buf: &[u8]) -> R
             Some(min) if self.flags & (1 << (FlagSignAwareZeroPad as uint)) != 0 => {
                 self.fill = '0';
                 try!(write_prefix(self));
-                self.with_padding(min - width, parse::AlignRight, |f| f.buf.write(buf))
+                self.with_padding(min - width, rt::AlignRight, |f| f.buf.write(buf))
             }
             // Otherwise, the sign and prefix goes after the padding
             Some(min) => {
-                self.with_padding(min - width, parse::AlignRight, |f| {
+                self.with_padding(min - width, rt::AlignRight, |f| {
                     try!(write_prefix(f)); f.buf.write(buf)
                 })
             }
@@ -1055,7 +1080,7 @@ pub fn pad(&mut self, s: &str) -> Result {
             // If we're under both the maximum and the minimum width, then fill
             // up the minimum width with the specified string + some alignment.
             Some(width) => {
-                self.with_padding(width - s.len(), parse::AlignLeft, |me| {
+                self.with_padding(width - s.len(), rt::AlignLeft, |me| {
                     me.buf.write(s.as_bytes())
                 })
             }
@@ -1066,13 +1091,13 @@ pub fn pad(&mut self, s: &str) -> Result {
     /// afterwards depending on whether right or left alingment is requested.
     fn with_padding(&mut self,
                     padding: uint,
-                    default: parse::Alignment,
+                    default: rt::Alignment,
                     f: |&mut Formatter| -> Result) -> Result {
         let align = match self.align {
-            parse::AlignUnknown => default,
-            parse::AlignLeft | parse::AlignRight => self.align
+            rt::AlignUnknown => default,
+            rt::AlignLeft | rt::AlignRight => self.align
         };
-        if align == parse::AlignLeft {
+        if align == rt::AlignLeft {
             try!(f(self));
         }
         let mut fill = [0u8, ..4];
@@ -1080,7 +1105,7 @@ fn with_padding(&mut self,
         for _ in range(0, padding) {
             try!(self.buf.write(fill.slice_to(len)));
         }
-        if align == parse::AlignRight {
+        if align == rt::AlignRight {
             try!(f(self));
         }
         Ok(())
@@ -1203,7 +1228,7 @@ fn fmt(&self, f: &mut Formatter) -> Result {
 
 impl<T> Pointer for *T {
     fn fmt(&self, f: &mut Formatter) -> Result {
-        f.flags |= 1 << (parse::FlagAlternate as uint);
+        f.flags |= 1 << (rt::FlagAlternate as uint);
         secret_lower_hex::<uint>(&(*self as uint), f)
     }
 }
@@ -1304,7 +1329,7 @@ fn fmt(&self, f: &mut Formatter) -> Result {
 
 impl<'a, T: Show> Show for &'a [T] {
     fn fmt(&self, f: &mut Formatter) -> Result {
-        if f.flags & (1 << (parse::FlagAlternate as uint)) == 0 {
+        if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 {
             try!(write!(f.buf, "["));
         }
         let mut is_first = true;
@@ -1316,7 +1341,7 @@ fn fmt(&self, f: &mut Formatter) -> Result {
             }
             try!(write!(f.buf, "{}", *x))
         }
-        if f.flags & (1 << (parse::FlagAlternate as uint)) == 0 {
+        if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 {
             try!(write!(f.buf, "]"));
         }
         Ok(())
diff --git a/src/libstd/fmt/parse.rs b/src/libstd/fmt/parse.rs
deleted file mode 100644 (file)
index ba126e0..0000000
+++ /dev/null
@@ -1,986 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Parsing of format strings
-//!
-//! These structures are used when parsing format strings for the compiler.
-//! Parsing does not happen at runtime: structures of `std::fmt::rt` are
-//! generated instead.
-
-use prelude::*;
-
-use char;
-use owned::Box;
-use str;
-
-/// A piece is a portion of the format string which represents the next part
-/// to emit. These are emitted as a stream by the `Parser` class.
-#[deriving(Eq)]
-pub enum Piece<'a> {
-    /// A literal string which should directly be emitted
-    String(&'a str),
-    /// A back-reference to whatever the current argument is. This is used
-    /// inside of a method call to refer back to the original argument.
-    CurrentArgument,
-    /// This describes that formatting should process the next argument (as
-    /// specified inside) for emission.
-    Argument(Argument<'a>),
-}
-
-/// Representation of an argument specification.
-#[deriving(Eq)]
-pub struct Argument<'a> {
-    /// Where to find this argument
-    pub position: Position<'a>,
-    /// How to format the argument
-    pub format: FormatSpec<'a>,
-    /// If not `None`, what method to invoke on the argument
-    pub method: Option<Box<Method<'a>>>
-}
-
-/// Specification for the formatting of an argument in the format string.
-#[deriving(Eq)]
-pub struct FormatSpec<'a> {
-    /// Optionally specified character to fill alignment with
-    pub fill: Option<char>,
-    /// Optionally specified alignment
-    pub align: Alignment,
-    /// Packed version of various flags provided
-    pub flags: uint,
-    /// The integer precision to use
-    pub precision: Count<'a>,
-    /// The string width requested for the resulting format
-    pub width: Count<'a>,
-    /// The descriptor string representing the name of the format desired for
-    /// this argument, this can be empty or any number of characters, although
-    /// it is required to be one word.
-    pub ty: &'a str
-}
-
-/// Enum describing where an argument for a format can be located.
-#[deriving(Eq)]
-pub enum Position<'a> {
-    /// The argument will be in the next position. This is the default.
-    ArgumentNext,
-    /// The argument is located at a specific index.
-    ArgumentIs(uint),
-    /// The argument has a name.
-    ArgumentNamed(&'a str),
-}
-
-/// Enum of alignments which are supported.
-#[deriving(Eq)]
-pub enum Alignment {
-    /// The value will be aligned to the left.
-    AlignLeft,
-    /// The value will be aligned to the right.
-    AlignRight,
-    /// The value will take on a default alignment.
-    AlignUnknown,
-}
-
-/// Various flags which can be applied to format strings. The meaning of these
-/// flags is defined by the formatters themselves.
-#[deriving(Eq)]
-pub enum Flag {
-    /// A `+` will be used to denote positive numbers.
-    FlagSignPlus,
-    /// A `-` will be used to denote negative numbers. This is the default.
-    FlagSignMinus,
-    /// An alternate form will be used for the value. In the case of numbers,
-    /// this means that the number will be prefixed with the supplied string.
-    FlagAlternate,
-    /// For numbers, this means that the number will be padded with zeroes,
-    /// and the sign (`+` or `-`) will precede them.
-    FlagSignAwareZeroPad,
-}
-
-/// A count is used for the precision and width parameters of an integer, and
-/// can reference either an argument or a literal integer.
-#[deriving(Eq)]
-pub enum Count<'a> {
-    /// The count is specified explicitly.
-    CountIs(uint),
-    /// The count is specified by the argument with the given name.
-    CountIsName(&'a str),
-    /// The count is specified by the argument at the given index.
-    CountIsParam(uint),
-    /// The count is specified by the next parameter.
-    CountIsNextParam,
-    /// The count is implied and cannot be explicitly specified.
-    CountImplied,
-}
-
-/// Enum describing all of the possible methods which the formatting language
-/// currently supports.
-#[deriving(Eq)]
-pub enum Method<'a> {
-    /// A plural method selects on an integer over a list of either integer or
-    /// keyword-defined clauses. The meaning of the keywords is defined by the
-    /// current locale.
-    ///
-    /// An offset is optionally present at the beginning which is used to
-    /// match against keywords, but it is not matched against the literal
-    /// integers.
-    ///
-    /// The final element of this enum is the default "other" case which is
-    /// always required to be specified.
-    Plural(Option<uint>, Vec<PluralArm<'a>>, Vec<Piece<'a>>),
-
-    /// A select method selects over a string. Each arm is a different string
-    /// which can be selected for.
-    ///
-    /// As with `Plural`, a default "other" case is required as well.
-    Select(Vec<SelectArm<'a>>, Vec<Piece<'a>>),
-}
-
-/// A selector for what pluralization a plural method should take
-#[deriving(Eq, TotalEq, Hash)]
-pub enum PluralSelector {
-    /// One of the plural keywords should be used
-    Keyword(PluralKeyword),
-    /// A literal pluralization should be used
-    Literal(uint),
-}
-
-/// Structure representing one "arm" of the `plural` function.
-#[deriving(Eq)]
-pub struct PluralArm<'a> {
-    /// A selector can either be specified by a keyword or with an integer
-    /// literal.
-    pub selector: PluralSelector,
-    /// Array of pieces which are the format of this arm
-    pub result: Vec<Piece<'a>>,
-}
-
-/// Enum of the 5 CLDR plural keywords. There is one more, "other", but that
-/// is specially placed in the `Plural` variant of `Method`.
-///
-/// http://www.icu-project.org/apiref/icu4c/classicu_1_1PluralRules.html
-#[deriving(Eq, TotalEq, Hash)]
-#[allow(missing_doc)]
-pub enum PluralKeyword {
-    /// The plural form for zero objects.
-    Zero,
-    /// The plural form for one object.
-    One,
-    /// The plural form for two objects.
-    Two,
-    /// The plural form for few objects.
-    Few,
-    /// The plural form for many objects.
-    Many,
-}
-
-/// Structure representing one "arm" of the `select` function.
-#[deriving(Eq)]
-pub struct SelectArm<'a> {
-    /// String selector which guards this arm
-    pub selector: &'a str,
-    /// Array of pieces which are the format of this arm
-    pub result: Vec<Piece<'a>>,
-}
-
-/// The parser structure for interpreting the input format string. This is
-/// modelled as an iterator over `Piece` structures to form a stream of tokens
-/// being output.
-///
-/// This is a recursive-descent parser for the sake of simplicity, and if
-/// necessary there's probably lots of room for improvement performance-wise.
-pub struct Parser<'a> {
-    input: &'a str,
-    cur: str::CharOffsets<'a>,
-    depth: uint,
-    /// Error messages accumulated during parsing
-    pub errors: Vec<~str>,
-}
-
-impl<'a> Iterator<Piece<'a>> for Parser<'a> {
-    fn next(&mut self) -> Option<Piece<'a>> {
-        match self.cur.clone().next() {
-            Some((_, '#')) => { self.cur.next(); Some(CurrentArgument) }
-            Some((_, '{')) => {
-                self.cur.next();
-                let ret = Some(Argument(self.argument()));
-                self.must_consume('}');
-                ret
-            }
-            Some((pos, '\\')) => {
-                self.cur.next();
-                self.escape(); // ensure it's a valid escape sequence
-                Some(String(self.string(pos + 1))) // skip the '\' character
-            }
-            Some((_, '}')) if self.depth == 0 => {
-                self.cur.next();
-                self.err("unmatched `}` found");
-                None
-            }
-            Some((_, '}')) | None => { None }
-            Some((pos, _)) => {
-                Some(String(self.string(pos)))
-            }
-        }
-    }
-}
-
-impl<'a> Parser<'a> {
-    /// Creates a new parser for the given format string
-    pub fn new<'a>(s: &'a str) -> Parser<'a> {
-        Parser {
-            input: s,
-            cur: s.char_indices(),
-            depth: 0,
-            errors: vec!(),
-        }
-    }
-
-    /// Notifies of an error. The message doesn't actually need to be of type
-    /// ~str, but I think it does when this eventually uses conditions so it
-    /// might as well start using it now.
-    fn err(&mut self, msg: &str) {
-        self.errors.push(msg.to_owned());
-    }
-
-    /// Optionally consumes the specified character. If the character is not at
-    /// the current position, then the current iterator isn't moved and false is
-    /// returned, otherwise the character is consumed and true is returned.
-    fn consume(&mut self, c: char) -> bool {
-        match self.cur.clone().next() {
-            Some((_, maybe)) if c == maybe => {
-                self.cur.next();
-                true
-            }
-            Some(..) | None => false,
-        }
-    }
-
-    /// Forces consumption of the specified character. If the character is not
-    /// found, an error is emitted.
-    fn must_consume(&mut self, c: char) {
-        self.ws();
-        match self.cur.clone().next() {
-            Some((_, maybe)) if c == maybe => {
-                self.cur.next();
-            }
-            Some((_, other)) => {
-                self.err(
-                    format!("expected `{}` but found `{}`", c, other));
-            }
-            None => {
-                self.err(
-                    format!("expected `{}` but string was terminated", c));
-            }
-        }
-    }
-
-    /// Attempts to consume any amount of whitespace followed by a character
-    fn wsconsume(&mut self, c: char) -> bool {
-        self.ws(); self.consume(c)
-    }
-
-    /// Consumes all whitespace characters until the first non-whitespace
-    /// character
-    fn ws(&mut self) {
-        loop {
-            match self.cur.clone().next() {
-                Some((_, c)) if char::is_whitespace(c) => { self.cur.next(); }
-                Some(..) | None => { return }
-            }
-        }
-    }
-
-    /// Consumes an escape sequence, failing if there is not a valid character
-    /// to be escaped.
-    fn escape(&mut self) -> char {
-        match self.cur.next() {
-            Some((_, c @ '#')) | Some((_, c @ '{')) |
-            Some((_, c @ '\\')) | Some((_, c @ '}')) => { c }
-            Some((_, c)) => {
-                self.err(format!("invalid escape character `{}`", c));
-                c
-            }
-            None => {
-                self.err("expected an escape sequence, but format string was \
-                           terminated");
-                ' '
-            }
-        }
-    }
-
-    /// Parses all of a string which is to be considered a "raw literal" in a
-    /// format string. This is everything outside of the braces.
-    fn string(&mut self, start: uint) -> &'a str {
-        loop {
-            // we may not consume the character, so clone the iterator
-            match self.cur.clone().next() {
-                Some((pos, '\\')) | Some((pos, '#')) |
-                Some((pos, '}')) | Some((pos, '{')) => {
-                    return self.input.slice(start, pos);
-                }
-                Some(..) => { self.cur.next(); }
-                None => {
-                    self.cur.next();
-                    return self.input.slice(start, self.input.len());
-                }
-            }
-        }
-    }
-
-    /// Parses an Argument structure, or what's contained within braces inside
-    /// the format string
-    fn argument(&mut self) -> Argument<'a> {
-        Argument {
-            position: self.position(),
-            format: self.format(),
-            method: self.method(),
-        }
-    }
-
-    /// Parses a positional argument for a format. This could either be an
-    /// integer index of an argument, a named argument, or a blank string.
-    fn position(&mut self) -> Position<'a> {
-        match self.integer() {
-            Some(i) => { ArgumentIs(i) }
-            None => {
-                match self.cur.clone().next() {
-                    Some((_, c)) if char::is_alphabetic(c) => {
-                        ArgumentNamed(self.word())
-                    }
-                    _ => ArgumentNext
-                }
-            }
-        }
-    }
-
-    /// Parses a format specifier at the current position, returning all of the
-    /// relevant information in the FormatSpec struct.
-    fn format(&mut self) -> FormatSpec<'a> {
-        let mut spec = FormatSpec {
-            fill: None,
-            align: AlignUnknown,
-            flags: 0,
-            precision: CountImplied,
-            width: CountImplied,
-            ty: self.input.slice(0, 0),
-        };
-        if !self.consume(':') { return spec }
-
-        // fill character
-        match self.cur.clone().next() {
-            Some((_, c)) => {
-                match self.cur.clone().skip(1).next() {
-                    Some((_, '>')) | Some((_, '<')) => {
-                        spec.fill = Some(c);
-                        self.cur.next();
-                    }
-                    Some(..) | None => {}
-                }
-            }
-            None => {}
-        }
-        // Alignment
-        if self.consume('<') {
-            spec.align = AlignLeft;
-        } else if self.consume('>') {
-            spec.align = AlignRight;
-        }
-        // Sign flags
-        if self.consume('+') {
-            spec.flags |= 1 << (FlagSignPlus as uint);
-        } else if self.consume('-') {
-            spec.flags |= 1 << (FlagSignMinus as uint);
-        }
-        // Alternate marker
-        if self.consume('#') {
-            spec.flags |= 1 << (FlagAlternate as uint);
-        }
-        // Width and precision
-        let mut havewidth = false;
-        if self.consume('0') {
-            // small ambiguity with '0$' as a format string. In theory this is a
-            // '0' flag and then an ill-formatted format string with just a '$'
-            // and no count, but this is better if we instead interpret this as
-            // no '0' flag and '0$' as the width instead.
-            if self.consume('$') {
-                spec.width = CountIsParam(0);
-                havewidth = true;
-            } else {
-                spec.flags |= 1 << (FlagSignAwareZeroPad as uint);
-            }
-        }
-        if !havewidth {
-            spec.width = self.count();
-        }
-        if self.consume('.') {
-            if self.consume('*') {
-                spec.precision = CountIsNextParam;
-            } else {
-                spec.precision = self.count();
-            }
-        }
-        // Finally the actual format specifier
-        if self.consume('?') {
-            spec.ty = "?";
-        } else {
-            spec.ty = self.word();
-        }
-        return spec;
-    }
-
-    /// Parses a method to be applied to the previously specified argument and
-    /// its format. The two current supported methods are 'plural' and 'select'
-    fn method(&mut self) -> Option<Box<Method<'a>>> {
-        if !self.wsconsume(',') {
-            return None;
-        }
-        self.ws();
-        match self.word() {
-            "select" => {
-                self.must_consume(',');
-                Some(self.select())
-            }
-            "plural" => {
-                self.must_consume(',');
-                Some(self.plural())
-            }
-            "" => {
-                self.err("expected method after comma");
-                return None;
-            }
-            method => {
-                self.err(format!("unknown method: `{}`", method));
-                return None;
-            }
-        }
-    }
-
-    /// Parses a 'select' statement (after the initial 'select' word)
-    fn select(&mut self) -> Box<Method<'a>> {
-        let mut other = None;
-        let mut arms = vec!();
-        // Consume arms one at a time
-        loop {
-            self.ws();
-            let selector = self.word();
-            if selector == "" {
-                self.err("cannot have an empty selector");
-                break
-            }
-            self.must_consume('{');
-            self.depth += 1;
-            let pieces = self.collect();
-            self.depth -= 1;
-            self.must_consume('}');
-            if selector == "other" {
-                if !other.is_none() {
-                    self.err("multiple `other` statements in `select");
-                }
-                other = Some(pieces);
-            } else {
-                arms.push(SelectArm { selector: selector, result: pieces });
-            }
-            self.ws();
-            match self.cur.clone().next() {
-                Some((_, '}')) => { break }
-                Some(..) | None => {}
-            }
-        }
-        // The "other" selector must be present
-        let other = match other {
-            Some(arm) => { arm }
-            None => {
-                self.err("`select` statement must provide an `other` case");
-                vec!()
-            }
-        };
-        box Select(arms, other)
-    }
-
-    /// Parses a 'plural' statement (after the initial 'plural' word)
-    fn plural(&mut self) -> Box<Method<'a>> {
-        let mut offset = None;
-        let mut other = None;
-        let mut arms = vec!();
-
-        // First, attempt to parse the 'offset:' field. We know the set of
-        // selector words which can appear in plural arms, and the only ones
-        // which start with 'o' are "other" and "offset", hence look two
-        // characters deep to see if we can consume the word "offset"
-        self.ws();
-        let mut it = self.cur.clone();
-        match it.next() {
-            Some((_, 'o')) => {
-                match it.next() {
-                    Some((_, 'f')) => {
-                        let word = self.word();
-                        if word != "offset" {
-                            self.err(format!("expected `offset`, found `{}`",
-                                             word));
-                        } else {
-                            self.must_consume(':');
-                            match self.integer() {
-                                Some(i) => { offset = Some(i); }
-                                None => {
-                                    self.err("offset must be an integer");
-                                }
-                            }
-                        }
-                    }
-                    Some(..) | None => {}
-                }
-            }
-            Some(..) | None => {}
-        }
-
-        // Next, generate all the arms
-        loop {
-            let mut isother = false;
-            let selector = if self.wsconsume('=') {
-                match self.integer() {
-                    Some(i) => Literal(i),
-                    None => {
-                        self.err("plural `=` selectors must be followed by an \
-                                  integer");
-                        Literal(0)
-                    }
-                }
-            } else {
-                let word = self.word();
-                match word {
-                    "other" => { isother = true; Keyword(Zero) }
-                    "zero"  => Keyword(Zero),
-                    "one"   => Keyword(One),
-                    "two"   => Keyword(Two),
-                    "few"   => Keyword(Few),
-                    "many"  => Keyword(Many),
-                    word    => {
-                        self.err(format!("unexpected plural selector `{}`",
-                                         word));
-                        if word == "" {
-                            break
-                        } else {
-                            Keyword(Zero)
-                        }
-                    }
-                }
-            };
-            self.must_consume('{');
-            self.depth += 1;
-            let pieces = self.collect();
-            self.depth -= 1;
-            self.must_consume('}');
-            if isother {
-                if !other.is_none() {
-                    self.err("multiple `other` statements in `select");
-                }
-                other = Some(pieces);
-            } else {
-                arms.push(PluralArm { selector: selector, result: pieces });
-            }
-            self.ws();
-            match self.cur.clone().next() {
-                Some((_, '}')) => { break }
-                Some(..) | None => {}
-            }
-        }
-
-        let other = match other {
-            Some(arm) => { arm }
-            None => {
-                self.err("`plural` statement must provide an `other` case");
-                vec!()
-            }
-        };
-        box Plural(offset, arms, other)
-    }
-
-    /// Parses a Count parameter at the current position. This does not check
-    /// for 'CountIsNextParam' because that is only used in precision, not
-    /// width.
-    fn count(&mut self) -> Count<'a> {
-        match self.integer() {
-            Some(i) => {
-                if self.consume('$') {
-                    CountIsParam(i)
-                } else {
-                    CountIs(i)
-                }
-            }
-            None => {
-                let tmp = self.cur.clone();
-                match self.word() {
-                    word if word.len() > 0 && self.consume('$') => {
-                        CountIsName(word)
-                    }
-                    _ => {
-                        self.cur = tmp;
-                        CountImplied
-                    }
-                }
-            }
-        }
-    }
-
-    /// Parses a word starting at the current position. A word is considered to
-    /// be an alphabetic character followed by any number of alphanumeric
-    /// characters.
-    fn word(&mut self) -> &'a str {
-        let start = match self.cur.clone().next() {
-            Some((pos, c)) if char::is_XID_start(c) => {
-                self.cur.next();
-                pos
-            }
-            Some(..) | None => { return self.input.slice(0, 0); }
-        };
-        let mut end;
-        loop {
-            match self.cur.clone().next() {
-                Some((_, c)) if char::is_XID_continue(c) => {
-                    self.cur.next();
-                }
-                Some((pos, _)) => { end = pos; break }
-                None => { end = self.input.len(); break }
-            }
-        }
-        self.input.slice(start, end)
-    }
-
-    /// Optionally parses an integer at the current position. This doesn't deal
-    /// with overflow at all, it's just accumulating digits.
-    fn integer(&mut self) -> Option<uint> {
-        let mut cur = 0;
-        let mut found = false;
-        loop {
-            match self.cur.clone().next() {
-                Some((_, c)) => {
-                    match char::to_digit(c, 10) {
-                        Some(i) => {
-                            cur = cur * 10 + i;
-                            found = true;
-                            self.cur.next();
-                        }
-                        None => { break }
-                    }
-                }
-                None => { break }
-            }
-        }
-        if found {
-            return Some(cur);
-        } else {
-            return None;
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use prelude::*;
-
-    fn same(fmt: &'static str, p: &[Piece<'static>]) {
-        let mut parser = Parser::new(fmt);
-        assert!(p == parser.collect::<Vec<Piece<'static>>>().as_slice());
-    }
-
-    fn fmtdflt() -> FormatSpec<'static> {
-        return FormatSpec {
-            fill: None,
-            align: AlignUnknown,
-            flags: 0,
-            precision: CountImplied,
-            width: CountImplied,
-            ty: "",
-        }
-    }
-
-    fn musterr(s: &str) {
-        let mut p = Parser::new(s);
-        p.next();
-        assert!(p.errors.len() != 0);
-    }
-
-    #[test]
-    fn simple() {
-        same("asdf", [String("asdf")]);
-        same("a\\{b", [String("a"), String("{b")]);
-        same("a\\#b", [String("a"), String("#b")]);
-        same("a\\}b", [String("a"), String("}b")]);
-        same("a\\}", [String("a"), String("}")]);
-        same("\\}", [String("}")]);
-    }
-
-    #[test] fn invalid01() { musterr("{") }
-    #[test] fn invalid02() { musterr("\\") }
-    #[test] fn invalid03() { musterr("\\a") }
-    #[test] fn invalid04() { musterr("{3a}") }
-    #[test] fn invalid05() { musterr("{:|}") }
-    #[test] fn invalid06() { musterr("{:>>>}") }
-
-    #[test]
-    fn format_nothing() {
-        same("{}", [Argument(Argument {
-            position: ArgumentNext,
-            format: fmtdflt(),
-            method: None,
-        })]);
-    }
-    #[test]
-    fn format_position() {
-        same("{3}", [Argument(Argument {
-            position: ArgumentIs(3),
-            format: fmtdflt(),
-            method: None,
-        })]);
-    }
-    #[test]
-    fn format_position_nothing_else() {
-        same("{3:}", [Argument(Argument {
-            position: ArgumentIs(3),
-            format: fmtdflt(),
-            method: None,
-        })]);
-    }
-    #[test]
-    fn format_type() {
-        same("{3:a}", [Argument(Argument {
-            position: ArgumentIs(3),
-            format: FormatSpec {
-                fill: None,
-                align: AlignUnknown,
-                flags: 0,
-                precision: CountImplied,
-                width: CountImplied,
-                ty: "a",
-            },
-            method: None,
-        })]);
-    }
-    #[test]
-    fn format_align_fill() {
-        same("{3:>}", [Argument(Argument {
-            position: ArgumentIs(3),
-            format: FormatSpec {
-                fill: None,
-                align: AlignRight,
-                flags: 0,
-                precision: CountImplied,
-                width: CountImplied,
-                ty: "",
-            },
-            method: None,
-        })]);
-        same("{3:0<}", [Argument(Argument {
-            position: ArgumentIs(3),
-            format: FormatSpec {
-                fill: Some('0'),
-                align: AlignLeft,
-                flags: 0,
-                precision: CountImplied,
-                width: CountImplied,
-                ty: "",
-            },
-            method: None,
-        })]);
-        same("{3:*<abcd}", [Argument(Argument {
-            position: ArgumentIs(3),
-            format: FormatSpec {
-                fill: Some('*'),
-                align: AlignLeft,
-                flags: 0,
-                precision: CountImplied,
-                width: CountImplied,
-                ty: "abcd",
-            },
-            method: None,
-        })]);
-    }
-    #[test]
-    fn format_counts() {
-        same("{:10s}", [Argument(Argument {
-            position: ArgumentNext,
-            format: FormatSpec {
-                fill: None,
-                align: AlignUnknown,
-                flags: 0,
-                precision: CountImplied,
-                width: CountIs(10),
-                ty: "s",
-            },
-            method: None,
-        })]);
-        same("{:10$.10s}", [Argument(Argument {
-            position: ArgumentNext,
-            format: FormatSpec {
-                fill: None,
-                align: AlignUnknown,
-                flags: 0,
-                precision: CountIs(10),
-                width: CountIsParam(10),
-                ty: "s",
-            },
-            method: None,
-        })]);
-        same("{:.*s}", [Argument(Argument {
-            position: ArgumentNext,
-            format: FormatSpec {
-                fill: None,
-                align: AlignUnknown,
-                flags: 0,
-                precision: CountIsNextParam,
-                width: CountImplied,
-                ty: "s",
-            },
-            method: None,
-        })]);
-        same("{:.10$s}", [Argument(Argument {
-            position: ArgumentNext,
-            format: FormatSpec {
-                fill: None,
-                align: AlignUnknown,
-                flags: 0,
-                precision: CountIsParam(10),
-                width: CountImplied,
-                ty: "s",
-            },
-            method: None,
-        })]);
-        same("{:a$.b$s}", [Argument(Argument {
-            position: ArgumentNext,
-            format: FormatSpec {
-                fill: None,
-                align: AlignUnknown,
-                flags: 0,
-                precision: CountIsName("b"),
-                width: CountIsName("a"),
-                ty: "s",
-            },
-            method: None,
-        })]);
-    }
-    #[test]
-    fn format_flags() {
-        same("{:-}", [Argument(Argument {
-            position: ArgumentNext,
-            format: FormatSpec {
-                fill: None,
-                align: AlignUnknown,
-                flags: (1 << FlagSignMinus as uint),
-                precision: CountImplied,
-                width: CountImplied,
-                ty: "",
-            },
-            method: None,
-        })]);
-        same("{:+#}", [Argument(Argument {
-            position: ArgumentNext,
-            format: FormatSpec {
-                fill: None,
-                align: AlignUnknown,
-                flags: (1 << FlagSignPlus as uint) | (1 << FlagAlternate as uint),
-                precision: CountImplied,
-                width: CountImplied,
-                ty: "",
-            },
-            method: None,
-        })]);
-    }
-    #[test]
-    fn format_mixture() {
-        same("abcd {3:a} efg", [String("abcd "), Argument(Argument {
-            position: ArgumentIs(3),
-            format: FormatSpec {
-                fill: None,
-                align: AlignUnknown,
-                flags: 0,
-                precision: CountImplied,
-                width: CountImplied,
-                ty: "a",
-            },
-            method: None,
-        }), String(" efg")]);
-    }
-
-    #[test]
-    fn select_simple() {
-        same("{, select, other { haha } }", [Argument(Argument{
-            position: ArgumentNext,
-            format: fmtdflt(),
-            method: Some(box Select(vec![], vec![String(" haha ")]))
-        })]);
-        same("{1, select, other { haha } }", [Argument(Argument{
-            position: ArgumentIs(1),
-            format: fmtdflt(),
-            method: Some(box Select(vec![], vec![String(" haha ")]))
-        })]);
-        same("{1, select, other {#} }", [Argument(Argument{
-            position: ArgumentIs(1),
-            format: fmtdflt(),
-            method: Some(box Select(vec![], vec![CurrentArgument]))
-        })]);
-        same("{1, select, other {{2, select, other {lol}}} }", [Argument(Argument{
-            position: ArgumentIs(1),
-            format: fmtdflt(),
-            method: Some(box Select(vec![], vec![Argument(Argument{
-                position: ArgumentIs(2),
-                format: fmtdflt(),
-                method: Some(box Select(vec![], vec![String("lol")]))
-            })])) // wat
-        })]);
-    }
-
-    #[test]
-    fn select_cases() {
-        same("{1, select, a{1} b{2} c{3} other{4} }", [Argument(Argument{
-            position: ArgumentIs(1),
-            format: fmtdflt(),
-            method: Some(box Select(vec![
-                SelectArm{ selector: "a", result: vec![String("1")] },
-                SelectArm{ selector: "b", result: vec![String("2")] },
-                SelectArm{ selector: "c", result: vec![String("3")] },
-            ], vec![String("4")]))
-        })]);
-    }
-
-    #[test] fn badselect01() { musterr("{select, }") }
-    #[test] fn badselect02() { musterr("{1, select}") }
-    #[test] fn badselect03() { musterr("{1, select, }") }
-    #[test] fn badselect04() { musterr("{1, select, a {}}") }
-    #[test] fn badselect05() { musterr("{1, select, other }}") }
-    #[test] fn badselect06() { musterr("{1, select, other {}") }
-    #[test] fn badselect07() { musterr("{select, other {}") }
-    #[test] fn badselect08() { musterr("{1 select, other {}") }
-    #[test] fn badselect09() { musterr("{:d select, other {}") }
-    #[test] fn badselect10() { musterr("{1:d select, other {}") }
-
-    #[test]
-    fn plural_simple() {
-        same("{, plural, other { haha } }", [Argument(Argument{
-            position: ArgumentNext,
-            format: fmtdflt(),
-            method: Some(box Plural(None, vec![], vec![String(" haha ")]))
-        })]);
-        same("{:, plural, other { haha } }", [Argument(Argument{
-            position: ArgumentNext,
-            format: fmtdflt(),
-            method: Some(box Plural(None, vec![], vec![String(" haha ")]))
-        })]);
-        same("{, plural, offset:1 =2{2} =3{3} many{yes} other{haha} }",
-        [Argument(Argument{
-            position: ArgumentNext,
-            format: fmtdflt(),
-            method: Some(box Plural(Some(1), vec![
-                PluralArm{ selector: Literal(2), result: vec![String("2")] },
-                PluralArm{ selector: Literal(3), result: vec![String("3")] },
-                PluralArm{ selector: Keyword(Many), result: vec![String("yes")] }
-            ], vec![String("haha")]))
-        })]);
-    }
-}
index 01c2c06c3fbadb1f2bc8bcf6c81ee86449b46a3b..33e86a4485b3fa2f56fab7f6c4c89de71bab62c7 100644 (file)
 #![allow(missing_doc)]
 #![doc(hidden)]
 
-use fmt::parse;
 use option::Option;
 
+#[cfg(stage0)]
+pub use fmt::parse::{Alignment, AlignLeft, AlignRight, AlignUnknown};
+#[cfg(stage0)]
+pub use fmt::parse::{PluralKeyword, Zero, One, Two, Few, Many};
+#[cfg(stage0)]
+pub use fmt::parse::{Flag, FlagSignPlus, FlagSignMinus, FlagSignAwareZeroPad};
+#[cfg(stage0)]
+pub use fmt::parse::{FlagAlternate};
+
 pub enum Piece<'a> {
     String(&'a str),
     // FIXME(#8259): this shouldn't require the unit-value here
@@ -35,12 +43,20 @@ pub struct Argument<'a> {
 
 pub struct FormatSpec {
     pub fill: char,
-    pub align: parse::Alignment,
+    pub align: Alignment,
     pub flags: uint,
     pub precision: Count,
     pub width: Count,
 }
 
+#[cfg(not(stage0))]
+#[deriving(Eq)]
+pub enum Alignment {
+    AlignLeft,
+    AlignRight,
+    AlignUnknown,
+}
+
 pub enum Count {
     CountIs(uint), CountIsParam(uint), CountIsNextParam, CountImplied,
 }
@@ -49,16 +65,32 @@ pub enum Position {
     ArgumentNext, ArgumentIs(uint)
 }
 
+#[cfg(not(stage0))]
+pub enum Flag {
+    FlagSignPlus,
+    FlagSignMinus,
+    FlagAlternate,
+    FlagSignAwareZeroPad,
+}
+
 pub enum Method<'a> {
     Plural(Option<uint>, &'a [PluralArm<'a>], &'a [Piece<'a>]),
     Select(&'a [SelectArm<'a>], &'a [Piece<'a>]),
 }
 
 pub enum PluralSelector {
-    Keyword(parse::PluralKeyword),
+    Keyword(PluralKeyword),
     Literal(uint),
 }
 
+pub enum PluralKeyword {
+    Zero,
+    One,
+    Two,
+    Few,
+    Many,
+}
+
 pub struct PluralArm<'a> {
     pub selector: PluralSelector,
     pub result: &'a [Piece<'a>],
index cd069ddc1ea40df9ccecadd5d7f9008912528558..4a53a064610cb0e5b8661a283d39cb2d06fb1823 100644 (file)
@@ -76,7 +76,7 @@
 
     let path = Path::new("message.txt");
     let mut file = BufferedReader::new(File::open(&path));
-    let lines: ~[~str] = file.lines().map(|x| x.unwrap()).collect();
+    let lines: Vec<~str> = file.lines().map(|x| x.unwrap()).collect();
     ```
 
 * Make a simple TCP client connection and request
@@ -326,6 +326,8 @@ fn get_err(errno: i32) -> (IoErrorKind, &'static str) {
                 libc::WSAEADDRNOTAVAIL => (ConnectionRefused, "address not available"),
                 libc::WSAEADDRINUSE => (ConnectionRefused, "address in use"),
                 libc::ERROR_BROKEN_PIPE => (EndOfFile, "the pipe has ended"),
+                libc::ERROR_OPERATION_ABORTED =>
+                    (TimedOut, "operation timed out"),
 
                 // libuv maps this error code to EISDIR. we do too. if it is found
                 // to be incorrect, we can add in some more machinery to only
@@ -434,6 +436,17 @@ pub enum IoErrorKind {
     InvalidInput,
     /// The I/O operation's timeout expired, causing it to be canceled.
     TimedOut,
+    /// This write operation failed to write all of its data.
+    ///
+    /// Normally the write() method on a Writer guarantees that all of its data
+    /// has been written, but some operations may be terminated after only
+    /// partially writing some data. An example of this is a timed out write
+    /// which successfully wrote a known number of bytes, but bailed out after
+    /// doing so.
+    ///
+    /// The payload contained as part of this variant is the number of bytes
+    /// which are known to have been successfully written.
+    ShortWrite(uint),
 }
 
 /// A trait for objects which are byte-oriented streams. Readers are defined by
@@ -853,6 +866,11 @@ impl<'a, R: Reader> Reader for RefReader<'a, R> {
     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.inner.read(buf) }
 }
 
+impl<'a, R: Buffer> Buffer for RefReader<'a, R> {
+    fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> { self.inner.fill_buf() }
+    fn consume(&mut self, amt: uint) { self.inner.consume(amt) }
+}
+
 fn extend_sign(val: u64, nbytes: uint) -> i64 {
     let shift = (8 - nbytes) * 8;
     (val << shift) as i64 >> shift
@@ -1424,7 +1442,8 @@ pub fn standard_error(kind: IoErrorKind) -> IoError {
         PathDoesntExist => "no such file",
         MismatchedFileTypeForOperation => "mismatched file type",
         ResourceUnavailable => "resource unavailable",
-        TimedOut => "operation timed out"
+        TimedOut => "operation timed out",
+        ShortWrite(..) => "short write",
     };
     IoError {
         kind: kind,
index 4006665e886c6a3d671db65d70648e229dc180e1..879c66e0769d8eaecf80f54ed982df9d26964760 100644 (file)
@@ -24,7 +24,7 @@
 use io::net::ip::{SocketAddr, IpAddr};
 use option::{Option, Some, None};
 use rt::rtio::{IoFactory, LocalIo};
-use slice::OwnedVector;
+use vec::Vec;
 
 /// Hints to the types of sockets that are desired when looking up hosts
 pub enum SocketType {
@@ -73,7 +73,7 @@ pub struct Info {
 
 /// Easy name resolution. Given a hostname, returns the list of IP addresses for
 /// that hostname.
-pub fn get_host_addresses(host: &str) -> IoResult<~[IpAddr]> {
+pub fn get_host_addresses(host: &str) -> IoResult<Vec<IpAddr>> {
     lookup(Some(host), None, None).map(|a| a.move_iter().map(|i| i.address.ip).collect())
 }
 
@@ -90,7 +90,7 @@ pub fn get_host_addresses(host: &str) -> IoResult<~[IpAddr]> {
 /// FIXME: this is not public because the `Hint` structure is not ready for public
 ///      consumption just yet.
 fn lookup(hostname: Option<&str>, servname: Option<&str>, hint: Option<Hint>)
-          -> IoResult<~[Info]> {
+          -> IoResult<Vec<Info>> {
     LocalIo::maybe_raise(|io| io.get_host_addresses(hostname, servname, hint))
 }
 
index a2cd69da5aef33d8c5f7484af9bbc577d5cc820a..89141155ae4caef1d0094232e15d73b9f8bf0aa5 100644 (file)
@@ -32,7 +32,7 @@
 ///
 /// # Example
 ///
-/// ```rust
+/// ```no_run
 /// # #![allow(unused_must_use)]
 /// use std::io::net::tcp::TcpStream;
 /// use std::io::net::ip::{Ipv4Addr, SocketAddr};
@@ -109,6 +109,111 @@ pub fn set_keepalive(&mut self, delay_in_seconds: Option<uint>) -> IoResult<()>
             None => self.obj.letdie(),
         }
     }
+
+    /// Closes the reading half of this connection.
+    ///
+    /// This method will close the reading portion of this connection, causing
+    /// all pending and future reads to immediately return with an error.
+    ///
+    /// # Example
+    ///
+    /// ```no_run
+    /// # #![allow(unused_must_use)]
+    /// use std::io::timer;
+    /// use std::io::net::tcp::TcpStream;
+    /// use std::io::net::ip::{Ipv4Addr, SocketAddr};
+    ///
+    /// let addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 34254 };
+    /// let mut stream = TcpStream::connect(addr).unwrap();
+    /// let stream2 = stream.clone();
+    ///
+    /// spawn(proc() {
+    ///     // close this stream after one second
+    ///     timer::sleep(1000);
+    ///     let mut stream = stream2;
+    ///     stream.close_read();
+    /// });
+    ///
+    /// // wait for some data, will get canceled after one second
+    /// let mut buf = [0];
+    /// stream.read(buf);
+    /// ```
+    ///
+    /// Note that this method affects all cloned handles associated with this
+    /// stream, not just this one handle.
+    pub fn close_read(&mut self) -> IoResult<()> { self.obj.close_read() }
+
+    /// Closes the writing half of this connection.
+    ///
+    /// This method will close the writing portion of this connection, causing
+    /// all future writes to immediately return with an error.
+    ///
+    /// Note that this method affects all cloned handles associated with this
+    /// stream, not just this one handle.
+    pub fn close_write(&mut self) -> IoResult<()> { self.obj.close_write() }
+
+    /// Sets a timeout, in milliseconds, for blocking operations on this stream.
+    ///
+    /// This function will set a timeout for all blocking operations (including
+    /// reads and writes) on this stream. The timeout specified is a relative
+    /// time, in milliseconds, into the future after which point operations will
+    /// time out. This means that the timeout must be reset periodically to keep
+    /// it from expiring. Specifying a value of `None` will clear the timeout
+    /// for this stream.
+    ///
+    /// The timeout on this stream is local to this stream only. Setting a
+    /// timeout does not affect any other cloned instances of this stream, nor
+    /// does the timeout propagated to cloned handles of this stream. Setting
+    /// this timeout will override any specific read or write timeouts
+    /// previously set for this stream.
+    ///
+    /// For clarification on the semantics of interrupting a read and a write,
+    /// take a look at `set_read_timeout` and `set_write_timeout`.
+    pub fn set_timeout(&mut self, timeout_ms: Option<u64>) {
+        self.obj.set_timeout(timeout_ms)
+    }
+
+    /// Sets the timeout for read operations on this stream.
+    ///
+    /// See documentation in `set_timeout` for the semantics of this read time.
+    /// This will overwrite any previous read timeout set through either this
+    /// function or `set_timeout`.
+    ///
+    /// # Errors
+    ///
+    /// When this timeout expires, if there is no pending read operation, no
+    /// action is taken. Otherwise, the read operation will be scheduled to
+    /// promptly return. If a timeout error is returned, then no data was read
+    /// during the timeout period.
+    pub fn set_read_timeout(&mut self, timeout_ms: Option<u64>) {
+        self.obj.set_read_timeout(timeout_ms)
+    }
+
+    /// Sets the timeout for write operations on this stream.
+    ///
+    /// See documentation in `set_timeout` for the semantics of this write time.
+    /// This will overwrite any previous write timeout set through either this
+    /// function or `set_timeout`.
+    ///
+    /// # Errors
+    ///
+    /// When this timeout expires, if there is no pending write operation, no
+    /// action is taken. Otherwise, the pending write operation will be
+    /// scheduled to promptly return. The actual state of the underlying stream
+    /// is not specified.
+    ///
+    /// The write operation may return an error of type `ShortWrite` which
+    /// indicates that the object is known to have written an exact number of
+    /// bytes successfully during the timeout period, and the remaining bytes
+    /// were never written.
+    ///
+    /// If the write operation returns `TimedOut`, then it the timeout primitive
+    /// does not know how many bytes were written as part of the timeout
+    /// operation. It may be the case that bytes continue to be written in an
+    /// asynchronous fashion after the call to write returns.
+    pub fn set_write_timeout(&mut self, timeout_ms: Option<u64>) {
+        self.obj.set_write_timeout(timeout_ms)
+    }
 }
 
 impl Clone for TcpStream {
@@ -839,13 +944,18 @@ pub fn peer_name(addr: SocketAddr) {
 
         // Also make sure that even though the timeout is expired that we will
         // continue to receive any pending connections.
-        let l = TcpStream::connect(addr).unwrap();
+        let (tx, rx) = channel();
+        spawn(proc() {
+            tx.send(TcpStream::connect(addr).unwrap());
+        });
+        let l = rx.recv();
         for i in range(0, 1001) {
             match a.accept() {
                 Ok(..) => break,
                 Err(ref e) if e.kind == TimedOut => {}
                 Err(e) => fail!("error: {}", e),
             }
+            ::task::deschedule();
             if i == 1000 { fail!("should have a pending connection") }
         }
         drop(l);
@@ -853,8 +963,183 @@ pub fn peer_name(addr: SocketAddr) {
         // Unset the timeout and make sure that this always blocks.
         a.set_timeout(None);
         spawn(proc() {
-            drop(TcpStream::connect(addr));
+            drop(TcpStream::connect(addr).unwrap());
         });
         a.accept().unwrap();
     })
+
+    iotest!(fn close_readwrite_smoke() {
+        let addr = next_test_ip4();
+        let a = TcpListener::bind(addr).listen().unwrap();
+        let (_tx, rx) = channel::<()>();
+        spawn(proc() {
+            let mut a = a;
+            let _s = a.accept().unwrap();
+            let _ = rx.recv_opt();
+        });
+
+        let mut b = [0];
+        let mut s = TcpStream::connect(addr).unwrap();
+        let mut s2 = s.clone();
+
+        // closing should prevent reads/writes
+        s.close_write().unwrap();
+        assert!(s.write([0]).is_err());
+        s.close_read().unwrap();
+        assert!(s.read(b).is_err());
+
+        // closing should affect previous handles
+        assert!(s2.write([0]).is_err());
+        assert!(s2.read(b).is_err());
+
+        // closing should affect new handles
+        let mut s3 = s.clone();
+        assert!(s3.write([0]).is_err());
+        assert!(s3.read(b).is_err());
+
+        // make sure these don't die
+        let _ = s2.close_read();
+        let _ = s2.close_write();
+        let _ = s3.close_read();
+        let _ = s3.close_write();
+    })
+
+    iotest!(fn close_read_wakes_up() {
+        let addr = next_test_ip4();
+        let a = TcpListener::bind(addr).listen().unwrap();
+        let (_tx, rx) = channel::<()>();
+        spawn(proc() {
+            let mut a = a;
+            let _s = a.accept().unwrap();
+            let _ = rx.recv_opt();
+        });
+
+        let mut s = TcpStream::connect(addr).unwrap();
+        let s2 = s.clone();
+        let (tx, rx) = channel();
+        spawn(proc() {
+            let mut s2 = s2;
+            assert!(s2.read([0]).is_err());
+            tx.send(());
+        });
+        // this should wake up the child task
+        s.close_read().unwrap();
+
+        // this test will never finish if the child doesn't wake up
+        rx.recv();
+    })
+
+    iotest!(fn readwrite_timeouts() {
+        let addr = next_test_ip6();
+        let mut a = TcpListener::bind(addr).listen().unwrap();
+        let (tx, rx) = channel::<()>();
+        spawn(proc() {
+            let mut s = TcpStream::connect(addr).unwrap();
+            rx.recv();
+            assert!(s.write([0]).is_ok());
+            let _ = rx.recv_opt();
+        });
+
+        let mut s = a.accept().unwrap();
+        s.set_timeout(Some(20));
+        assert_eq!(s.read([0]).err().unwrap().kind, TimedOut);
+        assert_eq!(s.read([0]).err().unwrap().kind, TimedOut);
+
+        s.set_timeout(Some(20));
+        for i in range(0, 1001) {
+            match s.write([0, .. 128 * 1024]) {
+                Ok(()) | Err(IoError { kind: ShortWrite(..), .. }) => {},
+                Err(IoError { kind: TimedOut, .. }) => break,
+                Err(e) => fail!("{}", e),
+           }
+           if i == 1000 { fail!("should have filled up?!"); }
+        }
+        assert_eq!(s.write([0]).err().unwrap().kind, TimedOut);
+
+        tx.send(());
+        s.set_timeout(None);
+        assert_eq!(s.read([0, 0]), Ok(1));
+    })
+
+    iotest!(fn read_timeouts() {
+        let addr = next_test_ip6();
+        let mut a = TcpListener::bind(addr).listen().unwrap();
+        let (tx, rx) = channel::<()>();
+        spawn(proc() {
+            let mut s = TcpStream::connect(addr).unwrap();
+            rx.recv();
+            let mut amt = 0;
+            while amt < 100 * 128 * 1024 {
+                match s.read([0, ..128 * 1024]) {
+                    Ok(n) => { amt += n; }
+                    Err(e) => fail!("{}", e),
+                }
+            }
+            let _ = rx.recv_opt();
+        });
+
+        let mut s = a.accept().unwrap();
+        s.set_read_timeout(Some(20));
+        assert_eq!(s.read([0]).err().unwrap().kind, TimedOut);
+        assert_eq!(s.read([0]).err().unwrap().kind, TimedOut);
+
+        tx.send(());
+        for _ in range(0, 100) {
+            assert!(s.write([0, ..128 * 1024]).is_ok());
+        }
+    })
+
+    iotest!(fn write_timeouts() {
+        let addr = next_test_ip6();
+        let mut a = TcpListener::bind(addr).listen().unwrap();
+        let (tx, rx) = channel::<()>();
+        spawn(proc() {
+            let mut s = TcpStream::connect(addr).unwrap();
+            rx.recv();
+            assert!(s.write([0]).is_ok());
+            let _ = rx.recv_opt();
+        });
+
+        let mut s = a.accept().unwrap();
+        s.set_write_timeout(Some(20));
+        for i in range(0, 1001) {
+            match s.write([0, .. 128 * 1024]) {
+                Ok(()) | Err(IoError { kind: ShortWrite(..), .. }) => {},
+                Err(IoError { kind: TimedOut, .. }) => break,
+                Err(e) => fail!("{}", e),
+           }
+           if i == 1000 { fail!("should have filled up?!"); }
+        }
+        assert_eq!(s.write([0]).err().unwrap().kind, TimedOut);
+
+        tx.send(());
+        assert!(s.read([0]).is_ok());
+    })
+
+    iotest!(fn timeout_concurrent_read() {
+        let addr = next_test_ip6();
+        let mut a = TcpListener::bind(addr).listen().unwrap();
+        let (tx, rx) = channel::<()>();
+        spawn(proc() {
+            let mut s = TcpStream::connect(addr).unwrap();
+            rx.recv();
+            assert_eq!(s.write([0]), Ok(()));
+            let _ = rx.recv_opt();
+        });
+
+        let mut s = a.accept().unwrap();
+        let s2 = s.clone();
+        let (tx2, rx2) = channel();
+        spawn(proc() {
+            let mut s2 = s2;
+            assert_eq!(s2.read([0]), Ok(1));
+            tx2.send(());
+        });
+
+        s.set_read_timeout(Some(20));
+        assert_eq!(s.read([0]).err().unwrap().kind, TimedOut);
+        tx.send(());
+
+        rx2.recv();
+    })
 }
index b7636493decc72a2732e52eea32ef0700c3c66bb..45da872ca119836ae2c0b540f03fbaa0042e6296 100644 (file)
@@ -20,6 +20,7 @@
 use io::{Reader, Writer, IoResult};
 use kinds::Send;
 use owned::Box;
+use option::Option;
 use result::{Ok, Err};
 use rt::rtio::{RtioSocket, RtioUdpSocket, IoFactory, LocalIo};
 
@@ -142,6 +143,27 @@ pub fn set_broadast(&mut self, broadcast: bool) -> IoResult<()> {
             self.obj.ignore_broadcasts()
         }
     }
+
+    /// Sets the read/write timeout for this socket.
+    ///
+    /// For more information, see `TcpStream::set_timeout`
+    pub fn set_timeout(&mut self, timeout_ms: Option<u64>) {
+        self.obj.set_timeout(timeout_ms)
+    }
+
+    /// Sets the read timeout for this socket.
+    ///
+    /// For more information, see `TcpStream::set_timeout`
+    pub fn set_read_timeout(&mut self, timeout_ms: Option<u64>) {
+        self.obj.set_read_timeout(timeout_ms)
+    }
+
+    /// Sets the write timeout for this socket.
+    ///
+    /// For more information, see `TcpStream::set_timeout`
+    pub fn set_write_timeout(&mut self, timeout_ms: Option<u64>) {
+        self.obj.set_write_timeout(timeout_ms)
+    }
 }
 
 impl Clone for UdpSocket {
@@ -485,4 +507,56 @@ pub fn socket_name(addr: SocketAddr) {
         rx.recv();
         serv_rx.recv();
     })
+
+    iotest!(fn recvfrom_timeout() {
+        let addr1 = next_test_ip4();
+        let addr2 = next_test_ip4();
+        let mut a = UdpSocket::bind(addr1).unwrap();
+
+        let (tx, rx) = channel();
+        let (tx2, rx2) = channel();
+        spawn(proc() {
+            let mut a = UdpSocket::bind(addr2).unwrap();
+            assert_eq!(a.recvfrom([0]), Ok((1, addr1)));
+            assert_eq!(a.sendto([0], addr1), Ok(()));
+            rx.recv();
+            assert_eq!(a.sendto([0], addr1), Ok(()));
+
+            tx2.send(());
+        });
+
+        // Make sure that reads time out, but writes can continue
+        a.set_read_timeout(Some(20));
+        assert_eq!(a.recvfrom([0]).err().unwrap().kind, TimedOut);
+        assert_eq!(a.recvfrom([0]).err().unwrap().kind, TimedOut);
+        assert_eq!(a.sendto([0], addr2), Ok(()));
+
+        // Cloned handles should be able to block
+        let mut a2 = a.clone();
+        assert_eq!(a2.recvfrom([0]), Ok((1, addr2)));
+
+        // Clearing the timeout should allow for receiving
+        a.set_timeout(None);
+        tx.send(());
+        assert_eq!(a2.recvfrom([0]), Ok((1, addr2)));
+
+        // Make sure the child didn't die
+        rx2.recv();
+    })
+
+    iotest!(fn sendto_timeout() {
+        let addr1 = next_test_ip4();
+        let addr2 = next_test_ip4();
+        let mut a = UdpSocket::bind(addr1).unwrap();
+        let _b = UdpSocket::bind(addr2).unwrap();
+
+        a.set_write_timeout(Some(1000));
+        for _ in range(0, 100) {
+            match a.sendto([0, ..4*1024], addr2) {
+                Ok(()) | Err(IoError { kind: ShortWrite(..), .. }) => {},
+                Err(IoError { kind: TimedOut, .. }) => break,
+                Err(e) => fail!("other error: {}", e),
+            }
+        }
+    })
 }
index f6e985dc2780695352a409e305169805be96fec6..ac7a0f5cdce72a79f991d03af1a4cb5f23720fcb 100644 (file)
@@ -28,7 +28,6 @@
 
 use c_str::ToCStr;
 use clone::Clone;
-use io::pipe::PipeStream;
 use io::{Listener, Acceptor, Reader, Writer, IoResult};
 use kinds::Send;
 use owned::Box;
 
 /// A stream which communicates over a named pipe.
 pub struct UnixStream {
-    obj: PipeStream,
+    obj: Box<RtioPipe:Send>,
 }
 
 impl UnixStream {
-    fn new(obj: Box<RtioPipe:Send>) -> UnixStream {
-        UnixStream { obj: PipeStream::new(obj) }
-    }
-
     /// Connect to a pipe named by `path`. This will attempt to open a
     /// connection to the underlying socket.
     ///
@@ -62,33 +57,63 @@ fn new(obj: Box<RtioPipe:Send>) -> UnixStream {
     /// ```
     pub fn connect<P: ToCStr>(path: &P) -> IoResult<UnixStream> {
         LocalIo::maybe_raise(|io| {
-            io.unix_connect(&path.to_c_str(), None).map(UnixStream::new)
+            io.unix_connect(&path.to_c_str(), None).map(|p| UnixStream { obj: p })
         })
     }
 
-    /// Connect to a pipe named by `path`. This will attempt to open a
-    /// connection to the underlying socket.
-    ///
-    /// The returned stream will be closed when the object falls out of scope.
-    ///
-    /// # Example
+    /// Connect to a pipe named by `path`, timing out if the specified number of
+    /// milliseconds.
     ///
-    /// ```rust
-    /// # #![allow(unused_must_use)]
-    /// use std::io::net::unix::UnixStream;
-    ///
-    /// let server = Path::new("path/to/my/socket");
-    /// let mut stream = UnixStream::connect(&server);
-    /// stream.write([1, 2, 3]);
-    /// ```
+    /// This function is similar to `connect`, except that if `timeout_ms`
+    /// elapses the function will return an error of kind `TimedOut`.
     #[experimental = "the timeout argument is likely to change types"]
     pub fn connect_timeout<P: ToCStr>(path: &P,
                                       timeout_ms: u64) -> IoResult<UnixStream> {
         LocalIo::maybe_raise(|io| {
             let s = io.unix_connect(&path.to_c_str(), Some(timeout_ms));
-            s.map(UnixStream::new)
+            s.map(|p| UnixStream { obj: p })
         })
     }
+
+
+    /// Closes the reading half of this connection.
+    ///
+    /// This method will close the reading portion of this connection, causing
+    /// all pending and future reads to immediately return with an error.
+    ///
+    /// Note that this method affects all cloned handles associated with this
+    /// stream, not just this one handle.
+    pub fn close_read(&mut self) -> IoResult<()> { self.obj.close_read() }
+
+    /// Closes the writing half of this connection.
+    ///
+    /// This method will close the writing portion of this connection, causing
+    /// all pending and future writes to immediately return with an error.
+    ///
+    /// Note that this method affects all cloned handles associated with this
+    /// stream, not just this one handle.
+    pub fn close_write(&mut self) -> IoResult<()> { self.obj.close_write() }
+
+    /// Sets the read/write timeout for this socket.
+    ///
+    /// For more information, see `TcpStream::set_timeout`
+    pub fn set_timeout(&mut self, timeout_ms: Option<u64>) {
+        self.obj.set_timeout(timeout_ms)
+    }
+
+    /// Sets the read timeout for this socket.
+    ///
+    /// For more information, see `TcpStream::set_timeout`
+    pub fn set_read_timeout(&mut self, timeout_ms: Option<u64>) {
+        self.obj.set_read_timeout(timeout_ms)
+    }
+
+    /// Sets the write timeout for this socket.
+    ///
+    /// For more information, see `TcpStream::set_timeout`
+    pub fn set_write_timeout(&mut self, timeout_ms: Option<u64>) {
+        self.obj.set_write_timeout(timeout_ms)
+    }
 }
 
 impl Clone for UnixStream {
@@ -174,7 +199,7 @@ pub fn set_timeout(&mut self, timeout_ms: Option<u64>) {
 
 impl Acceptor<UnixStream> for UnixAcceptor {
     fn accept(&mut self) -> IoResult<UnixStream> {
-        self.obj.accept().map(UnixStream::new)
+        self.obj.accept().map(|s| UnixStream { obj: s })
     }
 }
 
@@ -431,13 +456,19 @@ pub fn smalltest(server: proc(UnixStream):Send, client: proc(UnixStream):Send) {
 
         // Also make sure that even though the timeout is expired that we will
         // continue to receive any pending connections.
-        let l = UnixStream::connect(&addr).unwrap();
+        let (tx, rx) = channel();
+        let addr2 = addr.clone();
+        spawn(proc() {
+            tx.send(UnixStream::connect(&addr2).unwrap());
+        });
+        let l = rx.recv();
         for i in range(0, 1001) {
             match a.accept() {
                 Ok(..) => break,
                 Err(ref e) if e.kind == TimedOut => {}
                 Err(e) => fail!("error: {}", e),
             }
+            ::task::deschedule();
             if i == 1000 { fail!("should have a pending connection") }
         }
         drop(l);
@@ -446,7 +477,7 @@ pub fn smalltest(server: proc(UnixStream):Send, client: proc(UnixStream):Send) {
         a.set_timeout(None);
         let addr2 = addr.clone();
         spawn(proc() {
-            drop(UnixStream::connect(&addr2));
+            drop(UnixStream::connect(&addr2).unwrap());
         });
         a.accept().unwrap();
     })
@@ -461,4 +492,183 @@ pub fn smalltest(server: proc(UnixStream):Send, client: proc(UnixStream):Send) {
         let _a = UnixListener::bind(&addr).unwrap().listen().unwrap();
         assert!(UnixStream::connect_timeout(&addr, 100).is_ok());
     })
+
+    iotest!(fn close_readwrite_smoke() {
+        let addr = next_test_unix();
+        let a = UnixListener::bind(&addr).listen().unwrap();
+        let (_tx, rx) = channel::<()>();
+        spawn(proc() {
+            let mut a = a;
+            let _s = a.accept().unwrap();
+            let _ = rx.recv_opt();
+        });
+
+        let mut b = [0];
+        let mut s = UnixStream::connect(&addr).unwrap();
+        let mut s2 = s.clone();
+
+        // closing should prevent reads/writes
+        s.close_write().unwrap();
+        assert!(s.write([0]).is_err());
+        s.close_read().unwrap();
+        assert!(s.read(b).is_err());
+
+        // closing should affect previous handles
+        assert!(s2.write([0]).is_err());
+        assert!(s2.read(b).is_err());
+
+        // closing should affect new handles
+        let mut s3 = s.clone();
+        assert!(s3.write([0]).is_err());
+        assert!(s3.read(b).is_err());
+
+        // make sure these don't die
+        let _ = s2.close_read();
+        let _ = s2.close_write();
+        let _ = s3.close_read();
+        let _ = s3.close_write();
+    })
+
+    iotest!(fn close_read_wakes_up() {
+        let addr = next_test_unix();
+        let a = UnixListener::bind(&addr).listen().unwrap();
+        let (_tx, rx) = channel::<()>();
+        spawn(proc() {
+            let mut a = a;
+            let _s = a.accept().unwrap();
+            let _ = rx.recv_opt();
+        });
+
+        let mut s = UnixStream::connect(&addr).unwrap();
+        let s2 = s.clone();
+        let (tx, rx) = channel();
+        spawn(proc() {
+            let mut s2 = s2;
+            assert!(s2.read([0]).is_err());
+            tx.send(());
+        });
+        // this should wake up the child task
+        s.close_read().unwrap();
+
+        // this test will never finish if the child doesn't wake up
+        rx.recv();
+    })
+
+    iotest!(fn readwrite_timeouts() {
+        let addr = next_test_unix();
+        let mut a = UnixListener::bind(&addr).listen().unwrap();
+        let (tx, rx) = channel::<()>();
+        spawn(proc() {
+            let mut s = UnixStream::connect(&addr).unwrap();
+            rx.recv();
+            assert!(s.write([0]).is_ok());
+            let _ = rx.recv_opt();
+        });
+
+        let mut s = a.accept().unwrap();
+        s.set_timeout(Some(20));
+        assert_eq!(s.read([0]).err().unwrap().kind, TimedOut);
+        assert_eq!(s.read([0]).err().unwrap().kind, TimedOut);
+
+        s.set_timeout(Some(20));
+        for i in range(0, 1001) {
+            match s.write([0, .. 128 * 1024]) {
+                Ok(()) | Err(IoError { kind: ShortWrite(..), .. }) => {},
+                Err(IoError { kind: TimedOut, .. }) => break,
+                Err(e) => fail!("{}", e),
+           }
+           if i == 1000 { fail!("should have filled up?!"); }
+        }
+
+        // I'm not sure as to why, but apparently the write on windows always
+        // succeeds after the previous timeout. Who knows?
+        if !cfg!(windows) {
+            assert_eq!(s.write([0]).err().unwrap().kind, TimedOut);
+        }
+
+        tx.send(());
+        s.set_timeout(None);
+        assert_eq!(s.read([0, 0]), Ok(1));
+    })
+
+    iotest!(fn read_timeouts() {
+        let addr = next_test_unix();
+        let mut a = UnixListener::bind(&addr).listen().unwrap();
+        let (tx, rx) = channel::<()>();
+        spawn(proc() {
+            let mut s = UnixStream::connect(&addr).unwrap();
+            rx.recv();
+            let mut amt = 0;
+            while amt < 100 * 128 * 1024 {
+                match s.read([0, ..128 * 1024]) {
+                    Ok(n) => { amt += n; }
+                    Err(e) => fail!("{}", e),
+                }
+            }
+            let _ = rx.recv_opt();
+        });
+
+        let mut s = a.accept().unwrap();
+        s.set_read_timeout(Some(20));
+        assert_eq!(s.read([0]).err().unwrap().kind, TimedOut);
+        assert_eq!(s.read([0]).err().unwrap().kind, TimedOut);
+
+        tx.send(());
+        for _ in range(0, 100) {
+            assert!(s.write([0, ..128 * 1024]).is_ok());
+        }
+    })
+
+    iotest!(fn write_timeouts() {
+        let addr = next_test_unix();
+        let mut a = UnixListener::bind(&addr).listen().unwrap();
+        let (tx, rx) = channel::<()>();
+        spawn(proc() {
+            let mut s = UnixStream::connect(&addr).unwrap();
+            rx.recv();
+            assert!(s.write([0]).is_ok());
+            let _ = rx.recv_opt();
+        });
+
+        let mut s = a.accept().unwrap();
+        s.set_write_timeout(Some(20));
+        for i in range(0, 1001) {
+            match s.write([0, .. 128 * 1024]) {
+                Ok(()) | Err(IoError { kind: ShortWrite(..), .. }) => {},
+                Err(IoError { kind: TimedOut, .. }) => break,
+                Err(e) => fail!("{}", e),
+           }
+           if i == 1000 { fail!("should have filled up?!"); }
+        }
+
+        tx.send(());
+        assert!(s.read([0]).is_ok());
+    })
+
+    iotest!(fn timeout_concurrent_read() {
+        let addr = next_test_unix();
+        let mut a = UnixListener::bind(&addr).listen().unwrap();
+        let (tx, rx) = channel::<()>();
+        spawn(proc() {
+            let mut s = UnixStream::connect(&addr).unwrap();
+            rx.recv();
+            assert!(s.write([0]).is_ok());
+            let _ = rx.recv_opt();
+        });
+
+        let mut s = a.accept().unwrap();
+        let s2 = s.clone();
+        let (tx2, rx2) = channel();
+        spawn(proc() {
+            let mut s2 = s2;
+            assert!(s2.read([0]).is_ok());
+            tx2.send(());
+        });
+
+        s.set_read_timeout(Some(20));
+        assert_eq!(s.read([0]).err().unwrap().kind, TimedOut);
+        tx.send(());
+
+        rx2.recv();
+    })
 }
index 74f6944f102eab95ae3bee120607eaedf00ef07c..3babef6126e8fcc84e3546677803c88b8d1b2486 100644 (file)
@@ -69,7 +69,7 @@ pub struct Process {
 
     /// Extra I/O handles as configured by the original `ProcessConfig` when
     /// this process was created. This is by default empty.
-    pub extra_io: ~[Option<io::PipeStream>],
+    pub extra_io: Vec<Option<io::PipeStream>>,
 }
 
 /// This configuration describes how a new process should be spawned. A blank
@@ -418,7 +418,7 @@ fn drop(&mut self) {
         drop(self.stdin.take());
         drop(self.stdout.take());
         drop(self.stderr.take());
-        drop(mem::replace(&mut self.extra_io, box []));
+        drop(mem::replace(&mut self.extra_io, Vec::new()));
 
         self.wait();
     }
index b2e6b27caabfe1fe441d605f3e9bb1a66ae05c77..05d5f19eeffad832e8b2af75a667ac31d6f256ee 100644 (file)
@@ -55,6 +55,24 @@ fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
     }
 }
 
+impl<R: Buffer> Buffer for LimitReader<R> {
+    fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
+        let amt = try!(self.inner.fill_buf());
+        let buf = amt.slice_to(cmp::min(amt.len(), self.limit));
+        if buf.len() == 0 {
+            Err(io::standard_error(io::EndOfFile))
+        } else {
+            Ok(buf)
+        }
+    }
+
+    fn consume(&mut self, amt: uint) {
+        self.limit -= amt;
+        self.inner.consume(amt);
+    }
+
+}
+
 /// A `Writer` which ignores bytes written to it, like /dev/null.
 pub struct NullWriter;
 
@@ -74,6 +92,14 @@ fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
     }
 }
 
+impl Buffer for ZeroReader {
+    fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
+        static DATA: [u8, ..64] = [0, ..64];
+        Ok(DATA.as_slice())
+    }
+    fn consume(&mut self, _amt: uint) {}
+}
+
 /// A `Reader` which is always at EOF, like /dev/null.
 pub struct NullReader;
 
@@ -84,6 +110,13 @@ fn read(&mut self, _buf: &mut [u8]) -> io::IoResult<uint> {
     }
 }
 
+impl Buffer for NullReader {
+    fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
+        Err(io::standard_error(io::EndOfFile))
+    }
+    fn consume(&mut self, _amt: uint) {}
+}
+
 /// A `Writer` which multiplexes writes to a set of `Writers`.
 pub struct MultiWriter {
     writers: Vec<Box<Writer>>
@@ -198,8 +231,8 @@ pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) -> io::IoResult<()> {
 
 #[cfg(test)]
 mod test {
+    use io::{MemReader, MemWriter, BufReader};
     use io;
-    use io::{MemReader, MemWriter};
     use owned::Box;
     use super::*;
     use prelude::*;
@@ -309,4 +342,28 @@ fn test_copy() {
         copy(&mut r, &mut w).unwrap();
         assert_eq!(vec!(0, 1, 2, 3, 4), w.unwrap());
     }
+
+    #[test]
+    fn limit_reader_buffer() {
+        let data = "0123456789\n0123456789\n";
+        let mut r = BufReader::new(data.as_bytes());
+        {
+            let mut r = LimitReader::new(r.by_ref(), 3);
+            assert_eq!(r.read_line(), Ok("012".to_str()));
+            assert_eq!(r.limit(), 0);
+            assert_eq!(r.read_line().err().unwrap().kind, io::EndOfFile);
+        }
+        {
+            let mut r = LimitReader::new(r.by_ref(), 9);
+            assert_eq!(r.read_line(), Ok("3456789\n".to_str()));
+            assert_eq!(r.limit(), 1);
+            assert_eq!(r.read_line(), Ok("0".to_str()));
+        }
+        {
+            let mut r = LimitReader::new(r.by_ref(), 100);
+            assert_eq!(r.read_char(), Ok('1'));
+            assert_eq!(r.limit(), 99);
+            assert_eq!(r.read_line(), Ok("23456789\n".to_str()));
+        }
+    }
 }
index ce64bb84ca07f16cdec2aad62177f3dddc64ac9b..dae28777867793ef0e6566f8d9e0a601ce60282b 100644 (file)
@@ -279,4 +279,7 @@ mod std {
     pub use ty;
     pub use unstable;
     pub use vec;
+
+    // The test runner requires std::slice::Vector, so re-export std::slice just for it.
+    #[cfg(test)] pub use slice;
 }
index da738a387b2cdbec8c416c96dad7c57468d1ce93..5d18ca4141b1fed73faddf93295d63c5e4ef446a 100644 (file)
 modify/read the slot specified by the key.
 
 ```rust
-use std::local_data;
-
 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.map(|x| *x), Some(3)));
+key_int.replace(Some(3));
+assert_eq!(*key_int.get().unwrap(), 3);
 
-local_data::set(key_vector, ~[4]);
-local_data::get(key_vector, |opt| assert_eq!(*opt.unwrap(), ~[4]));
+key_vector.replace(Some(~[4]));
+assert_eq!(*key_vector.get().unwrap(), ~[4]);
 ```
 
 */
 use cast;
 use iter::{Iterator};
 use kinds::Send;
+use kinds::marker;
 use mem::replace;
+use ops::{Drop, Deref};
 use option::{None, Option, Some};
 use owned::Box;
+use raw;
 use rt::task::{Task, LocalStorage};
 use slice::{ImmutableVector, MutableVector};
 use vec::Vec;
@@ -66,7 +67,7 @@
 #[allow(missing_doc)]
 pub enum KeyValue<T> { Key }
 
-#[allow(missing_doc)]
+#[doc(hidden)]
 trait LocalData {}
 impl<T: 'static> LocalData for T {}
 
@@ -91,7 +92,7 @@ impl<T: 'static> LocalData for T {}
 // n.b. If TLS is used heavily in future, this could be made more efficient with
 //      a proper map.
 #[doc(hidden)]
-pub type Map = Vec<Option<(*u8, TLSValue, LoanState)>>;
+pub type Map = Vec<Option<(*u8, TLSValue, uint)>>;
 type TLSValue = Box<LocalData:Send>;
 
 // Gets the map from the runtime. Lazily initialises if not done so already.
@@ -111,243 +112,156 @@ unsafe fn get_local_map() -> &mut Map {
             *slot = Some(vec!());
             match *slot {
                 Some(ref mut map_ptr) => { return map_ptr }
-                None => abort()
+                None => unreachable!(),
             }
         }
     }
 }
 
-#[deriving(Eq)]
-enum LoanState {
-    NoLoan, ImmLoan, MutLoan
-}
-
-impl LoanState {
-    fn describe(&self) -> &'static str {
-        match *self {
-            NoLoan => "no loan",
-            ImmLoan => "immutable",
-            MutLoan => "mutable"
-        }
-    }
-}
-
 fn key_to_key_value<T: 'static>(key: Key<T>) -> *u8 {
-    unsafe { cast::transmute(key) }
+    key as *KeyValue<T> as *u8
 }
 
-/// Removes a task-local value from task-local storage. This will return
-/// Some(value) if the key was present in TLS, otherwise it will return None.
+/// An RAII immutable reference to a task-local value.
 ///
-/// A runtime assertion will be triggered it removal of TLS value is attempted
-/// while the value is still loaned out via `get` or `get_mut`.
-pub fn pop<T: 'static>(key: Key<T>) -> Option<T> {
-    let map = unsafe { get_local_map() };
-    let key_value = key_to_key_value(key);
-
-    for entry in map.mut_iter() {
-        match *entry {
-            Some((k, _, loan)) if k == key_value => {
-                if loan != NoLoan {
-                    fail!("TLS value cannot be removed because it is currently \
-                          borrowed as {}", loan.describe());
-                }
-                // Move the data out of the `entry` slot via prelude::replace.
-                // This is guaranteed to succeed because we already matched
-                // on `Some` above.
-                let data = match replace(entry, None) {
-                    Some((_, data, _)) => data,
-                    None => abort()
-                };
-
-                // Move `data` into transmute to get out the memory that it
-                // owns, we must free it manually later.
-                let (_vtable, alloc): (uint, Box<T>) = unsafe {
-                    cast::transmute(data)
-                };
-
-                // Now that we own `alloc`, we can just move out of it as we
-                // would with any other data.
-                return Some(*alloc);
-            }
-            _ => {}
-        }
-    }
-    return None;
+/// The task-local data can be accessed through this value, and when this
+/// structure is dropped it will return the borrow on the data.
+pub struct Ref<T> {
+    ptr: &'static T,
+    key: Key<T>,
+    index: uint,
+    nosend: marker::NoSend,
 }
 
-/// Retrieves a value from TLS. The closure provided is yielded `Some` of a
-/// reference to the value located in TLS if one exists, or `None` if the key
-/// provided is not present in TLS currently.
-///
-/// It is considered a runtime error to attempt to get a value which is already
-/// on loan via the `get_mut` method provided.
-pub fn get<T: 'static, U>(key: Key<T>, f: |Option<&T>| -> U) -> U {
-    get_with(key, ImmLoan, f)
-}
-
-/// Retrieves a mutable value from TLS. The closure provided is yielded `Some`
-/// of a reference to the mutable value located in TLS if one exists, or `None`
-/// if the key provided is not present in TLS currently.
-///
-/// It is considered a runtime error to attempt to get a value which is already
-/// on loan via this or the `get` methods.
-pub fn get_mut<T: 'static, U>(key: Key<T>, f: |Option<&mut T>| -> U) -> U {
-    get_with(key, MutLoan, |x| {
-        match x {
-            None => f(None),
-            // We're violating a lot of compiler guarantees with this
-            // invocation of `transmute`, but we're doing runtime checks to
-            // ensure that it's always valid (only one at a time).
-            //
-            // there is no need to be upset!
-            Some(x) => { f(Some(unsafe { cast::transmute::<&_, &mut _>(x) })) }
-        }
-    })
-}
+impl<T: 'static> KeyValue<T> {
+    /// Replaces a value in task local storage.
+    ///
+    /// If this key is already present in TLS, then the previous value is
+    /// replaced with the provided data, and then returned.
+    ///
+    /// # Failure
+    ///
+    /// This function will fail if this key is present in TLS and currently on
+    /// loan with the `get` method.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// local_data_key!(foo: int)
+    ///
+    /// assert_eq!(foo.replace(Some(10)), None);
+    /// assert_eq!(foo.replace(Some(4)), Some(10));
+    /// assert_eq!(foo.replace(None), Some(4));
+    /// ```
+    pub fn replace(&'static self, data: Option<T>) -> Option<T> {
+        let map = unsafe { get_local_map() };
+        let keyval = key_to_key_value(self);
+
+        // When the task-local map is destroyed, all the data needs to be
+        // cleaned up. For this reason we can't do some clever tricks to store
+        // '~T' as a '*c_void' or something like that. To solve the problem, we
+        // cast everything to a trait (LocalData) which is then stored inside
+        // the map.  Upon destruction of the map, all the objects will be
+        // destroyed and the traits have enough information about them to
+        // destroy themselves.
+        //
+        // Additionally, the type of the local data map must ascribe to Send, so
+        // we do the transmute here to add the Send bound back on. This doesn't
+        // actually matter because TLS will always own the data (until its moved
+        // out) and we're not actually sending it to other schedulers or
+        // anything.
+        let newval = data.map(|d| {
+            let d = box d as Box<LocalData>;
+            let d: Box<LocalData:Send> = unsafe { cast::transmute(d) };
+            (keyval, d, 0)
+        });
 
-fn get_with<T:'static,
-            U>(
-            key: Key<T>,
-            state: LoanState,
-            f: |Option<&T>| -> U)
-            -> U {
-    // This function must be extremely careful. Because TLS can store owned
-    // values, and we must have some form of `get` function other than `pop`,
-    // this function has to give a `&` reference back to the caller.
-    //
-    // One option is to return the reference, but this cannot be sound because
-    // the actual lifetime of the object is not known. The slot in TLS could not
-    // be modified until the object goes out of scope, but the TLS code cannot
-    // know when this happens.
-    //
-    // For this reason, the reference is yielded to a specified closure. This
-    // way the TLS code knows exactly what the lifetime of the yielded pointer
-    // is, allowing callers to acquire references to owned data. This is also
-    // sound so long as measures are taken to ensure that while a TLS slot is
-    // loaned out to a caller, it's not modified recursively.
-    let map = unsafe { get_local_map() };
-    let key_value = key_to_key_value(key);
-
-    let pos = map.iter().position(|entry| {
-        match *entry {
-            Some((k, _, _)) if k == key_value => true, _ => false
-        }
-    });
-    match pos {
-        None => { return f(None); }
-        Some(i) => {
-            let ret;
-            let mut return_loan = false;
-            match *map.get_mut(i) {
-                Some((_, ref data, ref mut loan)) => {
-                    match (state, *loan) {
-                        (_, NoLoan) => {
-                            *loan = state;
-                            return_loan = true;
-                        }
-                        (ImmLoan, ImmLoan) => {}
-                        (want, cur) => {
-                            fail!("TLS slot cannot be borrowed as {} because \
-                                    it is already borrowed as {}",
-                                  want.describe(), cur.describe());
-                        }
-                    }
-                    // data was created with `box T as Box<LocalData>`, so we
-                    // extract pointer part of the trait, (as Box<T>), and
-                    // then use compiler coercions to achieve a '&' pointer.
-                    unsafe {
-                        match *cast::transmute::<&TLSValue,
-                                                 &(uint, Box<T>)>(data){
-                            (_vtable, ref alloc) => {
-                                let value: &T = *alloc;
-                                ret = f(Some(value));
-                            }
-                        }
-                    }
-                }
-                _ => abort()
+        let pos = match self.find(map) {
+            Some((i, _, &0)) => Some(i),
+            Some((_, _, _)) => fail!("TLS value cannot be replaced because it \
+                                      is already borrowed"),
+            None => map.iter().position(|entry| entry.is_none()),
+        };
+
+        match pos {
+            Some(i) => {
+                replace(map.get_mut(i), newval).map(|(_, data, _)| {
+                    // Move `data` into transmute to get out the memory that it
+                    // owns, we must free it manually later.
+                    let t: raw::TraitObject = unsafe { cast::transmute(data) };
+                    let alloc: Box<T> = unsafe { cast::transmute(t.data) };
+
+                    // Now that we own `alloc`, we can just move out of it as we
+                    // would with any other data.
+                    *alloc
+                })
             }
-
-            // n.b. 'data' and 'loans' are both invalid pointers at the point
-            // 'f' returned because `f` could have appended more TLS items which
-            // in turn relocated the vector. Hence we do another lookup here to
-            // fixup the loans.
-            if return_loan {
-                match *map.get_mut(i) {
-                    Some((_, _, ref mut loan)) => { *loan = NoLoan; }
-                    None => abort()
-                }
+            None => {
+                map.push(newval);
+                None
             }
-            return ret;
         }
     }
-}
 
-fn abort() -> ! {
-    use intrinsics;
-    unsafe { intrinsics::abort() }
-}
+    /// Borrows a value from TLS.
+    ///
+    /// If `None` is returned, then this key is not present in TLS. If `Some` is
+    /// returned, then the returned data is a smart pointer representing a new
+    /// loan on this TLS key. While on loan, this key cannot be altered via the
+    /// `replace` method.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// local_data_key!(key: int)
+    ///
+    /// assert!(key.get().is_none());
+    ///
+    /// key.replace(Some(3));
+    /// assert_eq!(*key.get().unwrap(), 3);
+    /// ```
+    pub fn get(&'static self) -> Option<Ref<T>> {
+        let map = unsafe { get_local_map() };
+
+        self.find(map).map(|(pos, data, loan)| {
+            *loan += 1;
+
+            // data was created with `~T as ~LocalData`, so we extract
+            // pointer part of the trait, (as ~T), and then use
+            // compiler coercions to achieve a '&' pointer.
+            let ptr = unsafe {
+                let data = data as *Box<LocalData:Send> as *raw::TraitObject;
+                &mut *((*data).data as *mut T)
+            };
+            Ref { ptr: ptr, index: pos, nosend: marker::NoSend, key: self }
+        })
+    }
 
-/// Inserts a value into task local storage. If the key is already present in
-/// TLS, then the previous value is removed and replaced with the provided data.
-///
-/// It is considered a runtime error to attempt to set a key which is currently
-/// on loan via the `get` or `get_mut` methods.
-pub fn set<T: 'static>(key: Key<T>, data: T) {
-    let map = unsafe { get_local_map() };
-    let keyval = key_to_key_value(key);
-
-    // When the task-local map is destroyed, all the data needs to be cleaned
-    // up. For this reason we can't do some clever tricks to store 'Box<T>' as
-    // a '*c_void' or something like that. To solve the problem, we cast
-    // everything to a trait (LocalData) which is then stored inside the map.
-    // Upon destruction of the map, all the objects will be destroyed and the
-    // traits have enough information about them to destroy themselves.
-    let data = box data as Box<LocalData:>;
-
-    fn insertion_position(map: &mut Map,
-                          key: *u8) -> Option<uint> {
-        // First see if the map contains this key already
-        let curspot = map.iter().position(|entry| {
+    fn find<'a>(&'static self,
+                map: &'a mut Map) -> Option<(uint, &'a TLSValue, &'a mut uint)>{
+        let key_value = key_to_key_value(self);
+        map.mut_iter().enumerate().filter_map(|(i, entry)| {
             match *entry {
-                Some((ekey, _, loan)) if key == ekey => {
-                    if loan != NoLoan {
-                        fail!("TLS value cannot be overwritten because it is
-                               already borrowed as {}", loan.describe())
-                    }
-                    true
+                Some((k, ref data, ref mut loan)) if k == key_value => {
+                    Some((i, data, loan))
                 }
-                _ => false,
+                _ => None
             }
-        });
-        // If it doesn't contain the key, just find a slot that's None
-        match curspot {
-            Some(i) => Some(i),
-            None => map.iter().position(|entry| entry.is_none())
-        }
+        }).next()
     }
+}
 
-    // The type of the local data map must ascribe to Send, so we do the
-    // transmute here to add the Send bound back on. This doesn't actually
-    // matter because TLS will always own the data (until its moved out) and
-    // we're not actually sending it to other schedulers or anything.
-    let data: Box<LocalData:Send> = unsafe { cast::transmute(data) };
-    match insertion_position(map, keyval) {
-        Some(i) => { *map.get_mut(i) = Some((keyval, data, NoLoan)); }
-        None => { map.push(Some((keyval, data, NoLoan))); }
-    }
+impl<T: 'static> Deref<T> for Ref<T> {
+    fn deref<'a>(&'a self) -> &'a T { self.ptr }
 }
 
-/// Modifies a task-local value by temporarily removing it from task-local
-/// storage and then re-inserting if `Some` is returned from the closure.
-///
-/// This function will have the same runtime errors as generated from `pop` and
-/// `set` (the key must not currently be on loan
-pub fn modify<T: 'static>(key: Key<T>, f: |Option<T>| -> Option<T>) {
-    match f(pop(key)) {
-        Some(next) => { set(key, next); }
-        None => {}
+#[unsafe_destructor]
+impl<T: 'static> Drop for Ref<T> {
+    fn drop(&mut self) {
+        let map = unsafe { get_local_map() };
+
+        let (_, _, ref mut loan) = *map.get_mut(self.index).get_mut_ref();
+        *loan -= 1;
     }
 }
 
@@ -361,55 +275,36 @@ mod tests {
     #[test]
     fn test_tls_multitask() {
         static my_key: Key<~str> = &Key;
-        set(my_key, "parent data".to_owned());
+        my_key.replace(Some("parent data".to_owned()));
         task::spawn(proc() {
             // TLS shouldn't carry over.
-            assert!(get(my_key, |k| k.map(|k| (*k).clone())).is_none());
-            set(my_key, "child data".to_owned());
-            assert!(get(my_key, |k| k.map(|k| (*k).clone())).unwrap() ==
-                    "child data".to_owned());
+            assert!(my_key.get().is_none());
+            my_key.replace(Some("child data".to_owned()));
+            assert!(my_key.get().get_ref().as_slice() == "child data");
             // should be cleaned up for us
         });
+
         // Must work multiple times
-        assert!(get(my_key, |k| k.map(|k| (*k).clone())).unwrap() == "parent data".to_owned());
-        assert!(get(my_key, |k| k.map(|k| (*k).clone())).unwrap() == "parent data".to_owned());
-        assert!(get(my_key, |k| k.map(|k| (*k).clone())).unwrap() == "parent data".to_owned());
+        assert!(my_key.get().unwrap().as_slice() == "parent data");
+        assert!(my_key.get().unwrap().as_slice() == "parent data");
+        assert!(my_key.get().unwrap().as_slice() == "parent data");
     }
 
     #[test]
     fn test_tls_overwrite() {
         static my_key: Key<~str> = &Key;
-        set(my_key, "first data".to_owned());
-        set(my_key, "next data".to_owned()); // Shouldn't leak.
-        assert!(get(my_key, |k| k.map(|k| (*k).clone())).unwrap() == "next data".to_owned());
+        my_key.replace(Some("first data".to_owned()));
+        my_key.replace(Some("next data".to_owned())); // Shouldn't leak.
+        assert!(my_key.get().unwrap().as_slice() == "next data");
     }
 
     #[test]
     fn test_tls_pop() {
         static my_key: Key<~str> = &Key;
-        set(my_key, "weasel".to_owned());
-        assert!(pop(my_key).unwrap() == "weasel".to_owned());
+        my_key.replace(Some("weasel".to_owned()));
+        assert!(my_key.replace(None).unwrap() == "weasel".to_owned());
         // Pop must remove the data from the map.
-        assert!(pop(my_key).is_none());
-    }
-
-    #[test]
-    fn test_tls_modify() {
-        static my_key: Key<~str> = &Key;
-        modify(my_key, |data| {
-            match data {
-                Some(ref val) => fail!("unwelcome value: {}", *val),
-                None           => Some("first data".to_owned())
-            }
-        });
-        modify(my_key, |data| {
-            match data.as_ref().map(|s| s.as_slice()) {
-                Some("first data") => Some("next data".to_owned()),
-                Some(ref val)       => fail!("wrong value: {}", *val),
-                None                 => fail!("missing value")
-            }
-        });
-        assert!(pop(my_key).unwrap() == "next data".to_owned());
+        assert!(my_key.replace(None).is_none());
     }
 
     #[test]
@@ -422,7 +317,7 @@ fn test_tls_crust_automorestack_memorial_bug() {
         // a stack smaller than 1 MB.
         static my_key: Key<~str> = &Key;
         task::spawn(proc() {
-            set(my_key, "hax".to_owned());
+            my_key.replace(Some("hax".to_owned()));
         });
     }
 
@@ -432,28 +327,27 @@ fn test_tls_multiple_types() {
         static box_key: Key<@()> = &Key;
         static int_key: Key<int> = &Key;
         task::spawn(proc() {
-            set(str_key, "string data".to_owned());
-            set(box_key, @());
-            set(int_key, 42);
+            str_key.replace(Some("string data".to_owned()));
+            box_key.replace(Some(@()));
+            int_key.replace(Some(42));
         });
     }
 
     #[test]
-    #[allow(dead_code)]
     fn test_tls_overwrite_multiple_types() {
         static str_key: Key<~str> = &Key;
         static box_key: Key<@()> = &Key;
         static int_key: Key<int> = &Key;
         task::spawn(proc() {
-            set(str_key, "string data".to_owned());
-            set(str_key, "string data 2".to_owned());
-            set(box_key, @());
-            set(box_key, @());
-            set(int_key, 42);
+            str_key.replace(Some("string data".to_owned()));
+            str_key.replace(Some("string data 2".to_owned()));
+            box_key.replace(Some(@()));
+            box_key.replace(Some(@()));
+            int_key.replace(Some(42));
             // This could cause a segfault if overwriting-destruction is done
             // with the crazy polymorphic transmute rather than the provided
             // finaliser.
-            set(int_key, 31337);
+            int_key.replace(Some(31337));
         });
     }
 
@@ -463,17 +357,16 @@ fn test_tls_cleanup_on_failure() {
         static str_key: Key<~str> = &Key;
         static box_key: Key<@()> = &Key;
         static int_key: Key<int> = &Key;
-        set(str_key, "parent data".to_owned());
-        set(box_key, @());
+        str_key.replace(Some("parent data".to_owned()));
+        box_key.replace(Some(@()));
         task::spawn(proc() {
-            // spawn_linked
-            set(str_key, "string data".to_owned());
-            set(box_key, @());
-            set(int_key, 42);
+            str_key.replace(Some("string data".to_owned()));
+            box_key.replace(Some(@()));
+            int_key.replace(Some(42));
             fail!();
         });
         // Not quite nondeterministic.
-        set(int_key, 31337);
+        int_key.replace(Some(31337));
         fail!();
     }
 
@@ -481,42 +374,24 @@ fn test_tls_cleanup_on_failure() {
     fn test_static_pointer() {
         static key: Key<&'static int> = &Key;
         static VALUE: int = 0;
-        let v: &'static int = &VALUE;
-        set(key, v);
+        key.replace(Some(&VALUE));
     }
 
     #[test]
     fn test_owned() {
         static key: Key<Box<int>> = &Key;
-        set(key, box 1);
-
-        get(key, |v| {
-            get(key, |v| {
-                get(key, |v| {
-                    assert_eq!(**v.unwrap(), 1);
-                });
-                assert_eq!(**v.unwrap(), 1);
-            });
-            assert_eq!(**v.unwrap(), 1);
-        });
-        set(key, box 2);
-        get(key, |v| {
-            assert_eq!(**v.unwrap(), 2);
-        })
-    }
-
-    #[test]
-    fn test_get_mut() {
-        static key: Key<int> = &Key;
-        set(key, 1);
-
-        get_mut(key, |v| {
-            *v.unwrap() = 2;
-        });
-
-        get(key, |v| {
-            assert_eq!(*v.unwrap(), 2);
-        })
+        key.replace(Some(box 1));
+
+        {
+            let k1 = key.get().unwrap();
+            let k2 = key.get().unwrap();
+            let k3 = key.get().unwrap();
+            assert_eq!(**k1, 1);
+            assert_eq!(**k2, 1);
+            assert_eq!(**k3, 1);
+        }
+        key.replace(Some(box 2));
+        assert_eq!(**key.get().unwrap(), 2);
     }
 
     #[test]
@@ -526,56 +401,26 @@ fn test_same_key_type() {
         static key3: Key<int> = &Key;
         static key4: Key<int> = &Key;
         static key5: Key<int> = &Key;
-        set(key1, 1);
-        set(key2, 2);
-        set(key3, 3);
-        set(key4, 4);
-        set(key5, 5);
-
-        get(key1, |x| assert_eq!(*x.unwrap(), 1));
-        get(key2, |x| assert_eq!(*x.unwrap(), 2));
-        get(key3, |x| assert_eq!(*x.unwrap(), 3));
-        get(key4, |x| assert_eq!(*x.unwrap(), 4));
-        get(key5, |x| assert_eq!(*x.unwrap(), 5));
+        key1.replace(Some(1));
+        key2.replace(Some(2));
+        key3.replace(Some(3));
+        key4.replace(Some(4));
+        key5.replace(Some(5));
+
+        assert_eq!(*key1.get().unwrap(), 1);
+        assert_eq!(*key2.get().unwrap(), 2);
+        assert_eq!(*key3.get().unwrap(), 3);
+        assert_eq!(*key4.get().unwrap(), 4);
+        assert_eq!(*key5.get().unwrap(), 5);
     }
 
     #[test]
     #[should_fail]
     fn test_nested_get_set1() {
         static key: Key<int> = &Key;
-        set(key, 4);
-        get(key, |_| {
-            set(key, 4);
-        })
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_nested_get_mut2() {
-        static key: Key<int> = &Key;
-        set(key, 4);
-        get(key, |_| {
-            get_mut(key, |_| {})
-        })
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_nested_get_mut3() {
-        static key: Key<int> = &Key;
-        set(key, 4);
-        get_mut(key, |_| {
-            get(key, |_| {})
-        })
-    }
+        key.replace(Some(4));
 
-    #[test]
-    #[should_fail]
-    fn test_nested_get_mut4() {
-        static key: Key<int> = &Key;
-        set(key, 4);
-        get_mut(key, |_| {
-            get_mut(key, |_| {})
-        })
+        let _k = key.get();
+        key.replace(Some(4));
     }
 }
index 4ae3d453f03608791935dcf0c4cbf3575af8e5f1..1efe56756eddebced081f29b246cc564c47d2a3c 100644 (file)
@@ -289,12 +289,10 @@ macro_rules! println(
 /// # Example
 ///
 /// ```
-/// use std::local_data;
-///
 /// local_data_key!(my_integer: int)
 ///
-/// local_data::set(my_integer, 2);
-/// local_data::get(my_integer, |val| println!("{}", val.map(|i| *i)));
+/// my_integer.replace(Some(2));
+/// println!("{}", my_integer.get().map(|a| *a));
 /// ```
 #[macro_export]
 macro_rules! local_data_key(
index 4bd2ba07634cacd291b895ddf069b8fe25b6ff45..d8f1c108b742d48dd8040b50dba5b578319d7450 100644 (file)
 //! Operations and constants for signed 16-bits integers (`i16` type)
 
 use from_str::FromStr;
-use iter::Iterator;
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::{ImmutableVector, OwnedVector};
+use slice::ImmutableVector;
 use str;
 
 pub use core::i16::{BITS, BYTES, MIN, MAX};
index 3c3acfae3c0f8757ddd80cfe68a237b06c2a976a..9cc8981fc13f422c10d231fd413362088f54723d 100644 (file)
 //! Operations and constants for signed 32-bits integers (`i32` type)
 
 use from_str::FromStr;
-use iter::Iterator;
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::{ImmutableVector, OwnedVector};
+use slice::ImmutableVector;
 use str;
 
 pub use core::i32::{BITS, BYTES, MIN, MAX};
index ad0fe1c08ef04cd621f3873b4b83726bc6cf5a6d..4f7fe32cc7088c9b7d3f171f258840d9e4bad851 100644 (file)
 //! Operations and constants for signed 64-bits integers (`i64` type)
 
 use from_str::FromStr;
-use iter::Iterator;
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::{ImmutableVector, OwnedVector};
+use slice::ImmutableVector;
 use str;
 
 pub use core::i64::{BITS, BYTES, MIN, MAX};
index bd40a2c53b656b0f99fdc8af858c649f904eb7f6..bea315d86837392e42a3236b646b7d747abfd36e 100644 (file)
 //! Operations and constants for signed 8-bits integers (`i8` type)
 
 use from_str::FromStr;
-use iter::Iterator;
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::{ImmutableVector, OwnedVector};
+use slice::ImmutableVector;
 use str;
 
 pub use core::i8::{BITS, BYTES, MIN, MAX};
index d9552ee33400ed5c898a126593009d1bb430beca..d6a7fd1660b42800eb61a8731d6eb86413ba815a 100644 (file)
 //! Operations and constants for architecture-sized signed integers (`int` type)
 
 use from_str::FromStr;
-use iter::Iterator;
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::{ImmutableVector, OwnedVector};
+use slice::ImmutableVector;
 use str;
 
 pub use core::int::{BITS, BYTES, MIN, MAX};
index 8a7bea465851ac21ba122a8866a2855c7af7c7fc..fcdb63f5ad5eb06564fadbc26af502becd07bc3d 100644 (file)
@@ -77,13 +77,16 @@ impl ToStrRadix for $T {
     /// Convert to a string in a given base.
     #[inline]
     fn to_str_radix(&self, radix: uint) -> ~str {
+        use slice::Vector;
+        use str::StrAllocating;
+
         let mut buf = ::vec::Vec::new();
         strconv::int_to_str_bytes_common(*self, radix, strconv::SignNeg, |i| {
             buf.push(i);
         });
         // We know we generated valid utf-8, so we don't need to go through that
         // check.
-        unsafe { str::raw::from_utf8_owned(buf.move_iter().collect()) }
+        unsafe { str::raw::from_utf8(buf.as_slice()).to_owned() }
     }
 }
 
index 8861597bb4c16d50348648dd6ffd882cdf6ab41e..4769b17fb2b84e7d15eb795117fd95311448ef69 100644 (file)
 use num;
 use ops::{Add, Sub, Mul, Div, Rem, Neg};
 use option::{None, Option, Some};
-use slice::OwnedVector;
 use slice::{CloneableVector, ImmutableVector, MutableVector};
 use std::cmp::{Ord, Eq};
-use str::{StrSlice};
-use str;
+use str::{StrAllocating, StrSlice};
+use strbuf::StrBuf;
 use vec::Vec;
 
 /// A flag that specifies whether to use exponential (scientific) notation.
@@ -262,7 +261,7 @@ pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+
                                   Div<T,T>+Neg<T>+Rem<T,T>+Mul<T,T>>(
         num: T, radix: uint, negative_zero: bool,
         sign: SignFormat, digits: SignificantDigits, exp_format: ExponentFormat, exp_upper: bool
-        ) -> (~[u8], bool) {
+        ) -> (Vec<u8>, bool) {
     assert!(2 <= radix && radix <= 36);
     match exp_format {
         ExpDec if radix >= DIGIT_E_RADIX       // decimal exponent 'e'
@@ -278,17 +277,17 @@ pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+
     let _1: T = One::one();
 
     match num.classify() {
-        FPNaN => { return ("NaN".as_bytes().to_owned(), true); }
+        FPNaN => { return (Vec::from_slice("NaN".as_bytes()), true); }
         FPInfinite if num > _0 => {
             return match sign {
-                SignAll => ("+inf".as_bytes().to_owned(), true),
-                _       => ("inf".as_bytes().to_owned(), true)
+                SignAll => (Vec::from_slice("+inf".as_bytes()), true),
+                _       => (Vec::from_slice("inf".as_bytes()), true)
             };
         }
         FPInfinite if num < _0 => {
             return match sign {
-                SignNone => ("inf".as_bytes().to_owned(), true),
-                _        => ("-inf".as_bytes().to_owned(), true),
+                SignNone => (Vec::from_slice("inf".as_bytes()), true),
+                _        => (Vec::from_slice("-inf".as_bytes()), true),
             };
         }
         _ => {}
@@ -483,7 +482,7 @@ pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+
         }
     }
 
-    (buf.move_iter().collect(), false)
+    (buf, false)
 }
 
 /**
@@ -498,7 +497,7 @@ pub fn float_to_str_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Float+
         ) -> (~str, bool) {
     let (bytes, special) = float_to_str_bytes_common(num, radix,
                                negative_zero, sign, digits, exp_format, exp_capital);
-    (str::from_utf8_owned(bytes).unwrap(), special)
+    (StrBuf::from_utf8(bytes).unwrap().into_owned(), special)
 }
 
 // Some constants for from_str_bytes_common's input validation,
index dd6a838df9ba649521654bda13a0c51722dd8794..5c93ca6c36b79748b8fba3a704eb353d4dd0feaa 100644 (file)
 //! Operations and constants for unsigned 16-bits integers (`u16` type)
 
 use from_str::FromStr;
-use iter::Iterator;
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::{ImmutableVector, OwnedVector};
+use slice::ImmutableVector;
 use str;
 
 pub use core::u16::{BITS, BYTES, MIN, MAX};
index bb05938969dee5bf60fd42fe0bd5f00f94b75e0c..436eae7cd14d0c839acb9f0a0a617560acaeb478 100644 (file)
 //! Operations and constants for unsigned 32-bits integers (`u32` type)
 
 use from_str::FromStr;
-use iter::Iterator;
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::{ImmutableVector, OwnedVector};
+use slice::ImmutableVector;
 use str;
 
 pub use core::u32::{BITS, BYTES, MIN, MAX};
index f38806e1527fd3b98ebcdcd13559033b8279d713..c654d6fbe3133df7e4e6cf36e0d4a58939a36741 100644 (file)
 //! Operations and constants for unsigned 64-bits integer (`u64` type)
 
 use from_str::FromStr;
-use iter::Iterator;
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::{ImmutableVector, OwnedVector};
+use slice::ImmutableVector;
 use str;
 
 pub use core::u64::{BITS, BYTES, MIN, MAX};
index 87fed563a1535658ddb17ce97274b84ad5dac09d..7051b9191be8158ba668ec23d3b079068383b5ce 100644 (file)
 //! Operations and constants for unsigned 8-bits integers (`u8` type)
 
 use from_str::FromStr;
-use iter::Iterator;
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::{ImmutableVector, OwnedVector};
+use slice::ImmutableVector;
 use str;
 
 pub use core::u8::{BITS, BYTES, MIN, MAX};
index 61ab97e86b87c25350772be94301a73560499ebb..d1c3e96b2c987d7334b82dd6d3dc0b70d88141e1 100644 (file)
 //! Operations and constants for architecture-sized unsigned integers (`uint` type)
 
 use from_str::FromStr;
-use iter::Iterator;
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::{ImmutableVector, OwnedVector};
+use slice::ImmutableVector;
 use str;
 
 pub use core::uint::{BITS, BYTES, MIN, MAX};
index 3e64c17161368bcc1f387918f82d6327f71085a3..0795238a49cff9578865f34f431f431575219533 100644 (file)
@@ -78,13 +78,16 @@ impl ToStrRadix for $T {
     /// Convert to a string in a given base.
     #[inline]
     fn to_str_radix(&self, radix: uint) -> ~str {
+        use slice::Vector;
+        use str::StrAllocating;
+
         let mut buf = ::vec::Vec::new();
         strconv::int_to_str_bytes_common(*self, radix, strconv::SignNone, |i| {
             buf.push(i);
         });
         // We know we generated valid utf-8, so we don't need to go through that
         // check.
-        unsafe { str::raw::from_utf8_owned(buf.move_iter().collect()) }
+        unsafe { str::raw::from_utf8(buf.as_slice()).to_owned() }
     }
 }
 
index 809757aaf4d0281a6445038a9f84d6d6cc64b245..66143b40d52514e3f572a768a64063c3383054af 100644 (file)
@@ -169,7 +169,7 @@ fn with_env_lock<T>(f: || -> T) -> T {
 ///
 /// Invalid UTF-8 bytes are replaced with \uFFFD. See `str::from_utf8_lossy()`
 /// for details.
-pub fn env() -> ~[(~str,~str)] {
+pub fn env() -> Vec<(~str,~str)> {
     env_as_bytes().move_iter().map(|(k,v)| {
         let k = str::from_utf8_lossy(k).into_owned();
         let v = str::from_utf8_lossy(v).into_owned();
@@ -179,7 +179,7 @@ pub fn env() -> ~[(~str,~str)] {
 
 /// Returns a vector of (variable, value) byte-vector pairs for all the
 /// environment variables of the current process.
-pub fn env_as_bytes() -> ~[(~[u8],~[u8])] {
+pub fn env_as_bytes() -> Vec<(~[u8],~[u8])> {
     unsafe {
         #[cfg(windows)]
         unsafe fn get_env_pairs() -> Vec<~[u8]> {
@@ -224,16 +224,16 @@ unsafe fn get_env_pairs() -> Vec<~[u8]> {
         fn env_convert(input: Vec<~[u8]>) -> Vec<(~[u8], ~[u8])> {
             let mut pairs = Vec::new();
             for p in input.iter() {
-                let vs: ~[&[u8]] = p.splitn(1, |b| *b == '=' as u8).collect();
-                let key = vs[0].to_owned();
-                let val = if vs.len() < 2 { box [] } else { vs[1].to_owned() };
+                let mut it = p.splitn(1, |b| *b == '=' as u8);
+                let key = it.next().unwrap().to_owned();
+                let val = it.next().unwrap_or(&[]).to_owned();
                 pairs.push((key, val));
             }
             pairs
         }
         with_env_lock(|| {
             let unparsed_environ = get_env_pairs();
-            env_convert(unparsed_environ).move_iter().collect()
+            env_convert(unparsed_environ)
         })
     }
 }
@@ -416,7 +416,7 @@ pub fn dll_filename(base: &str) -> ~str {
 pub fn self_exe_name() -> Option<Path> {
 
     #[cfg(target_os = "freebsd")]
-    fn load_self() -> Option<~[u8]> {
+    fn load_self() -> Option<Vec<u8>> {
         unsafe {
             use libc::funcs::bsd44::*;
             use libc::consts::os::extra::*;
@@ -436,23 +436,23 @@ fn load_self() -> Option<~[u8]> {
             if err != 0 { return None; }
             if sz == 0 { return None; }
             v.set_len(sz as uint - 1); // chop off trailing NUL
-            Some(v.move_iter().collect())
+            Some(v)
         }
     }
 
     #[cfg(target_os = "linux")]
     #[cfg(target_os = "android")]
-    fn load_self() -> Option<~[u8]> {
+    fn load_self() -> Option<Vec<u8>> {
         use std::io;
 
         match io::fs::readlink(&Path::new("/proc/self/exe")) {
-            Ok(path) => Some(path.as_vec().to_owned()),
+            Ok(path) => Some(path.into_vec()),
             Err(..) => None
         }
     }
 
     #[cfg(target_os = "macos")]
-    fn load_self() -> Option<~[u8]> {
+    fn load_self() -> Option<Vec<u8>> {
         unsafe {
             use libc::funcs::extra::_NSGetExecutablePath;
             let mut sz: u32 = 0;
@@ -462,19 +462,19 @@ fn load_self() -> Option<~[u8]> {
             let err = _NSGetExecutablePath(v.as_mut_ptr() as *mut i8, &mut sz);
             if err != 0 { return None; }
             v.set_len(sz as uint - 1); // chop off trailing NUL
-            Some(v.move_iter().collect())
+            Some(v)
         }
     }
 
     #[cfg(windows)]
-    fn load_self() -> Option<~[u8]> {
+    fn load_self() -> Option<Vec<u8>> {
         use str::OwnedStr;
 
         unsafe {
             use os::win32::fill_utf16_buf_and_decode;
             fill_utf16_buf_and_decode(|buf, sz| {
                 libc::GetModuleFileNameW(0u as libc::DWORD, buf, sz)
-            }).map(|s| s.into_bytes())
+            }).map(|s| s.into_strbuf().into_bytes())
         }
     }
 
@@ -789,12 +789,12 @@ pub fn get_exit_status() -> int {
 }
 
 #[cfg(target_os = "macos")]
-unsafe fn load_argc_and_argv(argc: int, argv: **c_char) -> ~[~[u8]] {
+unsafe fn load_argc_and_argv(argc: int, argv: **c_char) -> Vec<~[u8]> {
     use c_str::CString;
 
     Vec::from_fn(argc as uint, |i| {
         CString::new(*argv.offset(i as int), false).as_bytes_no_nul().to_owned()
-    }).move_iter().collect()
+    })
 }
 
 /**
@@ -803,7 +803,7 @@ unsafe fn load_argc_and_argv(argc: int, argv: **c_char) -> ~[~[u8]] {
  * Returns a list of the command line arguments.
  */
 #[cfg(target_os = "macos")]
-fn real_args_as_bytes() -> ~[~[u8]] {
+fn real_args_as_bytes() -> Vec<~[u8]> {
     unsafe {
         let (argc, argv) = (*_NSGetArgc() as int,
                             *_NSGetArgv() as **c_char);
@@ -814,7 +814,7 @@ fn real_args_as_bytes() -> ~[~[u8]] {
 #[cfg(target_os = "linux")]
 #[cfg(target_os = "android")]
 #[cfg(target_os = "freebsd")]
-fn real_args_as_bytes() -> ~[~[u8]] {
+fn real_args_as_bytes() -> Vec<~[u8]> {
     use rt;
 
     match rt::args::clone() {
@@ -824,12 +824,12 @@ fn real_args_as_bytes() -> ~[~[u8]] {
 }
 
 #[cfg(not(windows))]
-fn real_args() -> ~[~str] {
+fn real_args() -> Vec<~str> {
     real_args_as_bytes().move_iter().map(|v| str::from_utf8_lossy(v).into_owned()).collect()
 }
 
 #[cfg(windows)]
-fn real_args() -> ~[~str] {
+fn real_args() -> Vec<~str> {
     use slice;
     use option::Expect;
 
@@ -855,11 +855,11 @@ fn real_args() -> ~[~str] {
         LocalFree(szArgList as *c_void);
     }
 
-    return args.move_iter().collect();
+    return args
 }
 
 #[cfg(windows)]
-fn real_args_as_bytes() -> ~[~[u8]] {
+fn real_args_as_bytes() -> Vec<~[u8]> {
     real_args().move_iter().map(|s| s.into_bytes()).collect()
 }
 
@@ -883,13 +883,13 @@ fn real_args_as_bytes() -> ~[~[u8]] {
 ///
 /// The arguments are interpreted as utf-8, with invalid bytes replaced with \uFFFD.
 /// See `str::from_utf8_lossy` for details.
-pub fn args() -> ~[~str] {
+pub fn args() -> Vec<~str> {
     real_args()
 }
 
 /// Returns the arguments which this program was started with (normally passed
 /// via the command line) as byte vectors.
-pub fn args_as_bytes() -> ~[~[u8]] {
+pub fn args_as_bytes() -> Vec<~[u8]> {
     real_args_as_bytes()
 }
 
index ac1692e6bb33ab327bebdbb2285ef976e01cfa56..df0f1d8d449e44f44919b7351a45b0d366eb3ae6 100644 (file)
@@ -21,6 +21,7 @@
 //! FIXME #7756: This has a lot of C glue for lack of globals.
 
 use option::Option;
+use vec::Vec;
 #[cfg(test)] use option::{Some, None};
 #[cfg(test)] use realstd;
 #[cfg(test)] use realargs = realstd::rt::args;
@@ -36,10 +37,10 @@ pub unsafe fn init(argc: int, argv: **u8) { realargs::init(argc, argv) }
 #[cfg(test)]      pub unsafe fn cleanup() { realargs::cleanup() }
 
 /// Take the global arguments from global storage.
-#[cfg(not(test))] pub fn take() -> Option<~[~[u8]]> { imp::take() }
-#[cfg(test)]      pub fn take() -> Option<~[~[u8]]> {
+#[cfg(not(test))] pub fn take() -> Option<Vec<~[u8]>> { imp::take() }
+#[cfg(test)]      pub fn take() -> Option<Vec<~[u8]>> {
     match realargs::take() {
-        realstd::option::Some(a) => Some(a),
+        realstd::option::Some(v) => Some(unsafe{ ::cast::transmute(v) }),
         realstd::option::None => None,
     }
 }
@@ -47,14 +48,14 @@ pub unsafe fn init(argc: int, argv: **u8) { realargs::init(argc, argv) }
 /// Give the global arguments to global storage.
 ///
 /// It is an error if the arguments already exist.
-#[cfg(not(test))] pub fn put(args: ~[~[u8]]) { imp::put(args) }
-#[cfg(test)]      pub fn put(args: ~[~[u8]]) { realargs::put(args) }
+#[cfg(not(test))] pub fn put(args: Vec<~[u8]>) { imp::put(args) }
+#[cfg(test)]      pub fn put(args: Vec<~[u8]>) { realargs::put(unsafe { ::cast::transmute(args) }) }
 
 /// Make a clone of the global arguments.
-#[cfg(not(test))] pub fn clone() -> Option<~[~[u8]]> { imp::clone() }
-#[cfg(test)]      pub fn clone() -> Option<~[~[u8]]> {
+#[cfg(not(test))] pub fn clone() -> Option<Vec<~[u8]>> { imp::clone() }
+#[cfg(test)]      pub fn clone() -> Option<Vec<~[u8]>> {
     match realargs::clone() {
-        realstd::option::Some(a) => Some(a),
+        realstd::option::Some(v) => Some(unsafe { ::cast::transmute(v) }),
         realstd::option::None => None,
     }
 }
@@ -70,6 +71,7 @@ mod imp {
     use owned::Box;
     use unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
     use mem;
+    use vec::Vec;
     #[cfg(not(test))] use ptr::RawPtr;
 
     static mut global_args_ptr: uint = 0;
@@ -87,15 +89,15 @@ pub unsafe fn cleanup() {
         lock.destroy();
     }
 
-    pub fn take() -> Option<~[~[u8]]> {
+    pub fn take() -> Option<Vec<~[u8]>> {
         with_lock(|| unsafe {
             let ptr = get_global_ptr();
             let val = mem::replace(&mut *ptr, None);
-            val.as_ref().map(|s: &Box<~[~[u8]]>| (**s).clone())
+            val.as_ref().map(|s: &Box<Vec<~[u8]>>| (**s).clone())
         })
     }
 
-    pub fn put(args: ~[~[u8]]) {
+    pub fn put(args: Vec<~[u8]>) {
         with_lock(|| unsafe {
             let ptr = get_global_ptr();
             rtassert!((*ptr).is_none());
@@ -103,10 +105,10 @@ pub fn put(args: ~[~[u8]]) {
         })
     }
 
-    pub fn clone() -> Option<~[~[u8]]> {
+    pub fn clone() -> Option<Vec<~[u8]>> {
         with_lock(|| unsafe {
             let ptr = get_global_ptr();
-            (*ptr).as_ref().map(|s: &Box<~[~[u8]]>| (**s).clone())
+            (*ptr).as_ref().map(|s: &Box<Vec<~[u8]>>| (**s).clone())
         })
     }
 
@@ -117,13 +119,13 @@ fn with_lock<T>(f: || -> T) -> T {
         }
     }
 
-    fn get_global_ptr() -> *mut Option<Box<~[~[u8]]>> {
+    fn get_global_ptr() -> *mut Option<Box<Vec<~[u8]>>> {
         unsafe { cast::transmute(&global_args_ptr) }
     }
 
     // Copied from `os`.
     #[cfg(not(test))]
-    unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> ~[~[u8]] {
+    unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> Vec<~[u8]> {
         use c_str::CString;
         use ptr::RawPtr;
         use libc;
@@ -133,7 +135,7 @@ unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> ~[~[u8]] {
         Vec::from_fn(argc as uint, |i| {
             let cs = CString::new(*(argv as **libc::c_char).offset(i as int), false);
             cs.as_bytes_no_nul().to_owned()
-        }).move_iter().collect()
+        })
     }
 
     #[cfg(test)]
@@ -147,7 +149,7 @@ fn smoke_test() {
             // Preserve the actual global state.
             let saved_value = take();
 
-            let expected = box [bytes!("happy").to_owned(), bytes!("today?").to_owned()];
+            let expected = vec![bytes!("happy").to_owned(), bytes!("today?").to_owned()];
 
             put(expected.clone());
             assert!(clone() == Some(expected.clone()));
@@ -170,6 +172,7 @@ fn smoke_test() {
 #[cfg(target_os = "win32", not(test))]
 mod imp {
     use option::Option;
+    use vec::Vec;
 
     pub unsafe fn init(_argc: int, _argv: **u8) {
     }
@@ -177,15 +180,15 @@ pub unsafe fn init(_argc: int, _argv: **u8) {
     pub fn cleanup() {
     }
 
-    pub fn take() -> Option<~[~[u8]]> {
+    pub fn take() -> Option<Vec<~[u8]>> {
         fail!()
     }
 
-    pub fn put(_args: ~[~[u8]]) {
+    pub fn put(_args: Vec<~[u8]>) {
         fail!()
     }
 
-    pub fn clone() -> Option<~[~[u8]]> {
+    pub fn clone() -> Option<Vec<~[u8]>> {
         fail!()
     }
 }
index fe9f4932a2a20d3dcc39be2cb3e0cb0e008b63f0..ccde8d9c96af08cf15bcc141624531a4d5009aab 100644 (file)
@@ -161,7 +161,7 @@ fn unix_bind(&mut self, path: &CString)
     fn unix_connect(&mut self, path: &CString,
                     timeout: Option<u64>) -> IoResult<Box<RtioPipe:Send>>;
     fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
-                          hint: Option<ai::Hint>) -> IoResult<~[ai::Info]>;
+                          hint: Option<ai::Hint>) -> IoResult<Vec<ai::Info>>;
 
     // filesystem operations
     fn fs_from_raw_fd(&mut self, fd: c_int, close: CloseBehavior)
@@ -191,7 +191,7 @@ fn fs_utime(&mut self, src: &CString, atime: u64, mtime: u64) ->
     fn timer_init(&mut self) -> IoResult<Box<RtioTimer:Send>>;
     fn spawn(&mut self, config: ProcessConfig)
             -> IoResult<(Box<RtioProcess:Send>,
-                         ~[Option<Box<RtioPipe:Send>>])>;
+                         Vec<Option<Box<RtioPipe:Send>>>)>;
     fn kill(&mut self, pid: libc::pid_t, signal: int) -> IoResult<()>;
     fn pipe_open(&mut self, fd: c_int) -> IoResult<Box<RtioPipe:Send>>;
     fn tty_open(&mut self, fd: c_int, readable: bool)
@@ -221,6 +221,10 @@ pub trait RtioTcpStream : RtioSocket {
     fn letdie(&mut self) -> IoResult<()>;
     fn clone(&self) -> Box<RtioTcpStream:Send>;
     fn close_write(&mut self) -> IoResult<()>;
+    fn close_read(&mut self) -> IoResult<()>;
+    fn set_timeout(&mut self, timeout_ms: Option<u64>);
+    fn set_read_timeout(&mut self, timeout_ms: Option<u64>);
+    fn set_write_timeout(&mut self, timeout_ms: Option<u64>);
 }
 
 pub trait RtioSocket {
@@ -244,6 +248,9 @@ pub trait RtioUdpSocket : RtioSocket {
     fn ignore_broadcasts(&mut self) -> IoResult<()>;
 
     fn clone(&self) -> Box<RtioUdpSocket:Send>;
+    fn set_timeout(&mut self, timeout_ms: Option<u64>);
+    fn set_read_timeout(&mut self, timeout_ms: Option<u64>);
+    fn set_write_timeout(&mut self, timeout_ms: Option<u64>);
 }
 
 pub trait RtioTimer {
@@ -274,6 +281,12 @@ pub trait RtioPipe {
     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
     fn write(&mut self, buf: &[u8]) -> IoResult<()>;
     fn clone(&self) -> Box<RtioPipe:Send>;
+
+    fn close_write(&mut self) -> IoResult<()>;
+    fn close_read(&mut self) -> IoResult<()>;
+    fn set_timeout(&mut self, timeout_ms: Option<u64>);
+    fn set_read_timeout(&mut self, timeout_ms: Option<u64>);
+    fn set_write_timeout(&mut self, timeout_ms: Option<u64>);
 }
 
 pub trait RtioUnixListener {
index 909df5618aaa39042ab9d7403520a1992dee74ab..77bcb7b9904ac8b9e3a78273490d1fd1e391d441 100644 (file)
@@ -323,6 +323,12 @@ pub fn wake(self) -> Option<Box<Task>> {
         }
     }
 
+    /// Reawakens this task if ownership is acquired. If finer-grained control
+    /// is desired, use `wake` instead.
+    pub fn reawaken(self) {
+        self.wake().map(|t| t.reawaken());
+    }
+
     // This assertion has two flavours because the wake involves an atomic op.
     // In the faster version, destructors will fail dramatically instead.
     #[cfg(not(test))] pub fn trash(self) { }
@@ -414,13 +420,12 @@ fn local_heap() {
 
     #[test]
     fn tls() {
-        use local_data;
         local_data_key!(key: @~str)
-        local_data::set(key, @"data".to_owned());
-        assert!(*local_data::get(key, |k| k.map(|k| *k)).unwrap() == "data".to_owned());
+        key.replace(Some(@"data".to_owned()));
+        assert_eq!(key.get().unwrap().as_slice(), "data");
         local_data_key!(key2: @~str)
-        local_data::set(key2, @"data".to_owned());
-        assert!(*local_data::get(key2, |k| k.map(|k| *k)).unwrap() == "data".to_owned());
+        key2.replace(Some(@"data".to_owned()));
+        assert_eq!(key2.get().unwrap().as_slice(), "data");
     }
 
     #[test]
index c7cefbb28eef9d0e1a143f919db3f720f2723c3b..21084407b8d09db070560c5f4a64e06246f86311 100644 (file)
@@ -127,23 +127,23 @@ pub trait VectorVector<T> {
     // FIXME #5898: calling these .concat and .connect conflicts with
     // StrVector::con{cat,nect}, since they have generic contents.
     /// Flattens a vector of vectors of T into a single vector of T.
-    fn concat_vec(&self) -> ~[T];
+    fn concat_vec(&self) -> Vec<T>;
 
     /// Concatenate a vector of vectors, placing a given separator between each.
-    fn connect_vec(&self, sep: &T) -> ~[T];
+    fn connect_vec(&self, sep: &T) -> Vec<T>;
 }
 
 impl<'a, T: Clone, V: Vector<T>> VectorVector<T> for &'a [V] {
-    fn concat_vec(&self) -> ~[T] {
+    fn concat_vec(&self) -> Vec<T> {
         let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
         let mut result = Vec::with_capacity(size);
         for v in self.iter() {
             result.push_all(v.as_slice())
         }
-        result.move_iter().collect()
+        result
     }
 
-    fn connect_vec(&self, sep: &T) -> ~[T] {
+    fn connect_vec(&self, sep: &T) -> Vec<T> {
         let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
         let mut result = Vec::with_capacity(size + self.len());
         let mut first = true;
@@ -151,29 +151,10 @@ fn connect_vec(&self, sep: &T) -> ~[T] {
             if first { first = false } else { result.push(sep.clone()) }
             result.push_all(v.as_slice())
         }
-        result.move_iter().collect()
+        result
     }
 }
 
-/**
- * Convert an iterator of pairs into a pair of vectors.
- *
- * Returns a tuple containing two vectors where the i-th element of the first
- * vector contains the first element of the i-th tuple of the input iterator,
- * and the i-th element of the second vector contains the second element
- * of the i-th tuple of the input iterator.
- */
-pub fn unzip<T, U, V: Iterator<(T, U)>>(mut iter: V) -> (~[T], ~[U]) {
-    let (lo, _) = iter.size_hint();
-    let mut ts = Vec::with_capacity(lo);
-    let mut us = Vec::with_capacity(lo);
-    for (t, u) in iter {
-        ts.push(t);
-        us.push(u);
-    }
-    (ts.move_iter().collect(), us.move_iter().collect())
-}
-
 /// An Iterator that yields the element swaps needed to produce
 /// a sequence of all possible permutations for an indexed sequence of
 /// elements. Each permutation is only a single swap apart.
@@ -185,7 +166,7 @@ pub fn unzip<T, U, V: Iterator<(T, U)>>(mut iter: V) -> (~[T], ~[U]) {
 /// The last generated swap is always (0, 1), and it returns the
 /// sequence to its initial order.
 pub struct ElementSwaps {
-    sdir: ~[SizeDirection],
+    sdir: Vec<SizeDirection>,
     /// If true, emit the last swap that returns the sequence to initial state
     emit_reset: bool,
     swaps_made : uint,
@@ -199,9 +180,7 @@ pub fn new(length: uint) -> ElementSwaps {
         // element (equal to the original index).
         ElementSwaps{
             emit_reset: true,
-            sdir: range(0, length)
-                    .map(|i| SizeDirection{ size: i, dir: Neg })
-                    .collect::<~[_]>(),
+            sdir: range(0, length).map(|i| SizeDirection{ size: i, dir: Neg }).collect(),
             swaps_made: 0
         }
     }
@@ -228,12 +207,12 @@ fn new_pos(i: uint, s: Direction) -> uint {
         let max = self.sdir.iter().map(|&x| x).enumerate()
                            .filter(|&(i, sd)|
                                 new_pos(i, sd.dir) < self.sdir.len() &&
-                                self.sdir[new_pos(i, sd.dir)].size < sd.size)
+                                self.sdir.get(new_pos(i, sd.dir)).size < sd.size)
                            .max_by(|&(_, sd)| sd.size);
         match max {
             Some((i, sd)) => {
                 let j = new_pos(i, sd.dir);
-                self.sdir.swap(i, j);
+                self.sdir.as_mut_slice().swap(i, j);
 
                 // Swap the direction of each larger SizeDirection
                 for x in self.sdir.mut_iter() {
@@ -314,16 +293,29 @@ impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
     /// Returns a copy of `v`.
     #[inline]
     fn to_owned(&self) -> ~[T] {
+        use RawVec = core::raw::Vec;
+        use rt::global_heap::{malloc_raw, exchange_free};
+        use num::{CheckedAdd, CheckedMul};
+        use option::Expect;
+
         let len = self.len();
-        let mut result = Vec::with_capacity(len);
-        // Unsafe code so this can be optimised to a memcpy (or something
-        // similarly fast) when T is Copy. LLVM is easily confused, so any
-        // extra operations during the loop can prevent this optimisation
+        let data_size = len.checked_mul(&mem::size_of::<T>());
+        let data_size = data_size.expect("overflow in to_owned()");
+        let size = mem::size_of::<RawVec<()>>().checked_add(&data_size);
+        let size = size.expect("overflow in to_owned()");
+
         unsafe {
+            let ret = malloc_raw(size) as *mut RawVec<()>;
+
+            (*ret).fill = len * mem::nonzero_size_of::<T>();
+            (*ret).alloc = len * mem::nonzero_size_of::<T>();
+
+            // Be careful with the following loop. We want it to be optimized
+            // to a memcpy (or something similarly fast) when T is Copy. LLVM
+            // is easily confused, so any extra operations during the loop can
+            // prevent this optimization.
             let mut i = 0;
-            let p = result.as_mut_ptr();
-            // Use try_finally here otherwise the write to length
-            // inside the loop stops LLVM from optimising this.
+            let p = &mut (*ret).data as *mut _ as *mut T;
             try_finally(
                 &mut i, (),
                 |i, ()| while *i < len {
@@ -332,9 +324,15 @@ fn to_owned(&self) -> ~[T] {
                         self.unsafe_ref(*i).clone());
                     *i += 1;
                 },
-                |i| result.set_len(*i));
+                |i| if *i < len {
+                    // we must be failing, clean up after ourselves
+                    for j in range(0, *i as int) {
+                        ptr::read(&*p.offset(j));
+                    }
+                    exchange_free(ret as *u8);
+                });
+            cast::transmute(ret)
         }
-        result.move_iter().collect()
     }
 
     #[inline(always)]
@@ -354,7 +352,7 @@ fn into_owned(self) -> ~[T] { self }
 pub trait ImmutableCloneableVector<T> {
     /// Partitions the vector into two vectors `(A,B)`, where all
     /// elements of `A` satisfy `f` and all elements of `B` do not.
-    fn partitioned(&self, f: |&T| -> bool) -> (~[T], ~[T]);
+    fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>);
 
     /// Create an iterator that yields every possible permutation of the
     /// vector in succession.
@@ -363,7 +361,7 @@ pub trait ImmutableCloneableVector<T> {
 
 impl<'a,T:Clone> ImmutableCloneableVector<T> for &'a [T] {
     #[inline]
-    fn partitioned(&self, f: |&T| -> bool) -> (~[T], ~[T]) {
+    fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
         let mut lefts  = Vec::new();
         let mut rights = Vec::new();
 
@@ -375,7 +373,7 @@ fn partitioned(&self, f: |&T| -> bool) -> (~[T], ~[T]) {
             }
         }
 
-        (lefts.move_iter().collect(), rights.move_iter().collect())
+        (lefts, rights)
     }
 
     fn permutations(self) -> Permutations<T> {
@@ -412,7 +410,7 @@ pub trait OwnedVector<T> {
      * Partitions the vector into two vectors `(A,B)`, where all
      * elements of `A` satisfy `f` and all elements of `B` do not.
      */
-    fn partition(self, f: |&T| -> bool) -> (~[T], ~[T]);
+    fn partition(self, f: |&T| -> bool) -> (Vec<T>, Vec<T>);
 }
 
 impl<T> OwnedVector<T> for ~[T] {
@@ -432,7 +430,7 @@ fn move_rev_iter(self) -> Rev<MoveItems<T>> {
     }
 
     #[inline]
-    fn partition(self, f: |&T| -> bool) -> (~[T], ~[T]) {
+    fn partition(self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
         let mut lefts  = Vec::new();
         let mut rights = Vec::new();
 
@@ -444,7 +442,7 @@ fn partition(self, f: |&T| -> bool) -> (~[T], ~[T]) {
             }
         }
 
-        (lefts.move_iter().collect(), rights.move_iter().collect())
+        (lefts, rights)
     }
 }
 
@@ -729,45 +727,10 @@ fn sort(self) {
     }
 }
 
-/**
-* Constructs a vector from an unsafe pointer to a buffer
-*
-* # Arguments
-*
-* * ptr - An unsafe pointer to a buffer of `T`
-* * elts - The number of elements in the buffer
-*/
-// Wrapper for fn in raw: needs to be called by net_tcp::on_tcp_read_cb
-pub unsafe fn from_buf<T>(ptr: *T, elts: uint) -> ~[T] {
-    raw::from_buf_raw(ptr, elts)
-}
-
 /// Unsafe operations
 pub mod raw {
-    use iter::Iterator;
-    use ptr;
-    use slice::{MutableVector, OwnedVector};
-    use vec::Vec;
-
     pub use core::slice::raw::{buf_as_slice, mut_buf_as_slice};
     pub use core::slice::raw::{shift_ptr, pop_ptr};
-
-    /**
-    * Constructs a vector from an unsafe pointer to a buffer
-    *
-    * # Arguments
-    *
-    * * ptr - An unsafe pointer to a buffer of `T`
-    * * elts - The number of elements in the buffer
-    */
-    // Was in raw, but needs to be called by net_tcp::on_tcp_read_cb
-    #[inline]
-    pub unsafe fn from_buf_raw<T>(ptr: *T, elts: uint) -> ~[T] {
-        let mut dst = Vec::with_capacity(elts);
-        dst.set_len(elts);
-        ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
-        dst.move_iter().collect()
-    }
 }
 
 /// An iterator that moves out of a vector.
@@ -827,31 +790,6 @@ fn square(n: uint) -> uint { n * n }
 
     fn is_odd(n: &uint) -> bool { *n % 2u == 1u }
 
-    #[test]
-    fn test_unsafe_ptrs() {
-        unsafe {
-            // Test on-stack copy-from-buf.
-            let a = box [1, 2, 3];
-            let mut ptr = a.as_ptr();
-            let b = from_buf(ptr, 3u);
-            assert_eq!(b.len(), 3u);
-            assert_eq!(b[0], 1);
-            assert_eq!(b[1], 2);
-            assert_eq!(b[2], 3);
-
-            // Test on-heap copy-from-buf.
-            let c = box [1, 2, 3, 4, 5];
-            ptr = c.as_ptr();
-            let d = from_buf(ptr, 5u);
-            assert_eq!(d.len(), 5u);
-            assert_eq!(d[0], 1);
-            assert_eq!(d[1], 2);
-            assert_eq!(d[2], 3);
-            assert_eq!(d[3], 4);
-            assert_eq!(d[4], 5);
-        }
-    }
-
     #[test]
     fn test_from_fn() {
         // Test on-stack from_fn.
@@ -1230,17 +1168,6 @@ fn test_retain() {
         assert_eq!(v, vec![1, 3, 5]);
     }
 
-    #[test]
-    fn test_zip_unzip() {
-        let z1 = vec![(1, 4), (2, 5), (3, 6)];
-
-        let (left, right) = unzip(z1.iter().map(|&x| x));
-
-        assert_eq!((1, 4), (left[0], right[0]));
-        assert_eq!((2, 5), (left[1], right[1]));
-        assert_eq!((3, 6), (left[2], right[2]));
-    }
-
     #[test]
     fn test_element_swaps() {
         let mut v = [1, 2, 3];
@@ -1425,7 +1352,7 @@ fn test_sort_stability() {
                         let n = task_rng().gen::<uint>() % 10;
                         counts[n] += 1;
                         (n, counts[n])
-                    }).collect::<~[(uint, int)]>();
+                    }).collect::<Vec<(uint, int)>>();
 
                 // only sort on the first element, so an unstable sort
                 // may mix up the counts.
@@ -1436,46 +1363,45 @@ fn test_sort_stability() {
                 // will need to be ordered with increasing
                 // counts... i.e. exactly asserting that this sort is
                 // stable.
-                assert!(v.windows(2).all(|w| w[0] <= w[1]));
+                assert!(v.as_slice().windows(2).all(|w| w[0] <= w[1]));
             }
         }
     }
 
     #[test]
     fn test_partition() {
-        assert_eq!((box []).partition(|x: &int| *x < 3), (box [], box []));
-        assert_eq!((box [1, 2, 3]).partition(|x: &int| *x < 4), (box [1, 2, 3], box []));
-        assert_eq!((box [1, 2, 3]).partition(|x: &int| *x < 2), (box [1], box [2, 3]));
-        assert_eq!((box [1, 2, 3]).partition(|x: &int| *x < 0), (box [], box [1, 2, 3]));
+        assert_eq!((box []).partition(|x: &int| *x < 3), (vec![], vec![]));
+        assert_eq!((box [1, 2, 3]).partition(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
+        assert_eq!((box [1, 2, 3]).partition(|x: &int| *x < 2), (vec![1], vec![2, 3]));
+        assert_eq!((box [1, 2, 3]).partition(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
     }
 
     #[test]
     fn test_partitioned() {
-        assert_eq!(([]).partitioned(|x: &int| *x < 3), (box [], box []))
-        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 4), (box [1, 2, 3], box []));
-        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 2), (box [1], box [2, 3]));
-        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 0), (box [], box [1, 2, 3]));
+        assert_eq!(([]).partitioned(|x: &int| *x < 3), (vec![], vec![]));
+        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
+        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 2), (vec![1], vec![2, 3]));
+        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
     }
 
     #[test]
     fn test_concat() {
         let v: [~[int], ..0] = [];
-        assert_eq!(v.concat_vec(), box []);
-        assert_eq!([box [1], box [2,3]].concat_vec(), box [1, 2, 3]);
+        assert_eq!(v.concat_vec(), vec![]);
+        assert_eq!([box [1], box [2,3]].concat_vec(), vec![1, 2, 3]);
 
-        assert_eq!([&[1], &[2,3]].concat_vec(), box [1, 2, 3]);
+        assert_eq!([&[1], &[2,3]].concat_vec(), vec![1, 2, 3]);
     }
 
     #[test]
     fn test_connect() {
         let v: [~[int], ..0] = [];
-        assert_eq!(v.connect_vec(&0), box []);
-        assert_eq!([box [1], box [2, 3]].connect_vec(&0), box [1, 0, 2, 3]);
-        assert_eq!([box [1], box [2], box [3]].connect_vec(&0), box [1, 0, 2, 0, 3]);
+        assert_eq!(v.connect_vec(&0), vec![]);
+        assert_eq!([box [1], box [2, 3]].connect_vec(&0), vec![1, 0, 2, 3]);
+        assert_eq!([box [1], box [2], box [3]].connect_vec(&0), vec![1, 0, 2, 0, 3]);
 
-        assert_eq!(v.connect_vec(&0), box []);
-        assert_eq!([&[1], &[2, 3]].connect_vec(&0), box [1, 0, 2, 3]);
-        assert_eq!([&[1], &[2], &[3]].connect_vec(&0), box [1, 0, 2, 0, 3]);
+        assert_eq!([&[1], &[2, 3]].connect_vec(&0), vec![1, 0, 2, 3]);
+        assert_eq!([&[1], &[2], &[3]].connect_vec(&0), vec![1, 0, 2, 0, 3]);
     }
 
     #[test]
@@ -1773,74 +1699,74 @@ fn test_move_rev_iterator() {
     fn test_splitator() {
         let xs = &[1i,2,3,4,5];
 
-        assert_eq!(xs.split(|x| *x % 2 == 0).collect::<~[&[int]]>(),
-                   box [&[1], &[3], &[5]]);
-        assert_eq!(xs.split(|x| *x == 1).collect::<~[&[int]]>(),
-                   box [&[], &[2,3,4,5]]);
-        assert_eq!(xs.split(|x| *x == 5).collect::<~[&[int]]>(),
-                   box [&[1,2,3,4], &[]]);
-        assert_eq!(xs.split(|x| *x == 10).collect::<~[&[int]]>(),
-                   box [&[1,2,3,4,5]]);
-        assert_eq!(xs.split(|_| true).collect::<~[&[int]]>(),
-                   box [&[], &[], &[], &[], &[], &[]]);
+        assert_eq!(xs.split(|x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[1], &[3], &[5]]);
+        assert_eq!(xs.split(|x| *x == 1).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[], &[2,3,4,5]]);
+        assert_eq!(xs.split(|x| *x == 5).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[1,2,3,4], &[]]);
+        assert_eq!(xs.split(|x| *x == 10).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[1,2,3,4,5]]);
+        assert_eq!(xs.split(|_| true).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[], &[], &[], &[], &[], &[]]);
 
         let xs: &[int] = &[];
-        assert_eq!(xs.split(|x| *x == 5).collect::<~[&[int]]>(), box [&[]]);
+        assert_eq!(xs.split(|x| *x == 5).collect::<Vec<&[int]>>().as_slice(), &[&[]]);
     }
 
     #[test]
     fn test_splitnator() {
         let xs = &[1i,2,3,4,5];
 
-        assert_eq!(xs.splitn(0, |x| *x % 2 == 0).collect::<~[&[int]]>(),
-                   box [&[1,2,3,4,5]]);
-        assert_eq!(xs.splitn(1, |x| *x % 2 == 0).collect::<~[&[int]]>(),
-                   box [&[1], &[3,4,5]]);
-        assert_eq!(xs.splitn(3, |_| true).collect::<~[&[int]]>(),
-                   box [&[], &[], &[], &[4,5]]);
+        assert_eq!(xs.splitn(0, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[1,2,3,4,5]]);
+        assert_eq!(xs.splitn(1, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[1], &[3,4,5]]);
+        assert_eq!(xs.splitn(3, |_| true).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[], &[], &[], &[4,5]]);
 
         let xs: &[int] = &[];
-        assert_eq!(xs.splitn(1, |x| *x == 5).collect::<~[&[int]]>(), box [&[]]);
+        assert_eq!(xs.splitn(1, |x| *x == 5).collect::<Vec<&[int]>>().as_slice(), &[&[]]);
     }
 
     #[test]
     fn test_rsplitator() {
         let xs = &[1i,2,3,4,5];
 
-        assert_eq!(xs.split(|x| *x % 2 == 0).rev().collect::<~[&[int]]>(),
-                   box [&[5], &[3], &[1]]);
-        assert_eq!(xs.split(|x| *x == 1).rev().collect::<~[&[int]]>(),
-                   box [&[2,3,4,5], &[]]);
-        assert_eq!(xs.split(|x| *x == 5).rev().collect::<~[&[int]]>(),
-                   box [&[], &[1,2,3,4]]);
-        assert_eq!(xs.split(|x| *x == 10).rev().collect::<~[&[int]]>(),
-                   box [&[1,2,3,4,5]]);
+        assert_eq!(xs.split(|x| *x % 2 == 0).rev().collect::<Vec<&[int]>>().as_slice(),
+                   &[&[5], &[3], &[1]]);
+        assert_eq!(xs.split(|x| *x == 1).rev().collect::<Vec<&[int]>>().as_slice(),
+                   &[&[2,3,4,5], &[]]);
+        assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<&[int]>>().as_slice(),
+                   &[&[], &[1,2,3,4]]);
+        assert_eq!(xs.split(|x| *x == 10).rev().collect::<Vec<&[int]>>().as_slice(),
+                   &[&[1,2,3,4,5]]);
 
         let xs: &[int] = &[];
-        assert_eq!(xs.split(|x| *x == 5).rev().collect::<~[&[int]]>(), box [&[]]);
+        assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<&[int]>>().as_slice(), &[&[]]);
     }
 
     #[test]
     fn test_rsplitnator() {
         let xs = &[1,2,3,4,5];
 
-        assert_eq!(xs.rsplitn(0, |x| *x % 2 == 0).collect::<~[&[int]]>(),
-                   box [&[1,2,3,4,5]]);
-        assert_eq!(xs.rsplitn(1, |x| *x % 2 == 0).collect::<~[&[int]]>(),
-                   box [&[5], &[1,2,3]]);
-        assert_eq!(xs.rsplitn(3, |_| true).collect::<~[&[int]]>(),
-                   box [&[], &[], &[], &[1,2]]);
+        assert_eq!(xs.rsplitn(0, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[1,2,3,4,5]]);
+        assert_eq!(xs.rsplitn(1, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[5], &[1,2,3]]);
+        assert_eq!(xs.rsplitn(3, |_| true).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[], &[], &[], &[1,2]]);
 
         let xs: &[int] = &[];
-        assert_eq!(xs.rsplitn(1, |x| *x == 5).collect::<~[&[int]]>(), box [&[]]);
+        assert_eq!(xs.rsplitn(1, |x| *x == 5).collect::<Vec<&[int]>>().as_slice(), &[&[]]);
     }
 
     #[test]
     fn test_windowsator() {
         let v = &[1i,2,3,4];
 
-        assert_eq!(v.windows(2).collect::<~[&[int]]>(), box [&[1,2], &[2,3], &[3,4]]);
-        assert_eq!(v.windows(3).collect::<~[&[int]]>(), box [&[1i,2,3], &[2,3,4]]);
+        assert_eq!(v.windows(2).collect::<Vec<&[int]>>().as_slice(), &[&[1,2], &[2,3], &[3,4]]);
+        assert_eq!(v.windows(3).collect::<Vec<&[int]>>().as_slice(), &[&[1i,2,3], &[2,3,4]]);
         assert!(v.windows(6).next().is_none());
     }
 
@@ -1855,11 +1781,11 @@ fn test_windowsator_0() {
     fn test_chunksator() {
         let v = &[1i,2,3,4,5];
 
-        assert_eq!(v.chunks(2).collect::<~[&[int]]>(), box [&[1i,2], &[3,4], &[5]]);
-        assert_eq!(v.chunks(3).collect::<~[&[int]]>(), box [&[1i,2,3], &[4,5]]);
-        assert_eq!(v.chunks(6).collect::<~[&[int]]>(), box [&[1i,2,3,4,5]]);
+        assert_eq!(v.chunks(2).collect::<Vec<&[int]>>().as_slice(), &[&[1i,2], &[3,4], &[5]]);
+        assert_eq!(v.chunks(3).collect::<Vec<&[int]>>().as_slice(), &[&[1i,2,3], &[4,5]]);
+        assert_eq!(v.chunks(6).collect::<Vec<&[int]>>().as_slice(), &[&[1i,2,3,4,5]]);
 
-        assert_eq!(v.chunks(2).rev().collect::<~[&[int]]>(), box [&[5i], &[3,4], &[1,2]]);
+        assert_eq!(v.chunks(2).rev().collect::<Vec<&[int]>>().as_slice(), &[&[5i], &[3,4], &[1,2]]);
         let mut it = v.chunks(2);
         assert_eq!(it.indexable(), 3);
         assert_eq!(it.idx(0).unwrap(), &[1,2]);
@@ -2237,15 +2163,6 @@ fn mut_iterator(b: &mut Bencher) {
         })
     }
 
-    #[bench]
-    fn add(b: &mut Bencher) {
-        let xs: &[int] = [5, ..10];
-        let ys: &[int] = [5, ..10];
-        b.iter(|| {
-            xs + ys;
-        });
-    }
-
     #[bench]
     fn concat(b: &mut Bencher) {
         let xss: Vec<Vec<uint>> = Vec::from_fn(100, |i| range(0, i).collect());
index 666c0a58b3351b1d2b37473a4491de3312661f80..fb3dcc972871d67ac51fb365bd2ad57767e7ea26 100644 (file)
@@ -85,10 +85,9 @@ fn main() {
 use io::Writer;
 use iter::{Iterator, range, AdditiveIterator};
 use option::{None, Option, Some};
-use ptr;
 use from_str::FromStr;
-use slice::{OwnedVector, ImmutableVector, MutableVector};
-use slice::{Vector};
+use slice::{ImmutableVector, MutableVector, CloneableVector};
+use slice::Vector;
 use vec::Vec;
 use default::Default;
 use strbuf::StrBuf;
@@ -668,25 +667,22 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 /// Unsafe operations
 pub mod raw {
     use cast;
-    use iter::Iterator;
     use libc;
     use ptr::RawPtr;
-    use ptr;
-    use slice::{MutableVector, OwnedVector, Vector};
-    use str::{is_utf8};
-    use vec::Vec;
+    use raw::Slice;
+    use slice::CloneableVector;
+    use str::{is_utf8, StrAllocating};
 
     pub use core::str::raw::{from_utf8, c_str_to_static_slice, slice_bytes};
     pub use core::str::raw::{slice_unchecked};
 
     /// Create a Rust string from a *u8 buffer of the given length
     pub unsafe fn from_buf_len(buf: *u8, len: uint) -> ~str {
-        let mut v = Vec::with_capacity(len);
-        ptr::copy_memory(v.as_mut_ptr(), buf, len);
-        v.set_len(len);
-
-        assert!(is_utf8(v.as_slice()));
-        ::cast::transmute(v.move_iter().collect::<~[u8]>())
+        let v = Slice { data: buf, len: len };
+        let bytes: &[u8] = ::cast::transmute(v);
+        assert!(is_utf8(bytes));
+        let s: &str = ::cast::transmute(bytes);
+        s.to_owned()
     }
 
     #[lang="strdup_uniq"]
@@ -824,27 +820,23 @@ fn replace(&self, from: &str, to: &str) -> ~str {
     /// Copy a slice into a new owned str.
     #[inline]
     fn to_owned(&self) -> ~str {
-        let me = self.as_slice();
-        let len = me.len();
-        unsafe {
-            let mut v = Vec::with_capacity(len);
+        use slice::Vector;
 
-            ptr::copy_memory(v.as_mut_ptr(), me.as_ptr(), len);
-            v.set_len(len);
-            ::cast::transmute(v.move_iter().collect::<~[u8]>())
+        unsafe {
+            ::cast::transmute(self.as_slice().as_bytes().to_owned())
         }
     }
 
     /// Converts to a vector of `u16` encoded as UTF-16.
-    fn to_utf16(&self) -> ~[u16] {
+    fn to_utf16(&self) -> Vec<u16> {
         let me = self.as_slice();
-        let mut u = Vec::new();;
+        let mut u = Vec::new();
         for ch in me.chars() {
             let mut buf = [0u16, ..2];
             let n = ch.encode_utf16(buf /* as mut slice! */);
             u.push_all(buf.slice_to(n));
         }
-        u.move_iter().collect()
+        u
     }
 
     /// Given a string, make a new string with repeated copies of it.
@@ -1554,7 +1546,8 @@ fn test_subslice_offset() {
         assert_eq!(a.subslice_offset(c), 0);
 
         let string = "a\nb\nc";
-        let lines: ~[&str] = string.lines().collect();
+        let lines: Vec<&str> = string.lines().collect();
+        let lines = lines.as_slice();
         assert_eq!(string.subslice_offset(lines[0]), 0);
         assert_eq!(string.subslice_offset(lines[1]), 2);
         assert_eq!(string.subslice_offset(lines[2]), 4);
@@ -1617,13 +1610,13 @@ fn test_contains_char() {
     fn test_utf16() {
         let pairs =
             [("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n".to_owned(),
-              box [0xd800_u16, 0xdf45_u16, 0xd800_u16, 0xdf3f_u16,
+              vec![0xd800_u16, 0xdf45_u16, 0xd800_u16, 0xdf3f_u16,
                 0xd800_u16, 0xdf3b_u16, 0xd800_u16, 0xdf46_u16,
                 0xd800_u16, 0xdf39_u16, 0xd800_u16, 0xdf3b_u16,
                 0xd800_u16, 0xdf30_u16, 0x000a_u16]),
 
              ("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n".to_owned(),
-              box [0xd801_u16, 0xdc12_u16, 0xd801_u16,
+              vec![0xd801_u16, 0xdc12_u16, 0xd801_u16,
                 0xdc49_u16, 0xd801_u16, 0xdc2e_u16, 0xd801_u16,
                 0xdc40_u16, 0xd801_u16, 0xdc32_u16, 0xd801_u16,
                 0xdc4b_u16, 0x0020_u16, 0xd801_u16, 0xdc0f_u16,
@@ -1631,7 +1624,7 @@ fn test_utf16() {
                 0x000a_u16]),
 
              ("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n".to_owned(),
-              box [0xd800_u16, 0xdf00_u16, 0xd800_u16, 0xdf16_u16,
+              vec![0xd800_u16, 0xdf00_u16, 0xd800_u16, 0xdf16_u16,
                 0xd800_u16, 0xdf0b_u16, 0xd800_u16, 0xdf04_u16,
                 0xd800_u16, 0xdf11_u16, 0xd800_u16, 0xdf09_u16,
                 0x00b7_u16, 0xd800_u16, 0xdf0c_u16, 0xd800_u16,
@@ -1640,7 +1633,7 @@ fn test_utf16() {
                 0xdf09_u16, 0xd800_u16, 0xdf11_u16, 0x000a_u16 ]),
 
              ("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n".to_owned(),
-              box [0xd801_u16, 0xdc8b_u16, 0xd801_u16, 0xdc98_u16,
+              vec![0xd801_u16, 0xdc8b_u16, 0xd801_u16, 0xdc98_u16,
                 0xd801_u16, 0xdc88_u16, 0xd801_u16, 0xdc91_u16,
                 0xd801_u16, 0xdc9b_u16, 0xd801_u16, 0xdc92_u16,
                 0x0020_u16, 0xd801_u16, 0xdc95_u16, 0xd801_u16,
@@ -1653,18 +1646,18 @@ fn test_utf16() {
                 0x000a_u16 ]),
              // Issue #12318, even-numbered non-BMP planes
              ("\U00020000".to_owned(),
-              box [0xD840, 0xDC00])];
+              vec![0xD840, 0xDC00])];
 
         for p in pairs.iter() {
             let (s, u) = (*p).clone();
-            assert!(is_utf16(u));
+            assert!(is_utf16(u.as_slice()));
             assert_eq!(s.to_utf16(), u);
 
-            assert_eq!(from_utf16(u).unwrap(), s);
-            assert_eq!(from_utf16_lossy(u), s);
+            assert_eq!(from_utf16(u.as_slice()).unwrap(), s);
+            assert_eq!(from_utf16_lossy(u.as_slice()), s);
 
-            assert_eq!(from_utf16(s.to_utf16()).unwrap(), s);
-            assert_eq!(from_utf16(u).unwrap().to_utf16(), u);
+            assert_eq!(from_utf16(s.to_utf16().as_slice()).unwrap(), s);
+            assert_eq!(from_utf16(u.as_slice()).unwrap().to_utf16(), u);
         }
     }
 
@@ -1921,105 +1914,105 @@ fn test_char_indices_revator() {
     fn test_split_char_iterator() {
         let data = "\nMäry häd ä little lämb\nLittle lämb\n";
 
-        let split: ~[&str] = data.split(' ').collect();
-        assert_eq!( split, box ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
+        let split: Vec<&str> = data.split(' ').collect();
+        assert_eq!( split, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
 
-        let mut rsplit: ~[&str] = data.split(' ').rev().collect();
+        let mut rsplit: Vec<&str> = data.split(' ').rev().collect();
         rsplit.reverse();
-        assert_eq!(rsplit, box ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
+        assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
 
-        let split: ~[&str] = data.split(|c: char| c == ' ').collect();
-        assert_eq!( split, box ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
+        let split: Vec<&str> = data.split(|c: char| c == ' ').collect();
+        assert_eq!( split, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
 
-        let mut rsplit: ~[&str] = data.split(|c: char| c == ' ').rev().collect();
+        let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect();
         rsplit.reverse();
-        assert_eq!(rsplit, box ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
+        assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
 
         // Unicode
-        let split: ~[&str] = data.split('ä').collect();
-        assert_eq!( split, box ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
+        let split: Vec<&str> = data.split('ä').collect();
+        assert_eq!( split, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
 
-        let mut rsplit: ~[&str] = data.split('ä').rev().collect();
+        let mut rsplit: Vec<&str> = data.split('ä').rev().collect();
         rsplit.reverse();
-        assert_eq!(rsplit, box ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
+        assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
 
-        let split: ~[&str] = data.split(|c: char| c == 'ä').collect();
-        assert_eq!( split, box ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
+        let split: Vec<&str> = data.split(|c: char| c == 'ä').collect();
+        assert_eq!( split, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
 
-        let mut rsplit: ~[&str] = data.split(|c: char| c == 'ä').rev().collect();
+        let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect();
         rsplit.reverse();
-        assert_eq!(rsplit, box ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
+        assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
     }
 
     #[test]
     fn test_splitn_char_iterator() {
         let data = "\nMäry häd ä little lämb\nLittle lämb\n";
 
-        let split: ~[&str] = data.splitn(' ', 3).collect();
-        assert_eq!(split, box ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
+        let split: Vec<&str> = data.splitn(' ', 3).collect();
+        assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
 
-        let split: ~[&str] = data.splitn(|c: char| c == ' ', 3).collect();
-        assert_eq!(split, box ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
+        let split: Vec<&str> = data.splitn(|c: char| c == ' ', 3).collect();
+        assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
 
         // Unicode
-        let split: ~[&str] = data.splitn('ä', 3).collect();
-        assert_eq!(split, box ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
+        let split: Vec<&str> = data.splitn('ä', 3).collect();
+        assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
 
-        let split: ~[&str] = data.splitn(|c: char| c == 'ä', 3).collect();
-        assert_eq!(split, box ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
+        let split: Vec<&str> = data.splitn(|c: char| c == 'ä', 3).collect();
+        assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
     }
 
     #[test]
     fn test_rsplitn_char_iterator() {
         let data = "\nMäry häd ä little lämb\nLittle lämb\n";
 
-        let mut split: ~[&str] = data.rsplitn(' ', 3).collect();
+        let mut split: Vec<&str> = data.rsplitn(' ', 3).collect();
         split.reverse();
-        assert_eq!(split, box ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
+        assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
 
-        let mut split: ~[&str] = data.rsplitn(|c: char| c == ' ', 3).collect();
+        let mut split: Vec<&str> = data.rsplitn(|c: char| c == ' ', 3).collect();
         split.reverse();
-        assert_eq!(split, box ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
+        assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
 
         // Unicode
-        let mut split: ~[&str] = data.rsplitn('ä', 3).collect();
+        let mut split: Vec<&str> = data.rsplitn('ä', 3).collect();
         split.reverse();
-        assert_eq!(split, box ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
+        assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
 
-        let mut split: ~[&str] = data.rsplitn(|c: char| c == 'ä', 3).collect();
+        let mut split: Vec<&str> = data.rsplitn(|c: char| c == 'ä', 3).collect();
         split.reverse();
-        assert_eq!(split, box ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
+        assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
     }
 
     #[test]
     fn test_split_char_iterator_no_trailing() {
         let data = "\nMäry häd ä little lämb\nLittle lämb\n";
 
-        let split: ~[&str] = data.split('\n').collect();
-        assert_eq!(split, box ["", "Märy häd ä little lämb", "Little lämb", ""]);
+        let split: Vec<&str> = data.split('\n').collect();
+        assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb", ""]);
 
-        let split: ~[&str] = data.split_terminator('\n').collect();
-        assert_eq!(split, box ["", "Märy häd ä little lämb", "Little lämb"]);
+        let split: Vec<&str> = data.split_terminator('\n').collect();
+        assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb"]);
     }
 
     #[test]
     fn test_rev_split_char_iterator_no_trailing() {
         let data = "\nMäry häd ä little lämb\nLittle lämb\n";
 
-        let mut split: ~[&str] = data.split('\n').rev().collect();
+        let mut split: Vec<&str> = data.split('\n').rev().collect();
         split.reverse();
-        assert_eq!(split, box ["", "Märy häd ä little lämb", "Little lämb", ""]);
+        assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb", ""]);
 
-        let mut split: ~[&str] = data.split_terminator('\n').rev().collect();
+        let mut split: Vec<&str> = data.split_terminator('\n').rev().collect();
         split.reverse();
-        assert_eq!(split, box ["", "Märy häd ä little lämb", "Little lämb"]);
+        assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb"]);
     }
 
     #[test]
     fn test_words() {
         let data = "\n \tMäry   häd\tä  little lämb\nLittle lämb\n";
-        let words: ~[&str] = data.words().collect();
-        assert_eq!(words, box ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
+        let words: Vec<&str> = data.words().collect();
+        assert_eq!(words, vec!["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
     }
 
     #[test]
@@ -2053,34 +2046,34 @@ fn test_nfkd_chars() {
     #[test]
     fn test_lines() {
         let data = "\nMäry häd ä little lämb\n\nLittle lämb\n";
-        let lines: ~[&str] = data.lines().collect();
-        assert_eq!(lines, box ["", "Märy häd ä little lämb", "", "Little lämb"]);
+        let lines: Vec<&str> = data.lines().collect();
+        assert_eq!(lines, vec!["", "Märy häd ä little lämb", "", "Little lämb"]);
 
         let data = "\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
-        let lines: ~[&str] = data.lines().collect();
-        assert_eq!(lines, box ["", "Märy häd ä little lämb", "", "Little lämb"]);
+        let lines: Vec<&str> = data.lines().collect();
+        assert_eq!(lines, vec!["", "Märy häd ä little lämb", "", "Little lämb"]);
     }
 
     #[test]
     fn test_split_strator() {
-        fn t<'a>(s: &str, sep: &'a str, u: ~[&str]) {
-            let v: ~[&str] = s.split_str(sep).collect();
-            assert_eq!(v, u);
+        fn t(s: &str, sep: &str, u: &[&str]) {
+            let v: Vec<&str> = s.split_str(sep).collect();
+            assert_eq!(v.as_slice(), u.as_slice());
         }
-        t("--1233345--", "12345", box ["--1233345--"]);
-        t("abc::hello::there", "::", box ["abc", "hello", "there"]);
-        t("::hello::there", "::", box ["", "hello", "there"]);
-        t("hello::there::", "::", box ["hello", "there", ""]);
-        t("::hello::there::", "::", box ["", "hello", "there", ""]);
-        t("ประเทศไทย中华Việt Nam", "中华", box ["ประเทศไทย", "Việt Nam"]);
-        t("zzXXXzzYYYzz", "zz", box ["", "XXX", "YYY", ""]);
-        t("zzXXXzYYYz", "XXX", box ["zz", "zYYYz"]);
-        t(".XXX.YYY.", ".", box ["", "XXX", "YYY", ""]);
-        t("", ".", box [""]);
-        t("zz", "zz", box ["",""]);
-        t("ok", "z", box ["ok"]);
-        t("zzz", "zz", box ["","z"]);
-        t("zzzzz", "zz", box ["","","z"]);
+        t("--1233345--", "12345", ["--1233345--"]);
+        t("abc::hello::there", "::", ["abc", "hello", "there"]);
+        t("::hello::there", "::", ["", "hello", "there"]);
+        t("hello::there::", "::", ["hello", "there", ""]);
+        t("::hello::there::", "::", ["", "hello", "there", ""]);
+        t("ประเทศไทย中华Việt Nam", "中华", ["ประเทศไทย", "Việt Nam"]);
+        t("zzXXXzzYYYzz", "zz", ["", "XXX", "YYY", ""]);
+        t("zzXXXzYYYz", "XXX", ["zz", "zYYYz"]);
+        t(".XXX.YYY.", ".", ["", "XXX", "YYY", ""]);
+        t("", ".", [""]);
+        t("zz", "zz", ["",""]);
+        t("ok", "z", ["ok"]);
+        t("zzz", "zz", ["","z"]);
+        t("zzzzz", "zz", ["","","z"]);
     }
 
     #[test]
index ad703b8054b0bcf6e1c25201527e41ed2d41ab6b..8e05b2f527d0830903ad9dead6ec053099906be0 100644 (file)
@@ -19,7 +19,7 @@
 use iter::{Extendable, FromIterator, Iterator, range};
 use option::{None, Option, Some};
 use ptr::RawPtr;
-use slice::{OwnedVector, Vector};
+use slice::{OwnedVector, Vector, CloneableVector};
 use str::{OwnedStr, Str, StrSlice, StrAllocating};
 use str;
 use vec::Vec;
@@ -273,11 +273,8 @@ fn as_slice<'a>(&'a self) -> &'a str {
 impl StrAllocating for StrBuf {
     #[inline]
     fn into_owned(self) -> ~str {
-        let StrBuf {
-            vec: vec
-        } = self;
         unsafe {
-            cast::transmute::<~[u8],~str>(vec.move_iter().collect())
+            cast::transmute(self.vec.as_slice().to_owned())
         }
     }
 
index d277c514e444f4e4591572426379b78571dec465..676c836c459d72458a6abd468ea213dda1ad628c 100644 (file)
@@ -69,14 +69,14 @@ pub fn new2(data: T) -> (UnsafeArc<T>, UnsafeArc<T>) {
 
     /// As new(), but returns a vector of as many pre-cloned handles as
     /// requested.
-    pub fn newN(data: T, num_handles: uint) -> ~[UnsafeArc<T>] {
+    pub fn newN(data: T, num_handles: uint) -> Vec<UnsafeArc<T>> {
         unsafe {
             if num_handles == 0 {
-                box [] // need to free data here
+                vec![] // need to free data here
             } else {
                 let ptr = new_inner(data, num_handles);
                 let v = Vec::from_fn(num_handles, |_| UnsafeArc { data: ptr });
-                v.move_iter().collect()
+                v
             }
         }
     }
index d06062f02ac8adf4c22a7ca2f6484097e54635fa..8dfd691e6ffdc09f500af0e84d4d8c26a5aad01f 100644 (file)
@@ -407,7 +407,7 @@ mod tests {
     use rand::Rng;
     use sync::atomics::{AtomicBool, INIT_ATOMIC_BOOL, SeqCst,
                         AtomicUint, INIT_ATOMIC_UINT};
-    use slice;
+    use vec;
 
     #[test]
     fn smoke() {
@@ -603,7 +603,7 @@ fn no_starvation() {
         let mut pool = BufferPool::<(int, uint)>::new();
         let (mut w, s) = pool.deque();
 
-        let (threads, hits) = slice::unzip(range(0, NTHREADS).map(|_| {
+        let (threads, hits) = vec::unzip(range(0, NTHREADS).map(|_| {
             let s = s.clone();
             let unique_box = box AtomicUint::new(0);
             let thread_box = unsafe {
index 68f0aaab05b1b034075d23b691fb6911632ea318..e2a9f6a5c4821c481ace94816a41577fcdf4c6fa 100644 (file)
 
 use c_str::ToCStr;
 use cast;
+use iter::Iterator;
 use ops::*;
 use option::*;
 use os;
 use path::GenericPath;
 use path;
 use result::*;
+use slice::{Vector,OwnedVector};
 use str;
+use vec::Vec;
 
 pub struct DynamicLibrary { handle: *u8}
 
@@ -73,8 +76,10 @@ pub fn add_search_path(path: &path::Path) {
             ("LD_LIBRARY_PATH", ':' as u8)
         };
         let newenv = os::getenv_as_bytes(envvar).unwrap_or(box []);
-        let newenv = newenv + &[sep] + path.as_vec();
-        os::setenv(envvar, str::from_utf8(newenv).unwrap());
+        let mut newenv = newenv.move_iter().collect::<Vec<_>>();
+        newenv.push_all(&[sep]);
+        newenv.push_all(path.as_vec());
+        os::setenv(envvar, str::from_utf8(newenv.as_slice()).unwrap());
     }
 
     /// Access the value at the symbol of the dynamic library
index af146b96e505a1c3128baed38c241ec21b7c6435..da01da26709598e95df0ca54dad5ed4fc0964504 100644 (file)
 use mem;
 use num;
 use num::{CheckedMul, CheckedAdd};
-use ops::Drop;
+use ops::{Add, Drop};
 use option::{None, Option, Some, Expect};
 use ptr::RawPtr;
 use ptr;
 use rt::global_heap::{malloc_raw, realloc_raw};
 use raw::Slice;
+use RawVec = raw::Vec;
 use slice::{ImmutableEqVector, ImmutableVector, Items, MutItems, MutableVector};
 use slice::{MutableTotalOrdVector, OwnedVector, Vector};
 use slice::{MutableVectorAllocating};
@@ -1370,6 +1371,16 @@ fn as_slice<'a>(&'a self) -> &'a [T] {
     }
 }
 
+impl<T: Clone, V: Vector<T>> Add<V, Vec<T>> for Vec<T> {
+    #[inline]
+    fn add(&self, rhs: &V) -> Vec<T> {
+        let mut res = Vec::with_capacity(self.len() + rhs.as_slice().len());
+        res.push_all(self.as_slice());
+        res.push_all(rhs.as_slice());
+        res
+    }
+}
+
 #[unsafe_destructor]
 impl<T> Drop for Vec<T> {
     fn drop(&mut self) {
@@ -1436,10 +1447,94 @@ fn drop(&mut self) {
     }
 }
 
+/**
+ * Convert an iterator of pairs into a pair of vectors.
+ *
+ * Returns a tuple containing two vectors where the i-th element of the first
+ * vector contains the first element of the i-th tuple of the input iterator,
+ * and the i-th element of the second vector contains the second element
+ * of the i-th tuple of the input iterator.
+ */
+pub fn unzip<T, U, V: Iterator<(T, U)>>(mut iter: V) -> (Vec<T>, Vec<U>) {
+    let (lo, _) = iter.size_hint();
+    let mut ts = Vec::with_capacity(lo);
+    let mut us = Vec::with_capacity(lo);
+    for (t, u) in iter {
+        ts.push(t);
+        us.push(u);
+    }
+    (ts, us)
+}
+
+/// Mechanism to convert from a `Vec<T>` to a `[T]`.
+///
+/// In a post-DST world this will be used to convert to any `Ptr<[T]>`.
+///
+/// This could be implemented on more types than just pointers to vectors, but
+/// the recommended approach for those types is to implement `FromIterator`.
+// FIXME(#12938): Update doc comment when DST lands
+pub trait FromVec<T> {
+    /// Convert a `Vec<T>` into the receiver type.
+    fn from_vec(v: Vec<T>) -> Self;
+}
+
+impl<T> FromVec<T> for ~[T] {
+    fn from_vec(mut v: Vec<T>) -> ~[T] {
+        let len = v.len();
+        let data_size = len.checked_mul(&mem::size_of::<T>());
+        let data_size = data_size.expect("overflow in from_vec()");
+        let size = mem::size_of::<RawVec<()>>().checked_add(&data_size);
+        let size = size.expect("overflow in from_vec()");
+
+        // In a post-DST world, we can attempt to reuse the Vec allocation by calling
+        // shrink_to_fit() on it. That may involve a reallocation+memcpy, but that's no
+        // diffrent than what we're doing manually here.
+
+        let vp = v.as_mut_ptr();
+
+        unsafe {
+            let ret = malloc_raw(size) as *mut RawVec<()>;
+
+            (*ret).fill = len * mem::nonzero_size_of::<T>();
+            (*ret).alloc = len * mem::nonzero_size_of::<T>();
+
+            ptr::copy_nonoverlapping_memory(&mut (*ret).data as *mut _ as *mut u8,
+                                            vp as *u8, data_size);
+
+            // we've transferred ownership of the contents from v, but we can't drop it
+            // as it still needs to free its own allocation.
+            v.set_len(0);
+
+            transmute(ret)
+        }
+    }
+}
+
+/// Unsafe operations
+pub mod raw {
+    use super::Vec;
+    use ptr;
+
+    /// Constructs a vector from an unsafe pointer to a buffer.
+    ///
+    /// The elements of the buffer are copied into the vector without cloning,
+    /// as if `ptr::read()` were called on them.
+    #[inline]
+    pub unsafe fn from_buf<T>(ptr: *T, elts: uint) -> Vec<T> {
+        let mut dst = Vec::with_capacity(elts);
+        dst.set_len(elts);
+        ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(), ptr, elts);
+        dst
+    }
+}
+
+
 #[cfg(test)]
 mod tests {
     use prelude::*;
     use mem::size_of;
+    use kinds::marker;
+    use super::{unzip, raw, FromVec};
 
     #[test]
     fn test_small_vec_struct() {
@@ -1649,4 +1744,75 @@ fn zero_sized_values() {
         unsafe { v.set_len(0); }
         assert_eq!(v.mut_iter().len(), 0);
     }
+
+    #[test]
+    fn test_partition() {
+        assert_eq!(vec![].partition(|x: &int| *x < 3), (vec![], vec![]));
+        assert_eq!(vec![1, 2, 3].partition(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
+        assert_eq!(vec![1, 2, 3].partition(|x: &int| *x < 2), (vec![1], vec![2, 3]));
+        assert_eq!(vec![1, 2, 3].partition(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
+    }
+
+    #[test]
+    fn test_partitioned() {
+        assert_eq!(vec![].partitioned(|x: &int| *x < 3), (vec![], vec![]))
+        assert_eq!(vec![1, 2, 3].partitioned(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
+        assert_eq!(vec![1, 2, 3].partitioned(|x: &int| *x < 2), (vec![1], vec![2, 3]));
+        assert_eq!(vec![1, 2, 3].partitioned(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
+    }
+
+    #[test]
+    fn test_zip_unzip() {
+        let z1 = vec![(1, 4), (2, 5), (3, 6)];
+
+        let (left, right) = unzip(z1.iter().map(|&x| x));
+
+        let (left, right) = (left.as_slice(), right.as_slice());
+        assert_eq!((1, 4), (left[0], right[0]));
+        assert_eq!((2, 5), (left[1], right[1]));
+        assert_eq!((3, 6), (left[2], right[2]));
+    }
+
+    #[test]
+    fn test_unsafe_ptrs() {
+        unsafe {
+            // Test on-stack copy-from-buf.
+            let a = [1, 2, 3];
+            let ptr = a.as_ptr();
+            let b = raw::from_buf(ptr, 3u);
+            assert_eq!(b, vec![1, 2, 3]);
+
+            // Test on-heap copy-from-buf.
+            let c = box [1, 2, 3, 4, 5];
+            let ptr = c.as_ptr();
+            let d = raw::from_buf(ptr, 5u);
+            assert_eq!(d, vec![1, 2, 3, 4, 5]);
+        }
+    }
+
+    #[test]
+    fn test_from_vec() {
+        let a = vec![1u, 2, 3];
+        let b: ~[uint] = FromVec::from_vec(a);
+        assert_eq!(b.as_slice(), &[1u, 2, 3]);
+
+        let a = vec![];
+        let b: ~[u8] = FromVec::from_vec(a);
+        assert_eq!(b.as_slice(), &[]);
+
+        let a = vec!["one".to_owned(), "two".to_owned()];
+        let b: ~[~str] = FromVec::from_vec(a);
+        assert_eq!(b.as_slice(), &["one".to_owned(), "two".to_owned()]);
+
+        struct Foo {
+            x: uint,
+            nocopy: marker::NoCopy
+        }
+
+        let a = vec![Foo{x: 42, nocopy: marker::NoCopy}, Foo{x: 84, nocopy: marker::NoCopy}];
+        let b: ~[Foo] = FromVec::from_vec(a);
+        assert_eq!(b.len(), 2);
+        assert_eq!(b[0].x, 42);
+        assert_eq!(b[1].x, 84);
+    }
 }
index a5058de2c61351e884b399e538823a97591b8e6a..391116d2dbcd2aa0f9b53efc2dc8e7d311a39898 100644 (file)
@@ -876,7 +876,6 @@ pub struct FnDecl {
 pub enum FnStyle {
     UnsafeFn, // declared with "unsafe fn"
     NormalFn, // declared with "fn"
-    ExternFn, // declared with "extern fn"
 }
 
 impl fmt::Show for FnStyle {
@@ -884,7 +883,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             NormalFn => "normal".fmt(f),
             UnsafeFn => "unsafe".fmt(f),
-            ExternFn => "extern".fmt(f),
         }
     }
 }
index 865c3be4ae6469c1a5ee0b00b621d1498a8d4a95..333f876e479b168a839df0f575d243b0f0a3f758 100644 (file)
@@ -79,7 +79,7 @@ fn next(&mut self) -> Option<T> {
 /// The type of the iterator used by with_path.
 pub type PathElems<'a, 'b> = iter::Chain<Values<'a, PathElem>, LinkedPath<'b>>;
 
-pub fn path_to_str<PI: Iterator<PathElem>>(mut path: PI) -> ~str {
+pub fn path_to_str<PI: Iterator<PathElem>>(mut path: PI) -> StrBuf {
     let itr = token::get_ident_interner();
 
     path.fold(StrBuf::new(), |mut s, e| {
@@ -89,7 +89,7 @@ pub fn path_to_str<PI: Iterator<PathElem>>(mut path: PI) -> ~str {
         }
         s.push_str(e.as_slice());
         s
-    }).into_owned()
+    }).to_strbuf()
 }
 
 #[deriving(Clone)]
@@ -322,11 +322,11 @@ pub fn with_path<T>(&self, id: NodeId, f: |PathElems| -> T) -> T {
         self.with_path_next(id, None, f)
     }
 
-    pub fn path_to_str(&self, id: NodeId) -> ~str {
+    pub fn path_to_str(&self, id: NodeId) -> StrBuf {
         self.with_path(id, |path| path_to_str(path))
     }
 
-    fn path_to_str_with_ident(&self, id: NodeId, i: Ident) -> ~str {
+    fn path_to_str_with_ident(&self, id: NodeId, i: Ident) -> StrBuf {
         self.with_path(id, |path| {
             path_to_str(path.chain(Some(PathName(i.name)).move_iter()))
         })
@@ -405,7 +405,7 @@ pub fn span(&self, id: NodeId) -> Span {
         }
     }
 
-    pub fn node_to_str(&self, id: NodeId) -> ~str {
+    pub fn node_to_str(&self, id: NodeId) -> StrBuf {
         node_id_to_str(self, id)
     }
 }
@@ -650,7 +650,7 @@ pub fn map_decoded_item<F: FoldOps>(map: &Map,
     ii
 }
 
-fn node_id_to_str(map: &Map, id: NodeId) -> ~str {
+fn node_id_to_str(map: &Map, id: NodeId) -> StrBuf {
     match map.find(id) {
         Some(NodeItem(item)) => {
             let path_str = map.path_to_str_with_ident(id, item.ident);
@@ -666,51 +666,58 @@ fn node_id_to_str(map: &Map, id: NodeId) -> ~str {
                 ItemImpl(..) => "impl",
                 ItemMac(..) => "macro"
             };
-            format!("{} {} (id={})", item_str, path_str, id)
+            (format!("{} {} (id={})", item_str, path_str, id)).to_strbuf()
         }
         Some(NodeForeignItem(item)) => {
             let path_str = map.path_to_str_with_ident(id, item.ident);
-            format!("foreign item {} (id={})", path_str, id)
+            (format!("foreign item {} (id={})", path_str, id)).to_strbuf()
         }
         Some(NodeMethod(m)) => {
-            format!("method {} in {} (id={})",
+            (format!("method {} in {} (id={})",
                     token::get_ident(m.ident),
-                    map.path_to_str(id), id)
+                    map.path_to_str(id), id)).to_strbuf()
         }
         Some(NodeTraitMethod(ref tm)) => {
             let m = ast_util::trait_method_to_ty_method(&**tm);
-            format!("method {} in {} (id={})",
+            (format!("method {} in {} (id={})",
                     token::get_ident(m.ident),
-                    map.path_to_str(id), id)
+                    map.path_to_str(id), id)).to_strbuf()
         }
         Some(NodeVariant(ref variant)) => {
-            format!("variant {} in {} (id={})",
+            (format!("variant {} in {} (id={})",
                     token::get_ident(variant.node.name),
-                    map.path_to_str(id), id)
+                    map.path_to_str(id), id)).to_strbuf()
         }
         Some(NodeExpr(expr)) => {
-            format!("expr {} (id={})", pprust::expr_to_str(expr), id)
+            (format!("expr {} (id={})",
+                    pprust::expr_to_str(expr), id)).to_strbuf()
         }
         Some(NodeStmt(stmt)) => {
-            format!("stmt {} (id={})", pprust::stmt_to_str(stmt), id)
+            (format!("stmt {} (id={})",
+                    pprust::stmt_to_str(stmt), id)).to_strbuf()
         }
         Some(NodeArg(pat)) => {
-            format!("arg {} (id={})", pprust::pat_to_str(pat), id)
+            (format!("arg {} (id={})",
+                    pprust::pat_to_str(pat), id)).to_strbuf()
         }
         Some(NodeLocal(pat)) => {
-            format!("local {} (id={})", pprust::pat_to_str(pat), id)
+            (format!("local {} (id={})",
+                    pprust::pat_to_str(pat), id)).to_strbuf()
         }
         Some(NodeBlock(block)) => {
-            format!("block {} (id={})", pprust::block_to_str(block), id)
+            (format!("block {} (id={})",
+                    pprust::block_to_str(block), id)).to_strbuf()
         }
         Some(NodeStructCtor(_)) => {
-            format!("struct_ctor {} (id={})", map.path_to_str(id), id)
+            (format!("struct_ctor {} (id={})",
+                    map.path_to_str(id), id)).to_strbuf()
         }
         Some(NodeLifetime(ref l)) => {
-            format!("lifetime {} (id={})", pprust::lifetime_to_str(*l), id)
+            (format!("lifetime {} (id={})",
+                    pprust::lifetime_to_str(*l), id)).to_strbuf()
         }
         None => {
-            format!("unknown node (id={})", id)
+            (format!("unknown node (id={})", id)).to_strbuf()
         }
     }
 }
index ee61ce24c30f8521ce63b4a59448889c727059ba..550b6603d5d55e82ed7d738544363fd4960988ec 100644 (file)
 use std::strbuf::StrBuf;
 use std::u32;
 
-pub fn path_name_i(idents: &[Ident]) -> ~str {
+pub fn path_name_i(idents: &[Ident]) -> StrBuf {
     // FIXME: Bad copies (#2543 -- same for everything else that says "bad")
     idents.iter().map(|i| {
-        token::get_ident(*i).get().to_str()
-    }).collect::<Vec<~str>>().connect("::")
+        token::get_ident(*i).get().to_strbuf()
+    }).collect::<Vec<StrBuf>>().connect("::").to_strbuf()
 }
 
 // totally scary function: ignores all but the last element, should have
@@ -134,7 +134,7 @@ pub fn is_path(e: @Expr) -> bool {
 
 // Get a string representation of a signed int type, with its value.
 // We want to avoid "45int" and "-3int" in favor of "45" and "-3"
-pub fn int_ty_to_str(t: IntTy, val: Option<i64>) -> ~str {
+pub fn int_ty_to_str(t: IntTy, val: Option<i64>) -> StrBuf {
     let s = match t {
         TyI if val.is_some() => "",
         TyI => "int",
@@ -145,8 +145,8 @@ pub fn int_ty_to_str(t: IntTy, val: Option<i64>) -> ~str {
     };
 
     match val {
-        Some(n) => format!("{}{}", n, s),
-        None => s.to_owned()
+        Some(n) => format!("{}{}", n, s).to_strbuf(),
+        None => s.to_strbuf()
     }
 }
 
@@ -161,7 +161,7 @@ pub fn int_ty_max(t: IntTy) -> u64 {
 
 // Get a string representation of an unsigned int type, with its value.
 // We want to avoid "42uint" in favor of "42u"
-pub fn uint_ty_to_str(t: UintTy, val: Option<u64>) -> ~str {
+pub fn uint_ty_to_str(t: UintTy, val: Option<u64>) -> StrBuf {
     let s = match t {
         TyU if val.is_some() => "u",
         TyU => "uint",
@@ -172,8 +172,8 @@ pub fn uint_ty_to_str(t: UintTy, val: Option<u64>) -> ~str {
     };
 
     match val {
-        Some(n) => format!("{}{}", n, s),
-        None => s.to_owned()
+        Some(n) => format!("{}{}", n, s).to_strbuf(),
+        None => s.to_strbuf()
     }
 }
 
@@ -186,8 +186,12 @@ pub fn uint_ty_max(t: UintTy) -> u64 {
     }
 }
 
-pub fn float_ty_to_str(t: FloatTy) -> ~str {
-    match t { TyF32 => "f32".to_owned(), TyF64 => "f64".to_owned(), TyF128 => "f128".to_owned() }
+pub fn float_ty_to_str(t: FloatTy) -> StrBuf {
+    match t {
+        TyF32 => "f32".to_strbuf(),
+        TyF64 => "f64".to_strbuf(),
+        TyF128 => "f128".to_strbuf(),
+    }
 }
 
 pub fn is_call_expr(e: @Expr) -> bool {
@@ -252,11 +256,11 @@ pub fn unguarded_pat(a: &Arm) -> Option<Vec<@Pat> > {
 /// listed as `__extensions__::method_name::hash`, with no indication
 /// of the type).
 pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident {
-    let mut pretty = StrBuf::from_owned_str(pprust::ty_to_str(ty));
+    let mut pretty = pprust::ty_to_str(ty);
     match *trait_ref {
         Some(ref trait_ref) => {
             pretty.push_char('.');
-            pretty.push_str(pprust::path_to_str(&trait_ref.path));
+            pretty.push_str(pprust::path_to_str(&trait_ref.path).as_slice());
         }
         None => {}
     }
index 38cdf23b7b305ee4173593b4d4d5a698874faed5..cf5163af7170fd66f5113f8a98f1313bd4b08007 100644 (file)
@@ -125,7 +125,7 @@ fn desugar_doc(&self) -> Attribute {
             let meta = mk_name_value_item_str(
                 InternedString::new("doc"),
                 token::intern_and_get_ident(strip_doc_comment_decoration(
-                        comment.get())));
+                        comment.get()).as_slice()));
             mk_attr(meta)
         } else {
             *self
index b4730ace56d8ec4f672817ec2f7807dac8f11c62..07cf0a61a73e1da380c04a1d4a9006babd85a3dd 100644 (file)
@@ -189,7 +189,7 @@ pub enum MacroFormat {
 pub struct NameAndSpan {
     /// The name of the macro that was invoked to create the thing
     /// with this Span.
-    pub name: ~str,
+    pub name: StrBuf,
     /// The format with which the macro was invoked.
     pub format: MacroFormat,
     /// The span of the macro definition itself. The macro may not
@@ -220,7 +220,7 @@ pub struct ExpnInfo {
     pub callee: NameAndSpan
 }
 
-pub type FileName = ~str;
+pub type FileName = StrBuf;
 
 pub struct FileLines {
     pub file: Rc<FileMap>,
@@ -242,7 +242,7 @@ pub struct FileMap {
     /// e.g. `<anon>`
     pub name: FileName,
     /// The complete source code
-    pub src: ~str,
+    pub src: StrBuf,
     /// The start position of this source in the CodeMap
     pub start_pos: BytePos,
     /// Locations of lines beginnings in the source code
@@ -270,14 +270,14 @@ pub fn next_line(&self, pos: BytePos) {
     }
 
     // get a line from the list of pre-computed line-beginnings
-    pub fn get_line(&self, line: int) -> ~str {
+    pub fn get_line(&self, line: int) -> StrBuf {
         let mut lines = self.lines.borrow_mut();
         let begin: BytePos = *lines.get(line as uint) - self.start_pos;
         let begin = begin.to_uint();
-        let slice = self.src.slice_from(begin);
+        let slice = self.src.as_slice().slice_from(begin);
         match slice.find('\n') {
-            Some(e) => slice.slice_to(e).to_owned(),
-            None => slice.to_owned()
+            Some(e) => slice.slice_to(e).to_strbuf(),
+            None => slice.to_strbuf()
         }
     }
 
@@ -291,7 +291,8 @@ pub fn record_multibyte_char(&self, pos: BytePos, bytes: uint) {
     }
 
     pub fn is_real_file(&self) -> bool {
-        !(self.name.starts_with("<") && self.name.ends_with(">"))
+        !(self.name.as_slice().starts_with("<") &&
+          self.name.as_slice().ends_with(">"))
     }
 }
 
@@ -306,7 +307,7 @@ pub fn new() -> CodeMap {
         }
     }
 
-    pub fn new_filemap(&self, filename: FileName, src: ~str) -> Rc<FileMap> {
+    pub fn new_filemap(&self, filename: FileName, src: StrBuf) -> Rc<FileMap> {
         let mut files = self.files.borrow_mut();
         let start_pos = match files.last() {
             None => 0,
@@ -316,10 +317,10 @@ pub fn new_filemap(&self, filename: FileName, src: ~str) -> Rc<FileMap> {
         // Remove utf-8 BOM if any.
         // FIXME #12884: no efficient/safe way to remove from the start of a string
         // and reuse the allocation.
-        let mut src = if src.starts_with("\ufeff") {
+        let mut src = if src.as_slice().starts_with("\ufeff") {
             StrBuf::from_str(src.as_slice().slice_from(3))
         } else {
-            StrBuf::from_owned_str(src)
+            StrBuf::from_str(src.as_slice())
         };
 
         // Append '\n' in case it's not already there.
@@ -332,7 +333,7 @@ pub fn new_filemap(&self, filename: FileName, src: ~str) -> Rc<FileMap> {
 
         let filemap = Rc::new(FileMap {
             name: filename,
-            src: src.into_owned(),
+            src: src.to_strbuf(),
             start_pos: Pos::from_uint(start_pos),
             lines: RefCell::new(Vec::new()),
             multibyte_chars: RefCell::new(Vec::new()),
@@ -343,9 +344,12 @@ pub fn new_filemap(&self, filename: FileName, src: ~str) -> Rc<FileMap> {
         filemap
     }
 
-    pub fn mk_substr_filename(&self, sp: Span) -> ~str {
+    pub fn mk_substr_filename(&self, sp: Span) -> StrBuf {
         let pos = self.lookup_char_pos(sp.lo);
-        format!("<{}:{}:{}>", pos.file.name, pos.line, pos.col.to_uint() + 1)
+        (format!("<{}:{}:{}>",
+                 pos.file.name,
+                 pos.line,
+                 pos.col.to_uint() + 1)).to_strbuf()
     }
 
     /// Lookup source information about a BytePos
@@ -356,26 +360,30 @@ pub fn lookup_char_pos(&self, pos: BytePos) -> Loc {
     pub fn lookup_char_pos_adj(&self, pos: BytePos) -> LocWithOpt {
         let loc = self.lookup_char_pos(pos);
         LocWithOpt {
-            filename: loc.file.name.to_str(),
+            filename: loc.file.name.to_strbuf(),
             line: loc.line,
             col: loc.col,
             file: Some(loc.file)
         }
     }
 
-    pub fn span_to_str(&self, sp: Span) -> ~str {
+    pub fn span_to_str(&self, sp: Span) -> StrBuf {
         if self.files.borrow().len() == 0 && sp == DUMMY_SP {
-            return "no-location".to_owned();
+            return "no-location".to_strbuf();
         }
 
         let lo = self.lookup_char_pos_adj(sp.lo);
         let hi = self.lookup_char_pos_adj(sp.hi);
-        return format!("{}:{}:{}: {}:{}", lo.filename,
-                       lo.line, lo.col.to_uint() + 1, hi.line, hi.col.to_uint() + 1)
+        return (format!("{}:{}:{}: {}:{}",
+                        lo.filename,
+                        lo.line,
+                        lo.col.to_uint() + 1,
+                        hi.line,
+                        hi.col.to_uint() + 1)).to_strbuf()
     }
 
     pub fn span_to_filename(&self, sp: Span) -> FileName {
-        self.lookup_char_pos(sp.lo).file.name.to_str()
+        self.lookup_char_pos(sp.lo).file.name.to_strbuf()
     }
 
     pub fn span_to_lines(&self, sp: Span) -> FileLines {
@@ -388,7 +396,7 @@ pub fn span_to_lines(&self, sp: Span) -> FileLines {
         FileLines {file: lo.file, lines: lines}
     }
 
-    pub fn span_to_snippet(&self, sp: Span) -> Option<~str> {
+    pub fn span_to_snippet(&self, sp: Span) -> Option<StrBuf> {
         let begin = self.lookup_byte_offset(sp.lo);
         let end = self.lookup_byte_offset(sp.hi);
 
@@ -399,13 +407,14 @@ pub fn span_to_snippet(&self, sp: Span) -> Option<~str> {
         if begin.fm.start_pos != end.fm.start_pos {
             None
         } else {
-            Some(begin.fm.src.slice( begin.pos.to_uint(), end.pos.to_uint()).to_owned())
+            Some(begin.fm.src.as_slice().slice(begin.pos.to_uint(),
+                                               end.pos.to_uint()).to_strbuf())
         }
     }
 
     pub fn get_filemap(&self, filename: &str) -> Rc<FileMap> {
         for fm in self.files.borrow().iter() {
-            if filename == fm.name {
+            if filename == fm.name.as_slice() {
                 return fm.clone();
             }
         }
@@ -526,19 +535,21 @@ mod test {
     #[test]
     fn t1 () {
         let cm = CodeMap::new();
-        let fm = cm.new_filemap("blork.rs".to_owned(),"first line.\nsecond line".to_owned());
+        let fm = cm.new_filemap("blork.rs".to_strbuf(),
+                                "first line.\nsecond line".to_strbuf());
         fm.next_line(BytePos(0));
-        assert_eq!(&fm.get_line(0),&"first line.".to_owned());
+        assert_eq!(&fm.get_line(0),&"first line.".to_strbuf());
         // TESTING BROKEN BEHAVIOR:
         fm.next_line(BytePos(10));
-        assert_eq!(&fm.get_line(1),&".".to_owned());
+        assert_eq!(&fm.get_line(1), &".".to_strbuf());
     }
 
     #[test]
     #[should_fail]
     fn t2 () {
         let cm = CodeMap::new();
-        let fm = cm.new_filemap("blork.rs".to_owned(),"first line.\nsecond line".to_owned());
+        let fm = cm.new_filemap("blork.rs".to_strbuf(),
+                                "first line.\nsecond line".to_strbuf());
         // TESTING *REALLY* BROKEN BEHAVIOR:
         fm.next_line(BytePos(0));
         fm.next_line(BytePos(10));
@@ -547,9 +558,12 @@ fn t2 () {
 
     fn init_code_map() -> CodeMap {
         let cm = CodeMap::new();
-        let fm1 = cm.new_filemap("blork.rs".to_owned(),"first line.\nsecond line".to_owned());
-        let fm2 = cm.new_filemap("empty.rs".to_owned(),"".to_owned());
-        let fm3 = cm.new_filemap("blork2.rs".to_owned(),"first line.\nsecond line".to_owned());
+        let fm1 = cm.new_filemap("blork.rs".to_strbuf(),
+                                 "first line.\nsecond line".to_strbuf());
+        let fm2 = cm.new_filemap("empty.rs".to_strbuf(),
+                                 "".to_strbuf());
+        let fm3 = cm.new_filemap("blork2.rs".to_strbuf(),
+                                 "first line.\nsecond line".to_strbuf());
 
         fm1.next_line(BytePos(0));
         fm1.next_line(BytePos(12));
@@ -566,11 +580,11 @@ fn t3() {
         let cm = init_code_map();
 
         let fmabp1 = cm.lookup_byte_offset(BytePos(22));
-        assert_eq!(fmabp1.fm.name, "blork.rs".to_owned());
+        assert_eq!(fmabp1.fm.name, "blork.rs".to_strbuf());
         assert_eq!(fmabp1.pos, BytePos(22));
 
         let fmabp2 = cm.lookup_byte_offset(BytePos(24));
-        assert_eq!(fmabp2.fm.name, "blork2.rs".to_owned());
+        assert_eq!(fmabp2.fm.name, "blork2.rs".to_strbuf());
         assert_eq!(fmabp2.pos, BytePos(0));
     }
 
@@ -592,12 +606,12 @@ fn t5() {
         let cm = init_code_map();
 
         let loc1 = cm.lookup_char_pos(BytePos(22));
-        assert_eq!(loc1.file.name, "blork.rs".to_owned());
+        assert_eq!(loc1.file.name, "blork.rs".to_strbuf());
         assert_eq!(loc1.line, 2);
         assert_eq!(loc1.col, CharPos(10));
 
         let loc2 = cm.lookup_char_pos(BytePos(24));
-        assert_eq!(loc2.file.name, "blork2.rs".to_owned());
+        assert_eq!(loc2.file.name, "blork2.rs".to_strbuf());
         assert_eq!(loc2.line, 1);
         assert_eq!(loc2.col, CharPos(0));
     }
@@ -605,8 +619,11 @@ fn t5() {
     fn init_code_map_mbc() -> CodeMap {
         let cm = CodeMap::new();
         // € is a three byte utf8 char.
-        let fm1 = cm.new_filemap("blork.rs".to_owned(),"fir€st €€€€ line.\nsecond line".to_owned());
-        let fm2 = cm.new_filemap("blork2.rs".to_owned(),"first line€€.\n€ second line".to_owned());
+        let fm1 =
+            cm.new_filemap("blork.rs".to_strbuf(),
+                           "fir€st €€€€ line.\nsecond line".to_strbuf());
+        let fm2 = cm.new_filemap("blork2.rs".to_strbuf(),
+                                 "first line€€.\n€ second line".to_strbuf());
 
         fm1.next_line(BytePos(0));
         fm1.next_line(BytePos(22));
@@ -650,7 +667,7 @@ fn t7() {
         let span = Span {lo: BytePos(12), hi: BytePos(23), expn_info: None};
         let file_lines = cm.span_to_lines(span);
 
-        assert_eq!(file_lines.file.name, "blork.rs".to_owned());
+        assert_eq!(file_lines.file.name, "blork.rs".to_strbuf());
         assert_eq!(file_lines.lines.len(), 1);
         assert_eq!(*file_lines.lines.get(0), 1u);
     }
@@ -662,7 +679,7 @@ fn t8() {
         let span = Span {lo: BytePos(12), hi: BytePos(23), expn_info: None};
         let snippet = cm.span_to_snippet(span);
 
-        assert_eq!(snippet, Some("second line".to_owned()));
+        assert_eq!(snippet, Some("second line".to_strbuf()));
     }
 
     #[test]
@@ -672,6 +689,6 @@ fn t9() {
         let span = Span {lo: BytePos(12), hi: BytePos(23), expn_info: None};
         let sstr =  cm.span_to_str(span);
 
-        assert_eq!(sstr, "blork.rs:2:1: 2:12".to_owned());
+        assert_eq!(sstr, "blork.rs:2:1: 2:12".to_strbuf());
     }
 }
index 61c6af62768be12c96c2da82256ffa02cda2063f..84ef7941b2ed7546d65a671b5bd7306e3c04fec2 100644 (file)
 pub struct CrateId {
     /// A path which represents the codes origin. By convention this is the
     /// URL, without `http://` or `https://` prefix, to the crate's repository
-    pub path: ~str,
+    pub path: StrBuf,
     /// The name of the crate.
-    pub name: ~str,
+    pub name: StrBuf,
     /// The version of the crate.
-    pub version: Option<~str>,
+    pub version: Option<StrBuf>,
 }
 
 impl fmt::Show for CrateId {
@@ -38,7 +38,8 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             None => "0.0",
             Some(ref version) => version.as_slice(),
         };
-        if self.path == self.name || self.path.ends_with(format!("/{}", self.name)) {
+        if self.path == self.name ||
+                self.path.as_slice().ends_with(format!("/{}", self.name)) {
             write!(f.buf, "\\#{}", version)
         } else {
             write!(f.buf, "\\#{}:{}", self.name, version)
@@ -60,7 +61,7 @@ fn from_str(s: &str) -> Option<CrateId> {
         let inferred_name = *path_pieces.get(0);
 
         let (name, version) = if pieces.len() == 1 {
-            (inferred_name.to_owned(), None)
+            (inferred_name.to_strbuf(), None)
         } else {
             let hash_pieces: Vec<&str> = pieces.get(1)
                                                .splitn(':', 1)
@@ -72,16 +73,16 @@ fn from_str(s: &str) -> Option<CrateId> {
             };
 
             let name = if !hash_name.is_empty() {
-                hash_name.to_owned()
+                hash_name.to_strbuf()
             } else {
-                inferred_name.to_owned()
+                inferred_name.to_strbuf()
             };
 
             let version = if !hash_version.is_empty() {
                 if hash_version == "0.0" {
                     None
                 } else {
-                    Some(hash_version.to_owned())
+                    Some(hash_version.to_strbuf())
                 }
             } else {
                 None
@@ -91,7 +92,7 @@ fn from_str(s: &str) -> Option<CrateId> {
         };
 
         Some(CrateId {
-            path: path.clone(),
+            path: path.to_strbuf(),
             name: name,
             version: version,
         })
@@ -106,8 +107,8 @@ pub fn version_or_default<'a>(&'a self) -> &'a str {
         }
     }
 
-    pub fn short_name_with_version(&self) -> ~str {
-        format!("{}-{}", self.name, self.version_or_default())
+    pub fn short_name_with_version(&self) -> StrBuf {
+        (format!("{}-{}", self.name, self.version_or_default())).to_strbuf()
     }
 
     pub fn matches(&self, other: &CrateId) -> bool {
@@ -123,17 +124,17 @@ pub fn matches(&self, other: &CrateId) -> bool {
 #[test]
 fn bare_name() {
     let crateid: CrateId = from_str("foo").expect("valid crateid");
-    assert_eq!(crateid.name, "foo".to_owned());
+    assert_eq!(crateid.name, "foo".to_strbuf());
     assert_eq!(crateid.version, None);
-    assert_eq!(crateid.path, "foo".to_owned());
+    assert_eq!(crateid.path, "foo".to_strbuf());
 }
 
 #[test]
 fn bare_name_single_char() {
     let crateid: CrateId = from_str("f").expect("valid crateid");
-    assert_eq!(crateid.name, "f".to_owned());
+    assert_eq!(crateid.name, "f".to_strbuf());
     assert_eq!(crateid.version, None);
-    assert_eq!(crateid.path, "f".to_owned());
+    assert_eq!(crateid.path, "f".to_strbuf());
 }
 
 #[test]
@@ -145,17 +146,17 @@ fn empty_crateid() {
 #[test]
 fn simple_path() {
     let crateid: CrateId = from_str("example.com/foo/bar").expect("valid crateid");
-    assert_eq!(crateid.name, "bar".to_owned());
+    assert_eq!(crateid.name, "bar".to_strbuf());
     assert_eq!(crateid.version, None);
-    assert_eq!(crateid.path, "example.com/foo/bar".to_owned());
+    assert_eq!(crateid.path, "example.com/foo/bar".to_strbuf());
 }
 
 #[test]
 fn simple_version() {
     let crateid: CrateId = from_str("foo#1.0").expect("valid crateid");
-    assert_eq!(crateid.name, "foo".to_owned());
-    assert_eq!(crateid.version, Some("1.0".to_owned()));
-    assert_eq!(crateid.path, "foo".to_owned());
+    assert_eq!(crateid.name, "foo".to_strbuf());
+    assert_eq!(crateid.version, Some("1.0".to_strbuf()));
+    assert_eq!(crateid.path, "foo".to_strbuf());
 }
 
 #[test]
@@ -173,39 +174,39 @@ fn path_ends_with_slash() {
 #[test]
 fn path_and_version() {
     let crateid: CrateId = from_str("example.com/foo/bar#1.0").expect("valid crateid");
-    assert_eq!(crateid.name, "bar".to_owned());
-    assert_eq!(crateid.version, Some("1.0".to_owned()));
-    assert_eq!(crateid.path, "example.com/foo/bar".to_owned());
+    assert_eq!(crateid.name, "bar".to_strbuf());
+    assert_eq!(crateid.version, Some("1.0".to_strbuf()));
+    assert_eq!(crateid.path, "example.com/foo/bar".to_strbuf());
 }
 
 #[test]
 fn single_chars() {
     let crateid: CrateId = from_str("a/b#1").expect("valid crateid");
-    assert_eq!(crateid.name, "b".to_owned());
-    assert_eq!(crateid.version, Some("1".to_owned()));
-    assert_eq!(crateid.path, "a/b".to_owned());
+    assert_eq!(crateid.name, "b".to_strbuf());
+    assert_eq!(crateid.version, Some("1".to_strbuf()));
+    assert_eq!(crateid.path, "a/b".to_strbuf());
 }
 
 #[test]
 fn missing_version() {
     let crateid: CrateId = from_str("foo#").expect("valid crateid");
-    assert_eq!(crateid.name, "foo".to_owned());
+    assert_eq!(crateid.name, "foo".to_strbuf());
     assert_eq!(crateid.version, None);
-    assert_eq!(crateid.path, "foo".to_owned());
+    assert_eq!(crateid.path, "foo".to_strbuf());
 }
 
 #[test]
 fn path_and_name() {
     let crateid: CrateId = from_str("foo/rust-bar#bar:1.0").expect("valid crateid");
-    assert_eq!(crateid.name, "bar".to_owned());
-    assert_eq!(crateid.version, Some("1.0".to_owned()));
-    assert_eq!(crateid.path, "foo/rust-bar".to_owned());
+    assert_eq!(crateid.name, "bar".to_strbuf());
+    assert_eq!(crateid.version, Some("1.0".to_strbuf()));
+    assert_eq!(crateid.path, "foo/rust-bar".to_strbuf());
 }
 
 #[test]
 fn empty_name() {
     let crateid: CrateId = from_str("foo/bar#:1.0").expect("valid crateid");
-    assert_eq!(crateid.name, "bar".to_owned());
-    assert_eq!(crateid.version, Some("1.0".to_owned()));
-    assert_eq!(crateid.path, "foo/bar".to_owned());
+    assert_eq!(crateid.name, "bar".to_strbuf());
+    assert_eq!(crateid.version, Some("1.0".to_strbuf()));
+    assert_eq!(crateid.path, "foo/bar".to_strbuf());
 }
index ee03046b6d6897b893ee375e65d002af9c57ddc1..73027013090e72202197501c31d43db5dd7bc6b8 100644 (file)
@@ -320,12 +320,12 @@ fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan,
         // the span)
         let span_end = Span { lo: sp.hi, hi: sp.hi, expn_info: sp.expn_info};
         let ses = cm.span_to_str(span_end);
-        try!(print_diagnostic(dst, ses, lvl, msg));
+        try!(print_diagnostic(dst, ses.as_slice(), lvl, msg));
         if rsp.is_full_span() {
             try!(custom_highlight_lines(dst, cm, sp, lvl, lines));
         }
     } else {
-        try!(print_diagnostic(dst, ss, lvl, msg));
+        try!(print_diagnostic(dst, ss.as_slice(), lvl, msg));
         if rsp.is_full_span() {
             try!(highlight_lines(dst, cm, sp, lvl, lines));
         }
@@ -378,7 +378,7 @@ fn highlight_lines(err: &mut EmitterWriter,
         }
         let orig = fm.get_line(*lines.lines.get(0) as int);
         for pos in range(0u, left-skip) {
-            let cur_char = orig[pos] as char;
+            let cur_char = orig.as_slice()[pos] as char;
             // Whenever a tab occurs on the previous line, we insert one on
             // the error-point-squiggly-line as well (instead of a space).
             // That way the squiggly line will usually appear in the correct
@@ -452,24 +452,28 @@ fn print_macro_backtrace(w: &mut EmitterWriter,
                          sp: Span)
                          -> io::IoResult<()> {
     for ei in sp.expn_info.iter() {
-        let ss = ei.callee.span.as_ref().map_or("".to_owned(), |span| cm.span_to_str(*span));
+        let ss = ei.callee
+                   .span
+                   .as_ref()
+                   .map_or("".to_strbuf(), |span| cm.span_to_str(*span));
         let (pre, post) = match ei.callee.format {
             codemap::MacroAttribute => ("#[", "]"),
             codemap::MacroBang => ("", "!")
         };
-        try!(print_diagnostic(w, ss, Note,
+        try!(print_diagnostic(w, ss.as_slice(), Note,
                               format!("in expansion of {}{}{}", pre,
                                       ei.callee.name, post)));
         let ss = cm.span_to_str(ei.call_site);
-        try!(print_diagnostic(w, ss, Note, "expansion site"));
+        try!(print_diagnostic(w, ss.as_slice(), Note, "expansion site"));
         try!(print_macro_backtrace(w, cm, ei.call_site));
     }
     Ok(())
 }
 
-pub fn expect<T:Clone>(diag: &SpanHandler, opt: Option<T>, msg: || -> ~str) -> T {
+pub fn expect<T:Clone>(diag: &SpanHandler, opt: Option<T>, msg: || -> StrBuf)
+              -> T {
     match opt {
        Some(ref t) => (*t).clone(),
-       None => diag.handler().bug(msg()),
+       None => diag.handler().bug(msg().as_slice()),
     }
 }
index 01ec4c84b683ec4b723f452827c2ca57d19f8f96..f4330960acacb3e20d113b47916195231d865681 100644 (file)
@@ -30,7 +30,7 @@
 // ast::MacInvocTT.
 
 pub struct MacroDef {
-    pub name: ~str,
+    pub name: StrBuf,
     pub ext: SyntaxExtension
 }
 
@@ -361,8 +361,8 @@ fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
 
 pub struct MacroCrate {
     pub lib: Option<Path>,
-    pub macros: Vec<~str>,
-    pub registrar_symbol: Option<~str>,
+    pub macros: Vec<StrBuf>,
+    pub registrar_symbol: Option<StrBuf>,
 }
 
 pub trait CrateLoader {
@@ -425,7 +425,7 @@ pub fn backtrace(&self) -> Option<@ExpnInfo> { self.backtrace }
     pub fn mod_pop(&mut self) { self.mod_path.pop().unwrap(); }
     pub fn mod_path(&self) -> Vec<ast::Ident> {
         let mut v = Vec::new();
-        v.push(token::str_to_ident(self.ecfg.crate_id.name));
+        v.push(token::str_to_ident(self.ecfg.crate_id.name.as_slice()));
         v.extend(self.mod_path.iter().map(|a| *a));
         return v;
     }
@@ -540,14 +540,14 @@ pub fn get_single_str_from_tts(cx: &ExtCtxt,
                                sp: Span,
                                tts: &[ast::TokenTree],
                                name: &str)
-                               -> Option<~str> {
+                               -> Option<StrBuf> {
     if tts.len() != 1 {
         cx.span_err(sp, format!("{} takes 1 argument.", name));
     } else {
         match tts[0] {
             ast::TTTok(_, token::LIT_STR(ident))
             | ast::TTTok(_, token::LIT_STR_RAW(ident, _)) => {
-                return Some(token::get_ident(ident).get().to_str())
+                return Some(token::get_ident(ident).get().to_strbuf())
             }
             _ => cx.span_err(sp, format!("{} requires a string.", name)),
         }
index 457cb4b79bf94d3c1f0bfc0994e526717fd2bbae..3c7415ae0e9b9fe0a81bf116ed173ba26aae260b 100644 (file)
@@ -639,7 +639,9 @@ fn expr_fail(&self, span: Span, msg: InternedString) -> @ast::Expr {
             vec!(
                 self.expr_str(span, msg),
                 self.expr_str(span,
-                              token::intern_and_get_ident(loc.file.name)),
+                              token::intern_and_get_ident(loc.file
+                                                             .name
+                                                             .as_slice())),
                 self.expr_uint(span, loc.line)))
     }
 
index a3f9eaee892e73716b270af89ca7fea839f3ea5d..9c967cfb4eeaabb47d1cdf24387706c67af2ff41 100644 (file)
@@ -987,7 +987,7 @@ fn set_expn_info(&self,
         to_set.expn_info = Some(@codemap::ExpnInfo {
             call_site: to_set,
             callee: codemap::NameAndSpan {
-                name: format!("deriving({})", trait_name),
+                name: format!("deriving({})", trait_name).to_strbuf(),
                 format: codemap::MacroAttribute,
                 span: Some(self.span)
             }
index ea3fef352be67c4c19bb07c97df621cde6745988..8dbfbc53cecf73b4bbdfd86598b74207dd798adc 100644 (file)
@@ -30,7 +30,7 @@ pub fn expand_option_env(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
         Some(v) => v
     };
 
-    let e = match os::getenv(var) {
+    let e = match os::getenv(var.as_slice()) {
       None => {
           cx.expr_path(cx.path_all(sp,
                                    true,
index 0dc62728e5c95344838382d457281640c9d79b5d..0f3b96c2132b6ce65b85081f119d4d435ede885f 100644 (file)
@@ -71,7 +71,7 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
                             fld.cx.bt_push(ExpnInfo {
                                 call_site: e.span,
                                 callee: NameAndSpan {
-                                    name: extnamestr.get().to_str(),
+                                    name: extnamestr.get().to_strbuf(),
                                     format: MacroBang,
                                     span: exp_span,
                                 },
@@ -270,7 +270,7 @@ pub fn expand_item(it: @ast::Item, fld: &mut MacroExpander)
                 fld.cx.bt_push(ExpnInfo {
                     call_site: attr.span,
                     callee: NameAndSpan {
-                        name: mname.get().to_str(),
+                        name: mname.get().to_strbuf(),
                         format: MacroAttribute,
                         span: None
                     }
@@ -334,7 +334,7 @@ fn expand_item_modifiers(mut it: @ast::Item, fld: &mut MacroExpander)
                 fld.cx.bt_push(ExpnInfo {
                     call_site: attr.span,
                     callee: NameAndSpan {
-                        name: mname.get().to_str(),
+                        name: mname.get().to_strbuf(),
                         format: MacroAttribute,
                         span: None,
                     }
@@ -393,7 +393,7 @@ pub fn expand_item_mac(it: @ast::Item, fld: &mut MacroExpander)
             fld.cx.bt_push(ExpnInfo {
                 call_site: it.span,
                 callee: NameAndSpan {
-                    name: extnamestr.get().to_str(),
+                    name: extnamestr.get().to_strbuf(),
                     format: MacroBang,
                     span: span
                 }
@@ -412,7 +412,7 @@ pub fn expand_item_mac(it: @ast::Item, fld: &mut MacroExpander)
             fld.cx.bt_push(ExpnInfo {
                 call_site: it.span,
                 callee: NameAndSpan {
-                    name: extnamestr.get().to_str(),
+                    name: extnamestr.get().to_strbuf(),
                     format: MacroBang,
                     span: span
                 }
@@ -433,7 +433,7 @@ pub fn expand_item_mac(it: @ast::Item, fld: &mut MacroExpander)
         Some(MacroDef { name, ext }) => {
             // yikes... no idea how to apply the mark to this. I'm afraid
             // we're going to have to wait-and-see on this one.
-            fld.extsbox.insert(intern(name), ext);
+            fld.extsbox.insert(intern(name.as_slice()), ext);
             if attr::contains_name(it.attrs.as_slice(), "macro_export") {
                 SmallVector::one(it)
             } else {
@@ -493,6 +493,7 @@ fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) {
         _ => unreachable!()
     };
     let name = format!("<{} macros>", token::get_ident(crate_name));
+    let name = name.to_strbuf();
 
     for source in macros.iter() {
         let item = parse::parse_item_from_source_str(name.clone(),
@@ -524,11 +525,12 @@ fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) {
     };
 
     unsafe {
-        let registrar: MacroCrateRegistrationFun = match lib.symbol(registrar) {
-            Ok(registrar) => registrar,
-            // again fatal if we can't register macros
-            Err(err) => fld.cx.span_fatal(krate.span, err)
-        };
+        let registrar: MacroCrateRegistrationFun =
+            match lib.symbol(registrar.as_slice()) {
+                Ok(registrar) => registrar,
+                // again fatal if we can't register macros
+                Err(err) => fld.cx.span_fatal(krate.span, err)
+            };
         registrar(|name, extension| {
             let extension = match extension {
                 NormalTT(ext, _) => NormalTT(ext, Some(krate.span)),
@@ -576,7 +578,7 @@ pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<@Stmt> {
             fld.cx.bt_push(ExpnInfo {
                 call_site: s.span,
                 callee: NameAndSpan {
-                    name: extnamestr.get().to_str(),
+                    name: extnamestr.get().to_strbuf(),
                     format: MacroBang,
                     span: exp_span,
                 }
@@ -1020,10 +1022,10 @@ fn load_crate(&mut self, _: &ast::ViewItem) -> MacroCrate {
     #[should_fail]
     #[test] fn macros_cant_escape_fns_test () {
         let src = "fn bogus() {macro_rules! z (() => (3+4))}\
-                   fn inty() -> int { z!() }".to_owned();
+                   fn inty() -> int { z!() }".to_strbuf();
         let sess = parse::new_parse_sess();
         let crate_ast = parse::parse_crate_from_source_str(
-            "<test>".to_owned(),
+            "<test>".to_strbuf(),
             src,
             Vec::new(), &sess);
         // should fail:
@@ -1040,10 +1042,10 @@ fn load_crate(&mut self, _: &ast::ViewItem) -> MacroCrate {
     #[should_fail]
     #[test] fn macros_cant_escape_mods_test () {
         let src = "mod foo {macro_rules! z (() => (3+4))}\
-                   fn inty() -> int { z!() }".to_owned();
+                   fn inty() -> int { z!() }".to_strbuf();
         let sess = parse::new_parse_sess();
         let crate_ast = parse::parse_crate_from_source_str(
-            "<test>".to_owned(),
+            "<test>".to_strbuf(),
             src,
             Vec::new(), &sess);
         // should fail:
@@ -1059,10 +1061,10 @@ fn load_crate(&mut self, _: &ast::ViewItem) -> MacroCrate {
     // macro_escape modules shouldn't cause macros to leave scope
     #[test] fn macros_can_escape_flattened_mods_test () {
         let src = "#[macro_escape] mod foo {macro_rules! z (() => (3+4))}\
-                   fn inty() -> int { z!() }".to_owned();
+                   fn inty() -> int { z!() }".to_strbuf();
         let sess = parse::new_parse_sess();
         let crate_ast = parse::parse_crate_from_source_str(
-            "<test>".to_owned(),
+            "<test>".to_strbuf(),
             src,
             Vec::new(), &sess);
         // should fail:
@@ -1100,7 +1102,7 @@ fn make_dummy_attr(s: &str) -> ast::Attribute {
         }
     }
 
-    fn expand_crate_str(crate_str: ~str) -> ast::Crate {
+    fn expand_crate_str(crate_str: StrBuf) -> ast::Crate {
         let ps = parse::new_parse_sess();
         let crate_ast = string_to_parser(&ps, crate_str).parse_crate_mod();
         // the cfg argument actually does matter, here...
@@ -1118,13 +1120,14 @@ fn expand_crate_str(crate_str: ~str) -> ast::Crate {
         // println!("expanded: {:?}\n",expanded_ast);
         //mtwt_resolve_crate(expanded_ast)
     //}
-    //fn expand_and_resolve_and_pretty_print (crate_str: @str) -> ~str {
+    //fn expand_and_resolve_and_pretty_print (crate_str: @str) -> StrBuf {
         //let resolved_ast = expand_and_resolve(crate_str);
         //pprust::to_str(&resolved_ast,fake_print_crate,get_ident_interner())
     //}
 
     #[test] fn macro_tokens_should_match(){
-        expand_crate_str("macro_rules! m((a)=>(13)) fn main(){m!(a);}".to_owned());
+        expand_crate_str(
+            "macro_rules! m((a)=>(13)) fn main(){m!(a);}".to_strbuf());
     }
 
     // renaming tests expand a crate and then check that the bindings match
@@ -1182,7 +1185,7 @@ fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
         let (teststr, bound_connections, bound_ident_check) = match *t {
             (ref str,ref conns, bic) => (str.to_owned(), conns.clone(), bic)
         };
-        let cr = expand_crate_str(teststr.to_owned());
+        let cr = expand_crate_str(teststr.to_strbuf());
         // find the bindings:
         let mut name_finder = new_name_finder(Vec::new());
         visit::walk_crate(&mut name_finder,&cr,());
@@ -1257,7 +1260,7 @@ fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
         let crate_str = "macro_rules! fmt_wrap(($b:expr)=>($b.to_str()))
 macro_rules! foo_module (() => (mod generated { fn a() { let xx = 147; fmt_wrap!(xx);}}))
 foo_module!()
-".to_owned();
+".to_strbuf();
         let cr = expand_crate_str(crate_str);
         // find the xx binding
         let mut name_finder = new_name_finder(Vec::new());
@@ -1303,7 +1306,8 @@ fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
 
     #[test]
     fn pat_idents(){
-        let pat = string_to_pat("(a,Foo{x:c @ (b,9),y:Bar(4,d)})".to_owned());
+        let pat = string_to_pat(
+            "(a,Foo{x:c @ (b,9),y:Bar(4,d)})".to_strbuf());
         let mut pat_idents = new_name_finder(Vec::new());
         pat_idents.visit_pat(pat, ());
         assert_eq!(pat_idents.ident_accumulator,
index fc3136996ae10afea89720d1447e76754cefd2fe..c03d174365ed5fb94cd301d8bd99e95c577a596b 100644 (file)
 use parse::token;
 use rsparse = parse;
 
-use std::fmt::parse;
+use parse = fmt_macros;
 use collections::{HashMap, HashSet};
 
 #[deriving(Eq)]
 enum ArgumentType {
-    Known(~str),
+    Known(StrBuf),
     Unsigned,
     String,
 }
 
 enum Position {
     Exact(uint),
-    Named(~str),
+    Named(StrBuf),
 }
 
 struct Context<'a, 'b> {
@@ -45,13 +45,13 @@ struct Context<'a, 'b> {
     // Note that we keep a side-array of the ordering of the named arguments
     // found to be sure that we can translate them in the same order that they
     // were declared in.
-    names: HashMap<~str, @ast::Expr>,
-    name_types: HashMap<~str, ArgumentType>,
-    name_ordering: Vec<~str>,
+    names: HashMap<StrBuf, @ast::Expr>,
+    name_types: HashMap<StrBuf, ArgumentType>,
+    name_ordering: Vec<StrBuf>,
 
     // Collection of the compiled `rt::Piece` structures
     pieces: Vec<@ast::Expr> ,
-    name_positions: HashMap<~str, uint>,
+    name_positions: HashMap<StrBuf, uint>,
     method_statics: Vec<@ast::Item> ,
 
     // Updated as arguments are consumed or methods are entered
@@ -68,10 +68,10 @@ struct Context<'a, 'b> {
 ///     Some((fmtstr, unnamed arguments, ordering of named arguments,
 ///           named arguments))
 fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-    -> (@ast::Expr, Option<(@ast::Expr, Vec<@ast::Expr>, Vec<~str>,
-                            HashMap<~str, @ast::Expr>)>) {
+    -> (@ast::Expr, Option<(@ast::Expr, Vec<@ast::Expr>, Vec<StrBuf>,
+                            HashMap<StrBuf, @ast::Expr>)>) {
     let mut args = Vec::new();
-    let mut names = HashMap::<~str, @ast::Expr>::new();
+    let mut names = HashMap::<StrBuf, @ast::Expr>::new();
     let mut order = Vec::new();
 
     let mut p = rsparse::new_parser_from_tts(ecx.parse_sess(),
@@ -131,8 +131,8 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                     continue
                 }
             }
-            order.push(name.to_str());
-            names.insert(name.to_str(), e);
+            order.push(name.to_strbuf());
+            names.insert(name.to_strbuf(), e);
         } else {
             args.push(p.parse_expr());
         }
@@ -171,13 +171,13 @@ fn verify_piece(&mut self, p: &parse::Piece) {
                         Exact(i)
                     }
                     parse::ArgumentIs(i) => Exact(i),
-                    parse::ArgumentNamed(s) => Named(s.to_str()),
+                    parse::ArgumentNamed(s) => Named(s.to_strbuf()),
                 };
 
                 // and finally the method being applied
                 match arg.method {
                     None => {
-                        let ty = Known(arg.format.ty.to_str());
+                        let ty = Known(arg.format.ty.to_strbuf());
                         self.verify_arg_type(pos, ty);
                     }
                     Some(ref method) => { self.verify_method(pos, *method); }
@@ -199,7 +199,7 @@ fn verify_count(&mut self, c: parse::Count) {
                 self.verify_arg_type(Exact(i), Unsigned);
             }
             parse::CountIsName(s) => {
-                self.verify_arg_type(Named(s.to_str()), Unsigned);
+                self.verify_arg_type(Named(s.to_strbuf()), Unsigned);
             }
             parse::CountIsNextParam => {
                 if self.check_positional_ok() {
@@ -232,7 +232,7 @@ fn verify_method(&mut self, pos: Position, m: &parse::Method) {
                             parse::Keyword(name) => {
                                 self.ecx.span_err(self.fmtsp,
                                                   format!("duplicate selector \
-                                                           `{:?}`", name));
+                                                           `{}`", name));
                             }
                             parse::Literal(idx) => {
                                 self.ecx.span_err(self.fmtsp,
@@ -375,21 +375,11 @@ fn static_attrs(&self) -> Vec<ast::Attribute> {
         return vec!(unnamed, allow_dead_code);
     }
 
-    fn parsepath(&self, s: &str) -> Vec<ast::Ident> {
-        vec!(self.ecx.ident_of("std"), self.ecx.ident_of("fmt"),
-          self.ecx.ident_of("parse"), self.ecx.ident_of(s))
-    }
-
     fn rtpath(&self, s: &str) -> Vec<ast::Ident> {
         vec!(self.ecx.ident_of("std"), self.ecx.ident_of("fmt"),
           self.ecx.ident_of("rt"), self.ecx.ident_of(s))
     }
 
-    fn ctpath(&self, s: &str) -> Vec<ast::Ident> {
-        vec!(self.ecx.ident_of("std"), self.ecx.ident_of("fmt"),
-          self.ecx.ident_of("parse"), self.ecx.ident_of(s))
-    }
-
     fn none(&self) -> @ast::Expr {
         let none = self.ecx.path_global(self.fmtsp, vec!(
                 self.ecx.ident_of("std"),
@@ -475,7 +465,7 @@ fn trans_method(&mut self, method: &parse::Method) -> @ast::Expr {
                             }).collect();
                         let (lr, selarg) = match arm.selector {
                             parse::Keyword(t) => {
-                                let p = self.ctpath(format!("{:?}", t));
+                                let p = self.rtpath(t.to_str());
                                 let p = self.ecx.path_global(sp, p);
                                 (self.rtpath("Keyword"), self.ecx.expr_path(p))
                             }
@@ -564,13 +554,13 @@ fn trans_piece(&mut self, piece: &parse::Piece) -> @ast::Expr {
                 let fill = self.ecx.expr_lit(sp, ast::LitChar(fill));
                 let align = match arg.format.align {
                     parse::AlignLeft => {
-                        self.ecx.path_global(sp, self.parsepath("AlignLeft"))
+                        self.ecx.path_global(sp, self.rtpath("AlignLeft"))
                     }
                     parse::AlignRight => {
-                        self.ecx.path_global(sp, self.parsepath("AlignRight"))
+                        self.ecx.path_global(sp, self.rtpath("AlignRight"))
                     }
                     parse::AlignUnknown => {
-                        self.ecx.path_global(sp, self.parsepath("AlignUnknown"))
+                        self.ecx.path_global(sp, self.rtpath("AlignUnknown"))
                     }
                 };
                 let align = self.ecx.expr_path(align);
@@ -822,8 +812,8 @@ pub fn expand_args(ecx: &mut ExtCtxt, sp: Span,
 pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
                                     extra: @ast::Expr,
                                     efmt: @ast::Expr, args: Vec<@ast::Expr>,
-                                    name_ordering: Vec<~str>,
-                                    names: HashMap<~str, @ast::Expr>) -> @ast::Expr {
+                                    name_ordering: Vec<StrBuf>,
+                                    names: HashMap<StrBuf, @ast::Expr>) -> @ast::Expr {
     let arg_types = Vec::from_fn(args.len(), |_| None);
     let mut cx = Context {
         ecx: ecx,
index 4ae9d43697218a2650d6a2254a53334b0506671e..6ac3becf0b68dc2030ca0c2c404e059eca72b246 100644 (file)
@@ -18,7 +18,6 @@
 use ast::{Ident, Mrk, Name, SyntaxContext};
 
 use std::cell::RefCell;
-use std::local_data;
 use std::rc::Rc;
 
 use collections::HashMap;
@@ -91,17 +90,14 @@ fn new_rename_internal(id: Ident,
 pub fn with_sctable<T>(op: |&SCTable| -> T) -> T {
     local_data_key!(sctable_key: Rc<SCTable>)
 
-    local_data::get(sctable_key, |opt_ts| {
-        let table = match opt_ts {
-            None => {
-                let ts = Rc::new(new_sctable_internal());
-                local_data::set(sctable_key, ts.clone());
-                ts
-            }
-            Some(ts) => ts.clone()
-        };
-        op(&*table)
-    })
+    match sctable_key.get() {
+        Some(ts) => op(&**ts),
+        None => {
+            let ts = Rc::new(new_sctable_internal());
+            sctable_key.replace(Some(ts.clone()));
+            op(&*ts)
+        }
+    }
 }
 
 // Make a fresh syntax context table with EmptyCtxt in slot zero
@@ -154,17 +150,14 @@ pub fn resolve(id: Ident) -> Name {
 fn with_resolve_table_mut<T>(op: |&mut ResolveTable| -> T) -> T {
     local_data_key!(resolve_table_key: Rc<RefCell<ResolveTable>>)
 
-    local_data::get(resolve_table_key, |opt_ts| {
-        let table = match opt_ts {
-            None => {
-                let ts = Rc::new(RefCell::new(HashMap::new()));
-                local_data::set(resolve_table_key, ts.clone());
-                ts
-            }
-            Some(ts) => ts.clone()
-        };
-        op(&mut *table.borrow_mut())
-    })
+    match resolve_table_key.get() {
+        Some(ts) => op(&mut *ts.borrow_mut()),
+        None => {
+            let ts = Rc::new(RefCell::new(HashMap::new()));
+            resolve_table_key.replace(Some(ts.clone()));
+            op(&mut *ts.borrow_mut())
+        }
+    }
 }
 
 // Resolve a syntax object to a name, per MTWT.
index 4d8be9bab7685847d36e2092cb3e268d1124f3ab..b3eec136c7d696e87ceca81f992e772408fd339e 100644 (file)
@@ -55,7 +55,7 @@ fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
 
     trait ToSource : ToTokens {
         // Takes a thing and generates a string containing rust code for it.
-        pub fn to_source() -> ~str;
+        pub fn to_source() -> StrBuf;
 
         // If you can make source, you can definitely make tokens.
         pub fn to_tokens(cx: &ExtCtxt) -> ~[TokenTree] {
@@ -67,59 +67,67 @@ pub fn to_tokens(cx: &ExtCtxt) -> ~[TokenTree] {
 
     pub trait ToSource {
         // Takes a thing and generates a string containing rust code for it.
-        fn to_source(&self) -> ~str;
+        fn to_source(&self) -> StrBuf;
     }
 
     impl ToSource for ast::Ident {
-        fn to_source(&self) -> ~str {
-            get_ident(*self).get().to_str()
+        fn to_source(&self) -> StrBuf {
+            get_ident(*self).get().to_strbuf()
         }
     }
 
     impl ToSource for @ast::Item {
-        fn to_source(&self) -> ~str {
+        fn to_source(&self) -> StrBuf {
             pprust::item_to_str(*self)
         }
     }
 
     impl<'a> ToSource for &'a [@ast::Item] {
-        fn to_source(&self) -> ~str {
-            self.iter().map(|i| i.to_source()).collect::<Vec<~str>>().connect("\n\n")
+        fn to_source(&self) -> StrBuf {
+            self.iter()
+                .map(|i| i.to_source())
+                .collect::<Vec<StrBuf>>()
+                .connect("\n\n")
+                .to_strbuf()
         }
     }
 
     impl ToSource for ast::Ty {
-        fn to_source(&self) -> ~str {
+        fn to_source(&self) -> StrBuf {
             pprust::ty_to_str(self)
         }
     }
 
     impl<'a> ToSource for &'a [ast::Ty] {
-        fn to_source(&self) -> ~str {
-            self.iter().map(|i| i.to_source()).collect::<Vec<~str>>().connect(", ")
+        fn to_source(&self) -> StrBuf {
+            self.iter()
+                .map(|i| i.to_source())
+                .collect::<Vec<StrBuf>>()
+                .connect(", ")
+                .to_strbuf()
         }
     }
 
     impl ToSource for Generics {
-        fn to_source(&self) -> ~str {
+        fn to_source(&self) -> StrBuf {
             pprust::generics_to_str(self)
         }
     }
 
     impl ToSource for @ast::Expr {
-        fn to_source(&self) -> ~str {
+        fn to_source(&self) -> StrBuf {
             pprust::expr_to_str(*self)
         }
     }
 
     impl ToSource for ast::Block {
-        fn to_source(&self) -> ~str {
+        fn to_source(&self) -> StrBuf {
             pprust::block_to_str(self)
         }
     }
 
     impl<'a> ToSource for &'a str {
-        fn to_source(&self) -> ~str {
+        fn to_source(&self) -> StrBuf {
             let lit = dummy_spanned(ast::LitStr(
                     token::intern_and_get_ident(*self), ast::CookedStr));
             pprust::lit_to_str(&lit)
@@ -127,41 +135,41 @@ fn to_source(&self) -> ~str {
     }
 
     impl ToSource for () {
-        fn to_source(&self) -> ~str {
-            "()".to_owned()
+        fn to_source(&self) -> StrBuf {
+            "()".to_strbuf()
         }
     }
 
     impl ToSource for bool {
-        fn to_source(&self) -> ~str {
+        fn to_source(&self) -> StrBuf {
             let lit = dummy_spanned(ast::LitBool(*self));
             pprust::lit_to_str(&lit)
         }
     }
 
     impl ToSource for char {
-        fn to_source(&self) -> ~str {
+        fn to_source(&self) -> StrBuf {
             let lit = dummy_spanned(ast::LitChar(*self));
             pprust::lit_to_str(&lit)
         }
     }
 
     impl ToSource for int {
-        fn to_source(&self) -> ~str {
+        fn to_source(&self) -> StrBuf {
             let lit = dummy_spanned(ast::LitInt(*self as i64, ast::TyI));
             pprust::lit_to_str(&lit)
         }
     }
 
     impl ToSource for i8 {
-        fn to_source(&self) -> ~str {
+        fn to_source(&self) -> StrBuf {
             let lit = dummy_spanned(ast::LitInt(*self as i64, ast::TyI8));
             pprust::lit_to_str(&lit)
         }
     }
 
     impl ToSource for i16 {
-        fn to_source(&self) -> ~str {
+        fn to_source(&self) -> StrBuf {
             let lit = dummy_spanned(ast::LitInt(*self as i64, ast::TyI16));
             pprust::lit_to_str(&lit)
         }
@@ -169,49 +177,49 @@ fn to_source(&self) -> ~str {
 
 
     impl ToSource for i32 {
-        fn to_source(&self) -> ~str {
+        fn to_source(&self) -> StrBuf {
             let lit = dummy_spanned(ast::LitInt(*self as i64, ast::TyI32));
             pprust::lit_to_str(&lit)
         }
     }
 
     impl ToSource for i64 {
-        fn to_source(&self) -> ~str {
+        fn to_source(&self) -> StrBuf {
             let lit = dummy_spanned(ast::LitInt(*self as i64, ast::TyI64));
             pprust::lit_to_str(&lit)
         }
     }
 
     impl ToSource for uint {
-        fn to_source(&self) -> ~str {
+        fn to_source(&self) -> StrBuf {
             let lit = dummy_spanned(ast::LitUint(*self as u64, ast::TyU));
             pprust::lit_to_str(&lit)
         }
     }
 
     impl ToSource for u8 {
-        fn to_source(&self) -> ~str {
+        fn to_source(&self) -> StrBuf {
             let lit = dummy_spanned(ast::LitUint(*self as u64, ast::TyU8));
             pprust::lit_to_str(&lit)
         }
     }
 
     impl ToSource for u16 {
-        fn to_source(&self) -> ~str {
+        fn to_source(&self) -> StrBuf {
             let lit = dummy_spanned(ast::LitUint(*self as u64, ast::TyU16));
             pprust::lit_to_str(&lit)
         }
     }
 
     impl ToSource for u32 {
-        fn to_source(&self) -> ~str {
+        fn to_source(&self) -> StrBuf {
             let lit = dummy_spanned(ast::LitUint(*self as u64, ast::TyU32));
             pprust::lit_to_str(&lit)
         }
     }
 
     impl ToSource for u64 {
-        fn to_source(&self) -> ~str {
+        fn to_source(&self) -> StrBuf {
             let lit = dummy_spanned(ast::LitUint(*self as u64, ast::TyU64));
             pprust::lit_to_str(&lit)
         }
@@ -263,17 +271,17 @@ fn to_tokens(&self, cx: &ExtCtxt) -> Vec<TokenTree> {
     impl_to_tokens!(u64)
 
     pub trait ExtParseUtils {
-        fn parse_item(&self, s: ~str) -> @ast::Item;
-        fn parse_expr(&self, s: ~str) -> @ast::Expr;
-        fn parse_stmt(&self, s: ~str) -> @ast::Stmt;
-        fn parse_tts(&self, s: ~str) -> Vec<ast::TokenTree> ;
+        fn parse_item(&self, s: StrBuf) -> @ast::Item;
+        fn parse_expr(&self, s: StrBuf) -> @ast::Expr;
+        fn parse_stmt(&self, s: StrBuf) -> @ast::Stmt;
+        fn parse_tts(&self, s: StrBuf) -> Vec<ast::TokenTree> ;
     }
 
     impl<'a> ExtParseUtils for ExtCtxt<'a> {
 
-        fn parse_item(&self, s: ~str) -> @ast::Item {
+        fn parse_item(&self, s: StrBuf) -> @ast::Item {
             let res = parse::parse_item_from_source_str(
-                "<quote expansion>".to_str(),
+                "<quote expansion>".to_strbuf(),
                 s,
                 self.cfg(),
                 self.parse_sess());
@@ -286,23 +294,23 @@ fn parse_item(&self, s: ~str) -> @ast::Item {
             }
         }
 
-        fn parse_stmt(&self, s: ~str) -> @ast::Stmt {
-            parse::parse_stmt_from_source_str("<quote expansion>".to_str(),
+        fn parse_stmt(&self, s: StrBuf) -> @ast::Stmt {
+            parse::parse_stmt_from_source_str("<quote expansion>".to_strbuf(),
                                               s,
                                               self.cfg(),
                                               Vec::new(),
                                               self.parse_sess())
         }
 
-        fn parse_expr(&self, s: ~str) -> @ast::Expr {
-            parse::parse_expr_from_source_str("<quote expansion>".to_str(),
+        fn parse_expr(&self, s: StrBuf) -> @ast::Expr {
+            parse::parse_expr_from_source_str("<quote expansion>".to_strbuf(),
                                               s,
                                               self.cfg(),
                                               self.parse_sess())
         }
 
-        fn parse_tts(&self, s: ~str) -> Vec<ast::TokenTree> {
-            parse::parse_tts_from_source_str("<quote expansion>".to_str(),
+        fn parse_tts(&self, s: StrBuf) -> Vec<ast::TokenTree> {
+            parse::parse_tts_from_source_str("<quote expansion>".to_strbuf(),
                                              s,
                                              self.cfg(),
                                              self.parse_sess())
@@ -367,8 +375,8 @@ pub fn expand_quote_stmt(cx: &mut ExtCtxt,
     base::MacExpr::new(expanded)
 }
 
-fn ids_ext(strs: Vec<~str> ) -> Vec<ast::Ident> {
-    strs.iter().map(|str| str_to_ident(*str)).collect()
+fn ids_ext(strs: Vec<StrBuf> ) -> Vec<ast::Ident> {
+    strs.iter().map(|str| str_to_ident((*str).as_slice())).collect()
 }
 
 fn id_ext(str: &str) -> ast::Ident {
@@ -678,11 +686,11 @@ fn expand_wrapper(cx: &ExtCtxt,
                   sp: Span,
                   cx_expr: @ast::Expr,
                   expr: @ast::Expr) -> @ast::Expr {
-    let uses = vec!( cx.view_use_glob(sp, ast::Inherited,
-                                   ids_ext(vec!("syntax".to_owned(),
-                                             "ext".to_owned(),
-                                             "quote".to_owned(),
-                                             "rt".to_owned()))) );
+    let uses = vec![ cx.view_use_glob(sp, ast::Inherited,
+                                   ids_ext(vec!["syntax".to_strbuf(),
+                                                "ext".to_strbuf(),
+                                                "quote".to_strbuf(),
+                                                "rt".to_strbuf()])) ];
 
     let stmt_let_ext_cx = cx.stmt_let(sp, false, id_ext("ext_cx"), cx_expr);
 
index e221ab80d7bbcab0b16b0b7df5afece1fc25b285..6e7e72bd2e843145d8a9992893591e5a28e905b6 100644 (file)
@@ -57,14 +57,15 @@ pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
 
     let topmost = topmost_expn_info(cx.backtrace().unwrap());
     let loc = cx.codemap().lookup_char_pos(topmost.call_site.lo);
-    let filename = token::intern_and_get_ident(loc.file.name);
+    let filename = token::intern_and_get_ident(loc.file.name.as_slice());
     base::MacExpr::new(cx.expr_str(topmost.call_site, filename))
 }
 
 pub fn expand_stringify(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                         -> Box<base::MacResult> {
     let s = pprust::tts_to_str(tts);
-    base::MacExpr::new(cx.expr_str(sp, token::intern_and_get_ident(s)))
+    base::MacExpr::new(cx.expr_str(sp,
+                                   token::intern_and_get_ident(s.as_slice())))
 }
 
 pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
@@ -72,8 +73,8 @@ pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     base::check_zero_tts(cx, sp, tts, "module_path!");
     let string = cx.mod_path()
                    .iter()
-                   .map(|x| token::get_ident(*x).get().to_str())
-                   .collect::<Vec<~str>>()
+                   .map(|x| token::get_ident(*x).get().to_strbuf())
+                   .collect::<Vec<StrBuf>>()
                    .connect("::");
     base::MacExpr::new(cx.expr_str(sp, token::intern_and_get_ident(string)))
 }
@@ -117,9 +118,9 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
         Some(src) => {
             // Add this input file to the code map to make it available as
             // dependency information
-            let filename = file.display().to_str();
+            let filename = file.display().to_str().to_strbuf();
             let interned = token::intern_and_get_ident(src);
-            cx.codemap().new_filemap(filename, src.to_owned());
+            cx.codemap().new_filemap(filename, src.to_strbuf());
 
             base::MacExpr::new(cx.expr_str(sp, interned))
         }
@@ -161,7 +162,7 @@ fn topmost_expn_info(expn_info: @codemap::ExpnInfo) -> @codemap::ExpnInfo {
                             ..
                         } => {
                             // Don't recurse into file using "include!"
-                            if "include" == *name  {
+                            if "include" == name.as_slice() {
                                 expn_info
                             } else {
                                 topmost_expn_info(next_expn_info)
index ee3ff0c389e2119388dfc5fe8b1e5215f4359fcf..89e8d48425f6cc6ebfbd88c0120acff487c3b2de 100644 (file)
@@ -201,8 +201,8 @@ fn n_rec(p_s: &ParseSess, m: &Matcher, res: &[Rc<NamedMatch>],
 
 pub enum ParseResult {
     Success(HashMap<Ident, Rc<NamedMatch>>),
-    Failure(codemap::Span, ~str),
-    Error(codemap::Span, ~str)
+    Failure(codemap::Span, StrBuf),
+    Error(codemap::Span, StrBuf)
 }
 
 pub fn parse_or_else(sess: &ParseSess,
@@ -212,8 +212,12 @@ pub fn parse_or_else(sess: &ParseSess,
                      -> HashMap<Ident, Rc<NamedMatch>> {
     match parse(sess, cfg, rdr, ms.as_slice()) {
         Success(m) => m,
-        Failure(sp, str) => sess.span_diagnostic.span_fatal(sp, str),
-        Error(sp, str) => sess.span_diagnostic.span_fatal(sp, str)
+        Failure(sp, str) => {
+            sess.span_diagnostic.span_fatal(sp, str.as_slice())
+        }
+        Error(sp, str) => {
+            sess.span_diagnostic.span_fatal(sp, str.as_slice())
+        }
     }
 }
 
@@ -366,9 +370,9 @@ pub fn parse(sess: &ParseSess,
                 }
                 return Success(nameize(sess, ms, v.as_slice()));
             } else if eof_eis.len() > 1u {
-                return Error(sp, "ambiguity: multiple successful parses".to_owned());
+                return Error(sp, "ambiguity: multiple successful parses".to_strbuf());
             } else {
-                return Failure(sp, "unexpected end of macro invocation".to_owned());
+                return Failure(sp, "unexpected end of macro invocation".to_strbuf());
             }
         } else {
             if (bb_eis.len() > 0u && next_eis.len() > 0u)
@@ -376,19 +380,19 @@ pub fn parse(sess: &ParseSess,
                 let nts = bb_eis.iter().map(|ei| {
                     match ei.elts.get(ei.idx).node {
                       MatchNonterminal(bind, name, _) => {
-                        format!("{} ('{}')",
+                        (format!("{} ('{}')",
                                 token::get_ident(name),
-                                token::get_ident(bind))
+                                token::get_ident(bind))).to_strbuf()
                       }
                       _ => fail!()
-                    } }).collect::<Vec<~str>>().connect(" or ");
+                    } }).collect::<Vec<StrBuf>>().connect(" or ");
                 return Error(sp, format!(
                     "local ambiguity: multiple parsing options: \
                      built-in NTs {} or {} other options.",
-                    nts, next_eis.len()));
+                    nts, next_eis.len()).to_strbuf());
             } else if bb_eis.len() == 0u && next_eis.len() == 0u {
                 return Failure(sp, format!("no rules expected the token `{}`",
-                            token::to_str(&tok)));
+                            token::to_str(&tok)).to_strbuf());
             } else if next_eis.len() > 0u {
                 /* Now process the next token */
                 while next_eis.len() > 0u {
@@ -436,7 +440,8 @@ pub fn parse_nt(p: &mut Parser, name: &str) -> Nonterminal {
         token::IDENT(sn,b) => { p.bump(); token::NtIdent(box sn,b) }
         _ => {
             let token_str = token::to_str(&p.token);
-            p.fatal("expected ident, found ".to_owned() + token_str)
+            p.fatal((format!("expected ident, found {}",
+                             token_str.as_slice())).as_slice())
         }
       },
       "path" => {
index 5a02acdae1cea84f48ff5aad02a0d881b3ef35dc..7ff690582d6800f0030c9b048a20b755736152e8 100644 (file)
@@ -132,7 +132,7 @@ fn generic_extension(cx: &ExtCtxt,
 
     // Which arm's failure should we report? (the one furthest along)
     let mut best_fail_spot = DUMMY_SP;
-    let mut best_fail_msg = "internal error: ran no matchers".to_owned();
+    let mut best_fail_msg = "internal error: ran no matchers".to_strbuf();
 
     for (i, lhs) in lhses.iter().enumerate() { // try each arm's matchers
         match **lhs {
@@ -177,13 +177,13 @@ fn generic_extension(cx: &ExtCtxt,
                 best_fail_spot = sp;
                 best_fail_msg = (*msg).clone();
               },
-              Error(sp, ref msg) => cx.span_fatal(sp, (*msg))
+              Error(sp, ref msg) => cx.span_fatal(sp, msg.as_slice())
             }
           }
           _ => cx.bug("non-matcher found in parsed lhses")
         }
     }
-    cx.span_fatal(best_fail_spot, best_fail_msg);
+    cx.span_fatal(best_fail_spot, best_fail_msg.as_slice());
 }
 
 // this procedure performs the expansion of the
@@ -247,7 +247,7 @@ fn ms(m: Matcher_) -> Matcher {
 
     box MacroRulesDefiner {
         def: RefCell::new(Some(MacroDef {
-            name: token::get_ident(name).to_str(),
+            name: token::get_ident(name).to_str().to_strbuf(),
             ext: NormalTT(exp, Some(sp))
         }))
     } as Box<MacResult>
index f6bee0335533befcbf2ddf509d2e45e3edd126bd..1f264e73d4aa3eb3934b2dcb54d2131c52bbb837 100644 (file)
@@ -100,7 +100,7 @@ fn lookup_cur_matched(r: &TtReader, name: Ident) -> Rc<NamedMatch> {
 enum LockstepIterSize {
     LisUnconstrained,
     LisConstraint(uint, Ident),
-    LisContradiction(~str),
+    LisContradiction(StrBuf),
 }
 
 fn lis_merge(lhs: LockstepIterSize, rhs: LockstepIterSize) -> LockstepIterSize {
@@ -116,7 +116,7 @@ fn lis_merge(lhs: LockstepIterSize, rhs: LockstepIterSize) -> LockstepIterSize {
                 let r_n = token::get_ident(r_id);
                 LisContradiction(format!("inconsistent lockstep iteration: \
                                           '{}' has {} items, but '{}' has {}",
-                                          l_n, l_len, r_n, r_len))
+                                          l_n, l_len, r_n, r_len).to_strbuf())
             }
         }
     }
@@ -223,7 +223,7 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
                         }
                         LisContradiction(ref msg) => {
                             // FIXME #2887 blame macro invoker instead
-                            r.sp_diag.span_fatal(sp.clone(), *msg);
+                            r.sp_diag.span_fatal(sp.clone(), msg.as_slice());
                         }
                     LisConstraint(len, _) => {
                         if len == 0 {
index 685e08dd91819d1f1b43b380138ec9f6c9805cc2..10df264676e335f6919a423c48989b7da6d38578 100644 (file)
@@ -949,7 +949,7 @@ macro_rules! assert_pred (
                 let pred_val = $pred;
                 let a_val = $a;
                 let b_val = $b;
-                if !(pred_val(a_val,b_val)) {
+                if !(pred_val(a_val.as_slice(),b_val.as_slice())) {
                     fail!("expected args satisfying {}, got {:?} and {:?}",
                           $predname, a_val, b_val);
                 }
@@ -961,12 +961,13 @@ macro_rules! assert_pred (
     #[test] fn ident_transformation () {
         let mut zz_fold = ToZzIdentFolder;
         let ast = string_to_crate(
-            "#[a] mod b {fn c (d : e, f : g) {h!(i,j,k);l;m}}".to_owned());
+            "#[a] mod b {fn c (d : e, f : g) {h!(i,j,k);l;m}}".to_strbuf());
         let folded_crate = zz_fold.fold_crate(ast);
-        assert_pred!(matches_codepattern,
-                     "matches_codepattern",
-                     pprust::to_str(|s| fake_print_crate(s, &folded_crate)),
-                     "#[a]mod zz{fn zz(zz:zz,zz:zz){zz!(zz,zz,zz);zz;zz}}".to_owned());
+        assert_pred!(
+            matches_codepattern,
+            "matches_codepattern",
+            pprust::to_str(|s| fake_print_crate(s, &folded_crate)),
+            "#[a]mod zz{fn zz(zz:zz,zz:zz){zz!(zz,zz,zz);zz;zz}}".to_strbuf());
     }
 
     // even inside macro defs....
@@ -974,11 +975,12 @@ macro_rules! assert_pred (
         let mut zz_fold = ToZzIdentFolder;
         let ast = string_to_crate(
             "macro_rules! a {(b $c:expr $(d $e:token)f+ => \
-             (g $(d $d $e)+))} ".to_owned());
+             (g $(d $d $e)+))} ".to_strbuf());
         let folded_crate = zz_fold.fold_crate(ast);
-        assert_pred!(matches_codepattern,
-                     "matches_codepattern",
-                     pprust::to_str(|s| fake_print_crate(s, &folded_crate)),
-                     "zz!zz((zz$zz:zz$(zz $zz:zz)zz+=>(zz$(zz$zz$zz)+)))".to_owned());
+        assert_pred!(
+            matches_codepattern,
+            "matches_codepattern",
+            pprust::to_str(|s| fake_print_crate(s, &folded_crate)),
+            "zz!zz((zz$zz:zz$(zz $zz:zz)zz+=>(zz$(zz$zz$zz)+)))".to_strbuf());
     }
 }
index 012bc50ecabc80fa315107153d9606841c209dfe..5e1d988df5c30145a2eaf2f916f6fbe65ca97559 100644 (file)
@@ -35,6 +35,7 @@
 extern crate collections;
 #[phase(syntax, link)]
 extern crate log;
+extern crate fmt_macros;
 
 pub mod util {
     pub mod interner;
index a96905f859738093184e7c52e9846d9c720656ad..5fc214109c256555cbe92647cb5d0427e6e082f9 100644 (file)
@@ -33,7 +33,7 @@ pub enum CommentStyle {
 #[deriving(Clone)]
 pub struct Comment {
     pub style: CommentStyle,
-    pub lines: Vec<~str>,
+    pub lines: Vec<StrBuf>,
     pub pos: BytePos,
 }
 
@@ -53,35 +53,40 @@ pub fn doc_comment_style(comment: &str) -> ast::AttrStyle {
     }
 }
 
-pub fn strip_doc_comment_decoration(comment: &str) -> ~str {
+pub fn strip_doc_comment_decoration(comment: &str) -> StrBuf {
     /// remove whitespace-only lines from the start/end of lines
-    fn vertical_trim(lines: Vec<~str> ) -> Vec<~str> {
+    fn vertical_trim(lines: Vec<StrBuf> ) -> Vec<StrBuf> {
         let mut i = 0u;
         let mut j = lines.len();
         // first line of all-stars should be omitted
-        if lines.len() > 0 && lines.get(0).chars().all(|c| c == '*') {
+        if lines.len() > 0 &&
+                lines.get(0).as_slice().chars().all(|c| c == '*') {
             i += 1;
         }
-        while i < j && lines.get(i).trim().is_empty() {
+        while i < j && lines.get(i).as_slice().trim().is_empty() {
             i += 1;
         }
         // like the first, a last line of all stars should be omitted
-        if j > i && lines.get(j - 1).chars().skip(1).all(|c| c == '*') {
+        if j > i && lines.get(j - 1)
+                         .as_slice()
+                         .chars()
+                         .skip(1)
+                         .all(|c| c == '*') {
             j -= 1;
         }
-        while j > i && lines.get(j - 1).trim().is_empty() {
+        while j > i && lines.get(j - 1).as_slice().trim().is_empty() {
             j -= 1;
         }
         return lines.slice(i, j).iter().map(|x| (*x).clone()).collect();
     }
 
     /// remove a "[ \t]*\*" block from each line, if possible
-    fn horizontal_trim(lines: Vec<~str> ) -> Vec<~str> {
+    fn horizontal_trim(lines: Vec<StrBuf> ) -> Vec<StrBuf> {
         let mut i = uint::MAX;
         let mut can_trim = true;
         let mut first = true;
         for line in lines.iter() {
-            for (j, c) in line.chars().enumerate() {
+            for (j, c) in line.as_slice().chars().enumerate() {
                 if j > i || !"* \t".contains_char(c) {
                     can_trim = false;
                     break;
@@ -105,7 +110,9 @@ fn horizontal_trim(lines: Vec<~str> ) -> Vec<~str> {
         }
 
         if can_trim {
-            lines.iter().map(|line| line.slice(i + 1, line.len()).to_owned()).collect()
+            lines.iter().map(|line| {
+                line.as_slice().slice(i + 1, line.len()).to_strbuf()
+            }).collect()
         } else {
             lines
         }
@@ -115,39 +122,41 @@ fn horizontal_trim(lines: Vec<~str> ) -> Vec<~str> {
     static ONLINERS: &'static [&'static str] = &["///!", "///", "//!", "//"];
     for prefix in ONLINERS.iter() {
         if comment.starts_with(*prefix) {
-            return comment.slice_from(prefix.len()).to_owned();
+            return comment.slice_from(prefix.len()).to_strbuf();
         }
     }
 
     if comment.starts_with("/*") {
         let lines = comment.slice(3u, comment.len() - 2u)
             .lines_any()
-            .map(|s| s.to_owned())
-            .collect::<Vec<~str> >();
+            .map(|s| s.to_strbuf())
+            .collect::<Vec<StrBuf> >();
 
         let lines = vertical_trim(lines);
         let lines = horizontal_trim(lines);
 
-        return lines.connect("\n");
+        return lines.connect("\n").to_strbuf();
     }
 
     fail!("not a doc-comment: {}", comment);
 }
 
-fn read_to_eol(rdr: &mut StringReader) -> ~str {
+fn read_to_eol(rdr: &mut StringReader) -> StrBuf {
     let mut val = StrBuf::new();
     while !rdr.curr_is('\n') && !is_eof(rdr) {
         val.push_char(rdr.curr.unwrap());
         bump(rdr);
     }
     if rdr.curr_is('\n') { bump(rdr); }
-    return val.into_owned();
+    return val
 }
 
-fn read_one_line_comment(rdr: &mut StringReader) -> ~str {
+fn read_one_line_comment(rdr: &mut StringReader) -> StrBuf {
     let val = read_to_eol(rdr);
-    assert!((val[0] == '/' as u8 && val[1] == '/' as u8) ||
-                 (val[0] == '#' as u8 && val[1] == '!' as u8));
+    assert!((val.as_slice()[0] == '/' as u8 &&
+                val.as_slice()[1] == '/' as u8) ||
+                (val.as_slice()[0] == '#' as u8 &&
+                 val.as_slice()[1] == '!' as u8));
     return val;
 }
 
@@ -193,11 +202,12 @@ fn read_line_comments(rdr: &mut StringReader, code_to_the_left: bool,
                       comments: &mut Vec<Comment>) {
     debug!(">>> line comments");
     let p = rdr.last_pos;
-    let mut lines: Vec<~str> = Vec::new();
+    let mut lines: Vec<StrBuf> = Vec::new();
     while rdr.curr_is('/') && nextch_is(rdr, '/') {
         let line = read_one_line_comment(rdr);
         debug!("{}", line);
-        if is_doc_comment(line) { // doc-comments are not put in comments
+        // Doc comments are not put in comments.
+        if is_doc_comment(line.as_slice()) {
             break;
         }
         lines.push(line);
@@ -231,14 +241,16 @@ fn all_whitespace(s: &str, col: CharPos) -> Option<uint> {
     return Some(cursor);
 }
 
-fn trim_whitespace_prefix_and_push_line(lines: &mut Vec<~str> ,
-                                        s: ~str, col: CharPos) {
+fn trim_whitespace_prefix_and_push_line(lines: &mut Vec<StrBuf> ,
+                                        s: StrBuf, col: CharPos) {
     let len = s.len();
-    let s1 = match all_whitespace(s, col) {
+    let s1 = match all_whitespace(s.as_slice(), col) {
         Some(col) => {
             if col < len {
-                s.slice(col, len).to_owned()
-            } else {  "".to_owned() }
+                s.as_slice().slice(col, len).to_strbuf()
+            } else {
+                "".to_strbuf()
+            }
         }
         None => s,
     };
@@ -251,7 +263,7 @@ fn read_block_comment(rdr: &mut StringReader,
                       comments: &mut Vec<Comment> ) {
     debug!(">>> block comment");
     let p = rdr.last_pos;
-    let mut lines: Vec<~str> = Vec::new();
+    let mut lines: Vec<StrBuf> = Vec::new();
     let col = rdr.col;
     bump(rdr);
     bump(rdr);
@@ -273,17 +285,17 @@ fn read_block_comment(rdr: &mut StringReader,
             return
         }
         assert!(!curr_line.as_slice().contains_char('\n'));
-        lines.push(curr_line.into_owned());
+        lines.push(curr_line);
     } else {
         let mut level: int = 1;
         while level > 0 {
             debug!("=== block comment level {}", level);
             if is_eof(rdr) {
-                rdr.fatal("unterminated block comment".to_owned());
+                rdr.fatal("unterminated block comment".to_strbuf());
             }
             if rdr.curr_is('\n') {
                 trim_whitespace_prefix_and_push_line(&mut lines,
-                                                     curr_line.into_owned(),
+                                                     curr_line,
                                                      col);
                 curr_line = StrBuf::new();
                 bump(rdr);
@@ -306,7 +318,7 @@ fn read_block_comment(rdr: &mut StringReader,
         }
         if curr_line.len() != 0 {
             trim_whitespace_prefix_and_push_line(&mut lines,
-                                                 curr_line.into_owned(),
+                                                 curr_line,
                                                  col);
         }
     }
@@ -344,7 +356,7 @@ fn consume_comment(rdr: &mut StringReader,
 
 #[deriving(Clone)]
 pub struct Literal {
-    pub lit: ~str,
+    pub lit: StrBuf,
     pub pos: BytePos,
 }
 
@@ -352,11 +364,11 @@ pub struct Literal {
 // probably not a good thing.
 pub fn gather_comments_and_literals(span_diagnostic:
                                         &diagnostic::SpanHandler,
-                                    path: ~str,
+                                    path: StrBuf,
                                     srdr: &mut io::Reader)
                                  -> (Vec<Comment>, Vec<Literal>) {
     let src = srdr.read_to_end().unwrap();
-    let src = str::from_utf8(src.as_slice()).unwrap().to_owned();
+    let src = str::from_utf8(src.as_slice()).unwrap().to_strbuf();
     let cm = CodeMap::new();
     let filemap = cm.new_filemap(path, src);
     let mut rdr = lexer::new_low_level_string_reader(span_diagnostic, filemap);
@@ -387,7 +399,7 @@ pub fn gather_comments_and_literals(span_diagnostic:
         if token::is_lit(&tok) {
             with_str_from(&rdr, bstart, |s| {
                 debug!("tok lit: {}", s);
-                literals.push(Literal {lit: s.to_owned(), pos: sp.lo});
+                literals.push(Literal {lit: s.to_strbuf(), pos: sp.lo});
             })
         } else {
             debug!("tok: {}", token::to_str(&tok));
@@ -405,41 +417,41 @@ mod test {
     #[test] fn test_block_doc_comment_1() {
         let comment = "/**\n * Test \n **  Test\n *   Test\n*/";
         let stripped = strip_doc_comment_decoration(comment);
-        assert_eq!(stripped, " Test \n*  Test\n   Test".to_owned());
+        assert_eq!(stripped, " Test \n*  Test\n   Test".to_strbuf());
     }
 
     #[test] fn test_block_doc_comment_2() {
         let comment = "/**\n * Test\n *  Test\n*/";
         let stripped = strip_doc_comment_decoration(comment);
-        assert_eq!(stripped, " Test\n  Test".to_owned());
+        assert_eq!(stripped, " Test\n  Test".to_strbuf());
     }
 
     #[test] fn test_block_doc_comment_3() {
         let comment = "/**\n let a: *int;\n *a = 5;\n*/";
         let stripped = strip_doc_comment_decoration(comment);
-        assert_eq!(stripped, " let a: *int;\n *a = 5;".to_owned());
+        assert_eq!(stripped, " let a: *int;\n *a = 5;".to_strbuf());
     }
 
     #[test] fn test_block_doc_comment_4() {
         let comment = "/*******************\n test\n *********************/";
         let stripped = strip_doc_comment_decoration(comment);
-        assert_eq!(stripped, " test".to_owned());
+        assert_eq!(stripped, " test".to_strbuf());
     }
 
     #[test] fn test_line_doc_comment() {
         let stripped = strip_doc_comment_decoration("/// test");
-        assert_eq!(stripped, " test".to_owned());
+        assert_eq!(stripped, " test".to_strbuf());
         let stripped = strip_doc_comment_decoration("///! test");
-        assert_eq!(stripped, " test".to_owned());
+        assert_eq!(stripped, " test".to_strbuf());
         let stripped = strip_doc_comment_decoration("// test");
-        assert_eq!(stripped, " test".to_owned());
+        assert_eq!(stripped, " test".to_strbuf());
         let stripped = strip_doc_comment_decoration("// test");
-        assert_eq!(stripped, " test".to_owned());
+        assert_eq!(stripped, " test".to_strbuf());
         let stripped = strip_doc_comment_decoration("///test");
-        assert_eq!(stripped, "test".to_owned());
+        assert_eq!(stripped, "test".to_strbuf());
         let stripped = strip_doc_comment_decoration("///!test");
-        assert_eq!(stripped, "test".to_owned());
+        assert_eq!(stripped, "test".to_strbuf());
         let stripped = strip_doc_comment_decoration("//test");
-        assert_eq!(stripped, "test".to_owned());
+        assert_eq!(stripped, "test".to_strbuf());
     }
 }
index 43535205601f17ee7dde1cde0231f41adb6f2727..c78d2aaf3a7e891567519b443054d9c1b6fa0619 100644 (file)
@@ -28,7 +28,7 @@
 pub trait Reader {
     fn is_eof(&self) -> bool;
     fn next_token(&mut self) -> TokenAndSpan;
-    fn fatal(&self, ~str) -> !;
+    fn fatal(&self, StrBuf) -> !;
     fn span_diag<'a>(&'a self) -> &'a SpanHandler;
     fn peek(&self) -> TokenAndSpan;
 }
@@ -101,8 +101,8 @@ fn next_token(&mut self) -> TokenAndSpan {
         string_advance_token(self);
         ret_val
     }
-    fn fatal(&self, m: ~str) -> ! {
-        self.span_diagnostic.span_fatal(self.peek_span, m)
+    fn fatal(&self, m: StrBuf) -> ! {
+        self.span_diagnostic.span_fatal(self.peek_span, m.as_slice())
     }
     fn span_diag<'a>(&'a self) -> &'a SpanHandler { self.span_diagnostic }
     fn peek(&self) -> TokenAndSpan {
@@ -123,8 +123,8 @@ fn next_token(&mut self) -> TokenAndSpan {
         debug!("TtReader: r={:?}", r);
         r
     }
-    fn fatal(&self, m: ~str) -> ! {
-        self.sp_diag.span_fatal(self.cur_span, m);
+    fn fatal(&self, m: StrBuf) -> ! {
+        self.sp_diag.span_fatal(self.cur_span, m.as_slice());
     }
     fn span_diag<'a>(&'a self) -> &'a SpanHandler { self.sp_diag }
     fn peek(&self) -> TokenAndSpan {
@@ -139,7 +139,7 @@ fn peek(&self) -> TokenAndSpan {
 fn fatal_span(rdr: &mut StringReader,
               from_pos: BytePos,
               to_pos: BytePos,
-              m: ~str)
+              m: StrBuf)
            -> ! {
     rdr.peek_span = codemap::mk_sp(from_pos, to_pos);
     rdr.fatal(m);
@@ -150,13 +150,13 @@ fn fatal_span(rdr: &mut StringReader,
 fn fatal_span_char(rdr: &mut StringReader,
                    from_pos: BytePos,
                    to_pos: BytePos,
-                   m: ~str,
+                   m: StrBuf,
                    c: char)
                 -> ! {
-    let mut m = StrBuf::from_owned_str(m);
+    let mut m = m;
     m.push_str(": ");
     char::escape_default(c, |c| m.push_char(c));
-    fatal_span(rdr, from_pos, to_pos, m.into_owned());
+    fatal_span(rdr, from_pos, to_pos, m.into_strbuf());
 }
 
 // report a lexical error spanning [`from_pos`, `to_pos`), appending the
@@ -164,14 +164,14 @@ fn fatal_span_char(rdr: &mut StringReader,
 fn fatal_span_verbose(rdr: &mut StringReader,
                       from_pos: BytePos,
                       to_pos: BytePos,
-                      m: ~str)
+                      m: StrBuf)
                    -> ! {
-    let mut m = StrBuf::from_owned_str(m);
+    let mut m = m;
     m.push_str(": ");
     let from = byte_offset(rdr, from_pos).to_uint();
     let to = byte_offset(rdr, to_pos).to_uint();
-    m.push_str(rdr.filemap.src.slice(from, to));
-    fatal_span(rdr, from_pos, to_pos, m.into_owned());
+    m.push_str(rdr.filemap.src.as_slice().slice(from, to));
+    fatal_span(rdr, from_pos, to_pos, m);
 }
 
 // EFFECT: advance peek_tok and peek_span to refer to the next token.
@@ -218,7 +218,7 @@ fn with_str_from_to<T>(
                     end: BytePos,
                     f: |s: &str| -> T)
                     -> T {
-    f(rdr.filemap.src.slice(
+    f(rdr.filemap.src.as_slice().slice(
             byte_offset(rdr, start).to_uint(),
             byte_offset(rdr, end).to_uint()))
 }
@@ -231,7 +231,10 @@ pub fn bump(rdr: &mut StringReader) {
     if current_byte_offset < rdr.filemap.src.len() {
         assert!(rdr.curr.is_some());
         let last_char = rdr.curr.unwrap();
-        let next = rdr.filemap.src.char_range_at(current_byte_offset);
+        let next = rdr.filemap
+                      .src
+                      .as_slice()
+                      .char_range_at(current_byte_offset);
         let byte_offset_diff = next.next - current_byte_offset;
         rdr.pos = rdr.pos + Pos::from_uint(byte_offset_diff);
         rdr.curr = Some(next.ch);
@@ -256,7 +259,7 @@ pub fn is_eof(rdr: &StringReader) -> bool {
 pub fn nextch(rdr: &StringReader) -> Option<char> {
     let offset = byte_offset(rdr, rdr.pos).to_uint();
     if offset < rdr.filemap.src.len() {
-        Some(rdr.filemap.src.char_at(offset))
+        Some(rdr.filemap.src.as_slice().char_at(offset))
     } else {
         None
     }
@@ -400,9 +403,9 @@ fn consume_block_comment(rdr: &mut StringReader) -> Option<TokenAndSpan> {
     while level > 0 {
         if is_eof(rdr) {
             let msg = if is_doc_comment {
-                "unterminated block doc-comment".to_owned()
+                "unterminated block doc-comment".to_strbuf()
             } else {
-                "unterminated block comment".to_owned()
+                "unterminated block comment".to_strbuf()
             };
             fatal_span(rdr, start_bpos, rdr.last_pos, msg);
         } else if rdr.curr_is('/') && nextch_is(rdr, '*') {
@@ -438,7 +441,7 @@ fn consume_block_comment(rdr: &mut StringReader) -> Option<TokenAndSpan> {
     if res.is_some() { res } else { consume_whitespace_and_comments(rdr) }
 }
 
-fn scan_exponent(rdr: &mut StringReader, start_bpos: BytePos) -> Option<~str> {
+fn scan_exponent(rdr: &mut StringReader, start_bpos: BytePos) -> Option<StrBuf> {
     // \x00 hits the `return None` case immediately, so this is fine.
     let mut c = rdr.curr.unwrap_or('\x00');
     let mut rslt = StrBuf::new();
@@ -452,16 +455,18 @@ fn scan_exponent(rdr: &mut StringReader, start_bpos: BytePos) -> Option<~str> {
         }
         let exponent = scan_digits(rdr, 10u);
         if exponent.len() > 0u {
-            rslt.push_str(exponent);
-            return Some(rslt.into_owned());
+            rslt.push_str(exponent.as_slice());
+            return Some(rslt);
         } else {
             fatal_span(rdr, start_bpos, rdr.last_pos,
-                       "scan_exponent: bad fp literal".to_owned());
+                       "scan_exponent: bad fp literal".to_strbuf());
         }
-    } else { return None::<~str>; }
+    } else {
+        return None::<StrBuf>;
+    }
 }
 
-fn scan_digits(rdr: &mut StringReader, radix: uint) -> ~str {
+fn scan_digits(rdr: &mut StringReader, radix: uint) -> StrBuf {
     let mut rslt = StrBuf::new();
     loop {
         let c = rdr.curr;
@@ -471,7 +476,7 @@ fn scan_digits(rdr: &mut StringReader, radix: uint) -> ~str {
             rslt.push_char(c.unwrap());
             bump(rdr);
           }
-          _ => return rslt.into_owned()
+          _ => return rslt
         }
     };
 }
@@ -479,12 +484,14 @@ fn scan_digits(rdr: &mut StringReader, radix: uint) -> ~str {
 fn check_float_base(rdr: &mut StringReader, start_bpos: BytePos, last_bpos: BytePos,
                     base: uint) {
     match base {
-      16u => fatal_span(rdr, start_bpos, last_bpos,
-                      "hexadecimal float literal is not supported".to_owned()),
+      16u => {
+          fatal_span(rdr, start_bpos, last_bpos,
+                     "hexadecimal float literal is not supported".to_strbuf())
+      }
       8u => fatal_span(rdr, start_bpos, last_bpos,
-                     "octal float literal is not supported".to_owned()),
+                     "octal float literal is not supported".to_strbuf()),
       2u => fatal_span(rdr, start_bpos, last_bpos,
-                     "binary float literal is not supported".to_owned()),
+                     "binary float literal is not supported".to_strbuf()),
       _ => ()
     }
 }
@@ -508,7 +515,7 @@ fn scan_number(c: char, rdr: &mut StringReader) -> token::Token {
         bump(rdr);
         base = 2u;
     }
-    num_str = StrBuf::from_owned_str(scan_digits(rdr, base));
+    num_str = scan_digits(rdr, base);
     c = rdr.curr.unwrap_or('\x00');
     nextch(rdr);
     if c == 'u' || c == 'i' {
@@ -544,13 +551,13 @@ enum Result { Signed(ast::IntTy), Unsigned(ast::UintTy) }
         }
         if num_str.len() == 0u {
             fatal_span(rdr, start_bpos, rdr.last_pos,
-                       "no valid digits found for number".to_owned());
+                       "no valid digits found for number".to_strbuf());
         }
         let parsed = match from_str_radix::<u64>(num_str.as_slice(),
                                                  base as uint) {
             Some(p) => p,
             None => fatal_span(rdr, start_bpos, rdr.last_pos,
-                               "int literal is too large".to_owned())
+                               "int literal is too large".to_strbuf())
         };
 
         match tp {
@@ -564,12 +571,12 @@ enum Result { Signed(ast::IntTy), Unsigned(ast::UintTy) }
         bump(rdr);
         let dec_part = scan_digits(rdr, 10u);
         num_str.push_char('.');
-        num_str.push_str(dec_part);
+        num_str.push_str(dec_part.as_slice());
     }
     match scan_exponent(rdr, start_bpos) {
       Some(ref s) => {
         is_float = true;
-        num_str.push_str(*s);
+        num_str.push_str(s.as_slice());
       }
       None => ()
     }
@@ -601,7 +608,7 @@ enum Result { Signed(ast::IntTy), Unsigned(ast::UintTy) }
             return token::LIT_FLOAT(str_to_ident(num_str.as_slice()), ast::TyF128);
         }
         fatal_span(rdr, start_bpos, rdr.last_pos,
-                   "expected `f32`, `f64` or `f128` suffix".to_owned());
+                   "expected `f32`, `f64` or `f128` suffix".to_strbuf());
     }
     if is_float {
         check_float_base(rdr, start_bpos, rdr.last_pos, base);
@@ -610,13 +617,13 @@ enum Result { Signed(ast::IntTy), Unsigned(ast::UintTy) }
     } else {
         if num_str.len() == 0u {
             fatal_span(rdr, start_bpos, rdr.last_pos,
-                       "no valid digits found for number".to_owned());
+                       "no valid digits found for number".to_strbuf());
         }
         let parsed = match from_str_radix::<u64>(num_str.as_slice(),
                                                  base as uint) {
             Some(p) => p,
             None => fatal_span(rdr, start_bpos, rdr.last_pos,
-                               "int literal is too large".to_owned())
+                               "int literal is too large".to_strbuf())
         };
 
         debug!("lexing {} as an unsuffixed integer literal",
@@ -632,9 +639,12 @@ fn scan_numeric_escape(rdr: &mut StringReader, n_hex_digits: uint) -> char {
     while i != 0u && !is_eof(rdr) {
         let n = rdr.curr;
         if !is_hex_digit(n) {
-            fatal_span_char(rdr, rdr.last_pos, rdr.pos,
-                            "illegal character in numeric character escape".to_owned(),
-                            n.unwrap());
+            fatal_span_char(
+                rdr,
+                rdr.last_pos,
+                rdr.pos,
+                "illegal character in numeric character escape".to_strbuf(),
+                n.unwrap());
         }
         bump(rdr);
         accum_int *= 16;
@@ -643,13 +653,13 @@ fn scan_numeric_escape(rdr: &mut StringReader, n_hex_digits: uint) -> char {
     }
     if i != 0 && is_eof(rdr) {
         fatal_span(rdr, start_bpos, rdr.last_pos,
-                   "unterminated numeric character escape".to_owned());
+                   "unterminated numeric character escape".to_strbuf());
     }
 
     match char::from_u32(accum_int as u32) {
         Some(x) => x,
         None => fatal_span(rdr, start_bpos, rdr.last_pos,
-                           "illegal numeric character escape".to_owned())
+                           "illegal numeric character escape".to_strbuf())
     }
 }
 
@@ -819,11 +829,11 @@ fn binop(rdr: &mut StringReader, op: token::BinOp) -> token::Token {
             if token::is_keyword(token::keywords::Self, tok) {
                 fatal_span(rdr, start, rdr.last_pos,
                            "invalid lifetime name: 'self \
-                            is no longer a special lifetime".to_owned());
+                            is no longer a special lifetime".to_strbuf());
             } else if token::is_any_keyword(tok) &&
                 !token::is_keyword(token::keywords::Static, tok) {
                 fatal_span(rdr, start, rdr.last_pos,
-                           "invalid lifetime name".to_owned());
+                           "invalid lifetime name".to_strbuf());
             } else {
                 return token::LIFETIME(ident);
             }
@@ -851,16 +861,24 @@ fn binop(rdr: &mut StringReader, op: token::BinOp) -> token::Token {
                             'u' => scan_numeric_escape(rdr, 4u),
                             'U' => scan_numeric_escape(rdr, 8u),
                             c2 => {
-                                fatal_span_char(rdr, escaped_pos, rdr.last_pos,
-                                                "unknown character escape".to_owned(), c2)
+                                fatal_span_char(rdr,
+                                                escaped_pos,
+                                                rdr.last_pos,
+                                                "unknown character \
+                                                 escape".to_strbuf(),
+                                                c2)
                             }
                         }
                     }
                 }
             }
             '\t' | '\n' | '\r' | '\'' => {
-                fatal_span_char(rdr, start, rdr.last_pos,
-                                "character constant must be escaped".to_owned(), c2);
+                fatal_span_char(
+                    rdr,
+                    start,
+                    rdr.last_pos,
+                    "character constant must be escaped".to_strbuf(),
+                    c2);
             }
             _ => {}
         }
@@ -871,7 +889,7 @@ fn binop(rdr: &mut StringReader, op: token::BinOp) -> token::Token {
                                // ascii single quote.
                                start - BytePos(1),
                                rdr.last_pos,
-                               "unterminated character constant".to_owned());
+                               "unterminated character constant".to_strbuf());
         }
         bump(rdr); // advance curr past token
         return token::LIT_CHAR(c2);
@@ -883,7 +901,7 @@ fn binop(rdr: &mut StringReader, op: token::BinOp) -> token::Token {
         while !rdr.curr_is('"') {
             if is_eof(rdr) {
                 fatal_span(rdr, start_bpos, rdr.last_pos,
-                           "unterminated double quote string".to_owned());
+                           "unterminated double quote string".to_strbuf());
             }
 
             let ch = rdr.curr.unwrap();
@@ -892,7 +910,7 @@ fn binop(rdr: &mut StringReader, op: token::BinOp) -> token::Token {
               '\\' => {
                 if is_eof(rdr) {
                     fatal_span(rdr, start_bpos, rdr.last_pos,
-                           "unterminated double quote string".to_owned());
+                           "unterminated double quote string".to_strbuf());
                 }
 
                 let escaped = rdr.curr.unwrap();
@@ -918,7 +936,7 @@ fn binop(rdr: &mut StringReader, op: token::BinOp) -> token::Token {
                   }
                   c2 => {
                     fatal_span_char(rdr, escaped_pos, rdr.last_pos,
-                                    "unknown string escape".to_owned(), c2);
+                                    "unknown string escape".to_strbuf(), c2);
                   }
                 }
               }
@@ -939,11 +957,11 @@ fn binop(rdr: &mut StringReader, op: token::BinOp) -> token::Token {
 
         if is_eof(rdr) {
             fatal_span(rdr, start_bpos, rdr.last_pos,
-                       "unterminated raw string".to_owned());
+                       "unterminated raw string".to_strbuf());
         } else if !rdr.curr_is('"') {
             fatal_span_char(rdr, start_bpos, rdr.last_pos,
                             "only `#` is allowed in raw string delimitation; \
-                             found illegal character".to_owned(),
+                             found illegal character".to_strbuf(),
                             rdr.curr.unwrap());
         }
         bump(rdr);
@@ -952,7 +970,7 @@ fn binop(rdr: &mut StringReader, op: token::BinOp) -> token::Token {
         'outer: loop {
             if is_eof(rdr) {
                 fatal_span(rdr, start_bpos, rdr.last_pos,
-                           "unterminated raw string".to_owned());
+                           "unterminated raw string".to_strbuf());
             }
             if rdr.curr_is('"') {
                 content_end_bpos = rdr.last_pos;
@@ -1000,7 +1018,7 @@ fn binop(rdr: &mut StringReader, op: token::BinOp) -> token::Token {
       '%' => { return binop(rdr, token::PERCENT); }
       c => {
           fatal_span_char(rdr, rdr.last_pos, rdr.pos,
-                          "unknown start of token".to_owned(), c);
+                          "unknown start of token".to_strbuf(), c);
       }
     }
 }
@@ -1027,8 +1045,8 @@ fn mk_sh() -> diagnostic::SpanHandler {
 
     // open a string reader for the given string
     fn setup<'a>(span_handler: &'a diagnostic::SpanHandler,
-                 teststr: ~str) -> StringReader<'a> {
-        let fm = span_handler.cm.new_filemap("zebra.rs".to_owned(), teststr);
+                 teststr: StrBuf) -> StringReader<'a> {
+        let fm = span_handler.cm.new_filemap("zebra.rs".to_strbuf(), teststr);
         new_string_reader(span_handler, fm)
     }
 
@@ -1036,7 +1054,7 @@ fn setup<'a>(span_handler: &'a diagnostic::SpanHandler,
         let span_handler = mk_sh();
         let mut string_reader = setup(&span_handler,
             "/* my source file */ \
-             fn main() { println!(\"zebra\"); }\n".to_owned());
+             fn main() { println!(\"zebra\"); }\n".to_strbuf());
         let id = str_to_ident("fn");
         let tok1 = string_reader.next_token();
         let tok2 = TokenAndSpan{
@@ -1069,54 +1087,56 @@ fn mk_ident (id: &str, is_mod_name: bool) -> token::Token {
     }
 
     #[test] fn doublecolonparsing () {
-        check_tokenization(setup(&mk_sh(), "a b".to_owned()),
+        check_tokenization(setup(&mk_sh(), "a b".to_strbuf()),
                            vec!(mk_ident("a",false),
                              mk_ident("b",false)));
     }
 
     #[test] fn dcparsing_2 () {
-        check_tokenization(setup(&mk_sh(), "a::b".to_owned()),
+        check_tokenization(setup(&mk_sh(), "a::b".to_strbuf()),
                            vec!(mk_ident("a",true),
                              token::MOD_SEP,
                              mk_ident("b",false)));
     }
 
     #[test] fn dcparsing_3 () {
-        check_tokenization(setup(&mk_sh(), "a ::b".to_owned()),
+        check_tokenization(setup(&mk_sh(), "a ::b".to_strbuf()),
                            vec!(mk_ident("a",false),
                              token::MOD_SEP,
                              mk_ident("b",false)));
     }
 
     #[test] fn dcparsing_4 () {
-        check_tokenization(setup(&mk_sh(), "a:: b".to_owned()),
+        check_tokenization(setup(&mk_sh(), "a:: b".to_strbuf()),
                            vec!(mk_ident("a",true),
                              token::MOD_SEP,
                              mk_ident("b",false)));
     }
 
     #[test] fn character_a() {
-        assert_eq!(setup(&mk_sh(), "'a'".to_owned()).next_token().tok,
+        assert_eq!(setup(&mk_sh(), "'a'".to_strbuf()).next_token().tok,
                    token::LIT_CHAR('a'));
     }
 
     #[test] fn character_space() {
-        assert_eq!(setup(&mk_sh(), "' '".to_owned()).next_token().tok,
+        assert_eq!(setup(&mk_sh(), "' '".to_strbuf()).next_token().tok,
                    token::LIT_CHAR(' '));
     }
 
     #[test] fn character_escaped() {
-        assert_eq!(setup(&mk_sh(), "'\\n'".to_owned()).next_token().tok,
+        assert_eq!(setup(&mk_sh(), "'\\n'".to_strbuf()).next_token().tok,
                    token::LIT_CHAR('\n'));
     }
 
     #[test] fn lifetime_name() {
-        assert_eq!(setup(&mk_sh(), "'abc".to_owned()).next_token().tok,
+        assert_eq!(setup(&mk_sh(), "'abc".to_strbuf()).next_token().tok,
                    token::LIFETIME(token::str_to_ident("abc")));
     }
 
     #[test] fn raw_string() {
-        assert_eq!(setup(&mk_sh(), "r###\"\"#a\\b\x00c\"\"###".to_owned()).next_token().tok,
+        assert_eq!(setup(&mk_sh(),
+                         "r###\"\"#a\\b\x00c\"\"###".to_strbuf()).next_token()
+                                                                 .tok,
                    token::LIT_STR_RAW(token::str_to_ident("\"#a\\b\x00c\""), 3));
     }
 
@@ -1127,7 +1147,8 @@ fn mk_ident (id: &str, is_mod_name: bool) -> token::Token {
     }
 
     #[test] fn nested_block_comments() {
-        assert_eq!(setup(&mk_sh(), "/* /* */ */'a'".to_owned()).next_token().tok,
+        assert_eq!(setup(&mk_sh(),
+                         "/* /* */ */'a'".to_strbuf()).next_token().tok,
                    token::LIT_CHAR('a'));
     }
 
index dec6e6dd3747b9fe388e862c81976d3c45cc0012..28f235a3da0398fff283040cb16964ec108d0908 100644 (file)
@@ -77,8 +77,8 @@ pub fn parse_crate_attrs_from_file(
     inner
 }
 
-pub fn parse_crate_from_source_str(name: ~str,
-                                   source: ~str,
+pub fn parse_crate_from_source_str(name: StrBuf,
+                                   source: StrBuf,
                                    cfg: ast::CrateConfig,
                                    sess: &ParseSess)
                                    -> ast::Crate {
@@ -89,8 +89,8 @@ pub fn parse_crate_from_source_str(name: ~str,
     maybe_aborted(p.parse_crate_mod(),p)
 }
 
-pub fn parse_crate_attrs_from_source_str(name: ~str,
-                                         source: ~str,
+pub fn parse_crate_attrs_from_source_str(name: StrBuf,
+                                         source: StrBuf,
                                          cfg: ast::CrateConfig,
                                          sess: &ParseSess)
                                          -> Vec<ast::Attribute> {
@@ -102,8 +102,8 @@ pub fn parse_crate_attrs_from_source_str(name: ~str,
     inner
 }
 
-pub fn parse_expr_from_source_str(name: ~str,
-                                  source: ~str,
+pub fn parse_expr_from_source_str(name: StrBuf,
+                                  source: StrBuf,
                                   cfg: ast::CrateConfig,
                                   sess: &ParseSess)
                                   -> @ast::Expr {
@@ -111,8 +111,8 @@ pub fn parse_expr_from_source_str(name: ~str,
     maybe_aborted(p.parse_expr(), p)
 }
 
-pub fn parse_item_from_source_str(name: ~str,
-                                  source: ~str,
+pub fn parse_item_from_source_str(name: StrBuf,
+                                  source: StrBuf,
                                   cfg: ast::CrateConfig,
                                   sess: &ParseSess)
                                   -> Option<@ast::Item> {
@@ -121,8 +121,8 @@ pub fn parse_item_from_source_str(name: ~str,
     maybe_aborted(p.parse_item(attrs),p)
 }
 
-pub fn parse_meta_from_source_str(name: ~str,
-                                  source: ~str,
+pub fn parse_meta_from_source_str(name: StrBuf,
+                                  source: StrBuf,
                                   cfg: ast::CrateConfig,
                                   sess: &ParseSess)
                                   -> @ast::MetaItem {
@@ -130,8 +130,8 @@ pub fn parse_meta_from_source_str(name: ~str,
     maybe_aborted(p.parse_meta_item(),p)
 }
 
-pub fn parse_stmt_from_source_str(name: ~str,
-                                  source: ~str,
+pub fn parse_stmt_from_source_str(name: StrBuf,
+                                  source: StrBuf,
                                   cfg: ast::CrateConfig,
                                   attrs: Vec<ast::Attribute> ,
                                   sess: &ParseSess)
@@ -145,8 +145,8 @@ pub fn parse_stmt_from_source_str(name: ~str,
     maybe_aborted(p.parse_stmt(attrs),p)
 }
 
-pub fn parse_tts_from_source_str(name: ~str,
-                                 source: ~str,
+pub fn parse_tts_from_source_str(name: StrBuf,
+                                 source: StrBuf,
                                  cfg: ast::CrateConfig,
                                  sess: &ParseSess)
                                  -> Vec<ast::TokenTree> {
@@ -164,8 +164,8 @@ pub fn parse_tts_from_source_str(name: ~str,
 // Create a new parser from a source string
 pub fn new_parser_from_source_str<'a>(sess: &'a ParseSess,
                                       cfg: ast::CrateConfig,
-                                      name: ~str,
-                                      source: ~str)
+                                      name: StrBuf,
+                                      source: StrBuf)
                                       -> Parser<'a> {
     filemap_to_parser(sess, string_to_filemap(sess, source, name), cfg)
 }
@@ -225,8 +225,8 @@ pub fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
     };
     match str::from_utf8(bytes.as_slice()) {
         Some(s) => {
-            return string_to_filemap(sess, s.to_owned(),
-                                     path.as_str().unwrap().to_str())
+            return string_to_filemap(sess, s.to_strbuf(),
+                                     path.as_str().unwrap().to_strbuf())
         }
         None => err(format!("{} is not UTF-8 encoded", path.display())),
     }
@@ -235,7 +235,7 @@ pub fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
 
 // given a session and a string, add the string to
 // the session's codemap and return the new filemap
-pub fn string_to_filemap(sess: &ParseSess, source: ~str, path: ~str)
+pub fn string_to_filemap(sess: &ParseSess, source: StrBuf, path: StrBuf)
                          -> Rc<FileMap> {
     sess.span_diagnostic.cm.new_filemap(path, source)
 }
@@ -284,11 +284,11 @@ mod test {
     use util::parser_testing::{string_to_expr, string_to_item};
     use util::parser_testing::string_to_stmt;
 
-    fn to_json_str<'a, E: Encodable<json::Encoder<'a>, io::IoError>>(val: &E) -> ~str {
+    fn to_json_str<'a, E: Encodable<json::Encoder<'a>, io::IoError>>(val: &E) -> StrBuf {
         let mut writer = MemWriter::new();
         let mut encoder = json::Encoder::new(&mut writer as &mut io::Writer);
         let _ = val.encode(&mut encoder);
-        str::from_utf8(writer.unwrap().as_slice()).unwrap().to_owned()
+        str::from_utf8(writer.unwrap().as_slice()).unwrap().to_strbuf()
     }
 
     // produce a codemap::span
@@ -297,7 +297,7 @@ fn sp(a: u32, b: u32) -> Span {
     }
 
     #[test] fn path_exprs_1() {
-        assert!(string_to_expr("a".to_owned()) ==
+        assert!(string_to_expr("a".to_strbuf()) ==
                    @ast::Expr{
                     id: ast::DUMMY_NODE_ID,
                     node: ast::ExprPath(ast::Path {
@@ -316,7 +316,7 @@ fn sp(a: u32, b: u32) -> Span {
     }
 
     #[test] fn path_exprs_2 () {
-        assert!(string_to_expr("::a::b".to_owned()) ==
+        assert!(string_to_expr("::a::b".to_strbuf()) ==
                    @ast::Expr {
                     id: ast::DUMMY_NODE_ID,
                     node: ast::ExprPath(ast::Path {
@@ -341,12 +341,12 @@ fn sp(a: u32, b: u32) -> Span {
 
     #[should_fail]
     #[test] fn bad_path_expr_1() {
-        string_to_expr("::abc::def::return".to_owned());
+        string_to_expr("::abc::def::return".to_strbuf());
     }
 
     // check the token-tree-ization of macros
     #[test] fn string_to_tts_macro () {
-        let tts = string_to_tts("macro_rules! zip (($a)=>($a))".to_owned());
+        let tts = string_to_tts("macro_rules! zip (($a)=>($a))".to_strbuf());
         let tts: &[ast::TokenTree] = tts.as_slice();
         match tts {
             [ast::TTTok(_,_),
@@ -399,7 +399,7 @@ fn sp(a: u32, b: u32) -> Span {
     }
 
     #[test] fn string_to_tts_1 () {
-        let tts = string_to_tts("fn a (b : int) { b; }".to_owned());
+        let tts = string_to_tts("fn a (b : int) { b; }".to_strbuf());
         assert_eq!(to_json_str(&tts),
         "[\
     {\
@@ -523,12 +523,12 @@ fn sp(a: u32, b: u32) -> Span {
             ]\
         ]\
     }\
-]".to_owned()
+]".to_strbuf()
         );
     }
 
     #[test] fn ret_expr() {
-        assert!(string_to_expr("return d".to_owned()) ==
+        assert!(string_to_expr("return d".to_strbuf()) ==
                    @ast::Expr{
                     id: ast::DUMMY_NODE_ID,
                     node:ast::ExprRet(Some(@ast::Expr{
@@ -551,7 +551,7 @@ fn sp(a: u32, b: u32) -> Span {
     }
 
     #[test] fn parse_stmt_1 () {
-        assert!(string_to_stmt("b;".to_owned()) ==
+        assert!(string_to_stmt("b;".to_strbuf()) ==
                    @Spanned{
                        node: ast::StmtExpr(@ast::Expr {
                            id: ast::DUMMY_NODE_ID,
@@ -578,7 +578,7 @@ fn parser_done(p: Parser){
 
     #[test] fn parse_ident_pat () {
         let sess = new_parse_sess();
-        let mut parser = string_to_parser(&sess, "b".to_owned());
+        let mut parser = string_to_parser(&sess, "b".to_strbuf());
         assert!(parser.parse_pat() ==
                    @ast::Pat{id: ast::DUMMY_NODE_ID,
                              node: ast::PatIdent(
@@ -602,7 +602,7 @@ fn parser_done(p: Parser){
     // check the contents of the tt manually:
     #[test] fn parse_fundecl () {
         // this test depends on the intern order of "fn" and "int"
-        assert!(string_to_item("fn a (b : int) { b; }".to_owned()) ==
+        assert!(string_to_item("fn a (b : int) { b; }".to_strbuf()) ==
                   Some(
                       @ast::Item{ident:str_to_ident("a"),
                             attrs:Vec::new(),
@@ -694,13 +694,13 @@ fn parser_done(p: Parser){
 
     #[test] fn parse_exprs () {
         // just make sure that they parse....
-        string_to_expr("3 + 4".to_owned());
-        string_to_expr("a::z.froob(b,@(987+3))".to_owned());
+        string_to_expr("3 + 4".to_strbuf());
+        string_to_expr("a::z.froob(b,@(987+3))".to_strbuf());
     }
 
     #[test] fn attrs_fix_bug () {
         string_to_item("pub fn mk_file_writer(path: &Path, flags: &[FileFlag])
-                   -> Result<@Writer, ~str> {
+                   -> Result<@Writer, StrBuf> {
     #[cfg(windows)]
     fn wb() -> c_int {
       (O_WRONLY | libc::consts::os::extra::O_BINARY) as c_int
@@ -710,7 +710,7 @@ fn wb() -> c_int {
     fn wb() -> c_int { O_WRONLY as c_int }
 
     let mut fflags: c_int = wb();
-}".to_owned());
+}".to_strbuf());
     }
 
 }
index b9157e0043d1e0a30c51d389f2b04cc97a625cb5..b6aa47128e630991140f31745c58a02654de3766 100644 (file)
@@ -123,7 +123,7 @@ fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax) {
             ),
             ObsoleteManagedString => (
                 "managed string",
-                "use `Rc<~str>` instead of a managed string"
+                "use `Rc<StrBuf>` instead of a managed string"
             ),
             ObsoleteManagedVec => (
                 "managed vector",
index 6e9fa2f92d84114e983bc170442311db667a9151..8f3b77dd58c2d0b0a86be2092a70649806ac3b27 100644 (file)
@@ -27,7 +27,7 @@
 use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc};
 use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary};
 use ast::{ExprVec, ExprVstore, ExprVstoreSlice};
-use ast::{ExprVstoreMutSlice, ExprWhile, ExprForLoop, ExternFn, Field, FnDecl};
+use ast::{ExprVstoreMutSlice, ExprWhile, ExprForLoop, Field, FnDecl};
 use ast::{ExprVstoreUniq, Once, Many};
 use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod};
 use ast::{Ident, NormalFn, Inherited, Item, Item_, ItemStatic};
@@ -345,12 +345,12 @@ fn is_plain_ident_or_underscore(t: &token::Token) -> bool {
 
 impl<'a> Parser<'a> {
     // convert a token to a string using self's reader
-    pub fn token_to_str(token: &token::Token) -> ~str {
+    pub fn token_to_str(token: &token::Token) -> StrBuf {
         token::to_str(token)
     }
 
     // convert the current token to a string using self's reader
-    pub fn this_token_to_str(&mut self) -> ~str {
+    pub fn this_token_to_str(&mut self) -> StrBuf {
         Parser::token_to_str(&self.token)
     }
 
@@ -385,11 +385,17 @@ pub fn expect(&mut self, t: &token::Token) {
     pub fn expect_one_of(&mut self,
                          edible: &[token::Token],
                          inedible: &[token::Token]) {
-        fn tokens_to_str(tokens: &[token::Token]) -> ~str {
+        fn tokens_to_str(tokens: &[token::Token]) -> StrBuf {
             let mut i = tokens.iter();
             // This might be a sign we need a connect method on Iterator.
-            let b = i.next().map_or("".to_owned(), |t| Parser::token_to_str(t));
-            i.fold(b, |b,a| b + "`, `" + Parser::token_to_str(a))
+            let b = i.next()
+                     .map_or("".to_strbuf(), |t| Parser::token_to_str(t));
+            i.fold(b, |b,a| {
+                let mut b = b;
+                b.push_str("`, `");
+                b.push_str(Parser::token_to_str(a).as_slice());
+                b
+            })
         }
         if edible.contains(&self.token) {
             self.bump();
@@ -884,25 +890,29 @@ pub fn get_lifetime(&mut self) -> ast::Ident {
     pub fn parse_ty_bare_fn(&mut self) -> Ty_ {
         /*
 
-        [extern "ABI"] [unsafe] fn <'lt> (S) -> T
-                ^~~~^  ^~~~~~~^    ^~~~^ ^~^    ^
-                  |      |           |    |     |
-                  |      |           |    |   Return type
-                  |      |           |  Argument types
-                  |      |       Lifetimes
-                  |      |
-                  |    Function Style
-                 ABI
-
+        [unsafe] [extern "ABI"] fn <'lt> (S) -> T
+         ^~~~^           ^~~~^     ^~~~^ ^~^    ^
+           |               |         |    |     |
+           |               |         |    |   Return type
+           |               |         |  Argument types
+           |               |     Lifetimes
+           |              ABI
+        Function Style
         */
 
+        let fn_style = self.parse_unsafety();
         let abi = if self.eat_keyword(keywords::Extern) {
             self.parse_opt_abi().unwrap_or(abi::C)
         } else {
             abi::Rust
         };
 
-        let fn_style = self.parse_unsafety();
+        // NOTE: remove after a stage0 snapshot
+        let fn_style = match self.parse_unsafety() {
+            UnsafeFn => UnsafeFn,
+            NormalFn => fn_style,
+        };
+
         self.expect_keyword(keywords::Fn);
         let (decl, lifetimes) = self.parse_ty_fn_decl(true);
         return TyBareFn(@BareFnTy {
@@ -1256,6 +1266,7 @@ pub fn parse_ty(&mut self, _: bool) -> P<Ty> {
             self.expect_and();
             self.parse_borrowed_pointee()
         } else if self.is_keyword(keywords::Extern) ||
+                  self.is_keyword(keywords::Unsafe) ||
                 self.token_is_bare_fn_keyword() {
             // BARE FUNCTION
             self.parse_ty_bare_fn()
@@ -3893,7 +3904,7 @@ fn parse_item_impl(&mut self) -> ItemInfo {
         (ident, ItemImpl(generics, opt_trait, ty, meths), Some(inner_attrs))
     }
 
-    // parse a::B<~str,int>
+    // parse a::B<StrBuf,int>
     fn parse_trait_ref(&mut self) -> TraitRef {
         ast::TraitRef {
             path: self.parse_path(LifetimeAndTypesWithoutColons).path,
@@ -3901,7 +3912,7 @@ fn parse_trait_ref(&mut self) -> TraitRef {
         }
     }
 
-    // parse B + C<~str,int> + D
+    // parse B + C<StrBuf,int> + D
     fn parse_trait_ref_list(&mut self, ket: &token::Token) -> Vec<TraitRef> {
         self.parse_seq_to_before_end(
             ket,
@@ -4563,7 +4574,7 @@ fn parse_item_or_view_item(&mut self,
                 // EXTERN FUNCTION ITEM
                 let abi = opt_abi.unwrap_or(abi::C);
                 let (ident, item_, extra_attrs) =
-                    self.parse_item_fn(ExternFn, abi);
+                    self.parse_item_fn(NormalFn, abi);
                 let item = self.mk_item(lo,
                                         self.last_span.hi,
                                         ident,
@@ -4617,9 +4628,14 @@ fn parse_item_or_view_item(&mut self,
             && self.look_ahead(1u, |t| *t != token::LBRACE) {
             // UNSAFE FUNCTION ITEM
             self.bump();
+            let abi = if self.eat_keyword(keywords::Extern) {
+                self.parse_opt_abi().unwrap_or(abi::C)
+            } else {
+                abi::Rust
+            };
             self.expect_keyword(keywords::Fn);
             let (ident, item_, extra_attrs) =
-                self.parse_item_fn(UnsafeFn, abi::Rust);
+                self.parse_item_fn(UnsafeFn, abi);
             let item = self.mk_item(lo,
                                     self.last_span.hi,
                                     ident,
index e4e71baad44eba7530022f8d85982108142c1732..8fb2fe61b833d8fb669fcfa1f6429e2d2bb18800 100644 (file)
@@ -19,7 +19,6 @@
 use serialize::{Decodable, Decoder, Encodable, Encoder};
 use std::cast;
 use std::fmt;
-use std::local_data;
 use std::path::BytesContainer;
 use std::rc::Rc;
 use std::strbuf::StrBuf;
@@ -138,58 +137,62 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-pub fn binop_to_str(o: BinOp) -> ~str {
+pub fn binop_to_str(o: BinOp) -> StrBuf {
     match o {
-      PLUS => "+".to_owned(),
-      MINUS => "-".to_owned(),
-      STAR => "*".to_owned(),
-      SLASH => "/".to_owned(),
-      PERCENT => "%".to_owned(),
-      CARET => "^".to_owned(),
-      AND => "&".to_owned(),
-      OR => "|".to_owned(),
-      SHL => "<<".to_owned(),
-      SHR => ">>".to_owned()
+      PLUS => "+".to_strbuf(),
+      MINUS => "-".to_strbuf(),
+      STAR => "*".to_strbuf(),
+      SLASH => "/".to_strbuf(),
+      PERCENT => "%".to_strbuf(),
+      CARET => "^".to_strbuf(),
+      AND => "&".to_strbuf(),
+      OR => "|".to_strbuf(),
+      SHL => "<<".to_strbuf(),
+      SHR => ">>".to_strbuf()
     }
 }
 
-pub fn to_str(t: &Token) -> ~str {
+pub fn to_str(t: &Token) -> StrBuf {
     match *t {
-      EQ => "=".to_owned(),
-      LT => "<".to_owned(),
-      LE => "<=".to_owned(),
-      EQEQ => "==".to_owned(),
-      NE => "!=".to_owned(),
-      GE => ">=".to_owned(),
-      GT => ">".to_owned(),
-      NOT => "!".to_owned(),
-      TILDE => "~".to_owned(),
-      OROR => "||".to_owned(),
-      ANDAND => "&&".to_owned(),
+      EQ => "=".to_strbuf(),
+      LT => "<".to_strbuf(),
+      LE => "<=".to_strbuf(),
+      EQEQ => "==".to_strbuf(),
+      NE => "!=".to_strbuf(),
+      GE => ">=".to_strbuf(),
+      GT => ">".to_strbuf(),
+      NOT => "!".to_strbuf(),
+      TILDE => "~".to_strbuf(),
+      OROR => "||".to_strbuf(),
+      ANDAND => "&&".to_strbuf(),
       BINOP(op) => binop_to_str(op),
-      BINOPEQ(op) => binop_to_str(op) + "=",
+      BINOPEQ(op) => {
+          let mut s = binop_to_str(op);
+          s.push_str("=");
+          s
+      }
 
       /* Structural symbols */
-      AT => "@".to_owned(),
-      DOT => ".".to_owned(),
-      DOTDOT => "..".to_owned(),
-      DOTDOTDOT => "...".to_owned(),
-      COMMA => ",".to_owned(),
-      SEMI => ";".to_owned(),
-      COLON => ":".to_owned(),
-      MOD_SEP => "::".to_owned(),
-      RARROW => "->".to_owned(),
-      LARROW => "<-".to_owned(),
-      DARROW => "<->".to_owned(),
-      FAT_ARROW => "=>".to_owned(),
-      LPAREN => "(".to_owned(),
-      RPAREN => ")".to_owned(),
-      LBRACKET => "[".to_owned(),
-      RBRACKET => "]".to_owned(),
-      LBRACE => "{".to_owned(),
-      RBRACE => "}".to_owned(),
-      POUND => "#".to_owned(),
-      DOLLAR => "$".to_owned(),
+      AT => "@".to_strbuf(),
+      DOT => ".".to_strbuf(),
+      DOTDOT => "..".to_strbuf(),
+      DOTDOTDOT => "...".to_strbuf(),
+      COMMA => ",".to_strbuf(),
+      SEMI => ";".to_strbuf(),
+      COLON => ":".to_strbuf(),
+      MOD_SEP => "::".to_strbuf(),
+      RARROW => "->".to_strbuf(),
+      LARROW => "<-".to_strbuf(),
+      DARROW => "<->".to_strbuf(),
+      FAT_ARROW => "=>".to_strbuf(),
+      LPAREN => "(".to_strbuf(),
+      RPAREN => ")".to_strbuf(),
+      LBRACKET => "[".to_strbuf(),
+      RBRACKET => "]".to_strbuf(),
+      LBRACE => "{".to_strbuf(),
+      RBRACE => "}".to_strbuf(),
+      POUND => "#".to_strbuf(),
+      DOLLAR => "$".to_strbuf(),
 
       /* Literals */
       LIT_CHAR(c) => {
@@ -198,63 +201,64 @@ pub fn to_str(t: &Token) -> ~str {
               res.push_char(c);
           });
           res.push_char('\'');
-          res.into_owned()
+          res
       }
       LIT_INT(i, t) => ast_util::int_ty_to_str(t, Some(i)),
       LIT_UINT(u, t) => ast_util::uint_ty_to_str(t, Some(u)),
-      LIT_INT_UNSUFFIXED(i) => { i.to_str() }
+      LIT_INT_UNSUFFIXED(i) => { i.to_str().to_strbuf() }
       LIT_FLOAT(s, t) => {
         let mut body = StrBuf::from_str(get_ident(s).get());
         if body.as_slice().ends_with(".") {
             body.push_char('0');  // `10.f` is not a float literal
         }
-        body.push_str(ast_util::float_ty_to_str(t));
-        body.into_owned()
+        body.push_str(ast_util::float_ty_to_str(t).as_slice());
+        body
       }
       LIT_FLOAT_UNSUFFIXED(s) => {
         let mut body = StrBuf::from_str(get_ident(s).get());
         if body.as_slice().ends_with(".") {
             body.push_char('0');  // `10.f` is not a float literal
         }
-        body.into_owned()
+        body
       }
       LIT_STR(s) => {
-          format!("\"{}\"", get_ident(s).get().escape_default())
+          (format!("\"{}\"", get_ident(s).get().escape_default())).to_strbuf()
       }
       LIT_STR_RAW(s, n) => {
-          format!("r{delim}\"{string}\"{delim}",
-                  delim="#".repeat(n), string=get_ident(s))
+          (format!("r{delim}\"{string}\"{delim}",
+                  delim="#".repeat(n), string=get_ident(s))).to_strbuf()
       }
 
       /* Name components */
-      IDENT(s, _) => get_ident(s).get().to_str(),
+      IDENT(s, _) => get_ident(s).get().to_strbuf(),
       LIFETIME(s) => {
-          format!("'{}", get_ident(s))
+          (format!("'{}", get_ident(s))).to_strbuf()
       }
-      UNDERSCORE => "_".to_owned(),
+      UNDERSCORE => "_".to_strbuf(),
 
       /* Other */
-      DOC_COMMENT(s) => get_ident(s).get().to_str(),
-      EOF => "<eof>".to_owned(),
+      DOC_COMMENT(s) => get_ident(s).get().to_strbuf(),
+      EOF => "<eof>".to_strbuf(),
       INTERPOLATED(ref nt) => {
         match nt {
             &NtExpr(e) => ::print::pprust::expr_to_str(e),
             &NtMeta(e) => ::print::pprust::meta_item_to_str(e),
             _ => {
-                "an interpolated ".to_owned() +
-                    match *nt {
-                        NtItem(..) => "item".to_owned(),
-                        NtBlock(..) => "block".to_owned(),
-                        NtStmt(..) => "statement".to_owned(),
-                        NtPat(..) => "pattern".to_owned(),
-                        NtMeta(..) => fail!("should have been handled"),
-                        NtExpr(..) => fail!("should have been handled above"),
-                        NtTy(..) => "type".to_owned(),
-                        NtIdent(..) => "identifier".to_owned(),
-                        NtPath(..) => "path".to_owned(),
-                        NtTT(..) => "tt".to_owned(),
-                        NtMatchers(..) => "matcher sequence".to_owned()
-                    }
+                let mut s = "an interpolated ".to_strbuf();
+                match *nt {
+                    NtItem(..) => s.push_str("item"),
+                    NtBlock(..) => s.push_str("block"),
+                    NtStmt(..) => s.push_str("statement"),
+                    NtPat(..) => s.push_str("pattern"),
+                    NtMeta(..) => fail!("should have been handled"),
+                    NtExpr(..) => fail!("should have been handled above"),
+                    NtTy(..) => s.push_str("type"),
+                    NtIdent(..) => s.push_str("identifier"),
+                    NtPath(..) => s.push_str("path"),
+                    NtTT(..) => s.push_str("tt"),
+                    NtMatchers(..) => s.push_str("matcher sequence")
+                };
+                s
             }
         }
       }
@@ -529,11 +533,11 @@ pub fn token_to_binop(tok: &Token) -> Option<ast::BinOp> {
 // FIXME(eddyb) #8726 This should probably use a task-local reference.
 pub fn get_ident_interner() -> Rc<IdentInterner> {
     local_data_key!(key: Rc<::parse::token::IdentInterner>)
-    match local_data::get(key, |k| k.map(|k| k.clone())) {
-        Some(interner) => interner,
+    match key.get() {
+        Some(interner) => interner.clone(),
         None => {
             let interner = Rc::new(mk_fresh_ident_interner());
-            local_data::set(key, interner.clone());
+            key.replace(Some(interner.clone()));
             interner
         }
     }
index a32cad701754cbff86d771288e1dfda6e12c1878..f08cf264f8bfb0390df7f06a808be338e36ac1d0 100644 (file)
@@ -84,7 +84,7 @@ pub struct BeginToken {
 
 #[deriving(Clone)]
 pub enum Token {
-    String(~str, int),
+    String(StrBuf, int),
     Break(BreakToken),
     Begin(BeginToken),
     End,
@@ -109,13 +109,13 @@ pub fn is_hardbreak_tok(&self) -> bool {
     }
 }
 
-pub fn tok_str(t: Token) -> ~str {
+pub fn tok_str(t: Token) -> StrBuf {
     match t {
-        String(s, len) => return format!("STR({},{})", s, len),
-        Break(_) => return "BREAK".to_owned(),
-        Begin(_) => return "BEGIN".to_owned(),
-        End => return "END".to_owned(),
-        Eof => return "EOF".to_owned()
+        String(s, len) => return format!("STR({},{})", s, len).to_strbuf(),
+        Break(_) => return "BREAK".to_strbuf(),
+        Begin(_) => return "BEGIN".to_strbuf(),
+        End => return "END".to_strbuf(),
+        Eof => return "EOF".to_strbuf()
     }
 }
 
@@ -124,7 +124,7 @@ pub fn buf_str(toks: Vec<Token>,
                left: uint,
                right: uint,
                lim: uint)
-               -> ~str {
+               -> StrBuf {
     let n = toks.len();
     assert_eq!(n, szs.len());
     let mut i = left;
@@ -140,7 +140,7 @@ pub fn buf_str(toks: Vec<Token>,
         i %= n;
     }
     s.push_char(']');
-    return s.into_owned();
+    return s.into_strbuf();
 }
 
 pub enum PrintStackBreak {
@@ -585,7 +585,7 @@ pub fn print(&mut self, x: Token, l: int) -> io::IoResult<()> {
             assert_eq!(l, len);
             // assert!(l <= space);
             self.space -= len;
-            self.print_str(s)
+            self.print_str(s.as_slice())
           }
           Eof => {
             // Eof should never get here.
@@ -625,15 +625,15 @@ pub fn end(p: &mut Printer) -> io::IoResult<()> { p.pretty_print(End) }
 pub fn eof(p: &mut Printer) -> io::IoResult<()> { p.pretty_print(Eof) }
 
 pub fn word(p: &mut Printer, wrd: &str) -> io::IoResult<()> {
-    p.pretty_print(String(/* bad */ wrd.to_str(), wrd.len() as int))
+    p.pretty_print(String(/* bad */ wrd.to_strbuf(), wrd.len() as int))
 }
 
 pub fn huge_word(p: &mut Printer, wrd: &str) -> io::IoResult<()> {
-    p.pretty_print(String(/* bad */ wrd.to_str(), SIZE_INFINITY))
+    p.pretty_print(String(/* bad */ wrd.to_strbuf(), SIZE_INFINITY))
 }
 
 pub fn zero_word(p: &mut Printer, wrd: &str) -> io::IoResult<()> {
-    p.pretty_print(String(/* bad */ wrd.to_str(), 0))
+    p.pretty_print(String(/* bad */ wrd.to_strbuf(), 0))
 }
 
 pub fn spaces(p: &mut Printer, n: uint) -> io::IoResult<()> {
index 310ca18e4faf0b5e20e8a83be9a0cff223eff1c8..510ec2a370fb50aa8ad44ef9d2c33333ec39c8a0 100644 (file)
@@ -97,7 +97,7 @@ pub fn rust_printer_annotated<'a>(writer: Box<io::Writer>,
 pub fn print_crate<'a>(cm: &'a CodeMap,
                        span_diagnostic: &diagnostic::SpanHandler,
                        krate: &ast::Crate,
-                       filename: ~str,
+                       filename: StrBuf,
                        input: &mut io::Reader,
                        out: Box<io::Writer>,
                        ann: &'a PpAnn,
@@ -132,7 +132,7 @@ pub fn print_crate<'a>(cm: &'a CodeMap,
     eof(&mut s.s)
 }
 
-pub fn to_str(f: |&mut State| -> IoResult<()>) -> ~str {
+pub fn to_str(f: |&mut State| -> IoResult<()>) -> StrBuf {
     let mut s = rust_printer(box MemWriter::new());
     f(&mut s).unwrap();
     eof(&mut s.s).unwrap();
@@ -143,65 +143,65 @@ pub fn to_str(f: |&mut State| -> IoResult<()>) -> ~str {
         let (_, wr): (uint, Box<MemWriter>) = cast::transmute_copy(&s.s.out);
         let result = str::from_utf8_owned(wr.get_ref().to_owned()).unwrap();
         cast::forget(wr);
-        result
+        result.to_strbuf()
     }
 }
 
-pub fn ty_to_str(ty: &ast::Ty) -> ~str {
+pub fn ty_to_str(ty: &ast::Ty) -> StrBuf {
     to_str(|s| s.print_type(ty))
 }
 
-pub fn pat_to_str(pat: &ast::Pat) -> ~str {
+pub fn pat_to_str(pat: &ast::Pat) -> StrBuf {
     to_str(|s| s.print_pat(pat))
 }
 
-pub fn expr_to_str(e: &ast::Expr) -> ~str {
+pub fn expr_to_str(e: &ast::Expr) -> StrBuf {
     to_str(|s| s.print_expr(e))
 }
 
-pub fn lifetime_to_str(e: &ast::Lifetime) -> ~str {
+pub fn lifetime_to_str(e: &ast::Lifetime) -> StrBuf {
     to_str(|s| s.print_lifetime(e))
 }
 
-pub fn tt_to_str(tt: &ast::TokenTree) -> ~str {
+pub fn tt_to_str(tt: &ast::TokenTree) -> StrBuf {
     to_str(|s| s.print_tt(tt))
 }
 
-pub fn tts_to_str(tts: &[ast::TokenTree]) -> ~str {
+pub fn tts_to_str(tts: &[ast::TokenTree]) -> StrBuf {
     to_str(|s| s.print_tts(&tts))
 }
 
-pub fn stmt_to_str(stmt: &ast::Stmt) -> ~str {
+pub fn stmt_to_str(stmt: &ast::Stmt) -> StrBuf {
     to_str(|s| s.print_stmt(stmt))
 }
 
-pub fn item_to_str(i: &ast::Item) -> ~str {
+pub fn item_to_str(i: &ast::Item) -> StrBuf {
     to_str(|s| s.print_item(i))
 }
 
-pub fn generics_to_str(generics: &ast::Generics) -> ~str {
+pub fn generics_to_str(generics: &ast::Generics) -> StrBuf {
     to_str(|s| s.print_generics(generics))
 }
 
-pub fn ty_method_to_str(p: &ast::TypeMethod) -> ~str {
+pub fn ty_method_to_str(p: &ast::TypeMethod) -> StrBuf {
     to_str(|s| s.print_ty_method(p))
 }
 
-pub fn method_to_str(p: &ast::Method) -> ~str {
+pub fn method_to_str(p: &ast::Method) -> StrBuf {
     to_str(|s| s.print_method(p))
 }
 
-pub fn fn_block_to_str(p: &ast::FnDecl) -> ~str {
+pub fn fn_block_to_str(p: &ast::FnDecl) -> StrBuf {
     to_str(|s| s.print_fn_block_args(p))
 }
 
-pub fn path_to_str(p: &ast::Path) -> ~str {
+pub fn path_to_str(p: &ast::Path) -> StrBuf {
     to_str(|s| s.print_path(p, false))
 }
 
 pub fn fun_to_str(decl: &ast::FnDecl, fn_style: ast::FnStyle, name: ast::Ident,
                   opt_explicit_self: Option<ast::ExplicitSelf_>,
-                  generics: &ast::Generics) -> ~str {
+                  generics: &ast::Generics) -> StrBuf {
     to_str(|s| {
         try!(s.print_fn(decl, Some(fn_style), abi::Rust,
                         name, generics, opt_explicit_self, ast::Inherited));
@@ -210,7 +210,7 @@ pub fn fun_to_str(decl: &ast::FnDecl, fn_style: ast::FnStyle, name: ast::Ident,
     })
 }
 
-pub fn block_to_str(blk: &ast::Block) -> ~str {
+pub fn block_to_str(blk: &ast::Block) -> StrBuf {
     to_str(|s| {
         // containing cbox, will be closed by print-block at }
         try!(s.cbox(indent_unit));
@@ -220,30 +220,30 @@ pub fn block_to_str(blk: &ast::Block) -> ~str {
     })
 }
 
-pub fn meta_item_to_str(mi: &ast::MetaItem) -> ~str {
+pub fn meta_item_to_str(mi: &ast::MetaItem) -> StrBuf {
     to_str(|s| s.print_meta_item(mi))
 }
 
-pub fn attribute_to_str(attr: &ast::Attribute) -> ~str {
+pub fn attribute_to_str(attr: &ast::Attribute) -> StrBuf {
     to_str(|s| s.print_attribute(attr))
 }
 
-pub fn lit_to_str(l: &ast::Lit) -> ~str {
+pub fn lit_to_str(l: &ast::Lit) -> StrBuf {
     to_str(|s| s.print_literal(l))
 }
 
-pub fn explicit_self_to_str(explicit_self: ast::ExplicitSelf_) -> ~str {
+pub fn explicit_self_to_str(explicit_self: ast::ExplicitSelf_) -> StrBuf {
     to_str(|s| s.print_explicit_self(explicit_self, ast::MutImmutable).map(|_| {}))
 }
 
-pub fn variant_to_str(var: &ast::Variant) -> ~str {
+pub fn variant_to_str(var: &ast::Variant) -> StrBuf {
     to_str(|s| s.print_variant(var))
 }
 
-pub fn visibility_qualified(vis: ast::Visibility, s: &str) -> ~str {
+pub fn visibility_qualified(vis: ast::Visibility, s: &str) -> StrBuf {
     match vis {
-        ast::Public => format!("pub {}", s),
-        ast::Inherited => s.to_owned()
+        ast::Public => format!("pub {}", s).to_strbuf(),
+        ast::Inherited => s.to_strbuf()
     }
 }
 
@@ -366,10 +366,10 @@ pub fn break_offset_if_not_bol(&mut self, n: uint,
 
     // Synthesizes a comment that was not textually present in the original source
     // file.
-    pub fn synth_comment(&mut self, text: ~str) -> IoResult<()> {
+    pub fn synth_comment(&mut self, text: StrBuf) -> IoResult<()> {
         try!(word(&mut self.s, "/*"));
         try!(space(&mut self.s));
-        try!(word(&mut self.s, text));
+        try!(word(&mut self.s, text.as_slice()));
         try!(space(&mut self.s));
         word(&mut self.s, "*/")
     }
@@ -552,7 +552,8 @@ pub fn print_foreign_item(&mut self,
                 self.end() // end the outer fn box
             }
             ast::ForeignItemStatic(t, m) => {
-                try!(self.head(visibility_qualified(item.vis, "static")));
+                try!(self.head(visibility_qualified(item.vis,
+                                                    "static").as_slice()));
                 if m {
                     try!(self.word_space("mut"));
                 }
@@ -573,7 +574,8 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
         try!(self.ann.pre(self, NodeItem(item)));
         match item.node {
             ast::ItemStatic(ty, m, expr) => {
-                try!(self.head(visibility_qualified(item.vis, "static")));
+                try!(self.head(visibility_qualified(item.vis,
+                                                    "static").as_slice()));
                 if m == ast::MutMutable {
                     try!(self.word_space("mut"));
                 }
@@ -602,7 +604,8 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
                 try!(self.print_block_with_attrs(body, item.attrs.as_slice()));
             }
             ast::ItemMod(ref _mod) => {
-                try!(self.head(visibility_qualified(item.vis, "mod")));
+                try!(self.head(visibility_qualified(item.vis,
+                                                    "mod").as_slice()));
                 try!(self.print_ident(item.ident));
                 try!(self.nbsp());
                 try!(self.bopen());
@@ -619,7 +622,8 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
             ast::ItemTy(ty, ref params) => {
                 try!(self.ibox(indent_unit));
                 try!(self.ibox(0u));
-                try!(self.word_nbsp(visibility_qualified(item.vis, "type")));
+                try!(self.word_nbsp(visibility_qualified(item.vis,
+                                                         "type").as_slice()));
                 try!(self.print_ident(item.ident));
                 try!(self.print_generics(params));
                 try!(self.end()); // end the inner ibox
@@ -643,12 +647,14 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
                 if struct_def.is_virtual {
                     try!(self.word_space("virtual"));
                 }
-                try!(self.head(visibility_qualified(item.vis, "struct")));
+                try!(self.head(visibility_qualified(item.vis,
+                                                    "struct").as_slice()));
                 try!(self.print_struct(struct_def, generics, item.ident, item.span));
             }
 
             ast::ItemImpl(ref generics, ref opt_trait, ty, ref methods) => {
-                try!(self.head(visibility_qualified(item.vis, "impl")));
+                try!(self.head(visibility_qualified(item.vis,
+                                                    "impl").as_slice()));
                 if generics.is_parameterized() {
                     try!(self.print_generics(generics));
                     try!(space(&mut self.s));
@@ -674,7 +680,8 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
                 try!(self.bclose(item.span));
             }
             ast::ItemTrait(ref generics, ref sized, ref traits, ref methods) => {
-                try!(self.head(visibility_qualified(item.vis, "trait")));
+                try!(self.head(visibility_qualified(item.vis,
+                                                    "trait").as_slice()));
                 try!(self.print_ident(item.ident));
                 try!(self.print_generics(generics));
                 if *sized == ast::DynSize {
@@ -723,7 +730,7 @@ pub fn print_enum_def(&mut self, enum_definition: &ast::EnumDef,
                           generics: &ast::Generics, ident: ast::Ident,
                           span: codemap::Span,
                           visibility: ast::Visibility) -> IoResult<()> {
-        try!(self.head(visibility_qualified(visibility, "enum")));
+        try!(self.head(visibility_qualified(visibility, "enum").as_slice()));
         try!(self.print_ident(ident));
         try!(self.print_generics(generics));
         try!(space(&mut self.s));
@@ -825,7 +832,7 @@ pub fn print_tt(&mut self, tt: &ast::TokenTree) -> IoResult<()> {
         match *tt {
             ast::TTDelim(ref tts) => self.print_tts(&(tts.as_slice())),
             ast::TTTok(_, ref tk) => {
-                word(&mut self.s, parse::token::to_str(tk))
+                word(&mut self.s, parse::token::to_str(tk).as_slice())
             }
             ast::TTSeq(_, ref tts, ref sep, zerok) => {
                 try!(word(&mut self.s, "$("));
@@ -835,7 +842,8 @@ pub fn print_tt(&mut self, tt: &ast::TokenTree) -> IoResult<()> {
                 try!(word(&mut self.s, ")"));
                 match *sep {
                     Some(ref tk) => {
-                        try!(word(&mut self.s, parse::token::to_str(tk)));
+                        try!(word(&mut self.s,
+                                  parse::token::to_str(tk).as_slice()));
                     }
                     None => ()
                 }
@@ -2189,7 +2197,7 @@ pub fn print_literal(&mut self, lit: &ast::Lit) -> IoResult<()> {
         try!(self.maybe_print_comment(lit.span.lo));
         match self.next_lit(lit.span.lo) {
             Some(ref ltrl) => {
-                return word(&mut self.s, (*ltrl).lit);
+                return word(&mut self.s, (*ltrl).lit.as_slice());
             }
             _ => ()
         }
@@ -2202,16 +2210,19 @@ pub fn print_literal(&mut self, lit: &ast::Lit) -> IoResult<()> {
                 word(&mut self.s, res.into_owned())
             }
             ast::LitInt(i, t) => {
-                word(&mut self.s, ast_util::int_ty_to_str(t, Some(i)))
+                word(&mut self.s,
+                     ast_util::int_ty_to_str(t, Some(i)).as_slice())
             }
             ast::LitUint(u, t) => {
-                word(&mut self.s, ast_util::uint_ty_to_str(t, Some(u)))
+                word(&mut self.s,
+                     ast_util::uint_ty_to_str(t, Some(u)).as_slice())
             }
             ast::LitIntUnsuffixed(i) => {
                 word(&mut self.s, format!("{}", i))
             }
             ast::LitFloat(ref f, t) => {
-                word(&mut self.s, f.get() + ast_util::float_ty_to_str(t))
+                word(&mut self.s,
+                     f.get() + ast_util::float_ty_to_str(t).as_slice())
             }
             ast::LitFloatUnsuffixed(ref f) => word(&mut self.s, f.get()),
             ast::LitNil => word(&mut self.s, "()"),
@@ -2266,7 +2277,7 @@ pub fn print_comment(&mut self,
             comments::Mixed => {
                 assert_eq!(cmnt.lines.len(), 1u);
                 try!(zerobreak(&mut self.s));
-                try!(word(&mut self.s, *cmnt.lines.get(0)));
+                try!(word(&mut self.s, cmnt.lines.get(0).as_slice()));
                 zerobreak(&mut self.s)
             }
             comments::Isolated => {
@@ -2275,7 +2286,7 @@ pub fn print_comment(&mut self,
                     // Don't print empty lines because they will end up as trailing
                     // whitespace
                     if !line.is_empty() {
-                        try!(word(&mut self.s, *line));
+                        try!(word(&mut self.s, line.as_slice()));
                     }
                     try!(hardbreak(&mut self.s));
                 }
@@ -2284,13 +2295,13 @@ pub fn print_comment(&mut self,
             comments::Trailing => {
                 try!(word(&mut self.s, " "));
                 if cmnt.lines.len() == 1u {
-                    try!(word(&mut self.s, *cmnt.lines.get(0)));
+                    try!(word(&mut self.s, cmnt.lines.get(0).as_slice()));
                     hardbreak(&mut self.s)
                 } else {
                     try!(self.ibox(0u));
                     for line in cmnt.lines.iter() {
                         if !line.is_empty() {
-                            try!(word(&mut self.s, *line));
+                            try!(word(&mut self.s, line.as_slice()));
                         }
                         try!(hardbreak(&mut self.s));
                     }
@@ -2300,7 +2311,7 @@ pub fn print_comment(&mut self,
             comments::BlankLine => {
                 // We need to do at least one, possibly two hardbreaks.
                 let is_semi = match self.s.last_token() {
-                    pp::String(s, _) => ";" == s,
+                    pp::String(s, _) => ";" == s.as_slice(),
                     _ => false
                 };
                 if is_semi || self.is_begin() || self.is_end() {
@@ -2371,17 +2382,12 @@ pub fn print_fn_header_info(&mut self,
                                 opt_fn_style: Option<ast::FnStyle>,
                                 abi: abi::Abi,
                                 vis: ast::Visibility) -> IoResult<()> {
-        try!(word(&mut self.s, visibility_qualified(vis, "")));
+        try!(word(&mut self.s, visibility_qualified(vis, "").as_slice()));
+        try!(self.print_opt_fn_style(opt_fn_style));
 
         if abi != abi::Rust {
             try!(self.word_nbsp("extern"));
             try!(self.word_nbsp(abi.to_str()));
-
-            if opt_fn_style != Some(ast::ExternFn) {
-                try!(self.print_opt_fn_style(opt_fn_style));
-            }
-        } else {
-            try!(self.print_opt_fn_style(opt_fn_style));
         }
 
         word(&mut self.s, "fn")
@@ -2391,7 +2397,6 @@ pub fn print_fn_style(&mut self, s: ast::FnStyle) -> IoResult<()> {
         match s {
             ast::NormalFn => Ok(()),
             ast::UnsafeFn => self.word_nbsp("unsafe"),
-            ast::ExternFn => self.word_nbsp("extern")
         }
     }
 
@@ -2427,7 +2432,7 @@ fn test_fun_to_str() {
         let generics = ast_util::empty_generics();
         assert_eq!(&fun_to_str(&decl, ast::NormalFn, abba_ident,
                                None, &generics),
-                   &"fn abba()".to_owned());
+                   &"fn abba()".to_strbuf());
     }
 
     #[test]
@@ -2445,6 +2450,6 @@ fn test_variant_to_str() {
         });
 
         let varstr = variant_to_str(&var);
-        assert_eq!(&varstr,&"pub principal_skinner".to_owned());
+        assert_eq!(&varstr,&"pub principal_skinner".to_strbuf());
     }
 }
index d705da7b72b6301ce9db1a0fe44e2e8ead484652..7f85684572286fd05433cb563263065f9cd742ea 100644 (file)
@@ -92,7 +92,7 @@ pub fn clear(&self) {
 
 #[deriving(Clone, Eq, Hash, Ord)]
 pub struct RcStr {
-    string: Rc<~str>,
+    string: Rc<StrBuf>,
 }
 
 impl TotalEq for RcStr {}
@@ -106,7 +106,7 @@ fn cmp(&self, other: &RcStr) -> Ordering {
 impl Str for RcStr {
     #[inline]
     fn as_slice<'a>(&'a self) -> &'a str {
-        let s: &'a str = *self.string;
+        let s: &'a str = self.string.as_slice();
         s
     }
 }
@@ -121,7 +121,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 impl RcStr {
     pub fn new(string: &str) -> RcStr {
         RcStr {
-            string: Rc::new(string.to_owned()),
+            string: Rc::new(string.to_strbuf()),
         }
     }
 }
index cdf7455b1bc756c1628ffab2111dc9d810c8727b..359a8537b2b57d43818d06fce0cf8ccee0c3b4e8 100644 (file)
 use parse::token;
 
 // map a string to tts, using a made-up filename:
-pub fn string_to_tts(source_str: ~str) -> Vec<ast::TokenTree> {
+pub fn string_to_tts(source_str: StrBuf) -> Vec<ast::TokenTree> {
     let ps = new_parse_sess();
-    filemap_to_tts(&ps, string_to_filemap(&ps, source_str,"bogofile".to_owned()))
+    filemap_to_tts(&ps,
+                   string_to_filemap(&ps, source_str, "bogofile".to_strbuf()))
 }
 
 // map string to parser (via tts)
-pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: ~str) -> Parser<'a> {
-    new_parser_from_source_str(ps, Vec::new(), "bogofile".to_owned(), source_str)
+pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: StrBuf) -> Parser<'a> {
+    new_parser_from_source_str(ps,
+                               Vec::new(),
+                               "bogofile".to_strbuf(),
+                               source_str)
 }
 
-fn with_error_checking_parse<T>(s: ~str, f: |&mut Parser| -> T) -> T {
+fn with_error_checking_parse<T>(s: StrBuf, f: |&mut Parser| -> T) -> T {
     let ps = new_parse_sess();
     let mut p = string_to_parser(&ps, s);
     let x = f(&mut p);
@@ -35,28 +39,28 @@ fn with_error_checking_parse<T>(s: ~str, f: |&mut Parser| -> T) -> T {
 }
 
 // parse a string, return a crate.
-pub fn string_to_crate (source_str : ~str) -> ast::Crate {
+pub fn string_to_crate (source_str : StrBuf) -> ast::Crate {
     with_error_checking_parse(source_str, |p| {
         p.parse_crate_mod()
     })
 }
 
 // parse a string, return an expr
-pub fn string_to_expr (source_str : ~str) -> @ast::Expr {
+pub fn string_to_expr (source_str : StrBuf) -> @ast::Expr {
     with_error_checking_parse(source_str, |p| {
         p.parse_expr()
     })
 }
 
 // parse a string, return an item
-pub fn string_to_item (source_str : ~str) -> Option<@ast::Item> {
+pub fn string_to_item (source_str : StrBuf) -> Option<@ast::Item> {
     with_error_checking_parse(source_str, |p| {
         p.parse_item(Vec::new())
     })
 }
 
 // parse a string, return a stmt
-pub fn string_to_stmt(source_str : ~str) -> @ast::Stmt {
+pub fn string_to_stmt(source_str : StrBuf) -> @ast::Stmt {
     with_error_checking_parse(source_str, |p| {
         p.parse_stmt(Vec::new())
     })
@@ -64,7 +68,7 @@ pub fn string_to_stmt(source_str : ~str) -> @ast::Stmt {
 
 // parse a string, return a pat. Uses "irrefutable"... which doesn't
 // (currently) affect parsing.
-pub fn string_to_pat(source_str: ~str) -> @ast::Pat {
+pub fn string_to_pat(source_str: StrBuf) -> @ast::Pat {
     string_to_parser(&new_parse_sess(), source_str).parse_pat()
 }
 
diff --git a/src/test/auxiliary/issue-11680.rs b/src/test/auxiliary/issue-11680.rs
new file mode 100644 (file)
index 0000000..249a1ba
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+enum Foo {
+    Bar(int)
+}
+
+pub mod test {
+    enum Foo {
+        Bar(int)
+    }
+}
index a2c7e3533d8a7794340a603487ce19439721272e..670673fe047cc00bd2144583aa1810150d965f4f 100644 (file)
@@ -15,7 +15,6 @@
 extern crate syntax;
 
 use std::any::Any;
-use std::local_data;
 use syntax::ast::Name;
 use syntax::ext::base::SyntaxExtension;
 
@@ -30,6 +29,6 @@ fn drop(&mut self) {}
 #[macro_registrar]
 pub fn registrar(_: |Name, SyntaxExtension|) {
     local_data_key!(foo: Box<Any:Send>);
-    local_data::set(foo, box Foo { foo: 10 } as Box<Any:Send>);
+    foo.replace(Some(box Foo { foo: 10 } as Box<Any:Send>));
 }
 
index 4405245b9a0e1279e72add3e5bb5d55cc47598e2..6a8a56b4f1f8a2a4ce036226ef5e37775b7bdc20 100644 (file)
@@ -90,6 +90,7 @@ fn vector<M: MutableMap<uint, uint>>(map: &mut M, n_keys: uint, dist: &[uint]) {
 
 fn main() {
     let args = os::args();
+    let args = args.as_slice();
     let n_keys = {
         if args.len() == 2 {
             from_str::<uint>(args[1]).unwrap()
index 96f3c6814ab931f6170e1a4b77fb29cd606c8723..b1181a3c17c5ad24d8a3666e45043236fbcf8229 100644 (file)
@@ -155,6 +155,7 @@ fn empty_results() -> Results {
 
 fn main() {
     let args = os::args();
+    let args = args.as_slice();
     let num_keys = {
         if args.len() == 2 {
             from_str::<uint>(args[1]).unwrap()
index 902f2c72409ef8b8ceda31ecb8d6eb764ef491ae..7e54198bd3961655e4313fbfe103b942fc55f8c4 100644 (file)
@@ -24,7 +24,7 @@
 use std::io::File;
 
 macro_rules! bench (
-    ($argv:expr, $id:ident) => (maybe_run_test($argv, stringify!($id).to_owned(), $id))
+    ($argv:expr, $id:ident) => (maybe_run_test($argv.as_slice(), stringify!($id).to_owned(), $id))
 )
 
 fn main() {
index 044c4b07d443e5a896e7a65e98fa11cd5c634e7a..bbe6b6c23f0f97082a618803abc7d7a00887b997 100644 (file)
@@ -61,6 +61,7 @@ fn run_pair(n: uint) {
 fn main() {
 
     let args = os::args();
+    let args = args.as_slice();
     let n = if args.len() == 3 {
         from_str::<uint>(args[1]).unwrap()
     } else {
index 1a7302207d968857a30e34ece9624c669915fe82..29cee668389f873d89d557508625e63f43b6d265 100644 (file)
@@ -31,6 +31,7 @@ fn parfib(n: uint) -> uint {
 fn main() {
 
     let args = os::args();
+    let args = args.as_slice();
     let n = if args.len() == 2 {
         from_str::<uint>(args[1]).unwrap()
     } else {
index 4f07660779b2692c8c5a3c9647cda6017f221fd2..48d4a41c1a39aae1f9d7032ffc8d990bccd3a7f4 100644 (file)
@@ -28,6 +28,7 @@ fn start(argc: int, argv: **u8) -> int {
 fn main() {
 
     let args = os::args();
+    let args = args.as_slice();
     let n = if args.len() == 2 {
         from_str::<uint>(args[1]).unwrap()
     } else {
index 49184e188ebb61fbcd08efb0e93a91f3028c18b9..8914c5b327ecc6f843699269ca576a4684a4e31c 100644 (file)
@@ -40,6 +40,7 @@ fn bottom_up_tree<'r>(arena: &'r TypedArena<Tree<'r>>, item: int, depth: int)
 
 fn main() {
     let args = std::os::args();
+    let args = args.as_slice();
     let n = if std::os::getenv("RUST_BENCH").is_some() {
         17
     } else if args.len() <= 1u {
index 7587a21a9df0d0d20aec525d0a18bea7e6b2293f..07e5b08c37ccb996ce33065e420968f728359b2b 100644 (file)
@@ -194,7 +194,7 @@ fn main() {
     let nn = if std::os::getenv("RUST_BENCH").is_some() {
         200000
     } else {
-        std::os::args().get(1).and_then(|arg| from_str(*arg)).unwrap_or(600)
+        std::os::args().as_slice().get(1).and_then(|arg| from_str(*arg)).unwrap_or(600)
     };
 
     print_complements();
index 4bea355472de17838940fe727bf6c56614d3fcbe..3525b90d3f681c2fddbefa8aefc5aed08cd847a2 100644 (file)
@@ -53,7 +53,7 @@ fn fannkuch(n: uint, i: uint) -> (int, int) {
 }
 
 fn main() {
-    let n = std::os::args().get(1).and_then(|arg| from_str(*arg)).unwrap_or(2u);
+    let n = std::os::args().as_slice().get(1).and_then(|arg| from_str(*arg)).unwrap_or(2u);
 
     let (tx, rx) = channel();
     for i in range(0, n) {
index 01b75fa422f924474eb9a2e5bdfcb6923e740bc8..3f8d3275b64f9456c33312b2da515b2b2e0abc3a 100644 (file)
@@ -177,6 +177,7 @@ fn make(&mut self, n: uint) -> IoResult<()> {
 
 fn main() {
     let args = os::args();
+    let args = args.as_slice();
     let n = if args.len() > 1 {
         from_str::<uint>(args[1]).unwrap()
     } else {
index 76ac8407d60c57a77fb1332d2334445e6f219c40..c526ef54caff2277c9af923bca84ec485929ca07 100644 (file)
@@ -74,6 +74,7 @@ fn make_fasta<W: Writer, I: Iterator<u8>>(
 
 fn run<W: Writer>(writer: &mut W) {
     let args = os::args();
+    let args = args.as_slice();
     let n = if os::getenv("RUST_BENCH").is_some() {
         25000000
     } else if args.len() <= 1u {
index 659270b555427773ea941a367800e1ca2a0a04a8..e2bcc55d139828ca5da5186c4f25b242ce27a17a 100644 (file)
@@ -72,7 +72,7 @@ fn sortKV(mut orig: Vec<(Vec<u8> ,f64)> ) -> Vec<(Vec<u8> ,f64)> {
 
 // given a map, search for the frequency of a pattern
 fn find(mm: &HashMap<Vec<u8> , uint>, key: ~str) -> uint {
-   let key = key.into_ascii().to_lower().into_str();
+   let key = key.into_ascii().as_slice().to_lower().into_str();
    match mm.find_equiv(&key.as_bytes()) {
       option::None      => { return 0u; }
       option::Some(&num) => { return num; }
index e7b4d0a5c1c6d346bb5e92a0f5c4e48fe1e2f69e..ee715aecec4fcb9ff1a76ed6658dfdbf372b3bf9 100644 (file)
@@ -65,6 +65,7 @@ fn mandelbrot<W: io::Writer>(w: uint, mut out: W) -> io::IoResult<()> {
 
 fn main() {
     let args = std::os::args();
+    let args = args.as_slice();
     let res = if args.len() < 2 {
         println!("Test mode: do not dump the image because it's not utf8, \
                   which interferes with the test runner.");
index 6e86f5205f017a84ad06d44b0609032763214737..cb46c542f5bc84c03af85f141d9877f5226b301c 100644 (file)
@@ -190,7 +190,7 @@ fn to_utf8(raw_sol: &List<u64>) -> ~str {
             }
         }
     }
-    std::str::from_utf8_owned(sol.move_iter().collect()).unwrap()
+    std::str::from_utf8(sol.as_slice()).unwrap().to_owned()
 }
 
 // Prints a solution in ~str form.
@@ -270,6 +270,7 @@ fn search(
 
 fn main () {
     let args = std::os::args();
+    let args = args.as_slice();
     let stop_after = if args.len() <= 1 {
         2098
     } else {
index 71cd176a836ff86c0e9b941088f1afb43de3054b..49356e6e6458ebaf9a4444910c449ca2c28b6b96 100644 (file)
@@ -88,6 +88,7 @@ fn pidigits(n: int) {
 
 fn main() {
     let args = std::os::args();
+    let args = args.as_slice();
     let n = if args.len() < 2 {
         512
     } else {
index e63c78d50af72272a88eba230d5ae86d3e8ebd6e..70a0e7a957c6b0aa9aa68f5c425f7eed374e7e45 100644 (file)
@@ -94,6 +94,7 @@ fn mult_AtAv(v: Arc<RWLock<Vec<f64>>>, out: Arc<RWLock<Vec<f64>>>,
 
 fn main() {
     let args = os::args();
+    let args = args.as_slice();
     let n = if os::getenv("RUST_BENCH").is_some() {
         5500
     } else if args.len() < 2 {
index a845481f0e0283c3606ab947a4d0a3d828f97e59..60485f40ba4e0f064e268b0fe8420082d8c2e151 100644 (file)
@@ -35,6 +35,7 @@ fn roundtrip(id: int, tx: Sender<int>, rx: Receiver<int>) {
 
 fn main() {
     let args = std::os::args();
+    let args = args.as_slice();
     let token = if std::os::getenv("RUST_BENCH").is_some() {
         2000000
     } else {
index d1541f23c70c88f693ef5085e899cf7969f2fe70..2344bd0f090fdbe1c40cdee4dd3264fec770dde9 100644 (file)
@@ -10,8 +10,6 @@
 
 // Testing that we can't store a reference it task-local storage
 
-use std::local_data;
-
 local_data_key!(key: @&int)
 //~^ ERROR missing lifetime specifier
 
diff --git a/src/test/compile-fail/issue-11493.rs b/src/test/compile-fail/issue-11493.rs
new file mode 100644 (file)
index 0000000..af42a93
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file must never have a trailing newline
+
+fn main() {
+    let x = Some(3);
+    let y = x.as_ref().unwrap_or(&5); //~ ERROR: borrowed value does not live long enough
+}
\ No newline at end of file
diff --git a/src/test/compile-fail/issue-11680.rs b/src/test/compile-fail/issue-11680.rs
new file mode 100644 (file)
index 0000000..9c9663a
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:issue-11680.rs
+
+extern crate other = "issue-11680";
+
+fn main() {
+    let _b = other::Bar(1);
+    //~^ ERROR: variant `Bar` is private
+
+    let _b = other::test::Bar(1);
+    //~^ ERROR: variant `Bar` is private
+}
index e87d57aaa5623cd3beaa1a6b852f5b3b9acaca69..ec0e656cc292740d5294cc0a65b7d720a58daaf9 100644 (file)
@@ -8,8 +8,6 @@
 // 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 {
@@ -17,6 +15,6 @@ mod bar {
 }
 
 fn main() {
-    local_data::set(bar::baz, -10.0);
+    bar::baz.replace(Some(-10.0));
     //~^ ERROR static `baz` is private
 }
index 492a0afff3003bc1fe5a08ba6b4d81685a0cf86e..f7e5964fa2450da2db3f2d8bec82d5559479e474 100644 (file)
@@ -26,5 +26,4 @@ fn test1() {
 fn test2() {
     let x: Foo<_> = Bar::<uint>;
     //~^ ERROR mismatched types: expected `Foo<<generic #0>>` but found `Bar<uint>`
-    //~^^ ERROR cannot determine a type for this local variable: unconstrained type
 }
diff --git a/src/test/debug-info/basic-types-globals-metadata.rs b/src/test/debug-info/basic-types-globals-metadata.rs
deleted file mode 100644 (file)
index bf6d63f..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-win32: FIXME #13256
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-// debugger:whatis 'basic-types-globals-metadata::B'
-// check:type = bool
-// debugger:whatis 'basic-types-globals-metadata::I'
-// check:type = int
-// debugger:whatis 'basic-types-globals-metadata::C'
-// check:type = char
-// debugger:whatis 'basic-types-globals-metadata::I8'
-// check:type = i8
-// debugger:whatis 'basic-types-globals-metadata::I16'
-// check:type = i16
-// debugger:whatis 'basic-types-globals-metadata::I32'
-// check:type = i32
-// debugger:whatis 'basic-types-globals-metadata::I64'
-// check:type = i64
-// debugger:whatis 'basic-types-globals-metadata::U'
-// check:type = uint
-// debugger:whatis 'basic-types-globals-metadata::U8'
-// check:type = u8
-// debugger:whatis 'basic-types-globals-metadata::U16'
-// check:type = u16
-// debugger:whatis 'basic-types-globals-metadata::U32'
-// check:type = u32
-// debugger:whatis 'basic-types-globals-metadata::U64'
-// check:type = u64
-// debugger:whatis 'basic-types-globals-metadata::F32'
-// check:type = f32
-// debugger:whatis 'basic-types-globals-metadata::F64'
-// check:type = f64
-// debugger:continue
-
-#![allow(unused_variable)]
-#![allow(dead_code)]
-
-
-static B: bool = false;
-static I: int = -1;
-static C: char = 'a';
-static I8: i8 = 68;
-static I16: i16 = -16;
-static I32: i32 = -32;
-static I64: i64 = -64;
-static U: uint = 1;
-static U8: u8 = 100;
-static U16: u16 = 16;
-static U32: u32 = 32;
-static U64: u64 = 64;
-static F32: f32 = 2.5;
-static F64: f64 = 3.5;
-
-fn main() {
-    _zzz();
-
-    let a = (B, I, C, I8, I16, I32, I64, U, U8, U16, U32, U64, F32, F64);
-}
-
-fn _zzz() {()}
diff --git a/src/test/debug-info/basic-types-globals.rs b/src/test/debug-info/basic-types-globals.rs
deleted file mode 100644 (file)
index cdc3132..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Caveats - gdb prints any 8-bit value (meaning rust I8 and u8 values)
-// as its numerical value along with its associated ASCII char, there
-// doesn't seem to be any way around this. Also, gdb doesn't know
-// about UTF-32 character encoding and will print a rust char as only
-// its numerical value.
-
-// ignore-win32: FIXME #13256
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-// debugger:print 'basic-types-globals::B'
-// check:$1 = false
-// debugger:print 'basic-types-globals::I'
-// check:$2 = -1
-// debugger:print 'basic-types-globals::C'
-// check:$3 = 97
-// debugger:print/d 'basic-types-globals::I8'
-// check:$4 = 68
-// debugger:print 'basic-types-globals::I16'
-// check:$5 = -16
-// debugger:print 'basic-types-globals::I32'
-// check:$6 = -32
-// debugger:print 'basic-types-globals::I64'
-// check:$7 = -64
-// debugger:print 'basic-types-globals::U'
-// check:$8 = 1
-// debugger:print/d 'basic-types-globals::U8'
-// check:$9 = 100
-// debugger:print 'basic-types-globals::U16'
-// check:$10 = 16
-// debugger:print 'basic-types-globals::U32'
-// check:$11 = 32
-// debugger:print 'basic-types-globals::U64'
-// check:$12 = 64
-// debugger:print 'basic-types-globals::F32'
-// check:$13 = 2.5
-// debugger:print 'basic-types-globals::F64'
-// check:$14 = 3.5
-// debugger:continue
-
-#![allow(unused_variable)]
-
-static B: bool = false;
-static I: int = -1;
-static C: char = 'a';
-static I8: i8 = 68;
-static I16: i16 = -16;
-static I32: i32 = -32;
-static I64: i64 = -64;
-static U: uint = 1;
-static U8: u8 = 100;
-static U16: u16 = 16;
-static U32: u32 = 32;
-static U64: u64 = 64;
-static F32: f32 = 2.5;
-static F64: f64 = 3.5;
-
-fn main() {
-    _zzz();
-
-    let a = (B, I, C, I8, I16, I32, I64, U, U8, U16, U32, U64, F32, F64);
-}
-
-fn _zzz() {()}
diff --git a/src/test/debug-info/basic-types-metadata.rs b/src/test/debug-info/basic-types-metadata.rs
deleted file mode 100644 (file)
index ae5d3a8..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-// debugger:whatis unit
-// check:type = ()
-// debugger:whatis b
-// check:type = bool
-// debugger:whatis i
-// check:type = int
-// debugger:whatis c
-// check:type = char
-// debugger:whatis i8
-// check:type = i8
-// debugger:whatis i16
-// check:type = i16
-// debugger:whatis i32
-// check:type = i32
-// debugger:whatis i64
-// check:type = i64
-// debugger:whatis u
-// check:type = uint
-// debugger:whatis u8
-// check:type = u8
-// debugger:whatis u16
-// check:type = u16
-// debugger:whatis u32
-// check:type = u32
-// debugger:whatis u64
-// check:type = u64
-// debugger:whatis f32
-// check:type = f32
-// debugger:whatis f64
-// check:type = f64
-// debugger:info functions _yyy
-// check:[...]![...]_yyy([...])([...]);
-// debugger:continue
-
-#![allow(unused_variable)]
-
-fn main() {
-    let unit: () = ();
-    let b: bool = false;
-    let i: int = -1;
-    let c: char = 'a';
-    let i8: i8 = 68;
-    let i16: i16 = -16;
-    let i32: i32 = -32;
-    let i64: i64 = -64;
-    let u: uint = 1;
-    let u8: u8 = 100;
-    let u16: u16 = 16;
-    let u32: u32 = 32;
-    let u64: u64 = 64;
-    let f32: f32 = 2.5;
-    let f64: f64 = 3.5;
-    _zzz();
-    if 1 == 1 { _yyy(); }
-}
-
-fn _zzz() {()}
-fn _yyy() -> ! {fail!()}
diff --git a/src/test/debug-info/basic-types-mut-globals.rs b/src/test/debug-info/basic-types-mut-globals.rs
deleted file mode 100644 (file)
index 1580f73..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Caveats - gdb prints any 8-bit value (meaning rust I8 and u8 values)
-// as its numerical value along with its associated ASCII char, there
-// doesn't seem to be any way around this. Also, gdb doesn't know
-// about UTF-32 character encoding and will print a rust char as only
-// its numerical value.
-
-// ignore-win32: FIXME #13256
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// Check initializers
-// debugger:print 'basic-types-mut-globals::B'
-// check:$1 = false
-// debugger:print 'basic-types-mut-globals::I'
-// check:$2 = -1
-// debugger:print 'basic-types-mut-globals::C'
-// check:$3 = 97
-// debugger:print/d 'basic-types-mut-globals::I8'
-// check:$4 = 68
-// debugger:print 'basic-types-mut-globals::I16'
-// check:$5 = -16
-// debugger:print 'basic-types-mut-globals::I32'
-// check:$6 = -32
-// debugger:print 'basic-types-mut-globals::I64'
-// check:$7 = -64
-// debugger:print 'basic-types-mut-globals::U'
-// check:$8 = 1
-// debugger:print/d 'basic-types-mut-globals::U8'
-// check:$9 = 100
-// debugger:print 'basic-types-mut-globals::U16'
-// check:$10 = 16
-// debugger:print 'basic-types-mut-globals::U32'
-// check:$11 = 32
-// debugger:print 'basic-types-mut-globals::U64'
-// check:$12 = 64
-// debugger:print 'basic-types-mut-globals::F32'
-// check:$13 = 2.5
-// debugger:print 'basic-types-mut-globals::F64'
-// check:$14 = 3.5
-// debugger:continue
-
-// Check new values
-// debugger:print 'basic-types-mut-globals'::B
-// check:$15 = true
-// debugger:print 'basic-types-mut-globals'::I
-// check:$16 = 2
-// debugger:print 'basic-types-mut-globals'::C
-// check:$17 = 102
-// debugger:print/d 'basic-types-mut-globals'::I8
-// check:$18 = 78
-// debugger:print 'basic-types-mut-globals'::I16
-// check:$19 = -26
-// debugger:print 'basic-types-mut-globals'::I32
-// check:$20 = -12
-// debugger:print 'basic-types-mut-globals'::I64
-// check:$21 = -54
-// debugger:print 'basic-types-mut-globals'::U
-// check:$22 = 5
-// debugger:print/d 'basic-types-mut-globals'::U8
-// check:$23 = 20
-// debugger:print 'basic-types-mut-globals'::U16
-// check:$24 = 32
-// debugger:print 'basic-types-mut-globals'::U32
-// check:$25 = 16
-// debugger:print 'basic-types-mut-globals'::U64
-// check:$26 = 128
-// debugger:print 'basic-types-mut-globals'::F32
-// check:$27 = 5.75
-// debugger:print 'basic-types-mut-globals'::F64
-// check:$28 = 9.25
-
-// debugger:detach
-// debugger:quit
-
-#![allow(unused_variable)]
-
-static mut B: bool = false;
-static mut I: int = -1;
-static mut C: char = 'a';
-static mut I8: i8 = 68;
-static mut I16: i16 = -16;
-static mut I32: i32 = -32;
-static mut I64: i64 = -64;
-static mut U: uint = 1;
-static mut U8: u8 = 100;
-static mut U16: u16 = 16;
-static mut U32: u32 = 32;
-static mut U64: u64 = 64;
-static mut F32: f32 = 2.5;
-static mut F64: f64 = 3.5;
-
-fn main() {
-    _zzz();
-
-    unsafe {
-        B = true;
-        I = 2;
-        C = 'f';
-        I8 = 78;
-        I16 = -26;
-        I32 = -12;
-        I64 = -54;
-        U = 5;
-        U8 = 20;
-        U16 = 32;
-        U32 = 16;
-        U64 = 128;
-        F32 = 5.75;
-        F64 = 9.25;
-    }
-
-    _zzz();
-}
-
-fn _zzz() {()}
diff --git a/src/test/debug-info/basic-types.rs b/src/test/debug-info/basic-types.rs
deleted file mode 100644 (file)
index 9c32fcf..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Caveats - gdb prints any 8-bit value (meaning rust i8 and u8 values)
-// as its numerical value along with its associated ASCII char, there
-// doesn't seem to be any way around this. Also, gdb doesn't know
-// about UTF-32 character encoding and will print a rust char as only
-// its numerical value.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-// debugger:print b
-// check:$1 = false
-// debugger:print i
-// check:$2 = -1
-// debugger:print c
-// check:$3 = 97
-// debugger:print/d i8
-// check:$4 = 68
-// debugger:print i16
-// check:$5 = -16
-// debugger:print i32
-// check:$6 = -32
-// debugger:print i64
-// check:$7 = -64
-// debugger:print u
-// check:$8 = 1
-// debugger:print/d u8
-// check:$9 = 100
-// debugger:print u16
-// check:$10 = 16
-// debugger:print u32
-// check:$11 = 32
-// debugger:print u64
-// check:$12 = 64
-// debugger:print f32
-// check:$13 = 2.5
-// debugger:print f64
-// check:$14 = 3.5
-
-#![allow(unused_variable)]
-
-fn main() {
-    let b: bool = false;
-    let i: int = -1;
-    let c: char = 'a';
-    let i8: i8 = 68;
-    let i16: i16 = -16;
-    let i32: i32 = -32;
-    let i64: i64 = -64;
-    let u: uint = 1;
-    let u8: u8 = 100;
-    let u16: u16 = 16;
-    let u32: u32 = 32;
-    let u64: u64 = 64;
-    let f32: f32 = 2.5;
-    let f64: f64 = 3.5;
-    _zzz();
-}
-
-fn _zzz() {()}
diff --git a/src/test/debug-info/borrowed-basic.rs b/src/test/debug-info/borrowed-basic.rs
deleted file mode 100644 (file)
index 3d0f663..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// Gdb doesn't know about UTF-32 character encoding and will print a rust char as only
-// its numerical value.
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-// debugger:print *bool_ref
-// check:$1 = true
-
-// debugger:print *int_ref
-// check:$2 = -1
-
-// debugger:print *char_ref
-// check:$3 = 97
-
-// debugger:print *i8_ref
-// check:$4 = 68 'D'
-
-// debugger:print *i16_ref
-// check:$5 = -16
-
-// debugger:print *i32_ref
-// check:$6 = -32
-
-// debugger:print *i64_ref
-// check:$7 = -64
-
-// debugger:print *uint_ref
-// check:$8 = 1
-
-// debugger:print *u8_ref
-// check:$9 = 100 'd'
-
-// debugger:print *u16_ref
-// check:$10 = 16
-
-// debugger:print *u32_ref
-// check:$11 = 32
-
-// debugger:print *u64_ref
-// check:$12 = 64
-
-// debugger:print *f32_ref
-// check:$13 = 2.5
-
-// debugger:print *f64_ref
-// check:$14 = 3.5
-
-#![allow(unused_variable)]
-
-fn main() {
-    let bool_val: bool = true;
-    let bool_ref: &bool = &bool_val;
-
-    let int_val: int = -1;
-    let int_ref: &int = &int_val;
-
-    let char_val: char = 'a';
-    let char_ref: &char = &char_val;
-
-    let i8_val: i8 = 68;
-    let i8_ref: &i8 = &i8_val;
-
-    let i16_val: i16 = -16;
-    let i16_ref: &i16 = &i16_val;
-
-    let i32_val: i32 = -32;
-    let i32_ref: &i32 = &i32_val;
-
-    let uint_val: i64 = -64;
-    let i64_ref: &i64 = &uint_val;
-
-    let uint_val: uint = 1;
-    let uint_ref: &uint = &uint_val;
-
-    let u8_val: u8 = 100;
-    let u8_ref: &u8 = &u8_val;
-
-    let u16_val: u16 = 16;
-    let u16_ref: &u16 = &u16_val;
-
-    let u32_val: u32 = 32;
-    let u32_ref: &u32 = &u32_val;
-
-    let u64_val: u64 = 64;
-    let u64_ref: &u64 = &u64_val;
-
-    let f32_val: f32 = 2.5;
-    let f32_ref: &f32 = &f32_val;
-
-    let f64_val: f64 = 3.5;
-    let f64_ref: &f64 = &f64_val;
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/borrowed-c-style-enum.rs b/src/test/debug-info/borrowed-c-style-enum.rs
deleted file mode 100644 (file)
index 4007e35..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print *the_a_ref
-// check:$1 = TheA
-
-// debugger:print *the_b_ref
-// check:$2 = TheB
-
-// debugger:print *the_c_ref
-// check:$3 = TheC
-
-#![allow(unused_variable)]
-
-enum ABC { TheA, TheB, TheC }
-
-fn main() {
-    let the_a = TheA;
-    let the_a_ref: &ABC = &the_a;
-
-    let the_b = TheB;
-    let the_b_ref: &ABC = &the_b;
-
-    let the_c = TheC;
-    let the_c_ref: &ABC = &the_c;
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/borrowed-enum.rs b/src/test/debug-info/borrowed-enum.rs
deleted file mode 100644 (file)
index 3512bc6..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print *the_a_ref
-// check:$1 = {{TheA, x = 0, y = 8970181431921507452}, {TheA, 0, 2088533116, 2088533116}}
-
-// debugger:print *the_b_ref
-// check:$2 = {{TheB, x = 0, y = 1229782938247303441}, {TheB, 0, 286331153, 286331153}}
-
-// debugger:print *univariant_ref
-// check:$3 = {4820353753753434}
-
-#![allow(unused_variable)]
-#![feature(struct_variant)]
-
-// 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 ABC {
-    TheA { x: i64, y: i64 },
-    TheB (i64, i32, i32),
-}
-
-// This is a special case since it does not have the implicit discriminant field.
-enum Univariant {
-    TheOnlyCase(i64)
-}
-
-fn main() {
-
-    // 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452
-    // 0b01111100011111000111110001111100 = 2088533116
-    // 0b0111110001111100 = 31868
-    // 0b01111100 = 124
-    let the_a = TheA { x: 0, y: 8970181431921507452 };
-    let the_a_ref: &ABC = &the_a;
-
-    // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
-    // 0b00010001000100010001000100010001 = 286331153
-    // 0b0001000100010001 = 4369
-    // 0b00010001 = 17
-    let the_b = TheB (0, 286331153, 286331153);
-    let the_b_ref: &ABC = &the_b;
-
-    let univariant = TheOnlyCase(4820353753753434);
-    let univariant_ref: &Univariant = &univariant;
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/borrowed-managed-basic.rs b/src/test/debug-info/borrowed-managed-basic.rs
deleted file mode 100644 (file)
index e12ebe6..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-#![feature(managed_boxes)]
-
-// Gdb doesn't know about UTF-32 character encoding and will print a rust char as only
-// its numerical value.
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-// debugger:print *bool_ref
-// check:$1 = true
-
-// debugger:print *int_ref
-// check:$2 = -1
-
-// debugger:print *char_ref
-// check:$3 = 97
-
-// debugger:print/d *i8_ref
-// check:$4 = 68
-
-// debugger:print *i16_ref
-// check:$5 = -16
-
-// debugger:print *i32_ref
-// check:$6 = -32
-
-// debugger:print *i64_ref
-// check:$7 = -64
-
-// debugger:print *uint_ref
-// check:$8 = 1
-
-// debugger:print/d *u8_ref
-// check:$9 = 100
-
-// debugger:print *u16_ref
-// check:$10 = 16
-
-// debugger:print *u32_ref
-// check:$11 = 32
-
-// debugger:print *u64_ref
-// check:$12 = 64
-
-// debugger:print *f32_ref
-// check:$13 = 2.5
-
-// debugger:print *f64_ref
-// check:$14 = 3.5
-
-#![allow(unused_variable)]
-
-fn main() {
-    let bool_box: @bool = @true;
-    let bool_ref: &bool = bool_box;
-
-    let int_box: @int = @-1;
-    let int_ref: &int = int_box;
-
-    let char_box: @char = @'a';
-    let char_ref: &char = char_box;
-
-    let i8_box: @i8 = @68;
-    let i8_ref: &i8 = i8_box;
-
-    let i16_box: @i16 = @-16;
-    let i16_ref: &i16 = i16_box;
-
-    let i32_box: @i32 = @-32;
-    let i32_ref: &i32 = i32_box;
-
-    let i64_box: @i64 = @-64;
-    let i64_ref: &i64 = i64_box;
-
-    let uint_box: @uint = @1;
-    let uint_ref: &uint = uint_box;
-
-    let u8_box: @u8 = @100;
-    let u8_ref: &u8 = u8_box;
-
-    let u16_box: @u16 = @16;
-    let u16_ref: &u16 = u16_box;
-
-    let u32_box: @u32 = @32;
-    let u32_ref: &u32 = u32_box;
-
-    let u64_box: @u64 = @64;
-    let u64_ref: &u64 = u64_box;
-
-    let f32_box: @f32 = @2.5;
-    let f32_ref: &f32 = f32_box;
-
-    let f64_box: @f64 = @3.5;
-    let f64_ref: &f64 = f64_box;
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/borrowed-struct.rs b/src/test/debug-info/borrowed-struct.rs
deleted file mode 100644 (file)
index e271a22..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print *stack_val_ref
-// check:$1 = {x = 10, y = 23.5}
-
-// debugger:print *stack_val_interior_ref_1
-// check:$2 = 10
-
-// debugger:print *stack_val_interior_ref_2
-// check:$3 = 23.5
-
-// debugger:print *ref_to_unnamed
-// check:$4 = {x = 11, y = 24.5}
-
-// debugger:print *managed_val_ref
-// check:$5 = {x = 12, y = 25.5}
-
-// debugger:print *managed_val_interior_ref_1
-// check:$6 = 12
-
-// debugger:print *managed_val_interior_ref_2
-// check:$7 = 25.5
-
-// debugger:print *unique_val_ref
-// check:$8 = {x = 13, y = 26.5}
-
-// debugger:print *unique_val_interior_ref_1
-// check:$9 = 13
-
-// debugger:print *unique_val_interior_ref_2
-// check:$10 = 26.5
-
-#![feature(managed_boxes)]
-#![allow(unused_variable)]
-
-struct SomeStruct {
-    x: int,
-    y: f64
-}
-
-fn main() {
-    let stack_val: SomeStruct = SomeStruct { x: 10, y: 23.5 };
-    let stack_val_ref: &SomeStruct = &stack_val;
-    let stack_val_interior_ref_1: &int = &stack_val.x;
-    let stack_val_interior_ref_2: &f64 = &stack_val.y;
-    let ref_to_unnamed: &SomeStruct = &SomeStruct { x: 11, y: 24.5 };
-
-    let managed_val = @SomeStruct { x: 12, y: 25.5 };
-    let managed_val_ref: &SomeStruct = managed_val;
-    let managed_val_interior_ref_1: &int = &managed_val.x;
-    let managed_val_interior_ref_2: &f64 = &managed_val.y;
-
-    let unique_val = box SomeStruct { x: 13, y: 26.5 };
-    let unique_val_ref: &SomeStruct = unique_val;
-    let unique_val_interior_ref_1: &int = &unique_val.x;
-    let unique_val_interior_ref_2: &f64 = &unique_val.y;
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/borrowed-tuple.rs b/src/test/debug-info/borrowed-tuple.rs
deleted file mode 100644 (file)
index b619f8e..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-#![feature(managed_boxes)]
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print *stack_val_ref
-// check:$1 = {-14, -19}
-
-// debugger:print *ref_to_unnamed
-// check:$2 = {-15, -20}
-
-// debugger:print *managed_val_ref
-// check:$3 = {-16, -21}
-
-// 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;
-    let ref_to_unnamed: &(i16, f32) = &(-15, -20f32);
-
-    let managed_val: @(i16, f32) = @(-16, -21f32);
-    let managed_val_ref: &(i16, f32) = managed_val;
-
-    let unique_val: Box<(i16, f32)> = box() (-17, -22f32);
-    let unique_val_ref: &(i16, f32) = unique_val;
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/borrowed-unique-basic.rs b/src/test/debug-info/borrowed-unique-basic.rs
deleted file mode 100644 (file)
index eaa2679..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// Gdb doesn't know about UTF-32 character encoding and will print a rust char as only
-// its numerical value.
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-// debugger:print *bool_ref
-// check:$1 = true
-
-// debugger:print *int_ref
-// check:$2 = -1
-
-// debugger:print *char_ref
-// check:$3 = 97
-
-// debugger:print/d *i8_ref
-// check:$4 = 68
-
-// debugger:print *i16_ref
-// check:$5 = -16
-
-// debugger:print *i32_ref
-// check:$6 = -32
-
-// debugger:print *i64_ref
-// check:$7 = -64
-
-// debugger:print *uint_ref
-// check:$8 = 1
-
-// debugger:print/d *u8_ref
-// check:$9 = 100
-
-// debugger:print *u16_ref
-// check:$10 = 16
-
-// debugger:print *u32_ref
-// check:$11 = 32
-
-// debugger:print *u64_ref
-// check:$12 = 64
-
-// debugger:print *f32_ref
-// check:$13 = 2.5
-
-// debugger:print *f64_ref
-// check:$14 = 3.5
-
-#![allow(unused_variable)]
-
-
-fn main() {
-    let bool_box: Box<bool> = box true;
-    let bool_ref: &bool = bool_box;
-
-    let int_box: Box<int> = box -1;
-    let int_ref: &int = int_box;
-
-    let char_box: Box<char> = box 'a';
-    let char_ref: &char = char_box;
-
-    let i8_box: Box<i8> = box 68;
-    let i8_ref: &i8 = i8_box;
-
-    let i16_box: Box<i16> = box -16;
-    let i16_ref: &i16 = i16_box;
-
-    let i32_box: Box<i32> = box -32;
-    let i32_ref: &i32 = i32_box;
-
-    let i64_box: Box<i64> = box -64;
-    let i64_ref: &i64 = i64_box;
-
-    let uint_box: Box<uint> = box 1;
-    let uint_ref: &uint = uint_box;
-
-    let u8_box: Box<u8> = box 100;
-    let u8_ref: &u8 = u8_box;
-
-    let u16_box: Box<u16> = box 16;
-    let u16_ref: &u16 = u16_box;
-
-    let u32_box: Box<u32> = box 32;
-    let u32_ref: &u32 = u32_box;
-
-    let u64_box: Box<u64> = box 64;
-    let u64_ref: &u64 = u64_box;
-
-    let f32_box: Box<f32> = box 2.5;
-    let f32_ref: &f32 = f32_box;
-
-    let f64_box: Box<f64> = box 3.5;
-    let f64_ref: &f64 = f64_box;
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/box.rs b/src/test/debug-info/box.rs
deleted file mode 100644 (file)
index a849a05..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:set print pretty off
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-// debugger:print *a
-// check:$1 = 1
-// debugger:print *b
-// check:$2 = {2, 3.5}
-// debugger:print c->val
-// check:$3 = 4
-// debugger:print d->val
-// check:$4 = false
-
-#![feature(managed_boxes)]
-#![allow(unused_variable)]
-
-fn main() {
-    let a = box 1;
-    let b = box() (2, 3.5);
-    let c = @4;
-    let d = @false;
-    _zzz();
-}
-
-fn _zzz() {()}
diff --git a/src/test/debug-info/boxed-struct.rs b/src/test/debug-info/boxed-struct.rs
deleted file mode 100644 (file)
index a286fca..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print *unique
-// check:$1 = {x = 99, y = 999, z = 9999, w = 99999}
-
-// debugger:print managed->val
-// check:$2 = {x = 88, y = 888, z = 8888, w = 88888}
-
-// debugger:print *unique_dtor
-// check:$3 = {x = 77, y = 777, z = 7777, w = 77777}
-
-// debugger:print managed_dtor->val
-// check:$4 = {x = 33, y = 333, z = 3333, w = 33333}
-
-#![feature(managed_boxes)]
-#![allow(unused_variable)]
-
-
-struct StructWithSomePadding {
-    x: i16,
-    y: i32,
-    z: i32,
-    w: i64
-}
-
-struct StructWithDestructor {
-    x: i16,
-    y: i32,
-    z: i32,
-    w: i64
-}
-
-impl Drop for StructWithDestructor {
-    fn drop(&mut self) {}
-}
-
-fn main() {
-
-    let unique = box StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 };
-    let managed = @StructWithSomePadding { x: 88, y: 888, z: 8888, w: 88888 };
-
-    let unique_dtor = box StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 };
-    let managed_dtor = @StructWithDestructor { x: 33, y: 333, z: 3333, w: 33333 };
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/by-value-non-immediate-argument.rs b/src/test/debug-info/by-value-non-immediate-argument.rs
deleted file mode 100644 (file)
index ce876e9..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-
-// debugger:finish
-// debugger:print s
-// check:$1 = {a = 1, b = 2.5}
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$2 = {a = 3, b = 4.5}
-// debugger:print y
-// check:$3 = 5
-// debugger:print z
-// check:$4 = 6.5
-// debugger:continue
-
-// debugger:finish
-// debugger:print a
-// check:$5 = {7, 8, 9.5, 10.5}
-// debugger:continue
-
-// debugger:finish
-// debugger:print a
-// check:$6 = {11.5, 12.5, 13, 14}
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$7 = {{Case1, x = 0, y = 8970181431921507452}, {Case1, 0, 2088533116, 2088533116}}
-// debugger:continue
-
-#![feature(struct_variant)]
-
-#[deriving(Clone)]
-struct Struct {
-    a: int,
-    b: f64
-}
-
-#[deriving(Clone)]
-struct StructStruct {
-    a: Struct,
-    b: Struct
-}
-
-fn fun(s: Struct) {
-    zzz();
-}
-
-fn fun_fun(StructStruct { a: x, b: Struct { a: y, b: z } }: StructStruct) {
-    zzz();
-}
-
-fn tup(a: (int, uint, f64, f64)) {
-    zzz();
-}
-
-struct Newtype(f64, f64, int, uint);
-
-fn new_type(a: Newtype) {
-    zzz();
-}
-
-// 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 Enum {
-    Case1 { x: i64, y: i64 },
-    Case2 (i64, i32, i32),
-}
-
-fn by_val_enum(x: Enum) {
-    zzz();
-}
-
-fn main() {
-    fun(Struct { a: 1, b: 2.5 });
-    fun_fun(StructStruct { a: Struct { a: 3, b: 4.5 }, b: Struct { a: 5, b: 6.5 } });
-    tup((7, 8, 9.5, 10.5));
-    new_type(Newtype(11.5, 12.5, 13, 14));
-
-    // 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452
-    // 0b01111100011111000111110001111100 = 2088533116
-    // 0b0111110001111100 = 31868
-    // 0b01111100 = 124
-    by_val_enum(Case1 { x: 0, y: 8970181431921507452 });
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/by-value-self-argument-in-trait-impl.rs b/src/test/debug-info/by-value-self-argument-in-trait-impl.rs
deleted file mode 100644 (file)
index f8973f7..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-#![feature(managed_boxes)]
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-
-// debugger:finish
-// debugger:print self
-// check:$1 = 1111
-// debugger:continue
-
-// debugger:finish
-// debugger:print self
-// check:$2 = {x = 2222, y = 3333}
-// debugger:continue
-
-// debugger:finish
-// debugger:print self
-// check:$3 = {4444.5, 5555, 6666, 7777.5}
-// debugger:continue
-
-// debugger:finish
-// debugger:print self->val
-// check:$4 = 8888
-// debugger:continue
-
-trait Trait {
-    fn method(self) -> Self;
-}
-
-impl Trait for int {
-    fn method(self) -> int {
-        zzz();
-        self
-    }
-}
-
-struct Struct {
-    x: uint,
-    y: uint,
-}
-
-impl Trait for Struct {
-    fn method(self) -> Struct {
-        zzz();
-        self
-    }
-}
-
-impl Trait for (f64, int, int, f64) {
-    fn method(self) -> (f64, int, int, f64) {
-        zzz();
-        self
-    }
-}
-
-impl Trait for @int {
-    fn method(self) -> @int {
-        zzz();
-        self
-    }
-}
-
-fn main() {
-    let _ = (1111 as int).method();
-    let _ = Struct { x: 2222, y: 3333 }.method();
-    let _ = (4444.5, 5555, 6666, 7777.5).method();
-    let _ = (@8888).method();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/c-style-enum-in-composite.rs b/src/test/debug-info/c-style-enum-in-composite.rs
deleted file mode 100644 (file)
index 08104c2..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print tuple_interior_padding
-// check:$1 = {0, OneHundred}
-
-// debugger:print tuple_padding_at_end
-// check:$2 = {{1, OneThousand}, 2}
-
-// debugger:print tuple_different_enums
-// check:$3 = {OneThousand, MountainView, OneMillion, Vienna}
-
-// debugger:print padded_struct
-// check:$4 = {a = 3, b = OneMillion, c = 4, d = Toronto, e = 5}
-
-// debugger:print packed_struct
-// check:$5 = {a = 6, b = OneHundred, c = 7, d = Vienna, e = 8}
-
-// debugger:print non_padded_struct
-// check:$6 = {a = OneMillion, b = MountainView, c = OneThousand, d = Toronto}
-
-// debugger:print struct_with_drop
-// check:$7 = {{a = OneHundred, b = Vienna}, 9}
-
-#![allow(unused_variable)]
-
-enum AnEnum {
-    OneHundred = 100,
-    OneThousand = 1000,
-    OneMillion = 1000000
-}
-
-enum AnotherEnum {
-    MountainView,
-    Toronto,
-    Vienna
-}
-
-struct PaddedStruct {
-    a: i16,
-    b: AnEnum,
-    c: i16,
-    d: AnotherEnum,
-    e: i16
-}
-
-#[packed]
-struct PackedStruct {
-    a: i16,
-    b: AnEnum,
-    c: i16,
-    d: AnotherEnum,
-    e: i16
-}
-
-struct NonPaddedStruct {
-    a: AnEnum,
-    b: AnotherEnum,
-    c: AnEnum,
-    d: AnotherEnum
-}
-
-struct StructWithDrop {
-    a: AnEnum,
-    b: AnotherEnum
-}
-
-impl Drop for StructWithDrop {
-    fn drop(&mut self) {()}
-}
-
-fn main() {
-
-    let tuple_interior_padding = (0_i16, OneHundred);
-    // It will depend on the machine architecture if any padding is actually involved here
-    let tuple_padding_at_end = ((1_u64, OneThousand), 2_u64);
-    let tuple_different_enums = (OneThousand, MountainView, OneMillion, Vienna);
-
-    let padded_struct = PaddedStruct {
-        a: 3,
-        b: OneMillion,
-        c: 4,
-        d: Toronto,
-        e: 5
-    };
-
-    let packed_struct = PackedStruct {
-        a: 6,
-        b: OneHundred,
-        c: 7,
-        d: Vienna,
-        e: 8
-    };
-
-    let non_padded_struct = NonPaddedStruct {
-        a: OneMillion,
-        b: MountainView,
-        c: OneThousand,
-        d: Toronto
-    };
-
-    let struct_with_drop = (StructWithDrop { a: OneHundred, b: Vienna }, 9_i64);
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/c-style-enum.rs b/src/test/debug-info/c-style-enum.rs
deleted file mode 100644 (file)
index 0a20788..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-win32: FIXME #13256
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-
-// debugger:print 'c-style-enum::SINGLE_VARIANT'
-// check:$1 = TheOnlyVariant
-
-// debugger:print 'c-style-enum::AUTO_ONE'
-// check:$2 = One
-
-// debugger:print 'c-style-enum::AUTO_TWO'
-// check:$3 = One
-
-// debugger:print 'c-style-enum::AUTO_THREE'
-// check:$4 = One
-
-// debugger:print 'c-style-enum::MANUAL_ONE'
-// check:$5 = OneHundred
-
-// debugger:print 'c-style-enum::MANUAL_TWO'
-// check:$6 = OneHundred
-
-// debugger:print 'c-style-enum::MANUAL_THREE'
-// check:$7 = OneHundred
-
-// debugger:run
-// debugger:finish
-
-// debugger:print auto_one
-// check:$8 = One
-
-// debugger:print auto_two
-// check:$9 = Two
-
-// debugger:print auto_three
-// check:$10 = Three
-
-// debugger:print manual_one_hundred
-// check:$11 = OneHundred
-
-// debugger:print manual_one_thousand
-// check:$12 = OneThousand
-
-// debugger:print manual_one_million
-// check:$13 = OneMillion
-
-// debugger:print single_variant
-// check:$14 = TheOnlyVariant
-
-// debugger:print 'c-style-enum::AUTO_TWO'
-// check:$15 = Two
-
-// debugger:print 'c-style-enum::AUTO_THREE'
-// check:$16 = Three
-
-// debugger:print 'c-style-enum::MANUAL_TWO'
-// check:$17 = OneThousand
-
-// debugger:print 'c-style-enum::MANUAL_THREE'
-// check:$18 = OneMillion
-
-#![allow(unused_variable)]
-#![allow(dead_code)]
-
-enum AutoDiscriminant {
-    One,
-    Two,
-    Three
-}
-
-enum ManualDiscriminant {
-    OneHundred = 100,
-    OneThousand = 1000,
-    OneMillion = 1000000
-}
-
-enum SingleVariant {
-    TheOnlyVariant
-}
-
-static SINGLE_VARIANT: SingleVariant = TheOnlyVariant;
-
-static mut AUTO_ONE: AutoDiscriminant = One;
-static mut AUTO_TWO: AutoDiscriminant = One;
-static mut AUTO_THREE: AutoDiscriminant = One;
-
-static mut MANUAL_ONE: ManualDiscriminant = OneHundred;
-static mut MANUAL_TWO: ManualDiscriminant = OneHundred;
-static mut MANUAL_THREE: ManualDiscriminant = OneHundred;
-
-fn main() {
-
-    let auto_one = One;
-    let auto_two = Two;
-    let auto_three = Three;
-
-    let manual_one_hundred = OneHundred;
-    let manual_one_thousand = OneThousand;
-    let manual_one_million = OneMillion;
-
-    let single_variant = TheOnlyVariant;
-
-    unsafe {
-        AUTO_TWO = Two;
-        AUTO_THREE = Three;
-
-        MANUAL_TWO = OneThousand;
-        MANUAL_THREE = OneMillion;
-    };
-
-    zzz();
-
-    let a = SINGLE_VARIANT;
-    let a = unsafe { AUTO_ONE };
-    let a = unsafe { MANUAL_ONE };
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/closure-in-generic-function.rs b/src/test/debug-info/closure-in-generic-function.rs
deleted file mode 100644 (file)
index f3692e7..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak 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, box 110);
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/destructured-fn-argument.rs b/src/test/debug-info/destructured-fn-argument.rs
deleted file mode 100644 (file)
index 2f7fc96..0000000
+++ /dev/null
@@ -1,321 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-
-// debugger:finish
-// debugger:print a
-// check:$1 = 1
-// debugger:print b
-// check:$2 = false
-// debugger:continue
-
-// debugger:finish
-// debugger:print a
-// check:$3 = 2
-// debugger:print b
-// check:$4 = 3
-// debugger:print c
-// check:$5 = 4
-// debugger:continue
-
-// debugger:finish
-// debugger:print a
-// check:$6 = 5
-// debugger:print b
-// check:$7 = {6, 7}
-// debugger:continue
-
-// debugger:finish
-// debugger:print h
-// check:$8 = 8
-// debugger:print i
-// check:$9 = {a = 9, b = 10}
-// debugger:print j
-// check:$10 = 11
-// debugger:continue
-
-// debugger:finish
-// debugger:print k
-// check:$11 = 12
-// debugger:print l
-// check:$12 = 13
-// debugger:continue
-
-// debugger:finish
-// debugger:print m
-// check:$13 = 14
-// debugger:print n
-// check:$14 = 16
-// debugger:continue
-
-// debugger:finish
-// debugger:print o
-// check:$15 = 18
-// debugger:continue
-
-// debugger:finish
-// debugger:print p
-// check:$16 = 19
-// debugger:print q
-// check:$17 = 20
-// debugger:print r
-// check:$18 = {a = 21, b = 22}
-// debugger:continue
-
-// debugger:finish
-// debugger:print s
-// check:$19 = 24
-// debugger:print t
-// check:$20 = 23
-// debugger:continue
-
-// debugger:finish
-// debugger:print u
-// check:$21 = 25
-// debugger:print v
-// check:$22 = 26
-// debugger:print w
-// check:$23 = 27
-// debugger:print x
-// check:$24 = 28
-// debugger:print y
-// check:$25 = 29
-// debugger:print z
-// check:$26 = 30
-// debugger:print ae
-// check:$27 = 31
-// debugger:print oe
-// check:$28 = 32
-// debugger:print ue
-// check:$29 = 33
-// debugger:continue
-
-// debugger:finish
-// debugger:print aa
-// check:$30 = {34, 35}
-// debugger:continue
-
-// debugger:finish
-// debugger:print bb
-// check:$31 = {36, 37}
-// debugger:continue
-
-// debugger:finish
-// debugger:print cc
-// check:$32 = 38
-// debugger:continue
-
-// debugger:finish
-// debugger:print dd
-// check:$33 = {40, 41, 42}
-// debugger:continue
-
-// debugger:finish
-// debugger:print *ee
-// check:$34 = {43, 44, 45}
-// debugger:continue
-
-// debugger:finish
-// debugger:print *ff
-// check:$35 = 46
-// debugger:print gg
-// check:$36 = {47, 48}
-// debugger:continue
-
-// debugger:finish
-// debugger:print *hh
-// check:$37 = 50
-// debugger:continue
-
-// debugger:finish
-// debugger:print ii
-// check:$38 = 51
-// debugger:continue
-
-// debugger:finish
-// debugger:print *jj
-// check:$39 = 52
-// debugger:continue
-
-// debugger:finish
-// debugger:print kk
-// check:$40 = 53
-// debugger:print ll
-// check:$41 = 54
-// debugger:continue
-
-// debugger:finish
-// debugger:print mm
-// check:$42 = 55
-// debugger:print *nn
-// check:$43 = 56
-// debugger:continue
-
-// debugger:finish
-// debugger:print oo
-// check:$44 = 57
-// debugger:print pp
-// check:$45 = 58
-// debugger:print qq
-// check:$46 = 59
-// debugger:continue
-
-// debugger:finish
-// debugger:print rr
-// check:$47 = 60
-// debugger:print ss
-// check:$48 = 61
-// debugger:print tt
-// check:$49 = 62
-// debugger:continue
-
-#![allow(unused_variable)]
-
-
-struct Struct {
-    a: i64,
-    b: i32
-}
-
-enum Univariant {
-    Unit(i32)
-}
-
-struct TupleStruct (f64, int);
-
-
-fn simple_tuple((a, b): (int, bool)) {
-    zzz();
-}
-
-fn nested_tuple((a, (b, c)): (int, (u16, u16))) {
-    zzz();
-}
-
-fn destructure_only_first_level((a, b): (int, (u32, u32))) {
-    zzz();
-}
-
-fn struct_as_tuple_element((h, i, j): (i16, Struct, i16)) {
-    zzz();
-}
-
-fn struct_pattern(Struct { a: k, b: l }: Struct) {
-    zzz();
-}
-
-fn ignored_tuple_element((m, _, n): (int, u16, i32)) {
-    zzz();
-}
-
-fn ignored_struct_field(Struct { b: o, .. }: Struct) {
-    zzz();
-}
-
-fn one_struct_destructured_one_not((Struct { a: p, b: q }, r): (Struct, Struct)) {
-    zzz();
-}
-
-fn different_order_of_struct_fields(Struct { b: s, a: t }: Struct ) {
-    zzz();
-}
-
-fn complex_nesting(((u,   v  ), ((w,   (x,   Struct { a: y, b: z})), Struct { a: ae, b: oe }), ue ):
-                   ((i16, i32), ((i64, (i32, Struct,             )), Struct                 ), u16))
-{
-    zzz();
-}
-
-fn managed_box(&aa: &(int, int)) {
-    zzz();
-}
-
-fn borrowed_pointer(&bb: &(int, int)) {
-    zzz();
-}
-
-fn contained_borrowed_pointer((&cc, _): (&int, int)) {
-    zzz();
-}
-
-fn unique_pointer(box dd: Box<(int, int, int)>) {
-    zzz();
-}
-
-fn ref_binding(ref ee: (int, int, int)) {
-    zzz();
-}
-
-fn ref_binding_in_tuple((ref ff, gg): (int, (int, int))) {
-    zzz();
-}
-
-fn ref_binding_in_struct(Struct { b: ref hh, .. }: Struct) {
-    zzz();
-}
-
-fn univariant_enum(Unit(ii): Univariant) {
-    zzz();
-}
-
-fn univariant_enum_with_ref_binding(Unit(ref jj): Univariant) {
-    zzz();
-}
-
-fn tuple_struct(TupleStruct(kk, ll): TupleStruct) {
-    zzz();
-}
-
-fn tuple_struct_with_ref_binding(TupleStruct(mm, ref nn): TupleStruct) {
-    zzz();
-}
-
-fn multiple_arguments((oo, pp): (int, int), qq : int) {
-    zzz();
-}
-
-fn main() {
-    simple_tuple((1, false));
-    nested_tuple((2, (3, 4)));
-    destructure_only_first_level((5, (6, 7)));
-    struct_as_tuple_element((8, Struct { a: 9, b: 10 }, 11));
-    struct_pattern(Struct { a: 12, b: 13 });
-    ignored_tuple_element((14, 15, 16));
-    ignored_struct_field(Struct { a: 17, b: 18 });
-    one_struct_destructured_one_not((Struct { a: 19, b: 20 }, Struct { a: 21, b: 22 }));
-    different_order_of_struct_fields(Struct { a: 23, b: 24 });
-    complex_nesting(((25, 26), ((27, (28, Struct { a: 29, b: 30})), Struct { a: 31, b: 32 }), 33));
-    managed_box(&(34, 35));
-    borrowed_pointer(&(36, 37));
-    contained_borrowed_pointer((&38, 39));
-    unique_pointer(box() (40, 41, 42));
-    ref_binding((43, 44, 45));
-    ref_binding_in_tuple((46, (47, 48)));
-    ref_binding_in_struct(Struct { a: 49, b: 50 });
-    univariant_enum(Unit(51));
-    univariant_enum_with_ref_binding(Unit(52));
-    tuple_struct(TupleStruct(53.0, 54));
-    tuple_struct_with_ref_binding(TupleStruct(55.0, 56));
-    multiple_arguments((57, 58), 59);
-
-    fn nested_function(rr: int, (ss, tt): (int, int)) {
-        zzz();
-    }
-
-    nested_function(60, (61, 62));
-}
-
-
-fn zzz() {()}
diff --git a/src/test/debug-info/destructured-local.rs b/src/test/debug-info/destructured-local.rs
deleted file mode 100644 (file)
index 3dab6ac..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print a
-// check:$1 = 1
-// debugger:print b
-// check:$2 = false
-
-// debugger:print c
-// check:$3 = 2
-// debugger:print d
-// check:$4 = 3
-// debugger:print e
-// check:$5 = 4
-
-// debugger:print f
-// check:$6 = 5
-// debugger:print g
-// check:$7 = {6, 7}
-
-// debugger:print h
-// check:$8 = 8
-// debugger:print i
-// check:$9 = {a = 9, b = 10}
-// debugger:print j
-// check:$10 = 11
-
-// debugger:print k
-// check:$11 = 12
-// debugger:print l
-// check:$12 = 13
-
-// debugger:print m
-// check:$13 = 14
-// debugger:print n
-// check:$14 = 16
-
-// debugger:print o
-// check:$15 = 18
-
-// debugger:print p
-// check:$16 = 19
-// debugger:print q
-// check:$17 = 20
-// debugger:print r
-// check:$18 = {a = 21, b = 22}
-
-// debugger:print s
-// check:$19 = 24
-// debugger:print t
-// check:$20 = 23
-
-// debugger:print u
-// check:$21 = 25
-// debugger:print v
-// check:$22 = 26
-// debugger:print w
-// check:$23 = 27
-// debugger:print x
-// check:$24 = 28
-// debugger:print y
-// check:$25 = 29
-// debugger:print z
-// check:$26 = 30
-// debugger:print ae
-// check:$27 = 31
-// debugger:print oe
-// check:$28 = 32
-// debugger:print ue
-// check:$29 = 33
-
-// debugger:print aa
-// check:$30 = {34, 35}
-
-// debugger:print bb
-// check:$31 = {36, 37}
-
-// debugger:print cc
-// check:$32 = 38
-
-// debugger:print dd
-// check:$33 = {40, 41, 42}
-
-// debugger:print *ee
-// check:$34 = {43, 44, 45}
-
-// debugger:print *ff
-// check:$35 = 46
-
-// debugger:print gg
-// check:$36 = {47, 48}
-
-// debugger:print *hh
-// check:$37 = 50
-
-// debugger:print ii
-// check:$38 = 51
-
-// debugger:print *jj
-// check:$39 = 52
-
-// debugger:print kk
-// check:$40 = 53
-
-// debugger:print ll
-// check:$41 = 54
-
-// debugger:print mm
-// check:$42 = 55
-
-// debugger:print *nn
-// check:$43 = 56
-
-#![allow(unused_variable)]
-
-struct Struct {
-    a: i64,
-    b: i32
-}
-
-enum Univariant {
-    Unit(i32)
-}
-
-struct TupleStruct (f64, int);
-
-
-fn main() {
-    // simple tuple
-    let (a, b) : (int, bool) = (1, false);
-
-    // nested tuple
-    let (c, (d, e)) : (int, (u16, u16)) = (2, (3, 4));
-
-    // bind tuple-typed value to one name (destructure only first level)
-    let (f, g) : (int, (u32, u32)) = (5, (6, 7));
-
-    // struct as tuple element
-    let (h, i, j) : (i16, Struct, i16) = (8, Struct { a: 9, b: 10 }, 11);
-
-    // struct pattern
-    let Struct { a: k, b: l } = Struct { a: 12, b: 13 };
-
-    // ignored tuple element
-    let (m, _, n) = (14, 15, 16);
-
-    // ignored struct field
-    let Struct { b: o, .. } = Struct { a: 17, b: 18 };
-
-    // one struct destructured, one not
-    let (Struct { a: p, b: q }, r) = (Struct { a: 19, b: 20 }, Struct { a: 21, b: 22 });
-
-    // different order of struct fields
-    let Struct { b: s, a: t } = Struct { a: 23, b: 24 };
-
-    // complex nesting
-    let ((u, v), ((w, (x, Struct { a: y, b: z})), Struct { a: ae, b: oe }), ue) =
-        ((25, 26), ((27, (28, Struct { a: 29, b: 30})), Struct { a: 31, b: 32 }), 33);
-
-    // reference
-    let &aa = &(34, 35);
-
-    // reference
-    let &bb = &(36, 37);
-
-    // contained reference
-    let (&cc, _) = (&38, 39);
-
-    // unique pointer
-    let box dd = box() (40, 41, 42);
-
-    // ref binding
-    let ref ee = (43, 44, 45);
-
-    // ref binding in tuple
-    let (ref ff, gg) = (46, (47, 48));
-
-    // ref binding in struct
-    let Struct { b: ref hh, .. } = Struct { a: 49, b: 50 };
-
-    // univariant enum
-    let Unit(ii) = Unit(51);
-
-    // univariant enum with ref      binding
-    let &Unit(ref jj) = &Unit(52);
-
-    // tuple struct
-    let &TupleStruct(kk, ll) = &TupleStruct(53.0, 54);
-
-    // tuple struct with ref binding
-    let &TupleStruct(mm, ref nn) = &TupleStruct(55.0, 56);
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/evec-in-struct.rs b/src/test/debug-info/evec-in-struct.rs
deleted file mode 100644 (file)
index bf4a407..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:set print pretty off
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print no_padding1
-// check:$1 = {x = {0, 1, 2}, y = -3, z = {4.5, 5.5}}
-// debugger:print no_padding2
-// check:$2 = {x = {6, 7, 8}, y = {{9, 10}, {11, 12}}}
-
-// debugger:print struct_internal_padding
-// check:$3 = {x = {13, 14}, y = {15, 16}}
-
-// debugger:print single_vec
-// check:$4 = {x = {17, 18, 19, 20, 21}}
-
-// debugger:print struct_padded_at_end
-// check:$5 = {x = {22, 23}, y = {24, 25}}
-
-#![allow(unused_variable)]
-
-struct NoPadding1 {
-    x: [u32, ..3],
-    y: i32,
-    z: [f32, ..2]
-}
-
-struct NoPadding2 {
-    x: [u32, ..3],
-    y: [[u32, ..2], ..2]
-}
-
-struct StructInternalPadding {
-    x: [i16, ..2],
-    y: [i64, ..2]
-}
-
-struct SingleVec {
-    x: [i16, ..5]
-}
-
-struct StructPaddedAtEnd {
-    x: [i64, ..2],
-    y: [i16, ..2]
-}
-
-fn main() {
-
-    let no_padding1 = NoPadding1 {
-        x: [0, 1, 2],
-        y: -3,
-        z: [4.5, 5.5]
-    };
-
-    let no_padding2 = NoPadding2 {
-        x: [6, 7, 8],
-        y: [[9, 10], [11, 12]]
-    };
-
-    let struct_internal_padding = StructInternalPadding {
-        x: [13, 14],
-        y: [15, 16]
-    };
-
-    let single_vec = SingleVec {
-        x: [17, 18, 19, 20, 21]
-    };
-
-    let struct_padded_at_end = StructPaddedAtEnd {
-        x: [22, 23],
-        y: [24, 25]
-    };
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/function-arg-initialization.rs b/src/test/debug-info/function-arg-initialization.rs
deleted file mode 100644 (file)
index a5e6732..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// This test case checks if function arguments already have the correct value when breaking at the
-// first line of the function, that is if the function prologue has already been executed at the
-// first line. Note that because of the __morestack part of the prologue GDB incorrectly breaks at
-// before the arguments have been properly loaded when setting the breakpoint via the function name.
-// Therefore the setup here sets them using line numbers (so be careful when changing this file).
-
-// compile-flags:-g
-// debugger:set print pretty off
-// debugger:break function-arg-initialization.rs:139
-// debugger:break function-arg-initialization.rs:154
-// debugger:break function-arg-initialization.rs:158
-// debugger:break function-arg-initialization.rs:162
-// debugger:break function-arg-initialization.rs:166
-// debugger:break function-arg-initialization.rs:170
-// debugger:break function-arg-initialization.rs:174
-// debugger:break function-arg-initialization.rs:178
-// debugger:break function-arg-initialization.rs:182
-// debugger:break function-arg-initialization.rs:190
-// debugger:break function-arg-initialization.rs:197
-
-
-// debugger:run
-
-// IMMEDIATE ARGS
-// debugger:print a
-// check:$1 = 1
-// debugger:print b
-// check:$2 = true
-// debugger:print c
-// check:$3 = 2.5
-// debugger:continue
-
-// NON IMMEDIATE ARGS
-// debugger:print a
-// check:$4 = {a = 3, b = 4, c = 5, d = 6, e = 7, f = 8, g = 9, h = 10}
-// debugger:print b
-// check:$5 = {a = 11, b = 12, c = 13, d = 14, e = 15, f = 16, g = 17, h = 18}
-// debugger:continue
-
-// BINDING
-// debugger:print a
-// check:$6 = 19
-// debugger:print b
-// check:$7 = 20
-// debugger:print c
-// check:$8 = 21.5
-// debugger:continue
-
-// ASSIGNMENT
-// debugger:print a
-// check:$9 = 22
-// debugger:print b
-// check:$10 = 23
-// debugger:print c
-// check:$11 = 24.5
-// debugger:continue
-
-// FUNCTION CALL
-// debugger:print x
-// check:$12 = 25
-// debugger:print y
-// check:$13 = 26
-// debugger:print z
-// check:$14 = 27.5
-// debugger:continue
-
-// EXPR
-// debugger:print x
-// check:$15 = 28
-// debugger:print y
-// check:$16 = 29
-// debugger:print z
-// check:$17 = 30.5
-// debugger:continue
-
-// RETURN EXPR
-// debugger:print x
-// check:$18 = 31
-// debugger:print y
-// check:$19 = 32
-// debugger:print z
-// check:$20 = 33.5
-// debugger:continue
-
-// ARITHMETIC EXPR
-// debugger:print x
-// check:$21 = 34
-// debugger:print y
-// check:$22 = 35
-// debugger:print z
-// check:$23 = 36.5
-// debugger:continue
-
-// IF EXPR
-// debugger:print x
-// check:$24 = 37
-// debugger:print y
-// check:$25 = 38
-// debugger:print z
-// check:$26 = 39.5
-// debugger:continue
-
-// WHILE EXPR
-// debugger:print x
-// check:$27 = 40
-// debugger:print y
-// check:$28 = 41
-// debugger:print z
-// check:$29 = 42
-// debugger:continue
-
-// LOOP EXPR
-// debugger:print x
-// check:$30 = 43
-// debugger:print y
-// check:$31 = 44
-// debugger:print z
-// check:$32 = 45
-// debugger:continue
-
-#![allow(unused_variable)]
-
-
-
-
-fn immediate_args(a: int, b: bool, c: f64) {
-    ()
-}
-
-struct BigStruct {
-    a: u64,
-    b: u64,
-    c: u64,
-    d: u64,
-    e: u64,
-    f: u64,
-    g: u64,
-    h: u64
-}
-
-fn non_immediate_args(a: BigStruct, b: BigStruct) {
-    ()
-}
-
-fn binding(a: i64, b: u64, c: f64) {
-    let x = 0;
-}
-
-fn assignment(mut a: u64, b: u64, c: f64) {
-    a = b;
-}
-
-fn function_call(x: u64, y: u64, z: f64) {
-    std::io::stdio::print("Hi!")
-}
-
-fn identifier(x: u64, y: u64, z: f64) -> u64 {
-    x
-}
-
-fn return_expr(x: u64, y: u64, z: f64) -> u64 {
-    return x;
-}
-
-fn arithmetic_expr(x: u64, y: u64, z: f64) -> u64 {
-    x + y
-}
-
-fn if_expr(x: u64, y: u64, z: f64) -> u64 {
-    if x + y < 1000 {
-        x
-    } else {
-        y
-    }
-}
-
-fn while_expr(mut x: u64, y: u64, z: u64) -> u64 {
-    while x + y < 1000 {
-        x += z
-    }
-    return x;
-}
-
-fn loop_expr(mut x: u64, y: u64, z: u64) -> u64 {
-    loop {
-        x += z;
-
-        if x + y > 1000 {
-            return x;
-        }
-    }
-}
-
-fn main() {
-    immediate_args(1, true, 2.5);
-
-    non_immediate_args(
-        BigStruct {
-            a: 3,
-            b: 4,
-            c: 5,
-            d: 6,
-            e: 7,
-            f: 8,
-            g: 9,
-            h: 10
-        },
-        BigStruct {
-            a: 11,
-            b: 12,
-            c: 13,
-            d: 14,
-            e: 15,
-            f: 16,
-            g: 17,
-            h: 18
-        }
-    );
-
-    binding(19, 20, 21.5);
-    assignment(22, 23, 24.5);
-    function_call(25, 26, 27.5);
-    identifier(28, 29, 30.5);
-    return_expr(31, 32, 33.5);
-    arithmetic_expr(34, 35, 36.5);
-    if_expr(37, 38, 39.5);
-    while_expr(40, 41, 42);
-    loop_expr(43, 44, 45);
-}
-
-
-
diff --git a/src/test/debug-info/function-arguments.rs b/src/test/debug-info/function-arguments.rs
deleted file mode 100644 (file)
index d459005..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print x
-// check:$1 = 111102
-// debugger:print y
-// check:$2 = true
-
-// debugger:continue
-// debugger:finish
-
-// debugger:print a
-// check:$3 = 2000
-// debugger:print b
-// check:$4 = 3000
-
-fn main() {
-
-    fun(111102, true);
-    nested(2000, 3000);
-
-    fn nested(a: i32, b: i64) -> (i32, i64) {
-        zzz();
-        (a, b)
-    }
-}
-
-fn fun(x: int, y: bool) -> (int, bool) {
-    zzz();
-
-    (x, y)
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/function-prologue-stepping-no-split-stack.rs b/src/test/debug-info/function-prologue-stepping-no-split-stack.rs
deleted file mode 100644 (file)
index 6f27305..0000000
+++ /dev/null
@@ -1,246 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// This test case checks if function arguments already have the correct value when breaking at the
-// beginning of a function. Functions with the #[no_split_stack] attribute have the same prologue as
-// regular C functions compiled with GCC or Clang and therefore are better handled by GDB. As a
-// consequence, and as opposed to regular Rust functions, we can set the breakpoints via the
-// function name (and don't have to fall back on using line numbers).
-
-// compile-flags:-g
-// debugger:set print pretty off
-// debugger:rbreak immediate_args
-// debugger:rbreak binding
-// debugger:rbreak assignment
-// debugger:rbreak function_call
-// debugger:rbreak identifier
-// debugger:rbreak return_expr
-// debugger:rbreak arithmetic_expr
-// debugger:rbreak if_expr
-// debugger:rbreak while_expr
-// debugger:rbreak loop_expr
-// debugger:run
-
-// IMMEDIATE ARGS
-// debugger:print a
-// check:$1 = 1
-// debugger:print b
-// check:$2 = true
-// debugger:print c
-// check:$3 = 2.5
-// debugger:continue
-
-// NON IMMEDIATE ARGS
-// debugger:print a
-// check:$4 = {a = 3, b = 4, c = 5, d = 6, e = 7, f = 8, g = 9, h = 10}
-// debugger:print b
-// check:$5 = {a = 11, b = 12, c = 13, d = 14, e = 15, f = 16, g = 17, h = 18}
-// debugger:continue
-
-// BINDING
-// debugger:print a
-// check:$6 = 19
-// debugger:print b
-// check:$7 = 20
-// debugger:print c
-// check:$8 = 21.5
-// debugger:continue
-
-// ASSIGNMENT
-// debugger:print a
-// check:$9 = 22
-// debugger:print b
-// check:$10 = 23
-// debugger:print c
-// check:$11 = 24.5
-// debugger:continue
-
-// FUNCTION CALL
-// debugger:print x
-// check:$12 = 25
-// debugger:print y
-// check:$13 = 26
-// debugger:print z
-// check:$14 = 27.5
-// debugger:continue
-
-// EXPR
-// debugger:print x
-// check:$15 = 28
-// debugger:print y
-// check:$16 = 29
-// debugger:print z
-// check:$17 = 30.5
-// debugger:continue
-
-// RETURN EXPR
-// debugger:print x
-// check:$18 = 31
-// debugger:print y
-// check:$19 = 32
-// debugger:print z
-// check:$20 = 33.5
-// debugger:continue
-
-// ARITHMETIC EXPR
-// debugger:print x
-// check:$21 = 34
-// debugger:print y
-// check:$22 = 35
-// debugger:print z
-// check:$23 = 36.5
-// debugger:continue
-
-// IF EXPR
-// debugger:print x
-// check:$24 = 37
-// debugger:print y
-// check:$25 = 38
-// debugger:print z
-// check:$26 = 39.5
-// debugger:continue
-
-// WHILE EXPR
-// debugger:print x
-// check:$27 = 40
-// debugger:print y
-// check:$28 = 41
-// debugger:print z
-// check:$29 = 42
-// debugger:continue
-
-// LOOP EXPR
-// debugger:print x
-// check:$30 = 43
-// debugger:print y
-// check:$31 = 44
-// debugger:print z
-// check:$32 = 45
-// debugger:continue
-
-#![allow(unused_variable)]
-
-#[no_split_stack]
-fn immediate_args(a: int, b: bool, c: f64) {
-    ()
-}
-
-struct BigStruct {
-    a: u64,
-    b: u64,
-    c: u64,
-    d: u64,
-    e: u64,
-    f: u64,
-    g: u64,
-    h: u64
-}
-
-#[no_split_stack]
-fn non_immediate_args(a: BigStruct, b: BigStruct) {
-    ()
-}
-
-#[no_split_stack]
-fn binding(a: i64, b: u64, c: f64) {
-    let x = 0;
-}
-
-#[no_split_stack]
-fn assignment(mut a: u64, b: u64, c: f64) {
-    a = b;
-}
-
-#[no_split_stack]
-fn function_call(x: u64, y: u64, z: f64) {
-    std::io::stdio::print("Hi!")
-}
-
-#[no_split_stack]
-fn identifier(x: u64, y: u64, z: f64) -> u64 {
-    x
-}
-
-#[no_split_stack]
-fn return_expr(x: u64, y: u64, z: f64) -> u64 {
-    return x;
-}
-
-#[no_split_stack]
-fn arithmetic_expr(x: u64, y: u64, z: f64) -> u64 {
-    x + y
-}
-
-#[no_split_stack]
-fn if_expr(x: u64, y: u64, z: f64) -> u64 {
-    if x + y < 1000 {
-        x
-    } else {
-        y
-    }
-}
-
-#[no_split_stack]
-fn while_expr(mut x: u64, y: u64, z: u64) -> u64 {
-    while x + y < 1000 {
-        x += z
-    }
-    return x;
-}
-
-#[no_split_stack]
-fn loop_expr(mut x: u64, y: u64, z: u64) -> u64 {
-    loop {
-        x += z;
-
-        if x + y > 1000 {
-            return x;
-        }
-    }
-}
-
-fn main() {
-    immediate_args(1, true, 2.5);
-
-    non_immediate_args(
-        BigStruct {
-            a: 3,
-            b: 4,
-            c: 5,
-            d: 6,
-            e: 7,
-            f: 8,
-            g: 9,
-            h: 10
-        },
-        BigStruct {
-            a: 11,
-            b: 12,
-            c: 13,
-            d: 14,
-            e: 15,
-            f: 16,
-            g: 17,
-            h: 18
-        }
-    );
-
-    binding(19, 20, 21.5);
-    assignment(22, 23, 24.5);
-    function_call(25, 26, 27.5);
-    identifier(28, 29, 30.5);
-    return_expr(31, 32, 33.5);
-    arithmetic_expr(34, 35, 36.5);
-    if_expr(37, 38, 39.5);
-    while_expr(40, 41, 42);
-    loop_expr(43, 44, 45);
-}
diff --git a/src/test/debug-info/generic-function.rs b/src/test/debug-info/generic-function.rs
deleted file mode 100644 (file)
index 6197520..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak 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: f64
-}
-
-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
deleted file mode 100644 (file)
index 20991ba..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak 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
deleted file mode 100644 (file)
index 7afa895..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak 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
-// debugger:print self
-// check:$4 = {x = {8888, -8888}}
-// debugger:print arg1
-// check:$5 = -3
-// debugger:print arg2
-// check:$6 = -4
-// debugger:continue
-
-// OWNED BY REF
-// debugger:finish
-// debugger:print *self
-// check:$7 = {x = 1234.5}
-// debugger:print arg1
-// check:$8 = -5
-// debugger:print arg2
-// check:$9 = -6
-// debugger:continue
-
-// OWNED BY VAL
-// debugger:finish
-// debugger:print self
-// check:$10 = {x = 1234.5}
-// debugger:print arg1
-// check:$11 = -7
-// debugger:print arg2
-// check:$12 = -8
-// debugger:continue
-
-// OWNED MOVED
-// debugger:finish
-// debugger:print *self
-// check:$13 = {x = 1234.5}
-// debugger:print arg1
-// check:$14 = -9
-// debugger:print arg2
-// check:$15 = -10.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 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 = box 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);
-}
-
-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
deleted file mode 100644 (file)
index 224e7aa..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak 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
-
-#![feature(struct_variant)]
-
-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(f64, 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
deleted file mode 100644 (file)
index e32110a..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:set print union on
-// debugger:rbreak 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}
-
-#![feature(struct_variant)]
-
-// 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
deleted file mode 100644 (file)
index 0fd491c..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak 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
deleted file mode 100644 (file)
index fbb1ef1..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-// ignore-test
-
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// compile-flags:-g
-// debugger:rbreak 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
deleted file mode 100644 (file)
index 73a46c3..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:set print union on
-// debugger:rbreak 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/include_string.rs b/src/test/debug-info/include_string.rs
deleted file mode 100644 (file)
index 6838af2..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-// debugger:print string1.length
-// check:$1 = 48
-// debugger:print string2.length
-// check:$2 = 48
-// debugger:print string3.length
-// check:$3 = 48
-// debugger:continue
-
-#![allow(unused_variable)]
-
-// This test case makes sure that debug info does not ICE when include_str is
-// used multiple times (see issue #11322).
-
-fn main() {
-    let string1 = include_str!("text-to-include-1.txt");
-    let string2 = include_str!("text-to-include-2.txt");
-    let string3 = include_str!("text-to-include-3.txt");
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/issue11600.rs b/src/test/debug-info/issue11600.rs
deleted file mode 100644 (file)
index 83ad5c4..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    let args : ~[~str] = ::std::os::args();
-    ::std::io::println(args[0]);
-}
-
-
-// ignore-android: FIXME(#10381)
-
-// This test case checks whether compile unit names are set correctly, so that the correct default
-// source file can be found.
-
-// compile-flags:-g
-// debugger:list
-// check:1[...]fn main() {
-// check:2[...]let args : ~[~str] = ::std::os::args();
-// check:3[...]::std::io::println(args[0]);
-// check:4[...]}
-
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
diff --git a/src/test/debug-info/issue12886.rs b/src/test/debug-info/issue12886.rs
deleted file mode 100644 (file)
index 328ed54..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:break issue12886.rs:29
-// debugger:run
-// debugger:next
-// check:[...]30[...]s
-// debugger:continue
-
-// IF YOU MODIFY THIS FILE, BE CAREFUL TO ADAPT THE LINE NUMBERS IN THE DEBUGGER COMMANDS
-
-// This test makes sure that gdb does not set unwanted breakpoints in inlined functions. If a
-// breakpoint existed in unwrap(), then calling `next` would (when stopped at line 27) would stop
-// in unwrap() instead of stepping over the function invocation. By making sure that `s` is
-// contained in the output, after calling `next` just once, we can be sure that we did not stop in
-// unwrap(). (The testing framework doesn't allow for checking that some text is *not* contained in
-// the output, which is why we have to make the test in this kind of roundabout way)
-fn bar() -> int {
-    let s = Some(5).unwrap();
-    s
-}
-
-fn main() {
-    let _ = bar();
-}
diff --git a/src/test/debug-info/issue13213.rs b/src/test/debug-info/issue13213.rs
deleted file mode 100644 (file)
index a03b263..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// aux-build:issue13213aux.rs
-extern crate issue13213aux;
-
-// compile-flags:-g
-
-// This tests make sure that we get no linker error when using a completely inlined static. Some
-// statics that are marked with AvailableExternallyLinkage in the importing crate, may actually not
-// be available because they have been optimized out from the exporting crate.
-fn main() {
-    let b: issue13213aux::S = issue13213aux::A;
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/issue7712.rs b/src/test/debug-info/issue7712.rs
deleted file mode 100644 (file)
index 8308afc..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// compile-flags:--debuginfo=1
-
-pub trait TraitWithDefaultMethod {
-    fn method(self) {
-        ()
-    }
-}
-
-struct MyStruct;
-
-impl TraitWithDefaultMethod for MyStruct { }
-
-pub fn main() {
-    MyStruct.method();
-}
diff --git a/src/test/debug-info/lexical-scope-in-for-loop.rs b/src/test/debug-info/lexical-scope-in-for-loop.rs
deleted file mode 100644 (file)
index 75f1d77..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-
-// FIRST ITERATION
-// debugger:finish
-// debugger:print x
-// check:$1 = 1
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$2 = -1
-// debugger:continue
-
-// SECOND ITERATION
-// debugger:finish
-// debugger:print x
-// check:$3 = 2
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$4 = -2
-// debugger:continue
-
-// THIRD ITERATION
-// debugger:finish
-// debugger:print x
-// check:$5 = 3
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$6 = -3
-// debugger:continue
-
-// AFTER LOOP
-// debugger:finish
-// debugger:print x
-// check:$7 = 1000000
-// debugger:continue
-
-fn main() {
-
-    let range = [1, 2, 3];
-
-    let x = 1000000; // wan meeeljen doollaars!
-
-    for &x in range.iter() {
-        zzz();
-        sentinel();
-
-        let x = -1 * x;
-
-        zzz();
-        sentinel();
-    }
-
-    zzz();
-    sentinel();
-}
-
-fn zzz() {()}
-fn sentinel() {()}
diff --git a/src/test/debug-info/lexical-scope-in-if.rs b/src/test/debug-info/lexical-scope-in-if.rs
deleted file mode 100644 (file)
index 712880d..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-
-// BEFORE if
-// debugger:finish
-// debugger:print x
-// check:$1 = 999
-// debugger:print y
-// check:$2 = -1
-// debugger:continue
-
-// AT BEGINNING of 'then' block
-// debugger:finish
-// debugger:print x
-// check:$3 = 999
-// debugger:print y
-// check:$4 = -1
-// debugger:continue
-
-// AFTER 1st redeclaration of 'x'
-// debugger:finish
-// debugger:print x
-// check:$5 = 1001
-// debugger:print y
-// check:$6 = -1
-// debugger:continue
-
-// AFTER 2st redeclaration of 'x'
-// debugger:finish
-// debugger:print x
-// check:$7 = 1002
-// debugger:print y
-// check:$8 = 1003
-// debugger:continue
-
-// AFTER 1st if expression
-// debugger:finish
-// debugger:print x
-// check:$9 = 999
-// debugger:print y
-// check:$10 = -1
-// debugger:continue
-
-// BEGINNING of else branch
-// debugger:finish
-// debugger:print x
-// check:$11 = 999
-// debugger:print y
-// check:$12 = -1
-// debugger:continue
-
-// BEGINNING of else branch
-// debugger:finish
-// debugger:print x
-// check:$13 = 1004
-// debugger:print y
-// check:$14 = 1005
-// debugger:continue
-
-// BEGINNING of else branch
-// debugger:finish
-// debugger:print x
-// check:$15 = 999
-// debugger:print y
-// check:$16 = -1
-// debugger:continue
-
-fn main() {
-
-    let x = 999;
-    let y = -1;
-
-    zzz();
-    sentinel();
-
-    if x < 1000 {
-        zzz();
-        sentinel();
-
-        let x = 1001;
-
-        zzz();
-        sentinel();
-
-        let x = 1002;
-        let y = 1003;
-        zzz();
-        sentinel();
-    } else {
-        unreachable!();
-    }
-
-    zzz();
-    sentinel();
-
-    if x > 1000 {
-        unreachable!();
-    } else {
-        zzz();
-        sentinel();
-
-        let x = 1004;
-        let y = 1005;
-        zzz();
-        sentinel();
-    }
-
-    zzz();
-    sentinel();
-}
-
-fn zzz() {()}
-fn sentinel() {()}
diff --git a/src/test/debug-info/lexical-scope-in-match.rs b/src/test/debug-info/lexical-scope-in-match.rs
deleted file mode 100644 (file)
index 041c8b5..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-
-// debugger:finish
-// debugger:print shadowed
-// check:$1 = 231
-// debugger:print not_shadowed
-// check:$2 = 232
-// debugger:continue
-
-// debugger:finish
-// debugger:print shadowed
-// check:$3 = 233
-// debugger:print not_shadowed
-// check:$4 = 232
-// debugger:print local_to_arm
-// check:$5 = 234
-// debugger:continue
-
-// debugger:finish
-// debugger:print shadowed
-// check:$6 = 236
-// debugger:print not_shadowed
-// check:$7 = 232
-// debugger:continue
-
-// debugger:finish
-// debugger:print shadowed
-// check:$8 = 237
-// debugger:print not_shadowed
-// check:$9 = 232
-// debugger:print local_to_arm
-// check:$10 = 238
-// debugger:continue
-
-// debugger:finish
-// debugger:print shadowed
-// check:$11 = 239
-// debugger:print not_shadowed
-// check:$12 = 232
-// debugger:continue
-
-// debugger:finish
-// debugger:print shadowed
-// check:$13 = 241
-// debugger:print not_shadowed
-// check:$14 = 232
-// debugger:continue
-
-// debugger:finish
-// debugger:print shadowed
-// check:$15 = 243
-// debugger:print *local_to_arm
-// check:$16 = 244
-// debugger:continue
-
-// debugger:finish
-// debugger:print shadowed
-// check:$17 = 231
-// debugger:print not_shadowed
-// check:$18 = 232
-// debugger:continue
-
-struct Struct {
-    x: int,
-    y: int
-}
-
-fn main() {
-
-    let shadowed = 231;
-    let not_shadowed = 232;
-
-    zzz();
-    sentinel();
-
-    match (233, 234) {
-        (shadowed, local_to_arm) => {
-
-            zzz();
-            sentinel();
-        }
-    }
-
-    match (235, 236) {
-        // with literal
-        (235, shadowed) => {
-
-            zzz();
-            sentinel();
-        }
-        _ => {}
-    }
-
-    match Struct { x: 237, y: 238 } {
-        Struct { x: shadowed, y: local_to_arm } => {
-
-            zzz();
-            sentinel();
-        }
-    }
-
-    match Struct { x: 239, y: 240 } {
-        // ignored field
-        Struct { x: shadowed, .. } => {
-
-            zzz();
-            sentinel();
-        }
-    }
-
-    match Struct { x: 241, y: 242 } {
-        // with literal
-        Struct { x: shadowed, y: 242 } => {
-
-            zzz();
-            sentinel();
-        }
-        _ => {}
-    }
-
-    match (243, 244) {
-        (shadowed, ref local_to_arm) => {
-
-            zzz();
-            sentinel();
-        }
-    }
-
-    zzz();
-    sentinel();
-}
-
-fn zzz() {()}
-fn sentinel() {()}
diff --git a/src/test/debug-info/lexical-scope-in-parameterless-closure.rs b/src/test/debug-info/lexical-scope-in-parameterless-closure.rs
deleted file mode 100644 (file)
index fd0a156..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:--debuginfo=1
-// debugger:run
-
-// Nothing to do here really, just make sure it compiles. See issue #8513.
-fn main() {
-    let _ = ||();
-    let _ = range(1u,3).map(|_| 5);
-}
-
diff --git a/src/test/debug-info/lexical-scope-in-stack-closure.rs b/src/test/debug-info/lexical-scope-in-stack-closure.rs
deleted file mode 100644 (file)
index 41432c6..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-
-// debugger:finish
-// debugger:print x
-// check:$1 = false
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$2 = false
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$3 = 1000
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$4 = 2.5
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$5 = true
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$6 = false
-// debugger:continue
-
-fn main() {
-
-    let x = false;
-
-    zzz();
-    sentinel();
-
-    let stack_closure: |int| = |x| {
-        zzz();
-        sentinel();
-
-        let x = 2.5;
-
-        zzz();
-        sentinel();
-
-        let x = true;
-
-        zzz();
-        sentinel();
-    };
-
-    zzz();
-    sentinel();
-
-    stack_closure(1000);
-
-    zzz();
-    sentinel();
-}
-
-fn zzz() {()}
-fn sentinel() {()}
diff --git a/src/test/debug-info/lexical-scope-in-unconditional-loop.rs b/src/test/debug-info/lexical-scope-in-unconditional-loop.rs
deleted file mode 100644 (file)
index fd21791..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-
-// FIRST ITERATION
-// debugger:finish
-// debugger:print x
-// check:$1 = 0
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$2 = 1
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$3 = 101
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$4 = 101
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$5 = -987
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$6 = 101
-// debugger:continue
-
-
-// SECOND ITERATION
-// debugger:finish
-// debugger:print x
-// check:$7 = 1
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$8 = 2
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$9 = 102
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$10 = 102
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$11 = -987
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$12 = 102
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$13 = 2
-// debugger:continue
-
-fn main() {
-
-    let mut x = 0;
-
-    loop {
-        if x >= 2 {
-            break;
-        }
-
-        zzz();
-        sentinel();
-
-        x += 1;
-        zzz();
-        sentinel();
-
-        // Shadow x
-        let x = x + 100;
-        zzz();
-        sentinel();
-
-        // open scope within loop's top level scope
-        {
-            zzz();
-            sentinel();
-
-            let x = -987;
-
-            zzz();
-            sentinel();
-        }
-
-        // Check that we get the x before the inner scope again
-        zzz();
-        sentinel();
-    }
-
-    zzz();
-    sentinel();
-}
-
-fn zzz() {()}
-fn sentinel() {()}
diff --git a/src/test/debug-info/lexical-scope-in-unique-closure.rs b/src/test/debug-info/lexical-scope-in-unique-closure.rs
deleted file mode 100644 (file)
index e0ab212..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-
-// debugger:finish
-// debugger:print x
-// check:$1 = false
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$2 = false
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$3 = 1000
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$4 = 2.5
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$5 = true
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$6 = false
-// debugger:continue
-
-fn main() {
-
-    let x = false;
-
-    zzz();
-    sentinel();
-
-    let unique_closure: proc(int) = proc(x) {
-        zzz();
-        sentinel();
-
-        let x = 2.5;
-
-        zzz();
-        sentinel();
-
-        let x = true;
-
-        zzz();
-        sentinel();
-    };
-
-    zzz();
-    sentinel();
-
-    unique_closure(1000);
-
-    zzz();
-    sentinel();
-}
-
-fn zzz() {()}
-fn sentinel() {()}
diff --git a/src/test/debug-info/lexical-scope-in-while.rs b/src/test/debug-info/lexical-scope-in-while.rs
deleted file mode 100644 (file)
index a473434..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-
-// FIRST ITERATION
-// debugger:finish
-// debugger:print x
-// check:$1 = 0
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$2 = 1
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$3 = 101
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$4 = 101
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$5 = -987
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$6 = 101
-// debugger:continue
-
-
-// SECOND ITERATION
-// debugger:finish
-// debugger:print x
-// check:$7 = 1
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$8 = 2
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$9 = 102
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$10 = 102
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$11 = -987
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$12 = 102
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$13 = 2
-// debugger:continue
-
-fn main() {
-
-    let mut x = 0;
-
-    while x < 2 {
-        zzz();
-        sentinel();
-
-        x += 1;
-        zzz();
-        sentinel();
-
-        // Shadow x
-        let x = x + 100;
-        zzz();
-        sentinel();
-
-        // open scope within loop's top level scope
-        {
-            zzz();
-            sentinel();
-
-            let x = -987;
-
-            zzz();
-            sentinel();
-        }
-
-        // Check that we get the x before the inner scope again
-        zzz();
-        sentinel();
-    }
-
-    zzz();
-    sentinel();
-}
-
-fn zzz() {()}
-fn sentinel() {()}
diff --git a/src/test/debug-info/lexical-scope-with-macro.rs b/src/test/debug-info/lexical-scope-with-macro.rs
deleted file mode 100644 (file)
index 6cbaedf..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-
-// debugger:finish
-// debugger:print a
-// check:$1 = 10
-// debugger:print b
-// check:$2 = 34
-// debugger:continue
-
-// debugger:finish
-// debugger:print a
-// check:$3 = 890242
-// debugger:print b
-// check:$4 = 34
-// debugger:continue
-
-// debugger:finish
-// debugger:print a
-// check:$5 = 10
-// debugger:print b
-// check:$6 = 34
-// debugger:continue
-
-// debugger:finish
-// debugger:print a
-// check:$7 = 102
-// debugger:print b
-// check:$8 = 34
-// debugger:continue
-
-// debugger:finish
-// debugger:print a
-// check:$9 = 110
-// debugger:print b
-// check:$10 = 34
-// debugger:continue
-
-// debugger:finish
-// debugger:print a
-// check:$11 = 10
-// debugger:print b
-// check:$12 = 34
-// debugger:continue
-
-// debugger:finish
-// debugger:print a
-// check:$13 = 10
-// debugger:print b
-// check:$14 = 34
-// debugger:print c
-// check:$15 = 400
-// debugger:continue
-
-#![feature(macro_rules)]
-
-macro_rules! trivial(
-    ($e1:expr) => ($e1)
-)
-
-macro_rules! no_new_scope(
-    ($e1:expr) => (($e1 + 2) - 1)
-)
-
-macro_rules! new_scope(
-    () => ({
-        let a = 890242;
-        zzz();
-        sentinel();
-    })
-)
-
-macro_rules! shadow_within_macro(
-    ($e1:expr) => ({
-        let a = $e1 + 2;
-
-        zzz();
-        sentinel();
-
-        let a = $e1 + 10;
-
-        zzz();
-        sentinel();
-    })
-)
-
-
-macro_rules! dup_expr(
-    ($e1:expr) => (($e1) + ($e1))
-)
-
-
-fn main() {
-
-    let a = trivial!(10);
-    let b = no_new_scope!(33);
-
-    zzz();
-    sentinel();
-
-    new_scope!();
-
-    zzz();
-    sentinel();
-
-    shadow_within_macro!(100);
-
-    zzz();
-    sentinel();
-
-    let c = dup_expr!(10 * 20);
-
-    zzz();
-    sentinel();
-}
-
-fn zzz() {()}
-fn sentinel() {()}
diff --git a/src/test/debug-info/lexical-scopes-in-block-expression.rs b/src/test/debug-info/lexical-scopes-in-block-expression.rs
deleted file mode 100644 (file)
index 6626d75..0000000
+++ /dev/null
@@ -1,377 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-win32: FIXME #13256
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-
-// debugger:print 'lexical-scopes-in-block-expression::MUT_INT'
-// check:$1 = 0
-
-// STRUCT EXPRESSION
-// debugger:finish
-// debugger:print val
-// check:$2 = -1
-// debugger:print ten
-// check:$3 = 10
-// debugger:continue
-
-// debugger:finish
-// debugger:print val
-// check:$4 = 11
-// debugger:print 'lexical-scopes-in-block-expression::MUT_INT'
-// check:$5 = 1
-// debugger:print ten
-// check:$6 = 10
-// debugger:continue
-
-// debugger:finish
-// debugger:print val
-// check:$7 = -1
-// debugger:print ten
-// check:$8 = 10
-// debugger:continue
-
-// FUNCTION CALL
-// debugger:finish
-// debugger:print val
-// check:$9 = -1
-// debugger:print ten
-// check:$10 = 10
-// debugger:continue
-
-// debugger:finish
-// debugger:print val
-// check:$11 = 12
-// debugger:print 'lexical-scopes-in-block-expression::MUT_INT'
-// check:$12 = 2
-// debugger:print ten
-// check:$13 = 10
-// debugger:continue
-
-// debugger:finish
-// debugger:print val
-// check:$14 = -1
-// debugger:print ten
-// check:$15 = 10
-// debugger:continue
-
-// TUPLE EXPRESSION
-// debugger:finish
-// debugger:print val
-// check:$16 = -1
-// debugger:print ten
-// check:$17 = 10
-// debugger:continue
-
-// debugger:finish
-// debugger:print val
-// check:$18 = 13
-// debugger:print 'lexical-scopes-in-block-expression::MUT_INT'
-// check:$19 = 3
-// debugger:print ten
-// check:$20 = 10
-// debugger:continue
-
-// debugger:finish
-// debugger:print val
-// check:$21 = -1
-// debugger:print ten
-// check:$22 = 10
-// debugger:continue
-
-// VEC EXPRESSION
-// debugger:finish
-// debugger:print val
-// check:$23 = -1
-// debugger:print ten
-// check:$24 = 10
-// debugger:continue
-
-// debugger:finish
-// debugger:print val
-// check:$25 = 14
-// debugger:print 'lexical-scopes-in-block-expression::MUT_INT'
-// check:$26 = 4
-// debugger:print ten
-// check:$27 = 10
-// debugger:continue
-
-// debugger:finish
-// debugger:print val
-// check:$28 = -1
-// debugger:print ten
-// check:$29 = 10
-// debugger:continue
-
-// REPEAT VEC EXPRESSION
-// debugger:finish
-// debugger:print val
-// check:$30 = -1
-// debugger:print ten
-// check:$31 = 10
-// debugger:continue
-
-// debugger:finish
-// debugger:print val
-// check:$32 = 15
-// debugger:print 'lexical-scopes-in-block-expression::MUT_INT'
-// check:$33 = 5
-// debugger:print ten
-// check:$34 = 10
-// debugger:continue
-
-// debugger:finish
-// debugger:print val
-// check:$35 = -1
-// debugger:print ten
-// check:$36 = 10
-// debugger:continue
-
-// ASSIGNMENT EXPRESSION
-// debugger:finish
-// debugger:print val
-// check:$37 = -1
-// debugger:print ten
-// check:$38 = 10
-// debugger:continue
-
-// debugger:finish
-// debugger:print val
-// check:$39 = 16
-// debugger:print 'lexical-scopes-in-block-expression::MUT_INT'
-// check:$40 = 6
-// debugger:print ten
-// check:$41 = 10
-// debugger:continue
-
-// debugger:finish
-// debugger:print val
-// check:$42 = -1
-// debugger:print ten
-// check:$43 = 10
-// debugger:continue
-
-
-// ARITHMETIC EXPRESSION
-// debugger:finish
-// debugger:print val
-// check:$44 = -1
-// debugger:print ten
-// check:$45 = 10
-// debugger:continue
-
-// debugger:finish
-// debugger:print val
-// check:$46 = 17
-// debugger:print 'lexical-scopes-in-block-expression::MUT_INT'
-// check:$47 = 7
-// debugger:print ten
-// check:$48 = 10
-// debugger:continue
-
-// debugger:finish
-// debugger:print val
-// check:$49 = -1
-// debugger:print ten
-// check:$50 = 10
-// debugger:continue
-
-// INDEX EXPRESSION
-// debugger:finish
-// debugger:print val
-// check:$51 = -1
-// debugger:print ten
-// check:$52 = 10
-// debugger:continue
-
-// debugger:finish
-// debugger:print val
-// check:$53 = 18
-// debugger:print 'lexical-scopes-in-block-expression::MUT_INT'
-// check:$54 = 8
-// debugger:print ten
-// check:$55 = 10
-// debugger:continue
-
-// debugger:finish
-// debugger:print val
-// check:$56 = -1
-// debugger:print ten
-// check:$57 = 10
-// debugger:continue
-
-#![allow(unused_variable)]
-#![allow(dead_assignment)]
-
-static mut MUT_INT: int = 0;
-
-struct Point {
-    x: int,
-    y: int
-}
-
-fn a_function(x: int) -> int {
-    x + 1
-}
-
-fn main() {
-
-    let val = -1;
-    let ten = 10;
-
-    // surrounded by struct expression
-    let point = Point {
-        x: {
-            zzz();
-            sentinel();
-
-            let val = ten + 1;
-            unsafe {MUT_INT = 1;};
-
-            zzz();
-            sentinel();
-
-            val
-        },
-        y: 10
-    };
-
-    zzz();
-    sentinel();
-
-    // surrounded by function call
-    let _ = a_function({
-        zzz();
-        sentinel();
-
-        let val = ten + 2;
-        unsafe {MUT_INT = 2;};
-
-        zzz();
-        sentinel();
-
-        val
-    });
-
-    zzz();
-    sentinel();
-
-
-    // surrounded by tup
-    let _ = ({
-        zzz();
-        sentinel();
-
-        let val = ten + 3;
-        unsafe {MUT_INT = 3;};
-
-        zzz();
-        sentinel();
-
-        val
-    }, 0);
-
-    zzz();
-    sentinel();
-
-    // surrounded by vec
-    let _ = [{
-        zzz();
-        sentinel();
-
-        let val = ten + 4;
-        unsafe {MUT_INT = 4;};
-
-        zzz();
-        sentinel();
-
-        val
-    }, 0, 0];
-
-    zzz();
-    sentinel();
-
-    // surrounded by repeat vec
-    let _ = [{
-        zzz();
-        sentinel();
-
-        let val = ten + 5;
-        unsafe {MUT_INT = 5;};
-
-        zzz();
-        sentinel();
-
-        val
-    }, ..10];
-
-    zzz();
-    sentinel();
-
-    // assignment expression
-    let mut var = 0;
-    var = {
-        zzz();
-        sentinel();
-
-        let val = ten + 6;
-        unsafe {MUT_INT = 6;};
-
-        zzz();
-        sentinel();
-
-        val
-    };
-
-    zzz();
-    sentinel();
-
-    // arithmetic expression
-    var = 10 + -{
-        zzz();
-        sentinel();
-
-        let val = ten + 7;
-        unsafe {MUT_INT = 7;};
-
-        zzz();
-        sentinel();
-
-        val
-    } * 5;
-
-    zzz();
-    sentinel();
-
-    // index expression
-    let a_vector = [10, ..20];
-    let _ = a_vector[{
-        zzz();
-        sentinel();
-
-        let val = ten + 8;
-        unsafe {MUT_INT = 8;};
-
-        zzz();
-        sentinel();
-
-        val as uint
-    }];
-
-    zzz();
-    sentinel();
-}
-
-fn zzz() {()}
-fn sentinel() {()}
diff --git a/src/test/debug-info/limited-debuginfo.rs b/src/test/debug-info/limited-debuginfo.rs
deleted file mode 100644 (file)
index 51d9aa7..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:--debuginfo=1
-
-// Make sure functions have proper names
-// debugger:info functions
-// check:[...]void[...]main([...]);
-// check:[...]void[...]some_function([...]);
-// check:[...]void[...]some_other_function([...]);
-// check:[...]void[...]zzz([...]);
-
-// debugger:rbreak zzz
-// debugger:run
-
-// Make sure there is no information about locals
-// debugger:finish
-// debugger:info locals
-// check:No locals.
-// debugger:continue
-
-
-#![allow(unused_variable)]
-
-struct Struct {
-    a: i64,
-    b: i32
-}
-
-fn main() {
-    some_function(101, 202);
-    some_other_function(1, 2);
-}
-
-
-fn zzz() {()}
-
-fn some_function(a: int, b: int) {
-    let some_variable = Struct { a: 11, b: 22 };
-    let some_other_variable = 23;
-    zzz();
-}
-
-fn some_other_function(a: int, b: int) -> bool { true }
diff --git a/src/test/debug-info/managed-enum.rs b/src/test/debug-info/managed-enum.rs
deleted file mode 100644 (file)
index a7fb3b3..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print the_a->val
-// check:$1 = {{TheA, x = 0, y = 8970181431921507452}, {TheA, 0, 2088533116, 2088533116}}
-
-// debugger:print the_b->val
-// check:$2 = {{TheB, x = 0, y = 1229782938247303441}, {TheB, 0, 286331153, 286331153}}
-
-// debugger:print univariant->val
-// check:$3 = {-9747455}
-
-#![allow(unused_variable)]
-#![feature(struct_variant, managed_boxes)]
-
-// 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 ABC {
-    TheA { x: i64, y: i64 },
-    TheB (i64, i32, i32),
-}
-
-// This is a special case since it does not have the implicit discriminant field.
-enum Univariant {
-    TheOnlyCase(i64)
-}
-
-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 the_a = @TheA { x: 0, y: 8970181431921507452 };
-
-    // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
-    // 0b00010001000100010001000100010001 = 286331153
-    // 0b0001000100010001 = 4369
-    // 0b00010001 = 17
-    let the_b = @TheB (0, 286331153, 286331153);
-
-    let univariant = @TheOnlyCase(-9747455);
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/managed-pointer-within-unique-vec.rs b/src/test/debug-info/managed-pointer-within-unique-vec.rs
deleted file mode 100644 (file)
index 45989fd..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-#![feature(managed_boxes)]
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print unique.ptr[0]->val
-// check:$1 = 10
-
-// debugger:print unique.ptr[1]->val
-// check:$2 = 11
-
-// debugger:print unique.ptr[2]->val
-// check:$3 = 12
-
-// debugger:print unique.ptr[3]->val
-// check:$4 = 13
-
-#![allow(unused_variable)]
-
-fn main() {
-
-    let unique: Vec<@i64> = vec!(@10, @11, @12, @13);
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/managed-pointer-within-unique.rs b/src/test/debug-info/managed-pointer-within-unique.rs
deleted file mode 100644 (file)
index 2207b3e..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-#![feature(managed_boxes)]
-
-// compile-flags:-g
-// debugger:set print pretty off
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print *ordinary_unique
-// check:$1 = {-1, -2}
-
-// debugger:print managed_within_unique->x
-// check:$2 = -3
-
-// debugger:print managed_within_unique->y->val
-// check:$3 = -4
-
-#![allow(unused_variable)]
-
-struct ContainsManaged {
-    x: int,
-    y: @int
-}
-
-fn main() {
-    let ordinary_unique = box() (-1, -2);
-
-    let managed_within_unique = box ContainsManaged { x: -3, y: @-4 };
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/method-on-enum.rs b/src/test/debug-info/method-on-enum.rs
deleted file mode 100644 (file)
index 9c8718a..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-
-// STACK BY REF
-// debugger:finish
-// debugger:print *self
-// check:$1 = {{Variant2, [...]}, {Variant2, 117901063}}
-// debugger:print arg1
-// check:$2 = -1
-// debugger:print arg2
-// check:$3 = -2
-// debugger:continue
-
-// STACK BY VAL
-// debugger:finish
-// debugger:print self
-// check:$4 = {{Variant2, [...]}, {Variant2, 117901063}}
-// debugger:print arg1
-// check:$5 = -3
-// debugger:print arg2
-// check:$6 = -4
-// debugger:continue
-
-// OWNED BY REF
-// debugger:finish
-// debugger:print *self
-// check:$7 = {{Variant1, x = 1799, y = 1799}, {Variant1, [...]}}
-// debugger:print arg1
-// check:$8 = -5
-// debugger:print arg2
-// check:$9 = -6
-// debugger:continue
-
-// OWNED BY VAL
-// debugger:finish
-// debugger:print self
-// check:$10 = {{Variant1, x = 1799, y = 1799}, {Variant1, [...]}}
-// debugger:print arg1
-// check:$11 = -7
-// debugger:print arg2
-// check:$12 = -8
-// debugger:continue
-
-// OWNED MOVED
-// debugger:finish
-// debugger:print *self
-// check:$13 = {{Variant1, x = 1799, y = 1799}, {Variant1, [...]}}
-// debugger:print arg1
-// check:$14 = -9
-// debugger:print arg2
-// check:$15 = -10
-// debugger:continue
-
-#![feature(struct_variant)]
-
-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 main() {
-    let stack = Variant2(117901063);
-    let _ = stack.self_by_ref(-1, -2);
-    let _ = stack.self_by_val(-3, -4);
-
-    let owned = box 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);
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/method-on-generic-struct.rs b/src/test/debug-info/method-on-generic-struct.rs
deleted file mode 100644 (file)
index f2cdadd..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak 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
-// debugger:print self
-// check:$4 = {x = {8888, -8888}}
-// debugger:print arg1
-// check:$5 = -3
-// debugger:print arg2
-// check:$6 = -4
-// debugger:continue
-
-// OWNED BY REF
-// debugger:finish
-// debugger:print *self
-// check:$7 = {x = 1234.5}
-// debugger:print arg1
-// check:$8 = -5
-// debugger:print arg2
-// check:$9 = -6
-// debugger:continue
-
-// OWNED BY VAL
-// debugger:finish
-// debugger:print self
-// check:$10 = {x = 1234.5}
-// debugger:print arg1
-// check:$11 = -7
-// debugger:print arg2
-// check:$12 = -8
-// debugger:continue
-
-// OWNED MOVED
-// debugger:finish
-// debugger:print *self
-// check:$13 = {x = 1234.5}
-// debugger:print arg1
-// check:$14 = -9
-// debugger:print arg2
-// check:$15 = -10
-// 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 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 = box Struct { x: 1234.5 };
-    let _ = owned.self_by_ref(-5, -6);
-    let _ = owned.self_by_val(-7, -8);
-    let _ = owned.self_owned(-9, -10);
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/method-on-struct.rs b/src/test/debug-info/method-on-struct.rs
deleted file mode 100644 (file)
index dcd285b..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak 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
-// debugger:print self
-// check:$4 = {x = 100}
-// debugger:print arg1
-// check:$5 = -3
-// debugger:print arg2
-// check:$6 = -4
-// debugger:continue
-
-// OWNED BY REF
-// debugger:finish
-// debugger:print *self
-// check:$7 = {x = 200}
-// debugger:print arg1
-// check:$8 = -5
-// debugger:print arg2
-// check:$9 = -6
-// debugger:continue
-
-// OWNED BY VAL
-// debugger:finish
-// debugger:print self
-// check:$10 = {x = 200}
-// debugger:print arg1
-// check:$11 = -7
-// debugger:print arg2
-// check:$12 = -8
-// debugger:continue
-
-// OWNED MOVED
-// debugger:finish
-// debugger:print *self
-// check:$13 = {x = 200}
-// debugger:print arg1
-// check:$14 = -9
-// debugger:print arg2
-// check:$15 = -10
-// 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 main() {
-    let stack = Struct { x: 100 };
-    let _ = stack.self_by_ref(-1, -2);
-    let _ = stack.self_by_val(-3, -4);
-
-    let owned = box Struct { x: 200 };
-    let _ = owned.self_by_ref(-5, -6);
-    let _ = owned.self_by_val(-7, -8);
-    let _ = owned.self_owned(-9, -10);
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/method-on-trait.rs b/src/test/debug-info/method-on-trait.rs
deleted file mode 100644 (file)
index 6e1f8e6..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak 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
-// debugger:print self
-// check:$4 = {x = 100}
-// debugger:print arg1
-// check:$5 = -3
-// debugger:print arg2
-// check:$6 = -4
-// debugger:continue
-
-// OWNED BY REF
-// debugger:finish
-// debugger:print *self
-// check:$7 = {x = 200}
-// debugger:print arg1
-// check:$8 = -5
-// debugger:print arg2
-// check:$9 = -6
-// debugger:continue
-
-// OWNED BY VAL
-// debugger:finish
-// debugger:print self
-// check:$10 = {x = 200}
-// debugger:print arg1
-// check:$11 = -7
-// debugger:print arg2
-// check:$12 = -8
-// debugger:continue
-
-// OWNED MOVED
-// debugger:finish
-// debugger:print *self
-// check:$13 = {x = 200}
-// debugger:print arg1
-// check:$14 = -9
-// debugger:print arg2
-// check:$15 = -10
-// 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;
-}
-
-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 main() {
-    let stack = Struct { x: 100 };
-    let _ = stack.self_by_ref(-1, -2);
-    let _ = stack.self_by_val(-3, -4);
-
-    let owned = box Struct { x: 200 };
-    let _ = owned.self_by_ref(-5, -6);
-    let _ = owned.self_by_val(-7, -8);
-    let _ = owned.self_owned(-9, -10);
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/method-on-tuple-struct.rs b/src/test/debug-info/method-on-tuple-struct.rs
deleted file mode 100644 (file)
index 184bee9..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak 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
-// debugger:print self
-// check:$4 = {100, -100.5}
-// debugger:print arg1
-// check:$5 = -3
-// debugger:print arg2
-// check:$6 = -4
-// debugger:continue
-
-// OWNED BY REF
-// debugger:finish
-// debugger:print *self
-// check:$7 = {200, -200.5}
-// debugger:print arg1
-// check:$8 = -5
-// debugger:print arg2
-// check:$9 = -6
-// debugger:continue
-
-// OWNED BY VAL
-// debugger:finish
-// debugger:print self
-// check:$10 = {200, -200.5}
-// debugger:print arg1
-// check:$11 = -7
-// debugger:print arg2
-// check:$12 = -8
-// debugger:continue
-
-// OWNED MOVED
-// debugger:finish
-// debugger:print *self
-// check:$13 = {200, -200.5}
-// debugger:print arg1
-// check:$14 = -9
-// debugger:print arg2
-// check:$15 = -10
-// debugger:continue
-
-struct TupleStruct(int, f64);
-
-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 main() {
-    let stack = TupleStruct(100, -100.5);
-    let _ = stack.self_by_ref(-1, -2);
-    let _ = stack.self_by_val(-3, -4);
-
-    let owned = box TupleStruct(200, -200.5);
-    let _ = owned.self_by_ref(-5, -6);
-    let _ = owned.self_by_val(-7, -8);
-    let _ = owned.self_owned(-9, -10);
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/multiple-functions-equal-var-names.rs b/src/test/debug-info/multiple-functions-equal-var-names.rs
deleted file mode 100644 (file)
index 524974a..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print abc
-// check:$1 = 10101
-// debugger:continue
-
-// debugger:finish
-// debugger:print abc
-// check:$2 = 20202
-// debugger:continue
-
-// debugger:finish
-// debugger:print abc
-// check:$3 = 30303
-
-#![allow(unused_variable)]
-
-fn function_one() {
-    let abc = 10101;
-    zzz();
-}
-
-fn function_two() {
-    let abc = 20202;
-    zzz();
-}
-
-
-fn function_three() {
-    let abc = 30303;
-    zzz();
-}
-
-
-fn main() {
-    function_one();
-    function_two();
-    function_three();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/multiple-functions.rs b/src/test/debug-info/multiple-functions.rs
deleted file mode 100644 (file)
index c93fc8b..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print a
-// check:$1 = 10101
-// debugger:continue
-
-// debugger:finish
-// debugger:print b
-// check:$2 = 20202
-// debugger:continue
-
-// debugger:finish
-// debugger:print c
-// check:$3 = 30303
-
-#![allow(unused_variable)]
-
-fn function_one() {
-    let a = 10101;
-    zzz();
-}
-
-fn function_two() {
-    let b = 20202;
-    zzz();
-}
-
-
-fn function_three() {
-    let c = 30303;
-    zzz();
-}
-
-
-fn main() {
-    function_one();
-    function_two();
-    function_three();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/name-shadowing-and-scope-nesting.rs b/src/test/debug-info/name-shadowing-and-scope-nesting.rs
deleted file mode 100644 (file)
index 97849bc..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-
-// debugger:finish
-// debugger:print x
-// check:$1 = false
-// debugger:print y
-// check:$2 = true
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$3 = 10
-// debugger:print y
-// check:$4 = true
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$5 = 10.5
-// debugger:print y
-// check:$6 = 20
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$7 = true
-// debugger:print y
-// check:$8 = 2220
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$9 = 203203.5
-// debugger:print y
-// check:$10 = 2220
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$11 = 10.5
-// debugger:print y
-// check:$12 = 20
-// debugger:continue
-
-fn main() {
-    let x = false;
-    let y = true;
-
-    zzz();
-    sentinel();
-
-    let x = 10;
-
-    zzz();
-    sentinel();
-
-    let x = 10.5;
-    let y = 20;
-
-    zzz();
-    sentinel();
-
-    {
-        let x = true;
-        let y = 2220;
-
-        zzz();
-        sentinel();
-
-        let x = 203203.5;
-
-        zzz();
-        sentinel();
-    }
-
-    zzz();
-    sentinel();
-}
-
-fn zzz() {()}
-fn sentinel() {()}
diff --git a/src/test/debug-info/nil-enum.rs b/src/test/debug-info/nil-enum.rs
deleted file mode 100644 (file)
index 31bfade..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print first
-// check:$1 = {<No data fields>}
-
-// debugger:print second
-// check:$2 = {<No data fields>}
-
-#![allow(unused_variable)]
-
-enum ANilEnum {}
-enum AnotherNilEnum {}
-
-// I (mw) am not sure this test case makes much sense...
-// Also, it relies on some implementation details:
-// 1. That empty enums as well as '()' are represented as empty structs
-// 2. That gdb prints the string "{<No data fields>}" for empty structs (which may change some time)
-fn main() {
-    unsafe {
-        let first: ANilEnum = std::cast::transmute(());
-        let second: AnotherNilEnum = std::cast::transmute(());
-
-        zzz();
-    }
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/option-like-enum.rs b/src/test/debug-info/option-like-enum.rs
deleted file mode 100644 (file)
index b025b3a..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print some
-// check:$1 = {0x12345678}
-
-// debugger:print none
-// check:$2 = {0x0}
-
-// debugger:print full
-// check:$3 = {454545, 0x87654321, 9988}
-
-// debugger:print empty->discr
-// check:$4 = (int *) 0x0
-
-// debugger:print droid
-// check:$5 = {id = 675675, range = 10000001, internals = 0x43218765}
-
-// debugger:print void_droid->internals
-// check:$6 = (int *) 0x0
-
-// debugger:continue
-
-#![feature(struct_variant)]
-
-// 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<'a> {
-    Full(u32, &'a int, i16),
-    Empty
-}
-
-struct MoreFieldsRepr<'a> {
-    a: u32,
-    discr: &'a int,
-    b: i16
-}
-
-enum NamedFields<'a> {
-    Droid { id: i32, range: i64, internals: &'a int },
-    Void
-}
-
-struct NamedFieldsRepr<'a> {
-    id: i32,
-    range: i64,
-    internals: &'a int
-}
-
-fn main() {
-
-    let some: Option<&u32> = Some(unsafe { std::cast::transmute(0x12345678) });
-    let none: Option<&u32> = None;
-
-    let full = Full(454545, unsafe { std::cast::transmute(0x87654321) }, 9988);
-
-    let int_val = 0;
-    let empty: &MoreFieldsRepr = unsafe { std::cast::transmute(&Empty) };
-
-    let droid = Droid {
-        id: 675675,
-        range: 10000001,
-        internals: unsafe { std::cast::transmute(0x43218765) }
-    };
-
-    let void_droid: &NamedFieldsRepr = unsafe { std::cast::transmute(&Void) };
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/packed-struct-with-destructor.rs b/src/test/debug-info/packed-struct-with-destructor.rs
deleted file mode 100644 (file)
index 2421692..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:set print pretty off
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print packed
-// check:$1 = {x = 123, y = 234, z = 345}
-
-// debugger:print packedInPacked
-// check:$2 = {a = 1111, b = {x = 2222, y = 3333, z = 4444}, c = 5555, d = {x = 6666, y = 7777, z = 8888}}
-
-// debugger:print packedInUnpacked
-// check:$3 = {a = -1111, b = {x = -2222, y = -3333, z = -4444}, c = -5555, d = {x = -6666, y = -7777, z = -8888}}
-
-// debugger:print unpackedInPacked
-// check:$4 = {a = 987, b = {x = 876, y = 765, z = 654}, c = {x = 543, y = 432, z = 321}, d = 210}
-
-
-// debugger:print packedInPackedWithDrop
-// check:$5 = {a = 11, b = {x = 22, y = 33, z = 44}, c = 55, d = {x = 66, y = 77, z = 88}}
-
-// debugger:print packedInUnpackedWithDrop
-// check:$6 = {a = -11, b = {x = -22, y = -33, z = -44}, c = -55, d = {x = -66, y = -77, z = -88}}
-
-// debugger:print unpackedInPackedWithDrop
-// check:$7 = {a = 98, b = {x = 87, y = 76, z = 65}, c = {x = 54, y = 43, z = 32}, d = 21}
-
-// 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,
-    y: i32,
-    z: i64
-}
-
-impl Drop for Packed {
-    fn drop(&mut self) {}
-}
-
-#[packed]
-struct PackedInPacked {
-    a: i32,
-    b: Packed,
-    c: i64,
-    d: Packed
-}
-
-struct PackedInUnpacked {
-    a: i32,
-    b: Packed,
-    c: i64,
-    d: Packed
-}
-
-struct Unpacked {
-    x: i64,
-    y: i32,
-    z: i16
-}
-
-impl Drop for Unpacked {
-    fn drop(&mut self) {}
-}
-
-#[packed]
-struct UnpackedInPacked {
-    a: i16,
-    b: Unpacked,
-    c: Unpacked,
-    d: i64
-}
-
-#[packed]
-struct PackedInPackedWithDrop {
-    a: i32,
-    b: Packed,
-    c: i64,
-    d: Packed
-}
-
-impl Drop for PackedInPackedWithDrop {
-    fn drop(&mut self) {}
-}
-
-struct PackedInUnpackedWithDrop {
-    a: i32,
-    b: Packed,
-    c: i64,
-    d: Packed
-}
-
-impl Drop for PackedInUnpackedWithDrop {
-    fn drop(&mut self) {}
-}
-
-#[packed]
-struct UnpackedInPackedWithDrop {
-    a: i16,
-    b: Unpacked,
-    c: Unpacked,
-    d: i64
-}
-
-impl Drop for UnpackedInPackedWithDrop {
-    fn drop(&mut self) {}
-}
-
-struct DeeplyNested {
-    a: PackedInPacked,
-    b: UnpackedInPackedWithDrop,
-    c: PackedInUnpacked,
-    d: PackedInUnpackedWithDrop,
-    e: UnpackedInPacked,
-    f: PackedInPackedWithDrop
-}
-
-fn main() {
-    let packed = Packed { x: 123, y: 234, z: 345 };
-
-    let packedInPacked = PackedInPacked {
-        a: 1111,
-        b: Packed { x: 2222, y: 3333, z: 4444 },
-        c: 5555,
-        d: Packed { x: 6666, y: 7777, z: 8888 }
-    };
-
-    let packedInUnpacked = PackedInUnpacked {
-        a: -1111,
-        b: Packed { x: -2222, y: -3333, z: -4444 },
-        c: -5555,
-        d: Packed { x: -6666, y: -7777, z: -8888 }
-    };
-
-    let unpackedInPacked = UnpackedInPacked {
-        a: 987,
-        b: Unpacked { x: 876, y: 765, z: 654 },
-        c: Unpacked { x: 543, y: 432, z: 321 },
-        d: 210
-    };
-
-    let packedInPackedWithDrop = PackedInPackedWithDrop {
-        a: 11,
-        b: Packed { x: 22, y: 33, z: 44 },
-        c: 55,
-        d: Packed { x: 66, y: 77, z: 88 }
-    };
-
-    let packedInUnpackedWithDrop = PackedInUnpackedWithDrop {
-        a: -11,
-        b: Packed { x: -22, y: -33, z: -44 },
-        c: -55,
-        d: Packed { x: -66, y: -77, z: -88 }
-    };
-
-    let unpackedInPackedWithDrop = UnpackedInPackedWithDrop {
-        a: 98,
-        b: Unpacked { x: 87, y: 76, z: 65 },
-        c: Unpacked { x: 54, y: 43, z: 32 },
-        d: 21
-    };
-
-    let deeplyNested = DeeplyNested {
-        a: PackedInPacked {
-            a: 1,
-            b: Packed { x: 2, y: 3, z: 4 },
-            c: 5,
-            d: Packed { x: 6, y: 7, z: 8 }
-        },
-        b: UnpackedInPackedWithDrop {
-            a: 9,
-            b: Unpacked { x: 10, y: 11, z: 12 },
-            c: Unpacked { x: 13, y: 14, z: 15 },
-            d: 16
-        },
-        c: PackedInUnpacked {
-            a: 17,
-            b: Packed { x: 18, y: 19, z: 20 },
-            c: 21,
-            d: Packed { x: 22, y: 23, z: 24 }
-        },
-        d: PackedInUnpackedWithDrop {
-            a: 25,
-            b: Packed { x: 26, y: 27, z: 28 },
-            c: 29,
-            d: Packed { x: 30, y: 31, z: 32 }
-        },
-        e: UnpackedInPacked {
-            a: 33,
-            b: Unpacked { x: 34, y: 35, z: 36 },
-            c: Unpacked { x: 37, y: 38, z: 39 },
-            d: 40
-        },
-        f: PackedInPackedWithDrop {
-            a: 41,
-            b: Packed { x: 42, y: 43, z: 44 },
-            c: 45,
-            d: Packed { x: 46, y: 47, z: 48 }
-        }
-    };
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/packed-struct.rs b/src/test/debug-info/packed-struct.rs
deleted file mode 100644 (file)
index 2b7df00..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:set print pretty off
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print packed
-// check:$1 = {x = 123, y = 234, z = 345}
-
-// debugger:print packedInPacked
-// check:$2 = {a = 1111, b = {x = 2222, y = 3333, z = 4444}, c = 5555, d = {x = 6666, y = 7777, z = 8888}}
-
-// debugger:print packedInUnpacked
-// check:$3 = {a = -1111, b = {x = -2222, y = -3333, z = -4444}, c = -5555, d = {x = -6666, y = -7777, z = -8888}}
-
-// debugger:print unpackedInPacked
-// check:$4 = {a = 987, b = {x = 876, y = 765, z = 654, w = 543}, c = {x = 432, y = 321, z = 210, w = 109}, d = -98}
-
-// debugger:print sizeof(packed)
-// check:$5 = 14
-
-// debugger:print sizeof(packedInPacked)
-// check:$6 = 40
-
-#![allow(unused_variable)]
-
-#[packed]
-struct Packed {
-    x: i16,
-    y: i32,
-    z: i64
-}
-
-#[packed]
-struct PackedInPacked {
-    a: i32,
-    b: Packed,
-    c: i64,
-    d: Packed
-}
-
-// layout (64 bit): aaaa bbbb bbbb bbbb bb.. .... cccc cccc dddd dddd dddd dd..
-struct PackedInUnpacked {
-    a: i32,
-    b: Packed,
-    c: i64,
-    d: Packed
-}
-
-// layout (64 bit): xx.. yyyy zz.. .... wwww wwww
-struct Unpacked {
-    x: i16,
-    y: i32,
-    z: i16,
-    w: i64
-}
-
-// layout (64 bit): aabb bbbb bbbb bbbb bbbb bbbb bbcc cccc cccc cccc cccc cccc ccdd dddd dd
-#[packed]
-struct UnpackedInPacked {
-    a: i16,
-    b: Unpacked,
-    c: Unpacked,
-    d: i64
-}
-
-fn main() {
-    let packed = Packed { x: 123, y: 234, z: 345 };
-
-    let packedInPacked = PackedInPacked {
-        a: 1111,
-        b: Packed { x: 2222, y: 3333, z: 4444 },
-        c: 5555,
-        d: Packed { x: 6666, y: 7777, z: 8888 }
-    };
-
-    let packedInUnpacked = PackedInUnpacked {
-        a: -1111,
-        b: Packed { x: -2222, y: -3333, z: -4444 },
-        c: -5555,
-        d: Packed { x: -6666, y: -7777, z: -8888 }
-    };
-
-    let unpackedInPacked = UnpackedInPacked {
-        a: 987,
-        b: Unpacked { x: 876, y: 765, z: 654, w: 543 },
-        c: Unpacked { x: 432, y: 321, z: 210, w: 109 },
-        d: -98
-    };
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/recursive-enum.rs b/src/test/debug-info/recursive-enum.rs
deleted file mode 100644 (file)
index aea8ab1..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:run
-
-// Test whether compiling a recursive enum definition crashes debug info generation. The test case
-// is taken from issue #11083.
-
-#![allow(unused_variable)]
-
-pub struct Window<'a> {
-    callbacks: WindowCallbacks<'a>
-}
-
-struct WindowCallbacks<'a> {
-    pos_callback: Option<WindowPosCallback<'a>>,
-}
-
-pub type WindowPosCallback<'a> = |&Window, i32, i32|: 'a;
-
-fn main() {
-    let x = WindowCallbacks { pos_callback: None };
-}
diff --git a/src/test/debug-info/recursive-struct.rs b/src/test/debug-info/recursive-struct.rs
deleted file mode 100644 (file)
index a46a1c2..0000000
+++ /dev/null
@@ -1,320 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-#![feature(managed_boxes)]
-
-// compile-flags:-g
-// debugger:set print pretty off
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print stack_unique.value
-// check:$1 = 0
-// debugger:print stack_unique.next.val->value
-// check:$2 = 1
-
-// debugger:print unique_unique->value
-// check:$3 = 2
-// debugger:print unique_unique->next.val->value
-// check:$4 = 3
-
-// debugger:print box_unique->val.value
-// check:$5 = 4
-// debugger:print box_unique->val.next.val->value
-// check:$6 = 5
-
-// debugger:print vec_unique[0].value
-// check:$7 = 6.5
-// debugger:print vec_unique[0].next.val->value
-// check:$8 = 7.5
-
-// debugger:print borrowed_unique->value
-// check:$9 = 8.5
-// debugger:print borrowed_unique->next.val->value
-// check:$10 = 9.5
-
-// MANAGED
-// debugger:print stack_managed.value
-// check:$11 = 10
-// debugger:print stack_managed.next.val->val.value
-// check:$12 = 11
-
-// debugger:print unique_managed->value
-// check:$13 = 12
-// debugger:print unique_managed->next.val->val.value
-// check:$14 = 13
-
-// debugger:print box_managed->val.value
-// check:$15 = 14
-// debugger:print box_managed->val.next.val->val.value
-// check:$16 = 15
-
-// debugger:print vec_managed[0].value
-// check:$17 = 16.5
-// debugger:print vec_managed[0].next.val->val.value
-// check:$18 = 17.5
-
-// debugger:print borrowed_managed->value
-// check:$19 = 18.5
-// debugger:print borrowed_managed->next.val->val.value
-// check:$20 = 19.5
-
-// LONG CYCLE
-// debugger:print long_cycle1.value
-// check:$21 = 20
-// debugger:print long_cycle1.next->value
-// check:$22 = 21
-// debugger:print long_cycle1.next->next->value
-// check:$23 = 22
-// debugger:print long_cycle1.next->next->next->value
-// check:$24 = 23
-
-// debugger:print long_cycle2.value
-// check:$25 = 24
-// debugger:print long_cycle2.next->value
-// check:$26 = 25
-// debugger:print long_cycle2.next->next->value
-// check:$27 = 26
-
-// debugger:print long_cycle3.value
-// check:$28 = 27
-// debugger:print long_cycle3.next->value
-// check:$29 = 28
-
-// debugger:print long_cycle4.value
-// check:$30 = 29.5
-
-// debugger:print (*****long_cycle_w_anonymous_types).value
-// check:$31 = 30
-
-// debugger:print (*****((*****long_cycle_w_anonymous_types).next.val)).value
-// check:$32 = 31
-
-// debugger:continue
-
-#![allow(unused_variable)]
-#![feature(struct_variant)]
-
-
-enum Opt<T> {
-    Empty,
-    Val { val: T }
-}
-
-struct UniqueNode<T> {
-    next: Opt<Box<UniqueNode<T>>>,
-    value: T
-}
-
-struct ManagedNode<T> {
-    next: Opt<@ManagedNode<T>>,
-    value: T
-}
-
-struct LongCycle1<T> {
-    next: Box<LongCycle2<T>>,
-    value: T,
-}
-
-struct LongCycle2<T> {
-    next: Box<LongCycle3<T>>,
-    value: T,
-}
-
-struct LongCycle3<T> {
-    next: Box<LongCycle4<T>>,
-    value: T,
-}
-
-struct LongCycle4<T> {
-    next: Option<Box<LongCycle1<T>>>,
-    value: T,
-}
-
-struct LongCycleWithAnonymousTypes {
-    next: Opt<Box<Box<Box<Box<Box<LongCycleWithAnonymousTypes>>>>>>,
-    value: uint,
-}
-
-// This test case makes sure that recursive structs are properly described. The Node structs are
-// generic so that we can have a new type (that newly needs to be described) for the different
-// cases. The potential problem with recursive types is that the DI generation algorithm gets
-// trapped in an endless loop. To make sure, we actually test this in the different cases, we have
-// to operate on a new type each time, otherwise we would just hit the DI cache for all but the
-// first case.
-
-// The different cases below (stack_*, unique_*, box_*, etc) are set up so that the type description
-// algorithm will enter the type reference cycle that is created by a recursive definition from a
-// different context each time.
-
-// The "long cycle" cases are constructed to span a longer, indirect recursion cycle between types.
-// The different locals will cause the DI algorithm to enter the type reference cycle at different
-// points.
-
-fn main() {
-    let stack_unique: UniqueNode<u16> = UniqueNode {
-        next: Val {
-            val: box UniqueNode {
-                next: Empty,
-                value: 1_u16,
-            }
-        },
-        value: 0_u16,
-    };
-
-    let unique_unique: Box<UniqueNode<u32>> = box UniqueNode {
-        next: Val {
-            val: box UniqueNode {
-                next: Empty,
-                value: 3,
-            }
-        },
-        value: 2,
-    };
-
-    let box_unique: @UniqueNode<u64> = @UniqueNode {
-        next: Val {
-            val: box UniqueNode {
-                next: Empty,
-                value: 5,
-            }
-        },
-        value: 4,
-    };
-
-    let vec_unique: [UniqueNode<f32>, ..1] = [UniqueNode {
-        next: Val {
-            val: box UniqueNode {
-                next: Empty,
-                value: 7.5,
-            }
-        },
-        value: 6.5,
-    }];
-
-    let borrowed_unique: &UniqueNode<f64> = &UniqueNode {
-        next: Val {
-            val: box UniqueNode {
-                next: Empty,
-                value: 9.5,
-            }
-        },
-        value: 8.5,
-    };
-
-    let stack_managed: ManagedNode<u16> = ManagedNode {
-        next: Val {
-            val: @ManagedNode {
-                next: Empty,
-                value: 11,
-            }
-        },
-        value: 10,
-    };
-
-    let unique_managed: Box<ManagedNode<u32>> = box ManagedNode {
-        next: Val {
-            val: @ManagedNode {
-                next: Empty,
-                value: 13,
-            }
-        },
-        value: 12,
-    };
-
-    let box_managed: @ManagedNode<u64> = @ManagedNode {
-        next: Val {
-            val: @ManagedNode {
-                next: Empty,
-                value: 15,
-            }
-        },
-        value: 14,
-    };
-
-    let vec_managed: [ManagedNode<f32>, ..1] = [ManagedNode {
-        next: Val {
-            val: @ManagedNode {
-                next: Empty,
-                value: 17.5,
-            }
-        },
-        value: 16.5,
-    }];
-
-    let borrowed_managed: &ManagedNode<f64> = &ManagedNode {
-        next: Val {
-            val: @ManagedNode {
-                next: Empty,
-                value: 19.5,
-            }
-        },
-        value: 18.5,
-    };
-
-    // LONG CYCLE
-    let long_cycle1: LongCycle1<u16> = LongCycle1 {
-        next: box LongCycle2 {
-            next: box LongCycle3 {
-                next: box LongCycle4 {
-                    next: None,
-                    value: 23,
-                },
-                value: 22,
-            },
-            value: 21
-        },
-        value: 20
-    };
-
-    let long_cycle2: LongCycle2<u32> = LongCycle2 {
-        next: box LongCycle3 {
-            next: box LongCycle4 {
-                next: None,
-                value: 26,
-            },
-            value: 25,
-        },
-        value: 24
-    };
-
-    let long_cycle3: LongCycle3<u64> = LongCycle3 {
-        next: box LongCycle4 {
-            next: None,
-            value: 28,
-        },
-        value: 27,
-    };
-
-    let long_cycle4: LongCycle4<f32> = LongCycle4 {
-        next: None,
-        value: 29.5,
-    };
-
-    // It's important that LongCycleWithAnonymousTypes is encountered only at the end of the
-    // `box` chain.
-    let long_cycle_w_anonymous_types = box box box box box LongCycleWithAnonymousTypes {
-        next: Val {
-            val: box box box box box LongCycleWithAnonymousTypes {
-                next: Empty,
-                value: 31,
-            }
-        },
-        value: 30
-    };
-
-    zzz();
-}
-
-fn zzz() {()}
-
diff --git a/src/test/debug-info/self-in-default-method.rs b/src/test/debug-info/self-in-default-method.rs
deleted file mode 100644 (file)
index 194cfc7..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak 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
-// debugger:print self
-// check:$4 = {x = 100}
-// debugger:print arg1
-// check:$5 = -3
-// debugger:print arg2
-// check:$6 = -4
-// debugger:continue
-
-// OWNED BY REF
-// debugger:finish
-// debugger:print *self
-// check:$7 = {x = 200}
-// debugger:print arg1
-// check:$8 = -5
-// debugger:print arg2
-// check:$9 = -6
-// debugger:continue
-
-// OWNED BY VAL
-// debugger:finish
-// debugger:print self
-// check:$10 = {x = 200}
-// debugger:print arg1
-// check:$11 = -7
-// debugger:print arg2
-// check:$12 = -8
-// debugger:continue
-
-// OWNED MOVED
-// debugger:finish
-// debugger:print *self
-// check:$13 = {x = 200}
-// debugger:print arg1
-// check:$14 = -9
-// debugger:print arg2
-// check:$15 = -10
-// 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
-    }
-}
-
-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 = box Struct { x: 200 };
-    let _ = owned.self_by_ref(-5, -6);
-    let _ = owned.self_by_val(-7, -8);
-    let _ = owned.self_owned(-9, -10);
-}
-
-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
deleted file mode 100644 (file)
index 9e7504b..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak 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
-// debugger:print self
-// check:$4 = {x = 987}
-// debugger:print arg1
-// check:$5 = -3
-// debugger:print arg2
-// check:$6 = -4
-// debugger:continue
-
-// OWNED BY REF
-// debugger:finish
-// debugger:print *self
-// check:$7 = {x = 879}
-// debugger:print arg1
-// check:$8 = -5
-// debugger:print arg2
-// check:$9 = -6
-// debugger:continue
-
-// OWNED BY VAL
-// debugger:finish
-// debugger:print self
-// check:$10 = {x = 879}
-// debugger:print arg1
-// check:$11 = -7
-// debugger:print arg2
-// check:$12 = -8
-// debugger:continue
-
-// OWNED MOVED
-// debugger:finish
-// debugger:print *self
-// check:$13 = {x = 879}
-// debugger:print arg1
-// check:$14 = -9
-// debugger:print arg2
-// check:$15 = -10.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
-    }
-}
-
-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 = box 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);
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/shadowed-argument.rs b/src/test/debug-info/shadowed-argument.rs
deleted file mode 100644 (file)
index cd3934e..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-
-// debugger:finish
-// debugger:print x
-// check:$1 = false
-// debugger:print y
-// check:$2 = true
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$3 = 10
-// debugger:print y
-// check:$4 = true
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$5 = 10.5
-// debugger:print y
-// check:$6 = 20
-// debugger:continue
-
-fn a_function(x: bool, y: bool) {
-    zzz();
-    sentinel();
-
-    let x = 10;
-
-    zzz();
-    sentinel();
-
-    let x = 10.5;
-    let y = 20;
-
-    zzz();
-    sentinel();
-}
-
-fn main() {
-    a_function(false, true);
-}
-
-fn zzz() {()}
-fn sentinel() {()}
diff --git a/src/test/debug-info/shadowed-variable.rs b/src/test/debug-info/shadowed-variable.rs
deleted file mode 100644 (file)
index 99edb70..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-
-// debugger:finish
-// debugger:print x
-// check:$1 = false
-// debugger:print y
-// check:$2 = true
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$3 = 10
-// debugger:print y
-// check:$4 = true
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$5 = 10.5
-// debugger:print y
-// check:$6 = 20
-// debugger:continue
-
-fn main() {
-    let x = false;
-    let y = true;
-
-    zzz();
-    sentinel();
-
-    let x = 10;
-
-    zzz();
-    sentinel();
-
-    let x = 10.5;
-    let y = 20;
-
-    zzz();
-    sentinel();
-}
-
-fn zzz() {()}
-fn sentinel() {()}
diff --git a/src/test/debug-info/simd.rs b/src/test/debug-info/simd.rs
deleted file mode 100644 (file)
index 9839727..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-
-// debugger:finish
-// debugger:print/d i8x16
-// check:$1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
-// debugger:print/d i16x8
-// check:$2 = {16, 17, 18, 19, 20, 21, 22, 23}
-// debugger:print/d i32x4
-// check:$3 = {24, 25, 26, 27}
-// debugger:print/d i64x2
-// check:$4 = {28, 29}
-
-// debugger:print/d u8x16
-// check:$5 = {30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45}
-// debugger:print/d u16x8
-// check:$6 = {46, 47, 48, 49, 50, 51, 52, 53}
-// debugger:print/d u32x4
-// check:$7 = {54, 55, 56, 57}
-// debugger:print/d u64x2
-// check:$8 = {58, 59}
-
-// debugger:print f32x4
-// check:$9 = {60.5, 61.5, 62.5, 63.5}
-// debugger:print f64x2
-// check:$10 = {64.5, 65.5}
-
-// debugger:continue
-
-#![allow(experimental)]
-#![allow(unused_variable)]
-
-use std::unstable::simd::{i8x16, i16x8,i32x4,i64x2,u8x16,u16x8,u32x4,u64x2,f32x4,f64x2};
-
-fn main() {
-
-    let i8x16 = i8x16(0i8, 1i8, 2i8, 3i8, 4i8, 5i8, 6i8, 7i8,
-                      8i8, 9i8, 10i8, 11i8, 12i8, 13i8, 14i8, 15i8);
-
-    let i16x8 = i16x8(16i16, 17i16, 18i16, 19i16, 20i16, 21i16, 22i16, 23i16);
-    let i32x4 = i32x4(24i32, 25i32, 26i32, 27i32);
-    let i64x2 = i64x2(28i64, 29i64);
-
-    let u8x16 = u8x16(30u8, 31u8, 32u8, 33u8, 34u8, 35u8, 36u8, 37u8,
-                      38u8, 39u8, 40u8, 41u8, 42u8, 43u8, 44u8, 45u8);
-    let u16x8 = u16x8(46u16, 47u16, 48u16, 49u16, 50u16, 51u16, 52u16, 53u16);
-    let u32x4 = u32x4(54u32, 55u32, 56u32, 57u32);
-    let u64x2 = u64x2(58u64, 59u64);
-
-    let f32x4 = f32x4(60.5f32, 61.5f32, 62.5f32, 63.5f32);
-    let f64x2 = f64x2(64.5f64, 65.5f64);
-
-    zzz();
-}
-
-#[inline(never)]
-fn zzz() { () }
diff --git a/src/test/debug-info/simple-lexical-scope.rs b/src/test/debug-info/simple-lexical-scope.rs
deleted file mode 100644 (file)
index 21ce21e..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-
-// debugger:finish
-// debugger:print x
-// check:$1 = false
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$2 = false
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$3 = 10
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$4 = 10
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$5 = 10.5
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$6 = 10
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$7 = false
-// debugger:continue
-
-
-fn main() {
-    let x = false;
-
-    zzz();
-    sentinel();
-
-    {
-        zzz();
-        sentinel();
-
-        let x = 10;
-
-        zzz();
-        sentinel();
-
-        {
-            zzz();
-            sentinel();
-
-            let x = 10.5;
-
-            zzz();
-            sentinel();
-        }
-
-        zzz();
-        sentinel();
-    }
-
-    zzz();
-    sentinel();
-}
-
-fn zzz() {()}
-fn sentinel() {()}
diff --git a/src/test/debug-info/simple-struct.rs b/src/test/debug-info/simple-struct.rs
deleted file mode 100644 (file)
index 2ac3b48..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-win32: FIXME #13256
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:set print pretty off
-// debugger:rbreak zzz
-
-// debugger:print 'simple-struct::NO_PADDING_16'
-// check:$1 = {x = 1000, y = -1001}
-
-// debugger:print 'simple-struct::NO_PADDING_32'
-// check:$2 = {x = 1, y = 2, z = 3}
-
-// debugger:print 'simple-struct::NO_PADDING_64'
-// check:$3 = {x = 4, y = 5, z = 6}
-
-// debugger:print 'simple-struct::NO_PADDING_163264'
-// check:$4 = {a = 7, b = 8, c = 9, d = 10}
-
-// debugger:print 'simple-struct::INTERNAL_PADDING'
-// check:$5 = {x = 11, y = 12}
-
-// debugger:print 'simple-struct::PADDING_AT_END'
-// check:$6 = {x = 13, y = 14}
-
-// debugger:run
-// debugger:finish
-
-// debugger:print no_padding16
-// check:$7 = {x = 10000, y = -10001}
-
-// debugger:print no_padding32
-// check:$8 = {x = -10002, y = -10003.5, z = 10004}
-
-// debugger:print no_padding64
-// check:$9 = {x = -10005.5, y = 10006, z = 10007}
-
-// debugger:print no_padding163264
-// check:$10 = {a = -10008, b = 10009, c = 10010, d = 10011}
-
-// debugger:print internal_padding
-// check:$11 = {x = 10012, y = -10013}
-
-// debugger:print padding_at_end
-// check:$12 = {x = -10014, y = 10015}
-
-// debugger:print 'simple-struct::NO_PADDING_16'
-// check:$13 = {x = 100, y = -101}
-
-// debugger:print 'simple-struct::NO_PADDING_32'
-// check:$14 = {x = -15, y = -16, z = 17}
-
-// debugger:print 'simple-struct::NO_PADDING_64'
-// check:$15 = {x = -18, y = 19, z = 20}
-
-// debugger:print 'simple-struct::NO_PADDING_163264'
-// check:$16 = {a = -21, b = 22, c = 23, d = 24}
-
-// debugger:print 'simple-struct::INTERNAL_PADDING'
-// check:$17 = {x = 25, y = -26}
-
-// debugger:print 'simple-struct::PADDING_AT_END'
-// check:$18 = {x = -27, y = 28}
-
-// debugger:print inheriting
-// check:$19 = {a = 10019, b = -10020, x = -10016, y = -10017.5, z = 10018}
-
-
-#![feature(struct_inherit)];
-#![allow(unused_variable)];
-#![allow(dead_code)];
-
-struct NoPadding16 {
-    x: u16,
-    y: i16
-}
-
-virtual struct NoPadding32 {
-    x: i32,
-    y: f32,
-    z: u32
-}
-
-struct NoPadding64 {
-    x: f64,
-    y: i64,
-    z: u64
-}
-
-struct NoPadding163264 {
-    a: i16,
-    b: u16,
-    c: i32,
-    d: u64
-}
-
-struct InternalPadding {
-    x: u16,
-    y: i64
-}
-
-struct PaddingAtEnd {
-    x: i64,
-    y: u16
-}
-
-static mut NO_PADDING_16: NoPadding16 = NoPadding16 {
-    x: 1000,
-    y: -1001
-};
-
-static mut NO_PADDING_32: NoPadding32 = NoPadding32 {
-    x: 1,
-    y: 2.0,
-    z: 3
-};
-
-static mut NO_PADDING_64: NoPadding64 = NoPadding64 {
-    x: 4.0,
-    y: 5,
-    z: 6
-};
-
-static mut NO_PADDING_163264: NoPadding163264 = NoPadding163264 {
-    a: 7,
-    b: 8,
-    c: 9,
-    d: 10
-};
-
-static mut INTERNAL_PADDING: InternalPadding = InternalPadding {
-    x: 11,
-    y: 12
-};
-
-static mut PADDING_AT_END: PaddingAtEnd = PaddingAtEnd {
-    x: 13,
-    y: 14
-};
-
-struct Inheriting : NoPadding32 {
-    a: u16,
-    b: i16
-}
-
-fn main() {
-    let no_padding16 = NoPadding16 { x: 10000, y: -10001 };
-    let no_padding32 = NoPadding32 { x: -10002, y: -10003.5, z: 10004 };
-    let no_padding64 = NoPadding64 { x: -10005.5, y: 10006, z: 10007 };
-    let no_padding163264 = NoPadding163264 { a: -10008, b: 10009, c: 10010, d: 10011 };
-
-    let internal_padding = InternalPadding { x: 10012, y: -10013 };
-    let padding_at_end = PaddingAtEnd { x: -10014, y: 10015 };
-
-    let inheriting = Inheriting { a: 10019, b: -10020, x: -10016, y: -10017.5, z: 10018 };
-
-    unsafe {
-        NO_PADDING_16.x = 100;
-        NO_PADDING_16.y = -101;
-
-        NO_PADDING_32.x = -15;
-        NO_PADDING_32.y = -16.0;
-        NO_PADDING_32.z = 17;
-
-        NO_PADDING_64.x = -18.0;
-        NO_PADDING_64.y = 19;
-        NO_PADDING_64.z = 20;
-
-        NO_PADDING_163264.a = -21;
-        NO_PADDING_163264.b = 22;
-        NO_PADDING_163264.c = 23;
-        NO_PADDING_163264.d = 24;
-
-        INTERNAL_PADDING.x = 25;
-        INTERNAL_PADDING.y = -26;
-
-        PADDING_AT_END.x = -27;
-        PADDING_AT_END.y = 28;
-    }
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/simple-tuple.rs b/src/test/debug-info/simple-tuple.rs
deleted file mode 100644 (file)
index 256a34f..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-win32: FIXME #13256
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:set print pretty off
-// debugger:rbreak zzz
-
-// debugger:print/d 'simple-tuple::NO_PADDING_8'
-// check:$1 = {-50, 50}
-// debugger:print 'simple-tuple::NO_PADDING_16'
-// check:$2 = {-1, 2, 3}
-// debugger:print 'simple-tuple::NO_PADDING_32'
-// check:$3 = {4, 5, 6}
-// debugger:print 'simple-tuple::NO_PADDING_64'
-// check:$4 = {7, 8, 9}
-
-// debugger:print 'simple-tuple::INTERNAL_PADDING_1'
-// check:$5 = {10, 11}
-// debugger:print 'simple-tuple::INTERNAL_PADDING_2'
-// check:$6 = {12, 13, 14, 15}
-
-// debugger:print 'simple-tuple::PADDING_AT_END'
-// check:$7 = {16, 17}
-
-// debugger:run
-// debugger:finish
-
-// debugger:print/d noPadding8
-// check:$8 = {-100, 100}
-// debugger:print noPadding16
-// check:$9 = {0, 1, 2}
-// debugger:print noPadding32
-// check:$10 = {3, 4.5, 5}
-// debugger:print noPadding64
-// check:$11 = {6, 7.5, 8}
-
-// debugger:print internalPadding1
-// check:$12 = {9, 10}
-// debugger:print internalPadding2
-// check:$13 = {11, 12, 13, 14}
-
-// debugger:print paddingAtEnd
-// check:$14 = {15, 16}
-
-// debugger:print/d 'simple-tuple::NO_PADDING_8'
-// check:$15 = {-127, 127}
-// debugger:print 'simple-tuple::NO_PADDING_16'
-// check:$16 = {-10, 10, 9}
-// debugger:print 'simple-tuple::NO_PADDING_32'
-// check:$17 = {14, 15, 16}
-// debugger:print 'simple-tuple::NO_PADDING_64'
-// check:$18 = {17, 18, 19}
-
-// debugger:print 'simple-tuple::INTERNAL_PADDING_1'
-// check:$19 = {110, 111}
-// debugger:print 'simple-tuple::INTERNAL_PADDING_2'
-// check:$20 = {112, 113, 114, 115}
-
-// debugger:print 'simple-tuple::PADDING_AT_END'
-// check:$21 = {116, 117}
-
-#![allow(unused_variable)]
-#![allow(dead_code)]
-
-static mut NO_PADDING_8: (i8, u8) = (-50, 50);
-static mut NO_PADDING_16: (i16, i16, u16) = (-1, 2, 3);
-
-static mut NO_PADDING_32: (i32, f32, u32) = (4, 5.0, 6);
-static mut NO_PADDING_64: (i64, f64, u64) = (7, 8.0, 9);
-
-static mut INTERNAL_PADDING_1: (i16, i32) = (10, 11);
-static mut INTERNAL_PADDING_2: (i16, i32, u32, u64) = (12, 13, 14, 15);
-
-static mut PADDING_AT_END: (i32, i16) = (16, 17);
-
-fn main() {
-    let noPadding8: (i8, u8) = (-100, 100);
-    let noPadding16: (i16, i16, u16) = (0, 1, 2);
-    let noPadding32: (i32, f32, u32) = (3, 4.5, 5);
-    let noPadding64: (i64, f64, u64) = (6, 7.5, 8);
-
-    let internalPadding1: (i16, i32) = (9, 10);
-    let internalPadding2: (i16, i32, u32, u64) = (11, 12, 13, 14);
-
-    let paddingAtEnd: (i32, i16) = (15, 16);
-
-    unsafe {
-        NO_PADDING_8 = (-127, 127);
-        NO_PADDING_16 = (-10, 10, 9);
-
-        NO_PADDING_32 = (14, 15.0, 16);
-        NO_PADDING_64 = (17, 18.0, 19);
-
-        INTERNAL_PADDING_1 = (110, 111);
-        INTERNAL_PADDING_2 = (112, 113, 114, 115);
-
-        PADDING_AT_END = (116, 117);
-    }
-
-    zzz();
-}
-
-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
deleted file mode 100644 (file)
index 68bc470..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak 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
-
-#![feature(struct_variant)]
-
-struct Struct {
-    x: int
-}
-
-impl Struct {
-
-    fn static_method(arg1: int, arg2: int) -> int {
-        zzz();
-        arg1 + arg2
-    }
-}
-
-enum Enum {
-    Variant1 { x: int },
-    Variant2,
-    Variant3(f64, int, char),
-}
-
-impl Enum {
-
-    fn static_method(arg1: int, arg2: f64, arg3: uint) -> int {
-        zzz();
-        arg1
-    }
-}
-
-fn main() {
-    Struct::static_method(1, 2);
-    Enum::static_method(-3, 4.5, 5);
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/struct-in-enum.rs b/src/test/debug-info/struct-in-enum.rs
deleted file mode 100644 (file)
index 9b39314..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:set print union on
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print case1
-// check:$1 = {{Case1, 0, {x = 2088533116, y = 2088533116, z = 31868}}, {Case1, 0, 8970181431921507452, 31868}}
-
-// debugger:print case2
-// check:$2 = {{Case2, 0, {x = 286331153, y = 286331153, z = 4369}}, {Case2, 0, 1229782938247303441, 4369}}
-
-// debugger:print univariant
-// check:$3 = {{x = 123, y = 456, z = 789}}
-
-#![allow(unused_variable)]
-
-struct Struct {
-    x: u32,
-    y: i32,
-    z: i16
-}
-
-// 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 {
-    Case1(u64, Struct),
-    Case2(u64, u64, i16)
-}
-
-enum Univariant {
-    TheOnlyCase(Struct)
-}
-
-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 = Case1(0, Struct { x: 2088533116, y: 2088533116, z: 31868 });
-
-    // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
-    // 0b00010001000100010001000100010001 = 286331153
-    // 0b0001000100010001 = 4369
-    // 0b00010001 = 17
-    let case2 = Case2(0, 1229782938247303441, 4369);
-
-    let univariant = TheOnlyCase(Struct { x: 123, y: 456, z: 789 });
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/struct-in-struct.rs b/src/test/debug-info/struct-in-struct.rs
deleted file mode 100644 (file)
index 182fb3d..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:set print pretty off
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print three_simple_structs
-// check:$1 = {x = {x = 1}, y = {x = 2}, z = {x = 3}}
-
-// debugger:print internal_padding_parent
-// check:$2 = {x = {x = 4, y = 5}, y = {x = 6, y = 7}, z = {x = 8, y = 9}}
-
-// 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
-}
-
-struct InternalPadding {
-    x: i32,
-    y: i64
-}
-
-struct PaddingAtEnd {
-    x: i64,
-    y: i32
-}
-
-struct ThreeSimpleStructs {
-    x: Simple,
-    y: Simple,
-    z: Simple
-}
-
-struct InternalPaddingParent {
-    x: InternalPadding,
-    y: InternalPadding,
-    z: InternalPadding
-}
-
-struct PaddingAtEndParent {
-    x: PaddingAtEnd,
-    y: PaddingAtEnd,
-    z: PaddingAtEnd
-}
-
-struct Mixed {
-    x: PaddingAtEnd,
-    y: InternalPadding,
-    z: Simple,
-    w: i16
-}
-
-struct Bag {
-    x: Simple
-}
-
-struct BagInBag {
-    x: Bag
-}
-
-struct ThatsJustOverkill {
-    x: BagInBag
-}
-
-struct Tree {
-    x: Simple,
-    y: InternalPaddingParent,
-    z: BagInBag
-}
-
-fn main() {
-
-    let three_simple_structs = ThreeSimpleStructs {
-        x: Simple { x: 1 },
-        y: Simple { x: 2 },
-        z: Simple { x: 3 }
-    };
-
-    let internal_padding_parent = InternalPaddingParent {
-        x: InternalPadding { x: 4, y: 5 },
-        y: InternalPadding { x: 6, y: 7 },
-        z: InternalPadding { x: 8, y: 9 }
-    };
-
-    let padding_at_end_parent = PaddingAtEndParent {
-        x: PaddingAtEnd { x: 10, y: 11 },
-        y: PaddingAtEnd { x: 12, y: 13 },
-        z: PaddingAtEnd { x: 14, y: 15 }
-    };
-
-    let mixed = Mixed {
-        x: PaddingAtEnd { x: 16, y: 17 },
-        y: InternalPadding { x: 18, y: 19 },
-        z: Simple { x: 20 },
-        w: 21
-    };
-
-    let bag = Bag { x: Simple { x: 22 } };
-    let bag_in_bag = BagInBag {
-        x: Bag {
-            x: Simple { x: 23 }
-        }
-    };
-
-    let tjo = ThatsJustOverkill {
-        x: BagInBag {
-            x: Bag {
-                x: Simple { x: 24 }
-            }
-        }
-    };
-
-    let tree = Tree {
-        x: Simple { x: 25 },
-        y: InternalPaddingParent {
-            x: InternalPadding { x: 26, y: 27 },
-            y: InternalPadding { x: 28, y: 29 },
-            z: InternalPadding { x: 30, y: 31 }
-        },
-        z: BagInBag {
-            x: Bag {
-                x: Simple { x: 32 }
-            }
-        }
-    };
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/struct-style-enum.rs b/src/test/debug-info/struct-style-enum.rs
deleted file mode 100644 (file)
index cb68245..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:set print union on
-// debugger:rbreak 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}
-
-#![allow(unused_variable)]
-#![feature(struct_variant)]
-
-// 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 {
-    Case1 { a: u64, b: u16, c: u16, d: u16, e: u16},
-    Case2 { a: u64, b: u32, c: u32},
-    Case3 { a: u64, b: u64 }
-}
-
-enum Univariant {
-    TheOnlyCase { a: i64 }
-}
-
-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 = Case1 { a: 0, b: 31868, c: 31868, d: 31868, e: 31868 };
-
-    // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
-    // 0b00010001000100010001000100010001 = 286331153
-    // 0b0001000100010001 = 4369
-    // 0b00010001 = 17
-    let case2 = Case2 { a: 0, b: 286331153, c: 286331153 };
-
-    // 0b0101100101011001010110010101100101011001010110010101100101011001 = 6438275382588823897
-    // 0b01011001010110010101100101011001 = 1499027801
-    // 0b0101100101011001 = 22873
-    // 0b01011001 = 89
-    let case3 = Case3 { a: 0, b: 6438275382588823897 };
-
-    let univariant = TheOnlyCase { a: -1 };
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/struct-with-destructor.rs b/src/test/debug-info/struct-with-destructor.rs
deleted file mode 100644 (file)
index ae43961..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-// debugger:print simple
-// check:$1 = {x = 10, y = 20}
-
-// debugger:print noDestructor
-// check:$2 = {a = {x = 10, y = 20}, guard = -1}
-
-// debugger:print withDestructor
-// check:$3 = {a = {x = 10, y = 20}, guard = -1}
-
-// debugger:print nested
-// check:$4 = {a = {a = {x = 7890, y = 9870}}}
-
-#![allow(unused_variable)]
-
-struct NoDestructor {
-    x: i32,
-    y: i64
-}
-
-struct WithDestructor {
-    x: i32,
-    y: i64
-}
-
-impl Drop for WithDestructor {
-    fn drop(&mut self) {}
-}
-
-struct NoDestructorGuarded {
-    a: NoDestructor,
-    guard: i64
-}
-
-struct WithDestructorGuarded {
-    a: WithDestructor,
-    guard: i64
-}
-
-struct NestedInner {
-    a: WithDestructor
-}
-
-impl Drop for NestedInner {
-    fn drop(&mut self) {}
-}
-
-struct NestedOuter {
-    a: NestedInner
-}
-
-
-// The compiler adds a 'destructed' boolean field to structs implementing Drop. This field is used
-// at runtime to prevent drop() to be executed more than once (see middle::trans::adt).
-// This field must be incorporated by the debug info generation. Otherwise the debugger assumes a
-// wrong size/layout for the struct.
-fn main() {
-
-    let simple = WithDestructor { x: 10, y: 20 };
-
-    let noDestructor = NoDestructorGuarded {
-        a: NoDestructor { x: 10, y: 20 },
-        guard: -1
-    };
-
-    // If the destructor flag field is not incorporated into the debug info for 'WithDestructor'
-    // then the debugger will have an invalid offset for the field 'guard' and thus should not be
-    // able to read its value correctly (dots are padding bytes, D is the boolean destructor flag):
-    //
-    // 64 bit
-    //
-    // NoDestructorGuarded = 0000....00000000FFFFFFFF
-    //                       <--------------><------>
-    //                         NoDestructor   guard
-    //
-    //
-    // withDestructorGuarded = 0000....00000000D.......FFFFFFFF
-    //                         <--------------><------>          // How debug info says it is
-    //                          WithDestructor  guard
-    //
-    //                         <----------------------><------>  // How it actually is
-    //                              WithDestructor      guard
-    //
-    // 32 bit
-    //
-    // NoDestructorGuarded = 000000000000FFFFFFFF
-    //                       <----------><------>
-    //                       NoDestructor guard
-    //
-    //
-    // withDestructorGuarded = 000000000000D...FFFFFFFF
-    //                         <----------><------>      // How debug info says it is
-    //                      WithDestructor  guard
-    //
-    //                         <--------------><------>  // How it actually is
-    //                          WithDestructor  guard
-    //
-    let withDestructor = WithDestructorGuarded {
-        a: WithDestructor { x: 10, y: 20 },
-        guard: -1
-    };
-
-    // expected layout (64 bit) = xxxx....yyyyyyyyD.......D...
-    //                            <--WithDestructor------>
-    //                            <-------NestedInner-------->
-    //                            <-------NestedOuter-------->
-    let nested = NestedOuter { a: NestedInner { a: WithDestructor { x: 7890, y: 9870 } } };
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/text-to-include-1.txt b/src/test/debug-info/text-to-include-1.txt
deleted file mode 100644 (file)
index ba05527..0000000
+++ /dev/null
@@ -1 +0,0 @@
-some text to include in another file as string 1
\ No newline at end of file
diff --git a/src/test/debug-info/text-to-include-2.txt b/src/test/debug-info/text-to-include-2.txt
deleted file mode 100644 (file)
index a2caa5e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-some text to include in another file as string 2
\ No newline at end of file
diff --git a/src/test/debug-info/text-to-include-3.txt b/src/test/debug-info/text-to-include-3.txt
deleted file mode 100644 (file)
index 9933e6c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-some text to include in another file as string 3
\ No newline at end of file
diff --git a/src/test/debug-info/trait-generic-static-default-method.rs b/src/test/debug-info/trait-generic-static-default-method.rs
deleted file mode 100644 (file)
index 169c84e..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-// ignore-test
-
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// compile-flags:-g
-// debugger:rbreak 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() {()}
diff --git a/src/test/debug-info/trait-pointers.rs b/src/test/debug-info/trait-pointers.rs
deleted file mode 100644 (file)
index fcb0f60..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:run
-
-#![allow(unused_variable)]
-
-
-trait Trait {
-    fn method(&self) -> int { 0 }
-}
-
-struct Struct {
-    a: int,
-    b: f64
-}
-
-impl Trait for Struct {}
-
-// There is no real test here yet. Just make sure that it compiles without crashing.
-fn main() {
-    let stack_struct = Struct { a:0, b: 1.0 };
-    let reference: &Trait = &stack_struct as &Trait;
-    let unique: Box<Trait> = box Struct { a:2, b: 3.0 } as Box<Trait>;
-}
diff --git a/src/test/debug-info/tuple-in-struct.rs b/src/test/debug-info/tuple-in-struct.rs
deleted file mode 100644 (file)
index 242f59a..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:set print pretty off
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print no_padding1
-// check:$1 = {x = {0, 1}, y = 2, z = {3, 4, 5}}
-// debugger:print no_padding2
-// check:$2 = {x = {6, 7}, y = {{8, 9}, 10}}
-
-// debugger:print tuple_internal_padding
-// check:$3 = {x = {11, 12}, y = {13, 14}}
-// debugger:print struct_internal_padding
-// check:$4 = {x = {15, 16}, y = {17, 18}}
-// debugger:print both_internally_padded
-// check:$5 = {x = {19, 20, 21}, y = {22, 23}}
-
-// debugger:print single_tuple
-// check:$6 = {x = {24, 25, 26}}
-
-// debugger:print tuple_padded_at_end
-// check:$7 = {x = {27, 28}, y = {29, 30}}
-// debugger:print struct_padded_at_end
-// check:$8 = {x = {31, 32}, y = {33, 34}}
-// debugger:print both_padded_at_end
-// check:$9 = {x = {35, 36, 37}, y = {38, 39}}
-
-// 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,
-    z: (i32, i32, i32)
-}
-
-struct NoPadding2 {
-    x: (i32, i32),
-    y: ((i32, i32), i32)
-}
-
-struct TupleInternalPadding {
-    x: (i16, i32),
-    y: (i32, i64)
-}
-
-struct StructInternalPadding {
-    x: (i16, i16),
-    y: (i64, i64)
-}
-
-struct BothInternallyPadded {
-    x: (i16, i32, i32),
-    y: (i32, i64)
-}
-
-struct SingleTuple {
-    x: (i16, i32, i64)
-}
-
-struct TuplePaddedAtEnd {
-    x: (i32, i16),
-    y: (i64, i32)
-}
-
-struct StructPaddedAtEnd {
-    x: (i64, i64),
-    y: (i16, i16)
-}
-
-struct BothPaddedAtEnd {
-    x: (i32, i32, i16),
-    y: (i64, i32)
-}
-
-// Data-layout (padding signified by dots, one column = 2 bytes):
-// [a.bbc...ddddee..ffffg.hhi...]
-struct MixedPadding {
-    x: ((i16, i32, i16), (i64, i32)),
-    y: (i64, i16, i32, i16)
-}
-
-
-fn main() {
-    let no_padding1 = NoPadding1 {
-        x: (0, 1),
-        y: 2,
-        z: (3, 4, 5)
-    };
-
-    let no_padding2 = NoPadding2 {
-        x: (6, 7),
-        y: ((8, 9), 10)
-    };
-
-    let tuple_internal_padding = TupleInternalPadding {
-        x: (11, 12),
-        y: (13, 14)
-    };
-
-    let struct_internal_padding = StructInternalPadding {
-        x: (15, 16),
-        y: (17, 18)
-    };
-
-    let both_internally_padded = BothInternallyPadded {
-        x: (19, 20, 21),
-        y: (22, 23)
-    };
-
-    let single_tuple = SingleTuple {
-        x: (24, 25, 26)
-    };
-
-    let tuple_padded_at_end = TuplePaddedAtEnd {
-        x: (27, 28),
-        y: (29, 30)
-    };
-
-    let struct_padded_at_end = StructPaddedAtEnd {
-        x: (31, 32),
-        y: (33, 34)
-    };
-
-    let both_padded_at_end = BothPaddedAtEnd {
-        x: (35, 36, 37),
-        y: (38, 39)
-    };
-
-    let mixed_padding = MixedPadding {
-        x: ((40, 41, 42), (43, 44)),
-        y: (45, 46, 47, 48)
-    };
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/tuple-in-tuple.rs b/src/test/debug-info/tuple-in-tuple.rs
deleted file mode 100644 (file)
index 1008af2..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:set print pretty off
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print no_padding1
-// check:$1 = {{0, 1}, 2, 3}
-// debugger:print no_padding2
-// check:$2 = {4, {5, 6}, 7}
-// debugger:print no_padding3
-// check:$3 = {8, 9, {10, 11}}
-
-// debugger:print internal_padding1
-// check:$4 = {12, {13, 14}}
-// debugger:print internal_padding2
-// check:$5 = {15, {16, 17}}
-
-// debugger:print padding_at_end1
-// check:$6 = {18, {19, 20}}
-// 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);
-    let no_padding3: (u32, u32, (u32, u32)) = (8, 9, (10, 11));
-
-    let internal_padding1: (i16, (i32, i32)) = (12, (13, 14));
-    let internal_padding2: (i16, (i16, i32)) = (15, (16, 17));
-
-    let padding_at_end1: (i32, (i32, i16)) = (18, (19, 20));
-    let padding_at_end2: ((i32, i16), i32) = ((21, 22), 23);
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/tuple-struct.rs b/src/test/debug-info/tuple-struct.rs
deleted file mode 100644 (file)
index eae0d0b..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:set print pretty off
-// debugger:rbreak 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 "<unnamed_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() {()}
diff --git a/src/test/debug-info/tuple-style-enum.rs b/src/test/debug-info/tuple-style-enum.rs
deleted file mode 100644 (file)
index 176e4b0..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:set print union on
-// debugger:rbreak 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}
-
-#![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.
-enum Regular {
-    Case1(u64, u16, u16, u16, u16),
-    Case2(u64, u32, u32),
-    Case3(u64, u64)
-}
-
-enum Univariant {
-    TheOnlyCase(i64)
-}
-
-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 = Case1(0, 31868, 31868, 31868, 31868);
-
-    // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
-    // 0b00010001000100010001000100010001 = 286331153
-    // 0b0001000100010001 = 4369
-    // 0b00010001 = 17
-    let case2 = Case2(0, 286331153, 286331153);
-
-    // 0b0101100101011001010110010101100101011001010110010101100101011001 = 6438275382588823897
-    // 0b01011001010110010101100101011001 = 1499027801
-    // 0b0101100101011001 = 22873
-    // 0b01011001 = 89
-    let case3 = Case3(0, 6438275382588823897);
-
-    let univariant = TheOnlyCase(-1);
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/unique-enum.rs b/src/test/debug-info/unique-enum.rs
deleted file mode 100644 (file)
index 45f0213..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print *the_a
-// check:$1 = {{TheA, x = 0, y = 8970181431921507452}, {TheA, 0, 2088533116, 2088533116}}
-
-// debugger:print *the_b
-// check:$2 = {{TheB, x = 0, y = 1229782938247303441}, {TheB, 0, 286331153, 286331153}}
-
-// debugger:print *univariant
-// check:$3 = {123234}
-
-#![allow(unused_variable)]
-#![feature(struct_variant)]
-
-// 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 ABC {
-    TheA { x: i64, y: i64 },
-    TheB (i64, i32, i32),
-}
-
-// This is a special case since it does not have the implicit discriminant field.
-enum Univariant {
-    TheOnlyCase(i64)
-}
-
-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 the_a = box TheA { x: 0, y: 8970181431921507452 };
-
-    // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
-    // 0b00010001000100010001000100010001 = 286331153
-    // 0b0001000100010001 = 4369
-    // 0b00010001 = 17
-    let the_b = box TheB (0, 286331153, 286331153);
-
-    let univariant = box TheOnlyCase(123234);
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/var-captured-in-nested-closure.rs b/src/test/debug-info/var-captured-in-nested-closure.rs
deleted file mode 100644 (file)
index 7677c9e..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print variable
-// check:$1 = 1
-// debugger:print constant
-// check:$2 = 2
-// debugger:print a_struct
-// check:$3 = {a = -3, b = 4.5, c = 5}
-// debugger:print *struct_ref
-// check:$4 = {a = -3, b = 4.5, c = 5}
-// debugger:print *owned
-// check:$5 = 6
-// debugger:print managed->val
-// check:$6 = 7
-// debugger:print closure_local
-// check:$7 = 8
-// debugger:continue
-
-// debugger:finish
-// debugger:print variable
-// check:$8 = 1
-// debugger:print constant
-// check:$9 = 2
-// debugger:print a_struct
-// check:$10 = {a = -3, b = 4.5, c = 5}
-// debugger:print *struct_ref
-// check:$11 = {a = -3, b = 4.5, c = 5}
-// debugger:print *owned
-// check:$12 = 6
-// debugger:print managed->val
-// check:$13 = 7
-// debugger:print closure_local
-// check:$14 = 8
-// debugger:continue
-
-#![feature(managed_boxes)]
-#![allow(unused_variable)]
-
-struct Struct {
-    a: int,
-    b: f64,
-    c: uint
-}
-
-fn main() {
-    let mut variable = 1;
-    let constant = 2;
-
-    let a_struct = Struct {
-        a: -3,
-        b: 4.5,
-        c: 5
-    };
-
-    let struct_ref = &a_struct;
-    let owned = box 6;
-    let managed = @7;
-
-    let closure = || {
-        let closure_local = 8;
-
-        let nested_closure = || {
-            zzz();
-            variable = constant + a_struct.a + struct_ref.a + *owned + *managed + closure_local;
-        };
-
-        zzz();
-
-        nested_closure();
-    };
-
-    closure();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/var-captured-in-sendable-closure.rs b/src/test/debug-info/var-captured-in-sendable-closure.rs
deleted file mode 100644 (file)
index 4316e50..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print constant
-// check:$1 = 1
-// debugger:print a_struct
-// check:$2 = {a = -2, b = 3.5, c = 4}
-// debugger:print *owned
-// check:$3 = 5
-
-#![allow(unused_variable)]
-
-struct Struct {
-    a: int,
-    b: f64,
-    c: uint
-}
-
-fn main() {
-    let constant = 1;
-
-    let a_struct = Struct {
-        a: -2,
-        b: 3.5,
-        c: 4
-    };
-
-    let owned = box 5;
-
-    let closure: proc() = proc() {
-        zzz();
-        do_something(&constant, &a_struct.a, owned);
-    };
-
-    closure();
-}
-
-fn do_something(_: &int, _:&int, _:&int) {
-
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/var-captured-in-stack-closure.rs b/src/test/debug-info/var-captured-in-stack-closure.rs
deleted file mode 100644 (file)
index 57dcabe..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print variable
-// check:$1 = 1
-// debugger:print constant
-// check:$2 = 2
-// debugger:print a_struct
-// check:$3 = {a = -3, b = 4.5, c = 5}
-// debugger:print *struct_ref
-// check:$4 = {a = -3, b = 4.5, c = 5}
-// debugger:print *owned
-// check:$5 = 6
-// debugger:print managed->val
-// check:$6 = 7
-
-#![feature(managed_boxes)]
-#![allow(unused_variable)]
-
-struct Struct {
-    a: int,
-    b: f64,
-    c: uint
-}
-
-fn main() {
-    let mut variable = 1;
-    let constant = 2;
-
-    let a_struct = Struct {
-        a: -3,
-        b: 4.5,
-        c: 5
-    };
-
-    let struct_ref = &a_struct;
-    let owned = box 6;
-    let managed = @7;
-
-    let closure = || {
-        zzz();
-        variable = constant + a_struct.a + struct_ref.a + *owned + *managed;
-    };
-
-    closure();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/vec-slices.rs b/src/test/debug-info/vec-slices.rs
deleted file mode 100644 (file)
index 6171fac..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-win32: FIXME #13256
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:set print pretty off
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-// debugger:print empty.length
-// check:$1 = 0
-
-// debugger:print singleton.length
-// check:$2 = 1
-// debugger:print *((int64_t[1]*)(singleton.data_ptr))
-// check:$3 = {1}
-
-// debugger:print multiple.length
-// check:$4 = 4
-// debugger:print *((int64_t[4]*)(multiple.data_ptr))
-// check:$5 = {2, 3, 4, 5}
-
-// debugger:print slice_of_slice.length
-// check:$6 = 2
-// debugger:print *((int64_t[2]*)(slice_of_slice.data_ptr))
-// check:$7 = {3, 4}
-
-// debugger:print padded_tuple.length
-// check:$8 = 2
-// debugger:print padded_tuple.data_ptr[0]
-// check:$9 = {6, 7}
-// debugger:print padded_tuple.data_ptr[1]
-// check:$10 = {8, 9}
-
-// debugger:print padded_struct.length
-// check:$11 = 2
-// debugger:print padded_struct.data_ptr[0]
-// check:$12 = {x = 10, y = 11, z = 12}
-// debugger:print padded_struct.data_ptr[1]
-// check:$13 = {x = 13, y = 14, z = 15}
-
-// debugger:print 'vec-slices::MUT_VECT_SLICE'.length
-// check:$14 = 2
-// debugger:print *((int64_t[2]*)('vec-slices::MUT_VECT_SLICE'.data_ptr))
-// check:$15 = {64, 65}
-
-#![allow(unused_variable)]
-
-struct AStruct {
-    x: i16,
-    y: i32,
-    z: i16
-}
-
-static VECT_SLICE: &'static [i64] = &[64, 65];
-static mut MUT_VECT_SLICE: &'static [i64] = &[32];
-
-fn main() {
-    let empty: &[i64] = &[];
-    let singleton: &[i64] = &[1];
-    let multiple: &[i64] = &[2, 3, 4, 5];
-    let slice_of_slice = multiple.slice(1,3);
-
-    let padded_tuple: &[(i32, i16)] = &[(6, 7), (8, 9)];
-
-    let padded_struct: &[AStruct] = &[
-        AStruct { x: 10, y: 11, z: 12 },
-        AStruct { x: 13, y: 14, z: 15 }
-    ];
-
-    unsafe {
-        MUT_VECT_SLICE = VECT_SLICE;
-    }
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debug-info/vec.rs b/src/test/debug-info/vec.rs
deleted file mode 100644 (file)
index e1ee1ae..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-win32: FIXME #13256
-// ignore-android: FIXME(#10381)
-
-// compile-flags:-g
-// debugger:set print pretty off
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-// debugger:print a
-// check:$1 = {1, 2, 3}
-// debugger:print vec::VECT
-// check:$2 = {4, 5, 6}
-
-#![allow(unused_variable)]
-
-static mut VECT: [i32, ..3] = [1, 2, 3];
-
-fn main() {
-    let a = [1, 2, 3];
-
-    unsafe {
-        VECT[0] = 4;
-        VECT[1] = 5;
-        VECT[2] = 6;
-    }
-
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/debuginfo/basic-types-globals-metadata.rs b/src/test/debuginfo/basic-types-globals-metadata.rs
new file mode 100644 (file)
index 0000000..1e157f1
--- /dev/null
@@ -0,0 +1,73 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-win32: FIXME #13256
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+// gdb-command:whatis 'basic-types-globals-metadata::B'
+// gdb-check:type = bool
+// gdb-command:whatis 'basic-types-globals-metadata::I'
+// gdb-check:type = int
+// gdb-command:whatis 'basic-types-globals-metadata::C'
+// gdb-check:type = char
+// gdb-command:whatis 'basic-types-globals-metadata::I8'
+// gdb-check:type = i8
+// gdb-command:whatis 'basic-types-globals-metadata::I16'
+// gdb-check:type = i16
+// gdb-command:whatis 'basic-types-globals-metadata::I32'
+// gdb-check:type = i32
+// gdb-command:whatis 'basic-types-globals-metadata::I64'
+// gdb-check:type = i64
+// gdb-command:whatis 'basic-types-globals-metadata::U'
+// gdb-check:type = uint
+// gdb-command:whatis 'basic-types-globals-metadata::U8'
+// gdb-check:type = u8
+// gdb-command:whatis 'basic-types-globals-metadata::U16'
+// gdb-check:type = u16
+// gdb-command:whatis 'basic-types-globals-metadata::U32'
+// gdb-check:type = u32
+// gdb-command:whatis 'basic-types-globals-metadata::U64'
+// gdb-check:type = u64
+// gdb-command:whatis 'basic-types-globals-metadata::F32'
+// gdb-check:type = f32
+// gdb-command:whatis 'basic-types-globals-metadata::F64'
+// gdb-check:type = f64
+// gdb-command:continue
+
+#![allow(unused_variable)]
+#![allow(dead_code)]
+
+
+static B: bool = false;
+static I: int = -1;
+static C: char = 'a';
+static I8: i8 = 68;
+static I16: i16 = -16;
+static I32: i32 = -32;
+static I64: i64 = -64;
+static U: uint = 1;
+static U8: u8 = 100;
+static U16: u16 = 16;
+static U32: u32 = 32;
+static U64: u64 = 64;
+static F32: f32 = 2.5;
+static F64: f64 = 3.5;
+
+fn main() {
+    _zzz();
+
+    let a = (B, I, C, I8, I16, I32, I64, U, U8, U16, U32, U64, F32, F64);
+}
+
+fn _zzz() {()}
diff --git a/src/test/debuginfo/basic-types-globals.rs b/src/test/debuginfo/basic-types-globals.rs
new file mode 100644 (file)
index 0000000..2fc20be
--- /dev/null
@@ -0,0 +1,77 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Caveats - gdb prints any 8-bit value (meaning rust I8 and u8 values)
+// as its numerical value along with its associated ASCII char, there
+// doesn't seem to be any way around this. Also, gdb doesn't know
+// about UTF-32 character encoding and will print a rust char as only
+// its numerical value.
+
+// ignore-win32: FIXME #13256
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+// gdb-command:print 'basic-types-globals::B'
+// gdb-check:$1 = false
+// gdb-command:print 'basic-types-globals::I'
+// gdb-check:$2 = -1
+// gdb-command:print 'basic-types-globals::C'
+// gdb-check:$3 = 97
+// gdb-command:print/d 'basic-types-globals::I8'
+// gdb-check:$4 = 68
+// gdb-command:print 'basic-types-globals::I16'
+// gdb-check:$5 = -16
+// gdb-command:print 'basic-types-globals::I32'
+// gdb-check:$6 = -32
+// gdb-command:print 'basic-types-globals::I64'
+// gdb-check:$7 = -64
+// gdb-command:print 'basic-types-globals::U'
+// gdb-check:$8 = 1
+// gdb-command:print/d 'basic-types-globals::U8'
+// gdb-check:$9 = 100
+// gdb-command:print 'basic-types-globals::U16'
+// gdb-check:$10 = 16
+// gdb-command:print 'basic-types-globals::U32'
+// gdb-check:$11 = 32
+// gdb-command:print 'basic-types-globals::U64'
+// gdb-check:$12 = 64
+// gdb-command:print 'basic-types-globals::F32'
+// gdb-check:$13 = 2.5
+// gdb-command:print 'basic-types-globals::F64'
+// gdb-check:$14 = 3.5
+// gdb-command:continue
+
+#![allow(unused_variable)]
+
+static B: bool = false;
+static I: int = -1;
+static C: char = 'a';
+static I8: i8 = 68;
+static I16: i16 = -16;
+static I32: i32 = -32;
+static I64: i64 = -64;
+static U: uint = 1;
+static U8: u8 = 100;
+static U16: u16 = 16;
+static U32: u32 = 32;
+static U64: u64 = 64;
+static F32: f32 = 2.5;
+static F64: f64 = 3.5;
+
+fn main() {
+    _zzz();
+
+    let a = (B, I, C, I8, I16, I32, I64, U, U8, U16, U32, U64, F32, F64);
+}
+
+fn _zzz() {()}
diff --git a/src/test/debuginfo/basic-types-metadata.rs b/src/test/debuginfo/basic-types-metadata.rs
new file mode 100644 (file)
index 0000000..da32518
--- /dev/null
@@ -0,0 +1,74 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+// gdb-command:whatis unit
+// gdb-check:type = ()
+// gdb-command:whatis b
+// gdb-check:type = bool
+// gdb-command:whatis i
+// gdb-check:type = int
+// gdb-command:whatis c
+// gdb-check:type = char
+// gdb-command:whatis i8
+// gdb-check:type = i8
+// gdb-command:whatis i16
+// gdb-check:type = i16
+// gdb-command:whatis i32
+// gdb-check:type = i32
+// gdb-command:whatis i64
+// gdb-check:type = i64
+// gdb-command:whatis u
+// gdb-check:type = uint
+// gdb-command:whatis u8
+// gdb-check:type = u8
+// gdb-command:whatis u16
+// gdb-check:type = u16
+// gdb-command:whatis u32
+// gdb-check:type = u32
+// gdb-command:whatis u64
+// gdb-check:type = u64
+// gdb-command:whatis f32
+// gdb-check:type = f32
+// gdb-command:whatis f64
+// gdb-check:type = f64
+// gdb-command:info functions _yyy
+// gdb-check:[...]![...]_yyy([...])([...]);
+// gdb-command:continue
+
+#![allow(unused_variable)]
+
+fn main() {
+    let unit: () = ();
+    let b: bool = false;
+    let i: int = -1;
+    let c: char = 'a';
+    let i8: i8 = 68;
+    let i16: i16 = -16;
+    let i32: i32 = -32;
+    let i64: i64 = -64;
+    let u: uint = 1;
+    let u8: u8 = 100;
+    let u16: u16 = 16;
+    let u32: u32 = 32;
+    let u64: u64 = 64;
+    let f32: f32 = 2.5;
+    let f64: f64 = 3.5;
+    _zzz();
+    if 1 == 1 { _yyy(); }
+}
+
+fn _zzz() {()}
+fn _yyy() -> ! {fail!()}
diff --git a/src/test/debuginfo/basic-types-mut-globals.rs b/src/test/debuginfo/basic-types-mut-globals.rs
new file mode 100644 (file)
index 0000000..f157919
--- /dev/null
@@ -0,0 +1,129 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Caveats - gdb prints any 8-bit value (meaning rust I8 and u8 values)
+// as its numerical value along with its associated ASCII char, there
+// doesn't seem to be any way around this. Also, gdb doesn't know
+// about UTF-32 character encoding and will print a rust char as only
+// its numerical value.
+
+// ignore-win32: FIXME #13256
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// Check initializers
+// gdb-command:print 'basic-types-mut-globals::B'
+// gdb-check:$1 = false
+// gdb-command:print 'basic-types-mut-globals::I'
+// gdb-check:$2 = -1
+// gdb-command:print 'basic-types-mut-globals::C'
+// gdb-check:$3 = 97
+// gdb-command:print/d 'basic-types-mut-globals::I8'
+// gdb-check:$4 = 68
+// gdb-command:print 'basic-types-mut-globals::I16'
+// gdb-check:$5 = -16
+// gdb-command:print 'basic-types-mut-globals::I32'
+// gdb-check:$6 = -32
+// gdb-command:print 'basic-types-mut-globals::I64'
+// gdb-check:$7 = -64
+// gdb-command:print 'basic-types-mut-globals::U'
+// gdb-check:$8 = 1
+// gdb-command:print/d 'basic-types-mut-globals::U8'
+// gdb-check:$9 = 100
+// gdb-command:print 'basic-types-mut-globals::U16'
+// gdb-check:$10 = 16
+// gdb-command:print 'basic-types-mut-globals::U32'
+// gdb-check:$11 = 32
+// gdb-command:print 'basic-types-mut-globals::U64'
+// gdb-check:$12 = 64
+// gdb-command:print 'basic-types-mut-globals::F32'
+// gdb-check:$13 = 2.5
+// gdb-command:print 'basic-types-mut-globals::F64'
+// gdb-check:$14 = 3.5
+// gdb-command:continue
+
+// Check new values
+// gdb-command:print 'basic-types-mut-globals'::B
+// gdb-check:$15 = true
+// gdb-command:print 'basic-types-mut-globals'::I
+// gdb-check:$16 = 2
+// gdb-command:print 'basic-types-mut-globals'::C
+// gdb-check:$17 = 102
+// gdb-command:print/d 'basic-types-mut-globals'::I8
+// gdb-check:$18 = 78
+// gdb-command:print 'basic-types-mut-globals'::I16
+// gdb-check:$19 = -26
+// gdb-command:print 'basic-types-mut-globals'::I32
+// gdb-check:$20 = -12
+// gdb-command:print 'basic-types-mut-globals'::I64
+// gdb-check:$21 = -54
+// gdb-command:print 'basic-types-mut-globals'::U
+// gdb-check:$22 = 5
+// gdb-command:print/d 'basic-types-mut-globals'::U8
+// gdb-check:$23 = 20
+// gdb-command:print 'basic-types-mut-globals'::U16
+// gdb-check:$24 = 32
+// gdb-command:print 'basic-types-mut-globals'::U32
+// gdb-check:$25 = 16
+// gdb-command:print 'basic-types-mut-globals'::U64
+// gdb-check:$26 = 128
+// gdb-command:print 'basic-types-mut-globals'::F32
+// gdb-check:$27 = 5.75
+// gdb-command:print 'basic-types-mut-globals'::F64
+// gdb-check:$28 = 9.25
+
+// gdb-command:detach
+// gdb-command:quit
+
+#![allow(unused_variable)]
+
+static mut B: bool = false;
+static mut I: int = -1;
+static mut C: char = 'a';
+static mut I8: i8 = 68;
+static mut I16: i16 = -16;
+static mut I32: i32 = -32;
+static mut I64: i64 = -64;
+static mut U: uint = 1;
+static mut U8: u8 = 100;
+static mut U16: u16 = 16;
+static mut U32: u32 = 32;
+static mut U64: u64 = 64;
+static mut F32: f32 = 2.5;
+static mut F64: f64 = 3.5;
+
+fn main() {
+    _zzz();
+
+    unsafe {
+        B = true;
+        I = 2;
+        C = 'f';
+        I8 = 78;
+        I16 = -26;
+        I32 = -12;
+        I64 = -54;
+        U = 5;
+        U8 = 20;
+        U16 = 32;
+        U32 = 16;
+        U64 = 128;
+        F32 = 5.75;
+        F64 = 9.25;
+    }
+
+    _zzz();
+}
+
+fn _zzz() {()}
diff --git a/src/test/debuginfo/basic-types.rs b/src/test/debuginfo/basic-types.rs
new file mode 100644 (file)
index 0000000..ae554ca
--- /dev/null
@@ -0,0 +1,72 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Caveats - gdb prints any 8-bit value (meaning rust i8 and u8 values)
+// as its numerical value along with its associated ASCII char, there
+// doesn't seem to be any way around this. Also, gdb doesn't know
+// about UTF-32 character encoding and will print a rust char as only
+// its numerical value.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+// gdb-command:print b
+// gdb-check:$1 = false
+// gdb-command:print i
+// gdb-check:$2 = -1
+// gdb-command:print c
+// gdb-check:$3 = 97
+// gdb-command:print/d i8
+// gdb-check:$4 = 68
+// gdb-command:print i16
+// gdb-check:$5 = -16
+// gdb-command:print i32
+// gdb-check:$6 = -32
+// gdb-command:print i64
+// gdb-check:$7 = -64
+// gdb-command:print u
+// gdb-check:$8 = 1
+// gdb-command:print/d u8
+// gdb-check:$9 = 100
+// gdb-command:print u16
+// gdb-check:$10 = 16
+// gdb-command:print u32
+// gdb-check:$11 = 32
+// gdb-command:print u64
+// gdb-check:$12 = 64
+// gdb-command:print f32
+// gdb-check:$13 = 2.5
+// gdb-command:print f64
+// gdb-check:$14 = 3.5
+
+#![allow(unused_variable)]
+
+fn main() {
+    let b: bool = false;
+    let i: int = -1;
+    let c: char = 'a';
+    let i8: i8 = 68;
+    let i16: i16 = -16;
+    let i32: i32 = -32;
+    let i64: i64 = -64;
+    let u: uint = 1;
+    let u8: u8 = 100;
+    let u16: u16 = 16;
+    let u32: u32 = 32;
+    let u64: u64 = 64;
+    let f32: f32 = 2.5;
+    let f64: f64 = 3.5;
+    _zzz();
+}
+
+fn _zzz() {()}
diff --git a/src/test/debuginfo/borrowed-basic.rs b/src/test/debuginfo/borrowed-basic.rs
new file mode 100644 (file)
index 0000000..d511e5e
--- /dev/null
@@ -0,0 +1,109 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// Gdb doesn't know about UTF-32 character encoding and will print a rust char as only
+// its numerical value.
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+// gdb-command:print *bool_ref
+// gdb-check:$1 = true
+
+// gdb-command:print *int_ref
+// gdb-check:$2 = -1
+
+// gdb-command:print *char_ref
+// gdb-check:$3 = 97
+
+// gdb-command:print *i8_ref
+// gdb-check:$4 = 68 'D'
+
+// gdb-command:print *i16_ref
+// gdb-check:$5 = -16
+
+// gdb-command:print *i32_ref
+// gdb-check:$6 = -32
+
+// gdb-command:print *i64_ref
+// gdb-check:$7 = -64
+
+// gdb-command:print *uint_ref
+// gdb-check:$8 = 1
+
+// gdb-command:print *u8_ref
+// gdb-check:$9 = 100 'd'
+
+// gdb-command:print *u16_ref
+// gdb-check:$10 = 16
+
+// gdb-command:print *u32_ref
+// gdb-check:$11 = 32
+
+// gdb-command:print *u64_ref
+// gdb-check:$12 = 64
+
+// gdb-command:print *f32_ref
+// gdb-check:$13 = 2.5
+
+// gdb-command:print *f64_ref
+// gdb-check:$14 = 3.5
+
+#![allow(unused_variable)]
+
+fn main() {
+    let bool_val: bool = true;
+    let bool_ref: &bool = &bool_val;
+
+    let int_val: int = -1;
+    let int_ref: &int = &int_val;
+
+    let char_val: char = 'a';
+    let char_ref: &char = &char_val;
+
+    let i8_val: i8 = 68;
+    let i8_ref: &i8 = &i8_val;
+
+    let i16_val: i16 = -16;
+    let i16_ref: &i16 = &i16_val;
+
+    let i32_val: i32 = -32;
+    let i32_ref: &i32 = &i32_val;
+
+    let uint_val: i64 = -64;
+    let i64_ref: &i64 = &uint_val;
+
+    let uint_val: uint = 1;
+    let uint_ref: &uint = &uint_val;
+
+    let u8_val: u8 = 100;
+    let u8_ref: &u8 = &u8_val;
+
+    let u16_val: u16 = 16;
+    let u16_ref: &u16 = &u16_val;
+
+    let u32_val: u32 = 32;
+    let u32_ref: &u32 = &u32_val;
+
+    let u64_val: u64 = 64;
+    let u64_ref: &u64 = &u64_val;
+
+    let f32_val: f32 = 2.5;
+    let f32_ref: &f32 = &f32_val;
+
+    let f64_val: f64 = 3.5;
+    let f64_ref: &f64 = &f64_val;
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/borrowed-c-style-enum.rs b/src/test/debuginfo/borrowed-c-style-enum.rs
new file mode 100644 (file)
index 0000000..9ab7e07
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print *the_a_ref
+// gdb-check:$1 = TheA
+
+// gdb-command:print *the_b_ref
+// gdb-check:$2 = TheB
+
+// gdb-command:print *the_c_ref
+// gdb-check:$3 = TheC
+
+#![allow(unused_variable)]
+
+enum ABC { TheA, TheB, TheC }
+
+fn main() {
+    let the_a = TheA;
+    let the_a_ref: &ABC = &the_a;
+
+    let the_b = TheB;
+    let the_b_ref: &ABC = &the_b;
+
+    let the_c = TheC;
+    let the_c_ref: &ABC = &the_c;
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/borrowed-enum.rs b/src/test/debuginfo/borrowed-enum.rs
new file mode 100644 (file)
index 0000000..7126aec
--- /dev/null
@@ -0,0 +1,65 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print *the_a_ref
+// gdb-check:$1 = {{TheA, x = 0, y = 8970181431921507452}, {TheA, 0, 2088533116, 2088533116}}
+
+// gdb-command:print *the_b_ref
+// gdb-check:$2 = {{TheB, x = 0, y = 1229782938247303441}, {TheB, 0, 286331153, 286331153}}
+
+// gdb-command:print *univariant_ref
+// gdb-check:$3 = {4820353753753434}
+
+#![allow(unused_variable)]
+#![feature(struct_variant)]
+
+// 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 ABC {
+    TheA { x: i64, y: i64 },
+    TheB (i64, i32, i32),
+}
+
+// This is a special case since it does not have the implicit discriminant field.
+enum Univariant {
+    TheOnlyCase(i64)
+}
+
+fn main() {
+
+    // 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452
+    // 0b01111100011111000111110001111100 = 2088533116
+    // 0b0111110001111100 = 31868
+    // 0b01111100 = 124
+    let the_a = TheA { x: 0, y: 8970181431921507452 };
+    let the_a_ref: &ABC = &the_a;
+
+    // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
+    // 0b00010001000100010001000100010001 = 286331153
+    // 0b0001000100010001 = 4369
+    // 0b00010001 = 17
+    let the_b = TheB (0, 286331153, 286331153);
+    let the_b_ref: &ABC = &the_b;
+
+    let univariant = TheOnlyCase(4820353753753434);
+    let univariant_ref: &Univariant = &univariant;
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/borrowed-managed-basic.rs b/src/test/debuginfo/borrowed-managed-basic.rs
new file mode 100644 (file)
index 0000000..85f3258
--- /dev/null
@@ -0,0 +1,111 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+#![feature(managed_boxes)]
+
+// Gdb doesn't know about UTF-32 character encoding and will print a rust char as only
+// its numerical value.
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+// gdb-command:print *bool_ref
+// gdb-check:$1 = true
+
+// gdb-command:print *int_ref
+// gdb-check:$2 = -1
+
+// gdb-command:print *char_ref
+// gdb-check:$3 = 97
+
+// gdb-command:print/d *i8_ref
+// gdb-check:$4 = 68
+
+// gdb-command:print *i16_ref
+// gdb-check:$5 = -16
+
+// gdb-command:print *i32_ref
+// gdb-check:$6 = -32
+
+// gdb-command:print *i64_ref
+// gdb-check:$7 = -64
+
+// gdb-command:print *uint_ref
+// gdb-check:$8 = 1
+
+// gdb-command:print/d *u8_ref
+// gdb-check:$9 = 100
+
+// gdb-command:print *u16_ref
+// gdb-check:$10 = 16
+
+// gdb-command:print *u32_ref
+// gdb-check:$11 = 32
+
+// gdb-command:print *u64_ref
+// gdb-check:$12 = 64
+
+// gdb-command:print *f32_ref
+// gdb-check:$13 = 2.5
+
+// gdb-command:print *f64_ref
+// gdb-check:$14 = 3.5
+
+#![allow(unused_variable)]
+
+fn main() {
+    let bool_box: @bool = @true;
+    let bool_ref: &bool = bool_box;
+
+    let int_box: @int = @-1;
+    let int_ref: &int = int_box;
+
+    let char_box: @char = @'a';
+    let char_ref: &char = char_box;
+
+    let i8_box: @i8 = @68;
+    let i8_ref: &i8 = i8_box;
+
+    let i16_box: @i16 = @-16;
+    let i16_ref: &i16 = i16_box;
+
+    let i32_box: @i32 = @-32;
+    let i32_ref: &i32 = i32_box;
+
+    let i64_box: @i64 = @-64;
+    let i64_ref: &i64 = i64_box;
+
+    let uint_box: @uint = @1;
+    let uint_ref: &uint = uint_box;
+
+    let u8_box: @u8 = @100;
+    let u8_ref: &u8 = u8_box;
+
+    let u16_box: @u16 = @16;
+    let u16_ref: &u16 = u16_box;
+
+    let u32_box: @u32 = @32;
+    let u32_ref: &u32 = u32_box;
+
+    let u64_box: @u64 = @64;
+    let u64_ref: &u64 = u64_box;
+
+    let f32_box: @f32 = @2.5;
+    let f32_ref: &f32 = f32_box;
+
+    let f64_box: @f64 = @3.5;
+    let f64_ref: &f64 = f64_box;
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/borrowed-struct.rs b/src/test/debuginfo/borrowed-struct.rs
new file mode 100644 (file)
index 0000000..8ac0745
--- /dev/null
@@ -0,0 +1,76 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print *stack_val_ref
+// gdb-check:$1 = {x = 10, y = 23.5}
+
+// gdb-command:print *stack_val_interior_ref_1
+// gdb-check:$2 = 10
+
+// gdb-command:print *stack_val_interior_ref_2
+// gdb-check:$3 = 23.5
+
+// gdb-command:print *ref_to_unnamed
+// gdb-check:$4 = {x = 11, y = 24.5}
+
+// gdb-command:print *managed_val_ref
+// gdb-check:$5 = {x = 12, y = 25.5}
+
+// gdb-command:print *managed_val_interior_ref_1
+// gdb-check:$6 = 12
+
+// gdb-command:print *managed_val_interior_ref_2
+// gdb-check:$7 = 25.5
+
+// gdb-command:print *unique_val_ref
+// gdb-check:$8 = {x = 13, y = 26.5}
+
+// gdb-command:print *unique_val_interior_ref_1
+// gdb-check:$9 = 13
+
+// gdb-command:print *unique_val_interior_ref_2
+// gdb-check:$10 = 26.5
+
+#![feature(managed_boxes)]
+#![allow(unused_variable)]
+
+struct SomeStruct {
+    x: int,
+    y: f64
+}
+
+fn main() {
+    let stack_val: SomeStruct = SomeStruct { x: 10, y: 23.5 };
+    let stack_val_ref: &SomeStruct = &stack_val;
+    let stack_val_interior_ref_1: &int = &stack_val.x;
+    let stack_val_interior_ref_2: &f64 = &stack_val.y;
+    let ref_to_unnamed: &SomeStruct = &SomeStruct { x: 11, y: 24.5 };
+
+    let managed_val = @SomeStruct { x: 12, y: 25.5 };
+    let managed_val_ref: &SomeStruct = managed_val;
+    let managed_val_interior_ref_1: &int = &managed_val.x;
+    let managed_val_interior_ref_2: &f64 = &managed_val.y;
+
+    let unique_val = box SomeStruct { x: 13, y: 26.5 };
+    let unique_val_ref: &SomeStruct = unique_val;
+    let unique_val_interior_ref_1: &int = &unique_val.x;
+    let unique_val_interior_ref_2: &f64 = &unique_val.y;
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/borrowed-tuple.rs b/src/test/debuginfo/borrowed-tuple.rs
new file mode 100644 (file)
index 0000000..4279814
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+#![feature(managed_boxes)]
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print *stack_val_ref
+// gdb-check:$1 = {-14, -19}
+
+// gdb-command:print *ref_to_unnamed
+// gdb-check:$2 = {-15, -20}
+
+// gdb-command:print *managed_val_ref
+// gdb-check:$3 = {-16, -21}
+
+// gdb-command:print *unique_val_ref
+// gdb-check:$4 = {-17, -22}
+
+#![allow(unused_variable)]
+
+
+fn main() {
+    let stack_val: (i16, f32) = (-14, -19f32);
+    let stack_val_ref: &(i16, f32) = &stack_val;
+    let ref_to_unnamed: &(i16, f32) = &(-15, -20f32);
+
+    let managed_val: @(i16, f32) = @(-16, -21f32);
+    let managed_val_ref: &(i16, f32) = managed_val;
+
+    let unique_val: Box<(i16, f32)> = box() (-17, -22f32);
+    let unique_val_ref: &(i16, f32) = unique_val;
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/borrowed-unique-basic.rs b/src/test/debuginfo/borrowed-unique-basic.rs
new file mode 100644 (file)
index 0000000..6e8fa62
--- /dev/null
@@ -0,0 +1,110 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// Gdb doesn't know about UTF-32 character encoding and will print a rust char as only
+// its numerical value.
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+// gdb-command:print *bool_ref
+// gdb-check:$1 = true
+
+// gdb-command:print *int_ref
+// gdb-check:$2 = -1
+
+// gdb-command:print *char_ref
+// gdb-check:$3 = 97
+
+// gdb-command:print/d *i8_ref
+// gdb-check:$4 = 68
+
+// gdb-command:print *i16_ref
+// gdb-check:$5 = -16
+
+// gdb-command:print *i32_ref
+// gdb-check:$6 = -32
+
+// gdb-command:print *i64_ref
+// gdb-check:$7 = -64
+
+// gdb-command:print *uint_ref
+// gdb-check:$8 = 1
+
+// gdb-command:print/d *u8_ref
+// gdb-check:$9 = 100
+
+// gdb-command:print *u16_ref
+// gdb-check:$10 = 16
+
+// gdb-command:print *u32_ref
+// gdb-check:$11 = 32
+
+// gdb-command:print *u64_ref
+// gdb-check:$12 = 64
+
+// gdb-command:print *f32_ref
+// gdb-check:$13 = 2.5
+
+// gdb-command:print *f64_ref
+// gdb-check:$14 = 3.5
+
+#![allow(unused_variable)]
+
+
+fn main() {
+    let bool_box: Box<bool> = box true;
+    let bool_ref: &bool = bool_box;
+
+    let int_box: Box<int> = box -1;
+    let int_ref: &int = int_box;
+
+    let char_box: Box<char> = box 'a';
+    let char_ref: &char = char_box;
+
+    let i8_box: Box<i8> = box 68;
+    let i8_ref: &i8 = i8_box;
+
+    let i16_box: Box<i16> = box -16;
+    let i16_ref: &i16 = i16_box;
+
+    let i32_box: Box<i32> = box -32;
+    let i32_ref: &i32 = i32_box;
+
+    let i64_box: Box<i64> = box -64;
+    let i64_ref: &i64 = i64_box;
+
+    let uint_box: Box<uint> = box 1;
+    let uint_ref: &uint = uint_box;
+
+    let u8_box: Box<u8> = box 100;
+    let u8_ref: &u8 = u8_box;
+
+    let u16_box: Box<u16> = box 16;
+    let u16_ref: &u16 = u16_box;
+
+    let u32_box: Box<u32> = box 32;
+    let u32_ref: &u32 = u32_box;
+
+    let u64_box: Box<u64> = box 64;
+    let u64_ref: &u64 = u64_box;
+
+    let f32_box: Box<f32> = box 2.5;
+    let f32_ref: &f32 = f32_box;
+
+    let f64_box: Box<f64> = box 3.5;
+    let f64_ref: &f64 = f64_box;
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/box.rs b/src/test/debuginfo/box.rs
new file mode 100644 (file)
index 0000000..c29d3d8
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:set print pretty off
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+// gdb-command:print *a
+// gdb-check:$1 = 1
+// gdb-command:print *b
+// gdb-check:$2 = {2, 3.5}
+// gdb-command:print c->val
+// gdb-check:$3 = 4
+// gdb-command:print d->val
+// gdb-check:$4 = false
+
+#![feature(managed_boxes)]
+#![allow(unused_variable)]
+
+fn main() {
+    let a = box 1;
+    let b = box() (2, 3.5);
+    let c = @4;
+    let d = @false;
+    _zzz();
+}
+
+fn _zzz() {()}
diff --git a/src/test/debuginfo/boxed-struct.rs b/src/test/debuginfo/boxed-struct.rs
new file mode 100644 (file)
index 0000000..1c94885
--- /dev/null
@@ -0,0 +1,63 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print *unique
+// gdb-check:$1 = {x = 99, y = 999, z = 9999, w = 99999}
+
+// gdb-command:print managed->val
+// gdb-check:$2 = {x = 88, y = 888, z = 8888, w = 88888}
+
+// gdb-command:print *unique_dtor
+// gdb-check:$3 = {x = 77, y = 777, z = 7777, w = 77777}
+
+// gdb-command:print managed_dtor->val
+// gdb-check:$4 = {x = 33, y = 333, z = 3333, w = 33333}
+
+#![feature(managed_boxes)]
+#![allow(unused_variable)]
+
+
+struct StructWithSomePadding {
+    x: i16,
+    y: i32,
+    z: i32,
+    w: i64
+}
+
+struct StructWithDestructor {
+    x: i16,
+    y: i32,
+    z: i32,
+    w: i64
+}
+
+impl Drop for StructWithDestructor {
+    fn drop(&mut self) {}
+}
+
+fn main() {
+
+    let unique = box StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 };
+    let managed = @StructWithSomePadding { x: 88, y: 888, z: 8888, w: 88888 };
+
+    let unique_dtor = box StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 };
+    let managed_dtor = @StructWithDestructor { x: 33, y: 333, z: 3333, w: 33333 };
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/by-value-non-immediate-argument.rs b/src/test/debuginfo/by-value-non-immediate-argument.rs
new file mode 100644 (file)
index 0000000..873e062
--- /dev/null
@@ -0,0 +1,103 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// gdb-command:finish
+// gdb-command:print s
+// gdb-check:$1 = {a = 1, b = 2.5}
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$2 = {a = 3, b = 4.5}
+// gdb-command:print y
+// gdb-check:$3 = 5
+// gdb-command:print z
+// gdb-check:$4 = 6.5
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print a
+// gdb-check:$5 = {7, 8, 9.5, 10.5}
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print a
+// gdb-check:$6 = {11.5, 12.5, 13, 14}
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$7 = {{Case1, x = 0, y = 8970181431921507452}, {Case1, 0, 2088533116, 2088533116}}
+// gdb-command:continue
+
+#![feature(struct_variant)]
+
+#[deriving(Clone)]
+struct Struct {
+    a: int,
+    b: f64
+}
+
+#[deriving(Clone)]
+struct StructStruct {
+    a: Struct,
+    b: Struct
+}
+
+fn fun(s: Struct) {
+    zzz();
+}
+
+fn fun_fun(StructStruct { a: x, b: Struct { a: y, b: z } }: StructStruct) {
+    zzz();
+}
+
+fn tup(a: (int, uint, f64, f64)) {
+    zzz();
+}
+
+struct Newtype(f64, f64, int, uint);
+
+fn new_type(a: Newtype) {
+    zzz();
+}
+
+// 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 Enum {
+    Case1 { x: i64, y: i64 },
+    Case2 (i64, i32, i32),
+}
+
+fn by_val_enum(x: Enum) {
+    zzz();
+}
+
+fn main() {
+    fun(Struct { a: 1, b: 2.5 });
+    fun_fun(StructStruct { a: Struct { a: 3, b: 4.5 }, b: Struct { a: 5, b: 6.5 } });
+    tup((7, 8, 9.5, 10.5));
+    new_type(Newtype(11.5, 12.5, 13, 14));
+
+    // 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452
+    // 0b01111100011111000111110001111100 = 2088533116
+    // 0b0111110001111100 = 31868
+    // 0b01111100 = 124
+    by_val_enum(Case1 { x: 0, y: 8970181431921507452 });
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/by-value-self-argument-in-trait-impl.rs b/src/test/debuginfo/by-value-self-argument-in-trait-impl.rs
new file mode 100644 (file)
index 0000000..b626fba
--- /dev/null
@@ -0,0 +1,83 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+#![feature(managed_boxes)]
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// gdb-command:finish
+// gdb-command:print self
+// gdb-check:$1 = 1111
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print self
+// gdb-check:$2 = {x = 2222, y = 3333}
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print self
+// gdb-check:$3 = {4444.5, 5555, 6666, 7777.5}
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print self->val
+// gdb-check:$4 = 8888
+// gdb-command:continue
+
+trait Trait {
+    fn method(self) -> Self;
+}
+
+impl Trait for int {
+    fn method(self) -> int {
+        zzz();
+        self
+    }
+}
+
+struct Struct {
+    x: uint,
+    y: uint,
+}
+
+impl Trait for Struct {
+    fn method(self) -> Struct {
+        zzz();
+        self
+    }
+}
+
+impl Trait for (f64, int, int, f64) {
+    fn method(self) -> (f64, int, int, f64) {
+        zzz();
+        self
+    }
+}
+
+impl Trait for @int {
+    fn method(self) -> @int {
+        zzz();
+        self
+    }
+}
+
+fn main() {
+    let _ = (1111 as int).method();
+    let _ = Struct { x: 2222, y: 3333 }.method();
+    let _ = (4444.5, 5555, 6666, 7777.5).method();
+    let _ = (@8888).method();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/c-style-enum-in-composite.rs b/src/test/debuginfo/c-style-enum-in-composite.rs
new file mode 100644 (file)
index 0000000..3e76bf1
--- /dev/null
@@ -0,0 +1,121 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print tuple_interior_padding
+// gdb-check:$1 = {0, OneHundred}
+
+// gdb-command:print tuple_padding_at_end
+// gdb-check:$2 = {{1, OneThousand}, 2}
+
+// gdb-command:print tuple_different_enums
+// gdb-check:$3 = {OneThousand, MountainView, OneMillion, Vienna}
+
+// gdb-command:print padded_struct
+// gdb-check:$4 = {a = 3, b = OneMillion, c = 4, d = Toronto, e = 5}
+
+// gdb-command:print packed_struct
+// gdb-check:$5 = {a = 6, b = OneHundred, c = 7, d = Vienna, e = 8}
+
+// gdb-command:print non_padded_struct
+// gdb-check:$6 = {a = OneMillion, b = MountainView, c = OneThousand, d = Toronto}
+
+// gdb-command:print struct_with_drop
+// gdb-check:$7 = {{a = OneHundred, b = Vienna}, 9}
+
+#![allow(unused_variable)]
+
+enum AnEnum {
+    OneHundred = 100,
+    OneThousand = 1000,
+    OneMillion = 1000000
+}
+
+enum AnotherEnum {
+    MountainView,
+    Toronto,
+    Vienna
+}
+
+struct PaddedStruct {
+    a: i16,
+    b: AnEnum,
+    c: i16,
+    d: AnotherEnum,
+    e: i16
+}
+
+#[packed]
+struct PackedStruct {
+    a: i16,
+    b: AnEnum,
+    c: i16,
+    d: AnotherEnum,
+    e: i16
+}
+
+struct NonPaddedStruct {
+    a: AnEnum,
+    b: AnotherEnum,
+    c: AnEnum,
+    d: AnotherEnum
+}
+
+struct StructWithDrop {
+    a: AnEnum,
+    b: AnotherEnum
+}
+
+impl Drop for StructWithDrop {
+    fn drop(&mut self) {()}
+}
+
+fn main() {
+
+    let tuple_interior_padding = (0_i16, OneHundred);
+    // It will depend on the machine architecture if any padding is actually involved here
+    let tuple_padding_at_end = ((1_u64, OneThousand), 2_u64);
+    let tuple_different_enums = (OneThousand, MountainView, OneMillion, Vienna);
+
+    let padded_struct = PaddedStruct {
+        a: 3,
+        b: OneMillion,
+        c: 4,
+        d: Toronto,
+        e: 5
+    };
+
+    let packed_struct = PackedStruct {
+        a: 6,
+        b: OneHundred,
+        c: 7,
+        d: Vienna,
+        e: 8
+    };
+
+    let non_padded_struct = NonPaddedStruct {
+        a: OneMillion,
+        b: MountainView,
+        c: OneThousand,
+        d: Toronto
+    };
+
+    let struct_with_drop = (StructWithDrop { a: OneHundred, b: Vienna }, 9_i64);
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/c-style-enum.rs b/src/test/debuginfo/c-style-enum.rs
new file mode 100644 (file)
index 0000000..19f8398
--- /dev/null
@@ -0,0 +1,130 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-win32: FIXME #13256
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+
+// gdb-command:print 'c-style-enum::SINGLE_VARIANT'
+// gdb-check:$1 = TheOnlyVariant
+
+// gdb-command:print 'c-style-enum::AUTO_ONE'
+// gdb-check:$2 = One
+
+// gdb-command:print 'c-style-enum::AUTO_TWO'
+// gdb-check:$3 = One
+
+// gdb-command:print 'c-style-enum::AUTO_THREE'
+// gdb-check:$4 = One
+
+// gdb-command:print 'c-style-enum::MANUAL_ONE'
+// gdb-check:$5 = OneHundred
+
+// gdb-command:print 'c-style-enum::MANUAL_TWO'
+// gdb-check:$6 = OneHundred
+
+// gdb-command:print 'c-style-enum::MANUAL_THREE'
+// gdb-check:$7 = OneHundred
+
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print auto_one
+// gdb-check:$8 = One
+
+// gdb-command:print auto_two
+// gdb-check:$9 = Two
+
+// gdb-command:print auto_three
+// gdb-check:$10 = Three
+
+// gdb-command:print manual_one_hundred
+// gdb-check:$11 = OneHundred
+
+// gdb-command:print manual_one_thousand
+// gdb-check:$12 = OneThousand
+
+// gdb-command:print manual_one_million
+// gdb-check:$13 = OneMillion
+
+// gdb-command:print single_variant
+// gdb-check:$14 = TheOnlyVariant
+
+// gdb-command:print 'c-style-enum::AUTO_TWO'
+// gdb-check:$15 = Two
+
+// gdb-command:print 'c-style-enum::AUTO_THREE'
+// gdb-check:$16 = Three
+
+// gdb-command:print 'c-style-enum::MANUAL_TWO'
+// gdb-check:$17 = OneThousand
+
+// gdb-command:print 'c-style-enum::MANUAL_THREE'
+// gdb-check:$18 = OneMillion
+
+#![allow(unused_variable)]
+#![allow(dead_code)]
+
+enum AutoDiscriminant {
+    One,
+    Two,
+    Three
+}
+
+enum ManualDiscriminant {
+    OneHundred = 100,
+    OneThousand = 1000,
+    OneMillion = 1000000
+}
+
+enum SingleVariant {
+    TheOnlyVariant
+}
+
+static SINGLE_VARIANT: SingleVariant = TheOnlyVariant;
+
+static mut AUTO_ONE: AutoDiscriminant = One;
+static mut AUTO_TWO: AutoDiscriminant = One;
+static mut AUTO_THREE: AutoDiscriminant = One;
+
+static mut MANUAL_ONE: ManualDiscriminant = OneHundred;
+static mut MANUAL_TWO: ManualDiscriminant = OneHundred;
+static mut MANUAL_THREE: ManualDiscriminant = OneHundred;
+
+fn main() {
+
+    let auto_one = One;
+    let auto_two = Two;
+    let auto_three = Three;
+
+    let manual_one_hundred = OneHundred;
+    let manual_one_thousand = OneThousand;
+    let manual_one_million = OneMillion;
+
+    let single_variant = TheOnlyVariant;
+
+    unsafe {
+        AUTO_TWO = Two;
+        AUTO_THREE = Three;
+
+        MANUAL_TWO = OneThousand;
+        MANUAL_THREE = OneMillion;
+    };
+
+    zzz();
+
+    let a = SINGLE_VARIANT;
+    let a = unsafe { AUTO_ONE };
+    let a = unsafe { MANUAL_ONE };
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/closure-in-generic-function.rs b/src/test/debuginfo/closure-in-generic-function.rs
new file mode 100644 (file)
index 0000000..7a89b68
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$1 = 0.5
+// gdb-command:print y
+// gdb-check:$2 = 10
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print *x
+// gdb-check:$3 = 29
+// gdb-command:print *y
+// gdb-check:$4 = 110
+// gdb-command: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, box 110);
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/destructured-fn-argument.rs b/src/test/debuginfo/destructured-fn-argument.rs
new file mode 100644 (file)
index 0000000..6977030
--- /dev/null
@@ -0,0 +1,321 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// gdb-command:finish
+// gdb-command:print a
+// gdb-check:$1 = 1
+// gdb-command:print b
+// gdb-check:$2 = false
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print a
+// gdb-check:$3 = 2
+// gdb-command:print b
+// gdb-check:$4 = 3
+// gdb-command:print c
+// gdb-check:$5 = 4
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print a
+// gdb-check:$6 = 5
+// gdb-command:print b
+// gdb-check:$7 = {6, 7}
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print h
+// gdb-check:$8 = 8
+// gdb-command:print i
+// gdb-check:$9 = {a = 9, b = 10}
+// gdb-command:print j
+// gdb-check:$10 = 11
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print k
+// gdb-check:$11 = 12
+// gdb-command:print l
+// gdb-check:$12 = 13
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print m
+// gdb-check:$13 = 14
+// gdb-command:print n
+// gdb-check:$14 = 16
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print o
+// gdb-check:$15 = 18
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print p
+// gdb-check:$16 = 19
+// gdb-command:print q
+// gdb-check:$17 = 20
+// gdb-command:print r
+// gdb-check:$18 = {a = 21, b = 22}
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print s
+// gdb-check:$19 = 24
+// gdb-command:print t
+// gdb-check:$20 = 23
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print u
+// gdb-check:$21 = 25
+// gdb-command:print v
+// gdb-check:$22 = 26
+// gdb-command:print w
+// gdb-check:$23 = 27
+// gdb-command:print x
+// gdb-check:$24 = 28
+// gdb-command:print y
+// gdb-check:$25 = 29
+// gdb-command:print z
+// gdb-check:$26 = 30
+// gdb-command:print ae
+// gdb-check:$27 = 31
+// gdb-command:print oe
+// gdb-check:$28 = 32
+// gdb-command:print ue
+// gdb-check:$29 = 33
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print aa
+// gdb-check:$30 = {34, 35}
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print bb
+// gdb-check:$31 = {36, 37}
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print cc
+// gdb-check:$32 = 38
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print dd
+// gdb-check:$33 = {40, 41, 42}
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print *ee
+// gdb-check:$34 = {43, 44, 45}
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print *ff
+// gdb-check:$35 = 46
+// gdb-command:print gg
+// gdb-check:$36 = {47, 48}
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print *hh
+// gdb-check:$37 = 50
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print ii
+// gdb-check:$38 = 51
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print *jj
+// gdb-check:$39 = 52
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print kk
+// gdb-check:$40 = 53
+// gdb-command:print ll
+// gdb-check:$41 = 54
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print mm
+// gdb-check:$42 = 55
+// gdb-command:print *nn
+// gdb-check:$43 = 56
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print oo
+// gdb-check:$44 = 57
+// gdb-command:print pp
+// gdb-check:$45 = 58
+// gdb-command:print qq
+// gdb-check:$46 = 59
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print rr
+// gdb-check:$47 = 60
+// gdb-command:print ss
+// gdb-check:$48 = 61
+// gdb-command:print tt
+// gdb-check:$49 = 62
+// gdb-command:continue
+
+#![allow(unused_variable)]
+
+
+struct Struct {
+    a: i64,
+    b: i32
+}
+
+enum Univariant {
+    Unit(i32)
+}
+
+struct TupleStruct (f64, int);
+
+
+fn simple_tuple((a, b): (int, bool)) {
+    zzz();
+}
+
+fn nested_tuple((a, (b, c)): (int, (u16, u16))) {
+    zzz();
+}
+
+fn destructure_only_first_level((a, b): (int, (u32, u32))) {
+    zzz();
+}
+
+fn struct_as_tuple_element((h, i, j): (i16, Struct, i16)) {
+    zzz();
+}
+
+fn struct_pattern(Struct { a: k, b: l }: Struct) {
+    zzz();
+}
+
+fn ignored_tuple_element((m, _, n): (int, u16, i32)) {
+    zzz();
+}
+
+fn ignored_struct_field(Struct { b: o, .. }: Struct) {
+    zzz();
+}
+
+fn one_struct_destructured_one_not((Struct { a: p, b: q }, r): (Struct, Struct)) {
+    zzz();
+}
+
+fn different_order_of_struct_fields(Struct { b: s, a: t }: Struct ) {
+    zzz();
+}
+
+fn complex_nesting(((u,   v  ), ((w,   (x,   Struct { a: y, b: z})), Struct { a: ae, b: oe }), ue ):
+                   ((i16, i32), ((i64, (i32, Struct,             )), Struct                 ), u16))
+{
+    zzz();
+}
+
+fn managed_box(&aa: &(int, int)) {
+    zzz();
+}
+
+fn borrowed_pointer(&bb: &(int, int)) {
+    zzz();
+}
+
+fn contained_borrowed_pointer((&cc, _): (&int, int)) {
+    zzz();
+}
+
+fn unique_pointer(box dd: Box<(int, int, int)>) {
+    zzz();
+}
+
+fn ref_binding(ref ee: (int, int, int)) {
+    zzz();
+}
+
+fn ref_binding_in_tuple((ref ff, gg): (int, (int, int))) {
+    zzz();
+}
+
+fn ref_binding_in_struct(Struct { b: ref hh, .. }: Struct) {
+    zzz();
+}
+
+fn univariant_enum(Unit(ii): Univariant) {
+    zzz();
+}
+
+fn univariant_enum_with_ref_binding(Unit(ref jj): Univariant) {
+    zzz();
+}
+
+fn tuple_struct(TupleStruct(kk, ll): TupleStruct) {
+    zzz();
+}
+
+fn tuple_struct_with_ref_binding(TupleStruct(mm, ref nn): TupleStruct) {
+    zzz();
+}
+
+fn multiple_arguments((oo, pp): (int, int), qq : int) {
+    zzz();
+}
+
+fn main() {
+    simple_tuple((1, false));
+    nested_tuple((2, (3, 4)));
+    destructure_only_first_level((5, (6, 7)));
+    struct_as_tuple_element((8, Struct { a: 9, b: 10 }, 11));
+    struct_pattern(Struct { a: 12, b: 13 });
+    ignored_tuple_element((14, 15, 16));
+    ignored_struct_field(Struct { a: 17, b: 18 });
+    one_struct_destructured_one_not((Struct { a: 19, b: 20 }, Struct { a: 21, b: 22 }));
+    different_order_of_struct_fields(Struct { a: 23, b: 24 });
+    complex_nesting(((25, 26), ((27, (28, Struct { a: 29, b: 30})), Struct { a: 31, b: 32 }), 33));
+    managed_box(&(34, 35));
+    borrowed_pointer(&(36, 37));
+    contained_borrowed_pointer((&38, 39));
+    unique_pointer(box() (40, 41, 42));
+    ref_binding((43, 44, 45));
+    ref_binding_in_tuple((46, (47, 48)));
+    ref_binding_in_struct(Struct { a: 49, b: 50 });
+    univariant_enum(Unit(51));
+    univariant_enum_with_ref_binding(Unit(52));
+    tuple_struct(TupleStruct(53.0, 54));
+    tuple_struct_with_ref_binding(TupleStruct(55.0, 56));
+    multiple_arguments((57, 58), 59);
+
+    fn nested_function(rr: int, (ss, tt): (int, int)) {
+        zzz();
+    }
+
+    nested_function(60, (61, 62));
+}
+
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/destructured-local.rs b/src/test/debuginfo/destructured-local.rs
new file mode 100644 (file)
index 0000000..c543a11
--- /dev/null
@@ -0,0 +1,210 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print a
+// gdb-check:$1 = 1
+// gdb-command:print b
+// gdb-check:$2 = false
+
+// gdb-command:print c
+// gdb-check:$3 = 2
+// gdb-command:print d
+// gdb-check:$4 = 3
+// gdb-command:print e
+// gdb-check:$5 = 4
+
+// gdb-command:print f
+// gdb-check:$6 = 5
+// gdb-command:print g
+// gdb-check:$7 = {6, 7}
+
+// gdb-command:print h
+// gdb-check:$8 = 8
+// gdb-command:print i
+// gdb-check:$9 = {a = 9, b = 10}
+// gdb-command:print j
+// gdb-check:$10 = 11
+
+// gdb-command:print k
+// gdb-check:$11 = 12
+// gdb-command:print l
+// gdb-check:$12 = 13
+
+// gdb-command:print m
+// gdb-check:$13 = 14
+// gdb-command:print n
+// gdb-check:$14 = 16
+
+// gdb-command:print o
+// gdb-check:$15 = 18
+
+// gdb-command:print p
+// gdb-check:$16 = 19
+// gdb-command:print q
+// gdb-check:$17 = 20
+// gdb-command:print r
+// gdb-check:$18 = {a = 21, b = 22}
+
+// gdb-command:print s
+// gdb-check:$19 = 24
+// gdb-command:print t
+// gdb-check:$20 = 23
+
+// gdb-command:print u
+// gdb-check:$21 = 25
+// gdb-command:print v
+// gdb-check:$22 = 26
+// gdb-command:print w
+// gdb-check:$23 = 27
+// gdb-command:print x
+// gdb-check:$24 = 28
+// gdb-command:print y
+// gdb-check:$25 = 29
+// gdb-command:print z
+// gdb-check:$26 = 30
+// gdb-command:print ae
+// gdb-check:$27 = 31
+// gdb-command:print oe
+// gdb-check:$28 = 32
+// gdb-command:print ue
+// gdb-check:$29 = 33
+
+// gdb-command:print aa
+// gdb-check:$30 = {34, 35}
+
+// gdb-command:print bb
+// gdb-check:$31 = {36, 37}
+
+// gdb-command:print cc
+// gdb-check:$32 = 38
+
+// gdb-command:print dd
+// gdb-check:$33 = {40, 41, 42}
+
+// gdb-command:print *ee
+// gdb-check:$34 = {43, 44, 45}
+
+// gdb-command:print *ff
+// gdb-check:$35 = 46
+
+// gdb-command:print gg
+// gdb-check:$36 = {47, 48}
+
+// gdb-command:print *hh
+// gdb-check:$37 = 50
+
+// gdb-command:print ii
+// gdb-check:$38 = 51
+
+// gdb-command:print *jj
+// gdb-check:$39 = 52
+
+// gdb-command:print kk
+// gdb-check:$40 = 53
+
+// gdb-command:print ll
+// gdb-check:$41 = 54
+
+// gdb-command:print mm
+// gdb-check:$42 = 55
+
+// gdb-command:print *nn
+// gdb-check:$43 = 56
+
+#![allow(unused_variable)]
+
+struct Struct {
+    a: i64,
+    b: i32
+}
+
+enum Univariant {
+    Unit(i32)
+}
+
+struct TupleStruct (f64, int);
+
+
+fn main() {
+    // simple tuple
+    let (a, b) : (int, bool) = (1, false);
+
+    // nested tuple
+    let (c, (d, e)) : (int, (u16, u16)) = (2, (3, 4));
+
+    // bind tuple-typed value to one name (destructure only first level)
+    let (f, g) : (int, (u32, u32)) = (5, (6, 7));
+
+    // struct as tuple element
+    let (h, i, j) : (i16, Struct, i16) = (8, Struct { a: 9, b: 10 }, 11);
+
+    // struct pattern
+    let Struct { a: k, b: l } = Struct { a: 12, b: 13 };
+
+    // ignored tuple element
+    let (m, _, n) = (14, 15, 16);
+
+    // ignored struct field
+    let Struct { b: o, .. } = Struct { a: 17, b: 18 };
+
+    // one struct destructured, one not
+    let (Struct { a: p, b: q }, r) = (Struct { a: 19, b: 20 }, Struct { a: 21, b: 22 });
+
+    // different order of struct fields
+    let Struct { b: s, a: t } = Struct { a: 23, b: 24 };
+
+    // complex nesting
+    let ((u, v), ((w, (x, Struct { a: y, b: z})), Struct { a: ae, b: oe }), ue) =
+        ((25, 26), ((27, (28, Struct { a: 29, b: 30})), Struct { a: 31, b: 32 }), 33);
+
+    // reference
+    let &aa = &(34, 35);
+
+    // reference
+    let &bb = &(36, 37);
+
+    // contained reference
+    let (&cc, _) = (&38, 39);
+
+    // unique pointer
+    let box dd = box() (40, 41, 42);
+
+    // ref binding
+    let ref ee = (43, 44, 45);
+
+    // ref binding in tuple
+    let (ref ff, gg) = (46, (47, 48));
+
+    // ref binding in struct
+    let Struct { b: ref hh, .. } = Struct { a: 49, b: 50 };
+
+    // univariant enum
+    let Unit(ii) = Unit(51);
+
+    // univariant enum with ref      binding
+    let &Unit(ref jj) = &Unit(52);
+
+    // tuple struct
+    let &TupleStruct(kk, ll) = &TupleStruct(53.0, 54);
+
+    // tuple struct with ref binding
+    let &TupleStruct(mm, ref nn) = &TupleStruct(55.0, 56);
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/evec-in-struct.rs b/src/test/debuginfo/evec-in-struct.rs
new file mode 100644 (file)
index 0000000..913038c
--- /dev/null
@@ -0,0 +1,90 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:set print pretty off
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print no_padding1
+// gdb-check:$1 = {x = {0, 1, 2}, y = -3, z = {4.5, 5.5}}
+// gdb-command:print no_padding2
+// gdb-check:$2 = {x = {6, 7, 8}, y = {{9, 10}, {11, 12}}}
+
+// gdb-command:print struct_internal_padding
+// gdb-check:$3 = {x = {13, 14}, y = {15, 16}}
+
+// gdb-command:print single_vec
+// gdb-check:$4 = {x = {17, 18, 19, 20, 21}}
+
+// gdb-command:print struct_padded_at_end
+// gdb-check:$5 = {x = {22, 23}, y = {24, 25}}
+
+#![allow(unused_variable)]
+
+struct NoPadding1 {
+    x: [u32, ..3],
+    y: i32,
+    z: [f32, ..2]
+}
+
+struct NoPadding2 {
+    x: [u32, ..3],
+    y: [[u32, ..2], ..2]
+}
+
+struct StructInternalPadding {
+    x: [i16, ..2],
+    y: [i64, ..2]
+}
+
+struct SingleVec {
+    x: [i16, ..5]
+}
+
+struct StructPaddedAtEnd {
+    x: [i64, ..2],
+    y: [i16, ..2]
+}
+
+fn main() {
+
+    let no_padding1 = NoPadding1 {
+        x: [0, 1, 2],
+        y: -3,
+        z: [4.5, 5.5]
+    };
+
+    let no_padding2 = NoPadding2 {
+        x: [6, 7, 8],
+        y: [[9, 10], [11, 12]]
+    };
+
+    let struct_internal_padding = StructInternalPadding {
+        x: [13, 14],
+        y: [15, 16]
+    };
+
+    let single_vec = SingleVec {
+        x: [17, 18, 19, 20, 21]
+    };
+
+    let struct_padded_at_end = StructPaddedAtEnd {
+        x: [22, 23],
+        y: [24, 25]
+    };
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/function-arg-initialization.rs b/src/test/debuginfo/function-arg-initialization.rs
new file mode 100644 (file)
index 0000000..d439f49
--- /dev/null
@@ -0,0 +1,244 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// This test case checks if function arguments already have the correct value when breaking at the
+// first line of the function, that is if the function prologue has already been executed at the
+// first line. Note that because of the __morestack part of the prologue GDB incorrectly breaks at
+// before the arguments have been properly loaded when setting the breakpoint via the function name.
+// Therefore the setup here sets them using line numbers (so be careful when changing this file).
+
+// compile-flags:-g
+// gdb-command:set print pretty off
+// gdb-command:break function-arg-initialization.rs:139
+// gdb-command:break function-arg-initialization.rs:154
+// gdb-command:break function-arg-initialization.rs:158
+// gdb-command:break function-arg-initialization.rs:162
+// gdb-command:break function-arg-initialization.rs:166
+// gdb-command:break function-arg-initialization.rs:170
+// gdb-command:break function-arg-initialization.rs:174
+// gdb-command:break function-arg-initialization.rs:178
+// gdb-command:break function-arg-initialization.rs:182
+// gdb-command:break function-arg-initialization.rs:190
+// gdb-command:break function-arg-initialization.rs:197
+
+
+// gdb-command:run
+
+// IMMEDIATE ARGS
+// gdb-command:print a
+// gdb-check:$1 = 1
+// gdb-command:print b
+// gdb-check:$2 = true
+// gdb-command:print c
+// gdb-check:$3 = 2.5
+// gdb-command:continue
+
+// NON IMMEDIATE ARGS
+// gdb-command:print a
+// gdb-check:$4 = {a = 3, b = 4, c = 5, d = 6, e = 7, f = 8, g = 9, h = 10}
+// gdb-command:print b
+// gdb-check:$5 = {a = 11, b = 12, c = 13, d = 14, e = 15, f = 16, g = 17, h = 18}
+// gdb-command:continue
+
+// BINDING
+// gdb-command:print a
+// gdb-check:$6 = 19
+// gdb-command:print b
+// gdb-check:$7 = 20
+// gdb-command:print c
+// gdb-check:$8 = 21.5
+// gdb-command:continue
+
+// ASSIGNMENT
+// gdb-command:print a
+// gdb-check:$9 = 22
+// gdb-command:print b
+// gdb-check:$10 = 23
+// gdb-command:print c
+// gdb-check:$11 = 24.5
+// gdb-command:continue
+
+// FUNCTION CALL
+// gdb-command:print x
+// gdb-check:$12 = 25
+// gdb-command:print y
+// gdb-check:$13 = 26
+// gdb-command:print z
+// gdb-check:$14 = 27.5
+// gdb-command:continue
+
+// EXPR
+// gdb-command:print x
+// gdb-check:$15 = 28
+// gdb-command:print y
+// gdb-check:$16 = 29
+// gdb-command:print z
+// gdb-check:$17 = 30.5
+// gdb-command:continue
+
+// RETURN EXPR
+// gdb-command:print x
+// gdb-check:$18 = 31
+// gdb-command:print y
+// gdb-check:$19 = 32
+// gdb-command:print z
+// gdb-check:$20 = 33.5
+// gdb-command:continue
+
+// ARITHMETIC EXPR
+// gdb-command:print x
+// gdb-check:$21 = 34
+// gdb-command:print y
+// gdb-check:$22 = 35
+// gdb-command:print z
+// gdb-check:$23 = 36.5
+// gdb-command:continue
+
+// IF EXPR
+// gdb-command:print x
+// gdb-check:$24 = 37
+// gdb-command:print y
+// gdb-check:$25 = 38
+// gdb-command:print z
+// gdb-check:$26 = 39.5
+// gdb-command:continue
+
+// WHILE EXPR
+// gdb-command:print x
+// gdb-check:$27 = 40
+// gdb-command:print y
+// gdb-check:$28 = 41
+// gdb-command:print z
+// gdb-check:$29 = 42
+// gdb-command:continue
+
+// LOOP EXPR
+// gdb-command:print x
+// gdb-check:$30 = 43
+// gdb-command:print y
+// gdb-check:$31 = 44
+// gdb-command:print z
+// gdb-check:$32 = 45
+// gdb-command:continue
+
+#![allow(unused_variable)]
+
+
+
+
+fn immediate_args(a: int, b: bool, c: f64) {
+    ()
+}
+
+struct BigStruct {
+    a: u64,
+    b: u64,
+    c: u64,
+    d: u64,
+    e: u64,
+    f: u64,
+    g: u64,
+    h: u64
+}
+
+fn non_immediate_args(a: BigStruct, b: BigStruct) {
+    ()
+}
+
+fn binding(a: i64, b: u64, c: f64) {
+    let x = 0;
+}
+
+fn assignment(mut a: u64, b: u64, c: f64) {
+    a = b;
+}
+
+fn function_call(x: u64, y: u64, z: f64) {
+    std::io::stdio::print("Hi!")
+}
+
+fn identifier(x: u64, y: u64, z: f64) -> u64 {
+    x
+}
+
+fn return_expr(x: u64, y: u64, z: f64) -> u64 {
+    return x;
+}
+
+fn arithmetic_expr(x: u64, y: u64, z: f64) -> u64 {
+    x + y
+}
+
+fn if_expr(x: u64, y: u64, z: f64) -> u64 {
+    if x + y < 1000 {
+        x
+    } else {
+        y
+    }
+}
+
+fn while_expr(mut x: u64, y: u64, z: u64) -> u64 {
+    while x + y < 1000 {
+        x += z
+    }
+    return x;
+}
+
+fn loop_expr(mut x: u64, y: u64, z: u64) -> u64 {
+    loop {
+        x += z;
+
+        if x + y > 1000 {
+            return x;
+        }
+    }
+}
+
+fn main() {
+    immediate_args(1, true, 2.5);
+
+    non_immediate_args(
+        BigStruct {
+            a: 3,
+            b: 4,
+            c: 5,
+            d: 6,
+            e: 7,
+            f: 8,
+            g: 9,
+            h: 10
+        },
+        BigStruct {
+            a: 11,
+            b: 12,
+            c: 13,
+            d: 14,
+            e: 15,
+            f: 16,
+            g: 17,
+            h: 18
+        }
+    );
+
+    binding(19, 20, 21.5);
+    assignment(22, 23, 24.5);
+    function_call(25, 26, 27.5);
+    identifier(28, 29, 30.5);
+    return_expr(31, 32, 33.5);
+    arithmetic_expr(34, 35, 36.5);
+    if_expr(37, 38, 39.5);
+    while_expr(40, 41, 42);
+    loop_expr(43, 44, 45);
+}
+
+
+
diff --git a/src/test/debuginfo/function-arguments.rs b/src/test/debuginfo/function-arguments.rs
new file mode 100644 (file)
index 0000000..e65b9a2
--- /dev/null
@@ -0,0 +1,48 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print x
+// gdb-check:$1 = 111102
+// gdb-command:print y
+// gdb-check:$2 = true
+
+// gdb-command:continue
+// gdb-command:finish
+
+// gdb-command:print a
+// gdb-check:$3 = 2000
+// gdb-command:print b
+// gdb-check:$4 = 3000
+
+fn main() {
+
+    fun(111102, true);
+    nested(2000, 3000);
+
+    fn nested(a: i32, b: i64) -> (i32, i64) {
+        zzz();
+        (a, b)
+    }
+}
+
+fn fun(x: int, y: bool) -> (int, bool) {
+    zzz();
+
+    (x, y)
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/function-prologue-stepping-no-split-stack.rs b/src/test/debuginfo/function-prologue-stepping-no-split-stack.rs
new file mode 100644 (file)
index 0000000..a9ccf3c
--- /dev/null
@@ -0,0 +1,246 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// This test case checks if function arguments already have the correct value when breaking at the
+// beginning of a function. Functions with the #[no_split_stack] attribute have the same prologue as
+// regular C functions compiled with GCC or Clang and therefore are better handled by GDB. As a
+// consequence, and as opposed to regular Rust functions, we can set the breakpoints via the
+// function name (and don't have to fall back on using line numbers).
+
+// compile-flags:-g
+// gdb-command:set print pretty off
+// gdb-command:rbreak immediate_args
+// gdb-command:rbreak binding
+// gdb-command:rbreak assignment
+// gdb-command:rbreak function_call
+// gdb-command:rbreak identifier
+// gdb-command:rbreak return_expr
+// gdb-command:rbreak arithmetic_expr
+// gdb-command:rbreak if_expr
+// gdb-command:rbreak while_expr
+// gdb-command:rbreak loop_expr
+// gdb-command:run
+
+// IMMEDIATE ARGS
+// gdb-command:print a
+// gdb-check:$1 = 1
+// gdb-command:print b
+// gdb-check:$2 = true
+// gdb-command:print c
+// gdb-check:$3 = 2.5
+// gdb-command:continue
+
+// NON IMMEDIATE ARGS
+// gdb-command:print a
+// gdb-check:$4 = {a = 3, b = 4, c = 5, d = 6, e = 7, f = 8, g = 9, h = 10}
+// gdb-command:print b
+// gdb-check:$5 = {a = 11, b = 12, c = 13, d = 14, e = 15, f = 16, g = 17, h = 18}
+// gdb-command:continue
+
+// BINDING
+// gdb-command:print a
+// gdb-check:$6 = 19
+// gdb-command:print b
+// gdb-check:$7 = 20
+// gdb-command:print c
+// gdb-check:$8 = 21.5
+// gdb-command:continue
+
+// ASSIGNMENT
+// gdb-command:print a
+// gdb-check:$9 = 22
+// gdb-command:print b
+// gdb-check:$10 = 23
+// gdb-command:print c
+// gdb-check:$11 = 24.5
+// gdb-command:continue
+
+// FUNCTION CALL
+// gdb-command:print x
+// gdb-check:$12 = 25
+// gdb-command:print y
+// gdb-check:$13 = 26
+// gdb-command:print z
+// gdb-check:$14 = 27.5
+// gdb-command:continue
+
+// EXPR
+// gdb-command:print x
+// gdb-check:$15 = 28
+// gdb-command:print y
+// gdb-check:$16 = 29
+// gdb-command:print z
+// gdb-check:$17 = 30.5
+// gdb-command:continue
+
+// RETURN EXPR
+// gdb-command:print x
+// gdb-check:$18 = 31
+// gdb-command:print y
+// gdb-check:$19 = 32
+// gdb-command:print z
+// gdb-check:$20 = 33.5
+// gdb-command:continue
+
+// ARITHMETIC EXPR
+// gdb-command:print x
+// gdb-check:$21 = 34
+// gdb-command:print y
+// gdb-check:$22 = 35
+// gdb-command:print z
+// gdb-check:$23 = 36.5
+// gdb-command:continue
+
+// IF EXPR
+// gdb-command:print x
+// gdb-check:$24 = 37
+// gdb-command:print y
+// gdb-check:$25 = 38
+// gdb-command:print z
+// gdb-check:$26 = 39.5
+// gdb-command:continue
+
+// WHILE EXPR
+// gdb-command:print x
+// gdb-check:$27 = 40
+// gdb-command:print y
+// gdb-check:$28 = 41
+// gdb-command:print z
+// gdb-check:$29 = 42
+// gdb-command:continue
+
+// LOOP EXPR
+// gdb-command:print x
+// gdb-check:$30 = 43
+// gdb-command:print y
+// gdb-check:$31 = 44
+// gdb-command:print z
+// gdb-check:$32 = 45
+// gdb-command:continue
+
+#![allow(unused_variable)]
+
+#[no_split_stack]
+fn immediate_args(a: int, b: bool, c: f64) {
+    ()
+}
+
+struct BigStruct {
+    a: u64,
+    b: u64,
+    c: u64,
+    d: u64,
+    e: u64,
+    f: u64,
+    g: u64,
+    h: u64
+}
+
+#[no_split_stack]
+fn non_immediate_args(a: BigStruct, b: BigStruct) {
+    ()
+}
+
+#[no_split_stack]
+fn binding(a: i64, b: u64, c: f64) {
+    let x = 0;
+}
+
+#[no_split_stack]
+fn assignment(mut a: u64, b: u64, c: f64) {
+    a = b;
+}
+
+#[no_split_stack]
+fn function_call(x: u64, y: u64, z: f64) {
+    std::io::stdio::print("Hi!")
+}
+
+#[no_split_stack]
+fn identifier(x: u64, y: u64, z: f64) -> u64 {
+    x
+}
+
+#[no_split_stack]
+fn return_expr(x: u64, y: u64, z: f64) -> u64 {
+    return x;
+}
+
+#[no_split_stack]
+fn arithmetic_expr(x: u64, y: u64, z: f64) -> u64 {
+    x + y
+}
+
+#[no_split_stack]
+fn if_expr(x: u64, y: u64, z: f64) -> u64 {
+    if x + y < 1000 {
+        x
+    } else {
+        y
+    }
+}
+
+#[no_split_stack]
+fn while_expr(mut x: u64, y: u64, z: u64) -> u64 {
+    while x + y < 1000 {
+        x += z
+    }
+    return x;
+}
+
+#[no_split_stack]
+fn loop_expr(mut x: u64, y: u64, z: u64) -> u64 {
+    loop {
+        x += z;
+
+        if x + y > 1000 {
+            return x;
+        }
+    }
+}
+
+fn main() {
+    immediate_args(1, true, 2.5);
+
+    non_immediate_args(
+        BigStruct {
+            a: 3,
+            b: 4,
+            c: 5,
+            d: 6,
+            e: 7,
+            f: 8,
+            g: 9,
+            h: 10
+        },
+        BigStruct {
+            a: 11,
+            b: 12,
+            c: 13,
+            d: 14,
+            e: 15,
+            f: 16,
+            g: 17,
+            h: 18
+        }
+    );
+
+    binding(19, 20, 21.5);
+    assignment(22, 23, 24.5);
+    function_call(25, 26, 27.5);
+    identifier(28, 29, 30.5);
+    return_expr(31, 32, 33.5);
+    arithmetic_expr(34, 35, 36.5);
+    if_expr(37, 38, 39.5);
+    while_expr(40, 41, 42);
+    loop_expr(43, 44, 45);
+}
diff --git a/src/test/debuginfo/generic-function.rs b/src/test/debuginfo/generic-function.rs
new file mode 100644 (file)
index 0000000..9fe17f9
--- /dev/null
@@ -0,0 +1,63 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// gdb-command:finish
+// gdb-command:print *t0
+// gdb-check:$1 = 1
+// gdb-command:print *t1
+// gdb-check:$2 = 2.5
+// gdb-command:print ret
+// gdb-check:$3 = {{1, 2.5}, {2.5, 1}}
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print *t0
+// gdb-check:$4 = 3.5
+// gdb-command:print *t1
+// gdb-check:$5 = 4
+// gdb-command:print ret
+// gdb-check:$6 = {{3.5, 4}, {4, 3.5}}
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print *t0
+// gdb-check:$7 = 5
+// gdb-command:print *t1
+// gdb-check:$8 = {a = 6, b = 7.5}
+// gdb-command:print ret
+// gdb-check:$9 = {{5, {a = 6, b = 7.5}}, {{a = 6, b = 7.5}, 5}}
+// gdb-command:continue
+
+#[deriving(Clone)]
+struct Struct {
+    a: int,
+    b: f64
+}
+
+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/debuginfo/generic-functions-nested.rs b/src/test/debuginfo/generic-functions-nested.rs
new file mode 100644 (file)
index 0000000..1849ca1
--- /dev/null
@@ -0,0 +1,59 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$1 = -1
+// gdb-command:print y
+// gdb-check:$2 = 1
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$3 = -1
+// gdb-command:print y
+// gdb-check:$4 = 2.5
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$5 = -2.5
+// gdb-command:print y
+// gdb-check:$6 = 1
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$7 = -2.5
+// gdb-command:print y
+// gdb-check:$8 = 2.5
+// gdb-command: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/debuginfo/generic-method-on-generic-struct.rs b/src/test/debuginfo/generic-method-on-generic-struct.rs
new file mode 100644 (file)
index 0000000..ad088d9
--- /dev/null
@@ -0,0 +1,100 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// STACK BY REF
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$1 = {x = {8888, -8888}}
+// gdb-command:print arg1
+// gdb-check:$2 = -1
+// gdb-command:print/d arg2
+// gdb-check:$3 = -2
+// gdb-command:continue
+
+// STACK BY VAL
+// gdb-command:finish
+// gdb-command:print self
+// gdb-check:$4 = {x = {8888, -8888}}
+// gdb-command:print arg1
+// gdb-check:$5 = -3
+// gdb-command:print arg2
+// gdb-check:$6 = -4
+// gdb-command:continue
+
+// OWNED BY REF
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$7 = {x = 1234.5}
+// gdb-command:print arg1
+// gdb-check:$8 = -5
+// gdb-command:print arg2
+// gdb-check:$9 = -6
+// gdb-command:continue
+
+// OWNED BY VAL
+// gdb-command:finish
+// gdb-command:print self
+// gdb-check:$10 = {x = 1234.5}
+// gdb-command:print arg1
+// gdb-check:$11 = -7
+// gdb-command:print arg2
+// gdb-check:$12 = -8
+// gdb-command:continue
+
+// OWNED MOVED
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$13 = {x = 1234.5}
+// gdb-command:print arg1
+// gdb-check:$14 = -9
+// gdb-command:print arg2
+// gdb-check:$15 = -10.5
+// gdb-command: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 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 = box 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);
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/generic-static-method-on-struct-and-enum.rs b/src/test/debuginfo/generic-static-method-on-struct-and-enum.rs
new file mode 100644 (file)
index 0000000..82a9d70
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// STRUCT
+// gdb-command:finish
+// gdb-command:print arg1
+// gdb-check:$1 = 1
+// gdb-command:print arg2
+// gdb-check:$2 = 2
+// gdb-command:continue
+
+// ENUM
+// gdb-command:finish
+// gdb-command:print arg1
+// gdb-check:$3 = -3
+// gdb-command:print arg2
+// gdb-check:$4 = 4.5
+// gdb-command:print arg3
+// gdb-check:$5 = 5
+// gdb-command:continue
+
+#![feature(struct_variant)]
+
+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(f64, 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/debuginfo/generic-struct-style-enum.rs b/src/test/debuginfo/generic-struct-style-enum.rs
new file mode 100644 (file)
index 0000000..498d098
--- /dev/null
@@ -0,0 +1,80 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-tidy-linelength
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:set print union on
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print case1
+// gdb-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}}
+
+// gdb-command:print case2
+// gdb-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}}
+
+// gdb-command:print case3
+// gdb-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}}
+
+// gdb-command:print univariant
+// gdb-check:$4 = {a = -1}
+
+#![feature(struct_variant)]
+
+// 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/debuginfo/generic-struct.rs b/src/test/debuginfo/generic-struct.rs
new file mode 100644 (file)
index 0000000..69217f4
--- /dev/null
@@ -0,0 +1,42 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// gdb-command:finish
+// gdb-command:print int_int
+// gdb-check:$1 = {key = 0, value = 1}
+// gdb-command:print int_float
+// gdb-check:$2 = {key = 2, value = 3.5}
+// gdb-command:print float_int
+// gdb-check:$3 = {key = 4.5, value = 5}
+// gdb-command:print float_int_float
+// gdb-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/debuginfo/generic-trait-generic-static-default-method.rs b/src/test/debuginfo/generic-trait-generic-static-default-method.rs
new file mode 100644 (file)
index 0000000..904b22f
--- /dev/null
@@ -0,0 +1,53 @@
+// ignore-test
+
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// gdb-command:finish
+// gdb-command:print arg1
+// gdb-check:$1 = 1000
+// gdb-command:print *arg2
+// gdb-check:$2 = {1, 2.5}
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print arg1
+// gdb-check:$3 = 2000
+// gdb-command:print *arg2
+// gdb-check:$4 = {3.5, {4, 5, 6}}
+// gdb-command: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/debuginfo/generic-tuple-style-enum.rs b/src/test/debuginfo/generic-tuple-style-enum.rs
new file mode 100644 (file)
index 0000000..16a665c
--- /dev/null
@@ -0,0 +1,79 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-tidy-linelength
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:set print union on
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print case1
+// gdb-check:$1 = {{Case1, 0, 31868, 31868, 31868, 31868}, {Case1, 0, 2088533116, 2088533116}, {Case1, 0, 8970181431921507452}}
+
+// gdb-command:print case2
+// gdb-check:$2 = {{Case2, 0, 4369, 4369, 4369, 4369}, {Case2, 0, 286331153, 286331153}, {Case2, 0, 1229782938247303441}}
+
+// gdb-command:print case3
+// gdb-check:$3 = {{Case3, 0, 22873, 22873, 22873, 22873}, {Case3, 0, 1499027801, 1499027801}, {Case3, 0, 6438275382588823897}}
+
+// gdb-command:print univariant
+// gdb-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/debuginfo/include_string.rs b/src/test/debuginfo/include_string.rs
new file mode 100644 (file)
index 0000000..1d544dd
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+// gdb-command:print string1.length
+// gdb-check:$1 = 48
+// gdb-command:print string2.length
+// gdb-check:$2 = 48
+// gdb-command:print string3.length
+// gdb-check:$3 = 48
+// gdb-command:continue
+
+#![allow(unused_variable)]
+
+// This test case makes sure that debug info does not ICE when include_str is
+// used multiple times (see issue #11322).
+
+fn main() {
+    let string1 = include_str!("text-to-include-1.txt");
+    let string2 = include_str!("text-to-include-2.txt");
+    let string3 = include_str!("text-to-include-3.txt");
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/issue11600.rs b/src/test/debuginfo/issue11600.rs
new file mode 100644 (file)
index 0000000..426a40b
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This test was actually never run before because commands were only parsed up to the first
+// function definition but the test relied on the function being above the commands. Ignore for now.
+// ignore-test
+
+fn main() {
+    let args : ~[~str] = ::std::os::args();
+    ::std::io::println(args[0]);
+}
+
+// ignore-android: FIXME(#10381)
+
+// This test case checks whether compile unit names are set correctly, so that the correct default
+// source file can be found.
+
+// compile-flags:-g
+// gdb-command:list
+// gdb-check:1[...]fn main() {
+// gdb-check:2[...]let args : ~[~str] = ::std::os::args();
+// gdb-check:3[...]::std::io::println(args[0]);
+// gdb-check:4[...]}
diff --git a/src/test/debuginfo/issue12886.rs b/src/test/debuginfo/issue12886.rs
new file mode 100644 (file)
index 0000000..3b152cd
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:break issue12886.rs:29
+// gdb-command:run
+// gdb-command:next
+// gdb-check:[...]30[...]s
+// gdb-command:continue
+
+// IF YOU MODIFY THIS FILE, BE CAREFUL TO ADAPT THE LINE NUMBERS IN THE DEBUGGER COMMANDS
+
+// This test makes sure that gdb does not set unwanted breakpoints in inlined functions. If a
+// breakpoint existed in unwrap(), then calling `next` would (when stopped at line 27) would stop
+// in unwrap() instead of stepping over the function invocation. By making sure that `s` is
+// contained in the output, after calling `next` just once, we can be sure that we did not stop in
+// unwrap(). (The testing framework doesn't allow for checking that some text is *not* contained in
+// the output, which is why we have to make the test in this kind of roundabout way)
+fn bar() -> int {
+    let s = Some(5).unwrap();
+    s
+}
+
+fn main() {
+    let _ = bar();
+}
diff --git a/src/test/debuginfo/issue13213.rs b/src/test/debuginfo/issue13213.rs
new file mode 100644 (file)
index 0000000..a03b263
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// aux-build:issue13213aux.rs
+extern crate issue13213aux;
+
+// compile-flags:-g
+
+// This tests make sure that we get no linker error when using a completely inlined static. Some
+// statics that are marked with AvailableExternallyLinkage in the importing crate, may actually not
+// be available because they have been optimized out from the exporting crate.
+fn main() {
+    let b: issue13213aux::S = issue13213aux::A;
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/issue7712.rs b/src/test/debuginfo/issue7712.rs
new file mode 100644 (file)
index 0000000..8308afc
--- /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.
+
+// compile-flags:--debuginfo=1
+
+pub trait TraitWithDefaultMethod {
+    fn method(self) {
+        ()
+    }
+}
+
+struct MyStruct;
+
+impl TraitWithDefaultMethod for MyStruct { }
+
+pub fn main() {
+    MyStruct.method();
+}
diff --git a/src/test/debuginfo/lexical-scope-in-for-loop.rs b/src/test/debuginfo/lexical-scope-in-for-loop.rs
new file mode 100644 (file)
index 0000000..0f6ac95
--- /dev/null
@@ -0,0 +1,77 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// FIRST ITERATION
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$1 = 1
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$2 = -1
+// gdb-command:continue
+
+// SECOND ITERATION
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$3 = 2
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$4 = -2
+// gdb-command:continue
+
+// THIRD ITERATION
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$5 = 3
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$6 = -3
+// gdb-command:continue
+
+// AFTER LOOP
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$7 = 1000000
+// gdb-command:continue
+
+fn main() {
+
+    let range = [1, 2, 3];
+
+    let x = 1000000; // wan meeeljen doollaars!
+
+    for &x in range.iter() {
+        zzz();
+        sentinel();
+
+        let x = -1 * x;
+
+        zzz();
+        sentinel();
+    }
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debuginfo/lexical-scope-in-if.rs b/src/test/debuginfo/lexical-scope-in-if.rs
new file mode 100644 (file)
index 0000000..ef57373
--- /dev/null
@@ -0,0 +1,126 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// BEFORE if
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$1 = 999
+// gdb-command:print y
+// gdb-check:$2 = -1
+// gdb-command:continue
+
+// AT BEGINNING of 'then' block
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$3 = 999
+// gdb-command:print y
+// gdb-check:$4 = -1
+// gdb-command:continue
+
+// AFTER 1st redeclaration of 'x'
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$5 = 1001
+// gdb-command:print y
+// gdb-check:$6 = -1
+// gdb-command:continue
+
+// AFTER 2st redeclaration of 'x'
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$7 = 1002
+// gdb-command:print y
+// gdb-check:$8 = 1003
+// gdb-command:continue
+
+// AFTER 1st if expression
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$9 = 999
+// gdb-command:print y
+// gdb-check:$10 = -1
+// gdb-command:continue
+
+// BEGINNING of else branch
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$11 = 999
+// gdb-command:print y
+// gdb-check:$12 = -1
+// gdb-command:continue
+
+// BEGINNING of else branch
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$13 = 1004
+// gdb-command:print y
+// gdb-check:$14 = 1005
+// gdb-command:continue
+
+// BEGINNING of else branch
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$15 = 999
+// gdb-command:print y
+// gdb-check:$16 = -1
+// gdb-command:continue
+
+fn main() {
+
+    let x = 999;
+    let y = -1;
+
+    zzz();
+    sentinel();
+
+    if x < 1000 {
+        zzz();
+        sentinel();
+
+        let x = 1001;
+
+        zzz();
+        sentinel();
+
+        let x = 1002;
+        let y = 1003;
+        zzz();
+        sentinel();
+    } else {
+        unreachable!();
+    }
+
+    zzz();
+    sentinel();
+
+    if x > 1000 {
+        unreachable!();
+    } else {
+        zzz();
+        sentinel();
+
+        let x = 1004;
+        let y = 1005;
+        zzz();
+        sentinel();
+    }
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debuginfo/lexical-scope-in-match.rs b/src/test/debuginfo/lexical-scope-in-match.rs
new file mode 100644 (file)
index 0000000..5f13c78
--- /dev/null
@@ -0,0 +1,148 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// gdb-command:finish
+// gdb-command:print shadowed
+// gdb-check:$1 = 231
+// gdb-command:print not_shadowed
+// gdb-check:$2 = 232
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print shadowed
+// gdb-check:$3 = 233
+// gdb-command:print not_shadowed
+// gdb-check:$4 = 232
+// gdb-command:print local_to_arm
+// gdb-check:$5 = 234
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print shadowed
+// gdb-check:$6 = 236
+// gdb-command:print not_shadowed
+// gdb-check:$7 = 232
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print shadowed
+// gdb-check:$8 = 237
+// gdb-command:print not_shadowed
+// gdb-check:$9 = 232
+// gdb-command:print local_to_arm
+// gdb-check:$10 = 238
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print shadowed
+// gdb-check:$11 = 239
+// gdb-command:print not_shadowed
+// gdb-check:$12 = 232
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print shadowed
+// gdb-check:$13 = 241
+// gdb-command:print not_shadowed
+// gdb-check:$14 = 232
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print shadowed
+// gdb-check:$15 = 243
+// gdb-command:print *local_to_arm
+// gdb-check:$16 = 244
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print shadowed
+// gdb-check:$17 = 231
+// gdb-command:print not_shadowed
+// gdb-check:$18 = 232
+// gdb-command:continue
+
+struct Struct {
+    x: int,
+    y: int
+}
+
+fn main() {
+
+    let shadowed = 231;
+    let not_shadowed = 232;
+
+    zzz();
+    sentinel();
+
+    match (233, 234) {
+        (shadowed, local_to_arm) => {
+
+            zzz();
+            sentinel();
+        }
+    }
+
+    match (235, 236) {
+        // with literal
+        (235, shadowed) => {
+
+            zzz();
+            sentinel();
+        }
+        _ => {}
+    }
+
+    match Struct { x: 237, y: 238 } {
+        Struct { x: shadowed, y: local_to_arm } => {
+
+            zzz();
+            sentinel();
+        }
+    }
+
+    match Struct { x: 239, y: 240 } {
+        // ignored field
+        Struct { x: shadowed, .. } => {
+
+            zzz();
+            sentinel();
+        }
+    }
+
+    match Struct { x: 241, y: 242 } {
+        // with literal
+        Struct { x: shadowed, y: 242 } => {
+
+            zzz();
+            sentinel();
+        }
+        _ => {}
+    }
+
+    match (243, 244) {
+        (shadowed, ref local_to_arm) => {
+
+            zzz();
+            sentinel();
+        }
+    }
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debuginfo/lexical-scope-in-parameterless-closure.rs b/src/test/debuginfo/lexical-scope-in-parameterless-closure.rs
new file mode 100644 (file)
index 0000000..ad8f04d
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:--debuginfo=1
+// gdb-command:run
+
+// Nothing to do here really, just make sure it compiles. See issue #8513.
+fn main() {
+    let _ = ||();
+    let _ = range(1u,3).map(|_| 5);
+}
+
diff --git a/src/test/debuginfo/lexical-scope-in-stack-closure.rs b/src/test/debuginfo/lexical-scope-in-stack-closure.rs
new file mode 100644 (file)
index 0000000..c56cdbe
--- /dev/null
@@ -0,0 +1,79 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$1 = false
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$2 = false
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$3 = 1000
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$4 = 2.5
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$5 = true
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$6 = false
+// gdb-command:continue
+
+fn main() {
+
+    let x = false;
+
+    zzz();
+    sentinel();
+
+    let stack_closure: |int| = |x| {
+        zzz();
+        sentinel();
+
+        let x = 2.5;
+
+        zzz();
+        sentinel();
+
+        let x = true;
+
+        zzz();
+        sentinel();
+    };
+
+    zzz();
+    sentinel();
+
+    stack_closure(1000);
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debuginfo/lexical-scope-in-unconditional-loop.rs b/src/test/debuginfo/lexical-scope-in-unconditional-loop.rs
new file mode 100644 (file)
index 0000000..12e95c4
--- /dev/null
@@ -0,0 +1,127 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// FIRST ITERATION
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$1 = 0
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$2 = 1
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$3 = 101
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$4 = 101
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$5 = -987
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$6 = 101
+// gdb-command:continue
+
+
+// SECOND ITERATION
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$7 = 1
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$8 = 2
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$9 = 102
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$10 = 102
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$11 = -987
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$12 = 102
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$13 = 2
+// gdb-command:continue
+
+fn main() {
+
+    let mut x = 0;
+
+    loop {
+        if x >= 2 {
+            break;
+        }
+
+        zzz();
+        sentinel();
+
+        x += 1;
+        zzz();
+        sentinel();
+
+        // Shadow x
+        let x = x + 100;
+        zzz();
+        sentinel();
+
+        // open scope within loop's top level scope
+        {
+            zzz();
+            sentinel();
+
+            let x = -987;
+
+            zzz();
+            sentinel();
+        }
+
+        // Check that we get the x before the inner scope again
+        zzz();
+        sentinel();
+    }
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debuginfo/lexical-scope-in-unique-closure.rs b/src/test/debuginfo/lexical-scope-in-unique-closure.rs
new file mode 100644 (file)
index 0000000..328910b
--- /dev/null
@@ -0,0 +1,79 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$1 = false
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$2 = false
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$3 = 1000
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$4 = 2.5
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$5 = true
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$6 = false
+// gdb-command:continue
+
+fn main() {
+
+    let x = false;
+
+    zzz();
+    sentinel();
+
+    let unique_closure: proc(int) = proc(x) {
+        zzz();
+        sentinel();
+
+        let x = 2.5;
+
+        zzz();
+        sentinel();
+
+        let x = true;
+
+        zzz();
+        sentinel();
+    };
+
+    zzz();
+    sentinel();
+
+    unique_closure(1000);
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debuginfo/lexical-scope-in-while.rs b/src/test/debuginfo/lexical-scope-in-while.rs
new file mode 100644 (file)
index 0000000..1b2a9f7
--- /dev/null
@@ -0,0 +1,123 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// FIRST ITERATION
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$1 = 0
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$2 = 1
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$3 = 101
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$4 = 101
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$5 = -987
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$6 = 101
+// gdb-command:continue
+
+
+// SECOND ITERATION
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$7 = 1
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$8 = 2
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$9 = 102
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$10 = 102
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$11 = -987
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$12 = 102
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$13 = 2
+// gdb-command:continue
+
+fn main() {
+
+    let mut x = 0;
+
+    while x < 2 {
+        zzz();
+        sentinel();
+
+        x += 1;
+        zzz();
+        sentinel();
+
+        // Shadow x
+        let x = x + 100;
+        zzz();
+        sentinel();
+
+        // open scope within loop's top level scope
+        {
+            zzz();
+            sentinel();
+
+            let x = -987;
+
+            zzz();
+            sentinel();
+        }
+
+        // Check that we get the x before the inner scope again
+        zzz();
+        sentinel();
+    }
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debuginfo/lexical-scope-with-macro.rs b/src/test/debuginfo/lexical-scope-with-macro.rs
new file mode 100644 (file)
index 0000000..3fb6f10
--- /dev/null
@@ -0,0 +1,131 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// gdb-command:finish
+// gdb-command:print a
+// gdb-check:$1 = 10
+// gdb-command:print b
+// gdb-check:$2 = 34
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print a
+// gdb-check:$3 = 890242
+// gdb-command:print b
+// gdb-check:$4 = 34
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print a
+// gdb-check:$5 = 10
+// gdb-command:print b
+// gdb-check:$6 = 34
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print a
+// gdb-check:$7 = 102
+// gdb-command:print b
+// gdb-check:$8 = 34
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print a
+// gdb-check:$9 = 110
+// gdb-command:print b
+// gdb-check:$10 = 34
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print a
+// gdb-check:$11 = 10
+// gdb-command:print b
+// gdb-check:$12 = 34
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print a
+// gdb-check:$13 = 10
+// gdb-command:print b
+// gdb-check:$14 = 34
+// gdb-command:print c
+// gdb-check:$15 = 400
+// gdb-command:continue
+
+#![feature(macro_rules)]
+
+macro_rules! trivial(
+    ($e1:expr) => ($e1)
+)
+
+macro_rules! no_new_scope(
+    ($e1:expr) => (($e1 + 2) - 1)
+)
+
+macro_rules! new_scope(
+    () => ({
+        let a = 890242;
+        zzz();
+        sentinel();
+    })
+)
+
+macro_rules! shadow_within_macro(
+    ($e1:expr) => ({
+        let a = $e1 + 2;
+
+        zzz();
+        sentinel();
+
+        let a = $e1 + 10;
+
+        zzz();
+        sentinel();
+    })
+)
+
+
+macro_rules! dup_expr(
+    ($e1:expr) => (($e1) + ($e1))
+)
+
+
+fn main() {
+
+    let a = trivial!(10);
+    let b = no_new_scope!(33);
+
+    zzz();
+    sentinel();
+
+    new_scope!();
+
+    zzz();
+    sentinel();
+
+    shadow_within_macro!(100);
+
+    zzz();
+    sentinel();
+
+    let c = dup_expr!(10 * 20);
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debuginfo/lexical-scopes-in-block-expression.rs b/src/test/debuginfo/lexical-scopes-in-block-expression.rs
new file mode 100644 (file)
index 0000000..41b88dc
--- /dev/null
@@ -0,0 +1,377 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-win32: FIXME #13256
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// gdb-command:print 'lexical-scopes-in-block-expression::MUT_INT'
+// gdb-check:$1 = 0
+
+// STRUCT EXPRESSION
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$2 = -1
+// gdb-command:print ten
+// gdb-check:$3 = 10
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$4 = 11
+// gdb-command:print 'lexical-scopes-in-block-expression::MUT_INT'
+// gdb-check:$5 = 1
+// gdb-command:print ten
+// gdb-check:$6 = 10
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$7 = -1
+// gdb-command:print ten
+// gdb-check:$8 = 10
+// gdb-command:continue
+
+// FUNCTION CALL
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$9 = -1
+// gdb-command:print ten
+// gdb-check:$10 = 10
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$11 = 12
+// gdb-command:print 'lexical-scopes-in-block-expression::MUT_INT'
+// gdb-check:$12 = 2
+// gdb-command:print ten
+// gdb-check:$13 = 10
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$14 = -1
+// gdb-command:print ten
+// gdb-check:$15 = 10
+// gdb-command:continue
+
+// TUPLE EXPRESSION
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$16 = -1
+// gdb-command:print ten
+// gdb-check:$17 = 10
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$18 = 13
+// gdb-command:print 'lexical-scopes-in-block-expression::MUT_INT'
+// gdb-check:$19 = 3
+// gdb-command:print ten
+// gdb-check:$20 = 10
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$21 = -1
+// gdb-command:print ten
+// gdb-check:$22 = 10
+// gdb-command:continue
+
+// VEC EXPRESSION
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$23 = -1
+// gdb-command:print ten
+// gdb-check:$24 = 10
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$25 = 14
+// gdb-command:print 'lexical-scopes-in-block-expression::MUT_INT'
+// gdb-check:$26 = 4
+// gdb-command:print ten
+// gdb-check:$27 = 10
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$28 = -1
+// gdb-command:print ten
+// gdb-check:$29 = 10
+// gdb-command:continue
+
+// REPEAT VEC EXPRESSION
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$30 = -1
+// gdb-command:print ten
+// gdb-check:$31 = 10
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$32 = 15
+// gdb-command:print 'lexical-scopes-in-block-expression::MUT_INT'
+// gdb-check:$33 = 5
+// gdb-command:print ten
+// gdb-check:$34 = 10
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$35 = -1
+// gdb-command:print ten
+// gdb-check:$36 = 10
+// gdb-command:continue
+
+// ASSIGNMENT EXPRESSION
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$37 = -1
+// gdb-command:print ten
+// gdb-check:$38 = 10
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$39 = 16
+// gdb-command:print 'lexical-scopes-in-block-expression::MUT_INT'
+// gdb-check:$40 = 6
+// gdb-command:print ten
+// gdb-check:$41 = 10
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$42 = -1
+// gdb-command:print ten
+// gdb-check:$43 = 10
+// gdb-command:continue
+
+
+// ARITHMETIC EXPRESSION
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$44 = -1
+// gdb-command:print ten
+// gdb-check:$45 = 10
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$46 = 17
+// gdb-command:print 'lexical-scopes-in-block-expression::MUT_INT'
+// gdb-check:$47 = 7
+// gdb-command:print ten
+// gdb-check:$48 = 10
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$49 = -1
+// gdb-command:print ten
+// gdb-check:$50 = 10
+// gdb-command:continue
+
+// INDEX EXPRESSION
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$51 = -1
+// gdb-command:print ten
+// gdb-check:$52 = 10
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$53 = 18
+// gdb-command:print 'lexical-scopes-in-block-expression::MUT_INT'
+// gdb-check:$54 = 8
+// gdb-command:print ten
+// gdb-check:$55 = 10
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print val
+// gdb-check:$56 = -1
+// gdb-command:print ten
+// gdb-check:$57 = 10
+// gdb-command:continue
+
+#![allow(unused_variable)]
+#![allow(dead_assignment)]
+
+static mut MUT_INT: int = 0;
+
+struct Point {
+    x: int,
+    y: int
+}
+
+fn a_function(x: int) -> int {
+    x + 1
+}
+
+fn main() {
+
+    let val = -1;
+    let ten = 10;
+
+    // surrounded by struct expression
+    let point = Point {
+        x: {
+            zzz();
+            sentinel();
+
+            let val = ten + 1;
+            unsafe {MUT_INT = 1;};
+
+            zzz();
+            sentinel();
+
+            val
+        },
+        y: 10
+    };
+
+    zzz();
+    sentinel();
+
+    // surrounded by function call
+    let _ = a_function({
+        zzz();
+        sentinel();
+
+        let val = ten + 2;
+        unsafe {MUT_INT = 2;};
+
+        zzz();
+        sentinel();
+
+        val
+    });
+
+    zzz();
+    sentinel();
+
+
+    // surrounded by tup
+    let _ = ({
+        zzz();
+        sentinel();
+
+        let val = ten + 3;
+        unsafe {MUT_INT = 3;};
+
+        zzz();
+        sentinel();
+
+        val
+    }, 0);
+
+    zzz();
+    sentinel();
+
+    // surrounded by vec
+    let _ = [{
+        zzz();
+        sentinel();
+
+        let val = ten + 4;
+        unsafe {MUT_INT = 4;};
+
+        zzz();
+        sentinel();
+
+        val
+    }, 0, 0];
+
+    zzz();
+    sentinel();
+
+    // surrounded by repeat vec
+    let _ = [{
+        zzz();
+        sentinel();
+
+        let val = ten + 5;
+        unsafe {MUT_INT = 5;};
+
+        zzz();
+        sentinel();
+
+        val
+    }, ..10];
+
+    zzz();
+    sentinel();
+
+    // assignment expression
+    let mut var = 0;
+    var = {
+        zzz();
+        sentinel();
+
+        let val = ten + 6;
+        unsafe {MUT_INT = 6;};
+
+        zzz();
+        sentinel();
+
+        val
+    };
+
+    zzz();
+    sentinel();
+
+    // arithmetic expression
+    var = 10 + -{
+        zzz();
+        sentinel();
+
+        let val = ten + 7;
+        unsafe {MUT_INT = 7;};
+
+        zzz();
+        sentinel();
+
+        val
+    } * 5;
+
+    zzz();
+    sentinel();
+
+    // index expression
+    let a_vector = [10, ..20];
+    let _ = a_vector[{
+        zzz();
+        sentinel();
+
+        let val = ten + 8;
+        unsafe {MUT_INT = 8;};
+
+        zzz();
+        sentinel();
+
+        val as uint
+    }];
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debuginfo/limited-debuginfo.rs b/src/test/debuginfo/limited-debuginfo.rs
new file mode 100644 (file)
index 0000000..616f312
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:--debuginfo=1
+
+// Make sure functions have proper names
+// gdb-command:info functions
+// gdb-check:[...]void[...]main([...]);
+// gdb-check:[...]void[...]some_function([...]);
+// gdb-check:[...]void[...]some_other_function([...]);
+// gdb-check:[...]void[...]zzz([...]);
+
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// Make sure there is no information about locals
+// gdb-command:finish
+// gdb-command:info locals
+// gdb-check:No locals.
+// gdb-command:continue
+
+
+#![allow(unused_variable)]
+
+struct Struct {
+    a: i64,
+    b: i32
+}
+
+fn main() {
+    some_function(101, 202);
+    some_other_function(1, 2);
+}
+
+
+fn zzz() {()}
+
+fn some_function(a: int, b: int) {
+    let some_variable = Struct { a: 11, b: 22 };
+    let some_other_variable = 23;
+    zzz();
+}
+
+fn some_other_function(a: int, b: int) -> bool { true }
diff --git a/src/test/debuginfo/managed-enum.rs b/src/test/debuginfo/managed-enum.rs
new file mode 100644 (file)
index 0000000..7899e0c
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print the_a->val
+// gdb-check:$1 = {{TheA, x = 0, y = 8970181431921507452}, {TheA, 0, 2088533116, 2088533116}}
+
+// gdb-command:print the_b->val
+// gdb-check:$2 = {{TheB, x = 0, y = 1229782938247303441}, {TheB, 0, 286331153, 286331153}}
+
+// gdb-command:print univariant->val
+// gdb-check:$3 = {-9747455}
+
+#![allow(unused_variable)]
+#![feature(struct_variant, managed_boxes)]
+
+// 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 ABC {
+    TheA { x: i64, y: i64 },
+    TheB (i64, i32, i32),
+}
+
+// This is a special case since it does not have the implicit discriminant field.
+enum Univariant {
+    TheOnlyCase(i64)
+}
+
+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 the_a = @TheA { x: 0, y: 8970181431921507452 };
+
+    // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
+    // 0b00010001000100010001000100010001 = 286331153
+    // 0b0001000100010001 = 4369
+    // 0b00010001 = 17
+    let the_b = @TheB (0, 286331153, 286331153);
+
+    let univariant = @TheOnlyCase(-9747455);
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/managed-pointer-within-unique-vec.rs b/src/test/debuginfo/managed-pointer-within-unique-vec.rs
new file mode 100644 (file)
index 0000000..a2a0d17
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+#![feature(managed_boxes)]
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print unique.ptr[0]->val
+// gdb-check:$1 = 10
+
+// gdb-command:print unique.ptr[1]->val
+// gdb-check:$2 = 11
+
+// gdb-command:print unique.ptr[2]->val
+// gdb-check:$3 = 12
+
+// gdb-command:print unique.ptr[3]->val
+// gdb-check:$4 = 13
+
+#![allow(unused_variable)]
+
+fn main() {
+
+    let unique: Vec<@i64> = vec!(@10, @11, @12, @13);
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/managed-pointer-within-unique.rs b/src/test/debuginfo/managed-pointer-within-unique.rs
new file mode 100644 (file)
index 0000000..be2cc69
--- /dev/null
@@ -0,0 +1,45 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+#![feature(managed_boxes)]
+
+// compile-flags:-g
+// gdb-command:set print pretty off
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print *ordinary_unique
+// gdb-check:$1 = {-1, -2}
+
+// gdb-command:print managed_within_unique->x
+// gdb-check:$2 = -3
+
+// gdb-command:print managed_within_unique->y->val
+// gdb-check:$3 = -4
+
+#![allow(unused_variable)]
+
+struct ContainsManaged {
+    x: int,
+    y: @int
+}
+
+fn main() {
+    let ordinary_unique = box() (-1, -2);
+
+    let managed_within_unique = box ContainsManaged { x: -3, y: @-4 };
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/method-on-enum.rs b/src/test/debuginfo/method-on-enum.rs
new file mode 100644 (file)
index 0000000..1a5fac1
--- /dev/null
@@ -0,0 +1,103 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// STACK BY REF
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$1 = {{Variant2, [...]}, {Variant2, 117901063}}
+// gdb-command:print arg1
+// gdb-check:$2 = -1
+// gdb-command:print arg2
+// gdb-check:$3 = -2
+// gdb-command:continue
+
+// STACK BY VAL
+// gdb-command:finish
+// gdb-command:print self
+// gdb-check:$4 = {{Variant2, [...]}, {Variant2, 117901063}}
+// gdb-command:print arg1
+// gdb-check:$5 = -3
+// gdb-command:print arg2
+// gdb-check:$6 = -4
+// gdb-command:continue
+
+// OWNED BY REF
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$7 = {{Variant1, x = 1799, y = 1799}, {Variant1, [...]}}
+// gdb-command:print arg1
+// gdb-check:$8 = -5
+// gdb-command:print arg2
+// gdb-check:$9 = -6
+// gdb-command:continue
+
+// OWNED BY VAL
+// gdb-command:finish
+// gdb-command:print self
+// gdb-check:$10 = {{Variant1, x = 1799, y = 1799}, {Variant1, [...]}}
+// gdb-command:print arg1
+// gdb-check:$11 = -7
+// gdb-command:print arg2
+// gdb-check:$12 = -8
+// gdb-command:continue
+
+// OWNED MOVED
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$13 = {{Variant1, x = 1799, y = 1799}, {Variant1, [...]}}
+// gdb-command:print arg1
+// gdb-check:$14 = -9
+// gdb-command:print arg2
+// gdb-check:$15 = -10
+// gdb-command:continue
+
+#![feature(struct_variant)]
+
+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 main() {
+    let stack = Variant2(117901063);
+    let _ = stack.self_by_ref(-1, -2);
+    let _ = stack.self_by_val(-3, -4);
+
+    let owned = box 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);
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/method-on-generic-struct.rs b/src/test/debuginfo/method-on-generic-struct.rs
new file mode 100644 (file)
index 0000000..2f7b0c8
--- /dev/null
@@ -0,0 +1,100 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// STACK BY REF
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$1 = {x = {8888, -8888}}
+// gdb-command:print arg1
+// gdb-check:$2 = -1
+// gdb-command:print arg2
+// gdb-check:$3 = -2
+// gdb-command:continue
+
+// STACK BY VAL
+// gdb-command:finish
+// gdb-command:print self
+// gdb-check:$4 = {x = {8888, -8888}}
+// gdb-command:print arg1
+// gdb-check:$5 = -3
+// gdb-command:print arg2
+// gdb-check:$6 = -4
+// gdb-command:continue
+
+// OWNED BY REF
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$7 = {x = 1234.5}
+// gdb-command:print arg1
+// gdb-check:$8 = -5
+// gdb-command:print arg2
+// gdb-check:$9 = -6
+// gdb-command:continue
+
+// OWNED BY VAL
+// gdb-command:finish
+// gdb-command:print self
+// gdb-check:$10 = {x = 1234.5}
+// gdb-command:print arg1
+// gdb-check:$11 = -7
+// gdb-command:print arg2
+// gdb-check:$12 = -8
+// gdb-command:continue
+
+// OWNED MOVED
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$13 = {x = 1234.5}
+// gdb-command:print arg1
+// gdb-check:$14 = -9
+// gdb-command:print arg2
+// gdb-check:$15 = -10
+// gdb-command: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 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 = box Struct { x: 1234.5 };
+    let _ = owned.self_by_ref(-5, -6);
+    let _ = owned.self_by_val(-7, -8);
+    let _ = owned.self_owned(-9, -10);
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/method-on-struct.rs b/src/test/debuginfo/method-on-struct.rs
new file mode 100644 (file)
index 0000000..3d7cc96
--- /dev/null
@@ -0,0 +1,100 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// STACK BY REF
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$1 = {x = 100}
+// gdb-command:print arg1
+// gdb-check:$2 = -1
+// gdb-command:print arg2
+// gdb-check:$3 = -2
+// gdb-command:continue
+
+// STACK BY VAL
+// gdb-command:finish
+// gdb-command:print self
+// gdb-check:$4 = {x = 100}
+// gdb-command:print arg1
+// gdb-check:$5 = -3
+// gdb-command:print arg2
+// gdb-check:$6 = -4
+// gdb-command:continue
+
+// OWNED BY REF
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$7 = {x = 200}
+// gdb-command:print arg1
+// gdb-check:$8 = -5
+// gdb-command:print arg2
+// gdb-check:$9 = -6
+// gdb-command:continue
+
+// OWNED BY VAL
+// gdb-command:finish
+// gdb-command:print self
+// gdb-check:$10 = {x = 200}
+// gdb-command:print arg1
+// gdb-check:$11 = -7
+// gdb-command:print arg2
+// gdb-check:$12 = -8
+// gdb-command:continue
+
+// OWNED MOVED
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$13 = {x = 200}
+// gdb-command:print arg1
+// gdb-check:$14 = -9
+// gdb-command:print arg2
+// gdb-check:$15 = -10
+// gdb-command: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 main() {
+    let stack = Struct { x: 100 };
+    let _ = stack.self_by_ref(-1, -2);
+    let _ = stack.self_by_val(-3, -4);
+
+    let owned = box Struct { x: 200 };
+    let _ = owned.self_by_ref(-5, -6);
+    let _ = owned.self_by_val(-7, -8);
+    let _ = owned.self_owned(-9, -10);
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/method-on-trait.rs b/src/test/debuginfo/method-on-trait.rs
new file mode 100644 (file)
index 0000000..a2b7362
--- /dev/null
@@ -0,0 +1,106 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// STACK BY REF
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$1 = {x = 100}
+// gdb-command:print arg1
+// gdb-check:$2 = -1
+// gdb-command:print arg2
+// gdb-check:$3 = -2
+// gdb-command:continue
+
+// STACK BY VAL
+// gdb-command:finish
+// gdb-command:print self
+// gdb-check:$4 = {x = 100}
+// gdb-command:print arg1
+// gdb-check:$5 = -3
+// gdb-command:print arg2
+// gdb-check:$6 = -4
+// gdb-command:continue
+
+// OWNED BY REF
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$7 = {x = 200}
+// gdb-command:print arg1
+// gdb-check:$8 = -5
+// gdb-command:print arg2
+// gdb-check:$9 = -6
+// gdb-command:continue
+
+// OWNED BY VAL
+// gdb-command:finish
+// gdb-command:print self
+// gdb-check:$10 = {x = 200}
+// gdb-command:print arg1
+// gdb-check:$11 = -7
+// gdb-command:print arg2
+// gdb-check:$12 = -8
+// gdb-command:continue
+
+// OWNED MOVED
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$13 = {x = 200}
+// gdb-command:print arg1
+// gdb-check:$14 = -9
+// gdb-command:print arg2
+// gdb-check:$15 = -10
+// gdb-command: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;
+}
+
+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 main() {
+    let stack = Struct { x: 100 };
+    let _ = stack.self_by_ref(-1, -2);
+    let _ = stack.self_by_val(-3, -4);
+
+    let owned = box Struct { x: 200 };
+    let _ = owned.self_by_ref(-5, -6);
+    let _ = owned.self_by_val(-7, -8);
+    let _ = owned.self_owned(-9, -10);
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/method-on-tuple-struct.rs b/src/test/debuginfo/method-on-tuple-struct.rs
new file mode 100644 (file)
index 0000000..fe72717
--- /dev/null
@@ -0,0 +1,98 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// STACK BY REF
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$1 = {100, -100.5}
+// gdb-command:print arg1
+// gdb-check:$2 = -1
+// gdb-command:print arg2
+// gdb-check:$3 = -2
+// gdb-command:continue
+
+// STACK BY VAL
+// gdb-command:finish
+// gdb-command:print self
+// gdb-check:$4 = {100, -100.5}
+// gdb-command:print arg1
+// gdb-check:$5 = -3
+// gdb-command:print arg2
+// gdb-check:$6 = -4
+// gdb-command:continue
+
+// OWNED BY REF
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$7 = {200, -200.5}
+// gdb-command:print arg1
+// gdb-check:$8 = -5
+// gdb-command:print arg2
+// gdb-check:$9 = -6
+// gdb-command:continue
+
+// OWNED BY VAL
+// gdb-command:finish
+// gdb-command:print self
+// gdb-check:$10 = {200, -200.5}
+// gdb-command:print arg1
+// gdb-check:$11 = -7
+// gdb-command:print arg2
+// gdb-check:$12 = -8
+// gdb-command:continue
+
+// OWNED MOVED
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$13 = {200, -200.5}
+// gdb-command:print arg1
+// gdb-check:$14 = -9
+// gdb-command:print arg2
+// gdb-check:$15 = -10
+// gdb-command:continue
+
+struct TupleStruct(int, f64);
+
+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 main() {
+    let stack = TupleStruct(100, -100.5);
+    let _ = stack.self_by_ref(-1, -2);
+    let _ = stack.self_by_val(-3, -4);
+
+    let owned = box TupleStruct(200, -200.5);
+    let _ = owned.self_by_ref(-5, -6);
+    let _ = owned.self_by_val(-7, -8);
+    let _ = owned.self_owned(-9, -10);
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/multiple-functions-equal-var-names.rs b/src/test/debuginfo/multiple-functions-equal-var-names.rs
new file mode 100644 (file)
index 0000000..5107182
--- /dev/null
@@ -0,0 +1,56 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print abc
+// gdb-check:$1 = 10101
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print abc
+// gdb-check:$2 = 20202
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print abc
+// gdb-check:$3 = 30303
+
+#![allow(unused_variable)]
+
+fn function_one() {
+    let abc = 10101;
+    zzz();
+}
+
+fn function_two() {
+    let abc = 20202;
+    zzz();
+}
+
+
+fn function_three() {
+    let abc = 30303;
+    zzz();
+}
+
+
+fn main() {
+    function_one();
+    function_two();
+    function_three();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/multiple-functions.rs b/src/test/debuginfo/multiple-functions.rs
new file mode 100644 (file)
index 0000000..362a8a9
--- /dev/null
@@ -0,0 +1,56 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print a
+// gdb-check:$1 = 10101
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print b
+// gdb-check:$2 = 20202
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print c
+// gdb-check:$3 = 30303
+
+#![allow(unused_variable)]
+
+fn function_one() {
+    let a = 10101;
+    zzz();
+}
+
+fn function_two() {
+    let b = 20202;
+    zzz();
+}
+
+
+fn function_three() {
+    let c = 30303;
+    zzz();
+}
+
+
+fn main() {
+    function_one();
+    function_two();
+    function_three();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/name-shadowing-and-scope-nesting.rs b/src/test/debuginfo/name-shadowing-and-scope-nesting.rs
new file mode 100644 (file)
index 0000000..f967ced
--- /dev/null
@@ -0,0 +1,95 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$1 = false
+// gdb-command:print y
+// gdb-check:$2 = true
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$3 = 10
+// gdb-command:print y
+// gdb-check:$4 = true
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$5 = 10.5
+// gdb-command:print y
+// gdb-check:$6 = 20
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$7 = true
+// gdb-command:print y
+// gdb-check:$8 = 2220
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$9 = 203203.5
+// gdb-command:print y
+// gdb-check:$10 = 2220
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$11 = 10.5
+// gdb-command:print y
+// gdb-check:$12 = 20
+// gdb-command:continue
+
+fn main() {
+    let x = false;
+    let y = true;
+
+    zzz();
+    sentinel();
+
+    let x = 10;
+
+    zzz();
+    sentinel();
+
+    let x = 10.5;
+    let y = 20;
+
+    zzz();
+    sentinel();
+
+    {
+        let x = true;
+        let y = 2220;
+
+        zzz();
+        sentinel();
+
+        let x = 203203.5;
+
+        zzz();
+        sentinel();
+    }
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debuginfo/nil-enum.rs b/src/test/debuginfo/nil-enum.rs
new file mode 100644 (file)
index 0000000..67c7eb3
--- /dev/null
@@ -0,0 +1,42 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print first
+// gdb-check:$1 = {<No data fields>}
+
+// gdb-command:print second
+// gdb-check:$2 = {<No data fields>}
+
+#![allow(unused_variable)]
+
+enum ANilEnum {}
+enum AnotherNilEnum {}
+
+// I (mw) am not sure this test case makes much sense...
+// Also, it relies on some implementation details:
+// 1. That empty enums as well as '()' are represented as empty structs
+// 2. That gdb prints the string "{<No data fields>}" for empty structs (which may change some time)
+fn main() {
+    unsafe {
+        let first: ANilEnum = std::cast::transmute(());
+        let second: AnotherNilEnum = std::cast::transmute(());
+
+        zzz();
+    }
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/option-like-enum.rs b/src/test/debuginfo/option-like-enum.rs
new file mode 100644 (file)
index 0000000..b60c9c4
--- /dev/null
@@ -0,0 +1,91 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print some
+// gdb-check:$1 = {0x12345678}
+
+// gdb-command:print none
+// gdb-check:$2 = {0x0}
+
+// gdb-command:print full
+// gdb-check:$3 = {454545, 0x87654321, 9988}
+
+// gdb-command:print empty->discr
+// gdb-check:$4 = (int *) 0x0
+
+// gdb-command:print droid
+// gdb-check:$5 = {id = 675675, range = 10000001, internals = 0x43218765}
+
+// gdb-command:print void_droid->internals
+// gdb-check:$6 = (int *) 0x0
+
+// gdb-command:continue
+
+#![feature(struct_variant)]
+
+// 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<'a> {
+    Full(u32, &'a int, i16),
+    Empty
+}
+
+struct MoreFieldsRepr<'a> {
+    a: u32,
+    discr: &'a int,
+    b: i16
+}
+
+enum NamedFields<'a> {
+    Droid { id: i32, range: i64, internals: &'a int },
+    Void
+}
+
+struct NamedFieldsRepr<'a> {
+    id: i32,
+    range: i64,
+    internals: &'a int
+}
+
+fn main() {
+
+    let some: Option<&u32> = Some(unsafe { std::cast::transmute(0x12345678) });
+    let none: Option<&u32> = None;
+
+    let full = Full(454545, unsafe { std::cast::transmute(0x87654321) }, 9988);
+
+    let int_val = 0;
+    let empty: &MoreFieldsRepr = unsafe { std::cast::transmute(&Empty) };
+
+    let droid = Droid {
+        id: 675675,
+        range: 10000001,
+        internals: unsafe { std::cast::transmute(0x43218765) }
+    };
+
+    let void_droid: &NamedFieldsRepr = unsafe { std::cast::transmute(&Void) };
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/packed-struct-with-destructor.rs b/src/test/debuginfo/packed-struct-with-destructor.rs
new file mode 100644 (file)
index 0000000..29087b1
--- /dev/null
@@ -0,0 +1,222 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-tidy-linelength
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:set print pretty off
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print packed
+// gdb-check:$1 = {x = 123, y = 234, z = 345}
+
+// gdb-command:print packedInPacked
+// gdb-check:$2 = {a = 1111, b = {x = 2222, y = 3333, z = 4444}, c = 5555, d = {x = 6666, y = 7777, z = 8888}}
+
+// gdb-command:print packedInUnpacked
+// gdb-check:$3 = {a = -1111, b = {x = -2222, y = -3333, z = -4444}, c = -5555, d = {x = -6666, y = -7777, z = -8888}}
+
+// gdb-command:print unpackedInPacked
+// gdb-check:$4 = {a = 987, b = {x = 876, y = 765, z = 654}, c = {x = 543, y = 432, z = 321}, d = 210}
+
+
+// gdb-command:print packedInPackedWithDrop
+// gdb-check:$5 = {a = 11, b = {x = 22, y = 33, z = 44}, c = 55, d = {x = 66, y = 77, z = 88}}
+
+// gdb-command:print packedInUnpackedWithDrop
+// gdb-check:$6 = {a = -11, b = {x = -22, y = -33, z = -44}, c = -55, d = {x = -66, y = -77, z = -88}}
+
+// gdb-command:print unpackedInPackedWithDrop
+// gdb-check:$7 = {a = 98, b = {x = 87, y = 76, z = 65}, c = {x = 54, y = 43, z = 32}, d = 21}
+
+// gdb-command:print deeplyNested
+// gdb-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,
+    y: i32,
+    z: i64
+}
+
+impl Drop for Packed {
+    fn drop(&mut self) {}
+}
+
+#[packed]
+struct PackedInPacked {
+    a: i32,
+    b: Packed,
+    c: i64,
+    d: Packed
+}
+
+struct PackedInUnpacked {
+    a: i32,
+    b: Packed,
+    c: i64,
+    d: Packed
+}
+
+struct Unpacked {
+    x: i64,
+    y: i32,
+    z: i16
+}
+
+impl Drop for Unpacked {
+    fn drop(&mut self) {}
+}
+
+#[packed]
+struct UnpackedInPacked {
+    a: i16,
+    b: Unpacked,
+    c: Unpacked,
+    d: i64
+}
+
+#[packed]
+struct PackedInPackedWithDrop {
+    a: i32,
+    b: Packed,
+    c: i64,
+    d: Packed
+}
+
+impl Drop for PackedInPackedWithDrop {
+    fn drop(&mut self) {}
+}
+
+struct PackedInUnpackedWithDrop {
+    a: i32,
+    b: Packed,
+    c: i64,
+    d: Packed
+}
+
+impl Drop for PackedInUnpackedWithDrop {
+    fn drop(&mut self) {}
+}
+
+#[packed]
+struct UnpackedInPackedWithDrop {
+    a: i16,
+    b: Unpacked,
+    c: Unpacked,
+    d: i64
+}
+
+impl Drop for UnpackedInPackedWithDrop {
+    fn drop(&mut self) {}
+}
+
+struct DeeplyNested {
+    a: PackedInPacked,
+    b: UnpackedInPackedWithDrop,
+    c: PackedInUnpacked,
+    d: PackedInUnpackedWithDrop,
+    e: UnpackedInPacked,
+    f: PackedInPackedWithDrop
+}
+
+fn main() {
+    let packed = Packed { x: 123, y: 234, z: 345 };
+
+    let packedInPacked = PackedInPacked {
+        a: 1111,
+        b: Packed { x: 2222, y: 3333, z: 4444 },
+        c: 5555,
+        d: Packed { x: 6666, y: 7777, z: 8888 }
+    };
+
+    let packedInUnpacked = PackedInUnpacked {
+        a: -1111,
+        b: Packed { x: -2222, y: -3333, z: -4444 },
+        c: -5555,
+        d: Packed { x: -6666, y: -7777, z: -8888 }
+    };
+
+    let unpackedInPacked = UnpackedInPacked {
+        a: 987,
+        b: Unpacked { x: 876, y: 765, z: 654 },
+        c: Unpacked { x: 543, y: 432, z: 321 },
+        d: 210
+    };
+
+    let packedInPackedWithDrop = PackedInPackedWithDrop {
+        a: 11,
+        b: Packed { x: 22, y: 33, z: 44 },
+        c: 55,
+        d: Packed { x: 66, y: 77, z: 88 }
+    };
+
+    let packedInUnpackedWithDrop = PackedInUnpackedWithDrop {
+        a: -11,
+        b: Packed { x: -22, y: -33, z: -44 },
+        c: -55,
+        d: Packed { x: -66, y: -77, z: -88 }
+    };
+
+    let unpackedInPackedWithDrop = UnpackedInPackedWithDrop {
+        a: 98,
+        b: Unpacked { x: 87, y: 76, z: 65 },
+        c: Unpacked { x: 54, y: 43, z: 32 },
+        d: 21
+    };
+
+    let deeplyNested = DeeplyNested {
+        a: PackedInPacked {
+            a: 1,
+            b: Packed { x: 2, y: 3, z: 4 },
+            c: 5,
+            d: Packed { x: 6, y: 7, z: 8 }
+        },
+        b: UnpackedInPackedWithDrop {
+            a: 9,
+            b: Unpacked { x: 10, y: 11, z: 12 },
+            c: Unpacked { x: 13, y: 14, z: 15 },
+            d: 16
+        },
+        c: PackedInUnpacked {
+            a: 17,
+            b: Packed { x: 18, y: 19, z: 20 },
+            c: 21,
+            d: Packed { x: 22, y: 23, z: 24 }
+        },
+        d: PackedInUnpackedWithDrop {
+            a: 25,
+            b: Packed { x: 26, y: 27, z: 28 },
+            c: 29,
+            d: Packed { x: 30, y: 31, z: 32 }
+        },
+        e: UnpackedInPacked {
+            a: 33,
+            b: Unpacked { x: 34, y: 35, z: 36 },
+            c: Unpacked { x: 37, y: 38, z: 39 },
+            d: 40
+        },
+        f: PackedInPackedWithDrop {
+            a: 41,
+            b: Packed { x: 42, y: 43, z: 44 },
+            c: 45,
+            d: Packed { x: 46, y: 47, z: 48 }
+        }
+    };
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/packed-struct.rs b/src/test/debuginfo/packed-struct.rs
new file mode 100644 (file)
index 0000000..bc8156c
--- /dev/null
@@ -0,0 +1,107 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-tidy-linelength
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:set print pretty off
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print packed
+// gdb-check:$1 = {x = 123, y = 234, z = 345}
+
+// gdb-command:print packedInPacked
+// gdb-check:$2 = {a = 1111, b = {x = 2222, y = 3333, z = 4444}, c = 5555, d = {x = 6666, y = 7777, z = 8888}}
+
+// gdb-command:print packedInUnpacked
+// gdb-check:$3 = {a = -1111, b = {x = -2222, y = -3333, z = -4444}, c = -5555, d = {x = -6666, y = -7777, z = -8888}}
+
+// gdb-command:print unpackedInPacked
+// gdb-check:$4 = {a = 987, b = {x = 876, y = 765, z = 654, w = 543}, c = {x = 432, y = 321, z = 210, w = 109}, d = -98}
+
+// gdb-command:print sizeof(packed)
+// gdb-check:$5 = 14
+
+// gdb-command:print sizeof(packedInPacked)
+// gdb-check:$6 = 40
+
+#![allow(unused_variable)]
+
+#[packed]
+struct Packed {
+    x: i16,
+    y: i32,
+    z: i64
+}
+
+#[packed]
+struct PackedInPacked {
+    a: i32,
+    b: Packed,
+    c: i64,
+    d: Packed
+}
+
+// layout (64 bit): aaaa bbbb bbbb bbbb bb.. .... cccc cccc dddd dddd dddd dd..
+struct PackedInUnpacked {
+    a: i32,
+    b: Packed,
+    c: i64,
+    d: Packed
+}
+
+// layout (64 bit): xx.. yyyy zz.. .... wwww wwww
+struct Unpacked {
+    x: i16,
+    y: i32,
+    z: i16,
+    w: i64
+}
+
+// layout (64 bit): aabb bbbb bbbb bbbb bbbb bbbb bbcc cccc cccc cccc cccc cccc ccdd dddd dd
+#[packed]
+struct UnpackedInPacked {
+    a: i16,
+    b: Unpacked,
+    c: Unpacked,
+    d: i64
+}
+
+fn main() {
+    let packed = Packed { x: 123, y: 234, z: 345 };
+
+    let packedInPacked = PackedInPacked {
+        a: 1111,
+        b: Packed { x: 2222, y: 3333, z: 4444 },
+        c: 5555,
+        d: Packed { x: 6666, y: 7777, z: 8888 }
+    };
+
+    let packedInUnpacked = PackedInUnpacked {
+        a: -1111,
+        b: Packed { x: -2222, y: -3333, z: -4444 },
+        c: -5555,
+        d: Packed { x: -6666, y: -7777, z: -8888 }
+    };
+
+    let unpackedInPacked = UnpackedInPacked {
+        a: 987,
+        b: Unpacked { x: 876, y: 765, z: 654, w: 543 },
+        c: Unpacked { x: 432, y: 321, z: 210, w: 109 },
+        d: -98
+    };
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/recursive-enum.rs b/src/test/debuginfo/recursive-enum.rs
new file mode 100644 (file)
index 0000000..68b6764
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:run
+
+// Test whether compiling a recursive enum definition crashes debug info generation. The test case
+// is taken from issue #11083.
+
+#![allow(unused_variable)]
+
+pub struct Window<'a> {
+    callbacks: WindowCallbacks<'a>
+}
+
+struct WindowCallbacks<'a> {
+    pos_callback: Option<WindowPosCallback<'a>>,
+}
+
+pub type WindowPosCallback<'a> = |&Window, i32, i32|: 'a;
+
+fn main() {
+    let x = WindowCallbacks { pos_callback: None };
+}
diff --git a/src/test/debuginfo/recursive-struct.rs b/src/test/debuginfo/recursive-struct.rs
new file mode 100644 (file)
index 0000000..8c2edbe
--- /dev/null
@@ -0,0 +1,320 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+#![feature(managed_boxes)]
+
+// compile-flags:-g
+// gdb-command:set print pretty off
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print stack_unique.value
+// gdb-check:$1 = 0
+// gdb-command:print stack_unique.next.val->value
+// gdb-check:$2 = 1
+
+// gdb-command:print unique_unique->value
+// gdb-check:$3 = 2
+// gdb-command:print unique_unique->next.val->value
+// gdb-check:$4 = 3
+
+// gdb-command:print box_unique->val.value
+// gdb-check:$5 = 4
+// gdb-command:print box_unique->val.next.val->value
+// gdb-check:$6 = 5
+
+// gdb-command:print vec_unique[0].value
+// gdb-check:$7 = 6.5
+// gdb-command:print vec_unique[0].next.val->value
+// gdb-check:$8 = 7.5
+
+// gdb-command:print borrowed_unique->value
+// gdb-check:$9 = 8.5
+// gdb-command:print borrowed_unique->next.val->value
+// gdb-check:$10 = 9.5
+
+// MANAGED
+// gdb-command:print stack_managed.value
+// gdb-check:$11 = 10
+// gdb-command:print stack_managed.next.val->val.value
+// gdb-check:$12 = 11
+
+// gdb-command:print unique_managed->value
+// gdb-check:$13 = 12
+// gdb-command:print unique_managed->next.val->val.value
+// gdb-check:$14 = 13
+
+// gdb-command:print box_managed->val.value
+// gdb-check:$15 = 14
+// gdb-command:print box_managed->val.next.val->val.value
+// gdb-check:$16 = 15
+
+// gdb-command:print vec_managed[0].value
+// gdb-check:$17 = 16.5
+// gdb-command:print vec_managed[0].next.val->val.value
+// gdb-check:$18 = 17.5
+
+// gdb-command:print borrowed_managed->value
+// gdb-check:$19 = 18.5
+// gdb-command:print borrowed_managed->next.val->val.value
+// gdb-check:$20 = 19.5
+
+// LONG CYCLE
+// gdb-command:print long_cycle1.value
+// gdb-check:$21 = 20
+// gdb-command:print long_cycle1.next->value
+// gdb-check:$22 = 21
+// gdb-command:print long_cycle1.next->next->value
+// gdb-check:$23 = 22
+// gdb-command:print long_cycle1.next->next->next->value
+// gdb-check:$24 = 23
+
+// gdb-command:print long_cycle2.value
+// gdb-check:$25 = 24
+// gdb-command:print long_cycle2.next->value
+// gdb-check:$26 = 25
+// gdb-command:print long_cycle2.next->next->value
+// gdb-check:$27 = 26
+
+// gdb-command:print long_cycle3.value
+// gdb-check:$28 = 27
+// gdb-command:print long_cycle3.next->value
+// gdb-check:$29 = 28
+
+// gdb-command:print long_cycle4.value
+// gdb-check:$30 = 29.5
+
+// gdb-command:print (*****long_cycle_w_anonymous_types).value
+// gdb-check:$31 = 30
+
+// gdb-command:print (*****((*****long_cycle_w_anonymous_types).next.val)).value
+// gdb-check:$32 = 31
+
+// gdb-command:continue
+
+#![allow(unused_variable)]
+#![feature(struct_variant)]
+
+
+enum Opt<T> {
+    Empty,
+    Val { val: T }
+}
+
+struct UniqueNode<T> {
+    next: Opt<Box<UniqueNode<T>>>,
+    value: T
+}
+
+struct ManagedNode<T> {
+    next: Opt<@ManagedNode<T>>,
+    value: T
+}
+
+struct LongCycle1<T> {
+    next: Box<LongCycle2<T>>,
+    value: T,
+}
+
+struct LongCycle2<T> {
+    next: Box<LongCycle3<T>>,
+    value: T,
+}
+
+struct LongCycle3<T> {
+    next: Box<LongCycle4<T>>,
+    value: T,
+}
+
+struct LongCycle4<T> {
+    next: Option<Box<LongCycle1<T>>>,
+    value: T,
+}
+
+struct LongCycleWithAnonymousTypes {
+    next: Opt<Box<Box<Box<Box<Box<LongCycleWithAnonymousTypes>>>>>>,
+    value: uint,
+}
+
+// This test case makes sure that recursive structs are properly described. The Node structs are
+// generic so that we can have a new type (that newly needs to be described) for the different
+// cases. The potential problem with recursive types is that the DI generation algorithm gets
+// trapped in an endless loop. To make sure, we actually test this in the different cases, we have
+// to operate on a new type each time, otherwise we would just hit the DI cache for all but the
+// first case.
+
+// The different cases below (stack_*, unique_*, box_*, etc) are set up so that the type description
+// algorithm will enter the type reference cycle that is created by a recursive definition from a
+// different context each time.
+
+// The "long cycle" cases are constructed to span a longer, indirect recursion cycle between types.
+// The different locals will cause the DI algorithm to enter the type reference cycle at different
+// points.
+
+fn main() {
+    let stack_unique: UniqueNode<u16> = UniqueNode {
+        next: Val {
+            val: box UniqueNode {
+                next: Empty,
+                value: 1_u16,
+            }
+        },
+        value: 0_u16,
+    };
+
+    let unique_unique: Box<UniqueNode<u32>> = box UniqueNode {
+        next: Val {
+            val: box UniqueNode {
+                next: Empty,
+                value: 3,
+            }
+        },
+        value: 2,
+    };
+
+    let box_unique: @UniqueNode<u64> = @UniqueNode {
+        next: Val {
+            val: box UniqueNode {
+                next: Empty,
+                value: 5,
+            }
+        },
+        value: 4,
+    };
+
+    let vec_unique: [UniqueNode<f32>, ..1] = [UniqueNode {
+        next: Val {
+            val: box UniqueNode {
+                next: Empty,
+                value: 7.5,
+            }
+        },
+        value: 6.5,
+    }];
+
+    let borrowed_unique: &UniqueNode<f64> = &UniqueNode {
+        next: Val {
+            val: box UniqueNode {
+                next: Empty,
+                value: 9.5,
+            }
+        },
+        value: 8.5,
+    };
+
+    let stack_managed: ManagedNode<u16> = ManagedNode {
+        next: Val {
+            val: @ManagedNode {
+                next: Empty,
+                value: 11,
+            }
+        },
+        value: 10,
+    };
+
+    let unique_managed: Box<ManagedNode<u32>> = box ManagedNode {
+        next: Val {
+            val: @ManagedNode {
+                next: Empty,
+                value: 13,
+            }
+        },
+        value: 12,
+    };
+
+    let box_managed: @ManagedNode<u64> = @ManagedNode {
+        next: Val {
+            val: @ManagedNode {
+                next: Empty,
+                value: 15,
+            }
+        },
+        value: 14,
+    };
+
+    let vec_managed: [ManagedNode<f32>, ..1] = [ManagedNode {
+        next: Val {
+            val: @ManagedNode {
+                next: Empty,
+                value: 17.5,
+            }
+        },
+        value: 16.5,
+    }];
+
+    let borrowed_managed: &ManagedNode<f64> = &ManagedNode {
+        next: Val {
+            val: @ManagedNode {
+                next: Empty,
+                value: 19.5,
+            }
+        },
+        value: 18.5,
+    };
+
+    // LONG CYCLE
+    let long_cycle1: LongCycle1<u16> = LongCycle1 {
+        next: box LongCycle2 {
+            next: box LongCycle3 {
+                next: box LongCycle4 {
+                    next: None,
+                    value: 23,
+                },
+                value: 22,
+            },
+            value: 21
+        },
+        value: 20
+    };
+
+    let long_cycle2: LongCycle2<u32> = LongCycle2 {
+        next: box LongCycle3 {
+            next: box LongCycle4 {
+                next: None,
+                value: 26,
+            },
+            value: 25,
+        },
+        value: 24
+    };
+
+    let long_cycle3: LongCycle3<u64> = LongCycle3 {
+        next: box LongCycle4 {
+            next: None,
+            value: 28,
+        },
+        value: 27,
+    };
+
+    let long_cycle4: LongCycle4<f32> = LongCycle4 {
+        next: None,
+        value: 29.5,
+    };
+
+    // It's important that LongCycleWithAnonymousTypes is encountered only at the end of the
+    // `box` chain.
+    let long_cycle_w_anonymous_types = box box box box box LongCycleWithAnonymousTypes {
+        next: Val {
+            val: box box box box box LongCycleWithAnonymousTypes {
+                next: Empty,
+                value: 31,
+            }
+        },
+        value: 30
+    };
+
+    zzz();
+}
+
+fn zzz() {()}
+
diff --git a/src/test/debuginfo/self-in-default-method.rs b/src/test/debuginfo/self-in-default-method.rs
new file mode 100644 (file)
index 0000000..45cbcf0
--- /dev/null
@@ -0,0 +1,101 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// STACK BY REF
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$1 = {x = 100}
+// gdb-command:print arg1
+// gdb-check:$2 = -1
+// gdb-command:print arg2
+// gdb-check:$3 = -2
+// gdb-command:continue
+
+// STACK BY VAL
+// gdb-command:finish
+// gdb-command:print self
+// gdb-check:$4 = {x = 100}
+// gdb-command:print arg1
+// gdb-check:$5 = -3
+// gdb-command:print arg2
+// gdb-check:$6 = -4
+// gdb-command:continue
+
+// OWNED BY REF
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$7 = {x = 200}
+// gdb-command:print arg1
+// gdb-check:$8 = -5
+// gdb-command:print arg2
+// gdb-check:$9 = -6
+// gdb-command:continue
+
+// OWNED BY VAL
+// gdb-command:finish
+// gdb-command:print self
+// gdb-check:$10 = {x = 200}
+// gdb-command:print arg1
+// gdb-check:$11 = -7
+// gdb-command:print arg2
+// gdb-check:$12 = -8
+// gdb-command:continue
+
+// OWNED MOVED
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$13 = {x = 200}
+// gdb-command:print arg1
+// gdb-check:$14 = -9
+// gdb-command:print arg2
+// gdb-check:$15 = -10
+// gdb-command: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
+    }
+}
+
+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 = box Struct { x: 200 };
+    let _ = owned.self_by_ref(-5, -6);
+    let _ = owned.self_by_val(-7, -8);
+    let _ = owned.self_owned(-9, -10);
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/self-in-generic-default-method.rs b/src/test/debuginfo/self-in-generic-default-method.rs
new file mode 100644 (file)
index 0000000..8ab3fd4
--- /dev/null
@@ -0,0 +1,102 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// STACK BY REF
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$1 = {x = 987}
+// gdb-command:print arg1
+// gdb-check:$2 = -1
+// gdb-command:print/d arg2
+// gdb-check:$3 = -2
+// gdb-command:continue
+
+// STACK BY VAL
+// gdb-command:finish
+// gdb-command:print self
+// gdb-check:$4 = {x = 987}
+// gdb-command:print arg1
+// gdb-check:$5 = -3
+// gdb-command:print arg2
+// gdb-check:$6 = -4
+// gdb-command:continue
+
+// OWNED BY REF
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$7 = {x = 879}
+// gdb-command:print arg1
+// gdb-check:$8 = -5
+// gdb-command:print arg2
+// gdb-check:$9 = -6
+// gdb-command:continue
+
+// OWNED BY VAL
+// gdb-command:finish
+// gdb-command:print self
+// gdb-check:$10 = {x = 879}
+// gdb-command:print arg1
+// gdb-check:$11 = -7
+// gdb-command:print arg2
+// gdb-check:$12 = -8
+// gdb-command:continue
+
+// OWNED MOVED
+// gdb-command:finish
+// gdb-command:print *self
+// gdb-check:$13 = {x = 879}
+// gdb-command:print arg1
+// gdb-check:$14 = -9
+// gdb-command:print arg2
+// gdb-check:$15 = -10.5
+// gdb-command: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
+    }
+}
+
+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 = box 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);
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/shadowed-argument.rs b/src/test/debuginfo/shadowed-argument.rs
new file mode 100644 (file)
index 0000000..129263c
--- /dev/null
@@ -0,0 +1,59 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$1 = false
+// gdb-command:print y
+// gdb-check:$2 = true
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$3 = 10
+// gdb-command:print y
+// gdb-check:$4 = true
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$5 = 10.5
+// gdb-command:print y
+// gdb-check:$6 = 20
+// gdb-command:continue
+
+fn a_function(x: bool, y: bool) {
+    zzz();
+    sentinel();
+
+    let x = 10;
+
+    zzz();
+    sentinel();
+
+    let x = 10.5;
+    let y = 20;
+
+    zzz();
+    sentinel();
+}
+
+fn main() {
+    a_function(false, true);
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debuginfo/shadowed-variable.rs b/src/test/debuginfo/shadowed-variable.rs
new file mode 100644 (file)
index 0000000..825ecb9
--- /dev/null
@@ -0,0 +1,58 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$1 = false
+// gdb-command:print y
+// gdb-check:$2 = true
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$3 = 10
+// gdb-command:print y
+// gdb-check:$4 = true
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$5 = 10.5
+// gdb-command:print y
+// gdb-check:$6 = 20
+// gdb-command:continue
+
+fn main() {
+    let x = false;
+    let y = true;
+
+    zzz();
+    sentinel();
+
+    let x = 10;
+
+    zzz();
+    sentinel();
+
+    let x = 10.5;
+    let y = 20;
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debuginfo/simd.rs b/src/test/debuginfo/simd.rs
new file mode 100644 (file)
index 0000000..ff9618a
--- /dev/null
@@ -0,0 +1,70 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// gdb-command:finish
+// gdb-command:print/d i8x16
+// gdb-check:$1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
+// gdb-command:print/d i16x8
+// gdb-check:$2 = {16, 17, 18, 19, 20, 21, 22, 23}
+// gdb-command:print/d i32x4
+// gdb-check:$3 = {24, 25, 26, 27}
+// gdb-command:print/d i64x2
+// gdb-check:$4 = {28, 29}
+
+// gdb-command:print/d u8x16
+// gdb-check:$5 = {30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45}
+// gdb-command:print/d u16x8
+// gdb-check:$6 = {46, 47, 48, 49, 50, 51, 52, 53}
+// gdb-command:print/d u32x4
+// gdb-check:$7 = {54, 55, 56, 57}
+// gdb-command:print/d u64x2
+// gdb-check:$8 = {58, 59}
+
+// gdb-command:print f32x4
+// gdb-check:$9 = {60.5, 61.5, 62.5, 63.5}
+// gdb-command:print f64x2
+// gdb-check:$10 = {64.5, 65.5}
+
+// gdb-command:continue
+
+#![allow(experimental)]
+#![allow(unused_variable)]
+
+use std::unstable::simd::{i8x16, i16x8,i32x4,i64x2,u8x16,u16x8,u32x4,u64x2,f32x4,f64x2};
+
+fn main() {
+
+    let i8x16 = i8x16(0i8, 1i8, 2i8, 3i8, 4i8, 5i8, 6i8, 7i8,
+                      8i8, 9i8, 10i8, 11i8, 12i8, 13i8, 14i8, 15i8);
+
+    let i16x8 = i16x8(16i16, 17i16, 18i16, 19i16, 20i16, 21i16, 22i16, 23i16);
+    let i32x4 = i32x4(24i32, 25i32, 26i32, 27i32);
+    let i64x2 = i64x2(28i64, 29i64);
+
+    let u8x16 = u8x16(30u8, 31u8, 32u8, 33u8, 34u8, 35u8, 36u8, 37u8,
+                      38u8, 39u8, 40u8, 41u8, 42u8, 43u8, 44u8, 45u8);
+    let u16x8 = u16x8(46u16, 47u16, 48u16, 49u16, 50u16, 51u16, 52u16, 53u16);
+    let u32x4 = u32x4(54u32, 55u32, 56u32, 57u32);
+    let u64x2 = u64x2(58u64, 59u64);
+
+    let f32x4 = f32x4(60.5f32, 61.5f32, 62.5f32, 63.5f32);
+    let f64x2 = f64x2(64.5f64, 65.5f64);
+
+    zzz();
+}
+
+#[inline(never)]
+fn zzz() { () }
diff --git a/src/test/debuginfo/simple-lexical-scope.rs b/src/test/debuginfo/simple-lexical-scope.rs
new file mode 100644 (file)
index 0000000..171e3ea
--- /dev/null
@@ -0,0 +1,87 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$1 = false
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$2 = false
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$3 = 10
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$4 = 10
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$5 = 10.5
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$6 = 10
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print x
+// gdb-check:$7 = false
+// gdb-command:continue
+
+
+fn main() {
+    let x = false;
+
+    zzz();
+    sentinel();
+
+    {
+        zzz();
+        sentinel();
+
+        let x = 10;
+
+        zzz();
+        sentinel();
+
+        {
+            zzz();
+            sentinel();
+
+            let x = 10.5;
+
+            zzz();
+            sentinel();
+        }
+
+        zzz();
+        sentinel();
+    }
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debuginfo/simple-struct.rs b/src/test/debuginfo/simple-struct.rs
new file mode 100644 (file)
index 0000000..c1f0e2c
--- /dev/null
@@ -0,0 +1,194 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-win32: FIXME #13256
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:set print pretty off
+// gdb-command:rbreak zzz
+
+// gdb-command:print 'simple-struct::NO_PADDING_16'
+// gdb-check:$1 = {x = 1000, y = -1001}
+
+// gdb-command:print 'simple-struct::NO_PADDING_32'
+// gdb-check:$2 = {x = 1, y = 2, z = 3}
+
+// gdb-command:print 'simple-struct::NO_PADDING_64'
+// gdb-check:$3 = {x = 4, y = 5, z = 6}
+
+// gdb-command:print 'simple-struct::NO_PADDING_163264'
+// gdb-check:$4 = {a = 7, b = 8, c = 9, d = 10}
+
+// gdb-command:print 'simple-struct::INTERNAL_PADDING'
+// gdb-check:$5 = {x = 11, y = 12}
+
+// gdb-command:print 'simple-struct::PADDING_AT_END'
+// gdb-check:$6 = {x = 13, y = 14}
+
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print no_padding16
+// gdb-check:$7 = {x = 10000, y = -10001}
+
+// gdb-command:print no_padding32
+// gdb-check:$8 = {x = -10002, y = -10003.5, z = 10004}
+
+// gdb-command:print no_padding64
+// gdb-check:$9 = {x = -10005.5, y = 10006, z = 10007}
+
+// gdb-command:print no_padding163264
+// gdb-check:$10 = {a = -10008, b = 10009, c = 10010, d = 10011}
+
+// gdb-command:print internal_padding
+// gdb-check:$11 = {x = 10012, y = -10013}
+
+// gdb-command:print padding_at_end
+// gdb-check:$12 = {x = -10014, y = 10015}
+
+// gdb-command:print 'simple-struct::NO_PADDING_16'
+// gdb-check:$13 = {x = 100, y = -101}
+
+// gdb-command:print 'simple-struct::NO_PADDING_32'
+// gdb-check:$14 = {x = -15, y = -16, z = 17}
+
+// gdb-command:print 'simple-struct::NO_PADDING_64'
+// gdb-check:$15 = {x = -18, y = 19, z = 20}
+
+// gdb-command:print 'simple-struct::NO_PADDING_163264'
+// gdb-check:$16 = {a = -21, b = 22, c = 23, d = 24}
+
+// gdb-command:print 'simple-struct::INTERNAL_PADDING'
+// gdb-check:$17 = {x = 25, y = -26}
+
+// gdb-command:print 'simple-struct::PADDING_AT_END'
+// gdb-check:$18 = {x = -27, y = 28}
+
+// gdb-command:print inheriting
+// gdb-check:$19 = {a = 10019, b = -10020, x = -10016, y = -10017.5, z = 10018}
+
+
+#![feature(struct_inherit)];
+#![allow(unused_variable)];
+#![allow(dead_code)];
+
+struct NoPadding16 {
+    x: u16,
+    y: i16
+}
+
+virtual struct NoPadding32 {
+    x: i32,
+    y: f32,
+    z: u32
+}
+
+struct NoPadding64 {
+    x: f64,
+    y: i64,
+    z: u64
+}
+
+struct NoPadding163264 {
+    a: i16,
+    b: u16,
+    c: i32,
+    d: u64
+}
+
+struct InternalPadding {
+    x: u16,
+    y: i64
+}
+
+struct PaddingAtEnd {
+    x: i64,
+    y: u16
+}
+
+static mut NO_PADDING_16: NoPadding16 = NoPadding16 {
+    x: 1000,
+    y: -1001
+};
+
+static mut NO_PADDING_32: NoPadding32 = NoPadding32 {
+    x: 1,
+    y: 2.0,
+    z: 3
+};
+
+static mut NO_PADDING_64: NoPadding64 = NoPadding64 {
+    x: 4.0,
+    y: 5,
+    z: 6
+};
+
+static mut NO_PADDING_163264: NoPadding163264 = NoPadding163264 {
+    a: 7,
+    b: 8,
+    c: 9,
+    d: 10
+};
+
+static mut INTERNAL_PADDING: InternalPadding = InternalPadding {
+    x: 11,
+    y: 12
+};
+
+static mut PADDING_AT_END: PaddingAtEnd = PaddingAtEnd {
+    x: 13,
+    y: 14
+};
+
+struct Inheriting : NoPadding32 {
+    a: u16,
+    b: i16
+}
+
+fn main() {
+    let no_padding16 = NoPadding16 { x: 10000, y: -10001 };
+    let no_padding32 = NoPadding32 { x: -10002, y: -10003.5, z: 10004 };
+    let no_padding64 = NoPadding64 { x: -10005.5, y: 10006, z: 10007 };
+    let no_padding163264 = NoPadding163264 { a: -10008, b: 10009, c: 10010, d: 10011 };
+
+    let internal_padding = InternalPadding { x: 10012, y: -10013 };
+    let padding_at_end = PaddingAtEnd { x: -10014, y: 10015 };
+
+    let inheriting = Inheriting { a: 10019, b: -10020, x: -10016, y: -10017.5, z: 10018 };
+
+    unsafe {
+        NO_PADDING_16.x = 100;
+        NO_PADDING_16.y = -101;
+
+        NO_PADDING_32.x = -15;
+        NO_PADDING_32.y = -16.0;
+        NO_PADDING_32.z = 17;
+
+        NO_PADDING_64.x = -18.0;
+        NO_PADDING_64.y = 19;
+        NO_PADDING_64.z = 20;
+
+        NO_PADDING_163264.a = -21;
+        NO_PADDING_163264.b = 22;
+        NO_PADDING_163264.c = 23;
+        NO_PADDING_163264.d = 24;
+
+        INTERNAL_PADDING.x = 25;
+        INTERNAL_PADDING.y = -26;
+
+        PADDING_AT_END.x = -27;
+        PADDING_AT_END.y = 28;
+    }
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/simple-tuple.rs b/src/test/debuginfo/simple-tuple.rs
new file mode 100644 (file)
index 0000000..9486ab2
--- /dev/null
@@ -0,0 +1,113 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-win32: FIXME #13256
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:set print pretty off
+// gdb-command:rbreak zzz
+
+// gdb-command:print/d 'simple-tuple::NO_PADDING_8'
+// gdb-check:$1 = {-50, 50}
+// gdb-command:print 'simple-tuple::NO_PADDING_16'
+// gdb-check:$2 = {-1, 2, 3}
+// gdb-command:print 'simple-tuple::NO_PADDING_32'
+// gdb-check:$3 = {4, 5, 6}
+// gdb-command:print 'simple-tuple::NO_PADDING_64'
+// gdb-check:$4 = {7, 8, 9}
+
+// gdb-command:print 'simple-tuple::INTERNAL_PADDING_1'
+// gdb-check:$5 = {10, 11}
+// gdb-command:print 'simple-tuple::INTERNAL_PADDING_2'
+// gdb-check:$6 = {12, 13, 14, 15}
+
+// gdb-command:print 'simple-tuple::PADDING_AT_END'
+// gdb-check:$7 = {16, 17}
+
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print/d noPadding8
+// gdb-check:$8 = {-100, 100}
+// gdb-command:print noPadding16
+// gdb-check:$9 = {0, 1, 2}
+// gdb-command:print noPadding32
+// gdb-check:$10 = {3, 4.5, 5}
+// gdb-command:print noPadding64
+// gdb-check:$11 = {6, 7.5, 8}
+
+// gdb-command:print internalPadding1
+// gdb-check:$12 = {9, 10}
+// gdb-command:print internalPadding2
+// gdb-check:$13 = {11, 12, 13, 14}
+
+// gdb-command:print paddingAtEnd
+// gdb-check:$14 = {15, 16}
+
+// gdb-command:print/d 'simple-tuple::NO_PADDING_8'
+// gdb-check:$15 = {-127, 127}
+// gdb-command:print 'simple-tuple::NO_PADDING_16'
+// gdb-check:$16 = {-10, 10, 9}
+// gdb-command:print 'simple-tuple::NO_PADDING_32'
+// gdb-check:$17 = {14, 15, 16}
+// gdb-command:print 'simple-tuple::NO_PADDING_64'
+// gdb-check:$18 = {17, 18, 19}
+
+// gdb-command:print 'simple-tuple::INTERNAL_PADDING_1'
+// gdb-check:$19 = {110, 111}
+// gdb-command:print 'simple-tuple::INTERNAL_PADDING_2'
+// gdb-check:$20 = {112, 113, 114, 115}
+
+// gdb-command:print 'simple-tuple::PADDING_AT_END'
+// gdb-check:$21 = {116, 117}
+
+#![allow(unused_variable)]
+#![allow(dead_code)]
+
+static mut NO_PADDING_8: (i8, u8) = (-50, 50);
+static mut NO_PADDING_16: (i16, i16, u16) = (-1, 2, 3);
+
+static mut NO_PADDING_32: (i32, f32, u32) = (4, 5.0, 6);
+static mut NO_PADDING_64: (i64, f64, u64) = (7, 8.0, 9);
+
+static mut INTERNAL_PADDING_1: (i16, i32) = (10, 11);
+static mut INTERNAL_PADDING_2: (i16, i32, u32, u64) = (12, 13, 14, 15);
+
+static mut PADDING_AT_END: (i32, i16) = (16, 17);
+
+fn main() {
+    let noPadding8: (i8, u8) = (-100, 100);
+    let noPadding16: (i16, i16, u16) = (0, 1, 2);
+    let noPadding32: (i32, f32, u32) = (3, 4.5, 5);
+    let noPadding64: (i64, f64, u64) = (6, 7.5, 8);
+
+    let internalPadding1: (i16, i32) = (9, 10);
+    let internalPadding2: (i16, i32, u32, u64) = (11, 12, 13, 14);
+
+    let paddingAtEnd: (i32, i16) = (15, 16);
+
+    unsafe {
+        NO_PADDING_8 = (-127, 127);
+        NO_PADDING_16 = (-10, 10, 9);
+
+        NO_PADDING_32 = (14, 15.0, 16);
+        NO_PADDING_64 = (17, 18.0, 19);
+
+        INTERNAL_PADDING_1 = (110, 111);
+        INTERNAL_PADDING_2 = (112, 113, 114, 115);
+
+        PADDING_AT_END = (116, 117);
+    }
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/static-method-on-struct-and-enum.rs b/src/test/debuginfo/static-method-on-struct-and-enum.rs
new file mode 100644 (file)
index 0000000..d7d962c
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// STRUCT
+// gdb-command:finish
+// gdb-command:print arg1
+// gdb-check:$1 = 1
+// gdb-command:print arg2
+// gdb-check:$2 = 2
+// gdb-command:continue
+
+// ENUM
+// gdb-command:finish
+// gdb-command:print arg1
+// gdb-check:$3 = -3
+// gdb-command:print arg2
+// gdb-check:$4 = 4.5
+// gdb-command:print arg3
+// gdb-check:$5 = 5
+// gdb-command:continue
+
+#![feature(struct_variant)]
+
+struct Struct {
+    x: int
+}
+
+impl Struct {
+
+    fn static_method(arg1: int, arg2: int) -> int {
+        zzz();
+        arg1 + arg2
+    }
+}
+
+enum Enum {
+    Variant1 { x: int },
+    Variant2,
+    Variant3(f64, int, char),
+}
+
+impl Enum {
+
+    fn static_method(arg1: int, arg2: f64, arg3: uint) -> int {
+        zzz();
+        arg1
+    }
+}
+
+fn main() {
+    Struct::static_method(1, 2);
+    Enum::static_method(-3, 4.5, 5);
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/struct-in-enum.rs b/src/test/debuginfo/struct-in-enum.rs
new file mode 100644 (file)
index 0000000..ee971d7
--- /dev/null
@@ -0,0 +1,72 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-tidy-linelength
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:set print union on
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print case1
+// gdb-check:$1 = {{Case1, 0, {x = 2088533116, y = 2088533116, z = 31868}}, {Case1, 0, 8970181431921507452, 31868}}
+
+// gdb-command:print case2
+// gdb-check:$2 = {{Case2, 0, {x = 286331153, y = 286331153, z = 4369}}, {Case2, 0, 1229782938247303441, 4369}}
+
+// gdb-command:print univariant
+// gdb-check:$3 = {{x = 123, y = 456, z = 789}}
+
+#![allow(unused_variable)]
+
+struct Struct {
+    x: u32,
+    y: i32,
+    z: i16
+}
+
+// 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 {
+    Case1(u64, Struct),
+    Case2(u64, u64, i16)
+}
+
+enum Univariant {
+    TheOnlyCase(Struct)
+}
+
+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 = Case1(0, Struct { x: 2088533116, y: 2088533116, z: 31868 });
+
+    // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
+    // 0b00010001000100010001000100010001 = 286331153
+    // 0b0001000100010001 = 4369
+    // 0b00010001 = 17
+    let case2 = Case2(0, 1229782938247303441, 4369);
+
+    let univariant = TheOnlyCase(Struct { x: 123, y: 456, z: 789 });
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/struct-in-struct.rs b/src/test/debuginfo/struct-in-struct.rs
new file mode 100644 (file)
index 0000000..e4c3f47
--- /dev/null
@@ -0,0 +1,146 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:set print pretty off
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print three_simple_structs
+// gdb-check:$1 = {x = {x = 1}, y = {x = 2}, z = {x = 3}}
+
+// gdb-command:print internal_padding_parent
+// gdb-check:$2 = {x = {x = 4, y = 5}, y = {x = 6, y = 7}, z = {x = 8, y = 9}}
+
+// gdb-command:print padding_at_end_parent
+// gdb-check:$3 = {x = {x = 10, y = 11}, y = {x = 12, y = 13}, z = {x = 14, y = 15}}
+
+#![allow(unused_variable)]
+
+struct Simple {
+    x: i32
+}
+
+struct InternalPadding {
+    x: i32,
+    y: i64
+}
+
+struct PaddingAtEnd {
+    x: i64,
+    y: i32
+}
+
+struct ThreeSimpleStructs {
+    x: Simple,
+    y: Simple,
+    z: Simple
+}
+
+struct InternalPaddingParent {
+    x: InternalPadding,
+    y: InternalPadding,
+    z: InternalPadding
+}
+
+struct PaddingAtEndParent {
+    x: PaddingAtEnd,
+    y: PaddingAtEnd,
+    z: PaddingAtEnd
+}
+
+struct Mixed {
+    x: PaddingAtEnd,
+    y: InternalPadding,
+    z: Simple,
+    w: i16
+}
+
+struct Bag {
+    x: Simple
+}
+
+struct BagInBag {
+    x: Bag
+}
+
+struct ThatsJustOverkill {
+    x: BagInBag
+}
+
+struct Tree {
+    x: Simple,
+    y: InternalPaddingParent,
+    z: BagInBag
+}
+
+fn main() {
+
+    let three_simple_structs = ThreeSimpleStructs {
+        x: Simple { x: 1 },
+        y: Simple { x: 2 },
+        z: Simple { x: 3 }
+    };
+
+    let internal_padding_parent = InternalPaddingParent {
+        x: InternalPadding { x: 4, y: 5 },
+        y: InternalPadding { x: 6, y: 7 },
+        z: InternalPadding { x: 8, y: 9 }
+    };
+
+    let padding_at_end_parent = PaddingAtEndParent {
+        x: PaddingAtEnd { x: 10, y: 11 },
+        y: PaddingAtEnd { x: 12, y: 13 },
+        z: PaddingAtEnd { x: 14, y: 15 }
+    };
+
+    let mixed = Mixed {
+        x: PaddingAtEnd { x: 16, y: 17 },
+        y: InternalPadding { x: 18, y: 19 },
+        z: Simple { x: 20 },
+        w: 21
+    };
+
+    let bag = Bag { x: Simple { x: 22 } };
+    let bag_in_bag = BagInBag {
+        x: Bag {
+            x: Simple { x: 23 }
+        }
+    };
+
+    let tjo = ThatsJustOverkill {
+        x: BagInBag {
+            x: Bag {
+                x: Simple { x: 24 }
+            }
+        }
+    };
+
+    let tree = Tree {
+        x: Simple { x: 25 },
+        y: InternalPaddingParent {
+            x: InternalPadding { x: 26, y: 27 },
+            y: InternalPadding { x: 28, y: 29 },
+            z: InternalPadding { x: 30, y: 31 }
+        },
+        z: BagInBag {
+            x: Bag {
+                x: Simple { x: 32 }
+            }
+        }
+    };
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/struct-style-enum.rs b/src/test/debuginfo/struct-style-enum.rs
new file mode 100644 (file)
index 0000000..1a51db1
--- /dev/null
@@ -0,0 +1,77 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-tidy-linelength
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:set print union on
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print case1
+// gdb-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}}
+
+// gdb-command:print case2
+// gdb-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}}
+
+// gdb-command:print case3
+// gdb-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}}
+
+// gdb-command:print univariant
+// gdb-check:$4 = {a = -1}
+
+#![allow(unused_variable)]
+#![feature(struct_variant)]
+
+// 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 {
+    Case1 { a: u64, b: u16, c: u16, d: u16, e: u16},
+    Case2 { a: u64, b: u32, c: u32},
+    Case3 { a: u64, b: u64 }
+}
+
+enum Univariant {
+    TheOnlyCase { a: i64 }
+}
+
+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 = Case1 { a: 0, b: 31868, c: 31868, d: 31868, e: 31868 };
+
+    // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
+    // 0b00010001000100010001000100010001 = 286331153
+    // 0b0001000100010001 = 4369
+    // 0b00010001 = 17
+    let case2 = Case2 { a: 0, b: 286331153, c: 286331153 };
+
+    // 0b0101100101011001010110010101100101011001010110010101100101011001 = 6438275382588823897
+    // 0b01011001010110010101100101011001 = 1499027801
+    // 0b0101100101011001 = 22873
+    // 0b01011001 = 89
+    let case3 = Case3 { a: 0, b: 6438275382588823897 };
+
+    let univariant = TheOnlyCase { a: -1 };
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/struct-with-destructor.rs b/src/test/debuginfo/struct-with-destructor.rs
new file mode 100644 (file)
index 0000000..16fbfc4
--- /dev/null
@@ -0,0 +1,127 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+// gdb-command:print simple
+// gdb-check:$1 = {x = 10, y = 20}
+
+// gdb-command:print noDestructor
+// gdb-check:$2 = {a = {x = 10, y = 20}, guard = -1}
+
+// gdb-command:print withDestructor
+// gdb-check:$3 = {a = {x = 10, y = 20}, guard = -1}
+
+// gdb-command:print nested
+// gdb-check:$4 = {a = {a = {x = 7890, y = 9870}}}
+
+#![allow(unused_variable)]
+
+struct NoDestructor {
+    x: i32,
+    y: i64
+}
+
+struct WithDestructor {
+    x: i32,
+    y: i64
+}
+
+impl Drop for WithDestructor {
+    fn drop(&mut self) {}
+}
+
+struct NoDestructorGuarded {
+    a: NoDestructor,
+    guard: i64
+}
+
+struct WithDestructorGuarded {
+    a: WithDestructor,
+    guard: i64
+}
+
+struct NestedInner {
+    a: WithDestructor
+}
+
+impl Drop for NestedInner {
+    fn drop(&mut self) {}
+}
+
+struct NestedOuter {
+    a: NestedInner
+}
+
+
+// The compiler adds a 'destructed' boolean field to structs implementing Drop. This field is used
+// at runtime to prevent drop() to be executed more than once (see middle::trans::adt).
+// This field must be incorporated by the debug info generation. Otherwise the debugger assumes a
+// wrong size/layout for the struct.
+fn main() {
+
+    let simple = WithDestructor { x: 10, y: 20 };
+
+    let noDestructor = NoDestructorGuarded {
+        a: NoDestructor { x: 10, y: 20 },
+        guard: -1
+    };
+
+    // If the destructor flag field is not incorporated into the debug info for 'WithDestructor'
+    // then the debugger will have an invalid offset for the field 'guard' and thus should not be
+    // able to read its value correctly (dots are padding bytes, D is the boolean destructor flag):
+    //
+    // 64 bit
+    //
+    // NoDestructorGuarded = 0000....00000000FFFFFFFF
+    //                       <--------------><------>
+    //                         NoDestructor   guard
+    //
+    //
+    // withDestructorGuarded = 0000....00000000D.......FFFFFFFF
+    //                         <--------------><------>          // How debug info says it is
+    //                          WithDestructor  guard
+    //
+    //                         <----------------------><------>  // How it actually is
+    //                              WithDestructor      guard
+    //
+    // 32 bit
+    //
+    // NoDestructorGuarded = 000000000000FFFFFFFF
+    //                       <----------><------>
+    //                       NoDestructor guard
+    //
+    //
+    // withDestructorGuarded = 000000000000D...FFFFFFFF
+    //                         <----------><------>      // How debug info says it is
+    //                      WithDestructor  guard
+    //
+    //                         <--------------><------>  // How it actually is
+    //                          WithDestructor  guard
+    //
+    let withDestructor = WithDestructorGuarded {
+        a: WithDestructor { x: 10, y: 20 },
+        guard: -1
+    };
+
+    // expected layout (64 bit) = xxxx....yyyyyyyyD.......D...
+    //                            <--WithDestructor------>
+    //                            <-------NestedInner-------->
+    //                            <-------NestedOuter-------->
+    let nested = NestedOuter { a: NestedInner { a: WithDestructor { x: 7890, y: 9870 } } };
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/text-to-include-1.txt b/src/test/debuginfo/text-to-include-1.txt
new file mode 100644 (file)
index 0000000..ba05527
--- /dev/null
@@ -0,0 +1 @@
+some text to include in another file as string 1
\ No newline at end of file
diff --git a/src/test/debuginfo/text-to-include-2.txt b/src/test/debuginfo/text-to-include-2.txt
new file mode 100644 (file)
index 0000000..a2caa5e
--- /dev/null
@@ -0,0 +1 @@
+some text to include in another file as string 2
\ No newline at end of file
diff --git a/src/test/debuginfo/text-to-include-3.txt b/src/test/debuginfo/text-to-include-3.txt
new file mode 100644 (file)
index 0000000..9933e6c
--- /dev/null
@@ -0,0 +1 @@
+some text to include in another file as string 3
\ No newline at end of file
diff --git a/src/test/debuginfo/trait-generic-static-default-method.rs b/src/test/debuginfo/trait-generic-static-default-method.rs
new file mode 100644 (file)
index 0000000..e91cd2f
--- /dev/null
@@ -0,0 +1,53 @@
+// ignore-test
+
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+
+// gdb-command:finish
+// gdb-command:print arg1
+// gdb-check:$1 = 1000
+// gdb-command:print arg2
+// gdb-check:$2 = 0.5
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print arg1
+// gdb-check:$3 = 2000
+// gdb-command:print *arg2
+// gdb-check:$4 = {1, 2, 3}
+// gdb-command: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() {()}
diff --git a/src/test/debuginfo/trait-pointers.rs b/src/test/debuginfo/trait-pointers.rs
new file mode 100644 (file)
index 0000000..e58ed4c
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:run
+
+#![allow(unused_variable)]
+
+
+trait Trait {
+    fn method(&self) -> int { 0 }
+}
+
+struct Struct {
+    a: int,
+    b: f64
+}
+
+impl Trait for Struct {}
+
+// There is no real test here yet. Just make sure that it compiles without crashing.
+fn main() {
+    let stack_struct = Struct { a:0, b: 1.0 };
+    let reference: &Trait = &stack_struct as &Trait;
+    let unique: Box<Trait> = box Struct { a:2, b: 3.0 } as Box<Trait>;
+}
diff --git a/src/test/debuginfo/tuple-in-struct.rs b/src/test/debuginfo/tuple-in-struct.rs
new file mode 100644 (file)
index 0000000..b38d354
--- /dev/null
@@ -0,0 +1,153 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:set print pretty off
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print no_padding1
+// gdb-check:$1 = {x = {0, 1}, y = 2, z = {3, 4, 5}}
+// gdb-command:print no_padding2
+// gdb-check:$2 = {x = {6, 7}, y = {{8, 9}, 10}}
+
+// gdb-command:print tuple_internal_padding
+// gdb-check:$3 = {x = {11, 12}, y = {13, 14}}
+// gdb-command:print struct_internal_padding
+// gdb-check:$4 = {x = {15, 16}, y = {17, 18}}
+// gdb-command:print both_internally_padded
+// gdb-check:$5 = {x = {19, 20, 21}, y = {22, 23}}
+
+// gdb-command:print single_tuple
+// gdb-check:$6 = {x = {24, 25, 26}}
+
+// gdb-command:print tuple_padded_at_end
+// gdb-check:$7 = {x = {27, 28}, y = {29, 30}}
+// gdb-command:print struct_padded_at_end
+// gdb-check:$8 = {x = {31, 32}, y = {33, 34}}
+// gdb-command:print both_padded_at_end
+// gdb-check:$9 = {x = {35, 36, 37}, y = {38, 39}}
+
+// gdb-command:print mixed_padding
+// gdb-check:$10 = {x = {{40, 41, 42}, {43, 44}}, y = {45, 46, 47, 48}}
+
+#![allow(unused_variable)]
+
+struct NoPadding1 {
+    x: (i32, i32),
+    y: i32,
+    z: (i32, i32, i32)
+}
+
+struct NoPadding2 {
+    x: (i32, i32),
+    y: ((i32, i32), i32)
+}
+
+struct TupleInternalPadding {
+    x: (i16, i32),
+    y: (i32, i64)
+}
+
+struct StructInternalPadding {
+    x: (i16, i16),
+    y: (i64, i64)
+}
+
+struct BothInternallyPadded {
+    x: (i16, i32, i32),
+    y: (i32, i64)
+}
+
+struct SingleTuple {
+    x: (i16, i32, i64)
+}
+
+struct TuplePaddedAtEnd {
+    x: (i32, i16),
+    y: (i64, i32)
+}
+
+struct StructPaddedAtEnd {
+    x: (i64, i64),
+    y: (i16, i16)
+}
+
+struct BothPaddedAtEnd {
+    x: (i32, i32, i16),
+    y: (i64, i32)
+}
+
+// Data-layout (padding signified by dots, one column = 2 bytes):
+// [a.bbc...ddddee..ffffg.hhi...]
+struct MixedPadding {
+    x: ((i16, i32, i16), (i64, i32)),
+    y: (i64, i16, i32, i16)
+}
+
+
+fn main() {
+    let no_padding1 = NoPadding1 {
+        x: (0, 1),
+        y: 2,
+        z: (3, 4, 5)
+    };
+
+    let no_padding2 = NoPadding2 {
+        x: (6, 7),
+        y: ((8, 9), 10)
+    };
+
+    let tuple_internal_padding = TupleInternalPadding {
+        x: (11, 12),
+        y: (13, 14)
+    };
+
+    let struct_internal_padding = StructInternalPadding {
+        x: (15, 16),
+        y: (17, 18)
+    };
+
+    let both_internally_padded = BothInternallyPadded {
+        x: (19, 20, 21),
+        y: (22, 23)
+    };
+
+    let single_tuple = SingleTuple {
+        x: (24, 25, 26)
+    };
+
+    let tuple_padded_at_end = TuplePaddedAtEnd {
+        x: (27, 28),
+        y: (29, 30)
+    };
+
+    let struct_padded_at_end = StructPaddedAtEnd {
+        x: (31, 32),
+        y: (33, 34)
+    };
+
+    let both_padded_at_end = BothPaddedAtEnd {
+        x: (35, 36, 37),
+        y: (38, 39)
+    };
+
+    let mixed_padding = MixedPadding {
+        x: ((40, 41, 42), (43, 44)),
+        y: (45, 46, 47, 48)
+    };
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/tuple-in-tuple.rs b/src/test/debuginfo/tuple-in-tuple.rs
new file mode 100644 (file)
index 0000000..3cc8b4e
--- /dev/null
@@ -0,0 +1,52 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:set print pretty off
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print no_padding1
+// gdb-check:$1 = {{0, 1}, 2, 3}
+// gdb-command:print no_padding2
+// gdb-check:$2 = {4, {5, 6}, 7}
+// gdb-command:print no_padding3
+// gdb-check:$3 = {8, 9, {10, 11}}
+
+// gdb-command:print internal_padding1
+// gdb-check:$4 = {12, {13, 14}}
+// gdb-command:print internal_padding2
+// gdb-check:$5 = {15, {16, 17}}
+
+// gdb-command:print padding_at_end1
+// gdb-check:$6 = {18, {19, 20}}
+// gdb-command:print padding_at_end2
+// gdb-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);
+    let no_padding3: (u32, u32, (u32, u32)) = (8, 9, (10, 11));
+
+    let internal_padding1: (i16, (i32, i32)) = (12, (13, 14));
+    let internal_padding2: (i16, (i16, i32)) = (15, (16, 17));
+
+    let padding_at_end1: (i32, (i32, i16)) = (18, (19, 20));
+    let padding_at_end2: ((i32, i16), i32) = ((21, 22), 23);
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/tuple-struct.rs b/src/test/debuginfo/tuple-struct.rs
new file mode 100644 (file)
index 0000000..cea0638
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:set print pretty off
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print no_padding16
+// gdb-check:$1 = {10000, -10001}
+
+// gdb-command:print no_padding32
+// gdb-check:$2 = {-10002, -10003.5, 10004}
+
+// gdb-command:print no_padding64
+// gdb-check:$3 = {-10005.5, 10006, 10007}
+
+// gdb-command:print no_padding163264
+// gdb-check:$4 = {-10008, 10009, 10010, 10011}
+
+// gdb-command:print internal_padding
+// gdb-check:$5 = {10012, -10013}
+
+// gdb-command:print padding_at_end
+// gdb-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 "<unnamed_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() {()}
diff --git a/src/test/debuginfo/tuple-style-enum.rs b/src/test/debuginfo/tuple-style-enum.rs
new file mode 100644 (file)
index 0000000..dc922b4
--- /dev/null
@@ -0,0 +1,76 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-tidy-linelength
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:set print union on
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print case1
+// gdb-check:$1 = {{Case1, 0, 31868, 31868, 31868, 31868}, {Case1, 0, 2088533116, 2088533116}, {Case1, 0, 8970181431921507452}}
+
+// gdb-command:print case2
+// gdb-check:$2 = {{Case2, 0, 4369, 4369, 4369, 4369}, {Case2, 0, 286331153, 286331153}, {Case2, 0, 1229782938247303441}}
+
+// gdb-command:print case3
+// gdb-check:$3 = {{Case3, 0, 22873, 22873, 22873, 22873}, {Case3, 0, 1499027801, 1499027801}, {Case3, 0, 6438275382588823897}}
+
+// gdb-command:print univariant
+// gdb-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.
+enum Regular {
+    Case1(u64, u16, u16, u16, u16),
+    Case2(u64, u32, u32),
+    Case3(u64, u64)
+}
+
+enum Univariant {
+    TheOnlyCase(i64)
+}
+
+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 = Case1(0, 31868, 31868, 31868, 31868);
+
+    // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
+    // 0b00010001000100010001000100010001 = 286331153
+    // 0b0001000100010001 = 4369
+    // 0b00010001 = 17
+    let case2 = Case2(0, 286331153, 286331153);
+
+    // 0b0101100101011001010110010101100101011001010110010101100101011001 = 6438275382588823897
+    // 0b01011001010110010101100101011001 = 1499027801
+    // 0b0101100101011001 = 22873
+    // 0b01011001 = 89
+    let case3 = Case3(0, 6438275382588823897);
+
+    let univariant = TheOnlyCase(-1);
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/unique-enum.rs b/src/test/debuginfo/unique-enum.rs
new file mode 100644 (file)
index 0000000..f85ec6a
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print *the_a
+// gdb-check:$1 = {{TheA, x = 0, y = 8970181431921507452}, {TheA, 0, 2088533116, 2088533116}}
+
+// gdb-command:print *the_b
+// gdb-check:$2 = {{TheB, x = 0, y = 1229782938247303441}, {TheB, 0, 286331153, 286331153}}
+
+// gdb-command:print *univariant
+// gdb-check:$3 = {123234}
+
+#![allow(unused_variable)]
+#![feature(struct_variant)]
+
+// 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 ABC {
+    TheA { x: i64, y: i64 },
+    TheB (i64, i32, i32),
+}
+
+// This is a special case since it does not have the implicit discriminant field.
+enum Univariant {
+    TheOnlyCase(i64)
+}
+
+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 the_a = box TheA { x: 0, y: 8970181431921507452 };
+
+    // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
+    // 0b00010001000100010001000100010001 = 286331153
+    // 0b0001000100010001 = 4369
+    // 0b00010001 = 17
+    let the_b = box TheB (0, 286331153, 286331153);
+
+    let univariant = box TheOnlyCase(123234);
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/var-captured-in-nested-closure.rs b/src/test/debuginfo/var-captured-in-nested-closure.rs
new file mode 100644 (file)
index 0000000..787c1cd
--- /dev/null
@@ -0,0 +1,90 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print variable
+// gdb-check:$1 = 1
+// gdb-command:print constant
+// gdb-check:$2 = 2
+// gdb-command:print a_struct
+// gdb-check:$3 = {a = -3, b = 4.5, c = 5}
+// gdb-command:print *struct_ref
+// gdb-check:$4 = {a = -3, b = 4.5, c = 5}
+// gdb-command:print *owned
+// gdb-check:$5 = 6
+// gdb-command:print managed->val
+// gdb-check:$6 = 7
+// gdb-command:print closure_local
+// gdb-check:$7 = 8
+// gdb-command:continue
+
+// gdb-command:finish
+// gdb-command:print variable
+// gdb-check:$8 = 1
+// gdb-command:print constant
+// gdb-check:$9 = 2
+// gdb-command:print a_struct
+// gdb-check:$10 = {a = -3, b = 4.5, c = 5}
+// gdb-command:print *struct_ref
+// gdb-check:$11 = {a = -3, b = 4.5, c = 5}
+// gdb-command:print *owned
+// gdb-check:$12 = 6
+// gdb-command:print managed->val
+// gdb-check:$13 = 7
+// gdb-command:print closure_local
+// gdb-check:$14 = 8
+// gdb-command:continue
+
+#![feature(managed_boxes)]
+#![allow(unused_variable)]
+
+struct Struct {
+    a: int,
+    b: f64,
+    c: uint
+}
+
+fn main() {
+    let mut variable = 1;
+    let constant = 2;
+
+    let a_struct = Struct {
+        a: -3,
+        b: 4.5,
+        c: 5
+    };
+
+    let struct_ref = &a_struct;
+    let owned = box 6;
+    let managed = @7;
+
+    let closure = || {
+        let closure_local = 8;
+
+        let nested_closure = || {
+            zzz();
+            variable = constant + a_struct.a + struct_ref.a + *owned + *managed + closure_local;
+        };
+
+        zzz();
+
+        nested_closure();
+    };
+
+    closure();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/var-captured-in-sendable-closure.rs b/src/test/debuginfo/var-captured-in-sendable-closure.rs
new file mode 100644 (file)
index 0000000..03525a3
--- /dev/null
@@ -0,0 +1,56 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print constant
+// gdb-check:$1 = 1
+// gdb-command:print a_struct
+// gdb-check:$2 = {a = -2, b = 3.5, c = 4}
+// gdb-command:print *owned
+// gdb-check:$3 = 5
+
+#![allow(unused_variable)]
+
+struct Struct {
+    a: int,
+    b: f64,
+    c: uint
+}
+
+fn main() {
+    let constant = 1;
+
+    let a_struct = Struct {
+        a: -2,
+        b: 3.5,
+        c: 4
+    };
+
+    let owned = box 5;
+
+    let closure: proc() = proc() {
+        zzz();
+        do_something(&constant, &a_struct.a, owned);
+    };
+
+    closure();
+}
+
+fn do_something(_: &int, _:&int, _:&int) {
+
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/var-captured-in-stack-closure.rs b/src/test/debuginfo/var-captured-in-stack-closure.rs
new file mode 100644 (file)
index 0000000..fc80933
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+
+// gdb-command:print variable
+// gdb-check:$1 = 1
+// gdb-command:print constant
+// gdb-check:$2 = 2
+// gdb-command:print a_struct
+// gdb-check:$3 = {a = -3, b = 4.5, c = 5}
+// gdb-command:print *struct_ref
+// gdb-check:$4 = {a = -3, b = 4.5, c = 5}
+// gdb-command:print *owned
+// gdb-check:$5 = 6
+// gdb-command:print managed->val
+// gdb-check:$6 = 7
+
+#![feature(managed_boxes)]
+#![allow(unused_variable)]
+
+struct Struct {
+    a: int,
+    b: f64,
+    c: uint
+}
+
+fn main() {
+    let mut variable = 1;
+    let constant = 2;
+
+    let a_struct = Struct {
+        a: -3,
+        b: 4.5,
+        c: 5
+    };
+
+    let struct_ref = &a_struct;
+    let owned = box 6;
+    let managed = @7;
+
+    let closure = || {
+        zzz();
+        variable = constant + a_struct.a + struct_ref.a + *owned + *managed;
+    };
+
+    closure();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/vec-slices.rs b/src/test/debuginfo/vec-slices.rs
new file mode 100644 (file)
index 0000000..783b198
--- /dev/null
@@ -0,0 +1,87 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-win32: FIXME #13256
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:set print pretty off
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+// gdb-command:print empty.length
+// gdb-check:$1 = 0
+
+// gdb-command:print singleton.length
+// gdb-check:$2 = 1
+// gdb-command:print *((int64_t[1]*)(singleton.data_ptr))
+// gdb-check:$3 = {1}
+
+// gdb-command:print multiple.length
+// gdb-check:$4 = 4
+// gdb-command:print *((int64_t[4]*)(multiple.data_ptr))
+// gdb-check:$5 = {2, 3, 4, 5}
+
+// gdb-command:print slice_of_slice.length
+// gdb-check:$6 = 2
+// gdb-command:print *((int64_t[2]*)(slice_of_slice.data_ptr))
+// gdb-check:$7 = {3, 4}
+
+// gdb-command:print padded_tuple.length
+// gdb-check:$8 = 2
+// gdb-command:print padded_tuple.data_ptr[0]
+// gdb-check:$9 = {6, 7}
+// gdb-command:print padded_tuple.data_ptr[1]
+// gdb-check:$10 = {8, 9}
+
+// gdb-command:print padded_struct.length
+// gdb-check:$11 = 2
+// gdb-command:print padded_struct.data_ptr[0]
+// gdb-check:$12 = {x = 10, y = 11, z = 12}
+// gdb-command:print padded_struct.data_ptr[1]
+// gdb-check:$13 = {x = 13, y = 14, z = 15}
+
+// gdb-command:print 'vec-slices::MUT_VECT_SLICE'.length
+// gdb-check:$14 = 2
+// gdb-command:print *((int64_t[2]*)('vec-slices::MUT_VECT_SLICE'.data_ptr))
+// gdb-check:$15 = {64, 65}
+
+#![allow(unused_variable)]
+
+struct AStruct {
+    x: i16,
+    y: i32,
+    z: i16
+}
+
+static VECT_SLICE: &'static [i64] = &[64, 65];
+static mut MUT_VECT_SLICE: &'static [i64] = &[32];
+
+fn main() {
+    let empty: &[i64] = &[];
+    let singleton: &[i64] = &[1];
+    let multiple: &[i64] = &[2, 3, 4, 5];
+    let slice_of_slice = multiple.slice(1,3);
+
+    let padded_tuple: &[(i32, i16)] = &[(6, 7), (8, 9)];
+
+    let padded_struct: &[AStruct] = &[
+        AStruct { x: 10, y: 11, z: 12 },
+        AStruct { x: 13, y: 14, z: 15 }
+    ];
+
+    unsafe {
+        MUT_VECT_SLICE = VECT_SLICE;
+    }
+
+    zzz();
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/vec.rs b/src/test/debuginfo/vec.rs
new file mode 100644 (file)
index 0000000..11f3174
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-win32: FIXME #13256
+// ignore-android: FIXME(#10381)
+
+// compile-flags:-g
+// gdb-command:set print pretty off
+// gdb-command:rbreak zzz
+// gdb-command:run
+// gdb-command:finish
+// gdb-command:print a
+// gdb-check:$1 = {1, 2, 3}
+// gdb-command:print vec::VECT
+// gdb-check:$2 = {4, 5, 6}
+
+#![allow(unused_variable)]
+
+static mut VECT: [i32, ..3] = [1, 2, 3];
+
+fn main() {
+    let a = [1, 2, 3];
+
+    unsafe {
+        VECT[0] = 4;
+        VECT[1] = 5;
+        VECT[2] = 6;
+    }
+
+    zzz();
+}
+
+fn zzz() {()}
index d54c04b77b0d8fbc9a5d1848de53ca6ac74998c0..a08d6bb0bf87fdb45ea3c309e80a0be2305225bd 100644 (file)
@@ -36,8 +36,8 @@ fn random_char() -> char {
 
 fn main() {
     let args = os::args();
-    let rustc = args[1].as_slice();
-    let tmpdir = Path::new(args[2].as_slice());
+    let rustc = args.get(1).as_slice();
+    let tmpdir = Path::new(args.get(2).as_slice());
 
     let main_file = tmpdir.join("unicode_input_multiple_files_main.rs");
     let main_file_str = main_file.as_str().unwrap();
index 5f4af50753ec7c04afc4251f7964bd8ec8191ddf..13f141008b7929775a1a979a8dace1317896b2fd 100644 (file)
@@ -35,8 +35,8 @@ fn random_char() -> char {
 
 fn main() {
     let args = os::args();
-    let rustc = args[1].as_slice();
-    let tmpdir = Path::new(args[2].as_slice());
+    let rustc = args.get(1).as_slice();
+    let tmpdir = Path::new(args.get(2).as_slice());
 
     let main_file = tmpdir.join("span_main.rs");
     let main_file_str = main_file.as_str().unwrap();
index 0277cb35f528635b64f1ae0aa2c3c489c1339096..989453d8570d169ae14b1dafb3d966dd479261c1 100644 (file)
@@ -100,6 +100,7 @@ fn runtest(me: &str) {
 
 fn main() {
     let args = os::args();
+    let args = args.as_slice();
     if args.len() >= 2 && args[1].as_slice() == "fail" {
         foo();
     } else if args.len() >= 2 && args[1].as_slice() == "double-fail" {
index 76d73fd5b8705874a88652906215a51ab064c8e0..c409852c6736cd63022a2cf9bbe2d4eb8266fede 100644 (file)
@@ -24,6 +24,7 @@
 
 pub fn main() {
     let args = os::args();
+    let args = args.as_slice();
 
     // Here, the rvalue `"signal".to_owned()` requires cleanup. Older versions
     // of the code had a problem that the cleanup scope for this
diff --git a/src/test/run-pass/issue-10025.rs b/src/test/run-pass/issue-10025.rs
new file mode 100644 (file)
index 0000000..8f494ea
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+unsafe extern fn foo() {}
+unsafe extern "C" fn bar() {}
+
+fn main() {
+    let _a: unsafe extern fn() = foo;
+    let _a: unsafe extern "C" fn() = foo;
+}
index a430e1c8de91668c485ec0d974f3601f71015bd8..38030eb6c1fdcb72cb0a1c70ffb114795958665f 100644 (file)
@@ -17,6 +17,7 @@
 
 pub fn main () {
     let args = os::args();
+    let args = args.as_slice();
     if args.len() > 1 && args[1] == "child".to_owned() {
         for _ in range(0, 1000) {
             println!("hello?");
index aa4deeb73c9317c33f7de375169fab42278b91bc..f66b943d85f64fbedc624ceb0e81923fc4e74b67 100644 (file)
@@ -25,6 +25,7 @@ fn start(argc: int, argv: **u8) -> int {
 
 fn main() {
     let args = os::args();
+    let args = args.as_slice();
     if args.len() > 1 && args[1].as_slice() == "child" {
         if args[2].as_slice() == "green" {
             child();
@@ -48,6 +49,7 @@ fn main() {
 
 fn parent(flavor: ~str) {
     let args = os::args();
+    let args = args.as_slice();
     let mut p = io::Process::new(args[0].as_slice(), ["child".to_owned(), flavor]).unwrap();
     p.stdin.get_mut_ref().write_str("test1\ntest2\ntest3").unwrap();
     let out = p.wait_with_output();
index adc5c86aa4aeb5acb46372673f7d4e842e18002b..f05b1932b738dd2916663b7655f628faabef65ec 100644 (file)
@@ -10,6 +10,7 @@
 
 fn parse_args() -> ~str {
     let args = ::std::os::args();
+    let args = args.as_slice();
     let mut n = 0;
 
     while n < args.len() {
index d051f91811507f7bca42beccc67138828b0c190d..a5e632b94a28888c7437d2dae2d2ad10885d0e7c 100644 (file)
@@ -22,6 +22,7 @@
 
 fn main() {
     let args = os::args();
+    let args = args.as_slice();
     if args.len() > 1 && args[1].as_slice() == "child" {
         debug!("foo");
         debug!("bar");
index e03256bfe499d275ef4aa8ea10716676077639cf..730b0b08d451abda2f3ba88e005a09303164d430 100644 (file)
@@ -8,8 +8,6 @@
 // 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 {
@@ -17,12 +15,12 @@ mod bar {
 }
 
 pub fn main() {
-    local_data::get(foo, |x| assert!(x.is_none()));
-    local_data::get(bar::baz, |y| assert!(y.is_none()));
+    assert!(foo.get().is_none());
+    assert!(bar::baz.get().is_none());
 
-    local_data::set(foo, 3);
-    local_data::set(bar::baz, -10.0);
+    foo.replace(Some(3));
+    bar::baz.replace(Some(-10.0));
 
-    local_data::get(foo, |x| assert_eq!(*x.unwrap(), 3));
-    local_data::get(bar::baz, |y| assert_eq!(*y.unwrap(), -10.0));
+    assert_eq!(*foo.get().unwrap(), 3);
+    assert_eq!(*bar::baz.get().unwrap(), -10.0);
 }
index 674286751cbae5ee96c87a6f3c89314a092feda6..ac3a9ef2d533089cea13c32ad362136e1f05e3f5 100644 (file)
@@ -34,6 +34,7 @@ fn loud_recurse() {
 
 fn main() {
     let args = os::args();
+    let args = args.as_slice();
     if args.len() > 1 && args[1].as_slice() == "silent" {
         silent_recurse();
     } else if args.len() > 1 && args[1].as_slice() == "loud" {
index ce748d8684dd8bace87c697d6ead93335d9a1038..e4a935eae7f431af3ebd99082bdc74d9ca9a266b 100644 (file)
@@ -62,7 +62,7 @@ pub fn main() {
 
     assert!(map.pop(&Slice("foo")).is_some());
     assert_eq!(map.move_iter().map(|(k, v)| k.to_str() + v.to_str())
-                              .collect::<~[~str]>()
+                              .collect::<Vec<~str>>()
                               .concat(),
                "abc50bcd51cde52def53".to_owned());
 }
index 4afdec1ac06c518f11eb3823f5b5c7e0ab34cb55..a0459e6e8c1ada7d6d3f9fea5af9c2101b7543d6 100644 (file)
@@ -25,6 +25,7 @@
 
 pub fn main() {
     let args = os::args();
+    let args = args.as_slice();
     if args.len() >= 2 && args[1] == "signal".to_owned() {
         // Raise a segfault.
         unsafe { *(0 as *mut int) = 0; }
index b923bb91427fe64a111df82a5abd543138431fd5..34d1f5e66c6782a66f700aad2b67933d8a5a94e5 100644 (file)
@@ -25,6 +25,7 @@ fn test() {
 
 fn main() {
     let args = os::args();
+    let args = args.as_slice();
     if args.len() > 1 && args[1].as_slice() == "test" {
         return test();
     }
index e104f92a8bc93eed92d1f680fb20239a4e05d144..794f810165dcb46380f3f1d011ed121ebc45dac7 100644 (file)
@@ -20,7 +20,7 @@ fn to_string(&self) -> ~str { self.to_str() }
 
 impl<T:to_str> to_str for Vec<T> {
     fn to_string(&self) -> ~str {
-        format!("[{}]", self.iter().map(|e| e.to_string()).collect::<~[~str]>().connect(", "))
+        format!("[{}]", self.iter().map(|e| e.to_string()).collect::<Vec<~str>>().connect(", "))
     }
 }