]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #15422 : steveklabnik/rust/guide_compound_data_types, r=brson
authorbors <bors@rust-lang.org>
Wed, 9 Jul 2014 02:21:37 +0000 (02:21 +0000)
committerbors <bors@rust-lang.org>
Wed, 9 Jul 2014 02:21:37 +0000 (02:21 +0000)
I'm not happy about the hand-waving around `cmp`, but I'm not sure how to get around it.

388 files changed:
RELEASES.txt
configure
man/rustc.1
mk/main.mk
mk/target.mk
mk/tests.mk
src/compiletest/compiletest.rs
src/compiletest/errors.rs
src/compiletest/util.rs
src/doc/guide-tasks.md
src/doc/guide.md
src/doc/po/ja/complement-cheatsheet.md.po
src/doc/po/ja/rust.md.po
src/doc/po/ja/tutorial.md.po
src/doc/rust.md
src/doc/tutorial.md
src/etc/vim/ftplugin/rust.vim
src/etc/vim/syntax/rust.vim
src/liballoc/lib.rs
src/libarena/lib.rs
src/libcollections/bitv.rs
src/libcollections/btree.rs
src/libcollections/dlist.rs
src/libcollections/lib.rs
src/libcollections/smallintmap.rs
src/libcollections/str.rs
src/libcollections/string.rs
src/libcollections/vec.rs
src/libcore/cmp.rs
src/libcore/fmt/float.rs
src/libcore/lib.rs
src/libcore/ops.rs
src/libcore/prelude.rs
src/libcore/result.rs
src/libcore/slice.rs
src/libcoretest/char.rs
src/libdebug/fmt.rs
src/libdebug/lib.rs
src/libdebug/repr.rs
src/libflate/lib.rs
src/libfmt_macros/lib.rs
src/libfourcc/lib.rs
src/libgetopts/lib.rs
src/libglob/lib.rs
src/libgraphviz/lib.rs
src/libgreen/lib.rs
src/libhexfloat/lib.rs
src/liblibc/lib.rs
src/liblog/lib.rs
src/libnative/io/file_win32.rs
src/libnative/io/pipe_unix.rs
src/libnative/io/pipe_win32.rs
src/libnative/io/process.rs
src/libnative/io/util.rs
src/libnative/lib.rs
src/libnum/bigint.rs
src/libnum/complex.rs
src/libnum/lib.rs
src/libnum/rational.rs
src/librand/lib.rs
src/libregex/lib.rs
src/libregex_macros/lib.rs
src/librlibc/lib.rs
src/librustc/back/link.rs
src/librustc/back/svh.rs
src/librustc/driver/config.rs
src/librustc/driver/driver.rs
src/librustc/driver/mod.rs
src/librustc/driver/session.rs
src/librustc/front/config.rs
src/librustc/front/std_inject.rs
src/librustc/front/test.rs
src/librustc/lib.rs
src/librustc/lib/llvm.rs
src/librustc/lint/builtin.rs
src/librustc/lint/context.rs
src/librustc/metadata/common.rs
src/librustc/metadata/creader.rs
src/librustc/metadata/cstore.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/encoder.rs
src/librustc/metadata/loader.rs
src/librustc/metadata/tyencode.rs
src/librustc/middle/astencode.rs
src/librustc/middle/borrowck/check_loans.rs
src/librustc/middle/borrowck/gather_loans/move_error.rs
src/librustc/middle/borrowck/mod.rs
src/librustc/middle/cfg/graphviz.rs
src/librustc/middle/check_const.rs
src/librustc/middle/check_match.rs
src/librustc/middle/check_static.rs
src/librustc/middle/dataflow.rs
src/librustc/middle/dead.rs
src/librustc/middle/effect.rs
src/librustc/middle/kind.rs
src/librustc/middle/lang_items.rs
src/librustc/middle/liveness.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/privacy.rs
src/librustc/middle/reachable.rs
src/librustc/middle/region.rs
src/librustc/middle/resolve.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/middle/save/mod.rs
src/librustc/middle/save/recorder.rs
src/librustc/middle/subst.rs
src/librustc/middle/trans/_match.rs
src/librustc/middle/trans/adt.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/build.rs
src/librustc/middle/trans/builder.rs
src/librustc/middle/trans/cabi_arm.rs
src/librustc/middle/trans/cabi_mips.rs
src/librustc/middle/trans/cabi_x86.rs
src/librustc/middle/trans/cabi_x86_64.rs
src/librustc/middle/trans/callee.rs
src/librustc/middle/trans/cleanup.rs
src/librustc/middle/trans/closure.rs
src/librustc/middle/trans/common.rs
src/librustc/middle/trans/consts.rs
src/librustc/middle/trans/controlflow.rs
src/librustc/middle/trans/datum.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/expr.rs
src/librustc/middle/trans/foreign.rs
src/librustc/middle/trans/glue.rs
src/librustc/middle/trans/intrinsic.rs
src/librustc/middle/trans/llrepr.rs
src/librustc/middle/trans/monomorphize.rs
src/librustc/middle/trans/reflect.rs
src/librustc/middle/trans/tvec.rs
src/librustc/middle/trans/type_.rs
src/librustc/middle/trans/type_of.rs
src/librustc/middle/ty.rs
src/librustc/middle/typeck/astconv.rs
src/librustc/middle/typeck/check/_match.rs
src/librustc/middle/typeck/check/method.rs
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/check/regionck.rs
src/librustc/middle/typeck/check/regionmanip.rs
src/librustc/middle/typeck/check/vtable.rs
src/librustc/middle/typeck/check/writeback.rs
src/librustc/middle/typeck/coherence.rs
src/librustc/middle/typeck/collect.rs
src/librustc/middle/typeck/infer/combine.rs
src/librustc/middle/typeck/infer/error_reporting.rs
src/librustc/middle/typeck/infer/glb.rs
src/librustc/middle/typeck/infer/lattice.rs
src/librustc/middle/typeck/infer/lub.rs
src/librustc/middle/typeck/infer/mod.rs
src/librustc/middle/typeck/infer/resolve.rs
src/librustc/middle/typeck/infer/sub.rs
src/librustc/middle/typeck/infer/test.rs
src/librustc/middle/typeck/mod.rs
src/librustc/middle/typeck/variance.rs
src/librustc/util/ppaux.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.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/test.rs
src/librustrt/c_str.rs
src/librustrt/lib.rs
src/librustuv/lib.rs
src/librustuv/net.rs
src/libsemver/lib.rs
src/libserialize/json.rs
src/libserialize/lib.rs
src/libserialize/serialize.rs
src/libstd/ascii.rs
src/libstd/collections/hashmap.rs
src/libstd/collections/lru_cache.rs
src/libstd/dynamic_lib.rs
src/libstd/from_str.rs
src/libstd/io/extensions.rs
src/libstd/io/fs.rs
src/libstd/io/mem.rs
src/libstd/io/mod.rs
src/libstd/io/net/ip.rs
src/libstd/io/net/tcp.rs
src/libstd/io/process.rs
src/libstd/io/stdio.rs
src/libstd/io/util.rs
src/libstd/lib.rs
src/libstd/num/f32.rs
src/libstd/num/f64.rs
src/libstd/num/int_macros.rs
src/libstd/num/strconv.rs
src/libstd/num/uint_macros.rs
src/libstd/os.rs
src/libstd/path/posix.rs
src/libstd/path/windows.rs
src/libstd/prelude.rs
src/libstd/rt/backtrace.rs
src/libstd/task.rs
src/libstd/to_str.rs
src/libsync/lib.rs
src/libsyntax/ast.rs
src/libsyntax/ast_map.rs
src/libsyntax/ast_util.rs
src/libsyntax/attr.rs
src/libsyntax/codemap.rs
src/libsyntax/diagnostic.rs
src/libsyntax/ext/asm.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/deriving/decodable.rs
src/libsyntax/ext/deriving/encodable.rs
src/libsyntax/ext/deriving/generic/mod.rs
src/libsyntax/ext/deriving/generic/ty.rs
src/libsyntax/ext/deriving/hash.rs
src/libsyntax/ext/deriving/rand.rs
src/libsyntax/ext/env.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/format.rs
src/libsyntax/ext/log_syntax.rs
src/libsyntax/ext/mtwt.rs
src/libsyntax/ext/quote.rs
src/libsyntax/ext/source_util.rs
src/libsyntax/ext/tt/macro_parser.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/fold.rs
src/libsyntax/lib.rs
src/libsyntax/parse/attr.rs
src/libsyntax/parse/lexer/comments.rs
src/libsyntax/parse/lexer/mod.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/parser.rs
src/libsyntax/parse/token.rs
src/libsyntax/print/pprust.rs
src/libterm/lib.rs
src/libterm/terminfo/parser/compiled.rs
src/libtest/lib.rs
src/libtest/stats.rs
src/libtime/lib.rs
src/liburl/lib.rs
src/libuuid/lib.rs
src/snapshots.txt
src/test/auxiliary/crateresolve1-1.rs
src/test/auxiliary/crateresolve1-2.rs
src/test/auxiliary/crateresolve1-3.rs
src/test/auxiliary/crateresolve2-1.rs [deleted file]
src/test/auxiliary/crateresolve2-2.rs [deleted file]
src/test/auxiliary/crateresolve2-3.rs [deleted file]
src/test/auxiliary/extern-crosscrate-source.rs
src/test/auxiliary/issue-11908-1.rs [deleted file]
src/test/auxiliary/issue-11908-2.rs [deleted file]
src/test/auxiliary/issue2378a.rs [deleted file]
src/test/auxiliary/issue2378b.rs [deleted file]
src/test/auxiliary/xcrate_struct_aliases.rs [new file with mode: 0644]
src/test/bench/core-set.rs
src/test/bench/core-uint-to-str.rs
src/test/bench/shootout-chameneos-redux.rs
src/test/bench/shootout-k-nucleotide-pipes.rs
src/test/bench/shootout-pfib.rs
src/test/bench/shootout-regex-dna.rs
src/test/compile-fail/bad-crate-id.rs
src/test/compile-fail/bad-crate-id2.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-forbid-static-unsafe-interior.rs
src/test/compile-fail/borrowck-overloaded-index.rs [new file with mode: 0644]
src/test/compile-fail/check-static-values-constraints.rs
src/test/compile-fail/crateresolve2.rs [deleted file]
src/test/compile-fail/crateresolve5.rs [deleted file]
src/test/compile-fail/dup-struct-enum-struct-variant.rs
src/test/compile-fail/enum-and-module-in-same-scope.rs [new file with mode: 0644]
src/test/compile-fail/issue-11908-1.rs [deleted file]
src/test/compile-fail/issue-11908-2.rs [deleted file]
src/test/compile-fail/issue-12187-1.rs [new file with mode: 0644]
src/test/compile-fail/issue-12187-2.rs [new file with mode: 0644]
src/test/compile-fail/issue-14541.rs
src/test/compile-fail/issue-2063.rs
src/test/compile-fail/issue-3099-a.rs
src/test/compile-fail/issue-3099-b.rs
src/test/compile-fail/issue-3973.rs
src/test/compile-fail/lint-uppercase-variables.rs
src/test/compile-fail/moves-based-on-type-block-bad.rs
src/test/compile-fail/multitrait.rs
src/test/compile-fail/no-implicit-prelude-nested.rs
src/test/compile-fail/no-implicit-prelude.rs
src/test/compile-fail/non-exhaustive-pattern-witness.rs
src/test/compile-fail/uninhabited-enum-cast.rs
src/test/compile-fail/unsized-bare-typaram.rs
src/test/compile-fail/unsized-enum.rs
src/test/compile-fail/unsized-struct.rs
src/test/compile-fail/unsized3.rs
src/test/compile-fail/unsized4.rs
src/test/compile-fail/unsized5.rs
src/test/compile-fail/unsized6.rs
src/test/compile-fail/use-after-move-implicity-coerced-object.rs
src/test/compile-fail/use-meta.rc [deleted file]
src/test/debuginfo/cross-crate-type-uniquing.rs
src/test/run-make/bootstrap-from-c-with-green/Makefile
src/test/run-make/bootstrap-from-c-with-green/lib.rs
src/test/run-make/bootstrap-from-c-with-native/Makefile
src/test/run-make/c-link-to-rust-dylib/Makefile
src/test/run-make/c-link-to-rust-staticlib/Makefile
src/test/run-make/crate-data-smoke/Makefile
src/test/run-make/crate-data-smoke/crate.rs
src/test/run-make/crate-data-smoke/lib.rs
src/test/run-make/crate-data-smoke/rlib.rs
src/test/run-make/crate-name-priority/Makefile [new file with mode: 0644]
src/test/run-make/crate-name-priority/foo.rs [new file with mode: 0644]
src/test/run-make/crate-name-priority/foo1.rs [new file with mode: 0644]
src/test/run-make/dep-info/lib.rs
src/test/run-make/extern-flag-disambiguates/Makefile [new file with mode: 0644]
src/test/run-make/extern-flag-disambiguates/a.rs [new file with mode: 0644]
src/test/run-make/extern-flag-disambiguates/b.rs [new file with mode: 0644]
src/test/run-make/extern-flag-disambiguates/c.rs [new file with mode: 0644]
src/test/run-make/extern-flag-disambiguates/d.rs [new file with mode: 0644]
src/test/run-make/extern-flag-fun/Makefile [new file with mode: 0644]
src/test/run-make/extern-flag-fun/bar.rs [new file with mode: 0644]
src/test/run-make/extern-flag-fun/foo.rs [new file with mode: 0644]
src/test/run-make/graphviz-flowgraph/f06.dot-expected.dot
src/test/run-make/issue-11908/Makefile [new file with mode: 0644]
src/test/run-make/issue-11908/bar.rs [new file with mode: 0644]
src/test/run-make/issue-11908/foo.rs [new file with mode: 0644]
src/test/run-make/lto-smoke-c/Makefile
src/test/run-make/lto-syntax-extension/lib.rs
src/test/run-make/manual-crate-name/Makefile [new file with mode: 0644]
src/test/run-make/manual-crate-name/bar.rs [new file with mode: 0644]
src/test/run-make/metadata-flag-frobs-symbols/Makefile [new file with mode: 0644]
src/test/run-make/metadata-flag-frobs-symbols/bar.rs [new file with mode: 0644]
src/test/run-make/metadata-flag-frobs-symbols/foo.rs [new file with mode: 0644]
src/test/run-make/multiple-versions/Makefile [new file with mode: 0644]
src/test/run-make/multiple-versions/bar.rs [new file with mode: 0644]
src/test/run-make/multiple-versions/foo.rs [new file with mode: 0644]
src/test/run-make/output-type-permutations/foo.rs
src/test/run-make/weird-output-filenames/Makefile
src/test/run-pass/bitv-perf-test.rs
src/test/run-pass/bool.rs
src/test/run-pass/byte-literals.rs
src/test/run-pass/capturing-logging.rs
src/test/run-pass/class-cast-to-trait-cross-crate-2.rs
src/test/run-pass/class-separate-impl.rs
src/test/run-pass/crateresolve1.rs [deleted file]
src/test/run-pass/crateresolve2.rs [deleted file]
src/test/run-pass/crateresolve3.rs [deleted file]
src/test/run-pass/crateresolve4.rs [deleted file]
src/test/run-pass/crateresolve5.rs [deleted file]
src/test/run-pass/crateresolve8.rs [deleted file]
src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs [new file with mode: 0644]
src/test/run-pass/deriving-show-2.rs
src/test/run-pass/enum-null-pointer-opt.rs [new file with mode: 0644]
src/test/run-pass/exponential-notation.rs
src/test/run-pass/extern-crosscrate.rs
src/test/run-pass/fixed_length_vec_glue.rs
src/test/run-pass/issue-11736.rs
src/test/run-pass/issue-15487.rs [new file with mode: 0644]
src/test/run-pass/issue-2904.rs
src/test/run-pass/issue-3037.rs
src/test/run-pass/issue-3559.rs
src/test/run-pass/issue-3563-3.rs
src/test/run-pass/issue-3702.rs
src/test/run-pass/issue-4241.rs
src/test/run-pass/issue-5280.rs
src/test/run-pass/issue-5917.rs
src/test/run-pass/issue-8578.rs
src/test/run-pass/issue2378c.rs [deleted file]
src/test/run-pass/match-pattern-bindings.rs [new file with mode: 0644]
src/test/run-pass/monad.rs
src/test/run-pass/move-out-of-field.rs
src/test/run-pass/new-impl-syntax.rs
src/test/run-pass/operator-overloading.rs
src/test/run-pass/order-drop-with-match.rs [new file with mode: 0644]
src/test/run-pass/overload-index-operator.rs
src/test/run-pass/overloaded-deref-count.rs
src/test/run-pass/overloaded-index.rs [new file with mode: 0644]
src/test/run-pass/send_str_treemap.rs
src/test/run-pass/static-impl.rs
src/test/run-pass/struct-aliases-xcrate.rs [new file with mode: 0644]
src/test/run-pass/struct-aliases.rs [new file with mode: 0644]
src/test/run-pass/task-stderr.rs
src/test/run-pass/tcp-connect-timeouts.rs
src/test/run-pass/tcp-stress.rs
src/test/run-pass/test-ignore-cfg.rs
src/test/run-pass/trait-cast.rs
src/test/run-pass/trait-generic.rs
src/test/run-pass/trait-to-str.rs
src/test/run-pass/trans-tag-static-padding.rs
src/test/run-pass/typeck_type_placeholder_1.rs
src/test/run-pass/unsized.rs
src/test/run-pass/unsized2.rs
src/test/run-pass/use.rs
src/test/run-pass/vec-to_str.rs

index 457328b2c90ca32ab54991f0ff1c21516a6e697c..ba87e575056377ecae8c1ab4fa536379ff5380fb 100644 (file)
@@ -306,7 +306,7 @@ Version 0.9 (January 2014)
       * A new facility for enabling experimental features (feature gating) has
         been added, using the crate-level `#[feature(foo)]` attribute.
       * Managed boxes (@) are now behind a feature gate
-        (`#[feature(managed_boxes)]`) in preperation for future removal. Use the
+        (`#[feature(managed_boxes)]`) in preparation for future removal. Use the
         standard library's `Gc` or `Rc` types instead.
       * `@mut` has been removed. Use `std::cell::{Cell, RefCell}` instead.
       * Jumping back to the top of a loop is now done with `continue` instead of
@@ -398,7 +398,7 @@ Version 0.9 (January 2014)
       * std: `fmt::Default` can be implemented for any type to provide default
         formatting to the `format!` macro, as in `format!("{}", myfoo)`.
       * std: The `rand` API continues to be tweaked.
-      * std: The `rust_begin_unwind` function, useful for insterting breakpoints
+      * std: The `rust_begin_unwind` function, useful for inserting breakpoints
         on failure in gdb, is now named `rust_fail`.
       * std: The `each_key` and `each_value` methods on `HashMap` have been
         replaced by the `keys` and `values` iterators.
@@ -429,7 +429,7 @@ Version 0.9 (January 2014)
         extensible interfaces and is now implemented by two different crates:
         libnative, for native threading and I/O; and libgreen, for green threading
         and I/O. This paves the way for using the standard library in more limited
-        embeded environments.
+        embedded environments.
       * std: The `comm` module has been rewritten to be much faster, have a
         simpler, more consistent API, and to work for both native and green
         threading.
index 59aa6ece6b2f1c230fa028f2ff722afc1b7758f5..135bdcd3782f06d54435328ab53e2e4f7f56bd86 100755 (executable)
--- a/configure
+++ b/configure
@@ -418,7 +418,7 @@ opt ccache 0 "invoke gcc/clang via ccache to reuse object files between builds"
 opt local-rust 0 "use an installed rustc rather than downloading a snapshot"
 opt inject-std-version 1 "inject the current compiler version of libstd into programs"
 opt llvm-static-stdcpp 0 "statically link to libstdc++ for LLVM"
-opt rpath 1 "build rpaths into rustc itself"
+opt rpath 0 "build rpaths into rustc itself"
 opt nightly 0 "build nightly packages"
 opt verify-install 1 "verify installed binaries work"
 opt jemalloc 1 "build liballoc with jemalloc"
index df65cf7bb37ffdd41d4179763c0f7557adbb12a7..2484960cac6da5f2d9b78056b573ca9a62bbd1a2 100644 (file)
@@ -138,8 +138,8 @@ A space-separated list of arguments to pass through to LLVM.
 If specified, the compiler will save more files (.bc, .o, .no-opt.bc) generated
 throughout compilation in the output directory.
 .TP
-\fBno-rpath\fR
-If specified, then the rpath value for dynamic libraries will not be set in
+\fBrpath\fR
+If specified, then the rpath value for dynamic libraries will be set in
 either dynamic library or executable outputs.
 .TP
 \fBno-prepopulate-passes\fR
index c4be89033a648933ab411ad7196184b582e074f5..7400b39c9680ca2d278e948f398b78fdbb7ab971 100644 (file)
@@ -16,6 +16,8 @@
 CFG_RELEASE_NUM=0.11.0
 CFG_RELEASE_LABEL=
 
+CFG_FILENAME_EXTRA=4e7c5e5c
+
 ifndef CFG_ENABLE_NIGHTLY
 # This is the normal version string
 CFG_RELEASE=$(CFG_RELEASE_NUM)$(CFG_RELEASE_LABEL)
@@ -120,8 +122,8 @@ endif
 ifdef TRACE
   CFG_RUSTC_FLAGS += -Z trace
 endif
-ifdef CFG_DISABLE_RPATH
-CFG_RUSTC_FLAGS += -C no-rpath
+ifdef CFG_ENABLE_RPATH
+CFG_RUSTC_FLAGS += -C rpath
 endif
 
 # The executables crated during this compilation process have no need to include
index 0f63ef9a430d0424323b0f69c8b55f9a664d8e90..1bdbf53af7ed1a76c6ee3b106312b0ba0e6ee1c4 100644 (file)
@@ -68,6 +68,15 @@ $(foreach host,$(CFG_HOST),                                              \
 # $(4) is the crate name
 define RUST_TARGET_STAGE_N
 
+# NOTE: after a stage0 snap this should be just EXTRA_FILENAME, not with a stage
+# or target bound
+EXTRA_FILENAME_$(1)_$(2) = -C extra-filename=-$$(CFG_FILENAME_EXTRA)
+ifeq ($(1),0)
+ifeq ($$(CFG_BUILD),$(2))
+EXTRA_FILENAME_$(1)_$(2) =
+endif
+endif
+
 $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): CFG_COMPILER_HOST_TRIPLE = $(2)
 $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4):                             \
                $$(CRATEFILE_$(4))                                  \
@@ -85,7 +94,9 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4):                                    \
                -L "$$(LLVM_LIBDIR_$(2))" \
                -L "$$(dir $$(LLVM_STDCPP_LOCATION_$(2)))" \
                $$(RUSTFLAGS_$(4)) \
-               --out-dir $$(@D) $$<
+               --out-dir $$(@D) \
+               $$(EXTRA_FILENAME_$(1)_$(2)) \
+               $$<
        @touch $$@
        $$(call LIST_ALL_OLD_GLOB_MATCHES,\
            $$(dir $$@)$$(call CFG_LIB_GLOB_$(2),$(4)))
index 44bedde99ccffdba2a1571000adc371b601da523..37540af4f6869d73157fc602a445004930f97768 100644 (file)
@@ -171,7 +171,7 @@ endif
 # Main test targets
 ######################################################################
 
-check: cleantmptestlogs cleantestlibs tidy check-notidy
+check: cleantmptestlogs cleantestlibs check-notidy tidy
 
 check-notidy: cleantmptestlogs cleantestlibs all check-stage2
        $(Q)$(CFG_PYTHON) $(S)src/etc/check-summary.py tmp/*.log
index 9eac38e4cd5b7cb77e70cc03e65fde68c64c45db..4de66d8746fbea72f45206832e1ef93c56a2ba9e 100644 (file)
@@ -187,7 +187,7 @@ pub fn log_config(config: &Config) {
                     opt_str(&config.filter
                                    .as_ref()
                                    .map(|re| {
-                                       re.to_str().into_string()
+                                       re.to_string().into_string()
                                    }))));
     logv(c, format!("runtool: {}", opt_str(&config.runtool)));
     logv(c, format!("host-rustcflags: {}",
index 8e79f58c60881d21399b2c98f0ab750f98222a73..7681792bdf53d1e1af5f92fe111e710f398410d6 100644 (file)
@@ -31,7 +31,7 @@ pub fn load_errors(re: &Regex, testfile: &Path) -> Vec<ExpectedError> {
 fn parse_expected(line_num: uint, line: &str, re: &Regex) -> Option<ExpectedError> {
     re.captures(line).and_then(|caps| {
         let adjusts = caps.name("adjusts").len();
-        let kind = caps.name("kind").to_ascii().to_lower().into_str();
+        let kind = caps.name("kind").to_ascii().to_lower().into_string();
         let msg = caps.name("msg").trim().to_string();
 
         debug!("line={} kind={} msg={}", line_num, kind, msg);
index c6e02606f74e750fa4eababd3d61c6a05f7941dc..369e6b0af645c82505bf6e08e7ed0df5b6f852b6 100644 (file)
@@ -41,7 +41,7 @@ pub fn make_new_path(path: &str) -> String {
       Some(curr) => {
         format!("{}{}{}", path, path_div(), curr)
       }
-      None => path.to_str()
+      None => path.to_string()
     }
 }
 
index 9021b761954d05dfd8212e52972c41132dc8d58c..6ef273e7a1a59099021bfdb11f3de3816f1ac9c3 100644 (file)
@@ -465,7 +465,7 @@ fn stringifier(channel: &DuplexStream<String, uint>) {
     let mut value: uint;
     loop {
         value = channel.recv();
-        channel.send(value.to_str());
+        channel.send(value.to_string());
         if value == 0 { break; }
     }
 }
@@ -478,7 +478,7 @@ send strings (the first type parameter) and receive `uint` messages
 (the second type parameter). The body itself simply loops, reading
 from the channel and then sending its response back.  The actual
 response itself is simply the stringified version of the received value,
-`uint::to_str(value)`.
+`uint::to_string(value)`.
 
 Here is the code for the parent task:
 
@@ -492,7 +492,7 @@ use std::comm::duplex;
 #     let mut value: uint;
 #     loop {
 #         value = channel.recv();
-#         channel.send(value.to_str());
+#         channel.send(value.to_string());
 #         if value == 0u { break; }
 #     }
 # }
index 6fe79b06214dded005504d4eccb73f64d30032b5..7136a7bafb0e5bcfa0dab7c11897cf4024c7dd07 100644 (file)
@@ -91,7 +91,6 @@ You should see some output that looks something like this:
 
 ```{ignore}
 rustc 0.11.0-pre (443a1cd 2014-06-08 14:56:52 -0700)
-host: x86_64-unknown-linux-gnu
 ```
 
 If you did, Rust has been installed successfully! Congrats!
@@ -737,10 +736,10 @@ let x = (let y = 5i); // found `let` in ident position
 The compiler is telling us here that it was expecting to see the beginning of
 an expression, and a `let` can only begin a statement, not an expression.
 
-However, re-assigning to a mutable binding is an expression:
+However, assigning to a variable binding is an expression:
 
 ```{rust}
-let mut x = 0i;
+let x;
 let y = x = 5i;
 ```
 
@@ -895,13 +894,14 @@ fn add_one(x: int) -> int {
 We would get an error:
 
 ```{ignore,notrust}
-note: consider removing this semicolon:
-     x + 1;
-          ^
 error: not all control paths return a value
 fn add_one(x: int) -> int {
      x + 1;
 }
+
+note: consider removing this semicolon:
+     x + 1;
+          ^
 ```
 
 Remember our earlier discussions about semicolons and `()`? Our function claims
@@ -940,11 +940,54 @@ fn foo(x: int) -> int {
 There are some additional ways to define functions, but they involve features
 that we haven't learned about yet, so let's just leave it at that for now.
 
+
 ## Comments
 
-return
+Now that we have some functions, it's a good idea to learn about comments.
+Comments are notes that you leave to other programmers to help explain things
+about your code. The compiler mostly ignores them.
+
+Rust has two kinds of comments that you should care about: **line comment**s
+and **doc comment**s.
+
+```{rust}
+// Line comments are anything after '//' and extend to the end of the line.
+
+let x = 5i; // this is also a line comment.
+
+// If you have a long explanation for something, you can put line comments next
+// to each other. Put a space between the // and your comment so that it's
+// more readable.
+```
+
+The other kind of comment is a doc comment. Doc comments use `///` instead of
+`//`, and support Markdown notation inside:
+
+```{rust}
+/// `hello` is a function that prints a greeting that is personalized based on
+/// the name given.
+///
+/// # Arguments
+///
+/// * `name` - The name of the person you'd like to greet.
+///
+/// # Example
+///
+/// ```rust
+/// let name = "Steve";
+/// hello(name); // prints "Hello, Steve!"
+/// ```
+fn hello(name: &str) {
+    println!("Hello, {}!", name);
+}
+```
+
+When writing doc comments, adding sections for any arguments, return values,
+and providing some examples of usage is very, very helpful.
 
-comments
+You can use the `rustdoc` tool to generate HTML documentation from these doc
+comments. We will talk more about `rustdoc` when we get to modules, as
+generally, you want to export documentation for a full module.
 
 ## Compound Data Types
 
index 3b7bb2e740d46a58ca7c0689acd859c7da0991ef..b429f3020a73c1414ca293193b2ee27735823f1c 100644 (file)
@@ -23,7 +23,7 @@ msgstr ""
 #| "[tarball]: http://static.rust-lang.org/dist/rust-nightly.tar.gz [win-exe]: "
 #| "http://static.rust-lang.org/dist/rust-nightly-install.exe"
 msgid ""
-"Use [`ToStr`](http://static.rust-lang.org/doc/master/std/to_str/trait.ToStr."
+"Use [`ToString`](http://static.rust-lang.org/doc/master/std/to_str/trait.ToString."
 "html)."
 msgstr ""
 "[tarball]: http://static.rust-lang.org/dist/rust-nightly.tar.gz\n"
@@ -34,7 +34,7 @@ msgstr ""
 #, fuzzy
 #| msgid ""
 #| "~~~~ let x: f64 = 4.0; let y: uint = x as uint; assert!(y == 4u); ~~~~"
-msgid "~~~ let x: int = 42; let y: String = x.to_str(); ~~~"
+msgid "~~~ let x: int = 42; let y: String = x.to_string(); ~~~"
 msgstr ""
 "~~~~\n"
 "let x: f64 = 4.0;\n"
index f0aef7accb6e1a0484f68cca36cf05bb4d3475b1..a28a62d01c2674d561ac69661fb19b6240dd0dc0 100644 (file)
@@ -1656,7 +1656,7 @@ msgstr ""
 #| msgid "~~~~ {.ignore} // main.rs extern crate world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
 msgid ""
 "impl Printable for int {\n"
-"  fn to_string(&self) -> String { self.to_str() }\n"
+"  fn to_string(&self) -> String { self.to_string() }\n"
 "}\n"
 msgstr ""
 "~~~~ {.ignore}\n"
index 68c32ae9704a36bc74a66ffe7f8447a4549dfe8d..597cf5b7ac509cfde4b42385ee3d07557b68d0ab 100644 (file)
@@ -4410,9 +4410,9 @@ msgstr ""
 
 #. type: Plain text
 #: src/doc/tutorial.md:2528
-msgid "#[deriving(Rand, ToStr)] enum ABC { A, B, C } ~~~"
+msgid "#[deriving(Rand, ToString)] enum ABC { A, B, C } ~~~"
 msgstr ""
-"#[deriving(Rand, ToStr)]\n"
+"#[deriving(Rand, ToString)]\n"
 "enum ABC { A, B, C }\n"
 "~~~"
 
@@ -4422,15 +4422,15 @@ msgstr ""
 #| msgid ""
 #| "The full list of derivable traits is `Eq`, `TotalEq`, `Ord`, `TotalOrd`, "
 #| "`Encodable` `Decodable`, `Clone`, `DeepClone`, `Hash`, `Rand`, "
-#| "`Zero`, and `ToStr`."
+#| "`Zero`, and `ToString`."
 msgid ""
 "The full list of derivable traits is `Eq`, `TotalEq`, `Ord`, `TotalOrd`, "
 "`Encodable` `Decodable`, `Clone`, `DeepClone`, `Hash`, `Rand`, "
-"`Default`, `Zero`, and `ToStr`."
+"`Default`, `Zero`, and `ToString`."
 msgstr ""
 "実装を自動的に導出可能なトレイトは、 `Eq`, `TotalEq`, `Ord`, `TotalOrd`, "
 "`Encodable` `Decodable`, `Clone`, `DeepClone`, `Hash`, `Rand`, `Zero`, "
-"および `ToStr` です。."
+"および `ToString` です。."
 
 #. type: Plain text
 #: src/doc/tutorial.md:2534
index e149920ab352d9fe9362f64e5208164115387fd3..9d5a6fa42a830239fb21695527511b85fc6abe1f 100644 (file)
@@ -3671,15 +3671,15 @@ An example of an object type:
 
 ~~~~
 trait Printable {
-  fn to_string(&self) -> String;
+  fn stringify(&self) -> String;
 }
 
 impl Printable for int {
-  fn to_string(&self) -> String { self.to_str() }
+  fn stringify(&self) -> String { self.to_string() }
 }
 
 fn print(a: Box<Printable>) {
-   println!("{}", a.to_string());
+   println!("{}", a.stringify());
 }
 
 fn main() {
@@ -3889,12 +3889,11 @@ by the prefix operator `box`. When the standard library is in use, the type of a
 An example of an owned box type and value:
 
 ~~~~
-
 let x: Box<int> = box 10;
 ~~~~
 
-Owned box values exist in 1:1 correspondence with their heap allocation
-copying an owned box value makes a shallow copy of the pointer
+Owned box values exist in 1:1 correspondence with their heap allocation,
+copying an owned box value makes a shallow copy of the pointer.
 Rust will consider a shallow copy of an owned box to move ownership of the value. After a value has been moved, the source location cannot be used unless it is reinitialized.
 
 ~~~~
index 2a788d7e7934c495d1d6ca218209faa3181c062c..0522def2d0f034bf3e6c95599090ffa5aee23b90 100644 (file)
@@ -3038,7 +3038,7 @@ fn main() {
 ~~~{.ignore}
 // `b/mod.rs`
 pub mod c;
-pub fn foo() { println!("Foo!"; }
+pub fn foo() { println!("Foo!"); }
 ~~~
 
 ~~~{.ignore}
index 65f9f4105ad8fda5c8d58657f5832072102e47d5..16ed43415c3ef5a7231011a19081a49870e3d6e5 100644 (file)
@@ -31,6 +31,12 @@ setlocal formatoptions-=t formatoptions+=croqnl
 " j was only added in 7.3.541, so stop complaints about its nonexistence
 silent! setlocal formatoptions+=j
 
+" smartindent will be overridden by indentexpr if filetype indent is on, but
+" otherwise it's better than nothing.
+setlocal smartindent nocindent
+
+setlocal tabstop=4 shiftwidth=4 expandtab
+
 " This includeexpr isn't perfect, but it's a good start
 setlocal includeexpr=substitute(v:fname,'::','/','g')
 
index a15bd3ca60ff1c7e484b10e1997a1fb525a8bd09..86df9cba4cdf5317b8a148f97dbde8b912a2607e 100644 (file)
@@ -65,7 +65,7 @@ syn keyword   rustTrait       Copy Send Sized Share
 syn keyword   rustTrait       Add Sub Mul Div Rem Neg Not
 syn keyword   rustTrait       BitAnd BitOr BitXor
 syn keyword   rustTrait       Drop Deref DerefMut
-syn keyword   rustTrait       Shl Shr Index
+syn keyword   rustTrait       Shl Shr Index IndexMut
 syn keyword   rustEnum        Option
 syn keyword   rustEnumVariant Some None
 syn keyword   rustEnum        Result
@@ -100,7 +100,7 @@ syn keyword rustTrait RawPtr
 syn keyword rustTrait Buffer Writer Reader Seek
 syn keyword rustTrait Str StrVector StrSlice OwnedStr
 syn keyword rustTrait IntoMaybeOwned StrAllocating
-syn keyword rustTrait ToStr IntoStr
+syn keyword rustTrait ToString IntoStr
 syn keyword rustTrait Tuple1 Tuple2 Tuple3 Tuple4
 syn keyword rustTrait Tuple5 Tuple6 Tuple7 Tuple8
 syn keyword rustTrait Tuple9 Tuple10 Tuple11 Tuple12
index 26b8ccaf573718523428bd8f82c76b61be87c3e4..3e403d122ac475856de0e364bb9f286f7236f147 100644 (file)
@@ -60,7 +60,8 @@
 //! by libc malloc/free.  The `libc_heap` module is defined to be wired up to
 //! the system malloc/free.
 
-#![crate_id = "alloc#0.11.0"]
+#![crate_id = "alloc#0.11.0"] // NOTE: remove after a stage0 snap
+#![crate_name = "alloc"]
 #![experimental]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
@@ -70,6 +71,7 @@
 
 #![no_std]
 #![feature(lang_items, phase, unsafe_destructor)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 #[phase(plugin, link)]
 extern crate core;
index 917de94470b35e0bf3ceb4f189e464fb747d2310..51eacd3fb4e84ff9833f028a04bed75bd7557688 100644 (file)
@@ -20,6 +20,7 @@
 //! more complex, slower Arena which can hold objects of any type.
 
 #![crate_id = "arena#0.11.0"]
+#![crate_name = "arena"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
@@ -30,6 +31,7 @@
 
 #![feature(unsafe_destructor)]
 #![allow(missing_doc)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 use std::cell::{Cell, RefCell};
 use std::cmp;
index 234393ce56183b8dfbf330e4bb370a04c4e96d3e..905c27ee82c9470cc1c2af5e70af59115727993f 100644 (file)
@@ -15,8 +15,7 @@
 use core::cmp;
 use core::default::Default;
 use core::fmt;
-use core::iter::{Enumerate, Repeat, Map, Zip};
-use core::ops;
+use core::iter::Take;
 use core::slice;
 use core::uint;
 use std::hash;
 use {Collection, Mutable, Set, MutableSet};
 use vec::Vec;
 
+#[cfg(not(stage0))]
+use core::ops::Index;
+
+#[cfg(not(stage0))]
+static TRUE: bool = true;
+
+#[cfg(not(stage0))]
+static FALSE: bool = false;
+
 #[deriving(Clone)]
 struct SmallBitv {
     /// only the lowest nbits of this value are used. the rest is undefined.
     bits: uint
 }
 
-/// a mask that has a 1 for each defined bit in a small_bitv, assuming n bits
-#[inline]
-fn small_mask(nbits: uint) -> uint {
-    (1 << nbits) - 1
-}
-
-impl SmallBitv {
-    fn new(bits: uint) -> SmallBitv {
-        SmallBitv {bits: bits}
-    }
-
-    #[inline]
-    fn bits_op(&mut self,
-                   right_bits: uint,
-                   nbits: uint,
-                   f: |uint, uint| -> uint)
-                   -> bool {
-        let mask = small_mask(nbits);
-        let old_b: uint = self.bits;
-        let new_b = f(old_b, right_bits);
-        self.bits = new_b;
-        mask & old_b != mask & new_b
-    }
-
-    #[inline]
-    fn union(&mut self, s: &SmallBitv, nbits: uint) -> bool {
-        self.bits_op(s.bits, nbits, |u1, u2| u1 | u2)
-    }
-
-    #[inline]
-    fn intersect(&mut self, s: &SmallBitv, nbits: uint) -> bool {
-        self.bits_op(s.bits, nbits, |u1, u2| u1 & u2)
-    }
-
-    #[inline]
-    fn become(&mut self, s: &SmallBitv, nbits: uint) -> bool {
-        self.bits_op(s.bits, nbits, |_u1, u2| u2)
-    }
-
-    #[inline]
-    fn difference(&mut self, s: &SmallBitv, nbits: uint) -> bool {
-        self.bits_op(s.bits, nbits, |u1, u2| u1 & !u2)
-    }
-
-    #[inline]
-    fn get(&self, i: uint) -> bool {
-        (self.bits & (1 << i)) != 0
-    }
-
-    #[inline]
-    fn set(&mut self, i: uint, x: bool) {
-        if x {
-            self.bits |= 1<<i;
-        }
-        else {
-            self.bits &= !(1<<i);
-        }
-    }
-
-    #[inline]
-    fn equals(&self, b: &SmallBitv, nbits: uint) -> bool {
-        let mask = small_mask(nbits);
-        mask & self.bits == mask & b.bits
-    }
-
-    #[inline]
-    fn clear(&mut self) { self.bits = 0; }
-
-    #[inline]
-    fn set_all(&mut self) { self.bits = !0; }
-
-    #[inline]
-    fn all(&self, nbits: uint) -> bool {
-        small_mask(nbits) & !self.bits == 0
-    }
-
-    #[inline]
-    fn none(&self, nbits: uint) -> bool {
-        small_mask(nbits) & self.bits == 0
-    }
-
-    #[inline]
-    fn negate(&mut self) { self.bits = !self.bits; }
-}
-
 #[deriving(Clone)]
 struct BigBitv {
     storage: Vec<uint>
 }
 
-/**
- * A mask that has a 1 for each defined bit in the n'th element of a `BigBitv`,
- * assuming n bits.
- */
-#[inline]
-fn big_mask(nbits: uint, elem: uint) -> uint {
-    let rmd = nbits % uint::BITS;
-    let nelems = nbits/uint::BITS + if rmd == 0 {0} else {1};
-
-    if elem < nelems - 1 || rmd == 0 {
-        !0
-    } else {
-        (1 << rmd) - 1
-    }
-}
-
-impl BigBitv {
-    fn new(storage: Vec<uint>) -> BigBitv {
-        BigBitv {storage: storage}
-    }
-
-    #[inline]
-    fn process(&mut self,
-                   b: &BigBitv,
-                   nbits: uint,
-                   op: |uint, uint| -> uint)
-                   -> bool {
-        let len = b.storage.len();
-        assert_eq!(self.storage.len(), len);
-        let mut changed = false;
-        for (i, (a, b)) in self.storage.mut_iter()
-                               .zip(b.storage.iter())
-                               .enumerate() {
-            let mask = big_mask(nbits, i);
-            let w0 = *a & mask;
-            let w1 = *b & mask;
-            let w = op(w0, w1) & mask;
-            if w0 != w {
-                changed = true;
-                *a = w;
-            }
-        }
-        changed
-    }
-
-    #[inline]
-    fn each_storage(&mut self, op: |v: &mut uint| -> bool) -> bool {
-        self.storage.mut_iter().advance(|elt| op(elt))
-    }
-
-    #[inline]
-    fn negate(&mut self) {
-        self.each_storage(|w| { *w = !*w; true });
-    }
-
-    #[inline]
-    fn union(&mut self, b: &BigBitv, nbits: uint) -> bool {
-        self.process(b, nbits, |w1, w2| w1 | w2)
-    }
-
-    #[inline]
-    fn intersect(&mut self, b: &BigBitv, nbits: uint) -> bool {
-        self.process(b, nbits, |w1, w2| w1 & w2)
-    }
-
-    #[inline]
-    fn become(&mut self, b: &BigBitv, nbits: uint) -> bool {
-        self.process(b, nbits, |_, w| w)
-    }
-
-    #[inline]
-    fn difference(&mut self, b: &BigBitv, nbits: uint) -> bool {
-        self.process(b, nbits, |w1, w2| w1 & !w2)
-    }
-
-    #[inline]
-    fn get(&self, i: uint) -> bool {
-        let w = i / uint::BITS;
-        let b = i % uint::BITS;
-        let x = 1 & self.storage.get(w) >> b;
-        x == 1
-    }
-
-    #[inline]
-    fn set(&mut self, i: uint, x: bool) {
-        let w = i / uint::BITS;
-        let b = i % uint::BITS;
-        let flag = 1 << b;
-        *self.storage.get_mut(w) = if x { *self.storage.get(w) | flag }
-                          else { *self.storage.get(w) & !flag };
-    }
-
-    #[inline]
-    fn equals(&self, b: &BigBitv, nbits: uint) -> bool {
-        for (i, elt) in b.storage.iter().enumerate() {
-            let mask = big_mask(nbits, i);
-            if mask & *self.storage.get(i) != mask & *elt {
-                return false;
-            }
-        }
-        true
-    }
-}
-
 #[deriving(Clone)]
 enum BitvVariant { Big(BigBitv), Small(SmallBitv) }
 
-enum Op {Union, Intersect, Assign, Difference}
-
 /// The bitvector type
 ///
 /// # Example
@@ -236,91 +53,126 @@ enum Op {Union, Intersect, Assign, Difference}
 /// ```rust
 /// use collections::bitv::Bitv;
 ///
-/// let mut bv = Bitv::new(10, false);
+/// let mut bv = Bitv::with_capacity(10, false);
 ///
 /// // insert all primes less than 10
 /// bv.set(2, true);
 /// bv.set(3, true);
 /// bv.set(5, true);
 /// bv.set(7, true);
-/// println!("{}", bv.to_str());
+/// println!("{}", bv.to_string());
 /// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count());
 ///
 /// // flip all values in bitvector, producing non-primes less than 10
 /// bv.negate();
-/// println!("{}", bv.to_str());
+/// println!("{}", bv.to_string());
 /// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count());
 ///
 /// // reset bitvector to empty
 /// bv.clear();
-/// println!("{}", bv.to_str());
+/// println!("{}", bv.to_string());
 /// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count());
 /// ```
-#[deriving(Clone)]
 pub struct Bitv {
-    /// Internal representation of the bit vector (small or large)
-    rep: BitvVariant,
+    /// Internal representation of the bit vector
+    storage: Vec<uint>,
     /// The number of valid bits in the internal representation
     nbits: uint
 }
 
-fn die() -> ! {
-    fail!("Tried to do operation on bit vectors with different sizes");
+#[cfg(not(stage0))]
+impl Index<uint,bool> for Bitv {
+    #[inline]
+    fn index<'a>(&'a self, i: &uint) -> &'a bool {
+        if self.get(*i) {
+            &TRUE
+        } else {
+            &FALSE
+        }
+    }
 }
 
-impl Bitv {
+struct MaskWords<'a> {
+    iter: slice::Items<'a, uint>,
+    next_word: Option<&'a uint>,
+    last_word_mask: uint,
+    offset: uint
+}
+
+impl<'a> Iterator<(uint, uint)> for MaskWords<'a> {
+    /// Returns (offset, word)
     #[inline]
-    fn do_op(&mut self, op: Op, other: &Bitv) -> bool {
-        if self.nbits != other.nbits {
-            die();
-        }
-        match self.rep {
-          Small(ref mut s) => match other.rep {
-            Small(ref s1) => match op {
-              Union      => s.union(s1,      self.nbits),
-              Intersect  => s.intersect(s1,  self.nbits),
-              Assign     => s.become(s1,     self.nbits),
-              Difference => s.difference(s1, self.nbits)
+    fn next<'a>(&'a mut self) -> Option<(uint, uint)> {
+        let ret = self.next_word;
+        match ret {
+            Some(&w) => {
+                self.next_word = self.iter.next();
+                self.offset += 1;
+                // The last word may need to be masked
+                if self.next_word.is_none() {
+                    Some((self.offset - 1, w & self.last_word_mask))
+                } else {
+                    Some((self.offset - 1, w))
+                }
             },
-            Big(_) => die()
-          },
-          Big(ref mut s) => match other.rep {
-            Small(_) => die(),
-            Big(ref s1) => match op {
-              Union      => s.union(s1,      self.nbits),
-              Intersect  => s.intersect(s1,  self.nbits),
-              Assign     => s.become(s1,     self.nbits),
-              Difference => s.difference(s1, self.nbits)
-            }
-          }
+            None => None
         }
     }
 }
 
 impl Bitv {
-    /// Creates an empty Bitv that holds `nbits` elements, setting each element
+    #[inline]
+    fn process(&mut self, other: &Bitv, op: |uint, uint| -> uint) -> bool {
+        let len = other.storage.len();
+        assert_eq!(self.storage.len(), len);
+        let mut changed = false;
+        // Notice: `a` is *not* masked here, which is fine as long as
+        // `op` is a bitwise operation, since any bits that should've
+        // been masked were fine to change anyway. `b` is masked to
+        // make sure its unmasked bits do not cause damage.
+        for (a, (_, b)) in self.storage.mut_iter()
+                           .zip(other.mask_words(0)) {
+            let w = op(*a, b);
+            if *a != w {
+                changed = true;
+                *a = w;
+            }
+        }
+        changed
+    }
+
+    #[inline]
+    fn mask_words<'a>(&'a self, mut start: uint) -> MaskWords<'a> {
+        if start > self.storage.len() {
+            start = self.storage.len();
+        }
+        let mut iter = self.storage.slice_from(start).iter();
+        MaskWords {
+          next_word: iter.next(),
+          iter: iter,
+          last_word_mask: {
+              let rem = self.nbits % uint::BITS;
+              if rem > 0 {
+                  (1 << rem) - 1
+              } else { !0 }
+          },
+          offset: start
+        }
+    }
+
+    /// Creates an empty Bitv
+    pub fn new() -> Bitv {
+        Bitv { storage: Vec::new(), nbits: 0 }
+    }
+
+    /// Creates a Bitv that holds `nbits` elements, setting each element
     /// to `init`.
-    pub fn new(nbits: uint, init: bool) -> Bitv {
-        let rep = if nbits < uint::BITS {
-            Small(SmallBitv::new(if init {(1<<nbits)-1} else {0}))
-        } else if nbits == uint::BITS {
-            Small(SmallBitv::new(if init {!0} else {0}))
-        } else {
-            let exact = nbits % uint::BITS == 0;
-            let nelems = nbits/uint::BITS + if exact {0} else {1};
-            let s =
-                if init {
-                    if exact {
-                        Vec::from_elem(nelems, !0u)
-                    } else {
-                        let mut v = Vec::from_elem(nelems-1, !0u);
-                        v.push((1<<nbits % uint::BITS)-1);
-                        v
-                    }
-                } else { Vec::from_elem(nelems, 0u)};
-            Big(BigBitv::new(s))
-        };
-        Bitv {rep: rep, nbits: nbits}
+    pub fn with_capacity(nbits: uint, init: bool) -> Bitv {
+        Bitv {
+            storage: Vec::from_elem((nbits + uint::BITS - 1) / uint::BITS,
+                                    if init { !0u } else { 0u }),
+            nbits: nbits
+        }
     }
 
     /**
@@ -330,7 +182,9 @@ pub fn new(nbits: uint, init: bool) -> Bitv {
      * the same length. Returns `true` if `self` changed.
     */
     #[inline]
-    pub fn union(&mut self, v1: &Bitv) -> bool { self.do_op(Union, v1) }
+    pub fn union(&mut self, other: &Bitv) -> bool {
+        self.process(other, |w1, w2| w1 | w2)
+    }
 
     /**
      * Calculates the intersection of two bitvectors
@@ -339,27 +193,18 @@ pub fn union(&mut self, v1: &Bitv) -> bool { self.do_op(Union, v1) }
      * must be the same length. Returns `true` if `self` changed.
     */
     #[inline]
-    pub fn intersect(&mut self, v1: &Bitv) -> bool {
-        self.do_op(Intersect, v1)
+    pub fn intersect(&mut self, other: &Bitv) -> bool {
+        self.process(other, |w1, w2| w1 & w2)
     }
 
-    /**
-     * Assigns the value of `v1` to `self`
-     *
-     * Both bitvectors must be the same length. Returns `true` if `self` was
-     * changed
-     */
-    #[inline]
-    pub fn assign(&mut self, v: &Bitv) -> bool { self.do_op(Assign, v) }
-
     /// Retrieve the value at index `i`
     #[inline]
     pub fn get(&self, i: uint) -> bool {
-        assert!((i < self.nbits));
-        match self.rep {
-            Big(ref b)   => b.get(i),
-            Small(ref s) => s.get(i)
-        }
+        assert!(i < self.nbits);
+        let w = i / uint::BITS;
+        let b = i % uint::BITS;
+        let x = self.storage.get(w) & (1 << b);
+        x != 0
     }
 
     /**
@@ -369,42 +214,24 @@ pub fn get(&self, i: uint) -> bool {
      */
     #[inline]
     pub fn set(&mut self, i: uint, x: bool) {
-      assert!((i < self.nbits));
-      match self.rep {
-        Big(ref mut b)   => b.set(i, x),
-        Small(ref mut s) => s.set(i, x)
-      }
-    }
-
-    /// Set all bits to 0
-    #[inline]
-    pub fn clear(&mut self) {
-        match self.rep {
-            Small(ref mut b) => b.clear(),
-            Big(ref mut s) => {
-                s.each_storage(|w| { *w = 0u; true });
-            }
-        }
+        assert!(i < self.nbits);
+        let w = i / uint::BITS;
+        let b = i % uint::BITS;
+        let flag = 1 << b;
+        *self.storage.get_mut(w) = if x { *self.storage.get(w) | flag }
+                          else { *self.storage.get(w) & !flag };
     }
 
     /// Set all bits to 1
     #[inline]
     pub fn set_all(&mut self) {
-        match self.rep {
-            Small(ref mut b) => b.set_all(),
-            Big(ref mut s) => {
-                s.each_storage(|w| { *w = !0u; true });
-            }
-        }
+        for w in self.storage.mut_iter() { *w = !0u; }
     }
 
     /// Flip all bits
     #[inline]
     pub fn negate(&mut self) {
-        match self.rep {
-            Small(ref mut s) => s.negate(),
-            Big(ref mut b) => b.negate(),
-        }
+        for w in self.storage.mut_iter() { *w = !*w; }
     }
 
     /**
@@ -417,17 +244,19 @@ pub fn negate(&mut self) {
      * Returns `true` if `v0` was changed.
      */
     #[inline]
-    pub fn difference(&mut self, v: &Bitv) -> bool {
-        self.do_op(Difference, v)
+    pub fn difference(&mut self, other: &Bitv) -> bool {
+        self.process(other, |w1, w2| w1 & !w2)
     }
 
     /// Returns `true` if all bits are 1
     #[inline]
     pub fn all(&self) -> bool {
-      match self.rep {
-        Small(ref b) => b.all(self.nbits),
-        _ => self.iter().all(|x| x)
-      }
+        let mut last_word = !0u;
+        // Check that every word but the last is all-ones...
+        self.mask_words(0).all(|(_, elem)|
+            { let tmp = last_word; last_word = elem; tmp == !0u }) &&
+        // ...and that the last word is ones as far as it needs to be
+        (last_word == ((1 << self.nbits % uint::BITS) - 1) || last_word == !0u)
     }
 
     /// Returns an iterator over the elements of the vector in order.
@@ -436,7 +265,7 @@ pub fn all(&self) -> bool {
     ///
     /// ```rust
     /// use collections::bitv::Bitv;
-    /// let mut bv = Bitv::new(10, false);
+    /// let mut bv = Bitv::with_capacity(10, false);
     /// bv.set(1, true);
     /// bv.set(2, true);
     /// bv.set(3, true);
@@ -452,10 +281,7 @@ pub fn iter<'a>(&'a self) -> Bits<'a> {
 
     /// Returns `true` if all bits are 0
     pub fn none(&self) -> bool {
-      match self.rep {
-        Small(ref b) => b.none(self.nbits),
-        _ => self.iter().all(|x| !x)
-      }
+        self.mask_words(0).all(|(_, w)| w == 0)
     }
 
     #[inline]
@@ -464,15 +290,6 @@ pub fn any(&self) -> bool {
         !self.none()
     }
 
-    /**
-     * Converts `self` to a vector of `uint` with the same length.
-     *
-     * Each `uint` in the resulting vector has either value `0u` or `1u`.
-     */
-    pub fn to_vec(&self) -> Vec<uint> {
-        Vec::from_fn(self.nbits, |i| if self.get(i) { 1 } else { 0 })
-    }
-
     /**
      * Organise the bits into bytes, such that the first bit in the
      * `Bitv` becomes the high-order bit of the first byte. If the
@@ -485,7 +302,7 @@ fn bit (bitv: &Bitv, byte: uint, bit: uint) -> u8 {
             if offset >= bitv.nbits {
                 0
             } else {
-                bitv[offset] as u8 << (7 - bit)
+                bitv.get(offset) as u8 << (7 - bit)
             }
         }
 
@@ -507,7 +324,7 @@ fn bit (bitv: &Bitv, byte: uint, bit: uint) -> u8 {
      * Transform `self` into a `Vec<bool>` by turning each bit into a `bool`.
      */
     pub fn to_bools(&self) -> Vec<bool> {
-        Vec::from_fn(self.nbits, |i| self[i])
+        Vec::from_fn(self.nbits, |i| self.get(i))
     }
 
     /**
@@ -525,10 +342,131 @@ pub fn eq_vec(&self, v: &[bool]) -> bool {
         true
     }
 
-    pub fn ones(&self, f: |uint| -> bool) -> bool {
-        range(0u, self.nbits).advance(|i| !self.get(i) || f(i))
+    /// Shorten a Bitv, dropping excess elements.
+    ///
+    /// If `len` is greater than the vector's current length, this has no
+    /// effect.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use collections::bitv::Bitv;
+    /// let mut bvec: Bitv = vec![false, true, true, false].iter().map(|n| *n).collect();
+    /// let expected: Bitv = vec![false, true].iter().map(|n| *n).collect();
+    /// bvec.truncate(2);
+    /// assert_eq!(bvec, expected);
+    /// ```
+    pub fn truncate(&mut self, len: uint) {
+        if len < self.len() {
+            self.nbits = len;
+            let word_len = (len + uint::BITS - 1) / uint::BITS;
+            self.storage.truncate(word_len);
+            if len % uint::BITS > 0 {
+                let mask = (1 << len % uint::BITS) - 1;
+                *self.storage.get_mut(word_len - 1) &= mask;
+            }
+        }
+    }
+
+    /// Grows the vector to be able to store `size` bits without resizing
+    pub fn reserve(&mut self, size: uint) {
+        let old_size = self.storage.len();
+        let size = (size + uint::BITS - 1) / uint::BITS;
+        if old_size < size {
+            self.storage.grow(size - old_size, &0);
+        }
+    }
+
+    /// Returns the capacity in bits for this bit vector. Inserting any
+    /// element less than this amount will not trigger a resizing.
+    #[inline]
+    pub fn capacity(&self) -> uint {
+        self.storage.len() * uint::BITS
+    }
+
+    /// Grows the `Bitv` in-place.
+    ///
+    /// Adds `n` copies of `value` to the `Bitv`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use collections::bitv::Bitv;
+    /// let mut bvec: Bitv = vec![false, true, true, false].iter().map(|n| *n).collect();
+    /// bvec.grow(2, true);
+    /// assert_eq!(bvec, vec![false, true, true, false, true, true].iter().map(|n| *n).collect());
+    /// ```
+    pub fn grow(&mut self, n: uint, value: bool) {
+        let new_nbits = self.nbits + n;
+        let new_nwords = (new_nbits + uint::BITS - 1) / uint::BITS;
+        let full_value = if value { !0 } else { 0 };
+        // Correct the old tail word
+        let old_last_word = (self.nbits + uint::BITS - 1) / uint::BITS - 1;
+        if self.nbits % uint::BITS > 0 {
+            let overhang = self.nbits % uint::BITS; // # of already-used bits
+            let mask = !((1 << overhang) - 1);  // e.g. 5 unused bits => 111110....0
+            if value {
+                *self.storage.get_mut(old_last_word) |= mask;
+            } else {
+                *self.storage.get_mut(old_last_word) &= !mask;
+            }
+        }
+        // Fill in words after the old tail word
+        let stop_idx = cmp::min(self.storage.len(), new_nwords);
+        for idx in range(old_last_word + 1, stop_idx) {
+            *self.storage.get_mut(idx) = full_value;
+        }
+        // Allocate new words, if needed
+        if new_nwords > self.storage.len() {
+          let to_add = new_nwords - self.storage.len();
+          self.storage.grow(to_add, &full_value);
+        }
+        // Adjust internal bit count
+        self.nbits = new_nbits;
+    }
+
+    /// Shorten a `Bitv` by one, returning the removed element
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use collections::bitv::Bitv;
+    /// let mut bvec: Bitv = vec![false, true, true, false].iter().map(|n| *n).collect();
+    /// let expected: Bitv = vec![false, true, true].iter().map(|n| *n).collect();
+    /// let popped = bvec.pop();
+    /// assert_eq!(popped, false);
+    /// assert_eq!(bvec, expected);
+    /// ```
+    pub fn pop(&mut self) -> bool {
+        let ret = self.get(self.nbits - 1);
+        // If we are unusing a whole word, make sure it is zeroed out
+        if self.nbits % uint::BITS == 1 {
+            *self.storage.get_mut(self.nbits / uint::BITS) = 0;
+        }
+        self.nbits -= 1;
+        ret
     }
 
+    /// Pushes a `bool` onto the `Bitv`
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use collections::bitv::Bitv;
+    /// let prototype: Bitv = vec![false, true, true, false].iter().map(|n| *n).collect();
+    /// let mut bvec: Bitv = vec![false, true].iter().map(|n| *n).collect();
+    /// bvec.push(true);
+    /// bvec.push(false);
+    /// assert_eq!(prototype, bvec);
+    /// ```
+    pub fn push(&mut self, elem: bool) {
+        let insert_pos = self.nbits;
+        self.nbits += 1;
+        if self.storage.len() * uint::BITS < self.nbits {
+            self.storage.push(0);
+        }
+        self.set(insert_pos, elem);
+    }
 }
 
 /**
@@ -544,28 +482,66 @@ pub fn from_bytes(bytes: &[u8]) -> Bitv {
     })
 }
 
-/**
- * Transform a `[bool]` into a `Bitv` by converting each `bool` into a bit.
- */
-pub fn from_bools(bools: &[bool]) -> Bitv {
-    from_fn(bools.len(), |i| bools[i])
-}
-
 /**
  * Create a `Bitv` of the specified length where the value at each
  * index is `f(index)`.
  */
 pub fn from_fn(len: uint, f: |index: uint| -> bool) -> Bitv {
-    let mut bitv = Bitv::new(len, false);
+    let mut bitv = Bitv::with_capacity(len, false);
     for i in range(0u, len) {
         bitv.set(i, f(i));
     }
     bitv
 }
 
-impl ops::Index<uint,bool> for Bitv {
-    fn index(&self, i: &uint) -> bool {
-        self.get(*i)
+impl Default for Bitv {
+    #[inline]
+    fn default() -> Bitv { Bitv::new() }
+}
+
+impl Collection for Bitv {
+    #[inline]
+    fn len(&self) -> uint { self.nbits }
+}
+
+impl Mutable for Bitv {
+    #[inline]
+    fn clear(&mut self) {
+        for w in self.storage.mut_iter() { *w = 0u; }
+    }
+}
+
+impl FromIterator<bool> for Bitv {
+    fn from_iter<I:Iterator<bool>>(iterator: I) -> Bitv {
+        let mut ret = Bitv::new();
+        ret.extend(iterator);
+        ret
+    }
+}
+
+impl Extendable<bool> for Bitv {
+    #[inline]
+    fn extend<I: Iterator<bool>>(&mut self, mut iterator: I) {
+        let (min, _) = iterator.size_hint();
+        let nbits = self.nbits;
+        self.reserve(nbits + min);
+        for element in iterator {
+            self.push(element)
+        }
+    }
+}
+
+impl Clone for Bitv {
+    #[inline]
+    fn clone(&self) -> Bitv {
+        Bitv { storage: self.storage.clone(), nbits: self.nbits }
+    }
+
+    #[inline]
+    fn clone_from(&mut self, source: &Bitv) {
+        self.nbits = source.nbits;
+        self.storage.reserve(source.storage.len());
+        for (i, w) in self.storage.mut_iter().enumerate() { *w = *source.storage.get(i); }
     }
 }
 
@@ -581,13 +557,8 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 impl<S: hash::Writer> hash::Hash<S> for Bitv {
     fn hash(&self, state: &mut S) {
         self.nbits.hash(state);
-        match self.rep {
-            Small(ref s) => (s.bits & small_mask(self.nbits)).hash(state),
-            Big(ref b) => {
-                for (i, ele) in b.storage.iter().enumerate() {
-                    (ele & big_mask(self.nbits, i)).hash(state);
-                }
-            }
+        for (_, elem) in self.mask_words(0) {
+            elem.hash(state);
         }
     }
 }
@@ -595,37 +566,15 @@ fn hash(&self, state: &mut S) {
 impl cmp::PartialEq for Bitv {
     #[inline]
     fn eq(&self, other: &Bitv) -> bool {
-        if self.nbits != other.nbits { return false; }
-        match self.rep {
-            Small(ref b) => match other.rep {
-                Small(ref b1) => b.equals(b1, self.nbits),
-                _ => false
-            },
-            Big(ref s) => match other.rep {
-                Big(ref s1) => s.equals(s1, self.nbits),
-                Small(_) => return false
-            }
+        if self.nbits != other.nbits {
+            return false;
         }
+        self.mask_words(0).zip(other.mask_words(0)).all(|((_, w1), (_, w2))| w1 == w2)
     }
 }
 
 impl cmp::Eq for Bitv {}
 
-#[inline]
-fn iterate_bits(base: uint, bits: uint, f: |uint| -> bool) -> bool {
-    if bits == 0 {
-        return true;
-    }
-    for i in range(0u, uint::BITS) {
-        if bits & (1 << i) != 0 {
-            if !f(base + i) {
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
 /// An iterator for `Bitv`.
 pub struct Bits<'a> {
     bitv: &'a Bitv,
@@ -687,15 +636,8 @@ fn idx(&mut self, index: uint) -> Option<bool> {
 /// It should also be noted that the amount of storage necessary for holding a
 /// set of objects is proportional to the maximum of the objects when viewed
 /// as a `uint`.
-#[deriving(Clone)]
-pub struct BitvSet {
-    size: uint,
-
-    // In theory this is a `Bitv` instead of always a `BigBitv`, but knowing that
-    // there's an array of storage makes our lives a whole lot easier when
-    // performing union/intersection/etc operations
-    bitv: BigBitv
-}
+#[deriving(Clone, PartialEq, Eq)]
+pub struct BitvSet(Bitv);
 
 impl Default for BitvSet {
     #[inline]
@@ -704,143 +646,168 @@ fn default() -> BitvSet { BitvSet::new() }
 
 impl BitvSet {
     /// Creates a new bit vector set with initially no contents
+    #[inline]
     pub fn new() -> BitvSet {
-        BitvSet{ size: 0, bitv: BigBitv::new(vec!(0)) }
+        BitvSet(Bitv::new())
+    }
+
+    /// Creates a new bit vector set with initially no contents, able to
+    /// hold `nbits` elements without resizing
+    #[inline]
+    pub fn with_capacity(nbits: uint) -> BitvSet {
+        BitvSet(Bitv::with_capacity(nbits, false))
     }
 
     /// Creates a new bit vector set from the given bit vector
+    #[inline]
     pub fn from_bitv(bitv: Bitv) -> BitvSet {
-        let mut size = 0;
-        bitv.ones(|_| {
-            size += 1;
-            true
-        });
-        let Bitv{rep, ..} = bitv;
-        match rep {
-            Big(b) => BitvSet{ size: size, bitv: b },
-            Small(SmallBitv{bits}) =>
-                BitvSet{ size: size, bitv: BigBitv{ storage: vec!(bits) } },
-        }
+        BitvSet(bitv)
     }
 
     /// Returns the capacity in bits for this bit vector. Inserting any
     /// element less than this amount will not trigger a resizing.
-    pub fn capacity(&self) -> uint { self.bitv.storage.len() * uint::BITS }
+    #[inline]
+    pub fn capacity(&self) -> uint {
+        let &BitvSet(ref bitv) = self;
+        bitv.capacity()
+    }
+
+    /// Grows the underlying vector to be able to store `size` bits
+    pub fn reserve(&mut self, size: uint) {
+        let &BitvSet(ref mut bitv) = self;
+        bitv.reserve(size)
+    }
 
     /// Consumes this set to return the underlying bit vector
+    #[inline]
     pub fn unwrap(self) -> Bitv {
-        let cap = self.capacity();
-        let BitvSet{bitv, ..} = self;
-        return Bitv{ nbits:cap, rep: Big(bitv) };
+        let BitvSet(bitv) = self;
+        bitv
+    }
+
+    /// Returns a reference to the underlying bit vector
+    #[inline]
+    pub fn get_ref<'a>(&'a self) -> &'a Bitv {
+        let &BitvSet(ref bitv) = self;
+        bitv
+    }
+
+    /// Returns a mutable reference to the underlying bit vector
+    #[inline]
+    pub fn get_mut_ref<'a>(&'a mut self) -> &'a mut Bitv {
+        let &BitvSet(ref mut bitv) = self;
+        bitv
     }
 
     #[inline]
     fn other_op(&mut self, other: &BitvSet, f: |uint, uint| -> uint) {
-        fn nbits(mut w: uint) -> uint {
-            let mut bits = 0;
-            for _ in range(0u, uint::BITS) {
-                if w == 0 {
-                    break;
-                }
-                bits += w & 1;
-                w >>= 1;
-            }
-            return bits;
-        }
-        if self.capacity() < other.capacity() {
-            self.bitv.storage.grow(other.capacity() / uint::BITS, &0);
-        }
-        for (i, &w) in other.bitv.storage.iter().enumerate() {
-            let old = *self.bitv.storage.get(i);
+        // Unwrap Bitvs
+        let &BitvSet(ref mut self_bitv) = self;
+        let &BitvSet(ref other_bitv) = other;
+        // Expand the vector if necessary
+        self_bitv.reserve(other_bitv.capacity());
+        // Apply values
+        for (i, w) in other_bitv.mask_words(0) {
+            let old = *self_bitv.storage.get(i);
             let new = f(old, w);
-            *self.bitv.storage.get_mut(i) = new;
-            self.size += nbits(new) - nbits(old);
+            *self_bitv.storage.get_mut(i) = new;
         }
     }
 
+    #[inline]
+    /// Truncate the underlying vector to the least length required
+    pub fn shrink_to_fit(&mut self) {
+        let &BitvSet(ref mut bitv) = self;
+        // Obtain original length
+        let old_len = bitv.storage.len();
+        // Obtain coarse trailing zero length
+        let n = bitv.storage.iter().rev().take_while(|&&n| n == 0).count();
+        // Truncate
+        let trunc_len = cmp::max(old_len - n, 1);
+        bitv.storage.truncate(trunc_len);
+        bitv.nbits = trunc_len * uint::BITS;
+    }
+
     /// Union in-place with the specified other bit vector
+    #[inline]
     pub fn union_with(&mut self, other: &BitvSet) {
         self.other_op(other, |w1, w2| w1 | w2);
     }
 
     /// Intersect in-place with the specified other bit vector
+    #[inline]
     pub fn intersect_with(&mut self, other: &BitvSet) {
         self.other_op(other, |w1, w2| w1 & w2);
     }
 
     /// Difference in-place with the specified other bit vector
+    #[inline]
     pub fn difference_with(&mut self, other: &BitvSet) {
         self.other_op(other, |w1, w2| w1 & !w2);
     }
 
     /// Symmetric difference in-place with the specified other bit vector
+    #[inline]
     pub fn symmetric_difference_with(&mut self, other: &BitvSet) {
         self.other_op(other, |w1, w2| w1 ^ w2);
     }
 
+    /// Iterator over each uint stored in the BitvSet
+    #[inline]
     pub fn iter<'a>(&'a self) -> BitPositions<'a> {
         BitPositions {set: self, next_idx: 0}
     }
 
-    pub fn difference(&self, other: &BitvSet, f: |&uint| -> bool) -> bool {
-        for (i, w1, w2) in self.commons(other) {
-            if !iterate_bits(i, w1 & !w2, |b| f(&b)) {
-                return false
-            }
-        };
-        /* everything we have that they don't also shows up */
-        self.outliers(other).advance(|(mine, i, w)|
-            !mine || iterate_bits(i, w, |b| f(&b))
-        )
-    }
-
-    pub fn symmetric_difference(&self, other: &BitvSet, f: |&uint| -> bool)
-                                -> bool {
-        for (i, w1, w2) in self.commons(other) {
-            if !iterate_bits(i, w1 ^ w2, |b| f(&b)) {
-                return false
-            }
-        };
-        self.outliers(other).advance(|(_, i, w)| iterate_bits(i, w, |b| f(&b)))
-    }
-
-    pub fn intersection(&self, other: &BitvSet, f: |&uint| -> bool) -> bool {
-        self.commons(other).advance(|(i, w1, w2)| iterate_bits(i, w1 & w2, |b| f(&b)))
+    /// Iterator over each uint stored in the `self` setminus `other`
+    #[inline]
+    pub fn difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
+        TwoBitPositions {
+            set: self,
+            other: other,
+            merge: |w1, w2| w1 & !w2,
+            current_word: 0,
+            next_idx: 0
+        }
     }
 
-    pub fn union(&self, other: &BitvSet, f: |&uint| -> bool) -> bool {
-        for (i, w1, w2) in self.commons(other) {
-            if !iterate_bits(i, w1 | w2, |b| f(&b)) {
-                return false
-            }
-        };
-        self.outliers(other).advance(|(_, i, w)| iterate_bits(i, w, |b| f(&b)))
+    /// Iterator over each uint stored in the symmetric difference of `self` and `other`
+    #[inline]
+    pub fn symmetric_difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
+        TwoBitPositions {
+            set: self,
+            other: other,
+            merge: |w1, w2| w1 ^ w2,
+            current_word: 0,
+            next_idx: 0
+        }
     }
-}
 
-impl cmp::PartialEq for BitvSet {
-    fn eq(&self, other: &BitvSet) -> bool {
-        if self.size != other.size {
-            return false;
-        }
-        for (_, w1, w2) in self.commons(other) {
-            if w1 != w2 {
-                return false;
-            }
-        }
-        for (_, _, w) in self.outliers(other) {
-            if w != 0 {
-                return false;
-            }
+    /// Iterator over each uint stored in `self` intersect `other`
+    #[inline]
+    pub fn intersection<'a>(&'a self, other: &'a BitvSet) -> Take<TwoBitPositions<'a>> {
+        let min = cmp::min(self.capacity(), other.capacity());
+        TwoBitPositions {
+            set: self,
+            other: other,
+            merge: |w1, w2| w1 & w2,
+            current_word: 0,
+            next_idx: 0
+        }.take(min)
+    }
+
+    /// Iterator over each uint stored in `self` union `other`
+    #[inline]
+    pub fn union<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
+        TwoBitPositions {
+            set: self,
+            other: other,
+            merge: |w1, w2| w1 | w2,
+            current_word: 0,
+            next_idx: 0
         }
-        return true;
     }
-
-    fn ne(&self, other: &BitvSet) -> bool { !self.eq(other) }
 }
 
-impl cmp::Eq for BitvSet {}
-
 impl fmt::Show for BitvSet {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         try!(write!(fmt, "{{"));
@@ -866,44 +833,45 @@ fn hash(&self, state: &mut S) {
 
 impl Collection for BitvSet {
     #[inline]
-    fn len(&self) -> uint { self.size }
+    fn len(&self) -> uint  {
+        let &BitvSet(ref bitv) = self;
+        bitv.storage.iter().fold(0, |acc, &n| acc + n.count_ones())
+    }
 }
 
 impl Mutable for BitvSet {
+    #[inline]
     fn clear(&mut self) {
-        self.bitv.each_storage(|w| { *w = 0; true });
-        self.size = 0;
+        let &BitvSet(ref mut bitv) = self;
+        bitv.clear();
     }
 }
 
 impl Set<uint> for BitvSet {
+    #[inline]
     fn contains(&self, value: &uint) -> bool {
-        *value < self.bitv.storage.len() * uint::BITS && self.bitv.get(*value)
+        let &BitvSet(ref bitv) = self;
+        *value < bitv.nbits && bitv.get(*value)
     }
 
+    #[inline]
     fn is_disjoint(&self, other: &BitvSet) -> bool {
-        self.intersection(other, |_| false)
+        self.intersection(other).count() > 0
     }
 
+    #[inline]
     fn is_subset(&self, other: &BitvSet) -> bool {
-        for (_, w1, w2) in self.commons(other) {
-            if w1 & w2 != w1 {
-                return false;
-            }
-        }
-        /* If anything is not ours, then everything is not ours so we're
-           definitely a subset in that case. Otherwise if there's any stray
-           ones that 'other' doesn't have, we're not a subset. */
-        for (mine, _, w) in self.outliers(other) {
-            if !mine {
-                return true;
-            } else if w != 0 {
-                return false;
-            }
-        }
-        return true;
+        let &BitvSet(ref self_bitv) = self;
+        let &BitvSet(ref other_bitv) = other;
+
+        // Check that `self` intersect `other` is self
+        self_bitv.mask_words(0).zip(other_bitv.mask_words(0))
+                               .all(|((_, w1), (_, w2))| w1 & w2 == w1) &&
+        // Check that `self` setminus `other` is empty
+        self_bitv.mask_words(other_bitv.storage.len()).all(|(_, w)| w == 0)
     }
 
+    #[inline]
     fn is_superset(&self, other: &BitvSet) -> bool {
         other.is_subset(self)
     }
@@ -914,14 +882,21 @@ fn insert(&mut self, value: uint) -> bool {
         if self.contains(&value) {
             return false;
         }
-        let nbits = self.capacity();
-        if value >= nbits {
-            let newsize = cmp::max(value, nbits * 2) / uint::BITS + 1;
-            assert!(newsize > self.bitv.storage.len());
-            self.bitv.storage.grow(newsize, &0);
+        if value >= self.capacity() {
+            let new_cap = cmp::max(value + 1, self.capacity() * 2);
+            self.reserve(new_cap);
+        }
+        let &BitvSet(ref mut bitv) = self;
+        if value >= bitv.nbits {
+            // If we are increasing nbits, make sure we mask out any previously-unconsidered bits
+            let old_rem = bitv.nbits % uint::BITS;
+            if old_rem != 0 {
+                let old_last_word = (bitv.nbits + uint::BITS - 1) / uint::BITS - 1;
+                *bitv.storage.get_mut(old_last_word) &= (1 << old_rem) - 1;
+            }
+            bitv.nbits = value + 1;
         }
-        self.size += 1;
-        self.bitv.set(value, true);
+        bitv.set(value, true);
         return true;
     }
 
@@ -929,66 +904,26 @@ fn remove(&mut self, value: &uint) -> bool {
         if !self.contains(value) {
             return false;
         }
-        self.size -= 1;
-        self.bitv.set(*value, false);
-
-        // Attempt to truncate our storage
-        let mut i = self.bitv.storage.len();
-        while i > 1 && *self.bitv.storage.get(i - 1) == 0 {
-            i -= 1;
-        }
-        self.bitv.storage.truncate(i);
-
+        let &BitvSet(ref mut bitv) = self;
+        bitv.set(*value, false);
         return true;
     }
 }
 
-impl BitvSet {
-    /// Visits each of the words that the two bit vectors (`self` and `other`)
-    /// both have in common. The three yielded arguments are (bit location,
-    /// w1, w2) where the bit location is the number of bits offset so far,
-    /// and w1/w2 are the words coming from the two vectors self, other.
-    fn commons<'a>(&'a self, other: &'a BitvSet)
-        -> Map<'static, ((uint, &'a uint), &'a Vec<uint>), (uint, uint, uint),
-               Zip<Enumerate<slice::Items<'a, uint>>, Repeat<&'a Vec<uint>>>> {
-        let min = cmp::min(self.bitv.storage.len(), other.bitv.storage.len());
-        self.bitv.storage.slice(0, min).iter().enumerate()
-            .zip(Repeat::new(&other.bitv.storage))
-            .map(|((i, &w), o_store)| (i * uint::BITS, w, *o_store.get(i)))
-    }
-
-    /// Visits each word in `self` or `other` that extends beyond the other. This
-    /// will only iterate through one of the vectors, and it only iterates
-    /// over the portion that doesn't overlap with the other one.
-    ///
-    /// The yielded arguments are a `bool`, the bit offset, and a word. The `bool`
-    /// is true if the word comes from `self`, and `false` if it comes from
-    /// `other`.
-    fn outliers<'a>(&'a self, other: &'a BitvSet)
-        -> Map<'static, ((uint, &'a uint), uint), (bool, uint, uint),
-               Zip<Enumerate<slice::Items<'a, uint>>, Repeat<uint>>> {
-        let slen = self.bitv.storage.len();
-        let olen = other.bitv.storage.len();
-
-        if olen < slen {
-            self.bitv.storage.slice_from(olen).iter().enumerate()
-                .zip(Repeat::new(olen))
-                .map(|((i, &w), min)| (true, (i + min) * uint::BITS, w))
-        } else {
-            other.bitv.storage.slice_from(slen).iter().enumerate()
-                .zip(Repeat::new(slen))
-                .map(|((i, &w), min)| (false, (i + min) * uint::BITS, w))
-        }
-    }
+pub struct BitPositions<'a> {
+    set: &'a BitvSet,
+    next_idx: uint
 }
 
-pub struct BitPositions<'a> {
+pub struct TwoBitPositions<'a> {
     set: &'a BitvSet,
+    other: &'a BitvSet,
+    merge: |uint, uint|: 'a -> uint,
+    current_word: uint,
     next_idx: uint
 }
 
 impl<'a> Iterator<uint> for BitPositions<'a> {
-    #[inline]
     fn next(&mut self) -> Option<uint> {
         while self.next_idx < self.set.capacity() {
             let idx = self.next_idx;
@@ -1002,11 +937,47 @@ fn next(&mut self) -> Option<uint> {
         return None;
     }
 
+    #[inline]
     fn size_hint(&self) -> (uint, Option<uint>) {
         (0, Some(self.set.capacity() - self.next_idx))
     }
 }
 
+impl<'a> Iterator<uint> for TwoBitPositions<'a> {
+    fn next(&mut self) -> Option<uint> {
+        while self.next_idx < self.set.capacity() ||
+              self.next_idx < self.other.capacity() {
+            let bit_idx = self.next_idx % uint::BITS;
+            if bit_idx == 0 {
+                let &BitvSet(ref s_bitv) = self.set;
+                let &BitvSet(ref o_bitv) = self.other;
+                // Merging the two words is a bit of an awkward dance since
+                // one Bitv might be longer than the other
+                let word_idx = self.next_idx / uint::BITS;
+                let w1 = if word_idx < s_bitv.storage.len() {
+                             *s_bitv.storage.get(word_idx)
+                         } else { 0 };
+                let w2 = if word_idx < o_bitv.storage.len() {
+                             *o_bitv.storage.get(word_idx)
+                         } else { 0 };
+                self.current_word = (self.merge)(w1, w2);
+            }
+
+            self.next_idx += 1;
+            if self.current_word & (1 << bit_idx) != 0 {
+                return Some(self.next_idx - 1);
+            }
+        }
+        return None;
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        let cap = cmp::max(self.set.capacity(), self.other.capacity());
+        (0, Some(cap - self.next_idx))
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use std::prelude::*;
@@ -1016,8 +987,7 @@ mod tests {
     use test::Bencher;
 
     use {Set, Mutable, MutableSet};
-    use bitv::{Bitv, SmallBitv, BigBitv, BitvSet, from_bools, from_fn,
-               from_bytes};
+    use bitv::{Bitv, BitvSet, from_fn, from_bytes};
     use bitv;
     use vec::Vec;
 
@@ -1025,34 +995,34 @@ mod tests {
 
     #[test]
     fn test_to_str() {
-        let zerolen = Bitv::new(0u, false);
-        assert_eq!(zerolen.to_str().as_slice(), "");
+        let zerolen = Bitv::new();
+        assert_eq!(zerolen.to_string().as_slice(), "");
 
-        let eightbits = Bitv::new(8u, false);
-        assert_eq!(eightbits.to_str().as_slice(), "00000000")
+        let eightbits = Bitv::with_capacity(8u, false);
+        assert_eq!(eightbits.to_string().as_slice(), "00000000")
     }
 
     #[test]
     fn test_0_elements() {
-        let act = Bitv::new(0u, false);
+        let act = Bitv::new();
         let exp = Vec::from_elem(0u, false);
         assert!(act.eq_vec(exp.as_slice()));
     }
 
     #[test]
     fn test_1_element() {
-        let mut act = Bitv::new(1u, false);
+        let mut act = Bitv::with_capacity(1u, false);
         assert!(act.eq_vec([false]));
-        act = Bitv::new(1u, true);
+        act = Bitv::with_capacity(1u, true);
         assert!(act.eq_vec([true]));
     }
 
     #[test]
     fn test_2_elements() {
-        let mut b = bitv::Bitv::new(2, false);
+        let mut b = bitv::Bitv::with_capacity(2, false);
         b.set(0, true);
         b.set(1, false);
-        assert_eq!(b.to_str().as_slice(), "10");
+        assert_eq!(b.to_string().as_slice(), "10");
     }
 
     #[test]
@@ -1060,16 +1030,16 @@ fn test_10_elements() {
         let mut act;
         // all 0
 
-        act = Bitv::new(10u, false);
+        act = Bitv::with_capacity(10u, false);
         assert!((act.eq_vec(
                     [false, false, false, false, false, false, false, false, false, false])));
         // all 1
 
-        act = Bitv::new(10u, true);
+        act = Bitv::with_capacity(10u, true);
         assert!((act.eq_vec([true, true, true, true, true, true, true, true, true, true])));
         // mixed
 
-        act = Bitv::new(10u, false);
+        act = Bitv::with_capacity(10u, false);
         act.set(0u, true);
         act.set(1u, true);
         act.set(2u, true);
@@ -1078,7 +1048,7 @@ fn test_10_elements() {
         assert!((act.eq_vec([true, true, true, true, true, false, false, false, false, false])));
         // mixed
 
-        act = Bitv::new(10u, false);
+        act = Bitv::with_capacity(10u, false);
         act.set(5u, true);
         act.set(6u, true);
         act.set(7u, true);
@@ -1087,7 +1057,7 @@ fn test_10_elements() {
         assert!((act.eq_vec([false, false, false, false, false, true, true, true, true, true])));
         // mixed
 
-        act = Bitv::new(10u, false);
+        act = Bitv::with_capacity(10u, false);
         act.set(0u, true);
         act.set(3u, true);
         act.set(6u, true);
@@ -1100,21 +1070,21 @@ fn test_31_elements() {
         let mut act;
         // all 0
 
-        act = Bitv::new(31u, false);
+        act = Bitv::with_capacity(31u, false);
         assert!(act.eq_vec(
                 [false, false, false, false, false, false, false, false, false, false, false,
                 false, false, false, false, false, false, false, false, false, false, false, false,
                 false, false, false, false, false, false, false, false]));
         // all 1
 
-        act = Bitv::new(31u, true);
+        act = Bitv::with_capacity(31u, true);
         assert!(act.eq_vec(
                 [true, true, true, true, true, true, true, true, true, true, true, true, true,
                 true, true, true, true, true, true, true, true, true, true, true, true, true, true,
                 true, true, true, true]));
         // mixed
 
-        act = Bitv::new(31u, false);
+        act = Bitv::with_capacity(31u, false);
         act.set(0u, true);
         act.set(1u, true);
         act.set(2u, true);
@@ -1129,7 +1099,7 @@ fn test_31_elements() {
                 false, false, false, false, false, false]));
         // mixed
 
-        act = Bitv::new(31u, false);
+        act = Bitv::with_capacity(31u, false);
         act.set(16u, true);
         act.set(17u, true);
         act.set(18u, true);
@@ -1144,7 +1114,7 @@ fn test_31_elements() {
                 false, false, false, false, false, false, false]));
         // mixed
 
-        act = Bitv::new(31u, false);
+        act = Bitv::with_capacity(31u, false);
         act.set(24u, true);
         act.set(25u, true);
         act.set(26u, true);
@@ -1158,7 +1128,7 @@ fn test_31_elements() {
                 false, true, true, true, true, true, true, true]));
         // mixed
 
-        act = Bitv::new(31u, false);
+        act = Bitv::with_capacity(31u, false);
         act.set(3u, true);
         act.set(17u, true);
         act.set(30u, true);
@@ -1173,21 +1143,21 @@ fn test_32_elements() {
         let mut act;
         // all 0
 
-        act = Bitv::new(32u, false);
+        act = Bitv::with_capacity(32u, false);
         assert!(act.eq_vec(
                 [false, false, false, false, false, false, false, false, false, false, false,
                 false, false, false, false, false, false, false, false, false, false, false, false,
                 false, false, false, false, false, false, false, false, false]));
         // all 1
 
-        act = Bitv::new(32u, true);
+        act = Bitv::with_capacity(32u, true);
         assert!(act.eq_vec(
                 [true, true, true, true, true, true, true, true, true, true, true, true, true,
                 true, true, true, true, true, true, true, true, true, true, true, true, true, true,
                 true, true, true, true, true]));
         // mixed
 
-        act = Bitv::new(32u, false);
+        act = Bitv::with_capacity(32u, false);
         act.set(0u, true);
         act.set(1u, true);
         act.set(2u, true);
@@ -1202,7 +1172,7 @@ fn test_32_elements() {
                 false, false, false, false, false, false, false]));
         // mixed
 
-        act = Bitv::new(32u, false);
+        act = Bitv::with_capacity(32u, false);
         act.set(16u, true);
         act.set(17u, true);
         act.set(18u, true);
@@ -1217,7 +1187,7 @@ fn test_32_elements() {
                 false, false, false, false, false, false, false, false]));
         // mixed
 
-        act = Bitv::new(32u, false);
+        act = Bitv::with_capacity(32u, false);
         act.set(24u, true);
         act.set(25u, true);
         act.set(26u, true);
@@ -1232,7 +1202,7 @@ fn test_32_elements() {
                 false, true, true, true, true, true, true, true, true]));
         // mixed
 
-        act = Bitv::new(32u, false);
+        act = Bitv::with_capacity(32u, false);
         act.set(3u, true);
         act.set(17u, true);
         act.set(30u, true);
@@ -1248,21 +1218,21 @@ fn test_33_elements() {
         let mut act;
         // all 0
 
-        act = Bitv::new(33u, false);
+        act = Bitv::with_capacity(33u, false);
         assert!(act.eq_vec(
                 [false, false, false, false, false, false, false, false, false, false, false,
                 false, false, false, false, false, false, false, false, false, false, false, false,
                 false, false, false, false, false, false, false, false, false, false]));
         // all 1
 
-        act = Bitv::new(33u, true);
+        act = Bitv::with_capacity(33u, true);
         assert!(act.eq_vec(
                 [true, true, true, true, true, true, true, true, true, true, true, true, true,
                 true, true, true, true, true, true, true, true, true, true, true, true, true, true,
                 true, true, true, true, true, true]));
         // mixed
 
-        act = Bitv::new(33u, false);
+        act = Bitv::with_capacity(33u, false);
         act.set(0u, true);
         act.set(1u, true);
         act.set(2u, true);
@@ -1277,7 +1247,7 @@ fn test_33_elements() {
                 false, false, false, false, false, false, false, false]));
         // mixed
 
-        act = Bitv::new(33u, false);
+        act = Bitv::with_capacity(33u, false);
         act.set(16u, true);
         act.set(17u, true);
         act.set(18u, true);
@@ -1292,7 +1262,7 @@ fn test_33_elements() {
                 false, false, false, false, false, false, false, false, false]));
         // mixed
 
-        act = Bitv::new(33u, false);
+        act = Bitv::with_capacity(33u, false);
         act.set(24u, true);
         act.set(25u, true);
         act.set(26u, true);
@@ -1307,7 +1277,7 @@ fn test_33_elements() {
                 false, true, true, true, true, true, true, true, true, false]));
         // mixed
 
-        act = Bitv::new(33u, false);
+        act = Bitv::with_capacity(33u, false);
         act.set(3u, true);
         act.set(17u, true);
         act.set(30u, true);
@@ -1321,24 +1291,24 @@ fn test_33_elements() {
 
     #[test]
     fn test_equal_differing_sizes() {
-        let v0 = Bitv::new(10u, false);
-        let v1 = Bitv::new(11u, false);
+        let v0 = Bitv::with_capacity(10u, false);
+        let v1 = Bitv::with_capacity(11u, false);
         assert!(v0 != v1);
     }
 
     #[test]
     fn test_equal_greatly_differing_sizes() {
-        let v0 = Bitv::new(10u, false);
-        let v1 = Bitv::new(110u, false);
+        let v0 = Bitv::with_capacity(10u, false);
+        let v1 = Bitv::with_capacity(110u, false);
         assert!(v0 != v1);
     }
 
     #[test]
     fn test_equal_sneaky_small() {
-        let mut a = bitv::Bitv::new(1, false);
+        let mut a = bitv::Bitv::with_capacity(1, false);
         a.set(0, true);
 
-        let mut b = bitv::Bitv::new(1, true);
+        let mut b = bitv::Bitv::with_capacity(1, true);
         b.set(0, true);
 
         assert_eq!(a, b);
@@ -1346,12 +1316,12 @@ fn test_equal_sneaky_small() {
 
     #[test]
     fn test_equal_sneaky_big() {
-        let mut a = bitv::Bitv::new(100, false);
+        let mut a = bitv::Bitv::with_capacity(100, false);
         for i in range(0u, 100) {
             a.set(i, true);
         }
 
-        let mut b = bitv::Bitv::new(100, true);
+        let mut b = bitv::Bitv::with_capacity(100, true);
         for i in range(0u, 100) {
             b.set(i, true);
         }
@@ -1363,16 +1333,16 @@ fn test_equal_sneaky_big() {
     fn test_from_bytes() {
         let bitv = from_bytes([0b10110110, 0b00000000, 0b11111111]);
         let str = format!("{}{}{}", "10110110", "00000000", "11111111");
-        assert_eq!(bitv.to_str().as_slice(), str.as_slice());
+        assert_eq!(bitv.to_string().as_slice(), str.as_slice());
     }
 
     #[test]
     fn test_to_bytes() {
-        let mut bv = Bitv::new(3, true);
+        let mut bv = Bitv::with_capacity(3, true);
         bv.set(1, false);
         assert_eq!(bv.to_bytes(), vec!(0b10100000));
 
-        let mut bv = Bitv::new(9, false);
+        let mut bv = Bitv::with_capacity(9, false);
         bv.set(2, true);
         bv.set(8, true);
         assert_eq!(bv.to_bytes(), vec!(0b00100000, 0b10000000));
@@ -1380,20 +1350,21 @@ fn test_to_bytes() {
 
     #[test]
     fn test_from_bools() {
-        assert!(from_bools([true, false, true, true]).to_str().as_slice() ==
-                "1011");
+        let bools = vec![true, false, true, true];
+        let bitv: Bitv = bools.iter().map(|n| *n).collect();
+        assert_eq!(bitv.to_string().as_slice(), "1011");
     }
 
     #[test]
     fn test_to_bools() {
         let bools = vec!(false, false, true, false, false, true, true, false);
-        assert_eq!(from_bytes([0b00100110]).to_bools(), bools);
+        assert_eq!(from_bytes([0b00100110]).iter().collect::<Vec<bool>>(), bools);
     }
 
     #[test]
     fn test_bitv_iterator() {
         let bools = [true, false, true, true];
-        let bitv = from_bools(bools);
+        let bitv: Bitv = bools.iter().map(|n| *n).collect();
 
         for (act, &ex) in bitv.iter().zip(bools.iter()) {
             assert_eq!(ex, act);
@@ -1403,7 +1374,7 @@ fn test_bitv_iterator() {
     #[test]
     fn test_bitv_set_iterator() {
         let bools = [true, false, true, true];
-        let bitv = BitvSet::from_bitv(from_bools(bools));
+        let bitv = BitvSet::from_bitv(bools.iter().map(|n| *n).collect());
 
         let idxs: Vec<uint> = bitv.iter().collect();
         assert_eq!(idxs, vec!(0, 2, 3));
@@ -1415,7 +1386,7 @@ fn test_bitv_set_frombitv_init() {
         let lengths = [10, 64, 100];
         for &b in bools.iter() {
             for &l in lengths.iter() {
-                let bitset = BitvSet::from_bitv(Bitv::new(l, b));
+                let bitset = BitvSet::from_bitv(Bitv::with_capacity(l, b));
                 assert_eq!(bitset.contains(&1u), b)
                 assert_eq!(bitset.contains(&(l-1u)), b)
                 assert!(!bitset.contains(&l))
@@ -1425,60 +1396,84 @@ fn test_bitv_set_frombitv_init() {
 
     #[test]
     fn test_small_difference() {
-        let mut b1 = Bitv::new(3, false);
-        let mut b2 = Bitv::new(3, false);
+        let mut b1 = Bitv::with_capacity(3, false);
+        let mut b2 = Bitv::with_capacity(3, false);
         b1.set(0, true);
         b1.set(1, true);
         b2.set(1, true);
         b2.set(2, true);
         assert!(b1.difference(&b2));
-        assert!(b1[0]);
-        assert!(!b1[1]);
-        assert!(!b1[2]);
+        assert!(b1.get(0));
+        assert!(!b1.get(1));
+        assert!(!b1.get(2));
     }
 
     #[test]
     fn test_big_difference() {
-        let mut b1 = Bitv::new(100, false);
-        let mut b2 = Bitv::new(100, false);
+        let mut b1 = Bitv::with_capacity(100, false);
+        let mut b2 = Bitv::with_capacity(100, false);
         b1.set(0, true);
         b1.set(40, true);
         b2.set(40, true);
         b2.set(80, true);
         assert!(b1.difference(&b2));
-        assert!(b1[0]);
-        assert!(!b1[40]);
-        assert!(!b1[80]);
+        assert!(b1.get(0));
+        assert!(!b1.get(40));
+        assert!(!b1.get(80));
     }
 
     #[test]
     fn test_small_clear() {
-        let mut b = Bitv::new(14, true);
+        let mut b = Bitv::with_capacity(14, true);
         b.clear();
-        b.ones(|i| {
+        BitvSet::from_bitv(b).iter().advance(|i| {
             fail!("found 1 at {:?}", i)
         });
     }
 
     #[test]
     fn test_big_clear() {
-        let mut b = Bitv::new(140, true);
+        let mut b = Bitv::with_capacity(140, true);
         b.clear();
-        b.ones(|i| {
+        BitvSet::from_bitv(b).iter().advance(|i| {
             fail!("found 1 at {:?}", i)
         });
     }
 
+    #[test]
+    fn test_bitv_masking() {
+        let b = Bitv::with_capacity(140, true);
+        let mut bs = BitvSet::from_bitv(b);
+        assert!(bs.contains(&139));
+        assert!(!bs.contains(&140));
+        assert!(bs.insert(150));
+        assert!(!bs.contains(&140));
+        assert!(!bs.contains(&149));
+        assert!(bs.contains(&150));
+        assert!(!bs.contains(&151));
+    }
+
     #[test]
     fn test_bitv_set_basic() {
+        // calculate nbits with uint::BITS granularity
+        fn calc_nbits(bits: uint) -> uint {
+            uint::BITS * ((bits + uint::BITS - 1) / uint::BITS)
+        }
+
         let mut b = BitvSet::new();
+        assert_eq!(b.capacity(), calc_nbits(0));
         assert!(b.insert(3));
+        assert_eq!(b.capacity(), calc_nbits(3));
         assert!(!b.insert(3));
         assert!(b.contains(&3));
+        assert!(b.insert(4));
+        assert!(!b.insert(4));
+        assert!(b.contains(&3));
         assert!(b.insert(400));
+        assert_eq!(b.capacity(), calc_nbits(400));
         assert!(!b.insert(400));
         assert!(b.contains(&400));
-        assert_eq!(b.len(), 2);
+        assert_eq!(b.len(), 3);
     }
 
     #[test]
@@ -1501,8 +1496,8 @@ fn test_bitv_set_intersection() {
 
         let mut i = 0;
         let expected = [3, 5, 11, 77];
-        a.intersection(&b|x| {
-            assert_eq!(*x, expected[i]);
+        a.intersection(&b).advance(|x| {
+            assert_eq!(x, expected[i]);
             i += 1;
             true
         });
@@ -1525,8 +1520,8 @@ fn test_bitv_set_difference() {
 
         let mut i = 0;
         let expected = [1, 5, 500];
-        a.difference(&b|x| {
-            assert_eq!(*x, expected[i]);
+        a.difference(&b).advance(|x| {
+            assert_eq!(x, expected[i]);
             i += 1;
             true
         });
@@ -1551,8 +1546,8 @@ fn test_bitv_set_symmetric_difference() {
 
         let mut i = 0;
         let expected = [1, 5, 11, 14, 220];
-        a.symmetric_difference(&b|x| {
-            assert_eq!(*x, expected[i]);
+        a.symmetric_difference(&b).advance(|x| {
+            assert_eq!(x, expected[i]);
             i += 1;
             true
         });
@@ -1580,14 +1575,40 @@ fn test_bitv_set_union() {
 
         let mut i = 0;
         let expected = [1, 3, 5, 9, 11, 13, 19, 24, 160];
-        a.union(&b|x| {
-            assert_eq!(*x, expected[i]);
+        a.union(&b).advance(|x| {
+            assert_eq!(x, expected[i]);
             i += 1;
             true
         });
         assert_eq!(i, expected.len());
     }
 
+    #[test]
+    fn test_bitv_set_subset() {
+        let mut set1 = BitvSet::new();
+        let mut set2 = BitvSet::new();
+
+        assert!(set1.is_subset(&set2)); //  {}  {}
+        set2.insert(100);
+        assert!(set1.is_subset(&set2)); //  {}  { 1 }
+        set2.insert(200);
+        assert!(set1.is_subset(&set2)); //  {}  { 1, 2 }
+        set1.insert(200);
+        assert!(set1.is_subset(&set2)); //  { 2 }  { 1, 2 }
+        set1.insert(300);
+        assert!(!set1.is_subset(&set2)); // { 2, 3 }  { 1, 2 }
+        set2.insert(300);
+        assert!(set1.is_subset(&set2)); // { 2, 3 }  { 1, 2, 3 }
+        set2.insert(400);
+        assert!(set1.is_subset(&set2)); // { 2, 3 }  { 1, 2, 3, 4 }
+        set2.remove(&100);
+        assert!(set1.is_subset(&set2)); // { 2, 3 }  { 2, 3, 4 }
+        set2.remove(&300);
+        assert!(!set1.is_subset(&set2)); // { 2, 3 }  { 2, 4 }
+        set1.remove(&300);
+        assert!(set1.is_subset(&set2)); // { 2 }  { 2, 4 }
+    }
+
     #[test]
     fn test_bitv_remove() {
         let mut a = BitvSet::new();
@@ -1600,6 +1621,7 @@ fn test_bitv_remove() {
 
         assert!(a.insert(1000));
         assert!(a.remove(&1000));
+        a.shrink_to_fit();
         assert_eq!(a.capacity(), uint::BITS);
     }
 
@@ -1667,6 +1689,97 @@ fn test_big_bitv_tests() {
         assert!(!v.none());
     }
 
+    #[test]
+    fn test_bitv_push_pop() {
+        let mut s = Bitv::with_capacity(5 * uint::BITS - 2, false);
+        assert_eq!(s.len(), 5 * uint::BITS - 2);
+        assert_eq!(s.get(5 * uint::BITS - 3), false);
+        s.push(true);
+        s.push(true);
+        assert_eq!(s.get(5 * uint::BITS - 2), true);
+        assert_eq!(s.get(5 * uint::BITS - 1), true);
+        // Here the internal vector will need to be extended
+        s.push(false);
+        assert_eq!(s.get(5 * uint::BITS), false);
+        s.push(false);
+        assert_eq!(s.get(5 * uint::BITS + 1), false);
+        assert_eq!(s.len(), 5 * uint::BITS + 2);
+        // Pop it all off
+        assert_eq!(s.pop(), false);
+        assert_eq!(s.pop(), false);
+        assert_eq!(s.pop(), true);
+        assert_eq!(s.pop(), true);
+        assert_eq!(s.len(), 5 * uint::BITS - 2);
+    }
+
+    #[test]
+    fn test_bitv_truncate() {
+        let mut s = Bitv::with_capacity(5 * uint::BITS, true);
+
+        assert_eq!(s, Bitv::with_capacity(5 * uint::BITS, true));
+        assert_eq!(s.len(), 5 * uint::BITS);
+        s.truncate(4 * uint::BITS);
+        assert_eq!(s, Bitv::with_capacity(4 * uint::BITS, true));
+        assert_eq!(s.len(), 4 * uint::BITS);
+        // Truncating to a size > s.len() should be a noop
+        s.truncate(5 * uint::BITS);
+        assert_eq!(s, Bitv::with_capacity(4 * uint::BITS, true));
+        assert_eq!(s.len(), 4 * uint::BITS);
+        s.truncate(3 * uint::BITS - 10);
+        assert_eq!(s, Bitv::with_capacity(3 * uint::BITS - 10, true));
+        assert_eq!(s.len(), 3 * uint::BITS - 10);
+        s.truncate(0);
+        assert_eq!(s, Bitv::with_capacity(0, true));
+        assert_eq!(s.len(), 0);
+    }
+
+    #[test]
+    fn test_bitv_reserve() {
+        let mut s = Bitv::with_capacity(5 * uint::BITS, true);
+        // Check capacity
+        assert_eq!(s.capacity(), 5 * uint::BITS);
+        s.reserve(2 * uint::BITS);
+        assert_eq!(s.capacity(), 5 * uint::BITS);
+        s.reserve(7 * uint::BITS);
+        assert_eq!(s.capacity(), 7 * uint::BITS);
+        s.reserve(7 * uint::BITS);
+        assert_eq!(s.capacity(), 7 * uint::BITS);
+        s.reserve(7 * uint::BITS + 1);
+        assert_eq!(s.capacity(), 8 * uint::BITS);
+        // Check that length hasn't changed
+        assert_eq!(s.len(), 5 * uint::BITS);
+        s.push(true);
+        s.push(false);
+        s.push(true);
+        assert_eq!(s.get(5 * uint::BITS - 1), true);
+        assert_eq!(s.get(5 * uint::BITS - 0), true);
+        assert_eq!(s.get(5 * uint::BITS + 1), false);
+        assert_eq!(s.get(5 * uint::BITS + 2), true);
+    }
+
+    #[test]
+    fn test_bitv_grow() {
+        let mut bitv = from_bytes([0b10110110, 0b00000000, 0b10101010]);
+        bitv.grow(32, true);
+        assert_eq!(bitv, from_bytes([0b10110110, 0b00000000, 0b10101010,
+                                     0xFF, 0xFF, 0xFF, 0xFF]));
+        bitv.grow(64, false);
+        assert_eq!(bitv, from_bytes([0b10110110, 0b00000000, 0b10101010,
+                                     0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0]));
+        bitv.grow(16, true);
+        assert_eq!(bitv, from_bytes([0b10110110, 0b00000000, 0b10101010,
+                                     0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]));
+    }
+
+    #[test]
+    fn test_bitv_extend() {
+        let mut bitv = from_bytes([0b10110110, 0b00000000, 0b11111111]);
+        let ext = from_bytes([0b01001001, 0b10010010, 0b10111101]);
+        bitv.extend(ext.iter());
+        assert_eq!(bitv, from_bytes([0b10110110, 0b00000000, 0b11111111,
+                                     0b01001001, 0b10010010, 0b10111101]));
+    }
+
     #[test]
     fn test_bitv_set_show() {
         let mut s = BitvSet::new();
@@ -1674,7 +1787,7 @@ fn test_bitv_set_show() {
         s.insert(10);
         s.insert(50);
         s.insert(2);
-        assert_eq!("{1, 2, 10, 50}".to_string(), s.to_str());
+        assert_eq!("{1, 2, 10, 50}".to_string(), s.to_string());
     }
 
     fn rng() -> rand::IsaacRng {
@@ -1692,42 +1805,10 @@ fn bench_uint_small(b: &mut Bencher) {
         })
     }
 
-    #[bench]
-    fn bench_small_bitv_small(b: &mut Bencher) {
-        let mut r = rng();
-        let mut bitv = SmallBitv::new(uint::BITS);
-        b.iter(|| {
-            bitv.set((r.next_u32() as uint) % uint::BITS, true);
-            &bitv
-        })
-    }
-
-    #[bench]
-    fn bench_big_bitv_small(b: &mut Bencher) {
-        let mut r = rng();
-        let mut bitv = BigBitv::new(vec!(0));
-        b.iter(|| {
-            bitv.set((r.next_u32() as uint) % uint::BITS, true);
-            &bitv
-        })
-    }
-
-    #[bench]
-    fn bench_big_bitv_big(b: &mut Bencher) {
-        let mut r = rng();
-        let mut storage = vec!();
-        storage.grow(BENCH_BITS / uint::BITS, &0u);
-        let mut bitv = BigBitv::new(storage);
-        b.iter(|| {
-            bitv.set((r.next_u32() as uint) % BENCH_BITS, true);
-            &bitv
-        })
-    }
-
     #[bench]
     fn bench_bitv_big(b: &mut Bencher) {
         let mut r = rng();
-        let mut bitv = Bitv::new(BENCH_BITS, false);
+        let mut bitv = Bitv::with_capacity(BENCH_BITS, false);
         b.iter(|| {
             bitv.set((r.next_u32() as uint) % BENCH_BITS, true);
             &bitv
@@ -1737,7 +1818,7 @@ fn bench_bitv_big(b: &mut Bencher) {
     #[bench]
     fn bench_bitv_small(b: &mut Bencher) {
         let mut r = rng();
-        let mut bitv = Bitv::new(uint::BITS, false);
+        let mut bitv = Bitv::with_capacity(uint::BITS, false);
         b.iter(|| {
             bitv.set((r.next_u32() as uint) % uint::BITS, true);
             &bitv
@@ -1766,8 +1847,8 @@ fn bench_bitv_set_big(b: &mut Bencher) {
 
     #[bench]
     fn bench_bitv_big_union(b: &mut Bencher) {
-        let mut b1 = Bitv::new(BENCH_BITS, false);
-        let b2 = Bitv::new(BENCH_BITS, false);
+        let mut b1 = Bitv::with_capacity(BENCH_BITS, false);
+        let b2 = Bitv::with_capacity(BENCH_BITS, false);
         b.iter(|| {
             b1.union(&b2);
         })
@@ -1775,7 +1856,7 @@ fn bench_bitv_big_union(b: &mut Bencher) {
 
     #[bench]
     fn bench_btv_small_iter(b: &mut Bencher) {
-        let bitv = Bitv::new(uint::BITS, false);
+        let bitv = Bitv::with_capacity(uint::BITS, false);
         b.iter(|| {
             let mut _sum = 0;
             for pres in bitv.iter() {
@@ -1786,7 +1867,7 @@ fn bench_btv_small_iter(b: &mut Bencher) {
 
     #[bench]
     fn bench_bitv_big_iter(b: &mut Bencher) {
-        let bitv = Bitv::new(BENCH_BITS, false);
+        let bitv = Bitv::with_capacity(BENCH_BITS, false);
         b.iter(|| {
             let mut _sum = 0;
             for pres in bitv.iter() {
index 92abfaad3483301016fa4449e51221967446f2c9..2d138b1a1895f3d45406c15d00dbc9bdf5c9c421 100644 (file)
@@ -787,7 +787,6 @@ mod test_btree {
     fn insert_test_one() {
         let b = BTree::new(1i, "abc".to_string(), 2);
         let is_insert = b.insert(2i, "xyz".to_string());
-        //println!("{}", is_insert.clone().to_str());
         assert!(is_insert.root.is_leaf());
     }
 
@@ -798,7 +797,7 @@ fn insert_test_two() {
         let leaf_elt_3 = LeafElt::new(3i, "ccc".to_string());
         let n = Node::new_leaf(vec!(leaf_elt_1, leaf_elt_2, leaf_elt_3));
         let b = BTree::new_with_node_len(n, 3, 2);
-        //println!("{}", b.clone().insert(4, "ddd".to_string()).to_str());
+        //println!("{}", b.clone().insert(4, "ddd".to_string()).to_string());
         assert!(b.insert(4, "ddd".to_string()).root.is_leaf());
     }
 
@@ -810,7 +809,7 @@ fn insert_test_three() {
         let leaf_elt_4 = LeafElt::new(4i, "ddd".to_string());
         let n = Node::new_leaf(vec!(leaf_elt_1, leaf_elt_2, leaf_elt_3, leaf_elt_4));
         let b = BTree::new_with_node_len(n, 3, 2);
-        //println!("{}", b.clone().insert(5, "eee".to_string()).to_str());
+        //println!("{}", b.clone().insert(5, "eee".to_string()).to_string());
         assert!(!b.insert(5, "eee".to_string()).root.is_leaf());
     }
 
@@ -827,7 +826,7 @@ fn insert_test_four() {
         b = b.clone().insert(7, "ggg".to_string());
         b = b.clone().insert(8, "hhh".to_string());
         b = b.clone().insert(0, "omg".to_string());
-        //println!("{}", b.clone().to_str());
+        //println!("{}", b.clone().to_string());
         assert!(!b.root.is_leaf());
     }
 
@@ -905,11 +904,11 @@ fn btree_cmp_test_greater() {
         assert!(&b2.cmp(&b) == &Greater)
     }
 
-    //Tests the BTree's to_str() method.
+    //Tests the BTree's to_string() method.
     #[test]
     fn btree_tostr_test() {
         let b = BTree::new(1i, "abc".to_string(), 2);
-        assert_eq!(b.to_str(), "Key: 1, value: abc;".to_string())
+        assert_eq!(b.to_string(), "Key: 1, value: abc;".to_string())
     }
 
 }
index 4114c8cb1c4ddc8b7a5a489de9ea5ee1f7a8c518..ed2d67388766700ebd3b99ddf4ec9d739d05ea88 100644 (file)
@@ -1041,12 +1041,12 @@ fn test_fuzz() {
     #[test]
     fn test_show() {
         let list: DList<int> = range(0i, 10).collect();
-        assert!(list.to_str().as_slice() == "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
+        assert!(list.to_string().as_slice() == "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
 
         let list: DList<&str> = vec!["just", "one", "test", "more"].iter()
                                                                    .map(|&s| s)
                                                                    .collect();
-        assert!(list.to_str().as_slice() == "[just, one, test, more]");
+        assert!(list.to_string().as_slice() == "[just, one, test, more]");
     }
 
     #[cfg(test)]
index c698b35c84811db2176daa87733a8394d99daafd..d9a62cd9acd76da42ccd59b626f95914858fd783 100644 (file)
@@ -12,7 +12,8 @@
  * Collection types.
  */
 
-#![crate_id = "collections#0.11.0"]
+#![crate_id = "collections#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "collections"]
 #![experimental]
 #![crate_type = "rlib"]
 #![license = "MIT/ASL2"]
@@ -24,6 +25,7 @@
 #![feature(macro_rules, managed_boxes, default_type_params, phase, globs)]
 #![feature(unsafe_destructor)]
 #![no_std]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 #[phase(plugin, link)] extern crate core;
 extern crate alloc;
index 14e41f3fef96546a257d531eb429e91e3b46e37e..ca62b1235d5549e01a6f3b6ed0fc522149a1ce71 100644 (file)
@@ -491,7 +491,7 @@ fn test_show() {
         map.insert(1, 2i);
         map.insert(3, 4i);
 
-        let map_str = map.to_str();
+        let map_str = map.to_string();
         let map_str = map_str.as_slice();
         assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}");
         assert_eq!(format!("{}", empty), "{}".to_string());
index ddba4b34e3a2a4e8a5664f54b61d95e08ffeb943..63c95fa25cb0da74b5d57b1d25569fb3eb363a41 100644 (file)
@@ -657,7 +657,7 @@ impl<'a> StrAllocating for MaybeOwned<'a> {
     #[inline]
     fn into_string(self) -> String {
         match self {
-            Slice(s) => s.to_string(),
+            Slice(s) => String::from_str(s),
             Owned(s) => s
         }
     }
@@ -673,7 +673,7 @@ impl<'a> Clone for MaybeOwned<'a> {
     fn clone(&self) -> MaybeOwned<'a> {
         match *self {
             Slice(s) => Slice(s),
-            Owned(ref s) => Owned(s.to_string())
+            Owned(ref s) => Owned(String::from_str(s.as_slice()))
         }
     }
 }
@@ -762,7 +762,7 @@ fn test_from_buf_len() {
             let a = vec![65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 0u8];
             let b = a.as_ptr();
             let c = from_buf_len(b, 3u);
-            assert_eq!(c, "AAA".to_string());
+            assert_eq!(c, String::from_str("AAA"));
         }
     }
 }
@@ -776,12 +776,6 @@ pub trait StrAllocating: Str {
     /// Convert `self` into a `String`, not making a copy if possible.
     fn into_string(self) -> String;
 
-    /// Convert `self` into a `String`.
-    #[inline]
-    fn to_string(&self) -> String {
-        String::from_str(self.as_slice())
-    }
-
     #[allow(missing_doc)]
     #[deprecated = "replaced by .into_string()"]
     fn into_owned(self) -> String {
@@ -933,7 +927,7 @@ fn nfkd_chars<'a>(&'a self) -> Decompositions<'a> {
 impl<'a> StrAllocating for &'a str {
     #[inline]
     fn into_string(self) -> String {
-        self.to_string()
+        String::from_str(self)
     }
 }
 
@@ -963,11 +957,19 @@ fn append(mut self, rhs: &str) -> String {
 
 #[cfg(test)]
 mod tests {
-    use std::prelude::*;
     use std::iter::AdditiveIterator;
     use std::default::Default;
+    use std::char::Char;
+    use std::clone::Clone;
+    use std::cmp::{Equal, Greater, Less, Ord, Eq, PartialOrd, PartialEq, Equiv};
+    use std::result::{Ok, Err};
+    use std::option::{Some, None};
+    use std::ptr::RawPtr;
+    use std::iter::{Iterator, DoubleEndedIterator};
+    use Collection;
 
-    use str::*;
+    use super::*;
+    use std::slice::{Vector, ImmutableVector};
     use string::String;
     use vec::Vec;
 
@@ -1028,17 +1030,17 @@ fn test_rfind() {
 
     #[test]
     fn test_collect() {
-        let empty = "".to_string();
+        let empty = String::from_str("");
         let s: String = empty.as_slice().chars().collect();
         assert_eq!(empty, s);
-        let data = "ประเทศไทย中".to_string();
+        let data = String::from_str("ประเทศไทย中");
         let s: String = data.as_slice().chars().collect();
         assert_eq!(data, s);
     }
 
     #[test]
     fn test_into_bytes() {
-        let data = "asdf".to_string();
+        let data = String::from_str("asdf");
         let buf = data.into_bytes();
         assert_eq!(b"asdf", buf.as_slice());
     }
@@ -1055,7 +1057,7 @@ fn test_find_str() {
         assert!(data.slice(2u, 4u).find_str("ab").is_none());
 
         let string = "ประเทศไทย中华Việt Nam";
-        let mut data = string.to_string();
+        let mut data = String::from_str(string);
         data.push_str(string);
         assert!(data.as_slice().find_str("ไท华").is_none());
         assert_eq!(data.as_slice().slice(0u, 43u).find_str(""), Some(0u));
@@ -1092,11 +1094,13 @@ fn test_concat() {
         fn t(v: &[String], s: &str) {
             assert_eq!(v.concat().as_slice(), s);
         }
-        t(["you".to_string(), "know".to_string(), "I'm".to_string(),
-          "no".to_string(), "good".to_string()], "youknowI'mnogood");
+        t([String::from_str("you"), String::from_str("know"),
+           String::from_str("I'm"),
+           String::from_str("no"), String::from_str("good")],
+          "youknowI'mnogood");
         let v: &[String] = [];
         t(v, "");
-        t(["hi".to_string()], "hi");
+        t([String::from_str("hi")], "hi");
     }
 
     #[test]
@@ -1104,12 +1108,13 @@ fn test_connect() {
         fn t(v: &[String], sep: &str, s: &str) {
             assert_eq!(v.connect(sep).as_slice(), s);
         }
-        t(["you".to_string(), "know".to_string(), "I'm".to_string(),
-           "no".to_string(), "good".to_string()],
+        t([String::from_str("you"), String::from_str("know"),
+           String::from_str("I'm"),
+           String::from_str("no"), String::from_str("good")],
           " ", "you know I'm no good");
         let v: &[String] = [];
         t(v, " ", "");
-        t(["hi".to_string()], " ", "hi");
+        t([String::from_str("hi")], " ", "hi");
     }
 
     #[test]
@@ -1136,11 +1141,11 @@ fn t(v: &[&str], sep: &str, s: &str) {
 
     #[test]
     fn test_repeat() {
-        assert_eq!("x".repeat(4), "xxxx".to_string());
-        assert_eq!("hi".repeat(4), "hihihihi".to_string());
-        assert_eq!("ไท华".repeat(3), "ไท华ไท华ไท华".to_string());
-        assert_eq!("".repeat(4), "".to_string());
-        assert_eq!("hi".repeat(0), "".to_string());
+        assert_eq!("x".repeat(4), String::from_str("xxxx"));
+        assert_eq!("hi".repeat(4), String::from_str("hihihihi"));
+        assert_eq!("ไท华".repeat(3), String::from_str("ไท华ไท华ไท华"));
+        assert_eq!("".repeat(4), String::from_str(""));
+        assert_eq!("hi".repeat(0), String::from_str(""));
     }
 
     #[test]
@@ -1168,9 +1173,9 @@ fn half_a_million_letter_a() -> String {
         }
         let letters = a_million_letter_a();
         assert!(half_a_million_letter_a() ==
-            unsafe {raw::slice_bytes(letters.as_slice(),
+            unsafe {String::from_str(raw::slice_bytes(letters.as_slice(),
                                      0u,
-                                     500000)}.to_string());
+                                     500000))});
     }
 
     #[test]
@@ -1204,13 +1209,13 @@ fn test_is_empty() {
     #[test]
     fn test_replace() {
         let a = "a";
-        assert_eq!("".replace(a, "b"), "".to_string());
-        assert_eq!("a".replace(a, "b"), "b".to_string());
-        assert_eq!("ab".replace(a, "b"), "bb".to_string());
+        assert_eq!("".replace(a, "b"), String::from_str(""));
+        assert_eq!("a".replace(a, "b"), String::from_str("b"));
+        assert_eq!("ab".replace(a, "b"), String::from_str("bb"));
         let test = "test";
         assert!(" test test ".replace(test, "toast") ==
-            " toast toast ".to_string());
-        assert_eq!(" test test ".replace(test, ""), "   ".to_string());
+            String::from_str(" toast toast "));
+        assert_eq!(" test test ".replace(test, ""), String::from_str("   "));
     }
 
     #[test]
@@ -1285,7 +1290,7 @@ fn half_a_million_letter_x() -> String {
         }
         let letters = a_million_letter_x();
         assert!(half_a_million_letter_x() ==
-            letters.as_slice().slice(0u, 3u * 500000u).to_string());
+            String::from_str(letters.as_slice().slice(0u, 3u * 500000u)));
     }
 
     #[test]
@@ -1513,7 +1518,7 @@ fn test_raw_from_c_str() {
             let a = vec![65, 65, 65, 65, 65, 65, 65, 0];
             let b = a.as_ptr();
             let c = raw::from_c_str(b);
-            assert_eq!(c, "AAAAAAA".to_string());
+            assert_eq!(c, String::from_str("AAAAAAA"));
         }
     }
 
@@ -1535,7 +1540,7 @@ fn test_as_bytes() {
     fn test_as_bytes_fail() {
         // Don't double free. (I'm not sure if this exercises the
         // original problem code path anymore.)
-        let s = "".to_string();
+        let s = String::from_str("");
         let _bytes = s.as_bytes();
         fail!();
     }
@@ -1578,10 +1583,10 @@ fn test_subslice_offset_2() {
 
     #[test]
     fn vec_str_conversions() {
-        let s1: String = "All mimsy were the borogoves".to_string();
+        let s1: String = String::from_str("All mimsy were the borogoves");
 
         let v: Vec<u8> = Vec::from_slice(s1.as_bytes());
-        let s2: String = from_utf8(v.as_slice()).unwrap().to_string();
+        let s2: String = String::from_str(from_utf8(v.as_slice()).unwrap());
         let mut i: uint = 0u;
         let n1: uint = s1.len();
         let n2: uint = v.len();
@@ -1624,13 +1629,13 @@ fn test_contains_char() {
     #[test]
     fn test_utf16() {
         let pairs =
-            [("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n".to_string(),
+            [(String::from_str("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
               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_string(),
+             (String::from_str("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
               vec![0xd801_u16, 0xdc12_u16, 0xd801_u16,
                 0xdc49_u16, 0xd801_u16, 0xdc2e_u16, 0xd801_u16,
                 0xdc40_u16, 0xd801_u16, 0xdc32_u16, 0xd801_u16,
@@ -1638,7 +1643,7 @@ fn test_utf16() {
                 0xd801_u16, 0xdc32_u16, 0xd801_u16, 0xdc4d_u16,
                 0x000a_u16]),
 
-             ("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n".to_string(),
+             (String::from_str("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
               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,
@@ -1647,7 +1652,7 @@ fn test_utf16() {
                 0xdf04_u16, 0xd800_u16, 0xdf0b_u16, 0xd800_u16,
                 0xdf09_u16, 0xd800_u16, 0xdf11_u16, 0x000a_u16 ]),
 
-             ("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n".to_string(),
+             (String::from_str("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
               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,
@@ -1660,7 +1665,7 @@ fn test_utf16() {
                 0xd801_u16, 0xdc95_u16, 0xd801_u16, 0xdc86_u16,
                 0x000a_u16 ]),
              // Issue #12318, even-numbered non-BMP planes
-             ("\U00020000".to_string(),
+             (String::from_str("\U00020000"),
               vec![0xD840, 0xDC00])];
 
         for p in pairs.iter() {
@@ -1698,16 +1703,16 @@ fn test_utf16_invalid() {
     fn test_utf16_lossy() {
         // completely positive cases tested above.
         // lead + eof
-        assert_eq!(from_utf16_lossy([0xD800]), "\uFFFD".to_string());
+        assert_eq!(from_utf16_lossy([0xD800]), String::from_str("\uFFFD"));
         // lead + lead
-        assert_eq!(from_utf16_lossy([0xD800, 0xD800]), "\uFFFD\uFFFD".to_string());
+        assert_eq!(from_utf16_lossy([0xD800, 0xD800]), String::from_str("\uFFFD\uFFFD"));
 
         // isolated trail
-        assert_eq!(from_utf16_lossy([0x0061, 0xDC00]), "a\uFFFD".to_string());
+        assert_eq!(from_utf16_lossy([0x0061, 0xDC00]), String::from_str("a\uFFFD"));
 
         // general
         assert_eq!(from_utf16_lossy([0xD800, 0xd801, 0xdc8b, 0xD800]),
-                   "\uFFFD𐒋\uFFFD".to_string());
+                   String::from_str("\uFFFD𐒋\uFFFD"));
     }
 
     #[test]
@@ -1752,27 +1757,29 @@ fn test_char_at_reverse() {
 
     #[test]
     fn test_escape_unicode() {
-        assert_eq!("abc".escape_unicode(), "\\x61\\x62\\x63".to_string());
-        assert_eq!("a c".escape_unicode(), "\\x61\\x20\\x63".to_string());
-        assert_eq!("\r\n\t".escape_unicode(), "\\x0d\\x0a\\x09".to_string());
-        assert_eq!("'\"\\".escape_unicode(), "\\x27\\x22\\x5c".to_string());
-        assert_eq!("\x00\x01\xfe\xff".escape_unicode(), "\\x00\\x01\\xfe\\xff".to_string());
-        assert_eq!("\u0100\uffff".escape_unicode(), "\\u0100\\uffff".to_string());
-        assert_eq!("\U00010000\U0010ffff".escape_unicode(), "\\U00010000\\U0010ffff".to_string());
-        assert_eq!("ab\ufb00".escape_unicode(), "\\x61\\x62\\ufb00".to_string());
-        assert_eq!("\U0001d4ea\r".escape_unicode(), "\\U0001d4ea\\x0d".to_string());
+        assert_eq!("abc".escape_unicode(), String::from_str("\\x61\\x62\\x63"));
+        assert_eq!("a c".escape_unicode(), String::from_str("\\x61\\x20\\x63"));
+        assert_eq!("\r\n\t".escape_unicode(), String::from_str("\\x0d\\x0a\\x09"));
+        assert_eq!("'\"\\".escape_unicode(), String::from_str("\\x27\\x22\\x5c"));
+        assert_eq!("\x00\x01\xfe\xff".escape_unicode(), String::from_str("\\x00\\x01\\xfe\\xff"));
+        assert_eq!("\u0100\uffff".escape_unicode(), String::from_str("\\u0100\\uffff"));
+        assert_eq!("\U00010000\U0010ffff".escape_unicode(),
+                   String::from_str("\\U00010000\\U0010ffff"));
+        assert_eq!("ab\ufb00".escape_unicode(), String::from_str("\\x61\\x62\\ufb00"));
+        assert_eq!("\U0001d4ea\r".escape_unicode(), String::from_str("\\U0001d4ea\\x0d"));
     }
 
     #[test]
     fn test_escape_default() {
-        assert_eq!("abc".escape_default(), "abc".to_string());
-        assert_eq!("a c".escape_default(), "a c".to_string());
-        assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t".to_string());
-        assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\".to_string());
-        assert_eq!("\u0100\uffff".escape_default(), "\\u0100\\uffff".to_string());
-        assert_eq!("\U00010000\U0010ffff".escape_default(), "\\U00010000\\U0010ffff".to_string());
-        assert_eq!("ab\ufb00".escape_default(), "ab\\ufb00".to_string());
-        assert_eq!("\U0001d4ea\r".escape_default(), "\\U0001d4ea\\r".to_string());
+        assert_eq!("abc".escape_default(), String::from_str("abc"));
+        assert_eq!("a c".escape_default(), String::from_str("a c"));
+        assert_eq!("\r\n\t".escape_default(), String::from_str("\\r\\n\\t"));
+        assert_eq!("'\"\\".escape_default(), String::from_str("\\'\\\"\\\\"));
+        assert_eq!("\u0100\uffff".escape_default(), String::from_str("\\u0100\\uffff"));
+        assert_eq!("\U00010000\U0010ffff".escape_default(),
+                   String::from_str("\\U00010000\\U0010ffff"));
+        assert_eq!("ab\ufb00".escape_default(), String::from_str("ab\\ufb00"));
+        assert_eq!("\U0001d4ea\r".escape_default(), String::from_str("\\U0001d4ea\\r"));
     }
 
     #[test]
@@ -2013,30 +2020,39 @@ fn test_words() {
 
     #[test]
     fn test_nfd_chars() {
-        assert_eq!("abc".nfd_chars().collect::<String>(), "abc".to_string());
-        assert_eq!("\u1e0b\u01c4".nfd_chars().collect::<String>(), "d\u0307\u01c4".to_string());
-        assert_eq!("\u2026".nfd_chars().collect::<String>(), "\u2026".to_string());
-        assert_eq!("\u2126".nfd_chars().collect::<String>(), "\u03a9".to_string());
-        assert_eq!("\u1e0b\u0323".nfd_chars().collect::<String>(), "d\u0323\u0307".to_string());
-        assert_eq!("\u1e0d\u0307".nfd_chars().collect::<String>(), "d\u0323\u0307".to_string());
-        assert_eq!("a\u0301".nfd_chars().collect::<String>(), "a\u0301".to_string());
-        assert_eq!("\u0301a".nfd_chars().collect::<String>(), "\u0301a".to_string());
-        assert_eq!("\ud4db".nfd_chars().collect::<String>(), "\u1111\u1171\u11b6".to_string());
-        assert_eq!("\uac1c".nfd_chars().collect::<String>(), "\u1100\u1162".to_string());
+        assert_eq!("abc".nfd_chars().collect::<String>(), String::from_str("abc"));
+        assert_eq!("\u1e0b\u01c4".nfd_chars().collect::<String>(),
+                   String::from_str("d\u0307\u01c4"));
+        assert_eq!("\u2026".nfd_chars().collect::<String>(), String::from_str("\u2026"));
+        assert_eq!("\u2126".nfd_chars().collect::<String>(), String::from_str("\u03a9"));
+        assert_eq!("\u1e0b\u0323".nfd_chars().collect::<String>(),
+                   String::from_str("d\u0323\u0307"));
+        assert_eq!("\u1e0d\u0307".nfd_chars().collect::<String>(),
+                   String::from_str("d\u0323\u0307"));
+        assert_eq!("a\u0301".nfd_chars().collect::<String>(), String::from_str("a\u0301"));
+        assert_eq!("\u0301a".nfd_chars().collect::<String>(), String::from_str("\u0301a"));
+        assert_eq!("\ud4db".nfd_chars().collect::<String>(),
+                   String::from_str("\u1111\u1171\u11b6"));
+        assert_eq!("\uac1c".nfd_chars().collect::<String>(), String::from_str("\u1100\u1162"));
     }
 
     #[test]
     fn test_nfkd_chars() {
-        assert_eq!("abc".nfkd_chars().collect::<String>(), "abc".to_string());
-        assert_eq!("\u1e0b\u01c4".nfkd_chars().collect::<String>(), "d\u0307DZ\u030c".to_string());
-        assert_eq!("\u2026".nfkd_chars().collect::<String>(), "...".to_string());
-        assert_eq!("\u2126".nfkd_chars().collect::<String>(), "\u03a9".to_string());
-        assert_eq!("\u1e0b\u0323".nfkd_chars().collect::<String>(), "d\u0323\u0307".to_string());
-        assert_eq!("\u1e0d\u0307".nfkd_chars().collect::<String>(), "d\u0323\u0307".to_string());
-        assert_eq!("a\u0301".nfkd_chars().collect::<String>(), "a\u0301".to_string());
-        assert_eq!("\u0301a".nfkd_chars().collect::<String>(), "\u0301a".to_string());
-        assert_eq!("\ud4db".nfkd_chars().collect::<String>(), "\u1111\u1171\u11b6".to_string());
-        assert_eq!("\uac1c".nfkd_chars().collect::<String>(), "\u1100\u1162".to_string());
+        assert_eq!("abc".nfkd_chars().collect::<String>(), String::from_str("abc"));
+        assert_eq!("\u1e0b\u01c4".nfkd_chars().collect::<String>(),
+                   String::from_str("d\u0307DZ\u030c"));
+        assert_eq!("\u2026".nfkd_chars().collect::<String>(), String::from_str("..."));
+        assert_eq!("\u2126".nfkd_chars().collect::<String>(), String::from_str("\u03a9"));
+        assert_eq!("\u1e0b\u0323".nfkd_chars().collect::<String>(),
+                   String::from_str("d\u0323\u0307"));
+        assert_eq!("\u1e0d\u0307".nfkd_chars().collect::<String>(),
+                   String::from_str("d\u0323\u0307"));
+        assert_eq!("a\u0301".nfkd_chars().collect::<String>(), String::from_str("a\u0301"));
+        assert_eq!("\u0301a".nfkd_chars().collect::<String>(),
+                   String::from_str("\u0301a"));
+        assert_eq!("\ud4db".nfkd_chars().collect::<String>(),
+String::from_str("\u1111\u1171\u11b6"));
+        assert_eq!("\uac1c".nfkd_chars().collect::<String>(), String::from_str("\u1100\u1162"));
     }
 
     #[test]
@@ -2090,10 +2106,10 @@ fn sum_len<S: Collection>(v: &[S]) -> uint {
             v.iter().map(|x| x.len()).sum()
         }
 
-        let s = "01234".to_string();
+        let s = String::from_str("01234");
         assert_eq!(5, sum_len(["012", "", "34"]));
-        assert_eq!(5, sum_len(["01".to_string(), "2".to_string(),
-                               "34".to_string(), "".to_string()]));
+        assert_eq!(5, sum_len([String::from_str("01"), String::from_str("2"),
+                               String::from_str("34"), String::from_str("")]));
         assert_eq!(5, sum_len([s.as_slice()]));
     }
 
@@ -2112,10 +2128,10 @@ fn test_str_from_utf8() {
     #[test]
     fn test_str_from_utf8_owned() {
         let xs = Vec::from_slice(b"hello");
-        assert_eq!(from_utf8_owned(xs), Ok("hello".to_string()));
+        assert_eq!(from_utf8_owned(xs), Ok(String::from_str("hello")));
 
         let xs = Vec::from_slice("ศไทย中华Việt Nam".as_bytes());
-        assert_eq!(from_utf8_owned(xs), Ok("ศไทย中华Việt Nam".to_string()));
+        assert_eq!(from_utf8_owned(xs), Ok(String::from_str("ศไทย中华Việt Nam")));
 
         let xs = Vec::from_slice(b"hello\xFF");
         assert_eq!(from_utf8_owned(xs),
@@ -2131,34 +2147,30 @@ fn test_str_from_utf8_lossy() {
         assert_eq!(from_utf8_lossy(xs), Slice("ศไทย中华Việt Nam"));
 
         let xs = b"Hello\xC2 There\xFF Goodbye";
-        assert_eq!(from_utf8_lossy(xs), Owned("Hello\uFFFD There\uFFFD Goodbye".to_string()));
+        assert_eq!(from_utf8_lossy(xs), Owned(String::from_str("Hello\uFFFD There\uFFFD Goodbye")));
 
         let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
-        assert_eq!(from_utf8_lossy(xs), Owned("Hello\uFFFD\uFFFD There\uFFFD Goodbye".to_string()));
+        assert_eq!(from_utf8_lossy(xs),
+                   Owned(String::from_str("Hello\uFFFD\uFFFD There\uFFFD Goodbye")));
 
         let xs = b"\xF5foo\xF5\x80bar";
-        assert_eq!(from_utf8_lossy(xs), Owned("\uFFFDfoo\uFFFD\uFFFDbar".to_string()));
+        assert_eq!(from_utf8_lossy(xs), Owned(String::from_str("\uFFFDfoo\uFFFD\uFFFDbar")));
 
         let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
-        assert_eq!(from_utf8_lossy(xs), Owned("\uFFFDfoo\uFFFDbar\uFFFDbaz".to_string()));
+        assert_eq!(from_utf8_lossy(xs), Owned(String::from_str("\uFFFDfoo\uFFFDbar\uFFFDbaz")));
 
         let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
-        assert_eq!(from_utf8_lossy(xs), Owned("\uFFFDfoo\uFFFDbar\uFFFD\uFFFDbaz".to_string()));
+        assert_eq!(from_utf8_lossy(xs),
+                   Owned(String::from_str("\uFFFDfoo\uFFFDbar\uFFFD\uFFFDbaz")));
 
         let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
-        assert_eq!(from_utf8_lossy(xs), Owned("\uFFFD\uFFFD\uFFFD\uFFFD\
-                                               foo\U00010000bar".to_string()));
+        assert_eq!(from_utf8_lossy(xs), Owned(String::from_str("\uFFFD\uFFFD\uFFFD\uFFFD\
+                                               foo\U00010000bar")));
 
         // surrogates
         let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
-        assert_eq!(from_utf8_lossy(xs), Owned("\uFFFD\uFFFD\uFFFDfoo\
-                                               \uFFFD\uFFFD\uFFFDbar".to_string()));
-    }
-
-    #[test]
-    fn test_from_str() {
-      let owned: Option<::std::string::String> = from_str("string");
-      assert_eq!(owned.as_ref().map(|s| s.as_slice()), Some("string"));
+        assert_eq!(from_utf8_lossy(xs), Owned(String::from_str("\uFFFD\uFFFD\uFFFDfoo\
+                                               \uFFFD\uFFFD\uFFFDbar")));
     }
 
     #[test]
@@ -2166,18 +2178,18 @@ fn test_maybe_owned_traits() {
         let s = Slice("abcde");
         assert_eq!(s.len(), 5);
         assert_eq!(s.as_slice(), "abcde");
-        assert_eq!(s.to_str().as_slice(), "abcde");
+        assert_eq!(String::from_str(s.as_slice()).as_slice(), "abcde");
         assert_eq!(format!("{}", s).as_slice(), "abcde");
-        assert!(s.lt(&Owned("bcdef".to_string())));
+        assert!(s.lt(&Owned(String::from_str("bcdef"))));
         assert_eq!(Slice(""), Default::default());
 
-        let o = Owned("abcde".to_string());
+        let o = Owned(String::from_str("abcde"));
         assert_eq!(o.len(), 5);
         assert_eq!(o.as_slice(), "abcde");
-        assert_eq!(o.to_str().as_slice(), "abcde");
+        assert_eq!(String::from_str(o.as_slice()).as_slice(), "abcde");
         assert_eq!(format!("{}", o).as_slice(), "abcde");
         assert!(o.lt(&Slice("bcdef")));
-        assert_eq!(Owned("".to_string()), Default::default());
+        assert_eq!(Owned(String::from_str("")), Default::default());
 
         assert!(s.cmp(&o) == Equal);
         assert!(s.equiv(&o));
@@ -2192,31 +2204,33 @@ fn test_maybe_owned_methods() {
         assert!(s.is_slice());
         assert!(!s.is_owned());
 
-        let o = Owned("abcde".to_string());
+        let o = Owned(String::from_str("abcde"));
         assert!(!o.is_slice());
         assert!(o.is_owned());
     }
 
     #[test]
     fn test_maybe_owned_clone() {
-        assert_eq!(Owned("abcde".to_string()), Slice("abcde").clone());
-        assert_eq!(Owned("abcde".to_string()), Owned("abcde".to_string()).clone());
+        assert_eq!(Owned(String::from_str("abcde")), Slice("abcde").clone());
+        assert_eq!(Owned(String::from_str("abcde")), Owned(String::from_str("abcde")).clone());
         assert_eq!(Slice("abcde"), Slice("abcde").clone());
-        assert_eq!(Slice("abcde"), Owned("abcde".to_string()).clone());
+        assert_eq!(Slice("abcde"), Owned(String::from_str("abcde")).clone());
     }
 
     #[test]
     fn test_maybe_owned_into_string() {
-        assert_eq!(Slice("abcde").into_string(), "abcde".to_string());
-        assert_eq!(Owned("abcde".to_string()).into_string(), "abcde".to_string());
+        assert_eq!(Slice("abcde").into_string(), String::from_str("abcde"));
+        assert_eq!(Owned(String::from_str("abcde")).into_string(),
+                   String::from_str("abcde"));
     }
 
     #[test]
     fn test_into_maybe_owned() {
         assert_eq!("abcde".into_maybe_owned(), Slice("abcde"));
-        assert_eq!(("abcde".to_string()).into_maybe_owned(), Slice("abcde"));
-        assert_eq!("abcde".into_maybe_owned(), Owned("abcde".to_string()));
-        assert_eq!(("abcde".to_string()).into_maybe_owned(), Owned("abcde".to_string()));
+        assert_eq!((String::from_str("abcde")).into_maybe_owned(), Slice("abcde"));
+        assert_eq!("abcde".into_maybe_owned(), Owned(String::from_str("abcde")));
+        assert_eq!((String::from_str("abcde")).into_maybe_owned(),
+                   Owned(String::from_str("abcde")));
     }
 }
 
@@ -2224,7 +2238,10 @@ fn test_into_maybe_owned() {
 mod bench {
     use test::Bencher;
     use super::*;
-    use std::prelude::*;
+    use vec::Vec;
+    use std::iter::{Iterator, DoubleEndedIterator};
+    use std::collections::Collection;
+    use std::slice::Vector;
 
     #[bench]
     fn char_iterator(b: &mut Bencher) {
index 936e60388a66ae8223cca470b4f837d626399bfc..74b9465f2a5690c560837f70598e63fbc03e5ee9 100644 (file)
@@ -208,7 +208,7 @@ pub fn truncate(&mut self, len: uint) {
     /// Appends a byte to this string buffer. The caller must preserve the valid UTF-8 property.
     #[inline]
     pub unsafe fn push_byte(&mut self, byte: u8) {
-        self.push_bytes([byte])
+        self.vec.push(byte)
     }
 
     /// Removes the last byte from the string buffer and returns it. Returns `None` if this string
@@ -354,7 +354,7 @@ fn equiv(&self, other: &S) -> bool {
 
 impl<S: Str> Add<S, String> for String {
     fn add(&self, other: &S) -> String {
-        let mut s = self.to_string();
+        let mut s = String::from_str(self.as_slice());
         s.push_str(other.as_slice());
         return s;
     }
@@ -369,6 +369,12 @@ mod tests {
     use str::{Str, StrSlice};
     use super::String;
 
+    #[test]
+    fn test_from_str() {
+      let owned: Option<::std::string::String> = from_str("string");
+      assert_eq!(owned.as_ref().map(|s| s.as_slice()), Some("string"));
+    }
+
     #[bench]
     fn bench_with_capacity(b: &mut Bencher) {
         b.iter(|| {
index d53ecabd5a9cb147e5093e7ce172dd91acf1835a..6e2dc95cfd6e506f47e519e726cfcb51cdff6eae 100644 (file)
 use slice::{MutableOrdVector, MutableVectorAllocating, CloneableVector};
 use slice::{Items, MutItems};
 
+
+#[doc(hidden)]
+pub static PTR_MARKER: u8 = 0;
+
 /// An owned, growable vector.
 ///
 /// # Examples
@@ -71,7 +75,11 @@ impl<T> Vec<T> {
     /// ```
     #[inline]
     pub fn new() -> Vec<T> {
-        Vec { len: 0, cap: 0, ptr: 0 as *mut T }
+        // We want ptr to never be NULL so instead we set it to some arbitrary
+        // non-null value which is fine since we never call deallocate on the ptr
+        // if cap is 0. The reason for this is because the pointer of a slice
+        // being NULL would break the null pointer optimization for enums.
+        Vec { len: 0, cap: 0, ptr: &PTR_MARKER as *const _ as *mut T }
     }
 
     /// Constructs a new, empty `Vec` with the specified capacity.
@@ -88,7 +96,7 @@ pub fn new() -> Vec<T> {
     #[inline]
     pub fn with_capacity(capacity: uint) -> Vec<T> {
         if mem::size_of::<T>() == 0 {
-            Vec { len: 0, cap: uint::MAX, ptr: 0 as *mut T }
+            Vec { len: 0, cap: uint::MAX, ptr: &PTR_MARKER as *const _ as *mut T }
         } else if capacity == 0 {
             Vec::new()
         } else {
@@ -1206,15 +1214,7 @@ pub fn init<'a>(&'a self) -> &'a [T] {
     /// would also make any pointers to it invalid.
     #[inline]
     pub fn as_ptr(&self) -> *const T {
-        // If we have a 0-sized vector, then the base pointer should not be NULL
-        // because an iterator over the slice will attempt to yield the base
-        // pointer as the first element in the vector, but this will end up
-        // being Some(NULL) which is optimized to None.
-        if mem::size_of::<T>() == 0 {
-            1 as *const T
-        } else {
-            self.ptr as *const T
-        }
+        self.ptr as *const T
     }
 
     /// Returns a mutable unsafe pointer to the vector's buffer.
@@ -1226,12 +1226,7 @@ pub fn as_ptr(&self) -> *const T {
     /// would also make any pointers to it invalid.
     #[inline]
     pub fn as_mut_ptr(&mut self) -> *mut T {
-        // see above for the 0-size check
-        if mem::size_of::<T>() == 0 {
-            1 as *mut T
-        } else {
-            self.ptr
-        }
+        self.ptr
     }
 
     /// Retains only the elements specified by the predicate.
index 8696d385c44884d6d257b03818de2360e7f574c3..f374d2e9a274338ac647206853624c4f4d9baf47 100644 (file)
@@ -38,8 +38,6 @@
 //! ```
 
 use option::{Option, Some};
-#[cfg(stage0)]
-use option::None;
 
 /// Trait for values that can be compared for equality and inequality.
 ///
@@ -162,19 +160,6 @@ pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering {
 pub trait PartialOrd: PartialEq {
     /// This method returns an ordering between `self` and `other` values
     /// if one exists.
-    #[cfg(stage0)]
-    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
-        match (!self.lt(other), !other.lt(self)) {
-            (false, false) => None,
-            (false, true) => Some(Less),
-            (true, false) => Some(Greater),
-            (true, true) => Some(Equal),
-        }
-    }
-
-    /// This method returns an ordering between `self` and `other` values
-    /// if one exists.
-    #[cfg(not(stage0))]
     fn partial_cmp(&self, other: &Self) -> Option<Ordering>;
 
     /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
index f326195be1607f270e6283c4a0830b6c9816b563..ef5b51fd00b3f5a6894db5356f68371fac385d98 100644 (file)
@@ -70,7 +70,7 @@ pub enum SignFormat {
 /**
  * Converts a number to its string representation as a byte vector.
  * This is meant to be a common base implementation for all numeric string
- * conversion functions like `to_str()` or `to_str_radix()`.
+ * conversion functions like `to_string()` or `to_str_radix()`.
  *
  * # Arguments
  * - `num`           - The number to convert. Accepts any number that
index 5e238aeae32711004f1c5bfc6397985d06c63e1d..6966c96b30ba950facd75543d9d1e4f2686a3294 100644 (file)
@@ -48,6 +48,7 @@
 // separate crate, libcoretest, to avoid bizarre issues.
 
 #![crate_id = "core#0.11.0"]
+#![crate_name = "core"]
 #![experimental]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
@@ -60,6 +61,7 @@
 #![feature(globs, intrinsics, lang_items, macro_rules, managed_boxes, phase)]
 #![feature(simd, unsafe_destructor)]
 #![deny(missing_doc)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 mod macros;
 
index d42c09b8163dd1d6159264109b8ae85847f84d58..fc37fdde8f5855682c43fc13f035f8d7a66385fe 100644 (file)
@@ -613,7 +613,7 @@ fn shr(&self, other: &$t) -> $t { (*self) >> (*other as uint) }
 /**
  *
  * The `Index` trait is used to specify the functionality of indexing operations
- * like `arr[idx]`.
+ * like `arr[idx]` when used in an immutable context.
  *
  * # Example
  *
@@ -624,9 +624,9 @@ fn shr(&self, other: &$t) -> $t { (*self) >> (*other as uint) }
  * struct Foo;
  *
  * impl Index<Foo, Foo> for Foo {
- *     fn index(&self, _rhs: &Foo) -> Foo {
+ *     fn index<'a>(&'a self, _rhs: &Foo) -> &'a Foo {
  *         println!("Indexing!");
- *         *self
+ *         self
  *     }
  * }
  *
@@ -636,9 +636,42 @@ fn shr(&self, other: &$t) -> $t { (*self) >> (*other as uint) }
  * ```
  */
 #[lang="index"]
+#[cfg(not(stage0))]
 pub trait Index<Index,Result> {
     /// The method for the indexing (`Foo[Bar]`) operation
-    fn index(&self, index: &Index) -> Result;
+    fn index<'a>(&'a self, index: &Index) -> &'a Result;
+}
+
+/**
+ *
+ * The `IndexMut` trait is used to specify the functionality of indexing
+ * operations like `arr[idx]`, when used in a mutable context.
+ *
+ * # Example
+ *
+ * A trivial implementation of `IndexMut`. When `Foo[Foo]` happens, it ends up
+ * calling `index`, and therefore, `main` prints `Indexing!`.
+ *
+ * ```
+ * struct Foo;
+ *
+ * impl IndexMut<Foo, Foo> for Foo {
+ *     fn index_mut<'a>(&'a mut self, _rhs: &Foo) -> &'a mut Foo {
+ *         println!("Indexing!");
+ *         self
+ *     }
+ * }
+ *
+ * fn main() {
+ *     &mut Foo[Foo];
+ * }
+ * ```
+ */
+#[lang="index_mut"]
+#[cfg(not(stage0))]
+pub trait IndexMut<Index,Result> {
+    /// The method for the indexing (`Foo[Bar]`) operation
+    fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Result;
 }
 
 /**
index df9c0e67b0d6d3ab1176df298b39aacffd3db9d4..f967a2a5fa5acb450695b549b2770eff7e6e9843 100644 (file)
@@ -33,7 +33,9 @@
 pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
 pub use ops::{BitAnd, BitOr, BitXor};
 pub use ops::{Drop, Deref, DerefMut};
-pub use ops::{Shl, Shr, Index};
+pub use ops::{Shl, Shr};
+#[cfg(not(stage0))]
+pub use ops::{Index, IndexMut};
 pub use option::{Option, Some, None};
 pub use result::{Result, Ok, Err};
 
index 5cbbf30cd360721c912bdb4e63fd07031c6e93c9..32e1d570be36d9a97c80c0d310b3ac9c7c92f601 100644 (file)
@@ -10,7 +10,7 @@
 
 //! Error handling with the `Result` type
 //!
-//! `Result<T>` is the type used for returning and propagating
+//! `Result<T, E>` is the type used for returning and propagating
 //! errors. It is an enum with the variants, `Ok(T)`, representing
 //! success and containing a value, and `Err(E)`, representing error
 //! and containing an error value.
index 0178c0318b81c2afde7be72eec396e4cfc55a425..8197a7c2dcbe2dc3904f20d1fbbc3457a0f1f68a 100644 (file)
@@ -884,17 +884,20 @@ fn next(&mut self) -> Option<$elem> {
                     if self.ptr == self.end {
                         None
                     } else {
-                        let old = self.ptr;
-                        self.ptr = if mem::size_of::<T>() == 0 {
+                        if mem::size_of::<T>() == 0 {
                             // purposefully don't use 'ptr.offset' because for
                             // vectors with 0-size elements this would return the
                             // same pointer.
-                            transmute(self.ptr as uint + 1)
+                            self.ptr = transmute(self.ptr as uint + 1);
+
+                            // Use a non-null pointer value
+                            Some(transmute(1u))
                         } else {
-                            self.ptr.offset(1)
-                        };
+                            let old = self.ptr;
+                            self.ptr = self.ptr.offset(1);
 
-                        Some(transmute(old))
+                            Some(transmute(old))
+                        }
                     }
                 }
             }
@@ -916,13 +919,17 @@ fn next_back(&mut self) -> Option<$elem> {
                     if self.end == self.ptr {
                         None
                     } else {
-                        self.end = if mem::size_of::<T>() == 0 {
+                        if mem::size_of::<T>() == 0 {
                             // See above for why 'ptr.offset' isn't used
-                            transmute(self.end as uint - 1)
+                            self.end = transmute(self.end as uint - 1);
+
+                            // Use a non-null pointer value
+                            Some(transmute(1u))
                         } else {
-                            self.end.offset(-1)
-                        };
-                        Some(transmute(self.end))
+                            self.end = self.end.offset(-1);
+
+                            Some(transmute(self.end))
+                        }
                     }
                 }
             }
@@ -956,7 +963,12 @@ fn indexable(&self) -> uint {
     fn idx(&mut self, index: uint) -> Option<&'a T> {
         unsafe {
             if index < self.indexable() {
-                transmute(self.ptr.offset(index as int))
+                if mem::size_of::<T>() == 0 {
+                    // Use a non-null pointer value
+                    Some(transmute(1u))
+                } else {
+                    Some(transmute(self.ptr.offset(index as int)))
+                }
             } else {
                 None
             }
index 852edd90b0f3fb28ecb6ad4b574dce7fe2079d50..5393c207344348a9e7575b91ed9f652ddbee3470 100644 (file)
@@ -167,12 +167,6 @@ fn string(c: char) -> String {
     assert_eq!(s.as_slice(), "\\U0001d4b6");
 }
 
-#[test]
-fn test_to_str() {
-    let s = 't'.to_str();
-    assert_eq!(s.as_slice(), "t");
-}
-
 #[test]
 fn test_encode_utf8() {
     fn check(input: char, expect: &[u8]) {
index 4087cb952716831fa3a55215e8a3538024b0392e..0b04a07ea888af5a667fa1ad61015c0382141c5d 100644 (file)
@@ -45,7 +45,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             // If we have a specified width for formatting, then we have to make
             // this allocation of a new string
             _ => {
-                let s = repr::repr_to_str(self);
+                let s = repr::repr_to_string(self);
                 f.pad(s.as_slice())
             }
         }
index 850002b595e91a0031981e494e4be42cc9cef124..e5424fccbed59e902f11905dbec7424a6e35f70a 100644 (file)
@@ -16,7 +16,8 @@
 //! Additionally, it is not guaranteed that functionality such as reflection
 //! will persist into the future.
 
-#![crate_id = "debug#0.11.0"]
+#![crate_id = "debug#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "debug"]
 #![experimental]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
@@ -27,6 +28,7 @@
 #![experimental]
 #![feature(managed_boxes, macro_rules)]
 #![allow(experimental)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 pub mod fmt;
 pub mod reflect;
index 133353ec3d717a09a9225a332d77ae0e5b61f55a..3e541929dbf0883957cd74cd4f5046d1a52882f8 100644 (file)
@@ -73,7 +73,7 @@ fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> {
 
 macro_rules! num_repr(($ty:ident, $suffix:expr) => (impl Repr for $ty {
     fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> {
-        let s = self.to_str();
+        let s = self.to_string();
         writer.write(s.as_bytes()).and_then(|()| {
             writer.write($suffix)
         })
@@ -564,7 +564,7 @@ pub fn write_repr<T>(writer: &mut io::Writer, object: &T) -> io::IoResult<()> {
     }
 }
 
-pub fn repr_to_str<T>(t: &T) -> String {
+pub fn repr_to_string<T>(t: &T) -> String {
     let mut result = io::MemWriter::new();
     write_repr(&mut result as &mut io::Writer, t).unwrap();
     String::from_utf8(result.unwrap()).unwrap()
index d944818abc56ad3a4054aa87590448e4d4c1a9b5..923aab5e032457e9a94e690bb1acce129ef36841 100644 (file)
@@ -18,7 +18,8 @@
 
 */
 
-#![crate_id = "flate#0.11.0"]
+#![crate_id = "flate#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "flate"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
@@ -27,6 +28,7 @@
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/0.11.0/")]
 #![feature(phase)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 #[cfg(test)] #[phase(plugin, link)] extern crate log;
 
index b9c0fcce52da7c3e162412c0292392d358c59a24..c32f27adf65937aa2950f23da17f5ddfb31f0d69 100644 (file)
 //! Parsing does not happen at runtime: structures of `std::fmt::rt` are
 //! generated instead.
 
-#![crate_id = "fmt_macros#0.11.0"]
+#![crate_id = "fmt_macros#0.11.0"] // NOTE: remove after stage0c
+#![crate_name = "fmt_macros"]
 #![experimental]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![feature(macro_rules, globs)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 use std::char;
 use std::str;
index e854cd3069c8a78d0ff031cfe203a4bd9977eae5..55e55ba7e51bc4de40f90d373ef8cc0baf57d222 100644 (file)
@@ -39,7 +39,8 @@ fn main() {
 
 */
 
-#![crate_id = "fourcc#0.11.0"]
+#![crate_id = "fourcc#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "fourcc"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
@@ -47,6 +48,7 @@ fn main() {
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 #![feature(plugin_registrar, managed_boxes)]
 
index 00e6df9ffbbb2eab49343ac77ca144970fe07e07..bb3e90958f14229d266bfc986be70ba7d89e1952 100644 (file)
@@ -59,7 +59,7 @@
 //!     ];
 //!     let matches = match getopts(args.tail(), opts) {
 //!         Ok(m) => { m }
-//!         Err(f) => { fail!(f.to_str()) }
+//!         Err(f) => { fail!(f.to_string()) }
 //!     };
 //!     if matches.opt_present("h") {
 //!         print_usage(program.as_slice(), opts);
@@ -76,7 +76,8 @@
 //! }
 //! ~~~
 
-#![crate_id = "getopts#0.11.0"]
+#![crate_id = "getopts#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "getopts"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
@@ -87,6 +88,7 @@
        html_playground_url = "http://play.rust-lang.org/")]
 #![feature(globs, phase)]
 #![deny(missing_doc)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 #[cfg(test)] extern crate debug;
 #[cfg(test)] #[phase(plugin, link)] extern crate log;
@@ -220,9 +222,9 @@ fn from_str(nm: &str) -> Name {
         }
     }
 
-    fn to_str(&self) -> String {
+    fn to_string(&self) -> String {
         match *self {
-            Short(ch) => ch.to_str(),
+            Short(ch) => ch.to_string(),
             Long(ref s) => s.to_string()
         }
     }
@@ -499,7 +501,7 @@ impl Fail_ {
     /// Convert a `Fail_` enum into an error string.
     #[deprecated="use `Show` (`{}` format specifier)"]
     pub fn to_err_msg(self) -> String {
-        self.to_str()
+        self.to_string()
     }
 }
 
@@ -607,12 +609,12 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
                 name_pos += 1;
                 let optid = match find_opt(opts.as_slice(), (*nm).clone()) {
                   Some(id) => id,
-                  None => return Err(UnrecognizedOption(nm.to_str()))
+                  None => return Err(UnrecognizedOption(nm.to_string()))
                 };
                 match opts.get(optid).hasarg {
                   No => {
                     if !i_arg.is_none() {
-                        return Err(UnexpectedArgument(nm.to_str()));
+                        return Err(UnexpectedArgument(nm.to_string()));
                     }
                     vals.get_mut(optid).push(Given);
                   }
@@ -633,7 +635,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
                     if !i_arg.is_none() {
                         vals.get_mut(optid).push(Val(i_arg.clone().unwrap()));
                     } else if i + 1 == l {
-                        return Err(ArgumentMissing(nm.to_str()));
+                        return Err(ArgumentMissing(nm.to_string()));
                     } else {
                         i += 1;
                         vals.get_mut(optid).push(Val(args[i].clone()));
@@ -650,12 +652,12 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
         let occ = opts.get(i).occur;
         if occ == Req {
             if n == 0 {
-                return Err(OptionMissing(opts.get(i).name.to_str()));
+                return Err(OptionMissing(opts.get(i).name.to_string()));
             }
         }
         if occ != Multi {
             if n > 1 {
-                return Err(OptionDuplicated(opts.get(i).name.to_str()));
+                return Err(OptionDuplicated(opts.get(i).name.to_string()));
             }
         }
         i += 1;
index 3cb21601e331d8f2f9d73022ecd076c4fde92bae..668000b2db42caab6e71356ff1a6f937ba6059d7 100644 (file)
@@ -23,7 +23,8 @@
  * `glob`/`fnmatch` functions.
  */
 
-#![crate_id = "glob#0.11.0"]
+#![crate_id = "glob#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "glob"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
@@ -32,6 +33,7 @@
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/0.11.0/",
        html_playground_url = "http://play.rust-lang.org/")]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 use std::cell::Cell;
 use std::{cmp, os, path};
@@ -701,11 +703,11 @@ fn test_range_pattern() {
         for &p in pats.iter() {
             let pat = Pattern::new(p);
             for c in "abcdefghijklmnopqrstuvwxyz".chars() {
-                assert!(pat.matches(c.to_str().as_slice()));
+                assert!(pat.matches(c.to_string().as_slice()));
             }
             for c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ".chars() {
                 let options = MatchOptions {case_sensitive: false, .. MatchOptions::new()};
-                assert!(pat.matches_with(c.to_str().as_slice(), options));
+                assert!(pat.matches_with(c.to_string().as_slice(), options));
             }
             assert!(pat.matches("1"));
             assert!(pat.matches("2"));
index 16298f51ea96b283a562537069a5ae98476f483b..662722e08d96fe1e09e0a01974b046802628808d 100644 (file)
@@ -266,7 +266,8 @@ pub fn main() {
 
 */
 
-#![crate_id = "graphviz#0.11.0"]
+#![crate_id = "graphviz#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "graphviz"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
@@ -274,8 +275,7 @@ pub fn main() {
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/0.11.0/")]
-
-#![experimental]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 use std::io;
 use std::str;
@@ -666,7 +666,7 @@ fn test_input(g: LabelledGraph) -> IoResult<String> {
         let mut writer = MemWriter::new();
         render(&g, &mut writer).unwrap();
         let mut r = BufReader::new(writer.get_ref());
-        match r.read_to_str() {
+        match r.read_to_string() {
             Ok(string) => Ok(string.to_string()),
             Err(err) => Err(err),
         }
@@ -768,7 +768,7 @@ fn left_aligned_text() {
 
         render(&g, &mut writer).unwrap();
         let mut r = BufReader::new(writer.get_ref());
-        let r = r.read_to_str();
+        let r = r.read_to_string();
 
         assert_eq!(r.unwrap().as_slice(),
 r#"digraph syntax_tree {
index 1b34679b0a18a67a0857d39ee3ce5aaf68c23f0c..357644aed03f9a37a24a5e27e6034fb9f327c00f 100644 (file)
 //! pool.shutdown();
 //! ```
 
-#![crate_id = "green#0.11.0"]
+#![crate_id = "green#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "green"]
 #![experimental]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
        html_playground_url = "http://play.rust-lang.org/")]
 
 // NB this does *not* include globs, please keep it that way.
-#![feature(macro_rules, phase)]
-#![allow(visible_private_types)]
-#![allow(deprecated)]
-#![feature(default_type_params)]
+#![feature(macro_rules, phase, default_type_params)]
+#![allow(visible_private_types, deprecated)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 #[cfg(test)] #[phase(plugin, link)] extern crate log;
 #[cfg(test)] extern crate rustuv;
index 64538bd2212a47e8d7562c7faa619036927172de..17c71c6365e1ba6008a51cb8aeb652f33a76ccc8 100644 (file)
@@ -36,7 +36,8 @@ fn main() {
 
 */
 
-#![crate_id = "hexfloat#0.11.0"]
+#![crate_id = "hexfloat#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "hexfloat"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
@@ -45,6 +46,7 @@ fn main() {
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/0.11.0/")]
 #![feature(plugin_registrar, managed_boxes)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 extern crate syntax;
 extern crate rustc;
index 81e50889952ec2671e931604c50654d03e2dd996..e0dd57f6ae92f99e4e4679a44b91c79bc4cb9a25 100644 (file)
@@ -9,7 +9,8 @@
 // except according to those terms.
 
 #![feature(globs)]
-#![crate_id = "libc#0.11.0"]
+#![crate_id = "libc#0.11.0"] // NOTE: remove after a stage0 snap
+#![crate_name = "libc"]
 #![experimental]
 #![no_std] // we don't need std, and we can't have std, since it doesn't exist
            // yet. std depends on us.
@@ -18,6 +19,7 @@
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/0.11.0/",
        html_playground_url = "http://play.rust-lang.org/")]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 /*!
 * Bindings for the C standard library and other platform libraries
index 6216e79fe841878f0ae73347f98c29609dcb8e1e..33d1cc87b7312c09b2ac8b8844267c4b96659588 100644 (file)
@@ -105,7 +105,8 @@ fn main() {
 
 */
 
-#![crate_id = "log#0.11.0"]
+#![crate_id = "log#0.11.0"] // NOTE: Remove after stage0
+#![crate_name = "log"]
 #![experimental]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
@@ -114,7 +115,7 @@ fn main() {
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/0.11.0/",
        html_playground_url = "http://play.rust-lang.org/")]
-
+#![allow(unused_attribute)] // NOTE: remove after stage0
 #![feature(macro_rules)]
 #![deny(missing_doc)]
 
index 98553603313404382aafa07a63d726c28ef9b1a6..dbca4ff7ff719a9575a8dafe09c2b5adb629afc1 100644 (file)
@@ -259,7 +259,7 @@ pub fn to_utf16(s: &CString) -> IoResult<Vec<u16>> {
         None => Err(IoError {
             code: libc::ERROR_INVALID_NAME as uint,
             extra: 0,
-            detail: Some("valid unicode input required".to_str()),
+            detail: Some("valid unicode input required".to_string()),
         })
     }
 }
index b5b2065f996ed29d079807a1454c3f86f2763269..0e019fa7e8fbdadf7b04ea38dd5e09a22ba5edc1 100644 (file)
@@ -43,7 +43,7 @@ fn addr_to_sockaddr_un(addr: &CString) -> IoResult<(libc::sockaddr_storage, uint
         return Err(IoError {
             code: ERROR as uint,
             extra: 0,
-            detail: Some("path must be smaller than SUN_LEN".to_str()),
+            detail: Some("path must be smaller than SUN_LEN".to_string()),
         })
     }
     s.sun_family = libc::AF_UNIX as libc::sa_family_t;
index e5e8cdeffd7e4c2249b44d5a7f1db0fa2fee47f7..ec40ff89bd2cdb9fdf6d46576c80c8005d5abfc1 100644 (file)
@@ -479,7 +479,7 @@ fn write(&mut self, buf: &[u8]) -> IoResult<()> {
                             Err(IoError {
                                 code: libc::ERROR_OPERATION_ABORTED as uint,
                                 extra: amt,
-                                detail: Some("short write during write".to_str()),
+                                detail: Some("short write during write".to_string()),
                             })
                         } else {
                             Err(util::timeout("write timed out"))
index 6fab73115cf9a5e2dcd1ddf7847f2796b4f44e4d..71702d180b9e0efaffb630e01fcecb23803e1c65 100644 (file)
@@ -170,7 +170,7 @@ fn kill(&mut self, signum: int) -> IoResult<()> {
             Some(..) => return Err(IoError {
                 code: ERROR as uint,
                 extra: 0,
-                detail: Some("can't kill an exited process".to_str()),
+                detail: Some("can't kill an exited process".to_string()),
             }),
             None => {}
         }
@@ -301,7 +301,7 @@ fn spawn_process_os(cfg: ProcessConfig,
         return Err(IoError {
             code: libc::ERROR_CALL_NOT_IMPLEMENTED as uint,
             extra: 0,
-            detail: Some("unsupported gid/uid requested on windows".to_str()),
+            detail: Some("unsupported gid/uid requested on windows".to_string()),
         })
     }
 
index 31ba2223082d554325d66814aa8869500c566324..06046cc74cfd85d7828d92b2f0688756764bf57a 100644 (file)
@@ -30,7 +30,7 @@ pub fn timeout(desc: &'static str) -> IoError {
     IoError {
         code: ERROR as uint,
         extra: 0,
-        detail: Some(desc.to_str()),
+        detail: Some(desc.to_string()),
     }
 }
 
@@ -40,7 +40,7 @@ pub fn short_write(n: uint, desc: &'static str) -> IoError {
     IoError {
         code: ERROR as uint,
         extra: n,
-        detail: Some(desc.to_str()),
+        detail: Some(desc.to_string()),
     }
 }
 
index 2e43ddba6449ce08bb956b2c14711911472775b5..85813a7dde38d1dfd55edea977019916ad9c2a33 100644 (file)
@@ -46,7 +46,8 @@
 //! }
 //! ```
 
-#![crate_id = "native#0.11.0"]
+#![crate_id = "native#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "native"]
 #![experimental]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
@@ -57,6 +58,7 @@
 
 #![deny(unused_result, unused_must_use)]
 #![allow(non_camel_case_types, deprecated)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 #![feature(default_type_params, lang_items)]
 
 // NB this crate explicitly does *not* allow glob imports, please seriously
index cc3753def59f4cc2a6ed98d1080f4a36fc33ae28..046ba96f45a38185e28770381c58094ca4713e77 100644 (file)
@@ -2737,7 +2737,7 @@ fn check(s: &str, ans: Option<int>) {
         // attempt to allocate a vector of size (-1u) == huge.
         let x: BigInt =
             from_str(format!("1{}", "0".repeat(36)).as_slice()).unwrap();
-        let _y = x.to_str();
+        let _y = x.to_string();
     }
 
     #[test]
@@ -2842,14 +2842,14 @@ fn fib_100(b: &mut Bencher) {
     }
 
     #[bench]
-    fn to_str(b: &mut Bencher) {
+    fn to_string(b: &mut Bencher) {
         let fac = factorial(100);
         let fib = fib(100);
         b.iter(|| {
-            fac.to_str();
+            fac.to_string();
         });
         b.iter(|| {
-            fib.to_str();
+            fib.to_string();
         });
     }
 
index 9ee80d283cf924621ac20309c075ea29d8fcf371..f4a3ac97a4ef762bca048dee50bab92cea967fc7 100644 (file)
@@ -347,9 +347,9 @@ fn test_neg() {
     }
 
     #[test]
-    fn test_to_str() {
+    fn test_to_string() {
         fn test(c : Complex64, s: String) {
-            assert_eq!(c.to_str(), s);
+            assert_eq!(c.to_string(), s);
         }
         test(_0_0i, "0+0i".to_string());
         test(_1_0i, "1+0i".to_string());
index db0cd7f2567243b006d36a0508bdd8cb55b601e0..06e69c132bde859a69911be6703eba585ff5629d 100644 (file)
@@ -44,7 +44,8 @@
 
 #![feature(macro_rules)]
 
-#![crate_id = "num#0.11.0"]
+#![crate_id = "num#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "num"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
@@ -53,7 +54,7 @@
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/0.11.0/",
        html_playground_url = "http://play.rust-lang.org/")]
-
+#![allow(unused_attribute)] // NOTE: remove after stage0
 #![allow(deprecated)] // from_str_radix
 
 extern crate rand;
index c35b2976b407f19aef7f9614c48d2f3fc19e4bd7..a279ede6fa5347d68b85d7251fb3ad20a4b43752 100644 (file)
@@ -15,7 +15,9 @@
 use std::cmp;
 use std::fmt;
 use std::from_str::FromStr;
+use std::num;
 use std::num::{Zero, One, ToStrRadix, FromStrRadix};
+
 use bigint::{BigInt, BigUint, Sign, Plus, Minus};
 
 /// Represents the ratio between 2 numbers.
@@ -273,6 +275,36 @@ fn one() -> Ratio<T> {
 impl<T: Clone + Integer + PartialOrd>
     Num for Ratio<T> {}
 
+impl<T: Clone + Integer + PartialOrd>
+    num::Signed for Ratio<T> {
+    #[inline]
+    fn abs(&self) -> Ratio<T> {
+        if self.is_negative() { -self.clone() } else { self.clone() }
+    }
+
+    #[inline]
+    fn abs_sub(&self, other: &Ratio<T>) -> Ratio<T> {
+        if *self <= *other { Zero::zero() } else { *self - *other }
+    }
+
+    #[inline]
+    fn signum(&self) -> Ratio<T> {
+        if *self > Zero::zero() {
+            num::one()
+        } else if self.is_zero() {
+            num::zero()
+        } else {
+            - num::one::<Ratio<T>>()
+        }
+    }
+
+    #[inline]
+    fn is_positive(&self) -> bool { *self > Zero::zero() }
+
+    #[inline]
+    fn is_negative(&self) -> bool { *self < Zero::zero() }
+}
+
 /* String conversions */
 impl<T: fmt::Show + Eq + One> fmt::Show for Ratio<T> {
     /// Renders as `numer/denom`. If denom=1, renders as numer.
@@ -338,6 +370,7 @@ mod test {
     use super::{Ratio, Rational, BigRational};
     use std::num::{Zero, One, FromStrRadix, FromPrimitive, ToStrRadix};
     use std::from_str::FromStr;
+    use std::num;
 
     pub static _0 : Rational = Ratio { numer: 0, denom: 1};
     pub static _1 : Rational = Ratio { numer: 1, denom: 1};
@@ -571,7 +604,7 @@ fn test_recip() {
     fn test_to_from_str() {
         fn test(r: Rational, s: String) {
             assert_eq!(FromStr::from_str(s.as_slice()), Some(r));
-            assert_eq!(r.to_str(), s);
+            assert_eq!(r.to_string(), s);
         }
         test(_1, "1".to_string());
         test(_0, "0".to_string());
@@ -672,4 +705,16 @@ fn test_from_float_fail() {
         assert_eq!(Ratio::from_float(f64::INFINITY), None);
         assert_eq!(Ratio::from_float(f64::NEG_INFINITY), None);
     }
+
+    #[test]
+    fn test_signed() {
+        assert_eq!(_neg1_2.abs(), _1_2);
+        assert_eq!(_3_2.abs_sub(&_1_2), _1);
+        assert_eq!(_1_2.abs_sub(&_3_2), Zero::zero());
+        assert_eq!(_1_2.signum(), One::one());
+        assert_eq!(_neg1_2.signum(), - num::one::<Ratio<int>>());
+        assert!(_neg1_2.is_negative());
+        assert!(! _neg1_2.is_positive());
+        assert!(! _1_2.is_negative());
+    }
 }
index 593b9785d475abb3f65ae9d3b49982ea7e8c5299..ac0f59225e8e775a860331639705082b43cb803c 100644 (file)
@@ -16,7 +16,8 @@
 //! is not recommended to use this library directly, but rather the official
 //! interface through `std::rand`.
 
-#![crate_id = "rand#0.11.0"]
+#![crate_id = "rand#0.11.0"] // NOTE: remove after a stage0 snap
+#![crate_name = "rand"]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
@@ -25,6 +26,7 @@
        html_playground_url = "http://play.rust-lang.org/")]
 
 #![feature(macro_rules, phase, globs)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 #![no_std]
 #![experimental]
 
index b69c4471267bb6cefdf80f1d940966eb32b941b9..2275f9639d130989d088f93c87a7565a7b99c56b 100644 (file)
 //! characters in the search text and `m` is the number of instructions in a
 //! compiled expression.
 
-#![crate_id = "regex#0.11.0"]
+#![crate_id = "regex#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "regex"]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![experimental]
        html_playground_url = "http://play.rust-lang.org/")]
 
 #![feature(macro_rules, phase)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 #![deny(missing_doc)]
 
 #[cfg(test)]
index b21b51bf4eb5e7e1a3bb915d194e4a668b18b704..95ed334c5d4ec8eb91ef867cd32e191859b54f76 100644 (file)
 //! This crate provides the `regex!` macro. Its use is documented in the
 //! `regex` crate.
 
-#![crate_id = "regex_macros#0.11.0"]
+#![crate_id = "regex_macros#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "regex_macros"]
 #![crate_type = "dylib"]
 #![experimental]
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 #![feature(plugin_registrar, managed_boxes, quote)]
 
@@ -85,7 +87,7 @@ fn native(cx: &mut ExtCtxt, sp: codemap::Span, tts: &[ast::TokenTree])
     let re = match Regex::new(regex.as_slice()) {
         Ok(re) => re,
         Err(err) => {
-            cx.span_err(sp, err.to_str().as_slice());
+            cx.span_err(sp, err.to_string().as_slice());
             return DummyResult::any(sp)
         }
     };
@@ -316,7 +318,7 @@ fn pc(&self, i: uint) -> uint {
 
         #[inline]
         fn groups<'r>(&'r mut self, i: uint) -> &'r mut Captures {
-            &'r mut self.queue[i].groups
+            &mut self.queue[i].groups
         }
     }
 }
@@ -619,11 +621,11 @@ fn parse(cx: &mut ExtCtxt, tts: &[ast::TokenTree]) -> Option<String> {
     let regex = match entry.node {
         ast::ExprLit(lit) => {
             match lit.node {
-                ast::LitStr(ref s, _) => s.to_str(),
+                ast::LitStr(ref s, _) => s.to_string(),
                 _ => {
                     cx.span_err(entry.span, format!(
                         "expected string literal but got `{}`",
-                        pprust::lit_to_str(lit)).as_slice());
+                        pprust::lit_to_string(lit)).as_slice());
                     return None
                 }
             }
@@ -631,7 +633,7 @@ fn parse(cx: &mut ExtCtxt, tts: &[ast::TokenTree]) -> Option<String> {
         _ => {
             cx.span_err(entry.span, format!(
                 "expected string literal but got `{}`",
-                pprust::expr_to_str(entry)).as_slice());
+                pprust::expr_to_string(entry)).as_slice());
             return None
         }
     };
index c653e1ca07787afc4b141a772ac9588d26a847c9..7b0fd3d6366fab37803eb5da8563fe4357372e04 100644 (file)
 //! necessary. It is an error to include this library when also linking with
 //! the system libc library.
 
-#![crate_id = "rlibc#0.11.0"]
+#![crate_id = "rlibc#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "rlibc"]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/0.11.0/")]
 #![feature(intrinsics)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 #![no_std]
 #![experimental]
index a190d9309cc8df8612f6fbe85f5a8b76173be14f..e2264088b4a84ab2f986470ff9ffb3f498498b62 100644 (file)
@@ -11,7 +11,7 @@
 use back::archive::{Archive, METADATA_FILENAME};
 use back::rpath;
 use back::svh::Svh;
-use driver::driver::{CrateTranslation, OutputFilenames};
+use driver::driver::{CrateTranslation, OutputFilenames, Input, FileInput};
 use driver::config::NoDebugInfo;
 use driver::session::Session;
 use driver::config;
@@ -19,7 +19,7 @@
 use lib::llvm::ModuleRef;
 use lib;
 use metadata::common::LinkMeta;
-use metadata::{encoder, cstore, filesearch, csearch, loader};
+use metadata::{encoder, cstore, filesearch, csearch, loader, creader};
 use middle::trans::context::CrateContext;
 use middle::trans::common::gensym_name;
 use middle::ty;
@@ -40,9 +40,8 @@
 use syntax::ast;
 use syntax::ast_map::{PathElem, PathElems, PathName};
 use syntax::ast_map;
-use syntax::attr;
 use syntax::attr::AttrMetaMethods;
-use syntax::crateid::CrateId;
+use syntax::codemap::Span;
 use syntax::parse::token;
 
 #[deriving(Clone, PartialEq, PartialOrd, Ord, Eq)]
@@ -546,32 +545,69 @@ unsafe fn populate_llvm_passes(fpm: lib::llvm::PassManagerRef,
  *    system linkers understand.
  */
 
-// FIXME (#9639): This needs to handle non-utf8 `out_filestem` values
-pub fn find_crate_id(attrs: &[ast::Attribute], out_filestem: &str) -> CrateId {
-    match attr::find_crateid(attrs) {
-        None => from_str(out_filestem).unwrap_or_else(|| {
-            let mut s = out_filestem.chars().filter(|c| c.is_XID_continue());
-            from_str(s.collect::<String>().as_slice())
-                .or(from_str("rust-out")).unwrap()
-        }),
-        Some(s) => s,
+pub fn find_crate_name(sess: Option<&Session>,
+                       attrs: &[ast::Attribute],
+                       input: &Input) -> String {
+    use syntax::crateid::CrateId;
+
+    let validate = |s: String, span: Option<Span>| {
+        creader::validate_crate_name(sess, s.as_slice(), span);
+        s
+    };
+
+    match sess {
+        Some(sess) => {
+            match sess.opts.crate_name {
+                Some(ref s) => return validate(s.clone(), None),
+                None => {}
+            }
+        }
+        None => {}
+    }
+
+    let crate_name = attrs.iter().find(|at| at.check_name("crate_name"))
+                          .and_then(|at| at.value_str().map(|s| (at, s)));
+    match crate_name {
+        Some((attr, s)) => return validate(s.get().to_string(), Some(attr.span)),
+        None => {}
+    }
+    let crate_id = attrs.iter().find(|at| at.check_name("crate_id"))
+                        .and_then(|at| at.value_str().map(|s| (at, s)))
+                        .and_then(|(at, s)| {
+                            from_str::<CrateId>(s.get()).map(|id| (at, id))
+                        });
+    match crate_id {
+        Some((attr, id)) => {
+            match sess {
+                Some(sess) => {
+                    sess.span_warn(attr.span, "the #[crate_id] attribute is \
+                                               deprecated for the \
+                                               #[crate_name] attribute");
+                }
+                None => {}
+            }
+            return validate(id.name, Some(attr.span))
+        }
+        None => {}
+    }
+    match *input {
+        FileInput(ref path) => {
+            match path.filestem_str() {
+                Some(s) => return validate(s.to_string(), None),
+                None => {}
+            }
+        }
+        _ => {}
     }
-}
 
-pub fn crate_id_hash(crate_id: &CrateId) -> String {
-    // This calculates CMH as defined above. Note that we don't use the path of
-    // 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().as_slice());
-    truncated_hash_result(&mut s).as_slice().slice_to(8).to_string()
+    "rust-out".to_string()
 }
 
-// FIXME (#9639): This needs to handle non-utf8 `out_filestem` values
-pub fn build_link_meta(krate: &ast::Crate, out_filestem: &str) -> LinkMeta {
+pub fn build_link_meta(sess: &Session, krate: &ast::Crate,
+                       name: String) -> LinkMeta {
     let r = LinkMeta {
-        crateid: find_crate_id(krate.attrs.as_slice(), out_filestem),
-        crate_hash: Svh::calculate(krate),
+        crate_name: name,
+        crate_hash: Svh::calculate(sess, krate),
     };
     info!("{}", r);
     return r;
@@ -594,9 +630,12 @@ 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.as_slice());
+    symbol_hasher.input_str(link_meta.crate_name.as_slice());
     symbol_hasher.input_str("-");
     symbol_hasher.input_str(link_meta.crate_hash.as_str());
+    for meta in tcx.sess.crate_metadata.borrow().iter() {
+        symbol_hasher.input_str(meta.as_slice());
+    }
     symbol_hasher.input_str("-");
     symbol_hasher.input_str(encoder::encoded_ty(tcx, t).as_slice());
     // Prefix with 'h' so that it never blends into adjacent digits
@@ -666,8 +705,7 @@ pub fn sanitize(s: &str) -> String {
 }
 
 pub fn mangle<PI: Iterator<PathElem>>(mut path: PI,
-                                      hash: Option<&str>,
-                                      vers: Option<&str>) -> String {
+                                      hash: Option<&str>) -> String {
     // Follow C++ namespace-mangling style, see
     // http://en.wikipedia.org/wiki/Name_mangling for more info.
     //
@@ -698,25 +736,13 @@ fn push(n: &mut String, s: &str) {
         Some(s) => push(&mut n, s),
         None => {}
     }
-    match vers {
-        Some(s) => push(&mut n, s),
-        None => {}
-    }
 
     n.push_char('E'); // End name-sequence.
     n
 }
 
-pub fn exported_name(path: PathElems, hash: &str, vers: &str) -> String {
-    // The version will get mangled to have a leading '_', but it makes more
-    // sense to lead with a 'v' b/c this is a version...
-    let vers = if vers.len() > 0 && !char::is_XID_start(vers.char_at(0)) {
-        format!("v{}", vers)
-    } else {
-        vers.to_string()
-    };
-
-    mangle(path, Some(hash), Some(vers.as_slice()))
+pub fn exported_name(path: PathElems, hash: &str) -> String {
+    mangle(path, Some(hash))
 }
 
 pub fn mangle_exported_name(ccx: &CrateContext, path: PathElems,
@@ -741,27 +767,21 @@ pub fn mangle_exported_name(ccx: &CrateContext, path: PathElems,
     hash.push_char(EXTRA_CHARS.as_bytes()[extra2] as char);
     hash.push_char(EXTRA_CHARS.as_bytes()[extra3] as char);
 
-    exported_name(path,
-                  hash.as_slice(),
-                  ccx.link_meta.crateid.version_or_default())
+    exported_name(path, hash.as_slice())
 }
 
 pub fn mangle_internal_name_by_type_and_seq(ccx: &CrateContext,
                                             t: ty::t,
                                             name: &str) -> String {
-    let s = ppaux::ty_to_str(ccx.tcx(), t);
+    let s = ppaux::ty_to_string(ccx.tcx(), t);
     let path = [PathName(token::intern(s.as_slice())),
                 gensym_name(name)];
     let hash = get_symbol_hash(ccx, t);
-    mangle(ast_map::Values(path.iter()), Some(hash.as_slice()), None)
+    mangle(ast_map::Values(path.iter()), Some(hash.as_slice()))
 }
 
 pub fn mangle_internal_name_by_path_and_seq(path: PathElems, flav: &str) -> String {
-    mangle(path.chain(Some(gensym_name(flav)).move_iter()), None, None)
-}
-
-pub fn output_lib_filename(id: &CrateId) -> String {
-    format!("{}-{}-{}", id.name, crate_id_hash(id), id.version_or_default())
+    mangle(path.chain(Some(gensym_name(flav)).move_iter()), None)
 }
 
 pub fn get_cc_prog(sess: &Session) -> String {
@@ -803,14 +823,15 @@ fn remove(sess: &Session, path: &Path) {
 pub fn link_binary(sess: &Session,
                    trans: &CrateTranslation,
                    outputs: &OutputFilenames,
-                   id: &CrateId) -> Vec<Path> {
+                   crate_name: &str) -> Vec<Path> {
     let mut out_filenames = Vec::new();
     for &crate_type in sess.crate_types.borrow().iter() {
         if invalid_output_for_target(sess, crate_type) {
             sess.bug(format!("invalid output type `{}` for target os `{}`",
                              crate_type, sess.targ_cfg.os).as_slice());
         }
-        let out_file = link_binary_output(sess, trans, crate_type, outputs, id);
+        let out_file = link_binary_output(sess, trans, crate_type, outputs,
+                                          crate_name);
         out_filenames.push(out_file);
     }
 
@@ -859,9 +880,11 @@ fn is_writeable(p: &Path) -> bool {
     }
 }
 
-pub fn filename_for_input(sess: &Session, crate_type: config::CrateType,
-                          id: &CrateId, out_filename: &Path) -> Path {
-    let libname = output_lib_filename(id);
+pub fn filename_for_input(sess: &Session,
+                          crate_type: config::CrateType,
+                          name: &str,
+                          out_filename: &Path) -> Path {
+    let libname = format!("{}{}", name, sess.opts.cg.extra_filename);
     match crate_type {
         config::CrateTypeRlib => {
             out_filename.with_filename(format!("lib{}.rlib", libname))
@@ -891,13 +914,13 @@ fn link_binary_output(sess: &Session,
                       trans: &CrateTranslation,
                       crate_type: config::CrateType,
                       outputs: &OutputFilenames,
-                      id: &CrateId) -> Path {
+                      crate_name: &str) -> Path {
     let obj_filename = outputs.temp_path(OutputTypeObject);
     let out_filename = match outputs.single_output_file {
         Some(ref file) => file.clone(),
         None => {
             let out_filename = outputs.path(OutputTypeExe);
-            filename_for_input(sess, crate_type, id, &out_filename)
+            filename_for_input(sess, crate_type, crate_name, &out_filename)
         }
     };
 
@@ -1340,7 +1363,7 @@ fn link_args(cmd: &mut Command,
         if sess.targ_cfg.os == abi::OsMacos {
             cmd.args(["-dynamiclib", "-Wl,-dylib"]);
 
-            if !sess.opts.cg.no_rpath {
+            if sess.opts.cg.rpath {
                 let mut v = Vec::from_slice("-Wl,-install_name,@rpath/".as_bytes());
                 v.push_all(out_filename.filename().unwrap());
                 cmd.arg(v.as_slice());
@@ -1359,7 +1382,7 @@ fn link_args(cmd: &mut Command,
     // FIXME (#2397): At some point we want to rpath our guesses as to
     // where extern libraries might live, based on the
     // addl_lib_search_paths
-    if !sess.opts.cg.no_rpath {
+    if sess.opts.cg.rpath {
         cmd.args(rpath::get_rpath_flags(sess, out_filename).as_slice());
     }
 
index c487f674c2d52794b58de889ea78556fecd6b850..324ed3b567ec44436b0d81166b3910b9fc95b0d9 100644 (file)
@@ -53,6 +53,8 @@
 use syntax::ast;
 use syntax::visit;
 
+use driver::session::Session;
+
 #[deriving(Clone, PartialEq)]
 pub struct Svh {
     hash: String,
@@ -68,7 +70,7 @@ pub fn as_str<'a>(&'a self) -> &'a str {
         self.hash.as_slice()
     }
 
-    pub fn calculate(krate: &ast::Crate) -> Svh {
+    pub fn calculate(sess: &Session, krate: &ast::Crate) -> Svh {
         // FIXME (#14132): This is better than it used to be, but it still not
         // ideal. We now attempt to hash only the relevant portions of the
         // Crate AST as well as the top-level crate attributes. (However,
@@ -80,6 +82,10 @@ pub fn calculate(krate: &ast::Crate) -> Svh {
         //        avoid collisions.
         let mut state = SipState::new();
 
+        for data in sess.opts.cg.metadata.iter() {
+            data.hash(&mut state);
+        }
+
         {
             let mut visit = svh_visitor::make(&mut state);
             visit::walk_crate(&mut visit, krate, ());
@@ -334,13 +340,13 @@ fn visit_mac(&mut self, macro: &Mac, e: E) {
                 // trees might be faster. Implementing this is far
                 // easier in short term.
                 let macro_defn_as_string =
-                    pprust::to_str(|pp_state| pp_state.print_mac(macro));
+                    pprust::to_string(|pp_state| pp_state.print_mac(macro));
                 macro_defn_as_string.hash(self.st);
             } else {
                 // It is not possible to observe any kind of macro
                 // invocation at this stage except `macro_rules!`.
                 fail!("reached macro somehow: {}",
-                      pprust::to_str(|pp_state| pp_state.print_mac(macro)));
+                      pprust::to_string(|pp_state| pp_state.print_mac(macro)));
             }
 
             visit::walk_mac(self, macro, e);
index 558d2ad71f33f3fa06927c119c5bec601851a634..9daaa2792ebad0e0140f55234769fc236645fc7d 100644 (file)
@@ -11,7 +11,7 @@
 //! Contains infrastructure for configuring the compiler, including parsing
 //! command line options.
 
-use driver::early_error;
+use driver::{early_error, early_warn};
 use driver::driver;
 use driver::session::Session;
 
@@ -30,7 +30,7 @@
 use syntax::parse;
 use syntax::parse::token::InternedString;
 
-use std::collections::HashSet;
+use std::collections::{HashSet, HashMap};
 use getopts::{optopt, optmulti, optflag, optflagopt};
 use getopts;
 use lib::llvm::llvm;
@@ -91,10 +91,12 @@ pub struct Options {
     pub debugging_opts: u64,
     /// Whether to write dependency files. It's (enabled, optional filename).
     pub write_dependency_info: (bool, Option<Path>),
-    /// Crate id-related things to maybe print. It's (crate_id, crate_name, crate_file_name).
-    pub print_metas: (bool, bool, bool),
+    /// Crate id-related things to maybe print. It's (crate_name, crate_file_name).
+    pub print_metas: (bool, bool),
     pub cg: CodegenOptions,
     pub color: ColorConfig,
+    pub externs: HashMap<String, Vec<String>>,
+    pub crate_name: Option<String>,
 }
 
 /// Some reasonable defaults
@@ -117,9 +119,11 @@ pub fn basic_options() -> Options {
         no_analysis: false,
         debugging_opts: 0,
         write_dependency_info: (false, None),
-        print_metas: (false, false, false),
+        print_metas: (false, false),
         cg: basic_codegen_options(),
         color: Auto,
+        externs: HashMap::new(),
+        crate_name: None,
     }
 }
 
@@ -302,8 +306,8 @@ fn parse_list(slot: &mut Vec<String>, v: Option<&str>)
         "a list of arguments to pass to llvm (space separated)"),
     save_temps: bool = (false, parse_bool,
         "save all temporary output files during compilation"),
-    no_rpath: bool = (false, parse_bool,
-        "disables setting the rpath in libs/exes"),
+    rpath: bool = (false, parse_bool,
+        "set rpath values in libs/exes"),
     no_prepopulate_passes: bool = (false, parse_bool,
         "don't pre-populate the pass manager with a list of passes"),
     no_vectorize_loops: bool = (false, parse_bool,
@@ -318,6 +322,10 @@ fn parse_list(slot: &mut Vec<String>, v: Option<&str>)
         "use an external assembler rather than LLVM's integrated one"),
     relocation_model: String = ("pic".to_string(), parse_string,
          "choose the relocation model to use (llc -relocation-model for details)"),
+    metadata: Vec<String> = (Vec::new(), parse_list,
+         "metadata to mangle symbol names with"),
+    extra_filename: String = ("".to_string(), parse_string,
+         "extra data to put in each output filename"),
 )
 
 pub fn build_codegen_options(matches: &getopts::Matches) -> CodegenOptions
@@ -427,7 +435,7 @@ pub fn get_os(triple: &str) -> Option<abi::Os> {
     }
     None
 }
-static os_names : &'static [(&'static str, abi::Os)] = &'static [
+static os_names : &'static [(&'static str, abi::Os)] = &[
     ("mingw32", abi::OsWin32),
     ("win32",   abi::OsWin32),
     ("darwin",  abi::OsMacos),
@@ -442,7 +450,7 @@ pub fn get_arch(triple: &str) -> Option<abi::Architecture> {
     }
     None
 }
-static architecture_abis : &'static [(&'static str, abi::Architecture)] = &'static [
+static architecture_abis : &'static [(&'static str, abi::Architecture)] = &[
     ("i386",   abi::X86),
     ("i486",   abi::X86),
     ("i586",   abi::X86),
@@ -505,10 +513,12 @@ pub fn optgroups() -> Vec<getopts::OptGroup> {
                  "[bin|lib|rlib|dylib|staticlib]"),
         optmulti("", "emit", "Comma separated list of types of output for the compiler to emit",
                  "[asm|bc|ir|obj|link]"),
-        optflag("", "crate-id", "Output the crate id and exit"),
-        optflag("", "crate-name", "Output the crate name and exit"),
-        optflag("", "crate-file-name", "Output the file(s) that would be written if compilation \
+        optopt("", "crate-name", "Specify the name of the crate being built",
+               "NAME"),
+        optflag("", "print-crate-name", "Output the crate name and exit"),
+        optflag("", "print-file-name", "Output the file(s) that would be written if compilation \
               continued and exit"),
+        optflag("", "crate-file-name", "deprecated in favor of --print-file-name"),
         optflag("g",  "",  "Equivalent to --debuginfo=2"),
         optopt("",  "debuginfo",  "Emit DWARF debug info to the objects created:
              0 = no debug info,
@@ -548,7 +558,9 @@ pub fn optgroups() -> Vec<getopts::OptGroup> {
         optopt("", "color", "Configure coloring of output:
             auto   = colorize, if output goes to a tty (default);
             always = always colorize output;
-            never  = never colorize output", "auto|always|never")
+            never  = never colorize output", "auto|always|never"),
+        optmulti("", "extern", "Specify where an external rust library is located",
+                 "PATH"),
     )
 }
 
@@ -709,9 +721,13 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
                                  matches.opt_str("dep-info")
                                         .map(|p| Path::new(p)));
 
-    let print_metas = (matches.opt_present("crate-id"),
-                       matches.opt_present("crate-name"),
+    let print_metas = (matches.opt_present("print-crate-name"),
+                       matches.opt_present("print-file-name") ||
                        matches.opt_present("crate-file-name"));
+    if matches.opt_present("crate-file-name") {
+        early_warn("the --crate-file-name argument has been renamed to \
+                    --print-file-name");
+    }
     let cg = build_codegen_options(matches);
 
     let color = match matches.opt_str("color").as_ref().map(|s| s.as_slice()) {
@@ -728,6 +744,23 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         }
     };
 
+    let mut externs = HashMap::new();
+    for arg in matches.opt_strs("extern").iter() {
+        let mut parts = arg.as_slice().splitn('=', 1);
+        let name = match parts.next() {
+            Some(s) => s,
+            None => early_error("--extern value must not be empty"),
+        };
+        let location = match parts.next() {
+            Some(s) => s,
+            None => early_error("--extern value must be of the format `foo=bar`"),
+        };
+        let locs = externs.find_or_insert(name.to_string(), Vec::new());
+        locs.push(location.to_string());
+    }
+
+    let crate_name = matches.opt_str("crate-name");
+
     Options {
         crate_types: crate_types,
         gc: gc,
@@ -748,7 +781,9 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         write_dependency_info: write_dependency_info,
         print_metas: print_metas,
         cg: cg,
-        color: color
+        color: color,
+        externs: externs,
+        crate_name: crate_name,
     }
 }
 
index 978a43106526f3b5a16929329cf210a1c629a3a9..6a016edcd2868fce87671e901d207f62464ec2b5 100644 (file)
@@ -41,7 +41,6 @@
 use syntax::ast;
 use syntax::attr;
 use syntax::attr::{AttrMetaMethods};
-use syntax::crateid::CrateId;
 use syntax::parse;
 use syntax::parse::token;
 use syntax::print::{pp, pprust};
@@ -69,7 +68,7 @@ pub fn compile_input(sess: Session,
     // large chunks of memory alive and we want to free them as soon as
     // possible to keep the peak memory usage low
     let (outputs, trans, sess) = {
-        let (outputs, expanded_crate, ast_map) = {
+        let (outputs, expanded_crate, ast_map, id) = {
             let krate = phase_1_parse_input(&sess, cfg, input);
             if stop_after_phase_1(&sess) { return; }
             let outputs = build_output_filenames(input,
@@ -77,25 +76,25 @@ pub fn compile_input(sess: Session,
                                                  output,
                                                  krate.attrs.as_slice(),
                                                  &sess);
-            let id = link::find_crate_id(krate.attrs.as_slice(),
-                                         outputs.out_filestem.as_slice());
+            let id = link::find_crate_name(Some(&sess), krate.attrs.as_slice(),
+                                           input);
             let (expanded_crate, ast_map)
-                = match phase_2_configure_and_expand(&sess, krate, &id) {
+                = match phase_2_configure_and_expand(&sess, krate, id.as_slice()) {
                     None => return,
                     Some(p) => p,
                 };
 
-            (outputs, expanded_crate, ast_map)
+            (outputs, expanded_crate, ast_map, id)
         };
-        write_out_deps(&sess, input, &outputs, &expanded_crate);
+        write_out_deps(&sess, input, &outputs, id.as_slice());
 
         if stop_after_phase_2(&sess) { return; }
 
-        let analysis = phase_3_run_analysis_passes(sess, &expanded_crate, ast_map);
+        let analysis = phase_3_run_analysis_passes(sess, &expanded_crate,
+                                                   ast_map, id);
         phase_save_analysis(&analysis.ty_cx.sess, &expanded_crate, &analysis, outdir);
         if stop_after_phase_3(&analysis.ty_cx.sess) { return; }
-        let (tcx, trans) = phase_4_translate_to_llvm(expanded_crate,
-                                                     analysis, &outputs);
+        let (tcx, trans) = phase_4_translate_to_llvm(expanded_crate, analysis);
 
         // Discard interned strings as they are no longer required.
         token::get_ident_interner().clear();
@@ -181,11 +180,14 @@ pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input)
 /// Returns `None` if we're aborting after handling -W help.
 pub fn phase_2_configure_and_expand(sess: &Session,
                                     mut krate: ast::Crate,
-                                    crate_id: &CrateId)
+                                    crate_name: &str)
                                     -> Option<(ast::Crate, syntax::ast_map::Map)> {
     let time_passes = sess.time_passes();
 
-    *sess.crate_types.borrow_mut() = collect_crate_types(sess, krate.attrs.as_slice());
+    *sess.crate_types.borrow_mut() =
+        collect_crate_types(sess, krate.attrs.as_slice());
+    *sess.crate_metadata.borrow_mut() =
+        collect_crate_metadata(sess, krate.attrs.as_slice());
 
     time(time_passes, "gated feature checking", (), |_|
          front::feature_gate::check_crate(sess, &krate));
@@ -247,7 +249,7 @@ pub fn phase_2_configure_and_expand(sess: &Session,
             }
             let cfg = syntax::ext::expand::ExpansionConfig {
                 deriving_hash_type_parameter: sess.features.default_type_params.get(),
-                crate_id: crate_id.clone(),
+                crate_name: crate_name.to_string(),
             };
             syntax::ext::expand::expand_crate(&sess.parse_sess,
                                               cfg,
@@ -286,6 +288,7 @@ pub struct CrateAnalysis {
     pub public_items: middle::privacy::PublicItems,
     pub ty_cx: ty::ctxt,
     pub reachable: NodeSet,
+    pub name: String,
 }
 
 /// Run the resolution, typechecking, region checking and other
@@ -293,7 +296,8 @@ pub struct CrateAnalysis {
 /// structures carrying the results of the analysis.
 pub fn phase_3_run_analysis_passes(sess: Session,
                                    krate: &ast::Crate,
-                                   ast_map: syntax::ast_map::Map) -> CrateAnalysis {
+                                   ast_map: syntax::ast_map::Map,
+                                   name: String) -> CrateAnalysis {
 
     let time_passes = sess.time_passes();
 
@@ -398,6 +402,7 @@ pub fn phase_3_run_analysis_passes(sess: Session,
         exported_items: exported_items,
         public_items: public_items,
         reachable: reachable_map,
+        name: name,
     }
 }
 
@@ -426,8 +431,7 @@ pub struct CrateTranslation {
 /// Run the translation phase to LLVM, after which the AST and analysis can
 /// be discarded.
 pub fn phase_4_translate_to_llvm(krate: ast::Crate,
-                                 analysis: CrateAnalysis,
-                                 outputs: &OutputFilenames) -> (ty::ctxt, CrateTranslation) {
+                                 analysis: CrateAnalysis) -> (ty::ctxt, CrateTranslation) {
     let time_passes = analysis.ty_cx.sess.time_passes();
 
     time(time_passes, "resolving dependency formats", (), |_|
@@ -435,7 +439,7 @@ pub fn phase_4_translate_to_llvm(krate: ast::Crate,
 
     // Option dance to work around the lack of stack once closures.
     time(time_passes, "translation", (krate, analysis), |(krate, analysis)|
-         trans::base::trans_crate(krate, analysis, outputs))
+         trans::base::trans_crate(krate, analysis))
 }
 
 /// Run LLVM itself, producing a bitcode file, assembly file or object file
@@ -473,7 +477,7 @@ pub fn phase_6_link_output(sess: &Session,
          link::link_binary(sess,
                            trans,
                            outputs,
-                           &trans.link.crateid));
+                           trans.link.crate_name.as_slice()));
 }
 
 pub fn stop_after_phase_3(sess: &Session) -> bool {
@@ -514,9 +518,7 @@ pub fn stop_after_phase_5(sess: &Session) -> bool {
 fn write_out_deps(sess: &Session,
                   input: &Input,
                   outputs: &OutputFilenames,
-                  krate: &ast::Crate) {
-    let id = link::find_crate_id(krate.attrs.as_slice(),
-                                 outputs.out_filestem.as_slice());
+                  id: &str) {
 
     let mut out_filenames = Vec::new();
     for output_type in sess.opts.output_types.iter() {
@@ -524,7 +526,8 @@ fn write_out_deps(sess: &Session,
         match *output_type {
             link::OutputTypeExe => {
                 for output in sess.crate_types.borrow().iter() {
-                    let p = link::filename_for_input(sess, *output, &id, &file);
+                    let p = link::filename_for_input(sess, *output,
+                                                     id, &file);
                     out_filenames.push(p);
                 }
             }
@@ -591,7 +594,7 @@ 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_string())
             }
             pprust::NodeBlock(blk) => {
                 try!(pp::space(&mut s.s));
@@ -599,7 +602,7 @@ fn post(&self,
             }
             pprust::NodeExpr(expr) => {
                 try!(pp::space(&mut s.s));
-                try!(s.synth_comment(expr.id.to_str()));
+                try!(s.synth_comment(expr.id.to_string()));
                 s.pclose()
             }
             pprust::NodePat(pat) => {
@@ -633,7 +636,7 @@ fn post(&self,
                 try!(pp::word(&mut s.s, "as"));
                 try!(pp::space(&mut s.s));
                 try!(pp::word(&mut s.s,
-                              ppaux::ty_to_str(
+                              ppaux::ty_to_string(
                                   tcx,
                                   ty::expr_ty(tcx, expr)).as_slice()));
                 s.pclose()
@@ -649,13 +652,13 @@ pub fn pretty_print_input(sess: Session,
                           ppm: PpMode,
                           ofile: Option<Path>) {
     let krate = phase_1_parse_input(&sess, cfg, input);
-    let id = link::find_crate_id(krate.attrs.as_slice(),
-                                 input.filestem().as_slice());
+    let id = link::find_crate_name(Some(&sess), krate.attrs.as_slice(), input);
 
     let (krate, ast_map, is_expanded) = match ppm {
         PpmExpanded | PpmExpandedIdentified | PpmTyped | PpmFlowGraph(_) => {
             let (krate, ast_map)
-                = match phase_2_configure_and_expand(&sess, krate, &id) {
+                = match phase_2_configure_and_expand(&sess, krate,
+                                                     id.as_slice()) {
                     None => return,
                     Some(p) => p,
                 };
@@ -695,7 +698,7 @@ pub fn pretty_print_input(sess: Session,
         }
         PpmTyped => {
             let ast_map = ast_map.expect("--pretty=typed missing ast_map");
-            let analysis = phase_3_run_analysis_passes(sess, &krate, ast_map);
+            let analysis = phase_3_run_analysis_passes(sess, &krate, ast_map, id);
             let annotation = TypedAnnotation {
                 analysis: analysis
             };
@@ -728,7 +731,8 @@ pub fn pretty_print_input(sess: Session,
                     }
                 }
             };
-            let analysis = phase_3_run_analysis_passes(sess, &krate, ast_map);
+            let analysis = phase_3_run_analysis_passes(sess, &krate,
+                                                       ast_map, id);
             print_flowgraph(analysis, block, out)
         }
         _ => {
@@ -845,6 +849,11 @@ pub fn collect_crate_types(session: &Session,
     }).collect()
 }
 
+pub fn collect_crate_metadata(session: &Session,
+                              _attrs: &[ast::Attribute]) -> Vec<String> {
+    session.opts.cg.metadata.clone()
+}
+
 pub struct OutputFilenames {
     pub out_directory: Path,
     pub out_filestem: String,
@@ -893,14 +902,22 @@ pub fn build_output_filenames(input: &Input,
                 None => Path::new(".")
             };
 
-            let mut stem = input.filestem();
+            // If a crate name is present, we use it as the link name
+            let stem = sess.opts.crate_name.clone().or_else(|| {
+                attr::find_crate_name(attrs).map(|n| n.get().to_string())
+            }).or_else(|| {
+                // NB: this clause can be removed once #[crate_id] is no longer
+                // deprecated.
+                //
+                // Also note that this will be warned about later so we don't
+                // warn about it here.
+                use syntax::crateid::CrateId;
+                attrs.iter().find(|at| at.check_name("crate_id"))
+                     .and_then(|at| at.value_str())
+                     .and_then(|s| from_str::<CrateId>(s.get()))
+                     .map(|id| id.name)
+            }).unwrap_or(input.filestem());
 
-            // If a crateid is present, we use it as the link name
-            let crateid = attr::find_crateid(attrs);
-            match crateid {
-                None => {}
-                Some(crateid) => stem = crateid.name.to_string(),
-            }
             OutputFilenames {
                 out_directory: dirpath,
                 out_filestem: stem,
index 87c0a2708395756800683198baed2dc757eb57c1..ad0d8cac1e3578fa8aebf0ec4d13d56b2a2aea3d 100644 (file)
@@ -251,7 +251,7 @@ pub fn handle_options(mut args: Vec<String>) -> Option<getopts::Matches> {
         match getopts::getopts(args.as_slice(), config::optgroups().as_slice()) {
             Ok(m) => m,
             Err(f) => {
-                early_error(f.to_str().as_slice());
+                early_error(f.to_string().as_slice());
             }
         };
 
@@ -294,28 +294,26 @@ fn print_crate_info(sess: &Session,
                     odir: &Option<Path>,
                     ofile: &Option<Path>)
                     -> bool {
-    let (crate_id, crate_name, crate_file_name) = sess.opts.print_metas;
+    let (crate_name, crate_file_name) = sess.opts.print_metas;
     // these nasty nested conditions are to avoid doing extra work
-    if crate_id || crate_name || crate_file_name {
+    if crate_name || crate_file_name {
         let attrs = parse_crate_attrs(sess, input);
         let t_outputs = driver::build_output_filenames(input,
                                                        odir,
                                                        ofile,
                                                        attrs.as_slice(),
                                                        sess);
-        let id = link::find_crate_id(attrs.as_slice(),
-                                     t_outputs.out_filestem.as_slice());
+        let id = link::find_crate_name(Some(sess), attrs.as_slice(), input);
 
-        if crate_id {
-            println!("{}", id.to_str());
-        }
         if crate_name {
-            println!("{}", id.name);
+            println!("{}", id);
         }
         if crate_file_name {
             let crate_types = driver::collect_crate_types(sess, attrs.as_slice());
+            let metadata = driver::collect_crate_metadata(sess, attrs.as_slice());
+            *sess.crate_metadata.borrow_mut() = metadata;
             for &style in crate_types.iter() {
-                let fname = link::filename_for_input(sess, style, &id,
+                let fname = link::filename_for_input(sess, style, id.as_slice(),
                                                      &t_outputs.with_extension(""));
                 println!("{}", fname.filename_display());
             }
@@ -390,6 +388,11 @@ pub fn early_error(msg: &str) -> ! {
     fail!(diagnostic::FatalError);
 }
 
+pub fn early_warn(msg: &str) {
+    let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto);
+    emitter.emit(None, msg, diagnostic::Warning);
+}
+
 pub fn list_metadata(sess: &Session, path: &Path,
                      out: &mut io::Writer) -> io::IoResult<()> {
     metadata::loader::list_file_metadata(sess.targ_cfg.os, path, out)
@@ -447,7 +450,7 @@ fn monitor(f: proc():Send) {
                     emitter.emit(None, note.as_slice(), diagnostic::Note)
                 }
 
-                match r.read_to_str() {
+                match r.read_to_string() {
                     Ok(s) => println!("{}", s),
                     Err(e) => {
                         emitter.emit(None,
index 07366f34c4e03d7018c1821d408645025f59ccee..50f61f8f06a5be795e5df197238e7ca01b473876 100644 (file)
@@ -47,6 +47,7 @@ pub struct Session {
     pub lints: RefCell<NodeMap<Vec<(lint::LintId, codemap::Span, String)>>>,
     pub node_id: Cell<ast::NodeId>,
     pub crate_types: RefCell<Vec<config::CrateType>>,
+    pub crate_metadata: RefCell<Vec<String>>,
     pub features: front::feature_gate::Features,
 
     /// The maximum recursion limit for potentially infinitely recursive
@@ -243,6 +244,7 @@ pub fn build_session_(sopts: config::Options,
         lints: RefCell::new(NodeMap::new()),
         node_id: Cell::new(1),
         crate_types: RefCell::new(Vec::new()),
+        crate_metadata: RefCell::new(Vec::new()),
         features: front::feature_gate::Features::new(),
         recursion_limit: Cell::new(64),
     };
index 2fa0ab9072c226f3ef566ba0cab6e37c5d4187e1..9bff6620aaafd624aea35b1acb4a7bd9f2c1f23e 100644 (file)
@@ -109,12 +109,12 @@ fn fold_item_underscore(cx: &mut Context, item: &ast::Item_) -> ast::Item_ {
                 .map(|x| *x).collect();
             ast::ItemImpl((*a).clone(), (*b).clone(), c, methods)
         }
-        ast::ItemTrait(ref a, b, ref c, ref methods) => {
+        ast::ItemTrait(ref a, ref b, ref c, ref methods) => {
             let methods = methods.iter()
                                  .filter(|m| trait_method_in_cfg(cx, *m) )
                                  .map(|x| (*x).clone())
                                  .collect();
-            ast::ItemTrait((*a).clone(), b, (*c).clone(), methods)
+            ast::ItemTrait((*a).clone(), (*b).clone(), (*c).clone(), methods)
         }
         ast::ItemStruct(ref def, ref generics) => {
             ast::ItemStruct(fold_struct(cx, &**def), generics.clone())
index 54ba9db570e6366af279777b1d4cdee4b96e4a11..351c9a6b771672c6506c4c95f04d1419a8c71b87 100644 (file)
@@ -25,8 +25,6 @@
 use std::mem;
 use std::gc::{Gc, GC};
 
-pub static VERSION: &'static str = "0.11.0";
-
 pub fn maybe_inject_crates_ref(sess: &Session, krate: ast::Crate)
                                -> ast::Crate {
     if use_std(&krate) {
@@ -60,24 +58,12 @@ struct StandardLibraryInjector<'a> {
     sess: &'a Session,
 }
 
-pub fn with_version(krate: &str) -> Option<(InternedString, ast::StrStyle)> {
-    match option_env!("CFG_DISABLE_INJECT_STD_VERSION") {
-        Some("1") => None,
-        _ => {
-            Some((token::intern_and_get_ident(format!("{}#{}",
-                                                      krate,
-                                                      VERSION).as_slice()),
-                  ast::CookedStr))
-        }
-    }
-}
-
 impl<'a> fold::Folder for StandardLibraryInjector<'a> {
     fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
         let mut vis = vec!(ast::ViewItem {
             node: ast::ViewItemExternCrate(token::str_to_ident("std"),
-                                         with_version("std"),
-                                         ast::DUMMY_NODE_ID),
+                                           None,
+                                           ast::DUMMY_NODE_ID),
             attrs: vec!(
                 attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_list_item(
                         InternedString::new("phase"),
@@ -95,8 +81,8 @@ fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
         if use_start(&krate) && any_exe {
             vis.push(ast::ViewItem {
                 node: ast::ViewItemExternCrate(token::str_to_ident("native"),
-                                             with_version("native"),
-                                             ast::DUMMY_NODE_ID),
+                                               None,
+                                               ast::DUMMY_NODE_ID),
                 attrs: Vec::new(),
                 vis: ast::Inherited,
                 span: DUMMY_SP
index d33b76ae08c5ede9b9b1d9329beb5d3c86e02624..0860d111a9ef04a2f254bbf2de4b615856651cd2 100644 (file)
@@ -15,7 +15,6 @@
 
 use driver::session::Session;
 use front::config;
-use front::std_inject::with_version;
 
 use std::cell::RefCell;
 use std::gc::{Gc, GC};
@@ -154,7 +153,7 @@ fn generate_test_harness(sess: &Session, krate: ast::Crate)
         ext_cx: ExtCtxt::new(&sess.parse_sess, sess.opts.cfg.clone(),
                              ExpansionConfig {
                                  deriving_hash_type_parameter: false,
-                                 crate_id: from_str("test").unwrap(),
+                                 crate_name: "test".to_string(),
                              }),
         path: RefCell::new(Vec::new()),
         testfns: RefCell::new(Vec::new()),
@@ -298,9 +297,7 @@ fn mk_std(cx: &TestCtxt) -> ast::ViewItem {
                                         ast::DUMMY_NODE_ID))),
          ast::Public)
     } else {
-        (ast::ViewItemExternCrate(id_test,
-                               with_version("test"),
-                               ast::DUMMY_NODE_ID),
+        (ast::ViewItemExternCrate(id_test, None, ast::DUMMY_NODE_ID),
          ast::Inherited)
     };
     ast::ViewItem {
@@ -350,7 +347,7 @@ pub fn main() {
         span: DUMMY_SP,
      };
 
-    debug!("Synthetic test module:\n{}\n", pprust::item_to_str(&item));
+    debug!("Synthetic test module:\n{}\n", pprust::item_to_string(&item));
 
     box(GC) item
 }
@@ -395,8 +392,8 @@ fn mk_tests(cx: &TestCtxt) -> Gc<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.as_slice() => true,
+    match attr::find_crate_name(krate.attrs.as_slice()) {
+        Some(ref s) if "test" == s.get().as_slice() => true,
         _ => false
     }
 }
index 729eb908e3943be911df2c82cf1a159e4fb02494..eee909f59e30453a77faab7955c16141409a254c 100644 (file)
@@ -18,7 +18,8 @@
 
 */
 
-#![crate_id = "rustc#0.11.0"]
+#![crate_id = "rustc#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "rustc"]
 #![experimental]
 #![comment = "The Rust compiler"]
 #![license = "MIT/ASL2"]
@@ -31,6 +32,7 @@
 #![allow(deprecated)]
 #![feature(macro_rules, globs, struct_variant, managed_boxes, quote)]
 #![feature(default_type_params, phase, unsafe_destructor)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 extern crate arena;
 extern crate debug;
index d07e74493be96dc4b82547a158860d7e68e3442e..a4425183cde64ad79f46fa646d43ab8aca5b3e3c 100644 (file)
@@ -1883,7 +1883,7 @@ pub fn find_type(&self, s: &str) -> Option<Type> {
         self.named_types.borrow().find_equiv(&s).map(|x| Type::from_ref(*x))
     }
 
-    pub fn type_to_str(&self, ty: Type) -> String {
+    pub fn type_to_string(&self, ty: Type) -> String {
         unsafe {
             let s = llvm::LLVMTypeToString(ty.to_ref());
             let ret = from_c_str(s);
@@ -1893,11 +1893,11 @@ pub fn type_to_str(&self, ty: Type) -> String {
     }
 
     pub fn types_to_str(&self, tys: &[Type]) -> String {
-        let strs: Vec<String> = tys.iter().map(|t| self.type_to_str(*t)).collect();
+        let strs: Vec<String> = tys.iter().map(|t| self.type_to_string(*t)).collect();
         format!("[{}]", strs.connect(","))
     }
 
-    pub fn val_to_str(&self, val: ValueRef) -> String {
+    pub fn val_to_string(&self, val: ValueRef) -> String {
         unsafe {
             let s = llvm::LLVMValueToString(val);
             let ret = from_c_str(s);
index a8f778934ae47e21c28b9b3c016d5326598bd1ea..98a6f7d5ed38d2879255f6065f3c7510839e3179 100644 (file)
@@ -31,7 +31,7 @@
 use middle::typeck::astconv::ast_ty_to_ty;
 use middle::typeck::infer;
 use middle::{typeck, ty, def, pat_util, stability};
-use util::ppaux::{ty_to_str};
+use util::ppaux::{ty_to_string};
 use util::nodemap::NodeSet;
 use lint::{Context, LintPass, LintArray};
 
@@ -412,14 +412,14 @@ fn check_heap_type(&self, cx: &Context, span: Span, ty: ty::t) {
         });
 
         if n_uniq > 0 {
-            let s = ty_to_str(cx.tcx, ty);
+            let s = ty_to_string(cx.tcx, ty);
             let m = format!("type uses owned (Box type) pointers: {}", s);
             cx.span_lint(OWNED_HEAP_MEMORY, span, m.as_slice());
             cx.span_lint(HEAP_MEMORY, span, m.as_slice());
         }
 
         if n_box > 0 {
-            let s = ty_to_str(cx.tcx, ty);
+            let s = ty_to_string(cx.tcx, ty);
             let m = format!("type uses managed (@ type) pointers: {}", s);
             cx.span_lint(MANAGED_HEAP_MEMORY, span, m.as_slice());
             cx.span_lint(HEAP_MEMORY, span, m.as_slice());
@@ -540,7 +540,7 @@ fn get_lints(&self) -> LintArray {
     }
 
     fn check_attribute(&mut self, cx: &Context, attr: &ast::Attribute) {
-        static ATTRIBUTE_WHITELIST: &'static [&'static str] = &'static [
+        static ATTRIBUTE_WHITELIST: &'static [&'static str] = &[
             // FIXME: #14408 whitelist docs since rustdoc looks at them
             "doc",
 
@@ -574,13 +574,13 @@ fn check_attribute(&mut self, cx: &Context, attr: &ast::Attribute) {
             "unstable",
         ];
 
-        static CRATE_ATTRS: &'static [&'static str] = &'static [
+        static CRATE_ATTRS: &'static [&'static str] = &[
+            "crate_name",
             "crate_type",
             "feature",
             "no_start",
             "no_main",
             "no_std",
-            "crate_id",
             "desc",
             "comment",
             "license",
index 79fbd73c23d3cbdbcffeef0ed299fcc604440657..61aaf068c1098bd06ce1e6e9c9433542bfc7e2a7 100644 (file)
@@ -666,7 +666,7 @@ pub fn check_crate(tcx: &ty::ctxt,
         for &(lint, span, ref msg) in v.iter() {
             tcx.sess.span_bug(span,
                               format!("unprocessed lint {} at {}: {}",
-                                      lint.as_str(), tcx.map.node_to_str(*id), *msg).as_slice())
+                                      lint.as_str(), tcx.map.node_to_string(*id), *msg).as_slice())
         }
     }
 
index 9e1d272f5da2e2ec8c4beb3a129dfe2a628b48d3..cdeecf3a080fe2f26fadafe77e2b673d17bb38fe 100644 (file)
@@ -11,7 +11,6 @@
 #![allow(non_camel_case_types)]
 
 use std::mem;
-use syntax::crateid::CrateId;
 use back::svh::Svh;
 
 // EBML enum definitions and utils shared by the encoder and decoder
@@ -71,9 +70,9 @@
 pub static tag_crate_dep: uint = 0x19;
 
 pub static tag_crate_hash: uint = 0x1a;
-pub static tag_crate_crateid: uint = 0x1b;
+pub static tag_crate_crate_name: uint = 0x1b;
 
-pub static tag_crate_dep_crateid: uint = 0x1d;
+pub static tag_crate_dep_crate_name: uint = 0x1d;
 pub static tag_crate_dep_hash: uint = 0x1e;
 
 pub static tag_mod_impl: uint = 0x1f;
@@ -215,7 +214,7 @@ pub fn from_uint(value : uint) -> Option<astencode_tag> {
 
 #[deriving(Clone, Show)]
 pub struct LinkMeta {
-    pub crateid: CrateId,
+    pub crate_name: String,
     pub crate_hash: Svh,
 }
 
index 218fc31f62356efd2b709ac16d86c2a3f81f4a5e..edf46c214ba63fa4b94757ab2dafc19f9fc91aed 100644 (file)
@@ -12,7 +12,6 @@
 
 //! Validates all used crates and extern libraries and loads their metadata
 
-use back::link;
 use back::svh::Svh;
 use driver::session::Session;
 use driver::{driver, config};
@@ -33,7 +32,6 @@
 use syntax::diagnostic::SpanHandler;
 use syntax::parse::token::InternedString;
 use syntax::parse::token;
-use syntax::crateid::CrateId;
 use syntax::visit;
 
 struct Env<'a> {
@@ -69,7 +67,7 @@ fn visit_item(&mut self, a: &ast::Item, _: ()) {
 fn dump_crates(cstore: &CStore) {
     debug!("resolved crates:");
     cstore.iter_crate_data_origins(|_, data, opt_source| {
-        debug!("crate_id: {}", data.crate_id());
+        debug!("  name: {}", data.name());
         debug!("  cnum: {}", data.cnum);
         debug!("  hash: {}", data.hash());
         opt_source.map(|cs| {
@@ -83,20 +81,17 @@ fn dump_crates(cstore: &CStore) {
 fn warn_if_multiple_versions(diag: &SpanHandler, cstore: &CStore) {
     let mut map = HashMap::new();
     cstore.iter_crate_data(|cnum, data| {
-        let crateid = data.crate_id();
-        let key = (crateid.name.clone(), crateid.path.clone());
-        map.find_or_insert_with(key, |_| Vec::new()).push(cnum);
+        map.find_or_insert_with(data.name(), |_| Vec::new()).push(cnum);
     });
 
-    for ((name, _), dupes) in map.move_iter() {
+    for (name, dupes) in map.move_iter() {
         if dupes.len() == 1 { continue }
         diag.handler().warn(
-            format!("using multiple versions of crate `{}`",
-                    name).as_slice());
+            format!("using multiple versions of crate `{}`", name).as_slice());
         for dupe in dupes.move_iter() {
             let data = cstore.get_crate_data(dupe);
             diag.span_note(data.span, "used here");
-            loader::note_crateid_attr(diag, &data.crate_id());
+            loader::note_crate_name(diag, data.name().as_slice());
         }
     }
 }
@@ -129,7 +124,7 @@ fn visit_view_item(e: &mut Env, i: &ast::ViewItem) {
             let (cnum, _, _) = resolve_crate(e,
                                              &None,
                                              info.ident.as_slice(),
-                                             &info.crate_id,
+                                             info.name.as_slice(),
                                              None,
                                              i.span);
             e.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
@@ -140,7 +135,7 @@ fn visit_view_item(e: &mut Env, i: &ast::ViewItem) {
 
 struct CrateInfo {
     ident: String,
-    crate_id: CrateId,
+    name: String,
     id: ast::NodeId,
     should_link: bool,
 }
@@ -151,22 +146,18 @@ fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> {
             let ident = token::get_ident(ident);
             debug!("resolving extern crate stmt. ident: {:?} path_opt: {:?}",
                    ident, path_opt);
-            let crate_id = match *path_opt {
+            let name = match *path_opt {
                 Some((ref path_str, _)) => {
-                    let crateid: Option<CrateId> = from_str(path_str.get());
-                    match crateid {
-                        None => {
-                            e.sess.span_err(i.span, "malformed crate id");
-                            return None
-                        }
-                        Some(id) => id
-                    }
+                    let name = path_str.get().to_string();
+                    validate_crate_name(Some(e.sess), name.as_slice(),
+                                        Some(i.span));
+                    name
                 }
-                None => from_str(ident.get().to_str().as_slice()).unwrap()
+                None => ident.get().to_string(),
             };
             Some(CrateInfo {
                 ident: ident.get().to_string(),
-                crate_id: crate_id,
+                name: name,
                 id: id,
                 should_link: should_link(i),
             })
@@ -175,6 +166,28 @@ fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> {
     }
 }
 
+pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
+    let err = |s: &str| {
+        match (sp, sess) {
+            (_, None) => fail!("{}", s),
+            (Some(sp), Some(sess)) => sess.span_err(sp, s),
+            (None, Some(sess)) => sess.err(s),
+        }
+    };
+    if s.len() == 0 {
+        err("crate name must not be empty");
+    }
+    for c in s.chars() {
+        if c.is_alphanumeric() { continue }
+        if c == '_' || c == '-' { continue }
+        err(format!("invalid character `{}` in crate name: `{}`", c, s).as_slice());
+    }
+    match sess {
+        Some(sess) => sess.abort_if_errors(),
+        None => {}
+    }
+}
+
 fn visit_item(e: &Env, i: &ast::Item) {
     match i.node {
         ast::ItemForeignMod(ref fm) => {
@@ -263,17 +276,36 @@ fn visit_item(e: &Env, i: &ast::Item) {
     }
 }
 
-fn existing_match(e: &Env, crate_id: &CrateId,
+fn existing_match(e: &Env, name: &str,
                   hash: Option<&Svh>) -> Option<ast::CrateNum> {
     let mut ret = None;
     e.sess.cstore.iter_crate_data(|cnum, data| {
-        let other_id = data.crate_id();
-        if crate_id.matches(&other_id) {
-            let other_hash = data.hash();
-            match hash {
-                Some(hash) if *hash != other_hash => {}
-                Some(..) | None => { ret = Some(cnum); }
+        if data.name().as_slice() != name { return }
+
+        match hash {
+            Some(hash) if *hash == data.hash() => { ret = Some(cnum); return }
+            Some(..) => return,
+            None => {}
+        }
+
+        // When the hash is None we're dealing with a top-level dependency in
+        // which case we may have a specification on the command line for this
+        // library. Even though an upstream library may have loaded something of
+        // the same name, we have to make sure it was loaded from the exact same
+        // location as well.
+        let source = e.sess.cstore.get_used_crate_source(cnum).unwrap();
+        let dylib = source.dylib.as_ref().map(|p| p.as_vec());
+        let rlib = source.rlib.as_ref().map(|p| p.as_vec());
+        match e.sess.opts.externs.find_equiv(&name) {
+            Some(locs) => {
+                let found = locs.iter().any(|l| {
+                    Some(l.as_bytes()) == dylib || Some(l.as_bytes()) == rlib
+                });
+                if found {
+                    ret = Some(cnum);
+                }
             }
+            None => ret = Some(cnum),
         }
     });
     return ret;
@@ -282,7 +314,7 @@ fn existing_match(e: &Env, crate_id: &CrateId,
 fn register_crate<'a>(e: &mut Env,
                   root: &Option<CratePaths>,
                   ident: &str,
-                  crate_id: &CrateId,
+                  name: &str,
                   span: Span,
                   lib: loader::Library)
                         -> (ast::CrateNum, Rc<cstore::crate_metadata>,
@@ -309,7 +341,7 @@ fn register_crate<'a>(e: &mut Env,
     let loader::Library{ dylib, rlib, metadata } = lib;
 
     let cmeta = Rc::new( cstore::crate_metadata {
-        name: crate_id.name.to_string(),
+        name: name.to_string(),
         data: metadata,
         cnum_map: cnum_map,
         cnum: cnum,
@@ -330,20 +362,18 @@ fn register_crate<'a>(e: &mut Env,
 fn resolve_crate<'a>(e: &mut Env,
                  root: &Option<CratePaths>,
                  ident: &str,
-                 crate_id: &CrateId,
+                 name: &str,
                  hash: Option<&Svh>,
                  span: Span)
                      -> (ast::CrateNum, Rc<cstore::crate_metadata>,
                          cstore::CrateSource) {
-    match existing_match(e, crate_id, hash) {
+    match existing_match(e, name, hash) {
         None => {
-            let id_hash = link::crate_id_hash(crate_id);
             let mut load_ctxt = loader::Context {
                 sess: e.sess,
                 span: span,
                 ident: ident,
-                crate_id: crate_id,
-                id_hash: id_hash.as_slice(),
+                crate_name: name,
                 hash: hash.map(|a| &*a),
                 filesearch: e.sess.target_filesearch(),
                 os: e.sess.targ_cfg.os,
@@ -351,9 +381,10 @@ fn resolve_crate<'a>(e: &mut Env,
                 root: root,
                 rejected_via_hash: vec!(),
                 rejected_via_triple: vec!(),
+                should_match_name: true,
             };
             let library = load_ctxt.load_library_crate();
-            register_crate(e, root, ident, crate_id, span, library)
+            register_crate(e, root, ident, name, span, library)
         }
         Some(cnum) => (cnum,
                        e.sess.cstore.get_crate_data(cnum),
@@ -370,10 +401,10 @@ fn resolve_crate_deps(e: &mut Env,
     // The map from crate numbers in the crate we're resolving to local crate
     // numbers
     decoder::get_crate_deps(cdata).iter().map(|dep| {
-        debug!("resolving dep crate {} hash: `{}`", dep.crate_id, dep.hash);
+        debug!("resolving dep crate {} hash: `{}`", dep.name, dep.hash);
         let (local_cnum, _, _) = resolve_crate(e, root,
-                                               dep.crate_id.name.as_slice(),
-                                               &dep.crate_id,
+                                               dep.name.as_slice(),
+                                               dep.name.as_slice(),
                                                Some(&dep.hash),
                                                span);
         (dep.cnum, local_cnum)
@@ -399,14 +430,12 @@ pub fn read_plugin_metadata(&mut self, krate: &ast::ViewItem) -> PluginMetadata
         let target_triple = self.env.sess.targ_cfg.target_strs.target_triple.as_slice();
         let is_cross = target_triple != driver::host_triple();
         let mut should_link = info.should_link && !is_cross;
-        let id_hash = link::crate_id_hash(&info.crate_id);
         let os = config::get_os(driver::host_triple()).unwrap();
         let mut load_ctxt = loader::Context {
             sess: self.env.sess,
             span: krate.span,
             ident: info.ident.as_slice(),
-            crate_id: &info.crate_id,
-            id_hash: id_hash.as_slice(),
+            crate_name: info.name.as_slice(),
             hash: None,
             filesearch: self.env.sess.host_filesearch(),
             triple: driver::host_triple(),
@@ -414,6 +443,7 @@ pub fn read_plugin_metadata(&mut self, krate: &ast::ViewItem) -> PluginMetadata
             root: &None,
             rejected_via_hash: vec!(),
             rejected_via_triple: vec!(),
+            should_match_name: true,
         };
         let library = match load_ctxt.maybe_load_library_crate() {
             Some (l) => l,
@@ -448,10 +478,11 @@ pub fn read_plugin_metadata(&mut self, krate: &ast::ViewItem) -> PluginMetadata
             macros: macros,
             registrar_symbol: registrar,
         };
-        if should_link && existing_match(&self.env, &info.crate_id, None).is_none() {
+        if should_link && existing_match(&self.env, info.name.as_slice(),
+                                         None).is_none() {
             // register crate now to avoid double-reading metadata
             register_crate(&mut self.env, &None, info.ident.as_slice(),
-                           &info.crate_id, krate.span, library);
+                           info.name.as_slice(), krate.span, library);
         }
         pc
     }
index 846f879104f64f7ba559e62815d7b025d65b024e..5dafb7a661dfd0c7755ca8281400aafa8cddcff4 100644 (file)
@@ -22,7 +22,6 @@
 use std::rc::Rc;
 use std::collections::HashMap;
 use syntax::ast;
-use syntax::crateid::CrateId;
 use syntax::codemap::Span;
 use syntax::parse::token::IdentInterner;
 
@@ -197,7 +196,7 @@ pub fn get_used_libraries<'a>(&'a self)
     }
 
     pub fn add_used_link_args(&self, args: &str) {
-        for s in args.split(' ') {
+        for s in args.split(' ').filter(|s| !s.is_empty()) {
             self.used_link_args.borrow_mut().push(s.to_string());
         }
     }
@@ -220,7 +219,7 @@ pub fn find_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId)
 
 impl crate_metadata {
     pub fn data<'a>(&'a self) -> &'a [u8] { self.data.as_slice() }
-    pub fn crate_id(&self) -> CrateId { decoder::get_crate_id(self.data()) }
+    pub fn name(&self) -> String { decoder::get_crate_name(self.data()) }
     pub fn hash(&self) -> Svh { decoder::get_crate_hash(self.data()) }
 }
 
index 78a29b52bdf5bc45974f05b5adf5bfe4ffc7d88b..0b9ed37c8384b78daca60e40d2e13ed10a35e471 100644 (file)
@@ -46,7 +46,6 @@
 use syntax::print::pprust;
 use syntax::ast;
 use syntax::codemap;
-use syntax::crateid::CrateId;
 
 pub type Cmd<'a> = &'a crate_metadata;
 
@@ -165,19 +164,6 @@ fn item_visibility(item: ebml::Doc) -> ast::Visibility {
     }
 }
 
-fn item_sized(item: ebml::Doc) -> ast::Sized {
-    match reader::maybe_get_doc(item, tag_items_data_item_sized) {
-        None => ast::StaticSize,
-        Some(sized_doc) => {
-            match reader::doc_as_u8(sized_doc) as char {
-                'd' => ast::DynSize,
-                's' => ast::StaticSize,
-                _ => fail!("unknown sized-ness character")
-            }
-        }
-    }
-}
-
 fn item_method_sort(item: ebml::Doc) -> char {
     let mut ret = 'r';
     reader::tagged_docs(item, tag_item_trait_method_sort, |doc| {
@@ -394,7 +380,6 @@ pub fn get_trait_def(cdata: Cmd,
     let tp_defs = item_ty_param_defs(item_doc, tcx, cdata,
                                      tag_items_data_item_ty_param_bounds);
     let rp_defs = item_region_param_defs(item_doc, cdata);
-    let sized = item_sized(item_doc);
     let mut bounds = ty::empty_builtin_bounds();
     // Collect the builtin bounds from the encoded supertraits.
     // FIXME(#8559): They should be encoded directly.
@@ -406,12 +391,6 @@ pub fn get_trait_def(cdata: Cmd,
         });
         true
     });
-    // Turn sized into a bound, FIXME(#8559).
-    if sized == ast::StaticSize {
-        tcx.lang_items.to_builtin_kind(tcx.lang_items.sized_trait().unwrap()).map(|bound| {
-            bounds.add(bound);
-        });
-    }
 
     ty::TraitDef {
         generics: ty::Generics {types: tp_defs,
@@ -1088,7 +1067,7 @@ fn list_crate_attributes(md: ebml::Doc, hash: &Svh,
 
     let r = get_attributes(md);
     for attr in r.iter() {
-        try!(write!(out, "{}\n", pprust::attribute_to_str(attr)));
+        try!(write!(out, "{}\n", pprust::attribute_to_string(attr)));
     }
 
     write!(out, "\n\n")
@@ -1101,7 +1080,7 @@ pub fn get_crate_attributes(data: &[u8]) -> Vec<ast::Attribute> {
 #[deriving(Clone)]
 pub struct CrateDep {
     pub cnum: ast::CrateNum,
-    pub crate_id: CrateId,
+    pub name: String,
     pub hash: Svh,
 }
 
@@ -1115,13 +1094,11 @@ fn docstr(doc: ebml::Doc, tag_: uint) -> String {
         d.as_str_slice().to_string()
     }
     reader::tagged_docs(depsdoc, tag_crate_dep, |depdoc| {
-        let crate_id =
-            from_str(docstr(depdoc,
-                            tag_crate_dep_crateid).as_slice()).unwrap();
+        let name = docstr(depdoc, tag_crate_dep_crate_name);
         let hash = Svh::new(docstr(depdoc, tag_crate_dep_hash).as_slice());
         deps.push(CrateDep {
             cnum: crate_num,
-            crate_id: crate_id,
+            name: name,
             hash: hash,
         });
         crate_num += 1;
@@ -1133,7 +1110,7 @@ fn docstr(doc: ebml::Doc, tag_: uint) -> String {
 fn list_crate_deps(data: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
     try!(write!(out, "=External Dependencies=\n"));
     for dep in get_crate_deps(data).iter() {
-        try!(write!(out, "{} {}-{}\n", dep.cnum, dep.crate_id, dep.hash));
+        try!(write!(out, "{} {}-{}\n", dep.cnum, dep.name, dep.hash));
     }
     try!(write!(out, "\n"));
     Ok(())
@@ -1152,23 +1129,21 @@ pub fn get_crate_hash(data: &[u8]) -> Svh {
     Svh::new(hashdoc.as_str_slice())
 }
 
-pub fn maybe_get_crate_id(data: &[u8]) -> Option<CrateId> {
+pub fn maybe_get_crate_name(data: &[u8]) -> Option<String> {
     let cratedoc = ebml::Doc::new(data);
-    reader::maybe_get_doc(cratedoc, tag_crate_crateid).map(|doc| {
-        from_str(doc.as_str_slice()).unwrap()
+    reader::maybe_get_doc(cratedoc, tag_crate_crate_name).map(|doc| {
+        doc.as_str_slice().to_string()
     })
 }
 
-pub fn get_crate_triple(data: &[u8]) -> String {
+pub fn get_crate_triple(data: &[u8]) -> Option<String> {
     let cratedoc = ebml::Doc::new(data);
     let triple_doc = reader::maybe_get_doc(cratedoc, tag_crate_triple);
-    triple_doc.expect("No triple in crate").as_str().to_string()
+    triple_doc.map(|s| s.as_str().to_string())
 }
 
-pub fn get_crate_id(data: &[u8]) -> CrateId {
-    let cratedoc = ebml::Doc::new(data);
-    let hashdoc = reader::get_doc(cratedoc, tag_crate_crateid);
-    from_str(hashdoc.as_str_slice()).unwrap()
+pub fn get_crate_name(data: &[u8]) -> String {
+    maybe_get_crate_name(data).expect("no crate name in crate")
 }
 
 pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
index 6eb7c5a4310e6f9cb61abc55001000ae275839cc..6c544e3809a078d2ede94ecd2252080f08412b87 100644 (file)
 use syntax::ast_map;
 use syntax::ast_util::*;
 use syntax::ast_util;
-use syntax::attr::AttrMetaMethods;
 use syntax::attr;
-use syntax::crateid::CrateId;
+use syntax::attr::AttrMetaMethods;
 use syntax::diagnostic::SpanHandler;
-use syntax::parse::token::InternedString;
 use syntax::parse::token::special_idents;
 use syntax::parse::token;
 use syntax::visit::Visitor;
@@ -103,7 +101,7 @@ fn encode_impl_type_basename(ebml_w: &mut Encoder, name: Ident) {
 }
 
 pub fn encode_def_id(ebml_w: &mut Encoder, id: DefId) {
-    ebml_w.wr_tagged_str(tag_def_id, def_to_str(id).as_slice());
+    ebml_w.wr_tagged_str(tag_def_id, def_to_string(id).as_slice());
 }
 
 #[deriving(Clone)]
@@ -118,7 +116,7 @@ fn encode_trait_ref(ebml_w: &mut Encoder,
                     tag: uint) {
     let ty_str_ctxt = &tyencode::ctxt {
         diag: ecx.diag,
-        ds: def_to_str,
+        ds: def_to_string,
         tcx: ecx.tcx,
         abbrevs: &ecx.type_abbrevs
     };
@@ -143,7 +141,7 @@ fn encode_family(ebml_w: &mut Encoder, c: char) {
     ebml_w.end_tag();
 }
 
-pub fn def_to_str(did: DefId) -> String {
+pub fn def_to_string(did: DefId) -> String {
     format!("{}:{}", did.krate, did.node)
 }
 
@@ -153,7 +151,7 @@ fn encode_ty_type_param_defs(ebml_w: &mut Encoder,
                              tag: uint) {
     let ty_str_ctxt = &tyencode::ctxt {
         diag: ecx.diag,
-        ds: def_to_str,
+        ds: def_to_string,
         tcx: ecx.tcx,
         abbrevs: &ecx.type_abbrevs
     };
@@ -174,7 +172,7 @@ fn encode_region_param_defs(ebml_w: &mut Encoder,
         ebml_w.end_tag();
 
         ebml_w.wr_tagged_str(tag_region_param_def_def_id,
-                             def_to_str(param.def_id).as_slice());
+                             def_to_string(param.def_id).as_slice());
 
         ebml_w.wr_tagged_u64(tag_region_param_def_space,
                              param.space.to_uint() as u64);
@@ -206,7 +204,7 @@ fn encode_bounds_and_type(ebml_w: &mut Encoder,
 
 fn encode_variant_id(ebml_w: &mut Encoder, vid: DefId) {
     ebml_w.start_tag(tag_items_data_item_variant);
-    let s = def_to_str(vid);
+    let s = def_to_string(vid);
     ebml_w.writer.write(s.as_bytes());
     ebml_w.end_tag();
 }
@@ -216,7 +214,7 @@ pub fn write_type(ecx: &EncodeContext,
                   typ: ty::t) {
     let ty_str_ctxt = &tyencode::ctxt {
         diag: ecx.diag,
-        ds: def_to_str,
+        ds: def_to_string,
         tcx: ecx.tcx,
         abbrevs: &ecx.type_abbrevs
     };
@@ -238,7 +236,7 @@ fn encode_method_fty(ecx: &EncodeContext,
 
     let ty_str_ctxt = &tyencode::ctxt {
         diag: ecx.diag,
-        ds: def_to_str,
+        ds: def_to_string,
         tcx: ecx.tcx,
         abbrevs: &ecx.type_abbrevs
     };
@@ -268,14 +266,14 @@ fn encode_disr_val(_: &EncodeContext,
                    ebml_w: &mut Encoder,
                    disr_val: ty::Disr) {
     ebml_w.start_tag(tag_disr_val);
-    let s = disr_val.to_str();
+    let s = disr_val.to_string();
     ebml_w.writer.write(s.as_bytes());
     ebml_w.end_tag();
 }
 
 fn encode_parent_item(ebml_w: &mut Encoder, id: DefId) {
     ebml_w.start_tag(tag_items_data_parent_item);
-    let s = def_to_str(id);
+    let s = def_to_string(id);
     ebml_w.writer.write(s.as_bytes());
     ebml_w.end_tag();
 }
@@ -293,7 +291,7 @@ fn encode_struct_fields(ebml_w: &mut Encoder,
         encode_struct_field_family(ebml_w, f.vis);
         encode_def_id(ebml_w, f.id);
         ebml_w.start_tag(tag_item_field_origin);
-        let s = def_to_str(origin);
+        let s = def_to_string(origin);
         ebml_w.writer.write(s.as_bytes());
         ebml_w.end_tag();
         ebml_w.end_tag();
@@ -384,7 +382,7 @@ fn encode_reexported_static_method(ebml_w: &mut Encoder,
             exp.name, token::get_ident(method_ident));
     ebml_w.start_tag(tag_items_data_item_reexport);
     ebml_w.start_tag(tag_items_data_item_reexport_def_id);
-    ebml_w.wr_str(def_to_str(method_def_id).as_slice());
+    ebml_w.wr_str(def_to_string(method_def_id).as_slice());
     ebml_w.end_tag();
     ebml_w.start_tag(tag_items_data_item_reexport_name);
     ebml_w.wr_str(format!("{}::{}",
@@ -531,7 +529,7 @@ fn encode_reexports(ecx: &EncodeContext,
                        id);
                 ebml_w.start_tag(tag_items_data_item_reexport);
                 ebml_w.start_tag(tag_items_data_item_reexport_def_id);
-                ebml_w.wr_str(def_to_str(exp.def_id).as_slice());
+                ebml_w.wr_str(def_to_string(exp.def_id).as_slice());
                 ebml_w.end_tag();
                 ebml_w.start_tag(tag_items_data_item_reexport_name);
                 ebml_w.wr_str(exp.name.as_slice());
@@ -564,12 +562,12 @@ fn encode_info_for_mod(ecx: &EncodeContext,
     // Encode info about all the module children.
     for item in md.items.iter() {
         ebml_w.start_tag(tag_mod_child);
-        ebml_w.wr_str(def_to_str(local_def(item.id)).as_slice());
+        ebml_w.wr_str(def_to_string(local_def(item.id)).as_slice());
         ebml_w.end_tag();
 
         each_auxiliary_node_id(*item, |auxiliary_node_id| {
             ebml_w.start_tag(tag_mod_child);
-            ebml_w.wr_str(def_to_str(local_def(
+            ebml_w.wr_str(def_to_string(local_def(
                         auxiliary_node_id)).as_slice());
             ebml_w.end_tag();
             true
@@ -581,10 +579,10 @@ fn encode_info_for_mod(ecx: &EncodeContext,
                 debug!("(encoding info for module) ... encoding impl {} \
                         ({:?}/{:?})",
                         token::get_ident(ident),
-                        did, ecx.tcx.map.node_to_str(did));
+                        did, ecx.tcx.map.node_to_string(did));
 
                 ebml_w.start_tag(tag_mod_impl);
-                ebml_w.wr_str(def_to_str(local_def(did)).as_slice());
+                ebml_w.wr_str(def_to_string(local_def(did)).as_slice());
                 ebml_w.end_tag();
             }
             _ => {}
@@ -661,7 +659,7 @@ fn encode_provided_source(ebml_w: &mut Encoder,
                           source_opt: Option<DefId>) {
     for source in source_opt.iter() {
         ebml_w.start_tag(tag_item_method_provided_source);
-        let s = def_to_str(*source);
+        let s = def_to_string(*source);
         ebml_w.writer.write(s.as_bytes());
         ebml_w.end_tag();
     }
@@ -883,16 +881,6 @@ fn encode_extension_implementations(ecx: &EncodeContext,
     }
 }
 
-fn encode_sized(ebml_w: &mut Encoder, sized: Sized) {
-    ebml_w.start_tag(tag_items_data_item_sized);
-    let ch = match sized {
-        DynSize => 'd',
-        StaticSize => 's',
-    };
-    ebml_w.wr_str(str::from_char(ch).as_slice());
-    ebml_w.end_tag();
-}
-
 fn encode_stability(ebml_w: &mut Encoder, stab_opt: Option<attr::Stability>) {
     stab_opt.map(|stab| {
         ebml_w.start_tag(tag_items_data_item_stability);
@@ -918,7 +906,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
     }
 
     debug!("encoding info for item at {}",
-           tcx.sess.codemap().span_to_str(item.span));
+           tcx.sess.codemap().span_to_string(item.span));
 
     let def_id = local_def(item.id);
     let stab = stability::lookup(tcx, ast_util::local_def(item.id));
@@ -989,7 +977,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
         // Encode all the items in this module.
         for foreign_item in fm.items.iter() {
             ebml_w.start_tag(tag_mod_child);
-            ebml_w.wr_str(def_to_str(local_def(foreign_item.id)).as_slice());
+            ebml_w.wr_str(def_to_string(local_def(foreign_item.id)).as_slice());
             ebml_w.end_tag();
         }
         encode_visibility(ebml_w, vis);
@@ -1113,7 +1101,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
         }
         for &method_def_id in methods.iter() {
             ebml_w.start_tag(tag_item_impl_method);
-            let s = def_to_str(method_def_id);
+            let s = def_to_string(method_def_id);
             ebml_w.writer.write(s.as_bytes());
             ebml_w.end_tag();
         }
@@ -1151,7 +1139,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
                                    ast_method)
         }
       }
-      ItemTrait(_, sized, ref super_traits, ref ms) => {
+      ItemTrait(_, _, ref super_traits, ref ms) => {
         add_to_index(item, ebml_w, index);
         ebml_w.start_tag(tag_items_data_item);
         encode_def_id(ebml_w, def_id);
@@ -1165,9 +1153,6 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
         encode_trait_ref(ebml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref);
         encode_name(ebml_w, item.ident.name);
         encode_attributes(ebml_w, item.attrs.as_slice());
-        // When we fix the rest of the supertrait nastiness (FIXME(#8559)), we
-        // should no longer need this ugly little hack either.
-        encode_sized(ebml_w, sized);
         encode_visibility(ebml_w, vis);
         encode_stability(ebml_w, stab);
         for &method_def_id in ty::trait_method_def_ids(tcx, def_id).iter() {
@@ -1176,7 +1161,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
             ebml_w.end_tag();
 
             ebml_w.start_tag(tag_mod_child);
-            ebml_w.wr_str(def_to_str(method_def_id).as_slice());
+            ebml_w.wr_str(def_to_string(method_def_id).as_slice());
             ebml_w.end_tag();
         }
         encode_path(ebml_w, path.clone());
@@ -1329,7 +1314,7 @@ fn my_visit_foreign_item(ni: &ForeignItem,
     // See above
     let ecx: &EncodeContext = unsafe { mem::transmute(ecx_ptr) };
     debug!("writing foreign item {}::{}",
-            ecx.tcx.map.path_to_str(ni.id),
+            ecx.tcx.map.path_to_string(ni.id),
             token::get_ident(ni.ident));
 
     let mut ebml_w = unsafe {
@@ -1494,35 +1479,6 @@ fn encode_attributes(ebml_w: &mut Encoder, attrs: &[Attribute]) {
     ebml_w.end_tag();
 }
 
-// So there's a special crate attribute called 'crate_id' which defines the
-// metadata that Rust cares about for linking crates. If the user didn't
-// provide it we will throw it in anyway with a default value.
-fn synthesize_crate_attrs(ecx: &EncodeContext,
-                          krate: &Crate) -> Vec<Attribute> {
-
-    fn synthesize_crateid_attr(ecx: &EncodeContext) -> Attribute {
-        assert!(!ecx.link_meta.crateid.name.is_empty());
-
-        attr::mk_attr_inner(attr::mk_attr_id(),
-            attr::mk_name_value_item_str(
-                InternedString::new("crate_id"),
-                token::intern_and_get_ident(ecx.link_meta
-                                               .crateid
-                                               .to_str()
-                                               .as_slice())))
-    }
-
-    let mut attrs = Vec::new();
-    for attr in krate.attrs.iter() {
-        if !attr.check_name("crate_id") {
-            attrs.push(*attr);
-        }
-    }
-    attrs.push(synthesize_crateid_attr(ecx));
-
-    attrs
-}
-
 fn encode_crate_deps(ebml_w: &mut Encoder, cstore: &cstore::CStore) {
     fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<decoder::CrateDep> {
         // Pull the cnums and name,vers,hash out of cstore
@@ -1530,8 +1486,8 @@ fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<decoder::CrateDep> {
         cstore.iter_crate_data(|key, val| {
             let dep = decoder::CrateDep {
                 cnum: key,
-                crate_id: decoder::get_crate_id(val.data()),
-                hash: decoder::get_crate_hash(val.data())
+                name: decoder::get_crate_name(val.data()),
+                hash: decoder::get_crate_hash(val.data()),
             };
             deps.push(dep);
         });
@@ -1724,12 +1680,12 @@ fn encode_misc_info(ecx: &EncodeContext,
     ebml_w.start_tag(tag_misc_info_crate_items);
     for &item in krate.module.items.iter() {
         ebml_w.start_tag(tag_mod_child);
-        ebml_w.wr_str(def_to_str(local_def(item.id)).as_slice());
+        ebml_w.wr_str(def_to_string(local_def(item.id)).as_slice());
         ebml_w.end_tag();
 
         each_auxiliary_node_id(item, |auxiliary_node_id| {
             ebml_w.start_tag(tag_mod_child);
-            ebml_w.wr_str(def_to_str(local_def(
+            ebml_w.wr_str(def_to_string(local_def(
                         auxiliary_node_id)).as_slice());
             ebml_w.end_tag();
             true
@@ -1766,8 +1722,8 @@ fn encode_reachable_extern_fns(ecx: &EncodeContext, ebml_w: &mut Encoder) {
 fn encode_crate_dep(ebml_w: &mut Encoder,
                     dep: decoder::CrateDep) {
     ebml_w.start_tag(tag_crate_dep);
-    ebml_w.start_tag(tag_crate_dep_crateid);
-    ebml_w.writer.write(dep.crate_id.to_str().as_bytes());
+    ebml_w.start_tag(tag_crate_dep_crate_name);
+    ebml_w.writer.write(dep.name.as_bytes());
     ebml_w.end_tag();
     ebml_w.start_tag(tag_crate_dep_hash);
     ebml_w.writer.write(dep.hash.as_str().as_bytes());
@@ -1781,9 +1737,9 @@ fn encode_hash(ebml_w: &mut Encoder, hash: &Svh) {
     ebml_w.end_tag();
 }
 
-fn encode_crate_id(ebml_w: &mut Encoder, crate_id: &CrateId) {
-    ebml_w.start_tag(tag_crate_crateid);
-    ebml_w.writer.write(crate_id.to_str().as_bytes());
+fn encode_crate_name(ebml_w: &mut Encoder, crate_name: &str) {
+    ebml_w.start_tag(tag_crate_crate_name);
+    ebml_w.writer.write(crate_name.as_bytes());
     ebml_w.end_tag();
 }
 
@@ -1880,7 +1836,7 @@ struct Stats {
 
     let mut ebml_w = writer::Encoder::new(wr);
 
-    encode_crate_id(&mut ebml_w, &ecx.link_meta.crateid);
+    encode_crate_name(&mut ebml_w, ecx.link_meta.crate_name.as_slice());
     encode_crate_triple(&mut ebml_w,
                         tcx.sess
                            .targ_cfg
@@ -1891,8 +1847,7 @@ struct Stats {
     encode_dylib_dependency_formats(&mut ebml_w, &ecx);
 
     let mut i = ebml_w.writer.tell().unwrap();
-    let crate_attrs = synthesize_crate_attrs(&ecx, krate);
-    encode_attributes(&mut ebml_w, crate_attrs.as_slice());
+    encode_attributes(&mut ebml_w, krate.attrs.as_slice());
     stats.attr_bytes = ebml_w.writer.tell().unwrap() - i;
 
     i = ebml_w.writer.tell().unwrap();
@@ -1971,7 +1926,7 @@ pub fn encoded_ty(tcx: &ty::ctxt, t: ty::t) -> String {
     let mut wr = MemWriter::new();
     tyencode::enc_ty(&mut wr, &tyencode::ctxt {
         diag: tcx.sess.diagnostic(),
-        ds: def_to_str,
+        ds: def_to_string,
         tcx: tcx,
         abbrevs: &RefCell::new(HashMap::new())
     }, t);
index ccab76ca6f012d641250ceaa8f369e953a793ff1..1b2349a271ed1a6ed6b776b597d83af09388b08a 100644 (file)
@@ -9,6 +9,208 @@
 // except according to those terms.
 
 //! Finds crate binaries and loads their metadata
+//!
+//! Might I be the first to welcome you to a world of platform differences,
+//! version requirements, dependency graphs, conficting desires, and fun! This
+//! is the major guts (along with metadata::creader) of the compiler for loading
+//! crates and resolving dependencies. Let's take a tour!
+//!
+//! # The problem
+//!
+//! Each invocation of the compiler is immediately concerned with one primary
+//! problem, to connect a set of crates to resolved crates on the filesystem.
+//! Concretely speaking, the compiler follows roughly these steps to get here:
+//!
+//! 1. Discover a set of `extern crate` statements.
+//! 2. Transform these directives into crate names. If the directive does not
+//!    have an explicit name, then the identifier is the name.
+//! 3. For each of these crate names, find a corresponding crate on the
+//!    filesystem.
+//!
+//! Sounds easy, right? Let's walk into some of the nuances.
+//!
+//! ## Transitive Dependencies
+//!
+//! Let's say we've got three crates: A, B, and C. A depends on B, and B depends
+//! on C. When we're compiling A, we primarily need to find and locate B, but we
+//! also end up needing to find and locate C as well.
+//!
+//! The reason for this is that any of B's types could be composed of C's types,
+//! any function in B could return a type from C, etc. To be able to guarantee
+//! that we can always typecheck/translate any function, we have to have
+//! complete knowledge of the whole ecosystem, not just our immediate
+//! dependencies.
+//!
+//! So now as part of the "find a corresponding crate on the filesystem" step
+//! above, this involves also finding all crates for *all upstream
+//! dependencies*. This includes all dependencies transitively.
+//!
+//! ## Rlibs and Dylibs
+//!
+//! The compiler has two forms of intermediate dependencies. These are dubbed
+//! rlibs and dylibs for the static and dynamic variants, respectively. An rlib
+//! is a rustc-defined file format (currently just an ar archive) while a dylib
+//! is a platform-defined dynamic library. Each library has a metadata somewhere
+//! inside of it.
+//!
+//! When translating a crate name to a crate on the filesystem, we all of a
+//! sudden need to take into account both rlibs and dylibs! Linkage later on may
+//! use either one of these files, as each has their pros/cons. The job of crate
+//! loading is to discover what's possible by finding all candidates.
+//!
+//! Most parts of this loading systems keep the dylib/rlib as just separate
+//! variables.
+//!
+//! ## Where to look?
+//!
+//! We can't exactly scan your whole hard drive when looking for dependencies,
+//! so we need to places to look. Currently the compiler will implicitly add the
+//! target lib search path ($prefix/lib/rustlib/$target/lib) to any compilation,
+//! and otherwise all -L flags are added to the search paths.
+//!
+//! ## What criterion to select on?
+//!
+//! This a pretty tricky area of loading crates. Given a file, how do we know
+//! whether it's the right crate? Currently, the rules look along these lines:
+//!
+//! 1. Does the filename match an rlib/dylib pattern? That is to say, does the
+//!    filename have the right prefix/suffix?
+//! 2. Does the filename have the right prefix for the crate name being queried?
+//!    This is filtering for files like `libfoo*.rlib` and such.
+//! 3. Is the file an actual rust library? This is done by loading the metadata
+//!    from the library and making sure it's actually there.
+//! 4. Does the name in the metadata agree with the name of the library?
+//! 5. Does the target in the metadata agree with the current target?
+//! 6. Does the SVH match? (more on this later)
+//!
+//! If the file answeres `yes` to all these questions, then the file is
+//! considered as being *candidate* for being accepted. It is illegal to have
+//! more than two candidates as the compiler has no method by which to resolve
+//! this conflict. Additionally, rlib/dylib candidates are considered
+//! separately.
+//!
+//! After all this has happened, we have 1 or two files as candidates. These
+//! represent the rlib/dylib file found for a library, and they're returned as
+//! being found.
+//!
+//! ### What about versions?
+//!
+//! A lot of effort has been put forth to remove versioning from the compiler.
+//! There have been forays in the past to have versioning baked in, but it was
+//! largely always deemed insufficient to the point that it was recognized that
+//! it's probably something the compiler shouldn't do anyway due to its
+//! complicated nature and the state of the half-baked solutions.
+//!
+//! With a departure from versioning, the primary criterion for loading crates
+//! is just the name of a crate. If we stopped here, it would imply that you
+//! could never link two crates of the same name from different sources
+//! together, which is clearly a bad state to be in.
+//!
+//! To resolve this problem, we come to the next section!
+//!
+//! # Expert Mode
+//!
+//! A number of flags have been added to the compiler to solve the "version
+//! problem" in the previous section, as well as generally enabling more
+//! powerful usage of the crate loading system of the compiler. The goal of
+//! these flags and options are to enable third-party tools to drive the
+//! compiler with prior knowledge about how the world should look.
+//!
+//! ## The `--extern` flag
+//!
+//! The compiler accepts a flag of this form a number of times:
+//!
+//! ```notrust
+//! --extern crate-name=path/to/the/crate.rlib
+//! ```
+//!
+//! This flag is basically the following letter to the compiler:
+//!
+//! > Dear rustc,
+//! >
+//! > When you are attempting to load the immediate dependency `crate-name`, I
+//! > would like you too assume that the library is located at
+//! > `path/to/the/crate.rlib`, and look nowhere else. Also, please do not
+//! > assume that the path I specified has the name `crate-name`.
+//!
+//! This flag basically overrides most matching logic except for validating that
+//! the file is indeed a rust library. The same `crate-name` can be specified
+//! twice to specify the rlib/dylib pair.
+//!
+//! ## Enabling "multiple versions"
+//!
+//! This basically boils down to the ability to specify arbitrary packages to
+//! the compiler. For example, if crate A wanted to use Bv1 and Bv2, then it
+//! would look something like:
+//!
+//! ```ignore
+//! extern crate b1;
+//! extern crate b2;
+//!
+//! fn main() {}
+//! ```
+//!
+//! and the compiler would be invoked as:
+//!
+//! ```notrust
+//! rustc a.rs --extern b1=path/to/libb1.rlib --extern b2=path/to/libb2.rlib
+//! ```
+//!
+//! In this scenario there are two crates named `b` and the compiler must be
+//! manually driven to be informed where each crate is.
+//!
+//! ## Frobbing symbols
+//!
+//! One of the immediate problems with linking the same library together twice
+//! in the same problem is dealing with duplicate symbols. The primary way to
+//! deal with this in rustc is to add hashes to the end of each symbol.
+//!
+//! In order to force hashes to change between versions of a library, if
+//! desired, the compiler exposes an option `-C metadata=foo`, which is used to
+//! initially seed each symbol hash. The string `foo` is prepended to each
+//! string-to-hash to ensure that symbols change over time.
+//!
+//! ## Loading transitive dependencies
+//!
+//! Dealing with same-named-but-distinct crates is not just a local problem, but
+//! one that also needs to be dealt with for transitive dependences. Note that
+//! in the letter above `--extern` flags only apply to the *local* set of
+//! dependencies, not the upstream transitive dependencies. Consider this
+//! dependency graph:
+//!
+//! ```notrust
+//! A.1   A.2
+//! |     |
+//! |     |
+//! B     C
+//!  \   /
+//!   \ /
+//!    D
+//! ```
+//!
+//! In this scenario, when we compile `D`, we need to be able to distinctly
+//! resolve `A.1` and `A.2`, but an `--extern` flag cannot apply to these
+//! transitive dependencies.
+//!
+//! Note that the key idea here is that `B` and `C` are both *already compiled*.
+//! That is, they have already resolved their dependencies. Due to unrelated
+//! technical reasons, when a library is compiled, it is only compatible with
+//! the *exact same* version of the upstream libraries it was compiled against.
+//! We use the "Strict Version Hash" to identify the exact copy of an upstream
+//! library.
+//!
+//! With this knowledge, we know that `B` and `C` will depend on `A` with
+//! different SVH values, so we crawl the normal `-L` paths looking for
+//! `liba*.rlib` and filter based on the contained SVH.
+//!
+//! In the end, this ends up not needing `--extern` to specify upstream
+//! transitive dependencies.
+//!
+//! # Wrapping up
+//!
+//! That's the general overview of loading crates in the compiler, but it's by
+//! no means all of the necessary details. Take a look at the rest of
+//! metadata::loader or metadata::creader for all the juicy details!
 
 use back::archive::{ArchiveRO, METADATA_FILENAME};
 use back::svh::Svh;
 use syntax::abi;
 use syntax::codemap::Span;
 use syntax::diagnostic::SpanHandler;
-use syntax::crateid::CrateId;
-use syntax::attr::AttrMetaMethods;
 use util::fs;
 
 use std::c_str::ToCStr;
@@ -61,8 +261,7 @@ pub struct Context<'a> {
     pub sess: &'a Session,
     pub span: Span,
     pub ident: &'a str,
-    pub crate_id: &'a CrateId,
-    pub id_hash: &'a str,
+    pub crate_name: &'a str,
     pub hash: Option<&'a Svh>,
     pub triple: &'a str,
     pub os: abi::Os,
@@ -70,6 +269,7 @@ pub struct Context<'a> {
     pub root: &'a Option<CratePaths>,
     pub rejected_via_hash: Vec<CrateMismatch>,
     pub rejected_via_triple: Vec<CrateMismatch>,
+    pub should_match_name: bool,
 }
 
 pub struct Library {
@@ -167,19 +367,30 @@ pub fn report_load_errs(&mut self) {
     }
 
     fn find_library_crate(&mut self) -> Option<Library> {
+        // If an SVH is specified, then this is a transitive dependency that
+        // must be loaded via -L plus some filtering.
+        if self.hash.is_none() {
+            self.should_match_name = false;
+            match self.find_commandline_library() {
+                Some(l) => return Some(l),
+                None => {}
+            }
+            self.should_match_name = true;
+        }
+
         let dypair = self.dylibname();
 
         // want: crate_name.dir_part() + prefix + crate_name.file_part + "-"
         let dylib_prefix = dypair.map(|(prefix, _)| {
-            format!("{}{}-", prefix, self.crate_id.name)
+            format!("{}{}", prefix, self.crate_name)
         });
-        let rlib_prefix = format!("lib{}-", self.crate_id.name);
+        let rlib_prefix = format!("lib{}", self.crate_name);
 
         let mut candidates = HashMap::new();
 
         // First, find all possible candidate rlibs and dylibs purely based on
         // the name of the files themselves. We're trying to match against an
-        // exact crate_id and a possibly an exact hash.
+        // exact crate name and a possibly an exact hash.
         //
         // During this step, we can filter all found libraries based on the
         // name and id found in the crate id (we ignore the path portion for
@@ -195,49 +406,32 @@ fn find_library_crate(&mut self) -> Option<Library> {
                 None => return FileDoesntMatch,
                 Some(file) => file,
             };
-            if file.starts_with(rlib_prefix.as_slice()) &&
+            let (hash, rlib) = if file.starts_with(rlib_prefix.as_slice()) &&
                     file.ends_with(".rlib") {
-                info!("rlib candidate: {}", path.display());
-                match self.try_match(file, rlib_prefix.as_slice(), ".rlib") {
-                    Some(hash) => {
-                        info!("rlib accepted, hash: {}", hash);
-                        let slot = candidates.find_or_insert_with(hash, |_| {
-                            (HashSet::new(), HashSet::new())
-                        });
-                        let (ref mut rlibs, _) = *slot;
-                        rlibs.insert(fs::realpath(path).unwrap());
-                        FileMatches
-                    }
-                    None => {
-                        info!("rlib rejected");
-                        FileDoesntMatch
-                    }
-                }
+                (file.slice(rlib_prefix.len(), file.len() - ".rlib".len()),
+                 true)
             } else if dypair.map_or(false, |(_, suffix)| {
                 file.starts_with(dylib_prefix.get_ref().as_slice()) &&
                 file.ends_with(suffix)
             }) {
                 let (_, suffix) = dypair.unwrap();
                 let dylib_prefix = dylib_prefix.get_ref().as_slice();
-                info!("dylib candidate: {}", path.display());
-                match self.try_match(file, dylib_prefix, suffix) {
-                    Some(hash) => {
-                        info!("dylib accepted, hash: {}", hash);
-                        let slot = candidates.find_or_insert_with(hash, |_| {
-                            (HashSet::new(), HashSet::new())
-                        });
-                        let (_, ref mut dylibs) = *slot;
-                        dylibs.insert(fs::realpath(path).unwrap());
-                        FileMatches
-                    }
-                    None => {
-                        info!("dylib rejected");
-                        FileDoesntMatch
-                    }
-                }
+                (file.slice(dylib_prefix.len(), file.len() - suffix.len()),
+                 false)
             } else {
-                FileDoesntMatch
+                return FileDoesntMatch
+            };
+            info!("lib candidate: {}", path.display());
+            let slot = candidates.find_or_insert_with(hash.to_string(), |_| {
+                (HashSet::new(), HashSet::new())
+            });
+            let (ref mut rlibs, ref mut dylibs) = *slot;
+            if rlib {
+                rlibs.insert(fs::realpath(path).unwrap());
+            } else {
+                dylibs.insert(fs::realpath(path).unwrap());
             }
+            FileMatches
         });
 
         // We have now collected all known libraries into a set of candidates
@@ -274,7 +468,7 @@ fn find_library_crate(&mut self) -> Option<Library> {
             _ => {
                 self.sess.span_err(self.span,
                     format!("multiple matching crates for `{}`",
-                            self.crate_id.name).as_slice());
+                            self.crate_name).as_slice());
                 self.sess.note("candidates:");
                 for lib in libraries.iter() {
                     match lib.dylib {
@@ -292,50 +486,14 @@ fn find_library_crate(&mut self) -> Option<Library> {
                         None => {}
                     }
                     let data = lib.metadata.as_slice();
-                    let crate_id = decoder::get_crate_id(data);
-                    note_crateid_attr(self.sess.diagnostic(), &crate_id);
+                    let name = decoder::get_crate_name(data);
+                    note_crate_name(self.sess.diagnostic(), name.as_slice());
                 }
                 None
             }
         }
     }
 
-    // Attempts to match the requested version of a library against the file
-    // specified. The prefix/suffix are specified (disambiguates between
-    // rlib/dylib).
-    //
-    // The return value is `None` if `file` doesn't look like a rust-generated
-    // library, or if a specific version was requested and it doesn't match the
-    // apparent file's version.
-    //
-    // If everything checks out, then `Some(hash)` is returned where `hash` is
-    // the listed hash in the filename itself.
-    fn try_match(&self, file: &str, prefix: &str, suffix: &str) -> Option<String>{
-        let middle = file.slice(prefix.len(), file.len() - suffix.len());
-        debug!("matching -- {}, middle: {}", file, middle);
-        let mut parts = middle.splitn('-', 1);
-        let hash = match parts.next() { Some(h) => h, None => return None };
-        debug!("matching -- {}, hash: {} (want {})", file, hash, self.id_hash);
-        let vers = match parts.next() { Some(v) => v, None => return None };
-        debug!("matching -- {}, vers: {} (want {})", file, vers,
-               self.crate_id.version);
-        match self.crate_id.version {
-            Some(ref version) if version.as_slice() != vers => return None,
-            Some(..) => {} // check the hash
-
-            // hash is irrelevant, no version specified
-            None => return Some(hash.to_string())
-        }
-        debug!("matching -- {}, vers ok", file);
-        // hashes in filenames are prefixes of the "true hash"
-        if self.id_hash == hash.as_slice() {
-            debug!("matching -- {}, hash ok", file);
-            Some(hash.to_string())
-        } else {
-            None
-        }
-    }
-
     // Attempts to extract *one* library from the set `m`. If the set has no
     // elements, `None` is returned. If the set has more than one element, then
     // the errors and notes are emitted about the set of libraries.
@@ -382,7 +540,7 @@ fn extract_one(&mut self, m: HashSet<Path>, flavor: &str,
                                    format!("multiple {} candidates for `{}` \
                                             found",
                                            flavor,
-                                           self.crate_id.name).as_slice());
+                                           self.crate_name).as_slice());
                 self.sess.span_note(self.span,
                                     format!(r"candidate #1: {}",
                                             ret.get_ref()
@@ -404,9 +562,11 @@ fn extract_one(&mut self, m: HashSet<Path>, flavor: &str,
     }
 
     fn crate_matches(&mut self, crate_data: &[u8], libpath: &Path) -> bool {
-        match decoder::maybe_get_crate_id(crate_data) {
-            Some(ref id) if self.crate_id.matches(id) => {}
-            _ => { info!("Rejecting via crate_id"); return false }
+        if self.should_match_name {
+            match decoder::maybe_get_crate_name(crate_data) {
+                Some(ref name) if self.crate_name == name.as_slice() => {}
+                _ => { info!("Rejecting via crate name"); return false }
+            }
         }
         let hash = match decoder::maybe_get_crate_hash(crate_data) {
             Some(hash) => hash, None => {
@@ -415,7 +575,10 @@ fn crate_matches(&mut self, crate_data: &[u8], libpath: &Path) -> bool {
             }
         };
 
-        let triple = decoder::get_crate_triple(crate_data);
+        let triple = match decoder::get_crate_triple(crate_data) {
+            None => { debug!("triple not present"); return false }
+            Some(t) => t,
+        };
         if triple.as_slice() != self.triple {
             info!("Rejecting via crate triple: expected {} got {}", self.triple, triple);
             self.rejected_via_triple.push(CrateMismatch {
@@ -456,10 +619,72 @@ fn dylibname(&self) -> Option<(&'static str, &'static str)> {
         }
     }
 
+    fn find_commandline_library(&mut self) -> Option<Library> {
+        let locs = match self.sess.opts.externs.find_equiv(&self.crate_name) {
+            Some(s) => s,
+            None => return None,
+        };
+
+        // First, filter out all libraries that look suspicious. We only accept
+        // files which actually exist that have the correct naming scheme for
+        // rlibs/dylibs.
+        let sess = self.sess;
+        let dylibname = self.dylibname();
+        let mut locs = locs.iter().map(|l| Path::new(l.as_slice())).filter(|loc| {
+            if !loc.exists() {
+                sess.err(format!("extern location does not exist: {}",
+                                 loc.display()).as_slice());
+                return false;
+            }
+            let file = loc.filename_str().unwrap();
+            if file.starts_with("lib") && file.ends_with(".rlib") {
+                return true
+            } else {
+                match dylibname {
+                    Some((prefix, suffix)) => {
+                        if file.starts_with(prefix) && file.ends_with(suffix) {
+                            return true
+                        }
+                    }
+                    None => {}
+                }
+            }
+            sess.err(format!("extern location is of an unknown type: {}",
+                             loc.display()).as_slice());
+            false
+        });
+
+        // Now that we have an itertor of good candidates, make sure there's at
+        // most one rlib and at most one dylib.
+        let mut rlibs = HashSet::new();
+        let mut dylibs = HashSet::new();
+        for loc in locs {
+            if loc.filename_str().unwrap().ends_with(".rlib") {
+                rlibs.insert(loc.clone());
+            } else {
+                dylibs.insert(loc.clone());
+            }
+        }
+
+        // Extract the rlib/dylib pair.
+        let mut metadata = None;
+        let rlib = self.extract_one(rlibs, "rlib", &mut metadata);
+        let dylib = self.extract_one(dylibs, "dylib", &mut metadata);
+
+        if rlib.is_none() && dylib.is_none() { return None }
+        match metadata {
+            Some(metadata) => Some(Library {
+                dylib: dylib,
+                rlib: rlib,
+                metadata: metadata,
+            }),
+            None => None,
+        }
+    }
 }
 
-pub fn note_crateid_attr(diag: &SpanHandler, crateid: &CrateId) {
-    diag.handler().note(format!("crate_id: {}", crateid.to_str()).as_slice());
+pub fn note_crate_name(diag: &SpanHandler, name: &str) {
+    diag.handler().note(format!("crate name: {}", name).as_slice());
 }
 
 impl ArchiveMetadata {
index 1f36c3850cf4b19ddd419b3694c7ee73eba3afe6..b207543398aaa2ec6b18df2ffbb1c74a754f39a1 100644 (file)
@@ -100,7 +100,7 @@ fn enc_vec_per_param_space<T>(w: &mut MemWriter,
                               op: |&mut MemWriter, &ctxt, &T|) {
     for &space in subst::ParamSpace::all().iter() {
         mywrite!(w, "[");
-        for t in v.get_vec(space).iter() {
+        for t in v.get_slice(space).iter() {
             op(w, cx, t);
         }
         mywrite!(w, "]");
index 19e7b9329b1ff218a9f25627766706e19732b98a..11b1687dc55999163defd6f49b10f3e731c0d5a2 100644 (file)
@@ -28,7 +28,7 @@
 use middle::subst::VecPerParamSpace;
 use middle::typeck::{MethodCall, MethodCallee, MethodOrigin};
 use middle::{ty, typeck};
-use util::ppaux::ty_to_str;
+use util::ppaux::ty_to_string;
 
 use syntax::{ast, ast_map, ast_util, codemap, fold};
 use syntax::codemap::Span;
@@ -86,7 +86,7 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
         e::IIMethodRef(_, _, m) => m.id,
     };
     debug!("> Encoding inlined item: {} ({})",
-           ecx.tcx.map.path_to_str(id),
+           ecx.tcx.map.path_to_string(id),
            ebml_w.writer.tell());
 
     let ii = simplify_ast(ii);
@@ -99,7 +99,7 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
     ebml_w.end_tag();
 
     debug!("< Encoded inlined fn: {} ({})",
-           ecx.tcx.map.path_to_str(id),
+           ecx.tcx.map.path_to_string(id),
            ebml_w.writer.tell());
 }
 
@@ -119,7 +119,7 @@ pub fn decode_inlined_item(cdata: &cstore::crate_metadata,
         debug!("> Decoding inlined fn: {}::?",
         {
             // Do an Option dance to use the path after it is moved below.
-            let s = ast_map::path_to_str(ast_map::Values(path.iter()));
+            let s = ast_map::path_to_string(ast_map::Values(path.iter()));
             path_as_str = Some(s);
             path_as_str.as_ref().map(|x| x.as_slice())
         });
@@ -147,7 +147,7 @@ pub fn decode_inlined_item(cdata: &cstore::crate_metadata,
         match ii {
           ast::IIItem(i) => {
             debug!(">>> DECODED ITEM >>>\n{}\n<<< DECODED ITEM <<<",
-                   syntax::print::pprust::item_to_str(&*i));
+                   syntax::print::pprust::item_to_string(&*i));
           }
           _ => { }
         }
@@ -810,7 +810,7 @@ fn encode_vec_per_param_space<T>(ebml_w: &mut Encoder,
                                  v: &subst::VecPerParamSpace<T>,
                                  f: |&mut Encoder, &T|) {
     for &space in subst::ParamSpace::all().iter() {
-        ebml_w.emit_from_vec(v.get_vec(space).as_slice(),
+        ebml_w.emit_from_vec(v.get_slice(space),
                              |ebml_w, n| Ok(f(ebml_w, n))).unwrap();
     }
 }
@@ -826,7 +826,7 @@ impl<'a> get_ty_str_ctxt for e::EncodeContext<'a> {
     fn ty_str_ctxt<'a>(&'a self) -> tyencode::ctxt<'a> {
         tyencode::ctxt {
             diag: self.tcx.sess.diagnostic(),
-            ds: e::def_to_str,
+            ds: e::def_to_string,
             tcx: self.tcx,
             abbrevs: &self.type_abbrevs
         }
@@ -1391,7 +1391,7 @@ fn decode_side_tables(xcx: &ExtendedDecodeContext,
                     c::tag_table_node_type => {
                         let ty = val_dsr.read_ty(xcx);
                         debug!("inserting ty for node {:?}: {}",
-                               id, ty_to_str(dcx.tcx, ty));
+                               id, ty_to_string(dcx.tcx, ty));
                         dcx.tcx.node_types.borrow_mut().insert(id as uint, ty);
                     }
                     c::tag_table_item_subst => {
@@ -1561,7 +1561,7 @@ fn new_int_alist<B>() -> alist<int, B> {
     ).unwrap());
     match (item_out, item_exp) {
       (ast::IIItem(item_out), ast::IIItem(item_exp)) => {
-        assert!(pprust::item_to_str(item_out) == pprust::item_to_str(item_exp));
+        assert!(pprust::item_to_string(item_out) == pprust::item_to_string(item_exp));
       }
       _ => fail!()
     }
index df208b9cdc133f85f352a0a3a60dec63e8433968..db8ab8c83fbdc78ae18f20bdb60d96bb08ae431a 100644 (file)
@@ -351,7 +351,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                 "it".to_string()
             } else {
                 format!("`{}`",
-                        self.bccx.loan_path_to_str(&*old_loan.loan_path))
+                        self.bccx.loan_path_to_string(&*old_loan.loan_path))
             };
 
             match (new_loan.kind, old_loan.kind) {
@@ -360,7 +360,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                         new_loan.span,
                         format!("cannot borrow `{}` as mutable \
                                 more than once at a time",
-                                self.bccx.loan_path_to_str(
+                                self.bccx.loan_path_to_string(
                                     &*new_loan.loan_path)).as_slice());
                 }
 
@@ -369,7 +369,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                         new_loan.span,
                         format!("closure requires unique access to `{}` \
                                 but {} is already borrowed",
-                                self.bccx.loan_path_to_str(&*new_loan.loan_path),
+                                self.bccx.loan_path_to_string(&*new_loan.loan_path),
                                 old_pronoun).as_slice());
                 }
 
@@ -378,7 +378,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                         new_loan.span,
                         format!("cannot borrow `{}` as {} because \
                                 previous closure requires unique access",
-                                self.bccx.loan_path_to_str(&*new_loan.loan_path),
+                                self.bccx.loan_path_to_string(&*new_loan.loan_path),
                                 new_loan.kind.to_user_str()).as_slice());
                 }
 
@@ -387,7 +387,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                         new_loan.span,
                         format!("cannot borrow `{}` as {} because \
                                 {} is also borrowed as {}",
-                                self.bccx.loan_path_to_str(&*new_loan.loan_path),
+                                self.bccx.loan_path_to_string(&*new_loan.loan_path),
                                 new_loan.kind.to_user_str(),
                                 old_pronoun,
                                 old_loan.kind.to_user_str()).as_slice());
@@ -399,7 +399,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                     self.bccx.span_note(
                         span,
                         format!("borrow occurs due to use of `{}` in closure",
-                                self.bccx.loan_path_to_str(
+                                self.bccx.loan_path_to_string(
                                     &*new_loan.loan_path)).as_slice());
                 }
                 _ => { }
@@ -410,7 +410,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                     format!("the mutable borrow prevents subsequent \
                             moves, borrows, or modification of `{0}` \
                             until the borrow ends",
-                            self.bccx.loan_path_to_str(
+                            self.bccx.loan_path_to_string(
                                 &*old_loan.loan_path))
                 }
 
@@ -418,14 +418,14 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                     format!("the immutable borrow prevents subsequent \
                             moves or mutable borrows of `{0}` \
                             until the borrow ends",
-                            self.bccx.loan_path_to_str(&*old_loan.loan_path))
+                            self.bccx.loan_path_to_string(&*old_loan.loan_path))
                 }
 
                 ty::UniqueImmBorrow => {
                     format!("the unique capture prevents subsequent \
                             moves or borrows of `{0}` \
                             until the borrow ends",
-                            self.bccx.loan_path_to_str(&*old_loan.loan_path))
+                            self.bccx.loan_path_to_string(&*old_loan.loan_path))
                 }
             };
 
@@ -433,7 +433,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                 euv::ClosureCapture(_) => {
                     format!("previous borrow of `{}` occurs here due to \
                             use in closure",
-                            self.bccx.loan_path_to_str(&*old_loan.loan_path))
+                            self.bccx.loan_path_to_string(&*old_loan.loan_path))
                 }
 
                 euv::OverloadedOperator(..) |
@@ -442,7 +442,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                 euv::ClosureInvocation(..) |
                 euv::RefBinding(..) => {
                     format!("previous borrow of `{}` occurs here",
-                            self.bccx.loan_path_to_str(&*old_loan.loan_path))
+                            self.bccx.loan_path_to_string(&*old_loan.loan_path))
                 }
             };
 
@@ -518,12 +518,12 @@ fn check_for_copy_of_frozen_path(&self,
                 self.bccx.span_err(
                     span,
                     format!("cannot use `{}` because it was mutably borrowed",
-                            self.bccx.loan_path_to_str(copy_path).as_slice())
+                            self.bccx.loan_path_to_string(copy_path).as_slice())
                     .as_slice());
                 self.bccx.span_note(
                     loan_span,
                     format!("borrow of `{}` occurs here",
-                            self.bccx.loan_path_to_str(&*loan_path).as_slice())
+                            self.bccx.loan_path_to_string(&*loan_path).as_slice())
                     .as_slice());
             }
         }
@@ -543,19 +543,19 @@ fn check_for_move_of_borrowed_path(&self,
                 let err_message = match move_kind {
                     move_data::Captured =>
                         format!("cannot move `{}` into closure because it is borrowed",
-                                self.bccx.loan_path_to_str(move_path).as_slice()),
+                                self.bccx.loan_path_to_string(move_path).as_slice()),
                     move_data::Declared |
                     move_data::MoveExpr |
                     move_data::MovePat =>
                         format!("cannot move out of `{}` because it is borrowed",
-                                self.bccx.loan_path_to_str(move_path).as_slice())
+                                self.bccx.loan_path_to_string(move_path).as_slice())
                 };
 
                 self.bccx.span_err(span, err_message.as_slice());
                 self.bccx.span_note(
                     loan_span,
                     format!("borrow of `{}` occurs here",
-                            self.bccx.loan_path_to_str(&*loan_path).as_slice())
+                            self.bccx.loan_path_to_string(&*loan_path).as_slice())
                     .as_slice());
             }
         }
@@ -567,7 +567,7 @@ pub fn analyze_restrictions_on_use(&self,
                                        borrow_kind: ty::BorrowKind)
                                        -> UseError {
         debug!("analyze_restrictions_on_use(expr_id={:?}, use_path={})",
-               self.tcx().map.node_to_str(expr_id),
+               self.tcx().map.node_to_string(expr_id),
                use_path.repr(self.tcx()));
 
         let mut ret = UseOk;
@@ -690,15 +690,15 @@ fn check_assignment(&self,
                     assignment_span,
                     format!("cannot assign to {} {} `{}`",
                             assignee_cmt.mutbl.to_user_str(),
-                            self.bccx.cmt_to_str(&*assignee_cmt),
-                            self.bccx.loan_path_to_str(&*lp)).as_slice());
+                            self.bccx.cmt_to_string(&*assignee_cmt),
+                            self.bccx.loan_path_to_string(&*lp)).as_slice());
             }
             None => {
                 self.bccx.span_err(
                     assignment_span,
                     format!("cannot assign to {} {}",
                             assignee_cmt.mutbl.to_user_str(),
-                            self.bccx.cmt_to_str(&*assignee_cmt)).as_slice());
+                            self.bccx.cmt_to_string(&*assignee_cmt)).as_slice());
             }
         }
         return;
@@ -824,10 +824,10 @@ pub fn report_illegal_mutation(&self,
         self.bccx.span_err(
             span,
             format!("cannot assign to `{}` because it is borrowed",
-                    self.bccx.loan_path_to_str(loan_path)).as_slice());
+                    self.bccx.loan_path_to_string(loan_path)).as_slice());
         self.bccx.span_note(
             loan.span,
             format!("borrow of `{}` occurs here",
-                    self.bccx.loan_path_to_str(loan_path)).as_slice());
+                    self.bccx.loan_path_to_string(loan_path)).as_slice());
     }
 }
index f5c91f7b1b3bf4441e664ff0fd479486864b6d22..9876e12d5ccac539efb1d03ff7ba34ae4ad00cb8 100644 (file)
@@ -120,7 +120,7 @@ fn report_cannot_move_out_of(bccx: &BorrowckCtxt, move_from: mc::cmt) {
             bccx.span_err(
                 move_from.span,
                 format!("cannot move out of {}",
-                        bccx.cmt_to_str(&*move_from)).as_slice());
+                        bccx.cmt_to_string(&*move_from)).as_slice());
         }
 
         mc::cat_downcast(ref b) |
@@ -145,7 +145,7 @@ fn note_move_destination(bccx: &BorrowckCtxt,
                          move_to_span: codemap::Span,
                          pat_ident: &ast::Ident,
                          is_first_note: bool) {
-    let pat_name = pprust::ident_to_str(pat_ident);
+    let pat_name = pprust::ident_to_string(pat_ident);
     if is_first_note {
         bccx.span_note(
             move_to_span,
index 9ab3202b9096e5733d084b7a953c568e6b1250a7..426a1fbede56b7fb9dca84c9f5e033e7fc9b95df 100644 (file)
@@ -418,7 +418,7 @@ pub fn cat_pattern(&self,
     pub fn report(&self, err: BckError) {
         self.span_err(
             err.span,
-            self.bckerr_to_str(&err).as_slice());
+            self.bckerr_to_string(&err).as_slice());
         self.note_and_explain_bckerr(err);
     }
 
@@ -439,7 +439,7 @@ pub fn report_use_of_moved_value(&self,
                     use_span,
                     format!("{} of possibly uninitialized variable: `{}`",
                             verb,
-                            self.loan_path_to_str(lp)).as_slice());
+                            self.loan_path_to_string(lp)).as_slice());
             }
             _ => {
                 let partially = if lp == moved_lp {""} else {"partially "};
@@ -448,7 +448,7 @@ pub fn report_use_of_moved_value(&self,
                     format!("{} of {}moved value: `{}`",
                             verb,
                             partially,
-                            self.loan_path_to_str(lp)).as_slice());
+                            self.loan_path_to_string(lp)).as_slice());
             }
         }
 
@@ -472,7 +472,7 @@ pub fn report_use_of_moved_value(&self,
                 self.tcx.sess.span_note(
                     expr_span,
                     format!("`{}` moved here because it has type `{}`, which is {}",
-                            self.loan_path_to_str(moved_lp),
+                            self.loan_path_to_string(moved_lp),
                             expr_ty.user_string(self.tcx),
                             suggestion).as_slice());
             }
@@ -483,7 +483,7 @@ pub fn report_use_of_moved_value(&self,
                     format!("`{}` moved here because it has type `{}`, \
                              which is moved by default (use `ref` to \
                              override)",
-                            self.loan_path_to_str(moved_lp),
+                            self.loan_path_to_string(moved_lp),
                             pat_ty.user_string(self.tcx)).as_slice());
             }
 
@@ -506,7 +506,7 @@ pub fn report_use_of_moved_value(&self,
                     expr_span,
                     format!("`{}` moved into closure environment here because it \
                             has type `{}`, which is {}",
-                            self.loan_path_to_str(moved_lp),
+                            self.loan_path_to_string(moved_lp),
                             expr_ty.user_string(self.tcx),
                             suggestion).as_slice());
             }
@@ -536,7 +536,7 @@ pub fn report_reassigned_immutable_variable(&self,
         self.tcx.sess.span_err(
             span,
             format!("re-assignment of immutable variable `{}`",
-                    self.loan_path_to_str(lp)).as_slice());
+                    self.loan_path_to_string(lp)).as_slice());
         self.tcx.sess.span_note(assign.span, "prior assignment occurs here");
     }
 
@@ -552,20 +552,20 @@ pub fn span_end_note(&self, s: Span, m: &str) {
         self.tcx.sess.span_end_note(s, m);
     }
 
-    pub fn bckerr_to_str(&self, err: &BckError) -> String {
+    pub fn bckerr_to_string(&self, err: &BckError) -> String {
         match err.code {
             err_mutbl => {
                 let descr = match opt_loan_path(&err.cmt) {
                     None => {
                         format!("{} {}",
                                 err.cmt.mutbl.to_user_str(),
-                                self.cmt_to_str(&*err.cmt))
+                                self.cmt_to_string(&*err.cmt))
                     }
                     Some(lp) => {
                         format!("{} {} `{}`",
                                 err.cmt.mutbl.to_user_str(),
-                                self.cmt_to_str(&*err.cmt),
-                                self.loan_path_to_str(&*lp))
+                                self.cmt_to_string(&*err.cmt),
+                                self.loan_path_to_string(&*lp))
                     }
                 };
 
@@ -589,7 +589,7 @@ pub fn bckerr_to_str(&self, err: &BckError) -> String {
                 let msg = match opt_loan_path(&err.cmt) {
                     None => "borrowed value".to_string(),
                     Some(lp) => {
-                        format!("`{}`", self.loan_path_to_str(&*lp))
+                        format!("`{}`", self.loan_path_to_string(&*lp))
                     }
                 };
                 format!("{} does not live long enough", msg)
@@ -597,9 +597,9 @@ pub fn bckerr_to_str(&self, err: &BckError) -> String {
             err_borrowed_pointer_too_short(..) => {
                 let descr = match opt_loan_path(&err.cmt) {
                     Some(lp) => {
-                        format!("`{}`", self.loan_path_to_str(&*lp))
+                        format!("`{}`", self.loan_path_to_string(&*lp))
                     }
-                    None => self.cmt_to_str(&*err.cmt),
+                    None => self.cmt_to_string(&*err.cmt),
                 };
 
                 format!("lifetime of {} is too short to guarantee \
@@ -691,9 +691,9 @@ pub fn note_and_explain_bckerr(&self, err: BckError) {
             err_borrowed_pointer_too_short(loan_scope, ptr_scope) => {
                 let descr = match opt_loan_path(&err.cmt) {
                     Some(lp) => {
-                        format!("`{}`", self.loan_path_to_str(&*lp))
+                        format!("`{}`", self.loan_path_to_string(&*lp))
                     }
-                    None => self.cmt_to_str(&*err.cmt),
+                    None => self.cmt_to_string(&*err.cmt),
                 };
                 note_and_explain_region(
                     self.tcx,
@@ -710,7 +710,7 @@ pub fn note_and_explain_bckerr(&self, err: BckError) {
         }
     }
 
-    pub fn append_loan_path_to_str(&self,
+    pub fn append_loan_path_to_string(&self,
                                    loan_path: &LoanPath,
                                    out: &mut String) {
         match *loan_path {
@@ -720,7 +720,7 @@ pub fn append_loan_path_to_str(&self,
             }
 
             LpExtend(ref lp_base, _, LpInterior(mc::InteriorField(fname))) => {
-                self.append_autoderefd_loan_path_to_str(&**lp_base, out);
+                self.append_autoderefd_loan_path_to_string(&**lp_base, out);
                 match fname {
                     mc::NamedField(fname) => {
                         out.push_char('.');
@@ -728,24 +728,24 @@ pub fn append_loan_path_to_str(&self,
                     }
                     mc::PositionalField(idx) => {
                         out.push_char('#'); // invent a notation here
-                        out.push_str(idx.to_str().as_slice());
+                        out.push_str(idx.to_string().as_slice());
                     }
                 }
             }
 
             LpExtend(ref lp_base, _, LpInterior(mc::InteriorElement(_))) => {
-                self.append_autoderefd_loan_path_to_str(&**lp_base, out);
+                self.append_autoderefd_loan_path_to_string(&**lp_base, out);
                 out.push_str("[..]");
             }
 
             LpExtend(ref lp_base, _, LpDeref(_)) => {
                 out.push_char('*');
-                self.append_loan_path_to_str(&**lp_base, out);
+                self.append_loan_path_to_string(&**lp_base, out);
             }
         }
     }
 
-    pub fn append_autoderefd_loan_path_to_str(&self,
+    pub fn append_autoderefd_loan_path_to_string(&self,
                                               loan_path: &LoanPath,
                                               out: &mut String) {
         match *loan_path {
@@ -753,23 +753,23 @@ pub fn append_autoderefd_loan_path_to_str(&self,
                 // For a path like `(*x).f` or `(*x)[3]`, autoderef
                 // rules would normally allow users to omit the `*x`.
                 // So just serialize such paths to `x.f` or x[3]` respectively.
-                self.append_autoderefd_loan_path_to_str(&**lp_base, out)
+                self.append_autoderefd_loan_path_to_string(&**lp_base, out)
             }
 
             LpVar(..) | LpUpvar(..) | LpExtend(_, _, LpInterior(..)) => {
-                self.append_loan_path_to_str(loan_path, out)
+                self.append_loan_path_to_string(loan_path, out)
             }
         }
     }
 
-    pub fn loan_path_to_str(&self, loan_path: &LoanPath) -> String {
+    pub fn loan_path_to_string(&self, loan_path: &LoanPath) -> String {
         let mut result = String::new();
-        self.append_loan_path_to_str(loan_path, &mut result);
+        self.append_loan_path_to_string(loan_path, &mut result);
         result
     }
 
-    pub fn cmt_to_str(&self, cmt: &mc::cmt_) -> String {
-        self.mc().cmt_to_str(cmt)
+    pub fn cmt_to_string(&self, cmt: &mc::cmt_) -> String {
+        self.mc().cmt_to_string(cmt)
     }
 }
 
@@ -815,11 +815,11 @@ impl Repr for LoanPath {
     fn repr(&self, tcx: &ty::ctxt) -> String {
         match self {
             &LpVar(id) => {
-                format!("$({})", tcx.map.node_to_str(id))
+                format!("$({})", tcx.map.node_to_string(id))
             }
 
             &LpUpvar(ty::UpvarId{ var_id, closure_expr_id }) => {
-                let s = tcx.map.node_to_str(var_id);
+                let s = tcx.map.node_to_string(var_id);
                 format!("$({} captured by id={})", s, closure_expr_id)
             }
 
index c33580d869b15ea7cc7381aa8232b5f0fc6cd9d3..9f44f0babc72abfaae37bf70e1133627ee020df8 100644 (file)
@@ -64,7 +64,7 @@ fn node_label(&'a self, &(i, n): &Node<'a>) -> dot::LabelText<'a> {
         } else if n.data.id == ast::DUMMY_NODE_ID {
             dot::LabelStr("(dummy_node)".into_maybe_owned())
         } else {
-            let s = self.ast_map.node_to_str(n.data.id);
+            let s = self.ast_map.node_to_string(n.data.id);
             // left-aligns the lines
             let s = replace_newline_with_backslash_l(s);
             dot::EscStr(s.into_maybe_owned())
@@ -80,7 +80,7 @@ fn edge_label(&self, e: &Edge<'a>) -> dot::LabelText<'a> {
             } else {
                 put_one = true;
             }
-            let s = self.ast_map.node_to_str(node_id);
+            let s = self.ast_map.node_to_string(node_id);
             // left-aligns the lines
             let s = replace_newline_with_backslash_l(s);
             label = label.append(format!("exiting scope_{} {}",
index cf886702d863126f7373e17b7db64e8ac646cf8f..33bf6ceed4f2b848d9811072495d8b0d0dd47dad 100644 (file)
@@ -108,7 +108,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
                  .span_err(e.span,
                            format!("can not cast to `{}` in a constant \
                                     expression",
-                                   ppaux::ty_to_str(v.tcx, ety)).as_slice())
+                                   ppaux::ty_to_string(v.tcx, ety)).as_slice())
             }
           }
           ExprPath(ref pth) => {
index 8b5c7061a149faf4587ff9eecfd6a742ec6e5140..599f5f4024f28ab2d98c3a29156790f22a7a5e80 100644 (file)
 use syntax::ast_util::{is_unguarded, walk_pat};
 use syntax::codemap::{Span, Spanned, DUMMY_SP};
 use syntax::owned_slice::OwnedSlice;
-use syntax::print::pprust::pat_to_str;
+use syntax::print::pprust::pat_to_string;
 use syntax::visit;
 use syntax::visit::{Visitor, FnKind};
-use util::ppaux::ty_to_str;
+use util::ppaux::ty_to_string;
 
 struct Matrix(Vec<Vec<Gc<Pat>>>);
 
@@ -47,7 +47,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
         let &Matrix(ref m) = self;
         let pretty_printed_matrix: Vec<Vec<String>> = m.iter().map(|row| {
-            row.iter().map(|&pat| pat_to_str(pat)).collect::<Vec<String>>()
+            row.iter().map(|&pat| pat_to_string(pat)).collect::<Vec<String>>()
         }).collect();
 
         let column_count = m.iter().map(|row| row.len()).max().unwrap_or(0u);
@@ -147,7 +147,7 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &Expr) {
                    // We know the type is inhabited, so this must be wrong
                    cx.tcx.sess.span_err(ex.span, format!("non-exhaustive patterns: \
                                 type {} is non-empty",
-                                ty_to_str(cx.tcx, pat_ty)).as_slice());
+                                ty_to_string(cx.tcx, pat_ty)).as_slice());
                }
                // If the type *is* empty, it's vacuously exhaustive
                return;
@@ -222,7 +222,8 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, m: &Matrix) {
                 [] => wild(),
                 _ => unreachable!()
             };
-            let msg = format!("non-exhaustive patterns: `{0}` not covered", pat_to_str(&*witness));
+            let msg = format!("non-exhaustive patterns: `{0}` not covered",
+                              pat_to_string(&*witness));
             cx.tcx.sess.span_err(sp, msg.as_slice());
         }
         NotUseful => {
@@ -283,13 +284,15 @@ fn construct_witness(cx: &MatchCheckCtxt, ctor: &Constructor,
             };
             if is_structure {
                 let fields = ty::lookup_struct_fields(cx.tcx, vid);
-                let field_pats = fields.move_iter()
+                let field_pats: Vec<FieldPat> = fields.move_iter()
                     .zip(pats.iter())
+                    .filter(|&(_, pat)| pat.node != PatWild)
                     .map(|(field, pat)| FieldPat {
                         ident: Ident::new(field.name),
                         pat: pat.clone()
                     }).collect();
-                PatStruct(def_to_path(cx.tcx, vid), field_pats, false)
+                let has_more_fields = field_pats.len() < pats.len();
+                PatStruct(def_to_path(cx.tcx, vid), field_pats, has_more_fields)
             } else {
                 PatEnum(def_to_path(cx.tcx, vid), Some(pats))
             }
@@ -411,14 +414,7 @@ fn is_useful(cx: &MatchCheckCtxt, matrix @ &Matrix(ref rows): &Matrix,
         return NotUseful;
     }
     let real_pat = match rows.iter().find(|r| r.get(0).id != 0) {
-        Some(r) => {
-            match r.get(0).node {
-                // An arm of the form `ref x @ sub_pat` has type
-                // `sub_pat`, not `&sub_pat` as `x` itself does.
-                PatIdent(BindByRef(_), _, Some(sub)) => sub,
-                _ => *r.get(0)
-            }
-        }
+        Some(r) => raw_pat(*r.get(0)),
         None if v.len() == 0 => return NotUseful,
         None => v[0]
     };
@@ -563,6 +559,7 @@ pub fn constructor_arity(cx: &MatchCheckCtxt, ctor: &Constructor, ty: ty::t) ->
         ty::ty_rptr(_, ty::mt { ty: ty, .. }) => match ty::get(ty).sty {
             ty::ty_vec(_, None) => match *ctor {
                 Slice(length) => length,
+                ConstantValue(_) => 0u,
                 _ => unreachable!()
             },
             ty::ty_str => 0u,
@@ -677,8 +674,17 @@ pub fn specialize(cx: &MatchCheckCtxt, r: &[Gc<Pat>],
                 } else {
                     None
                 },
-                DefStruct(struct_id) => Some(struct_id),
-                _ => None
+                _ => {
+                    // Assume this is a struct.
+                    match ty::ty_to_def_id(node_id_to_type(cx.tcx, pat_id)) {
+                        None => {
+                            cx.tcx.sess.span_bug(pat_span,
+                                                 "struct pattern wasn't of a \
+                                                  type with a def ID?!")
+                        }
+                        Some(def_id) => Some(def_id),
+                    }
+                }
             };
             class_id.map(|variant_id| {
                 let struct_fields = ty::lookup_struct_fields(cx.tcx, variant_id);
@@ -775,7 +781,7 @@ fn check_local(cx: &mut MatchCheckCtxt, loc: &Local) {
         Some(pat) => {
             let msg = format!(
                 "refutable pattern in {} binding: `{}` not covered",
-                name, pat_to_str(&*pat)
+                name, pat_to_string(&*pat)
             );
             cx.tcx.sess.span_err(loc.pat.span, msg.as_slice());
         },
@@ -797,7 +803,7 @@ fn check_fn(cx: &mut MatchCheckCtxt,
             Some(pat) => {
                 let msg = format!(
                     "refutable pattern in function argument: `{}` not covered",
-                    pat_to_str(&*pat)
+                    pat_to_string(&*pat)
                 );
                 cx.tcx.sess.span_err(input.pat.span, msg.as_slice());
             },
index 33949ee5b1644a91855be8f450873519abcc2328..1e948afb7018fe745ffc05f1e5db7dc33291e65d 100644 (file)
@@ -75,7 +75,7 @@ fn report_error(&self, span: Span, result: Option<String>) -> bool {
 impl<'a> Visitor<bool> for CheckStaticVisitor<'a> {
 
     fn visit_item(&mut self, i: &ast::Item, _is_const: bool) {
-        debug!("visit_item(item={})", pprust::item_to_str(i));
+        debug!("visit_item(item={})", pprust::item_to_string(i));
         match i.node {
             ast::ItemStatic(_, mutability, ref expr) => {
                 match mutability {
@@ -99,7 +99,7 @@ fn visit_item(&mut self, i: &ast::Item, _is_const: bool) {
     /// of a static item, this method does nothing but walking
     /// down through it.
     fn visit_expr(&mut self, e: &ast::Expr, is_const: bool) {
-        debug!("visit_expr(expr={})", pprust::expr_to_str(e));
+        debug!("visit_expr(expr={})", pprust::expr_to_string(e));
 
         if !is_const {
             return visit::walk_expr(self, e, is_const);
index 5ac85833e221eb3ccbcb47a23c47284ba2acf603..7d9178162a65adb11de93f371623b028d93cda68 100644 (file)
@@ -164,18 +164,18 @@ fn pre(&self,
             let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
             let (start, end) = self.compute_id_range_frozen(cfgidx);
             let on_entry = self.on_entry.slice(start, end);
-            let entry_str = bits_to_str(on_entry);
+            let entry_str = bits_to_string(on_entry);
 
             let gens = self.gens.slice(start, end);
             let gens_str = if gens.iter().any(|&u| u != 0) {
-                format!(" gen: {}", bits_to_str(gens))
+                format!(" gen: {}", bits_to_string(gens))
             } else {
                 "".to_string()
             };
 
             let kills = self.kills.slice(start, end);
             let kills_str = if kills.iter().any(|&u| u != 0) {
-                format!(" kill: {}", bits_to_str(kills))
+                format!(" kill: {}", bits_to_string(kills))
             } else {
                 "".to_string()
             };
@@ -289,7 +289,7 @@ pub fn add_kill(&mut self, id: ast::NodeId, bit: uint) {
     fn apply_gen_kill(&mut self, cfgidx: CFGIndex, bits: &mut [uint]) {
         //! Applies the gen and kill sets for `id` to `bits`
         debug!("{:s} apply_gen_kill(cfgidx={}, bits={}) [before]",
-               self.analysis_name, cfgidx, mut_bits_to_str(bits));
+               self.analysis_name, cfgidx, mut_bits_to_string(bits));
         let (start, end) = self.compute_id_range(cfgidx);
         let gens = self.gens.slice(start, end);
         bitwise(bits, gens, &Union);
@@ -297,7 +297,7 @@ fn apply_gen_kill(&mut self, cfgidx: CFGIndex, bits: &mut [uint]) {
         bitwise(bits, kills, &Subtract);
 
         debug!("{:s} apply_gen_kill(cfgidx={}, bits={}) [after]",
-               self.analysis_name, cfgidx, mut_bits_to_str(bits));
+               self.analysis_name, cfgidx, mut_bits_to_string(bits));
     }
 
     fn compute_id_range_frozen(&self, cfgidx: CFGIndex) -> (uint, uint) {
@@ -334,7 +334,7 @@ pub fn each_bit_on_entry_frozen(&self,
         let (start, end) = self.compute_id_range_frozen(cfgidx);
         let on_entry = self.on_entry.slice(start, end);
         debug!("{:s} each_bit_on_entry_frozen(id={:?}, on_entry={})",
-               self.analysis_name, id, bits_to_str(on_entry));
+               self.analysis_name, id, bits_to_string(on_entry));
         self.each_bit(on_entry, f)
     }
 
@@ -348,7 +348,7 @@ pub fn each_gen_bit_frozen(&self, id: ast::NodeId, f: |uint| -> bool)
         let (start, end) = self.compute_id_range_frozen(cfgidx);
         let gens = self.gens.slice(start, end);
         debug!("{:s} each_gen_bit(id={:?}, gens={})",
-               self.analysis_name, id, bits_to_str(gens));
+               self.analysis_name, id, bits_to_string(gens));
         self.each_bit(gens, f)
     }
 
@@ -426,10 +426,10 @@ pub fn add_kills_from_flow_exits(&mut self, cfg: &cfg::CFG) {
             if changed {
                 let bits = self.kills.mut_slice(start, end);
                 debug!("{:s} add_kills_from_flow_exits flow_exit={} bits={} [before]",
-                       self.analysis_name, flow_exit, mut_bits_to_str(bits));
+                       self.analysis_name, flow_exit, mut_bits_to_string(bits));
                 bits.copy_from(orig_kills.as_slice());
                 debug!("{:s} add_kills_from_flow_exits flow_exit={} bits={} [after]",
-                       self.analysis_name, flow_exit, mut_bits_to_str(bits));
+                       self.analysis_name, flow_exit, mut_bits_to_string(bits));
             }
             true
         });
@@ -483,10 +483,10 @@ fn walk_cfg(&mut self,
                 cfg: &cfg::CFG,
                 in_out: &mut [uint]) {
         debug!("DataFlowContext::walk_cfg(in_out={}) {:s}",
-               bits_to_str(in_out), self.dfcx.analysis_name);
+               bits_to_string(in_out), self.dfcx.analysis_name);
         cfg.graph.each_node(|node_index, node| {
             debug!("DataFlowContext::walk_cfg idx={} id={} begin in_out={}",
-                   node_index, node.data.id, bits_to_str(in_out));
+                   node_index, node.data.id, bits_to_string(in_out));
 
             let (start, end) = self.dfcx.compute_id_range(node_index);
 
@@ -526,7 +526,7 @@ fn propagate_bits_into_entry_set_for(&mut self,
         let source = edge.source();
         let cfgidx = edge.target();
         debug!("{:s} propagate_bits_into_entry_set_for(pred_bits={}, {} to {})",
-               self.dfcx.analysis_name, bits_to_str(pred_bits), source, cfgidx);
+               self.dfcx.analysis_name, bits_to_string(pred_bits), source, cfgidx);
         let (start, end) = self.dfcx.compute_id_range(cfgidx);
         let changed = {
             // (scoping mutable borrow of self.dfcx.on_entry)
@@ -536,17 +536,17 @@ fn propagate_bits_into_entry_set_for(&mut self,
         if changed {
             debug!("{:s} changed entry set for {:?} to {}",
                    self.dfcx.analysis_name, cfgidx,
-                   bits_to_str(self.dfcx.on_entry.slice(start, end)));
+                   bits_to_string(self.dfcx.on_entry.slice(start, end)));
             self.changed = true;
         }
     }
 }
 
-fn mut_bits_to_str(words: &mut [uint]) -> String {
-    bits_to_str(words)
+fn mut_bits_to_string(words: &mut [uint]) -> String {
+    bits_to_string(words)
 }
 
-fn bits_to_str(words: &[uint]) -> String {
+fn bits_to_string(words: &[uint]) -> String {
     let mut result = String::new();
     let mut sep = '[';
 
@@ -582,7 +582,7 @@ fn bitwise<Op:BitwiseOperator>(out_vec: &mut [uint],
 
 fn set_bit(words: &mut [uint], bit: uint) -> bool {
     debug!("set_bit: words={} bit={}",
-           mut_bits_to_str(words), bit_str(bit));
+           mut_bits_to_string(words), bit_str(bit));
     let word = bit / uint::BITS;
     let bit_in_word = bit % uint::BITS;
     let bit_mask = 1 << bit_in_word;
index 70db3e964abb3273cc2f4d078a3c809b1c7fdad0..9ec167ee8263ef7d9db5f036d3c67e6142e22d93 100644 (file)
@@ -141,16 +141,25 @@ fn handle_field_access(&mut self, lhs: &ast::Expr, name: &ast::Ident) {
     }
 
     fn handle_field_pattern_match(&mut self, lhs: &ast::Pat, pats: &[ast::FieldPat]) {
-        match self.tcx.def_map.borrow().get(&lhs.id) {
-            &def::DefStruct(id) | &def::DefVariant(_, id, _) => {
-                let fields = ty::lookup_struct_fields(self.tcx, id);
-                for pat in pats.iter() {
-                    let field_id = fields.iter()
-                        .find(|field| field.name == pat.ident.name).unwrap().id;
-                    self.live_symbols.insert(field_id.node);
+        let id = match self.tcx.def_map.borrow().get(&lhs.id) {
+            &def::DefVariant(_, id, _) => id,
+            _ => {
+                match ty::ty_to_def_id(ty::node_id_to_type(self.tcx,
+                                                           lhs.id)) {
+                    None => {
+                        self.tcx.sess.span_bug(lhs.span,
+                                               "struct pattern wasn't of a \
+                                                type with a def ID?!")
+                    }
+                    Some(def_id) => def_id,
                 }
             }
-            _ => ()
+        };
+        let fields = ty::lookup_struct_fields(self.tcx, id);
+        for pat in pats.iter() {
+            let field_id = fields.iter()
+                .find(|field| field.name == pat.ident.name).unwrap().id;
+            self.live_symbols.insert(field_id.node);
         }
     }
 
index 2333b329996401dc20c4596fbaa68b459a18d525..782a380e23a0ecdd3aa98e2f5cbb1adf858d941d 100644 (file)
@@ -68,7 +68,7 @@ fn check_str_index(&mut self, e: &ast::Expr) {
             _ => return
         };
         debug!("effect: checking index with base type {}",
-                ppaux::ty_to_str(self.tcx, base_type));
+                ppaux::ty_to_string(self.tcx, base_type));
         match ty::get(base_type).sty {
             ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => match ty::get(ty).sty {
                 ty::ty_str => {
@@ -147,7 +147,7 @@ fn visit_expr(&mut self, expr: &ast::Expr, _:()) {
                 let method_call = MethodCall::expr(expr.id);
                 let base_type = self.tcx.method_map.borrow().get(&method_call).ty;
                 debug!("effect: method call case, base type is {}",
-                       ppaux::ty_to_str(self.tcx, base_type));
+                       ppaux::ty_to_string(self.tcx, base_type));
                 if type_is_unsafe_function(base_type) {
                     self.require_unsafe(expr.span,
                                         "invocation of unsafe method")
@@ -156,7 +156,7 @@ fn visit_expr(&mut self, expr: &ast::Expr, _:()) {
             ast::ExprCall(base, _) => {
                 let base_type = ty::node_id_to_type(self.tcx, base.id);
                 debug!("effect: call case, base type is {}",
-                       ppaux::ty_to_str(self.tcx, base_type));
+                       ppaux::ty_to_string(self.tcx, base_type));
                 if type_is_unsafe_function(base_type) {
                     self.require_unsafe(expr.span, "call to unsafe function")
                 }
@@ -164,7 +164,7 @@ fn visit_expr(&mut self, expr: &ast::Expr, _:()) {
             ast::ExprUnary(ast::UnDeref, base) => {
                 let base_type = ty::node_id_to_type(self.tcx, base.id);
                 debug!("effect: unary case, base type is {}",
-                        ppaux::ty_to_str(self.tcx, base_type));
+                        ppaux::ty_to_string(self.tcx, base_type));
                 match ty::get(base_type).sty {
                     ty::ty_ptr(_) => {
                         self.require_unsafe(expr.span,
index a7154e78bc58612d7243430bd2aa3a106be75ac1..d432ced5226cee32781cfffea24c12d9eedfa8d8 100644 (file)
 use middle::ty;
 use middle::typeck::{MethodCall, NoAdjustment};
 use middle::typeck;
-use util::ppaux::{Repr, ty_to_str};
+use util::ppaux::{Repr, ty_to_string};
 use util::ppaux::UserString;
 
 use syntax::ast::*;
 use syntax::attr;
 use syntax::codemap::Span;
-use syntax::print::pprust::{expr_to_str, ident_to_str};
+use syntax::print::pprust::{expr_to_string, ident_to_string};
 use syntax::{visit};
 use syntax::visit::Visitor;
 
@@ -126,7 +126,7 @@ fn check_impl_of_trait(cx: &mut Context, it: &Item, trait_ref: &TraitRef, self_t
         cx.tcx.sess.span_err(self_type.span,
             format!("the type `{}', which does not fulfill `{}`, cannot implement this \
                     trait",
-                    ty_to_str(cx.tcx, self_ty),
+                    ty_to_string(cx.tcx, self_ty),
                     missing.user_string(cx.tcx)).as_slice());
         cx.tcx.sess.span_note(self_type.span,
             format!("types implementing this trait must fulfill `{}`",
@@ -246,7 +246,7 @@ fn check_fn(
 }
 
 pub fn check_expr(cx: &mut Context, e: &Expr) {
-    debug!("kind::check_expr({})", expr_to_str(e));
+    debug!("kind::check_expr({})", expr_to_string(e));
 
     // Handle any kind bounds on type parameters
     check_bounds_on_type_parameters(cx, e);
@@ -492,7 +492,7 @@ pub fn check_typaram_bounds(cx: &Context,
             sp,
             format!("instantiating a type parameter with an incompatible type \
                      `{}`, which does not fulfill `{}`",
-                    ty_to_str(cx.tcx, ty),
+                    ty_to_string(cx.tcx, ty),
                     missing.user_string(cx.tcx)).as_slice());
     });
 }
@@ -509,14 +509,14 @@ pub fn check_freevar_bounds(cx: &Context, sp: Span, ty: ty::t,
                 format!("cannot implicitly borrow variable of type `{}` in a \
                          bounded stack closure (implicit reference does not \
                          fulfill `{}`)",
-                        ty_to_str(cx.tcx, rty),
+                        ty_to_string(cx.tcx, rty),
                         missing.user_string(cx.tcx)).as_slice())
             }
             None => {
                 cx.tcx.sess.span_err(sp,
                 format!("cannot capture variable of type `{}`, which does \
                          not fulfill `{}`, in a bounded closure",
-                        ty_to_str(cx.tcx, ty),
+                        ty_to_string(cx.tcx, ty),
                         missing.user_string(cx.tcx)).as_slice())
             }
         }
@@ -533,20 +533,20 @@ pub fn check_trait_cast_bounds(cx: &Context, sp: Span, ty: ty::t,
         cx.tcx.sess.span_err(sp,
             format!("cannot pack type `{}`, which does not fulfill \
                      `{}`, as a trait bounded by {}",
-                    ty_to_str(cx.tcx, ty), missing.user_string(cx.tcx),
+                    ty_to_string(cx.tcx, ty), missing.user_string(cx.tcx),
                     bounds.user_string(cx.tcx)).as_slice());
     });
 }
 
 fn check_copy(cx: &Context, ty: ty::t, sp: Span, reason: &str) {
     debug!("type_contents({})={}",
-           ty_to_str(cx.tcx, ty),
-           ty::type_contents(cx.tcx, ty).to_str());
+           ty_to_string(cx.tcx, ty),
+           ty::type_contents(cx.tcx, ty).to_string());
     if ty::type_moves_by_default(cx.tcx, ty) {
         cx.tcx.sess.span_err(
             sp,
             format!("copying a value of non-copyable type `{}`",
-                    ty_to_str(cx.tcx, ty)).as_slice());
+                    ty_to_string(cx.tcx, ty)).as_slice());
         cx.tcx.sess.span_note(sp, format!("{}", reason).as_slice());
     }
 }
@@ -558,7 +558,7 @@ pub fn check_static(tcx: &ty::ctxt, ty: ty::t, sp: Span) -> bool {
             tcx.sess.span_err(sp,
                 format!("value may contain references; \
                          add `'static` bound to `{}`",
-                        ty_to_str(tcx, ty)).as_slice());
+                        ty_to_string(tcx, ty)).as_slice());
           }
           _ => {
             tcx.sess.span_err(sp, "value may contain references");
@@ -643,7 +643,7 @@ pub fn check_cast_for_escaping_regions(
             //         source_span,
             //         format!("source contains reference with lifetime \
             //               not found in the target type `{}`",
-            //              ty_to_str(cx.tcx, target_ty)));
+            //              ty_to_string(cx.tcx, target_ty)));
             //     note_and_explain_region(
             //         cx.tcx, "source data is only valid for ", r, "");
             // }
@@ -683,7 +683,7 @@ fn check_sized(tcx: &ty::ctxt, ty: ty::t, name: String, sp: Span) {
                           format!("variable `{}` has dynamically sized type \
                                    `{}`",
                                   name,
-                                  ty_to_str(tcx, ty)).as_slice());
+                                  ty_to_string(tcx, ty)).as_slice());
     }
 }
 
@@ -691,7 +691,7 @@ fn check_sized(tcx: &ty::ctxt, ty: ty::t, name: String, sp: Span) {
 fn check_pat(cx: &mut Context, pat: &Pat) {
     let var_name = match pat.node {
         PatWild => Some("_".to_string()),
-        PatIdent(_, ref path1, _) => Some(ident_to_str(&path1.node).to_string()),
+        PatIdent(_, ref path1, _) => Some(ident_to_string(&path1.node).to_string()),
         _ => None
     };
 
@@ -702,7 +702,7 @@ fn check_pat(cx: &mut Context, pat: &Pat) {
             match ty {
                 Some(ty) => {
                     debug!("kind: checking sized-ness of variable {}: {}",
-                           name, ty_to_str(cx.tcx, *ty));
+                           name, ty_to_string(cx.tcx, *ty));
                     check_sized(cx.tcx, *ty, name, pat.span);
                 }
                 None => {} // extern fn args
index 186a737a56ba34f6cd0833d10d5894a050797f0a..1a1d47b254770bd87293fea411963c95af53abc0 100644 (file)
@@ -234,6 +234,7 @@ pub fn collect_language_items(krate: &ast::Crate,
     ShlTraitLangItem,                "shl",                     shl_trait;
     ShrTraitLangItem,                "shr",                     shr_trait;
     IndexTraitLangItem,              "index",                   index_trait;
+    IndexMutTraitLangItem,           "index_mut",               index_mut_trait;
 
     UnsafeTypeLangItem,              "unsafe",                  unsafe_type;
 
index d48f7f541f0da016d1c85cfe980a529656c89031..79742d3173434cd5bafcef3173eccbbbc4f80d5c 100644 (file)
 use syntax::codemap::{BytePos, original_sp, Span};
 use syntax::parse::token::special_idents;
 use syntax::parse::token;
-use syntax::print::pprust::{expr_to_str, block_to_str};
+use syntax::print::pprust::{expr_to_string, block_to_string};
 use syntax::{visit, ast_util};
 use syntax::visit::{Visitor, FnKind};
 
@@ -152,17 +152,17 @@ enum LiveNodeKind {
     ExitNode
 }
 
-fn live_node_kind_to_str(lnk: LiveNodeKind, cx: &ty::ctxt) -> String {
+fn live_node_kind_to_string(lnk: LiveNodeKind, cx: &ty::ctxt) -> String {
     let cm = cx.sess.codemap();
     match lnk {
         FreeVarNode(s) => {
-            format!("Free var node [{}]", cm.span_to_str(s))
+            format!("Free var node [{}]", cm.span_to_string(s))
         }
         ExprNode(s) => {
-            format!("Expr node [{}]", cm.span_to_str(s))
+            format!("Expr node [{}]", cm.span_to_string(s))
         }
         VarDefNode(s) => {
-            format!("Var def node [{}]", cm.span_to_str(s))
+            format!("Var def node [{}]", cm.span_to_string(s))
         }
         ExitNode => "Exit node".to_string(),
     }
@@ -272,8 +272,8 @@ fn add_live_node(&mut self, lnk: LiveNodeKind) -> LiveNode {
         self.lnks.push(lnk);
         self.num_live_nodes += 1;
 
-        debug!("{} is of kind {}", ln.to_str(),
-               live_node_kind_to_str(lnk, self.tcx));
+        debug!("{} is of kind {}", ln.to_string(),
+               live_node_kind_to_string(lnk, self.tcx));
 
         ln
     }
@@ -282,7 +282,7 @@ fn add_live_node_for_node(&mut self, node_id: NodeId, lnk: LiveNodeKind) {
         let ln = self.add_live_node(lnk);
         self.live_node_map.insert(node_id, ln);
 
-        debug!("{} is node {}", ln.to_str(), node_id);
+        debug!("{} is node {}", ln.to_string(), node_id);
     }
 
     fn add_variable(&mut self, vk: VarKind) -> Variable {
@@ -297,7 +297,7 @@ fn add_variable(&mut self, vk: VarKind) -> Variable {
             ImplicitRet => {}
         }
 
-        debug!("{} is {:?}", v.to_str(), vk);
+        debug!("{} is {:?}", v.to_string(), vk);
 
         v
     }
@@ -317,7 +317,7 @@ fn variable(&self, node_id: NodeId, span: Span) -> Variable {
     fn variable_name(&self, var: Variable) -> String {
         match self.var_kinds.get(var.get()) {
             &Local(LocalInfo { ident: nm, .. }) | &Arg(_, nm) => {
-                token::get_ident(nm).get().to_str()
+                token::get_ident(nm).get().to_string()
             },
             &ImplicitRet => "<implicit-ret>".to_string()
         }
@@ -675,7 +675,7 @@ fn write_vars(&self,
         for var_idx in range(0u, self.ir.num_vars) {
             let idx = node_base_idx + var_idx;
             if test(idx).is_valid() {
-                try!(write!(wr, " {}", Variable(var_idx).to_str()));
+                try!(write!(wr, " {}", Variable(var_idx).to_string()));
             }
         }
         Ok(())
@@ -717,7 +717,7 @@ fn ln_str(&self, ln: LiveNode) -> String {
             self.write_vars(wr, ln, |idx| self.users.get(idx).reader);
             write!(wr, "  writes");
             self.write_vars(wr, ln, |idx| self.users.get(idx).writer);
-            write!(wr, "  precedes {}]", self.successors.get(ln.get()).to_str());
+            write!(wr, "  precedes {}]", self.successors.get(ln.get()).to_string());
         }
         str::from_utf8(wr.unwrap().as_slice()).unwrap().to_string()
     }
@@ -766,7 +766,7 @@ fn merge_from_succ(&mut self,
         });
 
         debug!("merge_from_succ(ln={}, succ={}, first_merge={}, changed={})",
-               ln.to_str(), self.ln_str(succ_ln), first_merge, changed);
+               ln.to_string(), self.ln_str(succ_ln), first_merge, changed);
         return changed;
 
         fn copy_if_invalid(src: LiveNode, dst: &mut LiveNode) -> bool {
@@ -787,14 +787,14 @@ fn define(&mut self, writer: LiveNode, var: Variable) {
         self.users.get_mut(idx).reader = invalid_node();
         self.users.get_mut(idx).writer = invalid_node();
 
-        debug!("{} defines {} (idx={}): {}", writer.to_str(), var.to_str(),
+        debug!("{} defines {} (idx={}): {}", writer.to_string(), var.to_string(),
                idx, self.ln_str(writer));
     }
 
     // Either read, write, or both depending on the acc bitset
     fn acc(&mut self, ln: LiveNode, var: Variable, acc: uint) {
         debug!("{} accesses[{:x}] {}: {}",
-               ln.to_str(), acc, var.to_str(), self.ln_str(ln));
+               ln.to_string(), acc, var.to_string(), self.ln_str(ln));
 
         let idx = self.idx(ln, var);
         let user = self.users.get_mut(idx);
@@ -822,7 +822,7 @@ fn compute(&mut self, decl: &FnDecl, body: &Block) -> LiveNode {
         // effectively a return---this only occurs in `for` loops,
         // where the body is really a closure.
 
-        debug!("compute: using id for block, {}", block_to_str(body));
+        debug!("compute: using id for block, {}", block_to_string(body));
 
         let exit_ln = self.s.exit_ln;
         let entry_ln: LiveNode =
@@ -837,7 +837,7 @@ fn compute(&mut self, decl: &FnDecl, body: &Block) -> LiveNode {
                    }
                    body.id
                },
-               entry_ln.to_str());
+               entry_ln.to_string());
 
         entry_ln
     }
@@ -928,7 +928,7 @@ fn propagate_through_opt_expr(&mut self,
 
     fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
                               -> LiveNode {
-        debug!("propagate_through_expr: {}", expr_to_str(expr));
+        debug!("propagate_through_expr: {}", expr_to_string(expr));
 
         match expr.node {
           // Interesting cases with control flow or which gen/kill
@@ -942,7 +942,7 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
           }
 
           ExprFnBlock(_, ref blk) | ExprProc(_, ref blk) => {
-              debug!("{} is an ExprFnBlock or ExprProc", expr_to_str(expr));
+              debug!("{} is an ExprFnBlock or ExprProc", expr_to_string(expr));
 
               /*
               The next-node for a break is the successor of the entire
@@ -1314,7 +1314,7 @@ fn propagate_through_loop(&mut self,
             first_merge = false;
         }
         debug!("propagate_through_loop: using id for loop body {} {}",
-               expr.id, block_to_str(body));
+               expr.id, block_to_string(body));
 
         let cond_ln = self.propagate_through_opt_expr(cond, ln);
         let body_ln = self.with_loop_nodes(expr.id, succ, ln, |this| {
@@ -1458,6 +1458,8 @@ fn check_ret(&self,
                         },
                     _ => false
                 };
+                self.ir.tcx.sess.span_err(
+                    sp, "not all control paths return a value");
                 if ends_with_stmt {
                     let last_stmt = body.stmts.last().unwrap();
                     let original_span = original_sp(last_stmt.span, sp);
@@ -1469,8 +1471,6 @@ fn check_ret(&self,
                     self.ir.tcx.sess.span_note(
                         span_semicolon, "consider removing this semicolon:");
                 }
-                self.ir.tcx.sess.span_err(
-                    sp, "not all control paths return a value");
            }
         }
     }
index 54cca082e0de86950a10f7c26aeb8672369b6ae4..33ab2ed3632405adaa0fa90286535f4ae84cb4fa 100644 (file)
@@ -66,7 +66,7 @@
 use middle::ty;
 use middle::typeck;
 use util::nodemap::NodeMap;
-use util::ppaux::{ty_to_str, Repr};
+use util::ppaux::{ty_to_string, Repr};
 
 use syntax::ast::{MutImmutable, MutMutable};
 use syntax::ast;
@@ -217,7 +217,7 @@ pub fn deref_kind(tcx: &ty::ctxt, t: ty::t) -> deref_kind {
       None => {
         tcx.sess.bug(
             format!("deref_cat() invoked on non-derefable type {}",
-                    ty_to_str(tcx, t)).as_slice());
+                    ty_to_string(tcx, t)).as_slice());
       }
     }
 }
@@ -443,10 +443,6 @@ pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> McResult<cmt> {
           }
 
           ast::ExprIndex(ref base, _) => {
-            if self.typer.is_method_call(expr.id) {
-                return Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty));
-            }
-
             let base_cmt = if_ok!(self.cat_expr(&**base));
             Ok(self.cat_index(expr, base_cmt, 0))
           }
@@ -759,7 +755,7 @@ fn cat_deref_common<N:ast_node>(&self,
 
     pub fn cat_index<N:ast_node>(&self,
                                  elt: &N,
-                                 base_cmt: cmt,
+                                 mut base_cmt: cmt,
                                  derefs: uint)
                                  -> cmt {
         //! Creates a cmt for an indexing operation (`[]`); this
@@ -793,14 +789,26 @@ pub fn cat_index<N:ast_node>(&self,
         //! - `derefs`: the deref number to be used for
         //!   the implicit index deref, if any (see above)
 
-        let element_ty = match ty::array_element_ty(base_cmt.ty) {
-          Some(ref mt) => mt.ty,
-          None => {
-            self.tcx().sess.span_bug(
-                elt.span(),
-                format!("Explicit index of non-index type `{}`",
-                        base_cmt.ty.repr(self.tcx())).as_slice());
-          }
+        let method_call = typeck::MethodCall::expr(elt.id());
+        let method_ty = self.typer.node_method_ty(method_call);
+
+        let element_ty = match method_ty {
+            Some(method_ty) => {
+                let ref_ty = ty::ty_fn_ret(method_ty);
+                base_cmt = self.cat_rvalue_node(elt.id(), elt.span(), ref_ty);
+                *ty::ty_fn_args(method_ty).get(0)
+            }
+            None => {
+                match ty::array_element_ty(base_cmt.ty) {
+                    Some(ref mt) => mt.ty,
+                    None => {
+                        self.tcx().sess.span_bug(
+                            elt.span(),
+                            format!("Explicit index of non-index type `{}`",
+                                    base_cmt.ty.repr(self.tcx())).as_slice());
+                    }
+                }
+            }
         };
 
         return match deref_kind(self.tcx(), base_cmt.ty) {
@@ -972,7 +980,7 @@ pub fn cat_pattern(&self,
         // get the type of the *subpattern* and use that.
 
         debug!("cat_pattern: id={} pat={} cmt={}",
-               pat.id, pprust::pat_to_str(pat),
+               pat.id, pprust::pat_to_string(pat),
                cmt.repr(self.tcx()));
 
         op(self, cmt.clone(), pat);
@@ -1097,7 +1105,7 @@ pub fn cat_pattern(&self,
         Ok(())
     }
 
-    pub fn cmt_to_str(&self, cmt: &cmt_) -> String {
+    pub fn cmt_to_string(&self, cmt: &cmt_) -> String {
         match cmt.cat {
           cat_static_item => {
               "static item".to_string()
@@ -1143,10 +1151,10 @@ pub fn cmt_to_str(&self, cmt: &cmt_) -> String {
               "captured outer variable".to_string()
           }
           cat_discr(ref cmt, _) => {
-            self.cmt_to_str(&**cmt)
+            self.cmt_to_string(&**cmt)
           }
           cat_downcast(ref cmt) => {
-            self.cmt_to_str(&**cmt)
+            self.cmt_to_string(&**cmt)
           }
         }
     }
@@ -1303,7 +1311,7 @@ impl Repr for InteriorKind {
     fn repr(&self, _tcx: &ty::ctxt) -> String {
         match *self {
             InteriorField(NamedField(fld)) => {
-                token::get_name(fld).get().to_str()
+                token::get_name(fld).get().to_string()
             }
             InteriorField(PositionalField(i)) => format!("#{:?}", i),
             InteriorElement(_) => "[]".to_string(),
index 76e962a3bc4da6a1894def5f64c29b5c0b374072..7630321bd559b0bbc5cd4b8b3b57e21e88bfa6db 100644 (file)
@@ -375,7 +375,7 @@ enum FieldName {
 impl<'a> PrivacyVisitor<'a> {
     // used when debugging
     fn nodestr(&self, id: ast::NodeId) -> String {
-        self.tcx.map.node_to_str(id).to_string()
+        self.tcx.map.node_to_string(id).to_string()
     }
 
     // Determines whether the given definition is public from the point of view
@@ -423,7 +423,7 @@ fn def_privacy(&self, did: ast::DefId) -> PrivacyResult {
         }
 
         debug!("privacy - local {} not public all the way down",
-               self.tcx.map.node_to_str(did.node));
+               self.tcx.map.node_to_string(did.node));
         // return quickly for things in the same module
         if self.parents.find(&did.node) == self.parents.find(&self.curitem) {
             debug!("privacy - same parent, we're done here");
index 682dcb2b709f396ff8bdfb1b8a61689002137838..26bb0b62cb05fbb1b8869c1bf4e34ad8057b3ba8 100644 (file)
@@ -336,7 +336,7 @@ fn propagate_node(&mut self, node: &ast_map::Node,
                     .bug(format!("found unexpected thingy in worklist: {}",
                                  self.tcx
                                      .map
-                                     .node_to_str(search_item)).as_slice())
+                                     .node_to_string(search_item)).as_slice())
             }
         }
     }
index 3b59736e292b51c2b4681367cb1fa660b931906f..df4d3b7efe432ea6ffada1db2c3bac9569f4bc8e 100644 (file)
@@ -821,7 +821,7 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor,
                                body.id={}, \
                                cx.parent={})",
            id,
-           visitor.sess.codemap().span_to_str(sp),
+           visitor.sess.codemap().span_to_string(sp),
            body.id,
            cx.parent);
 
index b7b4618a7904619a97f34eacd6d26a0efe1a2b0f..612b29afd3e9cc114cb24755b44a6bd77ab6cfac 100644 (file)
@@ -307,7 +307,7 @@ enum BareIdentifierPatternResolution {
 #[deriving(PartialEq)]
 enum DuplicateCheckingMode {
     ForbidDuplicateModules,
-    ForbidDuplicateTypes,
+    ForbidDuplicateTypesAndModules,
     ForbidDuplicateValues,
     ForbidDuplicateTypesAndValues,
     OverwriteDuplicates
@@ -790,12 +790,11 @@ fn intern(&mut self, string: &str, primitive_type: PrimTy) {
 }
 
 
-fn namespace_error_to_str(ns: NamespaceError) -> &'static str {
+fn namespace_error_to_string(ns: NamespaceError) -> &'static str {
     match ns {
-        NoError     => "",
-        ModuleError => "module",
-        TypeError   => "type",
-        ValueError  => "value",
+        NoError                 => "",
+        ModuleError | TypeError => "type or module",
+        ValueError              => "value",
     }
 }
 
@@ -1033,9 +1032,12 @@ fn add_child(&self,
                         }
                         Some(TypeNS)
                     }
-                    ForbidDuplicateTypes => {
+                    ForbidDuplicateTypesAndModules => {
                         match child.def_for_namespace(TypeNS) {
-                            Some(DefMod(_)) | None => {}
+                            None => {}
+                            Some(_) if child.get_module_if_available()
+                                            .map(|m| m.kind.get()) ==
+                                       Some(ImplModuleKind) => {}
                             Some(_) => duplicate_type = TypeError
                         }
                         Some(TypeNS)
@@ -1069,14 +1071,14 @@ fn add_child(&self,
                     let ns = ns.unwrap();
                     self.resolve_error(sp,
                         format!("duplicate definition of {} `{}`",
-                             namespace_error_to_str(duplicate_type),
+                             namespace_error_to_string(duplicate_type),
                              token::get_ident(name)).as_slice());
                     {
                         let r = child.span_for_namespace(ns);
                         for sp in r.iter() {
                             self.session.span_note(*sp,
                                  format!("first definition of {} `{}` here",
-                                      namespace_error_to_str(duplicate_type),
+                                      namespace_error_to_string(duplicate_type),
                                       token::get_ident(name)).as_slice());
                         }
                     }
@@ -1177,7 +1179,10 @@ fn build_reduced_graph_for_item(&mut self,
             // These items live in the type namespace.
             ItemTy(..) => {
                 let name_bindings =
-                    self.add_child(ident, parent.clone(), ForbidDuplicateTypes, sp);
+                    self.add_child(ident,
+                                   parent.clone(),
+                                   ForbidDuplicateTypesAndModules,
+                                   sp);
 
                 name_bindings.define_type
                     (DefTy(local_def(item.id)), sp, is_public);
@@ -1186,7 +1191,10 @@ fn build_reduced_graph_for_item(&mut self,
 
             ItemEnum(ref enum_definition, _) => {
                 let name_bindings =
-                    self.add_child(ident, parent.clone(), ForbidDuplicateTypes, sp);
+                    self.add_child(ident,
+                                   parent.clone(),
+                                   ForbidDuplicateTypesAndModules,
+                                   sp);
 
                 name_bindings.define_type
                     (DefTy(local_def(item.id)), sp, is_public);
@@ -1206,7 +1214,7 @@ fn build_reduced_graph_for_item(&mut self,
                 // Adding to both Type and Value namespaces or just Type?
                 let (forbid, ctor_id) = match struct_def.ctor_id {
                     Some(ctor_id)   => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
-                    None            => (ForbidDuplicateTypes, None)
+                    None            => (ForbidDuplicateTypesAndModules, None)
                 };
 
                 let name_bindings = self.add_child(ident, parent.clone(), forbid, sp);
@@ -1327,7 +1335,10 @@ fn build_reduced_graph_for_item(&mut self,
 
             ItemTrait(_, _, _, ref methods) => {
                 let name_bindings =
-                    self.add_child(ident, parent.clone(), ForbidDuplicateTypes, sp);
+                    self.add_child(ident,
+                                   parent.clone(),
+                                   ForbidDuplicateTypesAndModules,
+                                   sp);
 
                 // Add all the methods within to a new module.
                 let parent_link = self.get_parent_link(parent.clone(), ident);
@@ -1497,7 +1508,7 @@ fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
                                                               false,
                                                               true));
                     debug!("(build reduced graph for item) found extern `{}`",
-                            self.module_to_str(&*external_module));
+                            self.module_to_string(&*external_module));
                     parent.module().external_module_children.borrow_mut()
                                    .insert(name.name, external_module.clone());
                     self.build_reduced_graph_for_external_crate(external_module);
@@ -1851,7 +1862,7 @@ fn build_reduced_graph_for_external_crate_def(&mut self,
     /// Builds the reduced graph rooted at the given external module.
     fn populate_external_module(&mut self, module: Rc<Module>) {
         debug!("(populating external module) attempting to populate {}",
-               self.module_to_str(&*module));
+               self.module_to_string(&*module));
 
         let def_id = match module.def_id.get() {
             None => {
@@ -1919,7 +1930,7 @@ fn build_import_directive(&mut self,
             SingleImport(target, _) => {
                 debug!("(building import directive) building import \
                         directive: {}::{}",
-                       self.idents_to_str(module_.imports.borrow().last().unwrap()
+                       self.idents_to_string(module_.imports.borrow().last().unwrap()
                                                  .module_path.as_slice()),
                        token::get_ident(target));
 
@@ -1992,7 +2003,7 @@ fn resolve_imports(&mut self) {
     /// submodules.
     fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
         debug!("(resolving imports for module subtree) resolving {}",
-               self.module_to_str(&*module_));
+               self.module_to_string(&*module_));
         let orig_module = replace(&mut self.current_module, module_.clone());
         self.resolve_imports_for_module(module_.clone());
         self.current_module = orig_module;
@@ -2019,7 +2030,7 @@ fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
         if module.all_imports_resolved() {
             debug!("(resolving imports for module) all imports resolved for \
                    {}",
-                   self.module_to_str(&*module));
+                   self.module_to_string(&*module));
             return;
         }
 
@@ -2036,7 +2047,7 @@ fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
                         None => (import_directive.span, String::new())
                     };
                     let msg = format!("unresolved import `{}`{}",
-                                      self.import_path_to_str(
+                                      self.import_path_to_string(
                                           import_directive.module_path
                                                           .as_slice(),
                                           import_directive.subclass),
@@ -2052,7 +2063,7 @@ fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
         }
     }
 
-    fn idents_to_str(&self, idents: &[Ident]) -> String {
+    fn idents_to_string(&self, idents: &[Ident]) -> String {
         let mut first = true;
         let mut result = String::new();
         for ident in idents.iter() {
@@ -2066,15 +2077,15 @@ fn idents_to_str(&self, idents: &[Ident]) -> String {
         result
     }
 
-    fn path_idents_to_str(&self, path: &Path) -> String {
+    fn path_idents_to_string(&self, path: &Path) -> String {
         let identifiers: Vec<ast::Ident> = path.segments
                                              .iter()
                                              .map(|seg| seg.identifier)
                                              .collect();
-        self.idents_to_str(identifiers.as_slice())
+        self.idents_to_string(identifiers.as_slice())
     }
 
-    fn import_directive_subclass_to_str(&mut self,
+    fn import_directive_subclass_to_string(&mut self,
                                         subclass: ImportDirectiveSubclass)
                                         -> String {
         match subclass {
@@ -2085,16 +2096,16 @@ fn import_directive_subclass_to_str(&mut self,
         }
     }
 
-    fn import_path_to_str(&mut self,
+    fn import_path_to_string(&mut self,
                           idents: &[Ident],
                           subclass: ImportDirectiveSubclass)
                           -> String {
         if idents.is_empty() {
-            self.import_directive_subclass_to_str(subclass)
+            self.import_directive_subclass_to_string(subclass)
         } else {
             (format!("{}::{}",
-                     self.idents_to_str(idents),
-                     self.import_directive_subclass_to_str(
+                     self.idents_to_string(idents),
+                     self.import_directive_subclass_to_string(
                          subclass))).to_string()
         }
     }
@@ -2113,8 +2124,8 @@ fn resolve_import_for_module(&mut self,
 
         debug!("(resolving import for module) resolving import `{}::...` in \
                 `{}`",
-               self.idents_to_str(module_path.as_slice()),
-               self.module_to_str(&*module_));
+               self.idents_to_string(module_path.as_slice()),
+               self.module_to_string(&*module_));
 
         // First, resolve the module path for the directive, if necessary.
         let container = if module_path.len() == 0 {
@@ -2220,9 +2231,9 @@ fn resolve_single_import(&mut self,
         debug!("(resolving single import) resolving `{}` = `{}::{}` from \
                 `{}` id {}, last private {:?}",
                token::get_ident(target),
-               self.module_to_str(&*containing_module),
+               self.module_to_string(&*containing_module),
                token::get_ident(source),
-               self.module_to_str(module_),
+               self.module_to_string(module_),
                directive.id,
                lp);
 
@@ -2409,7 +2420,7 @@ fn get_binding(this: &mut Resolver,
         if value_result.is_unbound() && type_result.is_unbound() {
             let msg = format!("There is no `{}` in `{}`",
                               token::get_ident(source),
-                              self.module_to_str(&*containing_module));
+                              self.module_to_string(&*containing_module));
             return Failed(Some((directive.span, msg)));
         }
         let value_used_public = value_used_reexport || value_used_public;
@@ -2483,7 +2494,7 @@ fn resolve_glob_import(&mut self,
             debug!("(resolving glob import) writing module resolution \
                     {:?} into `{}`",
                    target_import_resolution.type_target.is_none(),
-                   self.module_to_str(module_));
+                   self.module_to_string(module_));
 
             if !target_import_resolution.is_public {
                 debug!("(resolving glob import) nevermind, just kidding");
@@ -2579,9 +2590,9 @@ fn merge_import_resolution(&mut self,
 
         debug!("(resolving glob import) writing resolution `{}` in `{}` \
                to `{}`",
-               token::get_name(name).get().to_str(),
-               self.module_to_str(&*containing_module),
-               self.module_to_str(module_));
+               token::get_name(name).get().to_string(),
+               self.module_to_string(&*containing_module),
+               self.module_to_string(module_));
 
         // Merge the child item into the import resolution.
         if name_bindings.defined_in_public_namespace(ValueNS) {
@@ -2641,7 +2652,7 @@ fn search_parent_externals(needle: Name, module: &Rc<Module>)
                                               false) {
                 Failed(None) => {
                     let segment_name = token::get_ident(name);
-                    let module_name = self.module_to_str(&*search_module);
+                    let module_name = self.module_to_string(&*search_module);
                     let mut span = span;
                     let msg = if "???" == module_name.as_slice() {
                         span.hi = span.lo + Pos::from_uint(segment_name.get().len());
@@ -2649,10 +2660,10 @@ fn search_parent_externals(needle: Name, module: &Rc<Module>)
                         match search_parent_externals(name.name,
                                                      &self.current_module) {
                             Some(module) => {
-                                let path_str = self.idents_to_str(module_path);
-                                let target_mod_str = self.module_to_str(&*module);
+                                let path_str = self.idents_to_string(module_path);
+                                let target_mod_str = self.module_to_string(&*module);
                                 let current_mod_str =
-                                    self.module_to_str(&*self.current_module);
+                                    self.module_to_string(&*self.current_module);
 
                                 let prefix = if target_mod_str == current_mod_str {
                                     "self::".to_string()
@@ -2760,8 +2771,8 @@ fn resolve_module_path(&mut self,
 
         debug!("(resolving module path for import) processing `{}` rooted at \
                `{}`",
-               self.idents_to_str(module_path),
-               self.module_to_str(&*module_));
+               self.idents_to_string(module_path),
+               self.module_to_string(&*module_));
 
         // Resolve the module prefix, if any.
         let module_prefix_result = self.resolve_module_prefix(module_.clone(),
@@ -2772,7 +2783,7 @@ fn resolve_module_path(&mut self,
         let last_private;
         match module_prefix_result {
             Failed(None) => {
-                let mpath = self.idents_to_str(module_path);
+                let mpath = self.idents_to_string(module_path);
                 let mpath = mpath.as_slice();
                 match mpath.rfind(':') {
                     Some(idx) => {
@@ -2854,7 +2865,7 @@ fn resolve_item_in_lexical_scope(&mut self,
                 namespace {:?} in `{}`",
                token::get_ident(name),
                namespace,
-               self.module_to_str(&*module_));
+               self.module_to_string(&*module_));
 
         // The current module node is handled specially. First, check for
         // its immediate children.
@@ -3087,7 +3098,7 @@ fn resolve_module_prefix(&mut self,
                 break
             }
             debug!("(resolving module prefix) resolving `super` at {}",
-                   self.module_to_str(&*containing_module));
+                   self.module_to_string(&*containing_module));
             match self.get_nearest_normal_module_parent(containing_module) {
                 None => return Failed(None),
                 Some(new_module) => {
@@ -3098,7 +3109,7 @@ fn resolve_module_prefix(&mut self,
         }
 
         debug!("(resolving module prefix) finished resolving prefix at {}",
-               self.module_to_str(&*containing_module));
+               self.module_to_string(&*containing_module));
 
         return Success(PrefixFound(containing_module, i));
     }
@@ -3118,7 +3129,7 @@ fn resolve_name_in_module(&mut self,
                               -> ResolveResult<(Target, bool)> {
         debug!("(resolving name in module) resolving `{}` in `{}`",
                token::get_name(name).get(),
-               self.module_to_str(&*module_));
+               self.module_to_string(&*module_));
 
         // First, check the direct children of the module.
         self.populate_module_if_necessary(&module_);
@@ -3251,19 +3262,19 @@ fn record_exports_for_module_subtree(&mut self,
                 // OK. Continue.
                 debug!("(recording exports for module subtree) recording \
                         exports for local module `{}`",
-                       self.module_to_str(&*module_));
+                       self.module_to_string(&*module_));
             }
             None => {
                 // Record exports for the root module.
                 debug!("(recording exports for module subtree) recording \
                         exports for root module `{}`",
-                       self.module_to_str(&*module_));
+                       self.module_to_string(&*module_));
             }
             Some(_) => {
                 // Bail out.
                 debug!("(recording exports for module subtree) not recording \
                         exports for `{}`",
-                       self.module_to_str(&*module_));
+                       self.module_to_string(&*module_));
                 return;
             }
         }
@@ -3379,7 +3390,7 @@ fn with_scope(&mut self, name: Option<Ident>, f: |&mut Resolver|) {
                     None => {
                         debug!("!!! (with scope) didn't find `{}` in `{}`",
                                token::get_ident(name),
-                               self.module_to_str(&*orig_module));
+                               self.module_to_string(&*orig_module));
                     }
                     Some(name_bindings) => {
                         match (*name_bindings).get_module_if_available() {
@@ -3387,7 +3398,7 @@ fn with_scope(&mut self, name: Option<Ident>, f: |&mut Resolver|) {
                                 debug!("!!! (with scope) didn't find module \
                                         for `{}` in `{}`",
                                        token::get_ident(name),
-                                       self.module_to_str(&*orig_module));
+                                       self.module_to_string(&*orig_module));
                             }
                             Some(module_) => {
                                 self.current_module = module_;
@@ -3587,6 +3598,7 @@ fn resolve_item(&mut self, item: &Item) {
                                                                item.id,
                                                                ItemRibKind),
                                              |this| {
+                    this.resolve_type_parameters(&generics.ty_params);
                     visit::walk_item(this, item, ());
                 });
             }
@@ -3612,7 +3624,7 @@ fn resolve_item(&mut self, item: &Item) {
                                             methods.as_slice());
             }
 
-            ItemTrait(ref generics, _, ref traits, ref methods) => {
+            ItemTrait(ref generics, ref unbound, ref traits, ref methods) => {
                 // Create a new rib for the self type.
                 let self_type_rib = Rib::new(ItemRibKind);
 
@@ -3634,6 +3646,12 @@ fn resolve_item(&mut self, item: &Item) {
                     for trt in traits.iter() {
                         this.resolve_trait_reference(item.id, trt, TraitDerivation);
                     }
+                    match unbound {
+                        &Some(ast::TraitTyParamBound(ref tpb)) => {
+                            this.resolve_trait_reference(item.id, tpb, TraitDerivation);
+                        }
+                        _ => {}
+                    }
 
                     for method in (*methods).iter() {
                         // Create a new rib for the method-specific type
@@ -3845,11 +3863,15 @@ fn resolve_function(&mut self,
     }
 
     fn resolve_type_parameters(&mut self,
-                                   type_parameters: &OwnedSlice<TyParam>) {
+                               type_parameters: &OwnedSlice<TyParam>) {
         for type_parameter in type_parameters.iter() {
             for bound in type_parameter.bounds.iter() {
                 self.resolve_type_parameter_bound(type_parameter.id, bound);
             }
+            match &type_parameter.unbound {
+                &Some(ref unbound) => self.resolve_type_parameter_bound(type_parameter.id, unbound),
+                &None => {}
+            }
             match type_parameter.default {
                 Some(ref ty) => self.resolve_type(&**ty),
                 None => {}
@@ -3876,12 +3898,12 @@ fn resolve_type_parameter_bound(&mut self,
     }
 
     fn resolve_trait_reference(&mut self,
-                                   id: NodeId,
-                                   trait_reference: &TraitRef,
-                                   reference_type: TraitReferenceType) {
+                               id: NodeId,
+                               trait_reference: &TraitRef,
+                               reference_type: TraitReferenceType) {
         match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
             None => {
-                let path_str = self.path_idents_to_str(&trait_reference.path);
+                let path_str = self.path_idents_to_string(&trait_reference.path);
                 let usage_str = match reference_type {
                     TraitBoundingTypeParameter => "bound type parameter with",
                     TraitImplementation        => "implement",
@@ -3900,7 +3922,7 @@ fn resolve_trait_reference(&mut self,
                     (def, _) => {
                         self.resolve_error(trait_reference.path.span,
                                            format!("`{}` is not a trait",
-                                                   self.path_idents_to_str(
+                                                   self.path_idents_to_string(
                                                         &trait_reference.path)));
 
                         // If it's a typedef, give a note
@@ -3948,7 +3970,7 @@ fn resolve_struct(&mut self,
                                                             .identifier),
                                        def);
                                 debug!("(resolving struct) writing resolution for `{}` (id {})",
-                                       this.path_idents_to_str(path),
+                                       this.path_idents_to_string(path),
                                        path_id);
                                 this.record_def(path_id, (def, lp));
                             }
@@ -4060,7 +4082,7 @@ fn check_trait_method(&self, method: &Method) {
             let method_name = method.ident.name;
 
             if self.method_map.borrow().find(&(method_name, did)).is_none() {
-                let path_str = self.path_idents_to_str(&trait_ref.path);
+                let path_str = self.path_idents_to_string(&trait_ref.path);
                 self.resolve_error(method.span,
                                     format!("method `{}` is not a member of trait `{}`",
                                             token::get_name(method_name),
@@ -4270,13 +4292,13 @@ fn resolve_type(&mut self, ty: &Ty) {
                         // Write the result into the def map.
                         debug!("(resolving type) writing resolution for `{}` \
                                 (id {})",
-                               self.path_idents_to_str(path),
+                               self.path_idents_to_string(path),
                                path_id);
                         self.record_def(path_id, def);
                     }
                     None => {
                         let msg = format!("use of undeclared type name `{}`",
-                                          self.path_idents_to_str(path));
+                                          self.path_idents_to_string(path));
                         self.resolve_error(ty.span, msg.as_slice());
                     }
                 }
@@ -4470,24 +4492,14 @@ struct or enum variant",
 
                 PatStruct(ref path, _, _) => {
                     match self.resolve_path(pat_id, path, TypeNS, false) {
-                        Some((DefTy(class_id), lp))
-                                if self.structs.contains_key(&class_id) => {
-                            let class_def = DefStruct(class_id);
-                            self.record_def(pattern.id, (class_def, lp));
-                        }
-                        Some(definition @ (DefStruct(class_id), _)) => {
-                            assert!(self.structs.contains_key(&class_id));
-                            self.record_def(pattern.id, definition);
-                        }
-                        Some(definition @ (DefVariant(_, variant_id, _), _))
-                                if self.structs.contains_key(&variant_id) => {
+                        Some(definition) => {
                             self.record_def(pattern.id, definition);
                         }
                         result => {
                             debug!("(resolving pattern) didn't find struct \
                                     def: {:?}", result);
                             let msg = format!("`{}` does not name a structure",
-                                              self.path_idents_to_str(path));
+                                              self.path_idents_to_string(path));
                             self.resolve_error(path.span, msg.as_slice());
                         }
                     }
@@ -4717,7 +4729,7 @@ fn resolve_module_relative_path(&mut self,
                     Some((span, msg)) => (span, msg),
                     None => {
                         let msg = format!("Use of undeclared module `{}`",
-                                          self.idents_to_str(
+                                          self.idents_to_string(
                                                module_path_idents.as_slice()));
                         (path.span, msg)
                     }
@@ -4793,7 +4805,7 @@ fn resolve_crate_relative_path(&mut self,
                     Some((span, msg)) => (span, msg),
                     None => {
                         let msg = format!("Use of undeclared module `::{}`",
-                                          self.idents_to_str(
+                                          self.idents_to_string(
                                                module_path_idents.as_slice()));
                         (path.span, msg)
                     }
@@ -4998,7 +5010,7 @@ fn get_module(this: &mut Resolver, span: Span, ident_path: &[ast::Ident])
         match get_module(self, path.span, ident_path.as_slice()) {
             Some(module) => match module.children.borrow().find(&name) {
                 Some(binding) => {
-                    let p_str = self.path_idents_to_str(&path);
+                    let p_str = self.path_idents_to_string(&path);
                     match binding.def_for_namespace(ValueNS) {
                         Some(DefStaticMethod(_, provenance, _)) => {
                             match provenance {
@@ -5020,7 +5032,7 @@ fn get_module(this: &mut Resolver, span: Span, ident_path: &[ast::Ident])
         let method_map = self.method_map.borrow();
         match self.current_trait_ref {
             Some((did, ref trait_ref)) => {
-                let path_str = self.path_idents_to_str(&trait_ref.path);
+                let path_str = self.path_idents_to_string(&trait_ref.path);
 
                 match method_map.find(&(name, did)) {
                     Some(&SelfStatic) => return StaticTraitMethod(path_str),
@@ -5093,7 +5105,7 @@ fn resolve_expr(&mut self, expr: &Expr) {
                     Some(def) => {
                         // Write the result into the def map.
                         debug!("(resolving expr) resolved `{}`",
-                               self.path_idents_to_str(path));
+                               self.path_idents_to_string(path));
 
                         // First-class methods are not supported yet; error
                         // out here.
@@ -5113,7 +5125,7 @@ fn resolve_expr(&mut self, expr: &Expr) {
                         self.record_def(expr.id, def);
                     }
                     None => {
-                        let wrong_name = self.path_idents_to_str(path);
+                        let wrong_name = self.path_idents_to_string(path);
                         // Be helpful if the name refers to a struct
                         // (The pattern matching def_tys where the id is in self.structs
                         // matches on regular structs while excluding tuple- and enum-like
@@ -5200,22 +5212,16 @@ fn resolve_expr(&mut self, expr: &Expr) {
             }
 
             ExprStruct(ref path, _, _) => {
-                // Resolve the path to the structure it goes to.
+                // Resolve the path to the structure it goes to. We don't
+                // check to ensure that the path is actually a structure; that
+                // is checked later during typeck.
                 match self.resolve_path(expr.id, path, TypeNS, false) {
-                    Some((DefTy(class_id), lp)) | Some((DefStruct(class_id), lp))
-                            if self.structs.contains_key(&class_id) => {
-                        let class_def = DefStruct(class_id);
-                        self.record_def(expr.id, (class_def, lp));
-                    }
-                    Some(definition @ (DefVariant(_, class_id, _), _))
-                            if self.structs.contains_key(&class_id) => {
-                        self.record_def(expr.id, definition);
-                    }
+                    Some(definition) => self.record_def(expr.id, definition),
                     result => {
                         debug!("(resolving expression) didn't find struct \
                                 def: {:?}", result);
                         let msg = format!("`{}` does not name a structure",
-                                          self.path_idents_to_str(path));
+                                          self.path_idents_to_string(path));
                         self.resolve_error(path.span, msg.as_slice());
                     }
                 }
@@ -5515,7 +5521,7 @@ fn finalize_import(&mut self, id: NodeId, span: Span) {
     //
 
     /// A somewhat inefficient routine to obtain the name of a module.
-    fn module_to_str(&self, module: &Module) -> String {
+    fn module_to_string(&self, module: &Module) -> String {
         let mut idents = Vec::new();
 
         fn collect_mod(idents: &mut Vec<ast::Ident>, module: &Module) {
@@ -5536,14 +5542,14 @@ fn collect_mod(idents: &mut Vec<ast::Ident>, module: &Module) {
         if idents.len() == 0 {
             return "???".to_string();
         }
-        self.idents_to_str(idents.move_iter().rev()
+        self.idents_to_string(idents.move_iter().rev()
                                  .collect::<Vec<ast::Ident>>()
                                  .as_slice())
     }
 
     #[allow(dead_code)]   // useful for debugging
     fn dump_module(&mut self, module_: Rc<Module>) {
-        debug!("Dump of module `{}`:", self.module_to_str(&*module_));
+        debug!("Dump of module `{}`:", self.module_to_string(&*module_));
 
         debug!("Children:");
         self.populate_module_if_necessary(&module_);
index 8ff5331cec2319dca978cf60064224f0dddde9c4..1c85413a8d8eb7a02f401790aa209e8620210036 100644 (file)
@@ -24,7 +24,7 @@
 use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token::special_idents;
 use syntax::parse::token;
-use syntax::print::pprust::{lifetime_to_str};
+use syntax::print::pprust::{lifetime_to_string};
 use syntax::visit;
 use syntax::visit::Visitor;
 use util::nodemap::NodeMap;
@@ -372,7 +372,7 @@ fn insert_lifetime(&mut self,
         }
 
         debug!("lifetime_ref={} id={} resolved to {:?}",
-                lifetime_to_str(lifetime_ref),
+                lifetime_to_string(lifetime_ref),
                 lifetime_ref.id,
                 def);
         self.named_region_map.insert(lifetime_ref.id, def);
index bdb7d30339d66f010f0ba8e170dffe17dcaafe4b..d16e2bbf66b937ff57a33236813c1de91cdee6e6 100644 (file)
@@ -51,7 +51,7 @@
 use syntax::parse::token::{get_ident,keywords};
 use syntax::visit;
 use syntax::visit::Visitor;
-use syntax::print::pprust::{path_to_str,ty_to_str};
+use syntax::print::pprust::{path_to_string,ty_to_string};
 
 use middle::save::span_utils::SpanUtils;
 use middle::save::recorder::Recorder;
@@ -108,7 +108,7 @@ fn process_path_prefixes(&self, path: &ast::Path) -> Vec<(Span, String)> {
         if spans.len() < path.segments.len() {
             error!("Mis-calculated spans for path '{}'. \
                     Found {} spans, expected {}. Found spans:",
-                   path_to_str(path), spans.len(), path.segments.len());
+                   path_to_string(path), spans.len(), path.segments.len());
             for s in spans.iter() {
                 let loc = self.sess.codemap().lookup_char_pos(s.lo);
                 error!("    '{}' in {}, line {}",
@@ -126,7 +126,7 @@ fn process_path_prefixes(&self, path: &ast::Path) -> Vec<(Span, String)> {
             let sub_path = ast::Path{span: *span, // span for the last segment
                                      global: path.global,
                                      segments: segs};
-            let qualname = path_to_str(&sub_path);
+            let qualname = path_to_string(&sub_path);
             result.push((*span, qualname));
             segs = sub_path.segments;
         }
@@ -249,7 +249,7 @@ fn process_formals(&mut self, formals: &Vec<ast::Arg>, qualname: &str, e:DxrVisi
             self.collecting = false;
             let span_utils = self.span;
             for &(id, ref p, _, _) in self.collected_paths.iter() {
-                let typ = ppaux::ty_to_str(&self.analysis.ty_cx,
+                let typ = ppaux::ty_to_string(&self.analysis.ty_cx,
                     *self.analysis.ty_cx.node_types.borrow().get(&(id as uint)));
                 // get the span only for the name of the variable (I hope the path is only ever a
                 // variable name, but who knows?)
@@ -257,7 +257,7 @@ fn process_formals(&mut self, formals: &Vec<ast::Arg>, qualname: &str, e:DxrVisi
                                     span_utils.span_for_last_ident(p.span),
                                     id,
                                     qualname,
-                                    path_to_str(p).as_slice(),
+                                    path_to_string(p).as_slice(),
                                     typ.as_slice());
             }
             self.collected_paths.clear();
@@ -280,7 +280,7 @@ fn process_method(&mut self, method: &ast::Method, e:DxrVisitorEnv) {
                     match item.node {
                         ast::ItemImpl(_, _, ty, _) => {
                             let mut result = String::from_str("<");
-                            result.push_str(ty_to_str(&*ty).as_slice());
+                            result.push_str(ty_to_string(&*ty).as_slice());
 
                             match ty::trait_of_method(&self.analysis.ty_cx,
                                                       ast_util::local_def(method.id)) {
@@ -400,7 +400,7 @@ fn process_struct_field_def(&mut self,
             ast::NamedField(ident, _) => {
                 let name = get_ident(ident);
                 let qualname = format!("{}::{}", qualname, name);
-                let typ = ppaux::ty_to_str(&self.analysis.ty_cx,
+                let typ = ppaux::ty_to_string(&self.analysis.ty_cx,
                     *self.analysis.ty_cx.node_types.borrow().get(&(field.node.id as uint)));
                 match self.span.sub_span_before_token(field.span, token::COLON) {
                     Some(sub_span) => self.fmt.field_str(field.span,
@@ -452,7 +452,7 @@ fn process_fn(&mut self,
                   decl: ast::P<ast::FnDecl>,
                   ty_params: &ast::Generics,
                   body: ast::P<ast::Block>) {
-        let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
+        let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
 
         let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Fn);
         self.fmt.fn_str(item.span,
@@ -482,7 +482,7 @@ fn process_static(&mut self,
                       mt: ast::Mutability,
                       expr: &ast::Expr)
     {
-        let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
+        let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
 
         // If the variable is immutable, save the initialising expression.
         let value = match mt {
@@ -497,7 +497,7 @@ fn process_static(&mut self,
                             get_ident(item.ident).get(),
                             qualname.as_slice(),
                             value.as_slice(),
-                            ty_to_str(&*typ).as_slice(),
+                            ty_to_string(&*typ).as_slice(),
                             e.cur_scope);
 
         // walk type and init value
@@ -510,7 +510,7 @@ fn process_struct(&mut self,
                       e: DxrVisitorEnv,
                       def: &ast::StructDef,
                       ty_params: &ast::Generics) {
-        let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
+        let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
 
         let ctor_id = match def.ctor_id {
             Some(node_id) => node_id,
@@ -538,7 +538,7 @@ fn process_enum(&mut self,
                     e: DxrVisitorEnv,
                     enum_definition: &ast::EnumDef,
                     ty_params: &ast::Generics) {
-        let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
+        let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
         match self.span.sub_span_after_keyword(item.span, keywords::Enum) {
             Some(sub_span) => self.fmt.enum_str(item.span,
                                                 Some(sub_span),
@@ -639,7 +639,7 @@ fn process_trait(&mut self,
                      generics: &ast::Generics,
                      trait_refs: &Vec<ast::TraitRef>,
                      methods: &Vec<ast::TraitMethod>) {
-        let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
+        let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
 
         let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Trait);
         self.fmt.trait_str(item.span,
@@ -678,7 +678,7 @@ fn process_mod(&mut self,
                    item: &ast::Item,  // The module in question, represented as an item.
                    e: DxrVisitorEnv,
                    m: &ast::Mod) {
-        let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
+        let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
 
         let cm = self.sess.codemap();
         let filename = cm.span_to_filename(m.inner);
@@ -971,8 +971,8 @@ fn visit_item(&mut self, item:&ast::Item, e: DxrVisitorEnv) {
                 self.process_trait(item, e, generics, trait_refs, methods),
             ast::ItemMod(ref m) => self.process_mod(item, e, m),
             ast::ItemTy(ty, ref ty_params) => {
-                let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
-                let value = ty_to_str(&*ty);
+                let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
+                let value = ty_to_string(&*ty);
                 let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Type);
                 self.fmt.typedef_str(item.span,
                                      sub_span,
@@ -1231,7 +1231,7 @@ fn visit_expr(&mut self, ex: &ast::Expr, e: DxrVisitorEnv) {
                     return
                 }
 
-                let id = String::from_str("$").append(ex.id.to_str().as_slice());
+                let id = String::from_str("$").append(ex.id.to_string().as_slice());
                 self.process_formals(&decl.inputs, id.as_slice(), e);
 
                 // walk arg and return types
@@ -1288,7 +1288,7 @@ fn visit_arm(&mut self, arm: &ast::Arm, e: DxrVisitorEnv) {
                 def::DefBinding(id, _)  => self.fmt.variable_str(p.span,
                                                                  sub_span,
                                                                  id,
-                                                                 path_to_str(p).as_slice(),
+                                                                 path_to_string(p).as_slice(),
                                                                  value.as_slice(),
                                                                  ""),
                 def::DefVariant(_,id,_) => self.fmt.ref_str(ref_kind,
@@ -1331,7 +1331,7 @@ fn visit_local(&mut self, l:&ast::Local, e: DxrVisitorEnv) {
         for &(id, ref p, ref immut, _) in self.collected_paths.iter() {
             let value = if *immut { value.to_owned() } else { "<mutable>".to_owned() };
             let types = self.analysis.ty_cx.node_types.borrow();
-            let typ = ppaux::ty_to_str(&self.analysis.ty_cx, *types.get(&(id as uint)));
+            let typ = ppaux::ty_to_string(&self.analysis.ty_cx, *types.get(&(id as uint)));
             // Get the span only for the name of the variable (I hope the path
             // is only ever a variable name, but who knows?).
             let sub_span = self.span.span_for_last_ident(p.span);
@@ -1339,7 +1339,7 @@ fn visit_local(&mut self, l:&ast::Local, e: DxrVisitorEnv) {
             self.fmt.variable_str(p.span,
                                   sub_span,
                                   id,
-                                  path_to_str(p).as_slice(),
+                                  path_to_string(p).as_slice(),
                                   value.as_slice(),
                                   typ.as_slice());
         }
@@ -1373,15 +1373,15 @@ pub fn process_crate(sess: &Session,
         return;
     }
 
-    let (cratename, crateid) = match attr::find_crateid(krate.attrs.as_slice()) {
-        Some(crateid) => (crateid.name.clone(), crateid.to_str()),
+    let cratename = match attr::find_crate_name(krate.attrs.as_slice()) {
+        Some(name) => name.get().to_string(),
         None => {
             info!("Could not find crate name, using 'unknown_crate'");
-            (String::from_str("unknown_crate"),"unknown_crate".to_owned())
+            String::from_str("unknown_crate")
         },
     };
 
-    info!("Dumping crate {} ({})", cratename, crateid);
+    info!("Dumping crate {}", cratename);
 
     // find a path to dump our data to
     let mut root_path = match os::getenv("DXR_RUST_TEMP_FOLDER") {
index fd76d6d37d10d932709447f110e8c9a6e992c599..7869aec1683c20c115814223a1e706ecb478b516 100644 (file)
@@ -252,7 +252,7 @@ pub fn variable_str(&mut self,
         // the local case they can be overridden in one block and there is no nice way
         // to refer to such a scope in english, so we just hack it by appending the
         // variable def's node id
-        let qualname = String::from_str(name).append("$").append(id.to_str().as_slice());
+        let qualname = String::from_str(name).append("$").append(id.to_string().as_slice());
         self.check_and_record(Variable,
                               span,
                               sub_span,
index 0cd3b6e7d79184ee8dd9f1f737e278ae0d7cba6e..4684bd3532ec13ebb9daedfbb227b958c0da7031 100644 (file)
@@ -15,7 +15,6 @@
 use middle::ty_fold::{TypeFoldable, TypeFolder};
 use util::ppaux::Repr;
 
-use std::iter::Chain;
 use std::mem;
 use std::raw;
 use std::slice::{Items, MutItems};
@@ -191,8 +190,8 @@ pub fn mut_regions<'a>(&'a mut self) -> &'a mut VecPerParamSpace<ty::Region> {
     }
 
     pub fn with_method_from(self, substs: &Substs) -> Substs {
-        self.with_method((*substs.types.get_vec(FnSpace)).clone(),
-                         (*substs.regions().get_vec(FnSpace)).clone())
+        self.with_method(Vec::from_slice(substs.types.get_slice(FnSpace)),
+                         Vec::from_slice(substs.regions().get_slice(FnSpace)))
     }
 
     pub fn with_method(self,
@@ -261,13 +260,44 @@ pub fn from_uint(u: uint) -> ParamSpace {
  */
 #[deriving(PartialEq, Eq, Clone, Hash, Encodable, Decodable)]
 pub struct VecPerParamSpace<T> {
-    vecs: (Vec<T>, Vec<T>, Vec<T>)
+    // This was originally represented as a tuple with one Vec<T> for
+    // each variant of ParamSpace, and that remains the abstraction
+    // that it provides to its clients.
+    //
+    // Here is how the representation corresponds to the abstraction
+    // i.e. the "abstraction function" AF:
+    //
+    // AF(self) = (self.content.slice_to(self.type_limit),
+    //             self.content.slice(self.type_limit, self.self_limit),
+    //             self.content.slice_from(self.self_limit))
+    type_limit: uint,
+    self_limit: uint,
+    content: Vec<T>,
+}
+
+impl<T:Clone> VecPerParamSpace<T> {
+    pub fn push_all(&mut self, space: ParamSpace, values: &[T]) {
+        // FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n).
+        for t in values.iter() {
+            self.push(space, t.clone());
+        }
+    }
 }
 
 impl<T> VecPerParamSpace<T> {
+    fn limits(&self, space: ParamSpace) -> (uint, uint) {
+        match space {
+            TypeSpace => (0, self.type_limit),
+            SelfSpace => (self.type_limit, self.self_limit),
+            FnSpace => (self.self_limit, self.content.len()),
+        }
+    }
+
     pub fn empty() -> VecPerParamSpace<T> {
         VecPerParamSpace {
-            vecs: (Vec::new(), Vec::new(), Vec::new())
+            type_limit: 0,
+            self_limit: 0,
+            content: Vec::new()
         }
     }
 
@@ -276,8 +306,15 @@ pub fn params_from_type(types: Vec<T>) -> VecPerParamSpace<T> {
     }
 
     pub fn new(t: Vec<T>, s: Vec<T>, f: Vec<T>) -> VecPerParamSpace<T> {
+        let type_limit = t.len();
+        let self_limit = t.len() + s.len();
+        let mut content = t;
+        content.push_all_move(s);
+        content.push_all_move(f);
         VecPerParamSpace {
-            vecs: (t, s, f)
+            type_limit: type_limit,
+            self_limit: self_limit,
+            content: content,
         }
     }
 
@@ -289,55 +326,98 @@ pub fn sort(t: Vec<T>, space: |&T| -> ParamSpace) -> VecPerParamSpace<T> {
         result
     }
 
+    /// Appends `value` to the vector associated with `space`.
+    ///
+    /// Unlike the `push` method in `Vec`, this should not be assumed
+    /// to be a cheap operation (even when amortized over many calls).
     pub fn push(&mut self, space: ParamSpace, value: T) {
-        self.get_mut_vec(space).push(value);
+        let (_, limit) = self.limits(space);
+        match space {
+            TypeSpace => { self.type_limit += 1; self.self_limit += 1; }
+            SelfSpace => { self.self_limit += 1; }
+            FnSpace   => {}
+        }
+        self.content.insert(limit, value);
+    }
+
+    pub fn pop(&mut self, space: ParamSpace) -> Option<T> {
+        let (start, limit) = self.limits(space);
+        if start == limit {
+            None
+        } else {
+            match space {
+                TypeSpace => { self.type_limit -= 1; self.self_limit -= 1; }
+                SelfSpace => { self.self_limit -= 1; }
+                FnSpace   => {}
+            }
+            self.content.remove(limit - 1)
+        }
+    }
+
+    pub fn truncate(&mut self, space: ParamSpace, len: uint) {
+        // FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n).
+        while self.len(space) > len {
+            self.pop(space);
+        }
+    }
+
+    pub fn replace(&mut self, space: ParamSpace, elems: Vec<T>) {
+        // FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n).
+        self.truncate(space, 0);
+        for t in elems.move_iter() {
+            self.push(space, t);
+        }
     }
 
     pub fn get_self<'a>(&'a self) -> Option<&'a T> {
-        let v = self.get_vec(SelfSpace);
+        let v = self.get_slice(SelfSpace);
         assert!(v.len() <= 1);
-        if v.len() == 0 { None } else { Some(v.get(0)) }
+        if v.len() == 0 { None } else { Some(&v[0]) }
     }
 
     pub fn len(&self, space: ParamSpace) -> uint {
-        self.get_vec(space).len()
+        self.get_slice(space).len()
+    }
+
+    pub fn is_empty_in(&self, space: ParamSpace) -> bool {
+        self.len(space) == 0
     }
 
-    pub fn get_vec<'a>(&'a self, space: ParamSpace) -> &'a Vec<T> {
-        self.vecs.get(space as uint).unwrap()
+    pub fn get_slice<'a>(&'a self, space: ParamSpace) -> &'a [T] {
+        let (start, limit) = self.limits(space);
+        self.content.slice(start, limit)
     }
 
-    pub fn get_mut_vec<'a>(&'a mut self, space: ParamSpace) -> &'a mut Vec<T> {
-        self.vecs.get_mut(space as uint).unwrap()
+    fn get_mut_slice<'a>(&'a mut self, space: ParamSpace) -> &'a mut [T] {
+        let (start, limit) = self.limits(space);
+        self.content.mut_slice(start, limit)
     }
 
     pub fn opt_get<'a>(&'a self,
                        space: ParamSpace,
                        index: uint)
                        -> Option<&'a T> {
-        let v = self.get_vec(space);
-        if index < v.len() { Some(v.get(index)) } else { None }
+        let v = self.get_slice(space);
+        if index < v.len() { Some(&v[index]) } else { None }
     }
 
     pub fn get<'a>(&'a self, space: ParamSpace, index: uint) -> &'a T {
-        self.get_vec(space).get(index)
+        &self.get_slice(space)[index]
     }
 
     pub fn get_mut<'a>(&'a mut self,
                        space: ParamSpace,
                        index: uint) -> &'a mut T {
-        self.get_mut_vec(space).get_mut(index)
+        &mut self.get_mut_slice(space)[index]
     }
 
-    pub fn iter<'a>(&'a self) -> Chain<Items<'a,T>,
-                                       Chain<Items<'a,T>,
-                                             Items<'a,T>>> {
-        let (ref r, ref s, ref f) = self.vecs;
-        r.iter().chain(s.iter().chain(f.iter()))
+    pub fn iter<'a>(&'a self) -> Items<'a,T> {
+        self.content.iter()
     }
 
-    pub fn all_vecs(&self, pred: |&Vec<T>| -> bool) -> bool {
-        self.vecs.iter().all(pred)
+    pub fn all_vecs(&self, pred: |&[T]| -> bool) -> bool {
+        let spaces = [TypeSpace, SelfSpace, FnSpace];
+        spaces.iter().all(|&space| { pred(self.get_slice(space)) })
     }
 
     pub fn all(&self, pred: |&T| -> bool) -> bool {
@@ -353,9 +433,13 @@ pub fn is_empty(&self) -> bool {
     }
 
     pub fn map<U>(&self, pred: |&T| -> U) -> VecPerParamSpace<U> {
-        VecPerParamSpace::new(self.vecs.ref0().iter().map(|p| pred(p)).collect(),
-                              self.vecs.ref1().iter().map(|p| pred(p)).collect(),
-                              self.vecs.ref2().iter().map(|p| pred(p)).collect())
+        // FIXME (#15418): this could avoid allocating the intermediate
+        // Vec's, but note that the values of type_limit and self_limit
+        // also need to be kept in sync during construction.
+        VecPerParamSpace::new(
+            self.get_slice(TypeSpace).iter().map(|p| pred(p)).collect(),
+            self.get_slice(SelfSpace).iter().map(|p| pred(p)).collect(),
+            self.get_slice(FnSpace).iter().map(|p| pred(p)).collect())
     }
 
     pub fn map_rev<U>(&self, pred: |&T| -> U) -> VecPerParamSpace<U> {
@@ -368,29 +452,46 @@ pub fn map_rev<U>(&self, pred: |&T| -> U) -> VecPerParamSpace<U> {
          * can be run to a fixed point
          */
 
-        let mut fns: Vec<U> = self.vecs.ref2().iter().rev().map(|p| pred(p)).collect();
+        let mut fns: Vec<U> = self.get_slice(FnSpace).iter().rev().map(|p| pred(p)).collect();
 
         // NB: Calling foo.rev().map().rev() causes the calls to map
         // to occur in the wrong order. This was somewhat surprising
         // to me, though it makes total sense.
         fns.reverse();
 
-        let mut selfs: Vec<U> = self.vecs.ref1().iter().rev().map(|p| pred(p)).collect();
+        let mut selfs: Vec<U> = self.get_slice(SelfSpace).iter().rev().map(|p| pred(p)).collect();
         selfs.reverse();
-        let mut tys: Vec<U> = self.vecs.ref0().iter().rev().map(|p| pred(p)).collect();
+        let mut tys: Vec<U> = self.get_slice(TypeSpace).iter().rev().map(|p| pred(p)).collect();
         tys.reverse();
         VecPerParamSpace::new(tys, selfs, fns)
     }
 
     pub fn split(self) -> (Vec<T>, Vec<T>, Vec<T>) {
-        self.vecs
+        // FIXME (#15418): this does two traversals when in principle
+        // one would suffice.  i.e. change to use `move_iter`.
+        let VecPerParamSpace { type_limit, self_limit, content } = self;
+        let mut i = 0;
+        let (prefix, fn_vec) = content.partition(|_| {
+            let on_left = i < self_limit;
+            i += 1;
+            on_left
+        });
+
+        let mut i = 0;
+        let (type_vec, self_vec) = prefix.partition(|_| {
+            let on_left = i < type_limit;
+            i += 1;
+            on_left
+        });
+
+        (type_vec, self_vec, fn_vec)
     }
 
     pub fn with_vec(mut self, space: ParamSpace, vec: Vec<T>)
                     -> VecPerParamSpace<T>
     {
-        assert!(self.get_vec(space).is_empty());
-        *self.get_mut_vec(space) = vec;
+        assert!(self.is_empty_in(space));
+        self.replace(space, vec);
         self
     }
 }
index 2f8918acb30bc30d8700ed3b954338b3ad36b037..3cfd1aaee8ff39a37e0f6c9a9d1dcfccdd01cfcd 100644 (file)
 use middle::trans::debuginfo;
 use middle::ty;
 use util::common::indenter;
-use util::ppaux::{Repr, vec_map_to_str};
+use util::ppaux::{Repr, vec_map_to_string};
 
 use std;
 use std::collections::HashMap;
@@ -409,30 +409,29 @@ fn expand_nested_bindings<'a, 'b>(
            bcx.to_str(),
            m.repr(bcx.tcx()),
            col,
-           bcx.val_to_str(val));
+           bcx.val_to_string(val));
     let _indenter = indenter();
 
     m.iter().map(|br| {
-        match br.pats.get(col).node {
-            ast::PatIdent(_, ref path1, Some(inner)) => {
-                let pats = Vec::from_slice(br.pats.slice(0u, col))
-                           .append((vec!(inner))
-                                   .append(br.pats.slice(col + 1u, br.pats.len())).as_slice());
-
-                let mut bound_ptrs = br.bound_ptrs.clone();
-                bound_ptrs.push((path1.node, val));
-                Match {
-                    pats: pats,
-                    data: &*br.data,
-                    bound_ptrs: bound_ptrs
-                }
-            }
-            _ => Match {
-                pats: br.pats.clone(),
-                data: &*br.data,
-                bound_ptrs: br.bound_ptrs.clone()
+        let mut bound_ptrs = br.bound_ptrs.clone();
+        let mut pat = *br.pats.get(col);
+        loop {
+            pat = match pat.node {
+                ast::PatIdent(_, ref path, Some(inner)) => {
+                    bound_ptrs.push((path.node, val));
+                    inner.clone()
+                },
+                _ => break
             }
         }
+
+        let mut pats = br.pats.clone();
+        *pats.get_mut(col) = pat;
+        Match {
+            pats: pats,
+            data: &*br.data,
+            bound_ptrs: bound_ptrs
+        }
     }).collect()
 }
 
@@ -450,7 +449,7 @@ fn enter_match<'a, 'b>(
            bcx.to_str(),
            m.repr(bcx.tcx()),
            col,
-           bcx.val_to_str(val));
+           bcx.val_to_string(val));
     let _indenter = indenter();
 
     m.iter().filter_map(|br| {
@@ -486,7 +485,7 @@ fn enter_default<'a, 'b>(
            bcx.to_str(),
            m.repr(bcx.tcx()),
            col,
-           bcx.val_to_str(val));
+           bcx.val_to_string(val));
     let _indenter = indenter();
 
     // Collect all of the matches that can match against anything.
@@ -542,7 +541,7 @@ fn enter_opt<'a, 'b>(
            m.repr(bcx.tcx()),
            *opt,
            col,
-           bcx.val_to_str(val));
+           bcx.val_to_string(val));
     let _indenter = indenter();
 
     let ctor = match opt {
@@ -781,9 +780,9 @@ fn extract_vec_elems<'a>(
 // matches should fit that sort of pattern or NONE (however, some of the
 // matches may be wildcards like _ or identifiers).
 macro_rules! any_pat (
-    ($m:expr, $pattern:pat) => (
+    ($m:expr, $col:expr, $pattern:pat) => (
         ($m).iter().any(|br| {
-            match br.pats.get(col).node {
+            match br.pats.get($col).node {
                 $pattern => true,
                 _ => false
             }
@@ -792,11 +791,11 @@ macro_rules! any_pat (
 )
 
 fn any_uniq_pat(m: &[Match], col: uint) -> bool {
-    any_pat!(m, ast::PatBox(_))
+    any_pat!(m, col, ast::PatBox(_))
 }
 
 fn any_region_pat(m: &[Match], col: uint) -> bool {
-    any_pat!(m, ast::PatRegion(_))
+    any_pat!(m, col, ast::PatRegion(_))
 }
 
 fn any_irrefutable_adt_pat(bcx: &Block, m: &[Match], col: uint) -> bool {
@@ -804,12 +803,19 @@ fn any_irrefutable_adt_pat(bcx: &Block, m: &[Match], col: uint) -> bool {
         let pat = *br.pats.get(col);
         match pat.node {
             ast::PatTup(_) => true,
-            ast::PatEnum(..) | ast::PatIdent(_, _, None) | ast::PatStruct(..) =>
+            ast::PatStruct(..) => {
+                match bcx.tcx().def_map.borrow().find(&pat.id) {
+                    Some(&def::DefVariant(..)) => false,
+                    _ => true,
+                }
+            }
+            ast::PatEnum(..) | ast::PatIdent(_, _, None) => {
                 match bcx.tcx().def_map.borrow().find(&pat.id) {
                     Some(&def::DefFn(..)) |
                     Some(&def::DefStruct(..)) => true,
                     _ => false
-                },
+                }
+            }
             _ => false
         }
     })
@@ -916,7 +922,7 @@ fn compare_str<'a>(cx: &'a Block<'a>,
         let did = langcall(cx,
                            None,
                            format!("comparison of `{}`",
-                                   cx.ty_to_str(rhs_t)).as_slice(),
+                                   cx.ty_to_string(rhs_t)).as_slice(),
                            StrEqFnLangItem);
         callee::trans_lang_call(cx, did, [lhs, rhs], None)
     }
@@ -947,8 +953,8 @@ fn compare_str<'a>(cx: &'a Block<'a>,
     }
 }
 
-fn insert_lllocals<'a>(mut bcx: &'a Block<'a>,
-                       bindings_map: &BindingsMap)
+fn insert_lllocals<'a>(mut bcx: &'a Block<'a>, bindings_map: &BindingsMap,
+                       cs: Option<cleanup::ScopeId>)
                        -> &'a Block<'a> {
     /*!
      * For each binding in `data.bindings_map`, adds an appropriate entry into
@@ -975,10 +981,14 @@ fn insert_lllocals<'a>(mut bcx: &'a Block<'a>,
         };
 
         let datum = Datum::new(llval, binding_info.ty, Lvalue);
+        match cs {
+            Some(cs) => bcx.fcx.schedule_drop_and_zero_mem(cs, llval, binding_info.ty),
+            _ => {}
+        }
 
         debug!("binding {:?} to {}",
                binding_info.id,
-               bcx.val_to_str(llval));
+               bcx.val_to_string(llval));
         bcx.fcx.lllocals.borrow_mut().insert(binding_info.id, datum);
 
         if bcx.sess().opts.debuginfo == FullDebugInfo {
@@ -1001,12 +1011,12 @@ fn compile_guard<'a, 'b>(
                  -> &'b Block<'b> {
     debug!("compile_guard(bcx={}, guard_expr={}, m={}, vals={})",
            bcx.to_str(),
-           bcx.expr_to_str(guard_expr),
+           bcx.expr_to_string(guard_expr),
            m.repr(bcx.tcx()),
-           vec_map_to_str(vals, |v| bcx.val_to_str(*v)));
+           vec_map_to_string(vals, |v| bcx.val_to_string(*v)));
     let _indenter = indenter();
 
-    let mut bcx = insert_lllocals(bcx, &data.bindings_map);
+    let mut bcx = insert_lllocals(bcx, &data.bindings_map, None);
 
     let val = unpack_datum!(bcx, expr::trans(bcx, guard_expr));
     let val = val.to_llbool(bcx);
@@ -1040,7 +1050,7 @@ fn compile_submatch<'a, 'b>(
     debug!("compile_submatch(bcx={}, m={}, vals={})",
            bcx.to_str(),
            m.repr(bcx.tcx()),
-           vec_map_to_str(vals, |v| bcx.val_to_str(*v)));
+           vec_map_to_string(vals, |v| bcx.val_to_string(*v)));
     let _indenter = indenter();
     let _icx = push_ctxt("match::compile_submatch");
     let mut bcx = bcx;
@@ -1145,7 +1155,7 @@ fn compile_submatch_continue<'a, 'b>(
     debug!("options={:?}", opts);
     let mut kind = no_branch;
     let mut test_val = val;
-    debug!("test_val={}", bcx.val_to_str(test_val));
+    debug!("test_val={}", bcx.val_to_string(test_val));
     if opts.len() > 0u {
         match *opts.get(0) {
             var(_, ref repr, _) => {
@@ -1460,9 +1470,11 @@ fn trans_match_inner<'a>(scope_cx: &'a Block<'a>,
     for arm_data in arm_datas.iter() {
         let mut bcx = arm_data.bodycx;
 
-        // insert bindings into the lllocals map
-        bcx = insert_lllocals(bcx, &arm_data.bindings_map);
+        // insert bindings into the lllocals map and add cleanups
+        let cs = fcx.push_custom_cleanup_scope();
+        bcx = insert_lllocals(bcx, &arm_data.bindings_map, Some(cleanup::CustomScope(cs)));
         bcx = expr::trans_into(bcx, &*arm_data.arm.body, dest);
+        bcx = fcx.pop_and_trans_custom_cleanup_scope(bcx, cs);
         arm_cxs.push(bcx);
     }
 
index d21ee37f2912ef11d570f57ff104810dbc455de9..898cb036ea5374954c7bd9d59a812135cc9569cf 100644 (file)
@@ -63,7 +63,7 @@
 use syntax::ast;
 use syntax::attr;
 use syntax::attr::IntType;
-use util::ppaux::ty_to_str;
+use util::ppaux::ty_to_string;
 
 type Hint = attr::ReprAttr;
 
@@ -111,7 +111,7 @@ pub enum Repr {
     StructWrappedNullablePointer {
         pub nonnull: Struct,
         pub nndiscr: Disr,
-        pub ptrfield: uint,
+        pub ptrfield: PointerField,
         pub nullfields: Vec<ty::t>,
     }
 }
@@ -135,7 +135,7 @@ pub fn represent_node(bcx: &Block, node: ast::NodeId) -> Rc<Repr> {
 
 /// Decides how to represent a given type.
 pub fn represent_type(cx: &CrateContext, t: ty::t) -> Rc<Repr> {
-    debug!("Representing: {}", ty_to_str(cx.tcx(), t));
+    debug!("Representing: {}", ty_to_string(cx.tcx(), t));
     match cx.adt_reprs.borrow().find(&t) {
         Some(repr) => return repr.clone(),
         None => {}
@@ -211,24 +211,21 @@ fn represent_type_uncached(cx: &CrateContext, t: ty::t) -> Repr {
                 let mut discr = 0;
                 while discr < 2 {
                     if cases.get(1 - discr).is_zerolen(cx) {
+                        let st = mk_struct(cx, cases.get(discr).tys.as_slice(), false);
                         match cases.get(discr).find_ptr() {
+                            Some(ThinPointer(_)) if st.fields.len() == 1 => {
+                                return RawNullablePointer {
+                                    nndiscr: discr as Disr,
+                                    nnty: *st.fields.get(0),
+                                    nullfields: cases.get(1 - discr).tys.clone()
+                                };
+                            }
                             Some(ptrfield) => {
-                                let st = mk_struct(cx, cases.get(discr).tys.as_slice(),
-                                                   false);
-
-                                return if st.fields.len() == 1 {
-                                    RawNullablePointer {
-                                        nndiscr: discr as Disr,
-                                        nnty: *st.fields.get(0),
-                                        nullfields: cases.get(1 - discr).tys.clone()
-                                    }
-                                } else {
-                                    StructWrappedNullablePointer {
-                                        nndiscr: discr as Disr,
-                                        nonnull: st,
-                                        ptrfield: ptrfield,
-                                        nullfields: cases.get(1 - discr).tys.clone()
-                                    }
+                                return StructWrappedNullablePointer {
+                                    nndiscr: discr as Disr,
+                                    nonnull: st,
+                                    ptrfield: ptrfield,
+                                    nullfields: cases.get(1 - discr).tys.clone()
                                 };
                             }
                             None => { }
@@ -283,23 +280,67 @@ pub fn is_ffi_safe(tcx: &ty::ctxt, def_id: ast::DefId) -> bool {
 }
 
 // this should probably all be in ty
-struct Case { discr: Disr, tys: Vec<ty::t> }
+struct Case {
+    discr: Disr,
+    tys: Vec<ty::t>
+}
+
+
+#[deriving(Show)]
+pub enum PointerField {
+    ThinPointer(uint),
+    FatPointer(uint, uint)
+}
+
 impl Case {
     fn is_zerolen(&self, cx: &CrateContext) -> bool {
         mk_struct(cx, self.tys.as_slice(), false).size == 0
     }
-    fn find_ptr(&self) -> Option<uint> {
-        self.tys.iter().position(|&ty| {
+    fn find_ptr(&self) -> Option<PointerField> {
+        use back::abi::{fn_field_code, slice_elt_base, trt_field_box};
+
+        for (i, &ty) in self.tys.iter().enumerate() {
             match ty::get(ty).sty {
-                ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => match ty::get(ty).sty {
-                    ty::ty_vec(_, None) | ty::ty_str| ty::ty_trait(..) => false,
-                    _ => true,
+                // &T/&mut T could either be a thin or fat pointer depending on T
+                ty::ty_rptr(_, ty::mt { ty, .. }) => match ty::get(ty).sty {
+                    // &[T] and &str are a pointer and length pair
+                    ty::ty_vec(_, None) | ty::ty_str => return Some(FatPointer(i, slice_elt_base)),
+
+                    // &Trait/&mut Trait are a pair of pointers: the actual object and a vtable
+                    ty::ty_trait(..) => return Some(FatPointer(i, trt_field_box)),
+
+                    // Any other &T/&mut T is just a pointer
+                    _ => return Some(ThinPointer(i))
+                },
+
+                // Box<T> could either be a thin or fat pointer depending on T
+                ty::ty_uniq(t) => match ty::get(t).sty {
+                    // Box<[T]>/Box<str> might be FatPointer in a post DST world
+                    ty::ty_vec(_, None) | ty::ty_str => continue,
+
+                    // Box<Trait> is a pair of pointers: the actual object and a vtable
+                    ty::ty_trait(..) => return Some(FatPointer(i, trt_field_box)),
+
+                    // Any other Box<T> is just a pointer
+                    _ => return Some(ThinPointer(i))
                 },
-                ty::ty_box(..) | ty::ty_bare_fn(..) => true,
-                // Is that everything?  Would closures or slices qualify?
-                _ => false
+
+                // Gc<T> is just a pointer
+                ty::ty_box(..) => return Some(ThinPointer(i)),
+
+                // Functions are just pointers
+                ty::ty_bare_fn(..) => return Some(ThinPointer(i)),
+
+                // Closures are a pair of pointers: the code and environment
+                ty::ty_closure(..) => return Some(FatPointer(i, fn_field_code)),
+
+                // Anything else is not a pointer
+                _ => continue
+
             }
-        })
+        }
+
+        None
     }
 }
 
@@ -552,8 +593,8 @@ pub fn trans_get_discr(bcx: &Block, r: &Repr, scrutinee: ValueRef, cast_to: Opti
             val = ICmp(bcx, cmp, Load(bcx, scrutinee), C_null(llptrty));
             signed = false;
         }
-        StructWrappedNullablePointer { nonnull: ref nonnull, nndiscr, ptrfield, .. } => {
-            val = struct_wrapped_nullable_bitdiscr(bcx, nonnull, nndiscr, ptrfield, scrutinee);
+        StructWrappedNullablePointer { nndiscr, ptrfield, .. } => {
+            val = struct_wrapped_nullable_bitdiscr(bcx, nndiscr, ptrfield, scrutinee);
             signed = false;
         }
     }
@@ -563,12 +604,15 @@ pub fn trans_get_discr(bcx: &Block, r: &Repr, scrutinee: ValueRef, cast_to: Opti
     }
 }
 
-fn struct_wrapped_nullable_bitdiscr(bcx: &Block, nonnull: &Struct, nndiscr: Disr, ptrfield: uint,
+fn struct_wrapped_nullable_bitdiscr(bcx: &Block, nndiscr: Disr, ptrfield: PointerField,
                                     scrutinee: ValueRef) -> ValueRef {
-    let llptr = Load(bcx, GEPi(bcx, scrutinee, [0, ptrfield]));
+    let llptrptr = match ptrfield {
+        ThinPointer(field) => GEPi(bcx, scrutinee, [0, field]),
+        FatPointer(field, pair) => GEPi(bcx, scrutinee, [0, field, pair])
+    };
+    let llptr = Load(bcx, llptrptr);
     let cmp = if nndiscr == 0 { IntEQ } else { IntNE };
-    let llptrty = type_of::type_of(bcx.ccx(), *nonnull.fields.get(ptrfield));
-    ICmp(bcx, cmp, llptr, C_null(llptrty))
+    ICmp(bcx, cmp, llptr, C_null(val_ty(llptr)))
 }
 
 /// Helper for cases where the discriminant is simply loaded.
@@ -618,7 +662,7 @@ pub fn trans_case<'a>(bcx: &'a Block<'a>, r: &Repr, discr: Disr)
         RawNullablePointer { .. } |
         StructWrappedNullablePointer { .. } => {
             assert!(discr == 0 || discr == 1);
-            _match::single_result(Result::new(bcx, C_i1(bcx.ccx(), discr != 0)))
+            _match::single_result(Result::new(bcx, C_bool(bcx.ccx(), discr != 0)))
         }
     }
 }
@@ -641,7 +685,7 @@ pub fn trans_start_init(bcx: &Block, r: &Repr, val: ValueRef, discr: Disr) {
         }
         Univariant(ref st, true) => {
             assert_eq!(discr, 0);
-            Store(bcx, C_bool(bcx.ccx(), true),
+            Store(bcx, C_u8(bcx.ccx(), 1),
                   GEPi(bcx, val, [0, st.fields.len() - 1]))
         }
         Univariant(..) => {
@@ -655,9 +699,15 @@ pub fn trans_start_init(bcx: &Block, r: &Repr, val: ValueRef, discr: Disr) {
         }
         StructWrappedNullablePointer { nonnull: ref nonnull, nndiscr, ptrfield, .. } => {
             if discr != nndiscr {
-                let llptrptr = GEPi(bcx, val, [0, ptrfield]);
-                let llptrty = type_of::type_of(bcx.ccx(),
-                                               *nonnull.fields.get(ptrfield));
+                let (llptrptr, llptrty) = match ptrfield {
+                    ThinPointer(field) =>
+                        (GEPi(bcx, val, [0, field]),
+                         type_of::type_of(bcx.ccx(), *nonnull.fields.get(field))),
+                    FatPointer(field, pair) => {
+                        let v = GEPi(bcx, val, [0, field, pair]);
+                        (v, val_ty(v).element_type())
+                    }
+                };
                 Store(bcx, C_null(llptrty), llptrptr)
             }
         }
@@ -925,7 +975,11 @@ pub fn const_get_discrim(ccx: &CrateContext, r: &Repr, val: ValueRef)
             }
         }
         StructWrappedNullablePointer { nndiscr, ptrfield, .. } => {
-            if is_null(const_struct_field(ccx, val, ptrfield)) {
+            let (idx, sub_idx) = match ptrfield {
+                ThinPointer(field) => (field, None),
+                FatPointer(field, pair) => (field, Some(pair))
+            };
+            if is_null(const_struct_field(ccx, val, idx, sub_idx)) {
                 /* subtraction as uint is ok because nndiscr is either 0 or 1 */
                 (1 - nndiscr) as Disr
             } else {
@@ -946,18 +1000,18 @@ pub fn const_get_field(ccx: &CrateContext, r: &Repr, val: ValueRef,
                        _discr: Disr, ix: uint) -> ValueRef {
     match *r {
         CEnum(..) => ccx.sess().bug("element access in C-like enum const"),
-        Univariant(..) => const_struct_field(ccx, val, ix),
-        General(..) => const_struct_field(ccx, val, ix + 1),
+        Univariant(..) => const_struct_field(ccx, val, ix, None),
+        General(..) => const_struct_field(ccx, val, ix + 1, None),
         RawNullablePointer { .. } => {
             assert_eq!(ix, 0);
             val
         }
-        StructWrappedNullablePointer{ .. } => const_struct_field(ccx, val, ix)
+        StructWrappedNullablePointer{ .. } => const_struct_field(ccx, val, ix, None)
     }
 }
 
 /// Extract field of struct-like const, skipping our alignment padding.
-fn const_struct_field(ccx: &CrateContext, val: ValueRef, ix: uint)
+fn const_struct_field(ccx: &CrateContext, val: ValueRef, ix: uint, sub_idx: Option<uint>)
     -> ValueRef {
     // Get the ix-th non-undef element of the struct.
     let mut real_ix = 0; // actual position in the struct
@@ -965,7 +1019,10 @@ fn const_struct_field(ccx: &CrateContext, val: ValueRef, ix: uint)
     let mut field;
     loop {
         loop {
-            field = const_get_elt(ccx, val, [real_ix]);
+            field = match sub_idx {
+                Some(si) => const_get_elt(ccx, val, [real_ix, si as u32]),
+                None => const_get_elt(ccx, val, [real_ix])
+            };
             if !is_undef(field) {
                 break;
             }
index 75271804b7911b32be2380cbfffc9d8015e824dc..84b253306ff57ccf9a79adeca63140a4388c3ccb 100644 (file)
@@ -30,7 +30,6 @@
 use driver::config;
 use driver::config::{NoDebugInfo, FullDebugInfo};
 use driver::session::Session;
-use driver::driver::OutputFilenames;
 use driver::driver::{CrateAnalysis, CrateTranslation};
 use lib::llvm::{ModuleRef, ValueRef, BasicBlockRef};
 use lib::llvm::{llvm, Vector};
@@ -72,7 +71,7 @@
 use middle::ty;
 use middle::typeck;
 use util::common::indenter;
-use util::ppaux::{Repr, ty_to_str};
+use util::ppaux::{Repr, ty_to_string};
 use util::sha2::Sha256;
 use util::nodemap::NodeMap;
 
@@ -302,7 +301,7 @@ fn require_alloc_fn(bcx: &Block, info_ty: ty::t, it: LangItem) -> ast::DefId {
         Ok(id) => id,
         Err(s) => {
             bcx.sess().fatal(format!("allocation of `{}` {}",
-                                     bcx.ty_to_str(info_ty),
+                                     bcx.ty_to_string(info_ty),
                                      s).as_slice());
         }
     }
@@ -539,8 +538,8 @@ fn die(cx: &Block) -> ! {
         // We don't need to do actual comparisons for nil.
         // () == () holds but () < () does not.
         match op {
-          ast::BiEq | ast::BiLe | ast::BiGe => return C_i1(cx.ccx(), true),
-          ast::BiNe | ast::BiLt | ast::BiGt => return C_i1(cx.ccx(), false),
+          ast::BiEq | ast::BiLe | ast::BiGe => return C_bool(cx.ccx(), true),
+          ast::BiNe | ast::BiLt | ast::BiGt => return C_bool(cx.ccx(), false),
           // refinements would be nice
           _ => die(cx)
         }
@@ -707,7 +706,7 @@ fn iter_variant<'r,
                       let variant_cx =
                           fcx.new_temp_block(
                               format!("enum-iter-variant-{}",
-                                      variant.disr_val.to_str().as_slice())
+                                      variant.disr_val.to_string().as_slice())
                                      .as_slice());
                       match adt::trans_case(cx, &*repr, variant.disr_val) {
                           _match::single_result(r) => {
@@ -810,7 +809,7 @@ pub fn fail_if_zero_or_overflows<'a>(
         }
         _ => {
             cx.sess().bug(format!("fail-if-zero on unexpected type: {}",
-                                  ty_to_str(cx.tcx(), rhs_t)).as_slice());
+                                  ty_to_string(cx.tcx(), rhs_t)).as_slice());
         }
     };
     let bcx = with_cond(cx, is_zero, |bcx| {
@@ -904,7 +903,7 @@ pub fn invoke<'a>(
             debug!("invoke at ???");
         }
         Some(id) => {
-            debug!("invoke at {}", bcx.tcx().map.node_to_str(id));
+            debug!("invoke at {}", bcx.tcx().map.node_to_string(id));
         }
     }
 
@@ -959,10 +958,42 @@ pub fn need_invoke(bcx: &Block) -> bool {
 
 pub fn load_if_immediate(cx: &Block, v: ValueRef, t: ty::t) -> ValueRef {
     let _icx = push_ctxt("load_if_immediate");
-    if type_is_immediate(cx.ccx(), t) { return Load(cx, v); }
+    if type_is_immediate(cx.ccx(), t) { return load_ty(cx, v, t); }
     return v;
 }
 
+pub fn load_ty(cx: &Block, ptr: ValueRef, t: ty::t) -> ValueRef {
+    /*!
+     * Helper for loading values from memory. Does the necessary conversion if
+     * the in-memory type differs from the type used for SSA values. Also
+     * handles various special cases where the type gives us better information
+     * about what we are loading.
+     */
+    if type_is_zero_size(cx.ccx(), t) {
+        C_undef(type_of::type_of(cx.ccx(), t))
+    } else if ty::type_is_bool(t) {
+        Trunc(cx, LoadRangeAssert(cx, ptr, 0, 2, lib::llvm::False), Type::i1(cx.ccx()))
+    } else if ty::type_is_char(t) {
+        // a char is a unicode codepoint, and so takes values from 0
+        // to 0x10FFFF inclusive only.
+        LoadRangeAssert(cx, ptr, 0, 0x10FFFF + 1, lib::llvm::False)
+    } else {
+        Load(cx, ptr)
+    }
+}
+
+pub fn store_ty(cx: &Block, v: ValueRef, dst: ValueRef, t: ty::t) {
+    /*!
+     * Helper for storing values in memory. Does the necessary conversion if
+     * the in-memory type differs from the type used for SSA values.
+     */
+    if ty::type_is_bool(t) {
+        Store(cx, ZExt(cx, v, Type::i8(cx.ccx())), dst);
+    } else {
+        Store(cx, v, dst);
+    };
+}
+
 pub fn ignore_lhs(_bcx: &Block, local: &ast::Local) -> bool {
     match local.pat.node {
         ast::PatWild => true, _ => false
@@ -1014,7 +1045,7 @@ pub fn call_memcpy(cx: &Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef,
     let dst_ptr = PointerCast(cx, dst, Type::i8p(ccx));
     let size = IntCast(cx, n_bytes, ccx.int_type);
     let align = C_i32(ccx, align as i32);
-    let volatile = C_i1(ccx, false);
+    let volatile = C_bool(ccx, false);
     Call(cx, memcpy, [dst_ptr, src_ptr, size, align, volatile], []);
 }
 
@@ -1059,7 +1090,7 @@ fn memzero(b: &Builder, llptr: ValueRef, ty: Type) {
     let llzeroval = C_u8(ccx, 0);
     let size = machine::llsize_of(ccx, ty);
     let align = C_i32(ccx, llalign_of_min(ccx, ty) as i32);
-    let volatile = C_i1(ccx, false);
+    let volatile = C_bool(ccx, false);
     b.call(llintrinsicfn, [llptr, llzeroval, size, align, volatile], []);
 }
 
@@ -1113,8 +1144,7 @@ pub fn make_return_pointer(fcx: &FunctionContext, output_type: ty::t)
             llvm::LLVMGetParam(fcx.llfn, 0)
         } else {
             let lloutputtype = type_of::type_of(fcx.ccx, output_type);
-            let bcx = fcx.entry_bcx.borrow().clone().unwrap();
-            Alloca(bcx, lloutputtype, "__make_return_pointer")
+            AllocaFcx(fcx, lloutputtype, "__make_return_pointer")
         }
     }
 }
@@ -1143,7 +1173,7 @@ pub fn new_fn_ctxt<'a>(ccx: &'a CrateContext,
            if id == -1 {
                "".to_string()
            } else {
-               ccx.tcx.map.path_to_str(id).to_string()
+               ccx.tcx.map.path_to_string(id).to_string()
            },
            id, param_substs.repr(ccx.tcx()));
 
@@ -1155,7 +1185,6 @@ pub fn new_fn_ctxt<'a>(ccx: &'a CrateContext,
           llfn: llfndecl,
           llenv: None,
           llretptr: Cell::new(None),
-          entry_bcx: RefCell::new(None),
           alloca_insert_pt: Cell::new(None),
           llreturn: Cell::new(None),
           personality: Cell::new(None),
@@ -1185,11 +1214,9 @@ pub fn new_fn_ctxt<'a>(ccx: &'a CrateContext,
 /// and allocating space for the return pointer.
 pub fn init_function<'a>(fcx: &'a FunctionContext<'a>,
                          skip_retptr: bool,
-                         output_type: ty::t) {
+                         output_type: ty::t) -> &'a Block<'a> {
     let entry_bcx = fcx.new_temp_block("entry-block");
 
-    *fcx.entry_bcx.borrow_mut() = Some(entry_bcx);
-
     // Use a dummy instruction as the insertion point for all allocas.
     // This is later removed in FunctionContext::cleanup.
     fcx.alloca_insert_pt.set(Some(unsafe {
@@ -1211,6 +1238,8 @@ pub fn init_function<'a>(fcx: &'a FunctionContext<'a>,
             fcx.llretptr.set(Some(make_return_pointer(fcx, substd_output_type)));
         }
     }
+
+    entry_bcx
 }
 
 // NB: must keep 4 fns in sync:
@@ -1285,9 +1314,14 @@ fn copy_args_to_allocas<'a>(fcx: &FunctionContext<'a>,
 // Ties up the llstaticallocas -> llloadenv -> lltop edges,
 // and builds the return block.
 pub fn finish_fn<'a>(fcx: &'a FunctionContext<'a>,
-                     last_bcx: &'a Block<'a>) {
+                     last_bcx: &'a Block<'a>,
+                     retty: ty::t) {
     let _icx = push_ctxt("finish_fn");
 
+    // This shouldn't need to recompute the return type,
+    // as new_fn_ctxt did it already.
+    let substd_retty = retty.substp(fcx.ccx.tcx(), fcx.param_substs);
+
     let ret_cx = match fcx.llreturn.get() {
         Some(llreturn) => {
             if !last_bcx.terminated.get() {
@@ -1297,13 +1331,13 @@ pub fn finish_fn<'a>(fcx: &'a FunctionContext<'a>,
         }
         None => last_bcx
     };
-    build_return_block(fcx, ret_cx);
+    build_return_block(fcx, ret_cx, substd_retty);
     debuginfo::clear_source_location(fcx);
     fcx.cleanup();
 }
 
 // Builds the return block for a function.
-pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block) {
+pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block, retty: ty::t) {
     // Return the value if this function immediate; otherwise, return void.
     if fcx.llretptr.get().is_none() || fcx.caller_expects_out_pointer {
         return RetVoid(ret_cx);
@@ -1321,13 +1355,16 @@ pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block) {
                 retptr.erase_from_parent();
             }
 
-            retval
+            if ty::type_is_bool(retty) {
+                Trunc(ret_cx, retval, Type::i1(fcx.ccx))
+            } else {
+                retval
+            }
         }
         // Otherwise, load the return value from the ret slot
-        None => Load(ret_cx, fcx.llretptr.get().unwrap())
+        None => load_ty(ret_cx, fcx.llretptr.get().unwrap(), retty)
     };
 
-
     Ret(ret_cx, retval);
 }
 
@@ -1365,15 +1402,11 @@ pub fn trans_closure(ccx: &CrateContext,
                           param_substs,
                           Some(body.span),
                           &arena);
-    init_function(&fcx, false, output_type);
+    let mut bcx = init_function(&fcx, false, output_type);
 
     // cleanup scope for the incoming arguments
     let arg_scope = fcx.push_custom_cleanup_scope();
 
-    // Create the first basic block in the function and keep a handle on it to
-    //  pass to finish_fn later.
-    let bcx_top = fcx.entry_bcx.borrow().clone().unwrap();
-    let mut bcx = bcx_top;
     let block_ty = node_id_type(bcx, body.id);
 
     // Set up arguments to the function.
@@ -1429,7 +1462,7 @@ pub fn trans_closure(ccx: &CrateContext,
     }
 
     // Insert the mandatory first few basic blocks before lltop.
-    finish_fn(&fcx, bcx);
+    finish_fn(&fcx, bcx, output_type);
 }
 
 // trans_fn: creates an LLVM function corresponding to a source language
@@ -1441,7 +1474,7 @@ pub fn trans_fn(ccx: &CrateContext,
                 param_substs: &param_substs,
                 id: ast::NodeId,
                 attrs: &[ast::Attribute]) {
-    let _s = StatRecorder::new(ccx, ccx.tcx.map.path_to_str(id).to_string());
+    let _s = StatRecorder::new(ccx, ccx.tcx.map.path_to_string(id).to_string());
     debug!("trans_fn(param_substs={})", param_substs.repr(ccx.tcx()));
     let _icx = push_ctxt("trans_fn");
     let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx(), id));
@@ -1494,20 +1527,18 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext,
         _ => ccx.sess().bug(
             format!("trans_enum_variant_or_tuple_like_struct: \
                      unexpected ctor return type {}",
-                    ty_to_str(ccx.tcx(), ctor_ty)).as_slice())
+                    ty_to_string(ccx.tcx(), ctor_ty)).as_slice())
     };
 
     let arena = TypedArena::new();
     let fcx = new_fn_ctxt(ccx, llfndecl, ctor_id, false, result_ty,
                           param_substs, None, &arena);
-    init_function(&fcx, false, result_ty);
+    let bcx = init_function(&fcx, false, result_ty);
 
     let arg_tys = ty::ty_fn_args(ctor_ty);
 
     let arg_datums = create_datums_for_fn_args(&fcx, arg_tys.as_slice());
 
-    let bcx = fcx.entry_bcx.borrow().clone().unwrap();
-
     if !type_is_zero_size(fcx.ccx, result_ty) {
         let repr = adt::represent_type(ccx, result_ty);
         adt::trans_start_init(bcx, &*repr, fcx.llretptr.get().unwrap(), disr);
@@ -1521,7 +1552,7 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext,
         }
     }
 
-    finish_fn(&fcx, bcx);
+    finish_fn(&fcx, bcx, result_ty);
 }
 
 fn trans_enum_def(ccx: &CrateContext, enum_definition: &ast::EnumDef,
@@ -1979,7 +2010,7 @@ fn exported_name(ccx: &CrateContext, id: ast::NodeId,
         _ => ccx.tcx.map.with_path(id, |mut path| {
             if attr::contains_name(attrs, "no_mangle") {
                 // Don't mangle
-                path.last().unwrap().to_str()
+                path.last().unwrap().to_string()
             } else {
                 match weak_lang_items::link_name(attrs) {
                     Some(name) => name.get().to_string(),
@@ -2270,8 +2301,9 @@ pub fn write_metadata(cx: &CrateContext, krate: &ast::Crate) -> Vec<u8> {
                      }.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);
+    let name = format!("rust_metadata_{}_{}",
+                       cx.link_meta.crate_name,
+                       cx.link_meta.crate_hash);
     let llglobal = name.with_c_str(|buf| {
         unsafe {
             llvm::LLVMAddGlobal(cx.metadata_llmod, val_ty(llconst).to_ref(), buf)
@@ -2288,9 +2320,8 @@ pub fn write_metadata(cx: &CrateContext, krate: &ast::Crate) -> Vec<u8> {
 }
 
 pub fn trans_crate(krate: ast::Crate,
-                   analysis: CrateAnalysis,
-                   output: &OutputFilenames) -> (ty::ctxt, CrateTranslation) {
-    let CrateAnalysis { ty_cx: tcx, exp_map2, reachable, .. } = analysis;
+                   analysis: CrateAnalysis) -> (ty::ctxt, CrateTranslation) {
+    let CrateAnalysis { ty_cx: tcx, exp_map2, reachable, name, .. } = analysis;
 
     // Before we touch LLVM, make sure that multithreading is enabled.
     unsafe {
@@ -2310,8 +2341,7 @@ pub fn trans_crate(krate: ast::Crate,
         }
     }
 
-    let link_meta = link::build_link_meta(&krate,
-                                          output.out_filestem.as_slice());
+    let link_meta = link::build_link_meta(&tcx.sess, &krate, name);
 
     // Append ".rs" to crate name as LLVM module identifier.
     //
@@ -2321,7 +2351,7 @@ pub fn trans_crate(krate: ast::Crate,
     // crashes if the module identifier is same as other symbols
     // such as a function name in the module.
     // 1. http://llvm.org/bugs/show_bug.cgi?id=11479
-    let mut llmod_id = link_meta.crateid.name.clone();
+    let mut llmod_id = link_meta.crate_name.clone();
     llmod_id.push_str(".rs");
 
     let ccx = CrateContext::new(llmod_id.as_slice(), tcx, exp_map2,
index e1c02f543bf9e7c4ee2046012efeeeb5ce3c69cc..ce11cd24f7b047688a4e3181a1d44cc0bd0fffcb 100644 (file)
@@ -122,8 +122,8 @@ pub fn Invoke(cx: &Block,
     check_not_terminated(cx);
     terminate(cx, "Invoke");
     debug!("Invoke({} with arguments ({}))",
-           cx.val_to_str(fn_),
-           args.iter().map(|a| cx.val_to_str(*a)).collect::<Vec<String>>().connect(", "));
+           cx.val_to_string(fn_),
+           args.iter().map(|a| cx.val_to_string(*a)).collect::<Vec<String>>().connect(", "));
     B(cx).invoke(fn_, args, then, catch, attributes)
 }
 
index a9c1adac3d7cf01e07c3926d4706708e8a087367..3a9e3e4cf9b07f5162f7b2a512c2e3b39d97b4f0 100644 (file)
@@ -161,9 +161,9 @@ pub fn invoke(&self,
         self.count_insn("invoke");
 
         debug!("Invoke {} with args ({})",
-               self.ccx.tn.val_to_str(llfn),
+               self.ccx.tn.val_to_string(llfn),
                args.iter()
-                   .map(|&v| self.ccx.tn.val_to_str(v))
+                   .map(|&v| self.ccx.tn.val_to_string(v))
                    .collect::<Vec<String>>()
                    .connect(", "));
 
@@ -497,8 +497,8 @@ pub fn load_range_assert(&self, ptr: ValueRef, lo: c_ulonglong,
 
     pub fn store(&self, val: ValueRef, ptr: ValueRef) {
         debug!("Store {} -> {}",
-               self.ccx.tn.val_to_str(val),
-               self.ccx.tn.val_to_str(ptr));
+               self.ccx.tn.val_to_string(val),
+               self.ccx.tn.val_to_string(ptr));
         assert!(self.llbuilder.is_not_null());
         self.count_insn("store");
         unsafe {
@@ -508,8 +508,8 @@ pub fn store(&self, val: ValueRef, ptr: ValueRef) {
 
     pub fn volatile_store(&self, val: ValueRef, ptr: ValueRef) {
         debug!("Store {} -> {}",
-               self.ccx.tn.val_to_str(val),
-               self.ccx.tn.val_to_str(ptr));
+               self.ccx.tn.val_to_string(val),
+               self.ccx.tn.val_to_string(ptr));
         assert!(self.llbuilder.is_not_null());
         self.count_insn("store.volatile");
         unsafe {
@@ -520,8 +520,8 @@ pub fn volatile_store(&self, val: ValueRef, ptr: ValueRef) {
 
     pub fn atomic_store(&self, val: ValueRef, ptr: ValueRef, order: AtomicOrdering) {
         debug!("Store {} -> {}",
-               self.ccx.tn.val_to_str(val),
-               self.ccx.tn.val_to_str(ptr));
+               self.ccx.tn.val_to_string(val),
+               self.ccx.tn.val_to_string(ptr));
         self.count_insn("store.atomic");
         unsafe {
             let ty = Type::from_ref(llvm::LLVMTypeOf(ptr));
@@ -760,7 +760,7 @@ pub fn add_span_comment(&self, sp: Span, text: &str) {
         if self.ccx.sess().asm_comments() {
             let s = format!("{} ({})",
                             text,
-                            self.ccx.sess().codemap().span_to_str(sp));
+                            self.ccx.sess().codemap().span_to_string(sp));
             debug!("{}", s.as_slice());
             self.add_comment(s.as_slice());
         }
@@ -794,11 +794,11 @@ pub fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char,
                          else          { lib::llvm::False };
 
         let argtys = inputs.iter().map(|v| {
-            debug!("Asm Input Type: {:?}", self.ccx.tn.val_to_str(*v));
+            debug!("Asm Input Type: {:?}", self.ccx.tn.val_to_string(*v));
             val_ty(*v)
         }).collect::<Vec<_>>();
 
-        debug!("Asm Output Type: {:?}", self.ccx.tn.type_to_str(output));
+        debug!("Asm Output Type: {:?}", self.ccx.tn.type_to_string(output));
         let fty = Type::func(argtys.as_slice(), &output);
         unsafe {
             let v = llvm::LLVMInlineAsm(
@@ -812,9 +812,9 @@ pub fn call(&self, llfn: ValueRef, args: &[ValueRef],
         self.count_insn("call");
 
         debug!("Call {} with args ({})",
-               self.ccx.tn.val_to_str(llfn),
+               self.ccx.tn.val_to_string(llfn),
                args.iter()
-                   .map(|&v| self.ccx.tn.val_to_str(v))
+                   .map(|&v| self.ccx.tn.val_to_string(v))
                    .collect::<Vec<String>>()
                    .connect(", "));
 
index 01bef64ebba642bf1fa0347de358191b179049eb..c44a4e02ad462a5be8ef51d67934634776880a49 100644 (file)
@@ -85,7 +85,7 @@ fn ty_size(ty: Type) -> uint {
 
 fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
     if is_reg_ty(ty) {
-        let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+        let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
         return ArgType::direct(ty, None, None, attr);
     }
     let size = ty_size(ty);
@@ -104,7 +104,7 @@ fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
 
 fn classify_arg_ty(ccx: &CrateContext, ty: Type) -> ArgType {
     if is_reg_ty(ty) {
-        let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+        let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
         return ArgType::direct(ty, None, None, attr);
     }
     let align = ty_align(ty);
index 60db609e59ed184cc9b7eac69e711be04643296f..9e5b38d2f7ddb4b468505c78b676bc73d5e9bb67 100644 (file)
@@ -85,7 +85,7 @@ fn ty_size(ty: Type) -> uint {
 
 fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
     if is_reg_ty(ty) {
-        let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+        let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
         ArgType::direct(ty, None, None, attr)
     } else {
         ArgType::indirect(ty, Some(StructRetAttribute))
@@ -102,7 +102,7 @@ fn classify_arg_ty(ccx: &CrateContext, ty: Type, offset: &mut uint) -> ArgType {
     *offset += align_up_to(size, align * 8) / 8;
 
     if is_reg_ty(ty) {
-        let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+        let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
         ArgType::direct(ty, None, None, attr)
     } else {
         ArgType::direct(
index 5fffdf08646b9824b9f8b1846fbe9041002bdcd2..0d88c611cbaede78a0a996f6eee4d6f34bc78573 100644 (file)
@@ -59,7 +59,7 @@ enum Strategy { RetValue(Type), RetPointer }
             }
         }
     } else {
-        let attr = if rty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+        let attr = if rty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
         ret_ty = ArgType::direct(rty, None, None, attr);
     }
 
@@ -74,7 +74,7 @@ enum Strategy { RetValue(Type), RetPointer }
                 }
             }
             _ => {
-                let attr = if t == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+                let attr = if t == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
                 ArgType::direct(t, None, None, attr)
             }
         };
index b2cd9d256dd43c4ea9845a3a74cf84d658433166..5b8ddfe1be7bf707d09dcdd1e9736cc53d40bc57 100644 (file)
@@ -350,7 +350,7 @@ fn x86_64_ty(ccx: &CrateContext,
                                 None)
             }
         } else {
-            let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+            let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
             ArgType::direct(ty, None, None, attr)
         }
     }
index 0cc4a9223d49963bd0909253711d2f3c3d8fb806..2e4a3d9fd7e3ed910a1fd38c8a7bbe27c3b3457a 100644 (file)
@@ -108,7 +108,7 @@ fn datum_callee<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {
                     expr.span,
                     format!("type of callee is neither bare-fn nor closure: \
                              {}",
-                            bcx.ty_to_str(datum.ty)).as_slice());
+                            bcx.ty_to_string(datum.ty)).as_slice());
             }
         }
     }
@@ -216,10 +216,8 @@ fn resolve_default_method_vtables(bcx: &Block,
         bcx.tcx(), &param_substs, &impl_res);
 
     // Now we pull any vtables for parameters on the actual method.
-    param_vtables
-        .get_mut_vec(subst::FnSpace)
-        .push_all(
-            impl_vtables.get_vec(subst::FnSpace).as_slice());
+    param_vtables.push_all(subst::FnSpace,
+                           impl_vtables.get_slice(subst::FnSpace));
 
     param_vtables
 }
@@ -279,10 +277,9 @@ pub fn trans_unboxing_shim(bcx: &Block,
                           &empty_param_substs,
                           None,
                           &block_arena);
-    init_function(&fcx, false, return_type);
+    let mut bcx = init_function(&fcx, false, return_type);
 
     // Create the substituted versions of the self type.
-    let mut bcx = fcx.entry_bcx.borrow().clone().unwrap();
     let arg_scope = fcx.push_custom_cleanup_scope();
     let arg_scope_id = cleanup::CustomScope(arg_scope);
     let boxed_arg_types = ty::ty_fn_args(boxed_function_type);
@@ -348,7 +345,7 @@ pub fn trans_unboxing_shim(bcx: &Block,
                            }).bcx;
 
     bcx = fcx.pop_and_trans_custom_cleanup_scope(bcx, arg_scope);
-    finish_fn(&fcx, bcx);
+    finish_fn(&fcx, bcx, return_type);
 
     llfn
 }
@@ -760,7 +757,7 @@ pub fn trans_call_inner<'a>(
                 if !type_of::return_uses_outptr(bcx.ccx(), ret_ty) &&
                     !type_is_zero_size(bcx.ccx(), ret_ty)
                 {
-                    Store(bcx, llret, llretslot);
+                    store_ty(bcx, llret, llretslot, ret_ty)
                 }
             }
             None => {}
@@ -908,7 +905,7 @@ pub fn trans_arg_datum<'a>(
 
     let arg_datum_ty = arg_datum.ty;
 
-    debug!("   arg datum: {}", arg_datum.to_str(bcx.ccx()));
+    debug!("   arg datum: {}", arg_datum.to_string(bcx.ccx()));
 
     let mut val;
     if ty::type_is_bot(arg_datum_ty) {
@@ -952,11 +949,11 @@ pub fn trans_arg_datum<'a>(
             // this could happen due to e.g. subtyping
             let llformal_arg_ty = type_of::type_of_explicit_arg(ccx, formal_arg_ty);
             debug!("casting actual type ({}) to match formal ({})",
-                   bcx.val_to_str(val), bcx.llty_str(llformal_arg_ty));
+                   bcx.val_to_string(val), bcx.llty_str(llformal_arg_ty));
             val = PointerCast(bcx, val, llformal_arg_ty);
         }
     }
 
-    debug!("--- trans_arg_datum passing {}", bcx.val_to_str(val));
+    debug!("--- trans_arg_datum passing {}", bcx.val_to_string(val));
     Result::new(bcx, val)
 }
index 24f30bae75a91fb762330adda0cea01b9bb50bc4..0485b100446577910abe00672a4dc468f1421012 100644 (file)
@@ -85,7 +85,7 @@ fn push_ast_cleanup_scope(&self, id: ast::NodeId) {
          */
 
         debug!("push_ast_cleanup_scope({})",
-               self.ccx.tcx.map.node_to_str(id));
+               self.ccx.tcx.map.node_to_string(id));
 
         // FIXME(#2202) -- currently closure bodies have a parent
         // region, which messes up the assertion below, since there
@@ -109,7 +109,7 @@ fn push_loop_cleanup_scope(&self,
                                id: ast::NodeId,
                                exits: [&'a Block<'a>, ..EXIT_MAX]) {
         debug!("push_loop_cleanup_scope({})",
-               self.ccx.tcx.map.node_to_str(id));
+               self.ccx.tcx.map.node_to_string(id));
         assert_eq!(Some(id), self.top_ast_scope());
 
         self.push_scope(CleanupScope::new(LoopScopeKind(id, exits)));
@@ -133,7 +133,7 @@ fn pop_and_trans_ast_cleanup_scope(&self,
          */
 
         debug!("pop_and_trans_ast_cleanup_scope({})",
-               self.ccx.tcx.map.node_to_str(cleanup_scope));
+               self.ccx.tcx.map.node_to_string(cleanup_scope));
 
         assert!(self.top_scope(|s| s.kind.is_ast_with_id(cleanup_scope)));
 
@@ -152,7 +152,7 @@ fn pop_loop_cleanup_scope(&self,
          */
 
         debug!("pop_loop_cleanup_scope({})",
-               self.ccx.tcx.map.node_to_str(cleanup_scope));
+               self.ccx.tcx.map.node_to_string(cleanup_scope));
 
         assert!(self.top_scope(|s| s.kind.is_loop_with_id(cleanup_scope)));
 
@@ -240,17 +240,45 @@ fn schedule_drop_mem(&self,
             is_immediate: false,
             on_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
             val: val,
-            ty: ty
+            ty: ty,
+            zero: false
         };
 
         debug!("schedule_drop_mem({:?}, val={}, ty={})",
                cleanup_scope,
-               self.ccx.tn.val_to_str(val),
+               self.ccx.tn.val_to_string(val),
                ty.repr(self.ccx.tcx()));
 
         self.schedule_clean(cleanup_scope, drop as Box<Cleanup>);
     }
 
+    fn schedule_drop_and_zero_mem(&self,
+                                  cleanup_scope: ScopeId,
+                                  val: ValueRef,
+                                  ty: ty::t) {
+        /*!
+         * Schedules a (deep) drop and zero-ing of `val`, which is a pointer
+         * to an instance of `ty`
+         */
+
+        if !ty::type_needs_drop(self.ccx.tcx(), ty) { return; }
+        let drop = box DropValue {
+            is_immediate: false,
+            on_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
+            val: val,
+            ty: ty,
+            zero: true
+        };
+
+        debug!("schedule_drop_and_zero_mem({:?}, val={}, ty={}, zero={})",
+               cleanup_scope,
+               self.ccx.tn.val_to_string(val),
+               ty.repr(self.ccx.tcx()),
+               true);
+
+        self.schedule_clean(cleanup_scope, drop as Box<Cleanup>);
+    }
+
     fn schedule_drop_immediate(&self,
                                cleanup_scope: ScopeId,
                                val: ValueRef,
@@ -264,12 +292,13 @@ fn schedule_drop_immediate(&self,
             is_immediate: true,
             on_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
             val: val,
-            ty: ty
+            ty: ty,
+            zero: false
         };
 
         debug!("schedule_drop_immediate({:?}, val={}, ty={})",
                cleanup_scope,
-               self.ccx.tn.val_to_str(val),
+               self.ccx.tn.val_to_string(val),
                ty.repr(self.ccx.tcx()));
 
         self.schedule_clean(cleanup_scope, drop as Box<Cleanup>);
@@ -289,7 +318,7 @@ fn schedule_free_value(&self,
 
         debug!("schedule_free_value({:?}, val={}, heap={:?})",
                cleanup_scope,
-               self.ccx.tn.val_to_str(val),
+               self.ccx.tn.val_to_string(val),
                heap);
 
         self.schedule_clean(cleanup_scope, drop as Box<Cleanup>);
@@ -329,7 +358,7 @@ fn schedule_clean_in_ast_scope(&self,
 
         self.ccx.sess().bug(
             format!("no cleanup scope {} found",
-                    self.ccx.tcx.map.node_to_str(cleanup_scope)).as_slice());
+                    self.ccx.tcx.map.node_to_string(cleanup_scope)).as_slice());
     }
 
     fn schedule_clean_in_custom_scope(&self,
@@ -824,6 +853,7 @@ pub struct DropValue {
     on_unwind: bool,
     val: ValueRef,
     ty: ty::t,
+    zero: bool
 }
 
 impl Cleanup for DropValue {
@@ -832,11 +862,15 @@ fn clean_on_unwind(&self) -> bool {
     }
 
     fn trans<'a>(&self, bcx: &'a Block<'a>) -> &'a Block<'a> {
-        if self.is_immediate {
+        let bcx = if self.is_immediate {
             glue::drop_ty_immediate(bcx, self.val, self.ty)
         } else {
             glue::drop_ty(bcx, self.val, self.ty)
+        };
+        if self.zero {
+            base::zero_mem(bcx, self.val, self.ty);
         }
+        bcx
     }
 }
 
@@ -927,6 +961,10 @@ fn schedule_drop_mem(&self,
                          cleanup_scope: ScopeId,
                          val: ValueRef,
                          ty: ty::t);
+    fn schedule_drop_and_zero_mem(&self,
+                                  cleanup_scope: ScopeId,
+                                  val: ValueRef,
+                                  ty: ty::t);
     fn schedule_drop_immediate(&self,
                                cleanup_scope: ScopeId,
                                val: ValueRef,
index f956b58031cde143c7812b1936d44ea997f07184..ef147eb22b5064cf321ed6c2ad20b9853329b43b 100644 (file)
@@ -27,7 +27,7 @@
 use middle::trans::type_::Type;
 use middle::ty;
 use util::ppaux::Repr;
-use util::ppaux::ty_to_str;
+use util::ppaux::ty_to_string;
 
 use arena::TypedArena;
 use syntax::ast;
@@ -104,8 +104,8 @@ pub struct EnvValue {
 }
 
 impl EnvValue {
-    pub fn to_str(&self, ccx: &CrateContext) -> String {
-        format!("{}({})", self.action, self.datum.to_str(ccx))
+    pub fn to_string(&self, ccx: &CrateContext) -> String {
+        format!("{}({})", self.action, self.datum.to_string(ccx))
     }
 }
 
@@ -124,7 +124,7 @@ pub fn mk_closure_tys(tcx: &ty::ctxt,
         }
     }).collect();
     let cdata_ty = ty::mk_tup(tcx, bound_tys);
-    debug!("cdata_ty={}", ty_to_str(tcx, cdata_ty));
+    debug!("cdata_ty={}", ty_to_string(tcx, cdata_ty));
     return cdata_ty;
 }
 
@@ -196,16 +196,16 @@ pub fn store_environment<'a>(
     let Result {bcx: bcx, val: llbox} = allocate_cbox(bcx, store, cdata_ty);
 
     let llbox = PointerCast(bcx, llbox, llboxptr_ty);
-    debug!("tuplify_box_ty = {}", ty_to_str(tcx, cbox_ty));
+    debug!("tuplify_box_ty = {}", ty_to_string(tcx, cbox_ty));
 
     // Copy expr values into boxed bindings.
     let mut bcx = bcx;
     for (i, bv) in bound_values.move_iter().enumerate() {
-        debug!("Copy {} into closure", bv.to_str(ccx));
+        debug!("Copy {} into closure", bv.to_string(ccx));
 
         if ccx.sess().asm_comments() {
             add_comment(bcx, format!("Copy {} into closure",
-                                     bv.to_str(ccx)).as_slice());
+                                     bv.to_string(ccx)).as_slice());
         }
 
         let bound_data = GEPi(bcx, llbox, [0u, abi::box_field_body, i]);
@@ -424,8 +424,7 @@ pub fn get_wrapper_for_bare_fn(ccx: &CrateContext,
     let empty_param_substs = param_substs::empty();
     let fcx = new_fn_ctxt(ccx, llfn, -1, true, f.sig.output,
                           &empty_param_substs, None, &arena);
-    init_function(&fcx, true, f.sig.output);
-    let bcx = fcx.entry_bcx.borrow().clone().unwrap();
+    let bcx = init_function(&fcx, true, f.sig.output);
 
     let args = create_datums_for_fn_args(&fcx,
                                          ty::ty_fn_args(closure_ty)
index b1577a6abfe1452f461a3a59c20ebb388424ad2a..23a391cb86dfefd35e534603313cee49f4f8d4da 100644 (file)
@@ -196,13 +196,13 @@ pub fn validate(&self) {
     }
 }
 
-fn param_substs_to_str(this: &param_substs, tcx: &ty::ctxt) -> String {
+fn param_substs_to_string(this: &param_substs, tcx: &ty::ctxt) -> String {
     format!("param_substs({})", this.substs.repr(tcx))
 }
 
 impl Repr for param_substs {
     fn repr(&self, tcx: &ty::ctxt) -> String {
-        param_substs_to_str(self, tcx)
+        param_substs_to_string(self, tcx)
     }
 }
 
@@ -239,8 +239,6 @@ pub struct FunctionContext<'a> {
     // always be Some.
     pub llretptr: Cell<Option<ValueRef>>,
 
-    pub entry_bcx: RefCell<Option<&'a Block<'a>>>,
-
     // These pub elements: "hoisted basic blocks" containing
     // administrative activities that have to happen in only one place in
     // the function, due to LLVM's quirks.
@@ -322,8 +320,6 @@ pub fn cleanup(&self) {
                                                      .get()
                                                      .unwrap());
         }
-        // Remove the cycle between fcx and bcx, so memory can be freed
-        *self.entry_bcx.borrow_mut() = None;
     }
 
     pub fn get_llreturn(&self) -> BasicBlockRef {
@@ -440,11 +436,11 @@ pub fn ident(&self, ident: Ident) -> String {
         token::get_ident(ident).get().to_string()
     }
 
-    pub fn node_id_to_str(&self, id: ast::NodeId) -> String {
-        self.tcx().map.node_to_str(id).to_string()
+    pub fn node_id_to_string(&self, id: ast::NodeId) -> String {
+        self.tcx().map.node_to_string(id).to_string()
     }
 
-    pub fn expr_to_str(&self, e: &ast::Expr) -> String {
+    pub fn expr_to_string(&self, e: &ast::Expr) -> String {
         e.repr(self.tcx())
     }
 
@@ -458,15 +454,15 @@ pub fn def(&self, nid: ast::NodeId) -> def::Def {
         }
     }
 
-    pub fn val_to_str(&self, val: ValueRef) -> String {
-        self.ccx().tn.val_to_str(val)
+    pub fn val_to_string(&self, val: ValueRef) -> String {
+        self.ccx().tn.val_to_string(val)
     }
 
     pub fn llty_str(&self, ty: Type) -> String {
-        self.ccx().tn.type_to_str(ty)
+        self.ccx().tn.type_to_string(ty)
     }
 
-    pub fn ty_to_str(&self, t: ty::t) -> String {
+    pub fn ty_to_string(&self, t: ty::t) -> String {
         t.repr(self.tcx())
     }
 
@@ -526,10 +522,6 @@ pub fn C_nil(ccx: &CrateContext) -> ValueRef {
 }
 
 pub fn C_bool(ccx: &CrateContext, val: bool) -> ValueRef {
-    C_integral(Type::bool(ccx), val as u64, false)
-}
-
-pub fn C_i1(ccx: &CrateContext, val: bool) -> ValueRef {
     C_integral(Type::i1(ccx), val as u64, false)
 }
 
@@ -653,7 +645,7 @@ pub fn const_get_elt(cx: &CrateContext, v: ValueRef, us: &[c_uint])
         let r = llvm::LLVMConstExtractValue(v, us.as_ptr(), us.len() as c_uint);
 
         debug!("const_get_elt(v={}, us={:?}, r={})",
-               cx.tn.val_to_str(v), us, cx.tn.val_to_str(r));
+               cx.tn.val_to_string(v), us, cx.tn.val_to_string(r));
 
         return r;
     }
index 527ce5dfaae4591d62285d229780ae8137279736..c35767f99a8352b4bed711311a9f0783b5ebbc1c 100644 (file)
@@ -31,7 +31,7 @@
 use middle::trans::type_of;
 use middle::trans::debuginfo;
 use middle::ty;
-use util::ppaux::{Repr, ty_to_str};
+use util::ppaux::{Repr, ty_to_string};
 
 use std::c_str::ToCStr;
 use std::gc::Gc;
@@ -59,7 +59,7 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: ast::Lit)
                 _ => cx.sess().span_bug(lit.span,
                         format!("integer literal has type {} (expected int \
                                  or uint)",
-                                ty_to_str(cx.tcx(), lit_int_ty)).as_slice())
+                                ty_to_string(cx.tcx(), lit_int_ty)).as_slice())
             }
         }
         ast::LitFloat(ref fs, t) => {
@@ -155,14 +155,14 @@ fn const_deref(cx: &CrateContext, v: ValueRef, t: ty::t, explicit: bool)
                 }
                 _ => {
                     cx.sess().bug(format!("unexpected dereferenceable type {}",
-                                          ty_to_str(cx.tcx(), t)).as_slice())
+                                          ty_to_string(cx.tcx(), t)).as_slice())
                 }
             };
             (dv, mt.ty)
         }
         None => {
             cx.sess().bug(format!("can't dereference const of type {}",
-                                  ty_to_str(cx.tcx(), t)).as_slice())
+                                  ty_to_string(cx.tcx(), t)).as_slice())
         }
     }
 }
@@ -285,7 +285,7 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef
             llvm::LLVMDumpValue(C_undef(llty));
         }
         cx.sess().bug(format!("const {} of type {} has size {} instead of {}",
-                         e.repr(cx.tcx()), ty_to_str(cx.tcx(), ety),
+                         e.repr(cx.tcx()), ty_to_string(cx.tcx(), ety),
                          csize, tsize).as_slice());
     }
     (llconst, inlineable)
@@ -484,8 +484,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
                 if ty::type_is_signed(ety) { llvm::LLVMConstFPToSI(v, llty.to_ref()) }
                 else { llvm::LLVMConstFPToUI(v, llty.to_ref()) }
               }
-              (expr::cast_enum, expr::cast_integral) |
-              (expr::cast_enum, expr::cast_float)  => {
+              (expr::cast_enum, expr::cast_integral) => {
                 let repr = adt::represent_type(cx, basety);
                 let discr = adt::const_get_discrim(cx, &*repr, v);
                 let iv = C_integral(cx.int_type, discr, false);
index e9b1c56eb00320485f34ccc5767d3e328436ec6b..acc44d08d3cb041b0e548ff2e1b9e8df5d80ee8d 100644 (file)
@@ -126,8 +126,8 @@ pub fn trans_if<'a>(bcx: &'a Block<'a>,
                     dest: expr::Dest)
                     -> &'a Block<'a> {
     debug!("trans_if(bcx={}, if_id={}, cond={}, thn={:?}, dest={})",
-           bcx.to_str(), if_id, bcx.expr_to_str(cond), thn.id,
-           dest.to_str(bcx.ccx()));
+           bcx.to_str(), if_id, bcx.expr_to_string(cond), thn.id,
+           dest.to_string(bcx.ccx()));
     let _icx = push_ctxt("trans_if");
     let mut bcx = bcx;
 
index 440aa36b28cbd2e9e8cb864b0bc9aa044fa27150..b65f5a5c7d6b69794d5270ecb01b5d8f9b995854 100644 (file)
  * Datums are and how they are intended to be used.
  */
 
-use lib;
 use lib::llvm::ValueRef;
 use middle::trans::base::*;
-use middle::trans::build::*;
 use middle::trans::common::*;
 use middle::trans::cleanup;
 use middle::trans::cleanup::CleanupMethods;
@@ -25,7 +23,7 @@
 use middle::trans::tvec;
 use middle::trans::type_of;
 use middle::ty;
-use util::ppaux::{ty_to_str};
+use util::ppaux::{ty_to_string};
 
 use syntax::ast;
 
@@ -344,7 +342,7 @@ pub fn to_appropriate_datum<'a>(self,
                 match self.kind.mode {
                     ByValue => DatumBlock::new(bcx, self),
                     ByRef => {
-                        let llval = load(bcx, self.val, self.ty);
+                        let llval = load_ty(bcx, self.val, self.ty);
                         DatumBlock::new(bcx, Datum::new(llval, self.ty, Rvalue::new(ByValue)))
                     }
                 }
@@ -471,7 +469,7 @@ pub fn to_rvalue_datum<'a>(self,
                         DatumBlock::new(bcx, scratch)
                     }
                     ByValue => {
-                        let v = load(bcx, l.val, l.ty);
+                        let v = load_ty(bcx, l.val, l.ty);
                         bcx = l.kind.post_store(bcx, l.val, l.ty);
                         DatumBlock::new(bcx, Datum::new(v, l.ty, Rvalue::new(ByValue)))
                     }
@@ -516,24 +514,6 @@ pub fn get_vec_base_and_len<'a>(&self, bcx: &'a Block<'a>) -> (ValueRef, ValueRe
     }
 }
 
-fn load<'a>(bcx: &'a Block<'a>, llptr: ValueRef, ty: ty::t) -> ValueRef {
-    /*!
-     * Private helper for loading from a by-ref datum. Handles various
-     * special cases where the type gives us better information about
-     * what we are loading.
-     */
-
-    if type_is_zero_size(bcx.ccx(), ty) {
-        C_undef(type_of::type_of(bcx.ccx(), ty))
-    } else if ty::type_is_char(ty) {
-        // a char is a unicode codepoint, and so takes values from 0
-        // to 0x10FFFF inclusive only.
-        LoadRangeAssert(bcx, llptr, 0, 0x10FFFF + 1, lib::llvm::False)
-    } else {
-        Load(bcx, llptr)
-    }
-}
-
 /**
  * Generic methods applicable to any sort of datum.
  */
@@ -591,7 +571,7 @@ fn shallow_copy<'a>(&self,
         if self.kind.is_by_ref() {
             memcpy_ty(bcx, dst, self.val, self.ty);
         } else {
-            Store(bcx, self.val, dst);
+            store_ty(bcx, self.val, dst, self.ty);
         }
 
         return bcx;
@@ -616,10 +596,10 @@ pub fn shallow_copy_and_take<'a>(&self,
     }
 
     #[allow(dead_code)] // useful for debugging
-    pub fn to_str(&self, ccx: &CrateContext) -> String {
+    pub fn to_string(&self, ccx: &CrateContext) -> String {
         format!("Datum({}, {}, {:?})",
-                ccx.tn.val_to_str(self.val),
-                ty_to_str(ccx.tcx(), self.ty),
+                ccx.tn.val_to_string(self.val),
+                ty_to_string(ccx.tcx(), self.ty),
                 self.kind)
     }
 
@@ -642,7 +622,7 @@ pub fn to_llscalarish<'a>(self, bcx: &'a Block<'a>) -> ValueRef {
         assert!(!ty::type_needs_drop(bcx.tcx(), self.ty));
         assert!(self.appropriate_rvalue_mode(bcx.ccx()) == ByValue);
         if self.kind.is_by_ref() {
-            load(bcx, self.val, self.ty)
+            load_ty(bcx, self.val, self.ty)
         } else {
             self.val
         }
index b3c7c0d0fac46e19c278ed001880bf935842e695..9acd04871999aecf94f0dd2ee4e1e4467ee618ff 100644 (file)
@@ -270,7 +270,7 @@ fn register_type_with_metadata(&mut self,
                                    metadata: DIType) {
         if !self.type_to_metadata.insert(ty::type_id(type_), metadata) {
             cx.sess().bug(format!("Type metadata for ty::t '{}' is already in the TypeMap!",
-                                   ppaux::ty_to_str(cx.tcx(), type_)).as_slice());
+                                   ppaux::ty_to_string(cx.tcx(), type_)).as_slice());
         }
     }
 
@@ -504,7 +504,7 @@ fn get_unique_type_id_of_type(&mut self, cx: &CrateContext, type_: ty::t) -> Uni
             },
             _ => {
                 cx.sess().bug(format!("get_unique_type_id_of_type() - unexpected type: {}, {:?}",
-                                      ppaux::ty_to_str(cx.tcx(), type_).as_slice(),
+                                      ppaux::ty_to_string(cx.tcx(), type_).as_slice(),
                                       ty::get(type_).sty).as_slice())
             }
         };
@@ -554,7 +554,7 @@ fn from_def_id_and_substs(type_map: &mut TypeMap,
 
             // Maybe check that there is no self type here.
 
-            let tps = substs.types.get_vec(subst::TypeSpace);
+            let tps = substs.types.get_slice(subst::TypeSpace);
             if tps.len() > 0 {
                 output.push_char('<');
 
@@ -808,7 +808,7 @@ pub fn create_global_var_metadata(cx: &CrateContext,
     let type_metadata = type_metadata(cx, variable_type, span);
 
     let namespace_node = namespace_for_item(cx, ast_util::local_def(node_id));
-    let var_name = token::get_ident(ident).get().to_str();
+    let var_name = token::get_ident(ident).get().to_string();
     let linkage_name =
         namespace_node.mangled_name_of_contained_item(var_name.as_slice());
     let var_scope = namespace_node.scope;
@@ -1056,7 +1056,7 @@ pub fn set_source_location(fcx: &FunctionContext,
         FunctionDebugContext(box ref function_debug_context) => {
             let cx = fcx.ccx;
 
-            debug!("set_source_location: {}", cx.sess().codemap().span_to_str(span));
+            debug!("set_source_location: {}", cx.sess().codemap().span_to_string(span));
 
             if function_debug_context.source_locations_enabled.get() {
                 let loc = span_start(cx, span);
@@ -1377,9 +1377,9 @@ fn get_template_parameters(cx: &CrateContext,
         }
 
         // Handle other generic parameters
-        let actual_types = param_substs.substs.types.get_vec(subst::FnSpace);
+        let actual_types = param_substs.substs.types.get_slice(subst::FnSpace);
         for (index, &ast::TyParam{ ident: ident, .. }) in generics.ty_params.iter().enumerate() {
-            let actual_type = *actual_types.get(index);
+            let actual_type = actual_types[index];
             // Add actual type name to <...> clause of function name
             let actual_type_name = compute_debuginfo_type_name(cx,
                                                                actual_type,
@@ -1496,7 +1496,7 @@ fn compile_unit_metadata(cx: &CrateContext) {
     });
 
     fn fallback_path(cx: &CrateContext) -> CString {
-        cx.link_meta.crateid.name.as_slice().to_c_str()
+        cx.link_meta.crate_name.as_slice().to_c_str()
     }
 }
 
@@ -1812,7 +1812,7 @@ fn finalize(&self, cx: &CrateContext) -> MetadataCreationResult {
                        type_map.find_metadata_for_type(unfinished_type).is_none() {
                         cx.sess().bug(format!("Forward declaration of potentially recursive type \
                                               '{}' was not found in TypeMap!",
-                                              ppaux::ty_to_str(cx.tcx(), unfinished_type))
+                                              ppaux::ty_to_string(cx.tcx(), unfinished_type))
                                       .as_slice());
                     }
                 }
@@ -2152,8 +2152,12 @@ fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription
                 let null_variant_index = (1 - nndiscr) as uint;
                 let null_variant_ident = self.variants.get(null_variant_index).name;
                 let null_variant_name = token::get_ident(null_variant_ident);
+                let discrfield = match ptrfield {
+                    adt::ThinPointer(field) => format!("{}", field),
+                    adt::FatPointer(field, pair) => format!("{}${}", field, pair)
+                };
                 let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
-                                                ptrfield,
+                                                discrfield,
                                                 null_variant_name);
 
                 // Create the (singleton) list of descriptions of union members.
@@ -2196,7 +2200,7 @@ fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription
 
 enum EnumDiscriminantInfo {
     RegularDiscriminant(DIType),
-    OptimizedDiscriminant(uint),
+    OptimizedDiscriminant(adt::PointerField),
     NoDiscriminant
 }
 
@@ -2241,7 +2245,7 @@ fn describe_enum_variant(cx: &CrateContext,
         Some(ref names) => {
             names.iter()
                  .map(|ident| {
-                     token::get_ident(*ident).get().to_str().into_string()
+                     token::get_ident(*ident).get().to_string().into_string()
                  }).collect()
         }
         None => variant_info.args.iter().map(|_| "".to_string()).collect()
@@ -2868,7 +2872,7 @@ fn trait_pointer_metadata(cx: &CrateContext,
         ty::ty_uniq(pointee_type) => pointee_type,
         ty::ty_rptr(_, ty::mt { ty, .. }) => ty,
         _ => {
-            let pp_type_name = ppaux::ty_to_str(cx.tcx(), trait_pointer_type);
+            let pp_type_name = ppaux::ty_to_string(cx.tcx(), trait_pointer_type);
             cx.sess().bug(format!("debuginfo: Unexpected trait-pointer type in \
                                    trait_pointer_metadata(): {}",
                                    pp_type_name.as_slice()).as_slice());
@@ -2878,7 +2882,7 @@ fn trait_pointer_metadata(cx: &CrateContext,
     let def_id = match ty::get(trait_object_type).sty {
         ty::ty_trait(box ty::TyTrait { def_id, .. }) => def_id,
         _ => {
-            let pp_type_name = ppaux::ty_to_str(cx.tcx(), trait_object_type);
+            let pp_type_name = ppaux::ty_to_string(cx.tcx(), trait_object_type);
             cx.sess().bug(format!("debuginfo: Unexpected trait-object type in \
                                    trait_pointer_metadata(): {}",
                                    pp_type_name.as_slice()).as_slice());
@@ -3060,7 +3064,7 @@ fn type_metadata(cx: &CrateContext,
                                                  the debuginfo::TypeMap but it \
                                                  was not. (ty::t = {})",
                                                 unique_type_id_str.as_slice(),
-                                                ppaux::ty_to_str(cx.tcx(), t));
+                                                ppaux::ty_to_string(cx.tcx(), t));
                     cx.sess().span_bug(usage_site_span, error_message.as_slice());
                 }
             };
@@ -3075,7 +3079,7 @@ fn type_metadata(cx: &CrateContext,
                                                      debuginfo::TypeMap. \
                                                      UniqueTypeId={}, ty::t={}",
                             unique_type_id_str.as_slice(),
-                            ppaux::ty_to_str(cx.tcx(), t));
+                            ppaux::ty_to_string(cx.tcx(), t));
                         cx.sess().span_bug(usage_site_span, error_message.as_slice());
                     }
                 }
@@ -3875,7 +3879,7 @@ fn push_debuginfo_type_name(cx: &CrateContext,
         ty::ty_infer(_) |
         ty::ty_param(_) => {
             cx.sess().bug(format!("debuginfo: Trying to create type name for \
-                unexpected type: {}", ppaux::ty_to_str(cx.tcx(), t)).as_slice());
+                unexpected type: {}", ppaux::ty_to_string(cx.tcx(), t)).as_slice());
         }
     }
 
@@ -3972,7 +3976,7 @@ fn fill_nested(node: &NamespaceTreeNode, output: &mut String) {
 }
 
 fn crate_root_namespace<'a>(cx: &'a CrateContext) -> &'a str {
-    cx.link_meta.crateid.name.as_slice()
+    cx.link_meta.crate_name.as_slice()
 }
 
 fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTreeNode> {
index b10190b23c721c87058a0f22bdee69ee53355e17..516c46564cd9ffe32eeda2c7bb959b987a25b3c1 100644 (file)
@@ -75,7 +75,7 @@
 
 use syntax::ast;
 use syntax::codemap;
-use syntax::print::pprust::{expr_to_str};
+use syntax::print::pprust::{expr_to_string};
 
 use std::gc::Gc;
 
@@ -91,9 +91,9 @@ pub enum Dest {
 }
 
 impl Dest {
-    pub fn to_str(&self, ccx: &CrateContext) -> String {
+    pub fn to_string(&self, ccx: &CrateContext) -> String {
         match *self {
-            SaveIn(v) => format!("SaveIn({})", ccx.tn.val_to_str(v)),
+            SaveIn(v) => format!("SaveIn({})", ccx.tn.val_to_string(v)),
             Ignore => "Ignore".to_string()
         }
     }
@@ -148,7 +148,7 @@ pub fn trans<'a>(bcx: &'a Block<'a>,
      * the stack.
      */
 
-    debug!("trans(expr={})", bcx.expr_to_str(expr));
+    debug!("trans(expr={})", bcx.expr_to_string(expr));
 
     let mut bcx = bcx;
     let fcx = bcx.fcx;
@@ -178,7 +178,7 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>,
         Some(adj) => { adj }
     };
     debug!("unadjusted datum for expr {}: {}",
-           expr.id, datum.to_str(bcx.ccx()));
+           expr.id, datum.to_string(bcx.ccx()));
     match adjustment {
         AutoAddEnv(..) => {
             datum = unpack_datum!(bcx, add_env(bcx, expr, datum));
@@ -216,7 +216,7 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>,
             datum = scratch.to_expr_datum();
         }
     }
-    debug!("after adjustments, datum={}", datum.to_str(bcx.ccx()));
+    debug!("after adjustments, datum={}", datum.to_string(bcx.ccx()));
     return DatumBlock {bcx: bcx, datum: datum};
 
     fn auto_slice<'a>(
@@ -325,7 +325,7 @@ fn trans_unadjusted<'a>(bcx: &'a Block<'a>,
 
     let mut bcx = bcx;
 
-    debug!("trans_unadjusted(expr={})", bcx.expr_to_str(expr));
+    debug!("trans_unadjusted(expr={})", bcx.expr_to_string(expr));
     let _indenter = indenter();
 
     debuginfo::set_source_location(bcx.fcx, expr.id, expr.span);
@@ -396,7 +396,7 @@ fn trans_datum_unadjusted<'a>(bcx: &'a Block<'a>,
             trans_rec_field(bcx, &**base, ident.node)
         }
         ast::ExprIndex(ref base, ref idx) => {
-            trans_index(bcx, expr, &**base, &**idx)
+            trans_index(bcx, expr, &**base, &**idx, MethodCall::expr(expr.id))
         }
         ast::ExprVstore(ref contents, ast::ExprVstoreUniq) => {
             fcx.push_ast_cleanup_scope(contents.id);
@@ -467,7 +467,8 @@ fn trans_rec_field<'a>(bcx: &'a Block<'a>,
 fn trans_index<'a>(bcx: &'a Block<'a>,
                    index_expr: &ast::Expr,
                    base: &ast::Expr,
-                   idx: &ast::Expr)
+                   idx: &ast::Expr,
+                   method_call: MethodCall)
                    -> DatumBlock<'a, Expr> {
     //! Translates `base[idx]`.
 
@@ -475,43 +476,97 @@ fn trans_index<'a>(bcx: &'a Block<'a>,
     let ccx = bcx.ccx();
     let mut bcx = bcx;
 
-    let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, base, "index"));
-
-    // Translate index expression and cast to a suitable LLVM integer.
-    // Rust is less strict than LLVM in this regard.
-    let ix_datum = unpack_datum!(bcx, trans(bcx, idx));
-    let ix_val = ix_datum.to_llscalarish(bcx);
-    let ix_size = machine::llbitsize_of_real(bcx.ccx(), val_ty(ix_val));
-    let int_size = machine::llbitsize_of_real(bcx.ccx(), ccx.int_type);
-    let ix_val = {
-        if ix_size < int_size {
-            if ty::type_is_signed(expr_ty(bcx, idx)) {
-                SExt(bcx, ix_val, ccx.int_type)
-            } else { ZExt(bcx, ix_val, ccx.int_type) }
-        } else if ix_size > int_size {
-            Trunc(bcx, ix_val, ccx.int_type)
-        } else {
-            ix_val
-        }
-    };
+    // Check for overloaded index.
+    let method_ty = ccx.tcx
+                       .method_map
+                       .borrow()
+                       .find(&method_call)
+                       .map(|method| method.ty);
+    let elt_datum = match method_ty {
+        Some(method_ty) => {
+            let base_datum = unpack_datum!(bcx, trans(bcx, base));
 
-    let vt = tvec::vec_types(bcx, ty::sequence_element_type(bcx.tcx(), base_datum.ty));
-    base::maybe_name_value(bcx.ccx(), vt.llunit_size, "unit_sz");
+            // Translate index expression.
+            let ix_datum = unpack_datum!(bcx, trans(bcx, idx));
 
-    let (base, len) = base_datum.get_vec_base_and_len(bcx);
+            // Overloaded. Evaluate `trans_overloaded_op`, which will
+            // invoke the user's index() method, which basically yields
+            // a `&T` pointer.  We can then proceed down the normal
+            // path (below) to dereference that `&T`.
+            let val =
+                unpack_result!(bcx,
+                               trans_overloaded_op(bcx,
+                                                   index_expr,
+                                                   method_call,
+                                                   base_datum,
+                                                   Some((ix_datum, idx.id)),
+                                                   None));
+            let ref_ty = ty::ty_fn_ret(monomorphize_type(bcx, method_ty));
+            let elt_ty = match ty::deref(ref_ty, true) {
+                None => {
+                    bcx.tcx().sess.span_bug(index_expr.span,
+                                            "index method didn't return a \
+                                             dereferenceable type?!")
+                }
+                Some(elt_tm) => elt_tm.ty,
+            };
+            Datum::new(val, elt_ty, LvalueExpr)
+        }
+        None => {
+            let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx,
+                                                                base,
+                                                                "index"));
+
+            // Translate index expression and cast to a suitable LLVM integer.
+            // Rust is less strict than LLVM in this regard.
+            let ix_datum = unpack_datum!(bcx, trans(bcx, idx));
+            let ix_val = ix_datum.to_llscalarish(bcx);
+            let ix_size = machine::llbitsize_of_real(bcx.ccx(),
+                                                     val_ty(ix_val));
+            let int_size = machine::llbitsize_of_real(bcx.ccx(),
+                                                      ccx.int_type);
+            let ix_val = {
+                if ix_size < int_size {
+                    if ty::type_is_signed(expr_ty(bcx, idx)) {
+                        SExt(bcx, ix_val, ccx.int_type)
+                    } else { ZExt(bcx, ix_val, ccx.int_type) }
+                } else if ix_size > int_size {
+                    Trunc(bcx, ix_val, ccx.int_type)
+                } else {
+                    ix_val
+                }
+            };
 
-    debug!("trans_index: base {}", bcx.val_to_str(base));
-    debug!("trans_index: len {}", bcx.val_to_str(len));
+            let vt =
+                tvec::vec_types(bcx,
+                                ty::sequence_element_type(bcx.tcx(),
+                                                          base_datum.ty));
+            base::maybe_name_value(bcx.ccx(), vt.llunit_size, "unit_sz");
+
+            let (base, len) = base_datum.get_vec_base_and_len(bcx);
+
+            debug!("trans_index: base {}", bcx.val_to_string(base));
+            debug!("trans_index: len {}", bcx.val_to_string(len));
+
+            let bounds_check = ICmp(bcx, lib::llvm::IntUGE, ix_val, len);
+            let expect = ccx.get_intrinsic(&("llvm.expect.i1"));
+            let expected = Call(bcx,
+                                expect,
+                                [bounds_check, C_bool(ccx, false)],
+                                []);
+            bcx = with_cond(bcx, expected, |bcx| {
+                controlflow::trans_fail_bounds_check(bcx,
+                                                     index_expr.span,
+                                                     ix_val,
+                                                     len)
+            });
+            let elt = InBoundsGEP(bcx, base, [ix_val]);
+            let elt = PointerCast(bcx, elt, vt.llunit_ty.ptr_to());
+            Datum::new(elt, vt.unit_ty, LvalueExpr)
+        }
+    };
 
-    let bounds_check = ICmp(bcx, lib::llvm::IntUGE, ix_val, len);
-    let expect = ccx.get_intrinsic(&("llvm.expect.i1"));
-    let expected = Call(bcx, expect, [bounds_check, C_i1(ccx, false)], []);
-    let bcx = with_cond(bcx, expected, |bcx| {
-            controlflow::trans_fail_bounds_check(bcx, index_expr.span, ix_val, len)
-        });
-    let elt = InBoundsGEP(bcx, base, [ix_val]);
-    let elt = PointerCast(bcx, elt, vt.llunit_ty.ptr_to());
-    DatumBlock::new(bcx, Datum::new(elt, vt.unit_ty, LvalueExpr))
+    DatumBlock::new(bcx, elt_datum)
 }
 
 fn trans_def<'a>(bcx: &'a Block<'a>,
@@ -725,7 +780,7 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
             let expr_ty = expr_ty(bcx, expr);
             let store = ty::ty_closure_store(expr_ty);
             debug!("translating block function {} with type {}",
-                   expr_to_str(expr), expr_ty.repr(tcx));
+                   expr_to_string(expr), expr_ty.repr(tcx));
             closure::trans_expr_fn(bcx, store, &**decl, &**body, expr.id, dest)
         }
         ast::ExprCall(ref f, ref args) => {
@@ -838,7 +893,7 @@ fn trans_def_dps_unadjusted<'a>(
         _ => {
             bcx.tcx().sess.span_bug(ref_expr.span, format!(
                 "Non-DPS def {:?} referened by {}",
-                def, bcx.node_id_to_str(ref_expr.id)).as_slice());
+                def, bcx.node_id_to_string(ref_expr.id)).as_slice());
         }
     }
 }
@@ -919,7 +974,7 @@ fn take_local<'a>(bcx: &'a Block<'a>,
             }
         };
         debug!("take_local(nid={:?}, v={}, ty={})",
-               nid, bcx.val_to_str(datum.val), bcx.ty_to_str(datum.ty));
+               nid, bcx.val_to_string(datum.val), bcx.ty_to_string(datum.ty));
         datum
     }
 }
@@ -1149,13 +1204,7 @@ fn trans_unary<'a>(bcx: &'a Block<'a>,
     match op {
         ast::UnNot => {
             let datum = unpack_datum!(bcx, trans(bcx, sub_expr));
-            let llresult = if ty::type_is_bool(un_ty) {
-                let val = datum.to_llscalarish(bcx);
-                Xor(bcx, val, C_bool(ccx, true))
-            } else {
-                // Note: `Not` is bitwise, not suitable for logical not.
-                Not(bcx, datum.to_llscalarish(bcx))
-            };
+            let llresult = Not(bcx, datum.to_llscalarish(bcx));
             immediate_rvalue_bcx(bcx, llresult, un_ty).to_expr_datumblock()
         }
         ast::UnNeg => {
@@ -1380,7 +1429,7 @@ fn trans_lazy_binop<'a>(
     }
 
     Br(past_rhs, join.llbb);
-    let phi = Phi(join, Type::bool(bcx.ccx()), [lhs, rhs],
+    let phi = Phi(join, Type::i1(bcx.ccx()), [lhs, rhs],
                   [past_lhs.llbb, past_rhs.llbb]);
 
     return immediate_rvalue_bcx(join, phi, binop_ty).to_expr_datumblock();
@@ -1413,13 +1462,13 @@ fn trans_binary<'a>(bcx: &'a Block<'a>,
 
             debug!("trans_binary (expr {}): lhs_datum={}",
                    expr.id,
-                   lhs_datum.to_str(ccx));
+                   lhs_datum.to_string(ccx));
             let lhs_ty = lhs_datum.ty;
             let lhs = lhs_datum.to_llscalarish(bcx);
 
             debug!("trans_binary (expr {}): rhs_datum={}",
                    expr.id,
-                   rhs_datum.to_str(ccx));
+                   rhs_datum.to_string(ccx));
             let rhs_ty = rhs_datum.ty;
             let rhs = rhs_datum.to_llscalarish(bcx);
             trans_eager_binop(bcx, expr, binop_ty, op,
@@ -1597,8 +1646,8 @@ fn trans_imm_cast<'a>(bcx: &'a Block<'a>,
     let k_in = cast_type_kind(t_in);
     let k_out = cast_type_kind(t_out);
     let s_in = k_in == cast_integral && ty::type_is_signed(t_in);
-    let ll_t_in = type_of::type_of(ccx, t_in);
-    let ll_t_out = type_of::type_of(ccx, t_out);
+    let ll_t_in = type_of::arg_type_of(ccx, t_in);
+    let ll_t_out = type_of::arg_type_of(ccx, t_out);
 
     // Convert the value to be cast into a ValueRef, either by-ref or
     // by-value as appropriate given its type:
@@ -1680,7 +1729,7 @@ fn trans_assign_op<'a>(
     let _icx = push_ctxt("trans_assign_op");
     let mut bcx = bcx;
 
-    debug!("trans_assign_op(expr={})", bcx.expr_to_str(expr));
+    debug!("trans_assign_op(expr={})", bcx.expr_to_string(expr));
 
     // User-defined operator methods cannot be used with `+=` etc right now
     assert!(!bcx.tcx().method_map.borrow().contains_key(&MethodCall::expr(expr.id)));
@@ -1689,7 +1738,7 @@ fn trans_assign_op<'a>(
     let dst_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, dst, "assign_op"));
     assert!(!ty::type_needs_drop(bcx.tcx(), dst_datum.ty));
     let dst_ty = dst_datum.ty;
-    let dst = Load(bcx, dst_datum.val);
+    let dst = load_ty(bcx, dst_datum.val, dst_datum.ty);
 
     // Evaluate RHS
     let rhs_datum = unpack_datum!(bcx, trans(bcx, &*src));
@@ -1750,7 +1799,7 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
 
     debug!("deref_once(expr={}, datum={}, method_call={})",
            expr.repr(bcx.tcx()),
-           datum.to_str(ccx),
+           datum.to_string(ccx),
            method_call);
 
     let mut bcx = bcx;
@@ -1762,7 +1811,7 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
         Some(method_ty) => {
             // Overloaded. Evaluate `trans_overloaded_op`, which will
             // invoke the user's deref() method, which basically
-            // converts from the `Shaht<T>` pointer that we have into
+            // converts from the `Smaht<T>` pointer that we have into
             // a `&T` pointer.  We can then proceed down the normal
             // path (below) to dereference that `&T`.
             let datum = match method_call.adjustment {
@@ -1828,7 +1877,7 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
     };
 
     debug!("deref_once(expr={}, method_call={}, result={})",
-           expr.id, method_call, r.datum.to_str(ccx));
+           expr.id, method_call, r.datum.to_string(ccx));
 
     return r;
 
index 488dc6d99e35c7a0d6063d816250a778ccaab540..0b12cd3da8254acc582fa84b204851de59c0056c 100644 (file)
@@ -17,7 +17,6 @@
 use middle::trans::base::push_ctxt;
 use middle::trans::base;
 use middle::trans::build::*;
-use middle::trans::builder::noname;
 use middle::trans::cabi;
 use middle::trans::common::*;
 use middle::trans::machine;
@@ -267,8 +266,8 @@ pub fn trans_native_call<'a>(
             llfn={}, \
             llretptr={})",
            callee_ty.repr(tcx),
-           ccx.tn.val_to_str(llfn),
-           ccx.tn.val_to_str(llretptr));
+           ccx.tn.val_to_string(llfn),
+           ccx.tn.val_to_string(llretptr));
 
     let (fn_abi, fn_sig) = match ty::get(callee_ty).sty {
         ty::ty_bare_fn(ref fn_ty) => (fn_ty.abi, fn_ty.sig.clone()),
@@ -315,9 +314,9 @@ pub fn trans_native_call<'a>(
 
         debug!("argument {}, llarg_rust={}, rust_indirect={}, arg_ty={}",
                i,
-               ccx.tn.val_to_str(llarg_rust),
+               ccx.tn.val_to_string(llarg_rust),
                rust_indirect,
-               ccx.tn.type_to_str(arg_tys[i].ty));
+               ccx.tn.type_to_string(arg_tys[i].ty));
 
         // Ensure that we always have the Rust value indirectly,
         // because it makes bitcasting easier.
@@ -326,12 +325,12 @@ pub fn trans_native_call<'a>(
                 base::alloca(bcx,
                              type_of::type_of(ccx, *passed_arg_tys.get(i)),
                              "__arg");
-            Store(bcx, llarg_rust, scratch);
+            base::store_ty(bcx, llarg_rust, scratch, *passed_arg_tys.get(i));
             llarg_rust = scratch;
         }
 
         debug!("llarg_rust={} (after indirection)",
-               ccx.tn.val_to_str(llarg_rust));
+               ccx.tn.val_to_string(llarg_rust));
 
         // Check whether we need to do any casting
         match arg_tys[i].cast {
@@ -340,18 +339,23 @@ pub fn trans_native_call<'a>(
         }
 
         debug!("llarg_rust={} (after casting)",
-               ccx.tn.val_to_str(llarg_rust));
+               ccx.tn.val_to_string(llarg_rust));
 
         // Finally, load the value if needed for the foreign ABI
         let foreign_indirect = arg_tys[i].is_indirect();
         let llarg_foreign = if foreign_indirect {
             llarg_rust
         } else {
-            Load(bcx, llarg_rust)
+            if ty::type_is_bool(*passed_arg_tys.get(i)) {
+                let val = LoadRangeAssert(bcx, llarg_rust, 0, 2, lib::llvm::False);
+                Trunc(bcx, val, Type::i1(bcx.ccx()))
+            } else {
+                Load(bcx, llarg_rust)
+            }
         };
 
         debug!("argument {}, llarg_foreign={}",
-               i, ccx.tn.val_to_str(llarg_foreign));
+               i, ccx.tn.val_to_string(llarg_foreign));
 
         // fill padding with undef value
         match arg_tys[i].pad {
@@ -426,13 +430,13 @@ pub fn trans_native_call<'a>(
             None => fn_type.ret_ty.ty
         };
 
-        debug!("llretptr={}", ccx.tn.val_to_str(llretptr));
-        debug!("llforeign_retval={}", ccx.tn.val_to_str(llforeign_retval));
-        debug!("llrust_ret_ty={}", ccx.tn.type_to_str(llrust_ret_ty));
-        debug!("llforeign_ret_ty={}", ccx.tn.type_to_str(llforeign_ret_ty));
+        debug!("llretptr={}", ccx.tn.val_to_string(llretptr));
+        debug!("llforeign_retval={}", ccx.tn.val_to_string(llforeign_retval));
+        debug!("llrust_ret_ty={}", ccx.tn.type_to_string(llrust_ret_ty));
+        debug!("llforeign_ret_ty={}", ccx.tn.type_to_string(llforeign_ret_ty));
 
         if llrust_ret_ty == llforeign_ret_ty {
-            Store(bcx, llforeign_retval, llretptr);
+            base::store_ty(bcx, llforeign_retval, llretptr, fn_sig.output)
         } else {
             // The actual return type is a struct, but the ABI
             // adaptation code has cast it into some scalar type.  The
@@ -534,7 +538,7 @@ pub fn register_rust_fn_with_foreign_abi(ccx: &CrateContext,
     let llfn = base::register_fn_llvmty(ccx, sp, sym, node_id, cconv, llfn_ty);
     add_argument_attributes(&tys, llfn);
     debug!("register_rust_fn_with_foreign_abi(node_id={:?}, llfn_ty={}, llfn={})",
-           node_id, ccx.tn.type_to_str(llfn_ty), ccx.tn.val_to_str(llfn));
+           node_id, ccx.tn.type_to_string(llfn_ty), ccx.tn.val_to_string(llfn));
     llfn
 }
 
@@ -567,7 +571,7 @@ fn build_rust_fn(ccx: &CrateContext,
 
         let ps = ccx.tcx.map.with_path(id, |path| {
             let abi = Some(ast_map::PathName(special_idents::clownshoe_abi.name));
-            link::mangle(path.chain(abi.move_iter()), None, None)
+            link::mangle(path.chain(abi.move_iter()), None)
         });
 
         // Compute the type that the function would have if it were just a
@@ -579,13 +583,13 @@ fn build_rust_fn(ccx: &CrateContext,
             _ => {
                 ccx.sess().bug(format!("build_rust_fn: extern fn {} has ty {}, \
                                         expected a bare fn ty",
-                                       ccx.tcx.map.path_to_str(id),
+                                       ccx.tcx.map.path_to_string(id),
                                        t.repr(tcx)).as_slice());
             }
         };
 
         debug!("build_rust_fn: path={} id={} t={}",
-               ccx.tcx.map.path_to_str(id),
+               ccx.tcx.map.path_to_string(id),
                id, t.repr(tcx));
 
         let llfn = base::decl_internal_rust_fn(ccx, t, ps.as_slice());
@@ -606,8 +610,8 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
         let t = ty::node_id_to_type(tcx, id);
 
         debug!("build_wrap_fn(llrustfn={}, llwrapfn={}, t={})",
-               ccx.tn.val_to_str(llrustfn),
-               ccx.tn.val_to_str(llwrapfn),
+               ccx.tn.val_to_string(llrustfn),
+               ccx.tn.val_to_string(llwrapfn),
                t.repr(ccx.tcx()));
 
         // Avoid all the Rust generation stuff and just generate raw
@@ -625,8 +629,8 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
             "the block".with_c_str(
                 |s| llvm::LLVMAppendBasicBlockInContext(ccx.llcx, llwrapfn, s));
 
-        let builder = ccx.builder.b;
-        llvm::LLVMPositionBuilderAtEnd(builder, the_block);
+        let builder = ccx.builder();
+        builder.position_at_end(the_block);
 
         // Array for the arguments we will pass to the rust function.
         let mut llrust_args = Vec::new();
@@ -664,31 +668,23 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
             match foreign_outptr {
                 Some(llforeign_outptr) => {
                     debug!("out pointer, foreign={}",
-                           ccx.tn.val_to_str(llforeign_outptr));
+                           ccx.tn.val_to_string(llforeign_outptr));
                     let llrust_retptr =
-                        llvm::LLVMBuildBitCast(builder,
-                                               llforeign_outptr,
-                                               llrust_ret_ty.ptr_to().to_ref(),
-                                               noname());
+                        builder.bitcast(llforeign_outptr, llrust_ret_ty.ptr_to());
                     debug!("out pointer, foreign={} (casted)",
-                           ccx.tn.val_to_str(llrust_retptr));
+                           ccx.tn.val_to_string(llrust_retptr));
                     llrust_args.push(llrust_retptr);
                     return_alloca = None;
                 }
 
                 None => {
-                    let slot = {
-                        "return_alloca".with_c_str(
-                            |s| llvm::LLVMBuildAlloca(builder,
-                                                      llrust_ret_ty.to_ref(),
-                                                      s))
-                    };
+                    let slot = builder.alloca(llrust_ret_ty, "return_alloca");
                     debug!("out pointer, \
                             allocad={}, \
                             llrust_ret_ty={}, \
                             return_ty={}",
-                           ccx.tn.val_to_str(slot),
-                           ccx.tn.type_to_str(llrust_ret_ty),
+                           ccx.tn.val_to_string(slot),
+                           ccx.tn.type_to_string(llrust_ret_ty),
                            tys.fn_sig.output.repr(tcx));
                     llrust_args.push(slot);
                     return_alloca = Some(slot);
@@ -716,7 +712,7 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
             let mut llforeign_arg = llvm::LLVMGetParam(llwrapfn, foreign_index);
 
             debug!("llforeign_arg {}{}: {}", "#",
-                   i, ccx.tn.val_to_str(llforeign_arg));
+                   i, ccx.tn.val_to_string(llforeign_arg));
             debug!("rust_indirect = {}, foreign_indirect = {}",
                    rust_indirect, foreign_indirect);
 
@@ -724,12 +720,15 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
             // pointer).  It makes adapting types easier, since we can
             // always just bitcast pointers.
             if !foreign_indirect {
-                let lltemp =
-                    llvm::LLVMBuildAlloca(
-                        builder, val_ty(llforeign_arg).to_ref(), noname());
-                llvm::LLVMBuildStore(
-                    builder, llforeign_arg, lltemp);
-                llforeign_arg = lltemp;
+                llforeign_arg = if ty::type_is_bool(rust_ty) {
+                    let lltemp = builder.alloca(Type::bool(ccx), "");
+                    builder.store(builder.zext(llforeign_arg, Type::bool(ccx)), lltemp);
+                    lltemp
+                } else {
+                    let lltemp = builder.alloca(val_ty(llforeign_arg), "");
+                    builder.store(llforeign_arg, lltemp);
+                    lltemp
+                }
             }
 
             // If the types in the ABI and the Rust types don't match,
@@ -737,31 +736,29 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
             // Rust expects.
             if llforeign_arg_ty.cast.is_some() {
                 assert!(!foreign_indirect);
-                llforeign_arg = llvm::LLVMBuildBitCast(
-                    builder, llforeign_arg,
-                    llrust_ty.ptr_to().to_ref(), noname());
+                llforeign_arg = builder.bitcast(llforeign_arg, llrust_ty.ptr_to());
             }
 
             let llrust_arg = if rust_indirect {
                 llforeign_arg
             } else {
-                llvm::LLVMBuildLoad(builder, llforeign_arg, noname())
+                if ty::type_is_bool(rust_ty) {
+                    let tmp = builder.load_range_assert(llforeign_arg, 0, 2, lib::llvm::False);
+                    builder.trunc(tmp, Type::i1(ccx))
+                } else {
+                    builder.load(llforeign_arg)
+                }
             };
 
             debug!("llrust_arg {}{}: {}", "#",
-                   i, ccx.tn.val_to_str(llrust_arg));
+                   i, ccx.tn.val_to_string(llrust_arg));
             llrust_args.push(llrust_arg);
         }
 
         // Perform the call itself
-        debug!("calling llrustfn = {}, t = {}", ccx.tn.val_to_str(llrustfn), t.repr(ccx.tcx()));
-        let llrust_ret_val = llvm::LLVMBuildCall(builder, llrustfn, llrust_args.as_ptr(),
-                                                 llrust_args.len() as c_uint, noname());
-
+        debug!("calling llrustfn = {}, t = {}", ccx.tn.val_to_string(llrustfn), t.repr(ccx.tcx()));
         let attributes = base::get_fn_llvm_attributes(ccx, t);
-        for &(idx, attr) in attributes.iter() {
-            llvm::LLVMAddCallSiteAttribute(llrust_ret_val, idx as c_uint, attr);
-        }
+        let llrust_ret_val = builder.call(llrustfn, llrust_args.as_slice(), attributes.as_slice());
 
         // Get the return value where the foreign fn expects it.
         let llforeign_ret_ty = match tys.fn_ty.ret_ty.cast {
@@ -772,20 +769,16 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
             None if !tys.ret_def => {
                 // Function returns `()` or `bot`, which in Rust is the LLVM
                 // type "{}" but in foreign ABIs is "Void".
-                llvm::LLVMBuildRetVoid(builder);
+                builder.ret_void();
             }
 
             None if rust_uses_outptr => {
                 // Rust uses an outpointer, but the foreign ABI does not. Load.
                 let llrust_outptr = return_alloca.unwrap();
                 let llforeign_outptr_casted =
-                    llvm::LLVMBuildBitCast(builder,
-                                           llrust_outptr,
-                                           llforeign_ret_ty.ptr_to().to_ref(),
-                                           noname());
-                let llforeign_retval =
-                    llvm::LLVMBuildLoad(builder, llforeign_outptr_casted, noname());
-                llvm::LLVMBuildRet(builder, llforeign_retval);
+                    builder.bitcast(llrust_outptr, llforeign_ret_ty.ptr_to());
+                let llforeign_retval = builder.load(llforeign_outptr_casted);
+                builder.ret(llforeign_retval);
             }
 
             None if llforeign_ret_ty != llrust_ret_ty => {
@@ -795,43 +788,31 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
                 // right now we just use a temp memory location and
                 // bitcast the pointer, which is the same thing the
                 // old wrappers used to do.
-                let lltemp =
-                    llvm::LLVMBuildAlloca(
-                        builder, llforeign_ret_ty.to_ref(), noname());
-                let lltemp_casted =
-                    llvm::LLVMBuildBitCast(builder,
-                                           lltemp,
-                                           llrust_ret_ty.ptr_to().to_ref(),
-                                           noname());
-                llvm::LLVMBuildStore(
-                    builder, llrust_ret_val, lltemp_casted);
-                let llforeign_retval =
-                    llvm::LLVMBuildLoad(builder, lltemp, noname());
-                llvm::LLVMBuildRet(builder, llforeign_retval);
+                let lltemp = builder.alloca(llforeign_ret_ty, "");
+                let lltemp_casted = builder.bitcast(lltemp, llrust_ret_ty.ptr_to());
+                builder.store(llrust_ret_val, lltemp_casted);
+                let llforeign_retval = builder.load(lltemp);
+                builder.ret(llforeign_retval);
             }
 
             None => {
                 // Neither ABI uses an outpointer, and the types
                 // match. Easy peasy.
-                llvm::LLVMBuildRet(builder, llrust_ret_val);
+                builder.ret(llrust_ret_val);
             }
 
             Some(llforeign_outptr) if !rust_uses_outptr => {
                 // Foreign ABI requires an out pointer, but Rust doesn't.
                 // Store Rust return value.
                 let llforeign_outptr_casted =
-                    llvm::LLVMBuildBitCast(builder,
-                                           llforeign_outptr,
-                                           llrust_retptr_ty.to_ref(),
-                                           noname());
-                llvm::LLVMBuildStore(
-                    builder, llrust_ret_val, llforeign_outptr_casted);
-                llvm::LLVMBuildRetVoid(builder);
+                    builder.bitcast(llforeign_outptr, llrust_retptr_ty);
+                builder.store(llrust_ret_val, llforeign_outptr_casted);
+                builder.ret_void();
             }
 
             Some(_) => {
                 // Both ABIs use outpointers. Easy peasy.
-                llvm::LLVMBuildRetVoid(builder);
+                builder.ret_void();
             }
         }
     }
@@ -863,8 +844,8 @@ fn foreign_signature(ccx: &CrateContext, fn_sig: &ty::FnSig, arg_tys: &[ty::t])
      * values by pointer like we do.
      */
 
-    let llarg_tys = arg_tys.iter().map(|&arg| type_of(ccx, arg)).collect();
-    let llret_ty = type_of::type_of(ccx, fn_sig.output);
+    let llarg_tys = arg_tys.iter().map(|&arg| arg_type_of(ccx, arg)).collect();
+    let llret_ty = type_of::arg_type_of(ccx, fn_sig.output);
     LlvmSignature {
         llarg_tys: llarg_tys,
         llret_ty: llret_ty
@@ -895,9 +876,9 @@ fn foreign_types_for_fn_ty(ccx: &CrateContext,
            ret_def={}",
            ty.repr(ccx.tcx()),
            ccx.tn.types_to_str(llsig.llarg_tys.as_slice()),
-           ccx.tn.type_to_str(llsig.llret_ty),
+           ccx.tn.type_to_string(llsig.llret_ty),
            ccx.tn.types_to_str(fn_ty.arg_tys.iter().map(|t| t.ty).collect::<Vec<_>>().as_slice()),
-           ccx.tn.type_to_str(fn_ty.ret_ty.ty),
+           ccx.tn.type_to_string(fn_ty.ret_ty.ty),
            ret_def);
 
     ForeignTypes {
index 7024ea4b3756907b0af8a544311a928e9ad7540a..4d9f004e3dcd111ea895016269df715a4b5f83ce 100644 (file)
@@ -167,11 +167,11 @@ pub fn lazily_emit_visit_glue(ccx: &CrateContext, ti: &tydesc_info) -> ValueRef
     match ti.visit_glue.get() {
         Some(visit_glue) => visit_glue,
         None => {
-            debug!("+++ lazily_emit_tydesc_glue VISIT {}", ppaux::ty_to_str(ccx.tcx(), ti.ty));
+            debug!("+++ lazily_emit_tydesc_glue VISIT {}", ppaux::ty_to_string(ccx.tcx(), ti.ty));
             let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, "visit");
             ti.visit_glue.set(Some(glue_fn));
             make_generic_glue(ccx, ti.ty, glue_fn, make_visit_glue, "visit");
-            debug!("--- lazily_emit_tydesc_glue VISIT {}", ppaux::ty_to_str(ccx.tcx(), ti.ty));
+            debug!("--- lazily_emit_tydesc_glue VISIT {}", ppaux::ty_to_string(ccx.tcx(), ti.ty));
             glue_fn
         }
     }
@@ -234,7 +234,7 @@ fn trans_struct_drop_flag<'a>(bcx: &'a Block<'a>,
                               -> &'a Block<'a> {
     let repr = adt::represent_type(bcx.ccx(), t);
     let drop_flag = adt::trans_drop_flag_ptr(bcx, &*repr, v0);
-    with_cond(bcx, IsNotNull(bcx, Load(bcx, drop_flag)), |cx| {
+    with_cond(bcx, load_ty(bcx, drop_flag, ty::mk_bool()), |cx| {
         trans_struct_drop(cx, t, v0, dtor_did, class_did, substs)
     })
 }
@@ -432,13 +432,13 @@ pub fn declare_tydesc(ccx: &CrateContext, t: ty::t) -> tydesc_info {
 
     if ccx.sess().count_type_sizes() {
         println!("{}\t{}", llsize_of_real(ccx, llty),
-                 ppaux::ty_to_str(ccx.tcx(), t));
+                 ppaux::ty_to_string(ccx.tcx(), t));
     }
 
     let llsize = llsize_of(ccx, llty);
     let llalign = llalign_of(ccx, llty);
     let name = mangle_internal_name_by_type_and_seq(ccx, t, "tydesc");
-    debug!("+++ declare_tydesc {} {}", ppaux::ty_to_str(ccx.tcx(), t), name);
+    debug!("+++ declare_tydesc {} {}", ppaux::ty_to_string(ccx.tcx(), t), name);
     let gvar = name.as_slice().with_c_str(|buf| {
         unsafe {
             llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type().to_ref(), buf)
@@ -447,10 +447,10 @@ pub fn declare_tydesc(ccx: &CrateContext, t: ty::t) -> tydesc_info {
     note_unique_llvm_symbol(ccx, name);
 
     let ty_name = token::intern_and_get_ident(
-        ppaux::ty_to_str(ccx.tcx(), t).as_slice());
+        ppaux::ty_to_string(ccx.tcx(), t).as_slice());
     let ty_name = C_str_slice(ccx, ty_name);
 
-    debug!("--- declare_tydesc {}", ppaux::ty_to_str(ccx.tcx(), t));
+    debug!("--- declare_tydesc {}", ppaux::ty_to_string(ccx.tcx(), t));
     tydesc_info {
         ty: t,
         tydesc: gvar,
@@ -468,7 +468,7 @@ fn declare_generic_glue(ccx: &CrateContext, t: ty::t, llfnty: Type,
         ccx,
         t,
         format!("glue_{}", name).as_slice());
-    debug!("{} is for type {}", fn_nm, ppaux::ty_to_str(ccx.tcx(), t));
+    debug!("{} is for type {}", fn_nm, ppaux::ty_to_string(ccx.tcx(), t));
     let llfn = decl_cdecl_fn(ccx, fn_nm.as_slice(), llfnty, ty::mk_nil());
     note_unique_llvm_symbol(ccx, fn_nm);
     return llfn;
@@ -490,7 +490,7 @@ fn make_generic_glue(ccx: &CrateContext,
     let fcx = new_fn_ctxt(ccx, llfn, -1, false, ty::mk_nil(),
                           &empty_param_substs, None, &arena);
 
-    init_function(&fcx, false, ty::mk_nil());
+    let bcx = init_function(&fcx, false, ty::mk_nil());
 
     lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
     ccx.stats.n_glues_created.set(ccx.stats.n_glues_created.get() + 1u);
@@ -502,10 +502,9 @@ fn make_generic_glue(ccx: &CrateContext,
     // llfn is expected be declared to take a parameter of the appropriate
     // type, so we don't need to explicitly cast the function parameter.
 
-    let bcx = fcx.entry_bcx.borrow().clone().unwrap();
     let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, fcx.arg_pos(0) as c_uint) };
     let bcx = helper(bcx, llrawptr0, t);
-    finish_fn(&fcx, bcx);
+    finish_fn(&fcx, bcx, ty::mk_nil());
 
     llfn
 }
index bc0c88ceee95fc5866159c067f70773851ad51f5..28bdc6852e8484f175ca5976689022c858dc0dbc 100644 (file)
@@ -29,7 +29,7 @@
 use syntax::ast;
 use syntax::ast_map;
 use syntax::parse::token;
-use util::ppaux::ty_to_str;
+use util::ppaux::ty_to_string;
 
 pub fn get_simple_intrinsic(ccx: &CrateContext, item: &ast::ForeignItem) -> Option<ValueRef> {
     let name = match token::get_ident(item.ident).get() {
@@ -96,13 +96,19 @@ fn with_overflow_instrinsic(bcx: &Block, name: &'static str, t: ty::t) {
         let b = get_param(bcx.fcx.llfn, first_real_arg + 1);
         let llfn = bcx.ccx().get_intrinsic(&name);
 
+        // convert `i1` to a `bool`, and write to the out parameter
         let val = Call(bcx, llfn, [a, b], []);
+        let result = ExtractValue(bcx, val, 0);
+        let overflow = ZExt(bcx, ExtractValue(bcx, val, 1), Type::bool(bcx.ccx()));
+        let ret = C_undef(type_of::type_of(bcx.ccx(), t));
+        let ret = InsertValue(bcx, ret, result, 0);
+        let ret = InsertValue(bcx, ret, overflow, 1);
 
         if type_is_immediate(bcx.ccx(), t) {
-            Ret(bcx, val);
+            Ret(bcx, ret);
         } else {
             let retptr = get_param(bcx.fcx.llfn, bcx.fcx.out_arg_pos());
-            Store(bcx, val, retptr);
+            Store(bcx, ret, retptr);
             RetVoid(bcx);
         }
     }
@@ -150,7 +156,8 @@ fn copy_intrinsic(bcx: &Block, allow_overlap: bool, volatile: bool, tp_ty: ty::t
         let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p(ccx));
         let count = get_param(decl, first_real_arg + 2);
         let llfn = ccx.get_intrinsic(&name);
-        Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, C_i1(ccx, volatile)], []);
+        Call(bcx, llfn,
+             [dst_ptr, src_ptr, Mul(bcx, size, count), align, C_bool(ccx, volatile)], []);
         RetVoid(bcx);
     }
 
@@ -171,13 +178,13 @@ fn memset_intrinsic(bcx: &Block, volatile: bool, tp_ty: ty::t) {
         let val = get_param(decl, first_real_arg + 1);
         let count = get_param(decl, first_real_arg + 2);
         let llfn = ccx.get_intrinsic(&name);
-        Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, C_i1(ccx, volatile)], []);
+        Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, C_bool(ccx, volatile)], []);
         RetVoid(bcx);
     }
 
     fn count_zeros_intrinsic(bcx: &Block, name: &'static str) {
         let x = get_param(bcx.fcx.llfn, bcx.fcx.arg_pos(0u));
-        let y = C_i1(bcx.ccx(), false);
+        let y = C_bool(bcx.ccx(), false);
         let llfn = bcx.ccx().get_intrinsic(&name);
         let llcall = Call(bcx, llfn, [x, y], []);
         Ret(bcx, llcall);
@@ -188,11 +195,10 @@ fn count_zeros_intrinsic(bcx: &Block, name: &'static str) {
     let arena = TypedArena::new();
     let fcx = new_fn_ctxt(ccx, decl, item.id, false, output_type,
                           substs, Some(item.span), &arena);
-    init_function(&fcx, true, output_type);
+    let mut bcx = init_function(&fcx, true, output_type);
 
     set_always_inline(fcx.llfn);
 
-    let mut bcx = fcx.entry_bcx.borrow().clone().unwrap();
     let first_real_arg = fcx.arg_pos(0u);
 
     let name = token::get_ident(item.ident);
@@ -366,7 +372,7 @@ fn count_zeros_intrinsic(bcx: &Block, name: &'static str) {
             let retty = *substs.substs.types.get(FnSpace, 0);
             if type_is_immediate(ccx, retty) && !return_type_is_void(ccx, retty) {
                 unsafe {
-                    Ret(bcx, lib::llvm::llvm::LLVMGetUndef(type_of(ccx, retty).to_ref()));
+                    Ret(bcx, lib::llvm::llvm::LLVMGetUndef(arg_type_of(ccx, retty).to_ref()));
                 }
             } else {
                 RetVoid(bcx)
@@ -392,10 +398,10 @@ fn count_zeros_intrinsic(bcx: &Block, name: &'static str) {
                     format!("transmute called on types with different sizes: \
                              {} ({} bit{}) to \
                              {} ({} bit{})",
-                            ty_to_str(ccx.tcx(), in_type),
+                            ty_to_string(ccx.tcx(), in_type),
                             in_type_size,
                             if in_type_size == 1 {""} else {"s"},
-                            ty_to_str(ccx.tcx(), out_type),
+                            ty_to_string(ccx.tcx(), out_type),
                             out_type_size,
                             if out_type_size == 1 {""} else {"s"}).as_slice());
             }
@@ -581,14 +587,14 @@ pub fn check_intrinsics(ccx: &CrateContext) {
                .span_err(transmute_restriction.span,
                 format!("transmute called on types with different sizes: \
                          {} ({} bit{}) to {} ({} bit{})",
-                        ty_to_str(ccx.tcx(), transmute_restriction.from),
+                        ty_to_string(ccx.tcx(), transmute_restriction.from),
                         from_type_size as uint,
                         if from_type_size == 1 {
                             ""
                         } else {
                             "s"
                         },
-                        ty_to_str(ccx.tcx(), transmute_restriction.to),
+                        ty_to_string(ccx.tcx(), transmute_restriction.to),
                         to_type_size as uint,
                         if to_type_size == 1 {
                             ""
index 3cd1a59abef38c1a56b5b06f34f9cf71afc23151..f7884ca5643f76d5990c3bf2ae37ae8ef7f54ca9 100644 (file)
@@ -25,13 +25,13 @@ fn llrepr(&self, ccx: &CrateContext) -> String {
 
 impl LlvmRepr for Type {
     fn llrepr(&self, ccx: &CrateContext) -> String {
-        ccx.tn.type_to_str(*self)
+        ccx.tn.type_to_string(*self)
     }
 }
 
 impl LlvmRepr for ValueRef {
     fn llrepr(&self, ccx: &CrateContext) -> String {
-        ccx.tn.val_to_str(*self)
+        ccx.tn.val_to_string(*self)
     }
 }
 
index 125fa6828c5562c82fb719ea7b455d0d8eafacdf..768deec8edc1eb449143fd3d96341476698e008f 100644 (file)
@@ -129,9 +129,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
         hash_id.hash(&mut state);
         mono_ty.hash(&mut state);
 
-        exported_name(path,
-                      format!("h{}", state.result()).as_slice(),
-                      ccx.link_meta.crateid.version_or_default())
+        exported_name(path, format!("h{}", state.result()).as_slice())
     });
     debug!("monomorphize_fn mangled to {}", s);
 
index 91148d31423fb59a9e0ee6e560ef4a2ce5123aa3..e50eb8f0be99353c77e94f67535404414401f733 100644 (file)
@@ -23,7 +23,7 @@
 use middle::trans::type_::Type;
 use middle::trans::type_of::*;
 use middle::ty;
-use util::ppaux::ty_to_str;
+use util::ppaux::ty_to_string;
 
 use std::rc::Rc;
 use arena::TypedArena;
@@ -98,7 +98,7 @@ pub fn visit(&mut self, ty_name: &str, args: &[ValueRef]) {
         debug!("passing {} args:", args.len());
         let mut bcx = self.bcx;
         for (i, a) in args.iter().enumerate() {
-            debug!("arg {}: {}", i, bcx.val_to_str(*a));
+            debug!("arg {}: {}", i, bcx.val_to_string(*a));
         }
         let result = unpack_result!(bcx, callee::trans_call_inner(
             self.bcx, None, mth_ty,
@@ -129,7 +129,7 @@ pub fn leaf(&mut self, name: &str) {
     pub fn visit_ty(&mut self, t: ty::t) {
         let bcx = self.bcx;
         let tcx = bcx.tcx();
-        debug!("reflect::visit_ty {}", ty_to_str(bcx.tcx(), t));
+        debug!("reflect::visit_ty {}", ty_to_string(bcx.tcx(), t));
 
         match ty::get(t).sty {
           ty::ty_bot => self.leaf("bot"),
@@ -175,7 +175,7 @@ pub fn visit_ty(&mut self, t: ty::t) {
                   ty::ty_trait(..) => {
                       let extra = [
                           self.c_slice(token::intern_and_get_ident(
-                                  ty_to_str(tcx, t).as_slice()))
+                                  ty_to_string(tcx, t).as_slice()))
                       ];
                       self.visit("trait", extra);
                   }
@@ -204,7 +204,7 @@ pub fn visit_ty(&mut self, t: ty::t) {
                   ty::ty_trait(..) => {
                       let extra = [
                           self.c_slice(token::intern_and_get_ident(
-                                  ty_to_str(tcx, t).as_slice()))
+                                  ty_to_string(tcx, t).as_slice()))
                       ];
                       self.visit("trait", extra);
                   }
@@ -269,7 +269,7 @@ pub fn visit_ty(&mut self, t: ty::t) {
 
               let extra = (vec!(
                   self.c_slice(
-                      token::intern_and_get_ident(ty_to_str(tcx,
+                      token::intern_and_get_ident(ty_to_string(tcx,
                                                             t).as_slice())),
                   self.c_bool(named_fields),
                   self.c_uint(fields.len())
@@ -313,7 +313,7 @@ pub fn visit_ty(&mut self, t: ty::t) {
                 let fcx = new_fn_ctxt(ccx, llfdecl, -1, false,
                                       ty::mk_u64(), &empty_param_substs,
                                       None, &arena);
-                init_function(&fcx, false, ty::mk_u64());
+                let bcx = init_function(&fcx, false, ty::mk_u64());
 
                 let arg = unsafe {
                     //
@@ -323,7 +323,6 @@ pub fn visit_ty(&mut self, t: ty::t) {
                     //
                     llvm::LLVMGetParam(llfdecl, fcx.arg_pos(0u) as c_uint)
                 };
-                let bcx = fcx.entry_bcx.borrow().clone().unwrap();
                 let arg = BitCast(bcx, arg, llptrty);
                 let ret = adt::trans_get_discr(bcx, &*repr, arg, Some(Type::i64(ccx)));
                 Store(bcx, ret, fcx.llretptr.get().unwrap());
@@ -331,7 +330,7 @@ pub fn visit_ty(&mut self, t: ty::t) {
                     Some(llreturn) => Br(bcx, llreturn),
                     None => {}
                 };
-                finish_fn(&fcx, bcx);
+                finish_fn(&fcx, bcx, ty::mk_u64());
                 llfdecl
             };
 
index 65bf0b8500821d820a9e87ade08fab792fd5d4f1..a6e554039e77e6ff9f12d2178830577491d9739b 100644 (file)
@@ -29,7 +29,7 @@
 use middle::trans::type_::Type;
 use middle::trans::type_of;
 use middle::ty;
-use util::ppaux::ty_to_str;
+use util::ppaux::ty_to_string;
 
 use syntax::ast;
 use syntax::parse::token::InternedString;
@@ -73,12 +73,12 @@ pub struct VecTypes {
 }
 
 impl VecTypes {
-    pub fn to_str(&self, ccx: &CrateContext) -> String {
+    pub fn to_string(&self, ccx: &CrateContext) -> String {
         format!("VecTypes {{unit_ty={}, llunit_ty={}, \
                  llunit_size={}, llunit_alloc_size={}}}",
-                ty_to_str(ccx.tcx(), self.unit_ty),
-                ccx.tn.type_to_str(self.llunit_ty),
-                ccx.tn.val_to_str(self.llunit_size),
+                ty_to_string(ccx.tcx(), self.unit_ty),
+                ccx.tn.type_to_string(self.llunit_ty),
+                ccx.tn.val_to_string(self.llunit_size),
                 self.llunit_alloc_size)
     }
 }
@@ -97,7 +97,7 @@ pub fn trans_fixed_vstore<'a>(
     // generate the content.
 
     debug!("trans_fixed_vstore(vstore_expr={}, dest={:?})",
-           bcx.expr_to_str(vstore_expr), dest.to_str(bcx.ccx()));
+           bcx.expr_to_string(vstore_expr), dest.to_string(bcx.ccx()));
 
     let vt = vec_types_from_expr(bcx, vstore_expr);
 
@@ -129,7 +129,7 @@ pub fn trans_slice_vstore<'a>(
     let mut bcx = bcx;
 
     debug!("trans_slice_vstore(vstore_expr={}, dest={})",
-           bcx.expr_to_str(vstore_expr), dest.to_str(ccx));
+           bcx.expr_to_string(vstore_expr), dest.to_string(ccx));
 
     // Handle the &"..." case:
     match content_expr.node {
@@ -150,13 +150,14 @@ pub fn trans_slice_vstore<'a>(
     // Handle the &[...] case:
     let vt = vec_types_from_expr(bcx, vstore_expr);
     let count = elements_required(bcx, content_expr);
-    debug!("vt={}, count={:?}", vt.to_str(ccx), count);
+    debug!("vt={}, count={:?}", vt.to_string(ccx), count);
 
     let llcount = C_uint(ccx, count);
     let llfixed;
     if count == 0 {
-        // Zero-length array: just use NULL as the data pointer
-        llfixed = C_null(vt.llunit_ty.ptr_to());
+        // Just create a zero-sized alloca to preserve
+        // the non-null invariant of the inner slice ptr
+        llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount);
     } else {
         // Make a fixed-length backing array and allocate it on the stack.
         llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount);
@@ -201,8 +202,8 @@ pub fn trans_lit_str<'a>(
      */
 
     debug!("trans_lit_str(lit_expr={}, dest={})",
-           bcx.expr_to_str(lit_expr),
-           dest.to_str(bcx.ccx()));
+           bcx.expr_to_string(lit_expr),
+           dest.to_string(bcx.ccx()));
 
     match dest {
         Ignore => bcx,
@@ -232,7 +233,7 @@ pub fn trans_uniq_vstore<'a>(bcx: &'a Block<'a>,
      * the array elements into them.
      */
 
-    debug!("trans_uniq_vstore(vstore_expr={})", bcx.expr_to_str(vstore_expr));
+    debug!("trans_uniq_vstore(vstore_expr={})", bcx.expr_to_string(vstore_expr));
     let fcx = bcx.fcx;
     let ccx = fcx.ccx;
 
@@ -296,7 +297,7 @@ pub fn trans_uniq_vstore<'a>(bcx: &'a Block<'a>,
     let dataptr = get_dataptr(bcx, val);
 
     debug!("alloc_uniq_vec() returned val={}, dataptr={}",
-           bcx.val_to_str(val), bcx.val_to_str(dataptr));
+           bcx.val_to_string(val), bcx.val_to_string(dataptr));
 
     let bcx = write_content(bcx, &vt, vstore_expr,
                             content_expr, SaveIn(dataptr));
@@ -318,9 +319,9 @@ pub fn write_content<'a>(
     let mut bcx = bcx;
 
     debug!("write_content(vt={}, dest={}, vstore_expr={:?})",
-           vt.to_str(bcx.ccx()),
-           dest.to_str(bcx.ccx()),
-           bcx.expr_to_str(vstore_expr));
+           vt.to_string(bcx.ccx()),
+           dest.to_string(bcx.ccx()),
+           bcx.expr_to_string(vstore_expr));
 
     match content_expr.node {
         ast::ExprLit(lit) => {
@@ -360,7 +361,7 @@ pub fn write_content<'a>(
                     for (i, element) in elements.iter().enumerate() {
                         let lleltptr = GEPi(bcx, lldest, [i]);
                         debug!("writing index {:?} with lleltptr={:?}",
-                               i, bcx.val_to_str(lleltptr));
+                               i, bcx.val_to_string(lleltptr));
                         bcx = expr::trans_into(bcx, &**element,
                                                SaveIn(lleltptr));
                         fcx.schedule_drop_mem(
index 1ec792182bd1e5171379ca28bbd333ec3637ef04..b10f6eda8805321359042c817fdbd9ecc2f0da25 100644 (file)
@@ -89,7 +89,7 @@ pub fn f64(ccx: &CrateContext) -> Type {
     }
 
     pub fn bool(ccx: &CrateContext) -> Type {
-        Type::i1(ccx)
+        Type::i8(ccx)
     }
 
     pub fn char(ccx: &CrateContext) -> Type {
index 31bf6cb0110a489699e189359b86db04a765ded9..50c81596edffe9ac1145979f97804c934131c217 100644 (file)
@@ -31,7 +31,7 @@ pub fn return_uses_outptr(ccx: &CrateContext, ty: ty::t) -> bool {
 }
 
 pub fn type_of_explicit_arg(ccx: &CrateContext, arg_ty: ty::t) -> Type {
-    let llty = type_of(ccx, arg_ty);
+    let llty = arg_type_of(ccx, arg_ty);
     if arg_is_indirect(ccx, arg_ty) {
         llty.ptr_to()
     } else {
@@ -46,7 +46,7 @@ pub fn type_of_rust_fn(cx: &CrateContext, has_env: bool,
     // Arg 0: Output pointer.
     // (if the output type is non-immediate)
     let use_out_pointer = return_uses_outptr(cx, output);
-    let lloutputtype = type_of(cx, output);
+    let lloutputtype = arg_type_of(cx, output);
     if use_out_pointer {
         atys.push(lloutputtype.ptr_to());
     }
@@ -167,6 +167,14 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
     llsizingty
 }
 
+pub fn arg_type_of(cx: &CrateContext, t: ty::t) -> Type {
+    if ty::type_is_bool(t) {
+        Type::i1(cx)
+    } else {
+        type_of(cx, t)
+    }
+}
+
 // NB: If you update this, be sure to update `sizing_type_of()` as well.
 pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
     // Check the cache.
@@ -191,7 +199,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
                 t,
                 t_norm.repr(cx.tcx()),
                 t_norm,
-                cx.tn.type_to_str(llty));
+                cx.tn.type_to_string(llty));
         cx.lltypes.borrow_mut().insert(t, llty);
         return llty;
     }
@@ -209,7 +217,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
         // avoids creating more than one copy of the enum when one
         // of the enum's variants refers to the enum itself.
         let repr = adt::represent_type(cx, t);
-        let tps = substs.types.get_vec(subst::TypeSpace);
+        let tps = substs.types.get_slice(subst::TypeSpace);
         let name = llvm_type_name(cx, an_enum, did, tps);
         adt::incomplete_type_of(cx, &*repr, name.as_slice())
       }
@@ -266,7 +274,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
               // in *after* placing it into the type cache. This prevents
               // infinite recursion with recursive struct types.
               let repr = adt::represent_type(cx, t);
-              let tps = substs.types.get_vec(subst::TypeSpace);
+              let tps = substs.types.get_slice(subst::TypeSpace);
               let name = llvm_type_name(cx, a_struct, did, tps);
               adt::incomplete_type_of(cx, &*repr, name.as_slice())
           }
@@ -283,7 +291,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
     debug!("--> mapped t={} {:?} to llty={}",
             t.repr(cx.tcx()),
             t,
-            cx.tn.type_to_str(llty));
+            cx.tn.type_to_string(llty));
 
     cx.lltypes.borrow_mut().insert(t, llty);
 
@@ -305,7 +313,7 @@ pub enum named_ty { a_struct, an_enum }
 pub fn llvm_type_name(cx: &CrateContext,
                       what: named_ty,
                       did: ast::DefId,
-                      tps: &Vec<ty::t>)
+                      tps: &[ty::t])
                       -> String
 {
     let name = match what {
index 9629fb38af80fb62cf58726d520725b139aba143..f9eda70d16ef201e94efd0312ab9a5a3e9369fd7 100644 (file)
@@ -32,8 +32,8 @@
 use middle::ty_fold;
 use middle::ty_fold::{TypeFoldable,TypeFolder};
 use middle;
-use util::ppaux::{note_and_explain_region, bound_region_ptr_to_str};
-use util::ppaux::{trait_store_to_str, ty_to_str};
+use util::ppaux::{note_and_explain_region, bound_region_ptr_to_string};
+use util::ppaux::{trait_store_to_string, ty_to_string};
 use util::ppaux::{Repr, UserString};
 use util::common::{indenter};
 use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet, FnvHashMap};
@@ -981,7 +981,7 @@ pub fn empty() -> Generics {
     }
 
     pub fn has_type_params(&self, space: subst::ParamSpace) -> bool {
-        !self.types.get_vec(space).is_empty()
+        !self.types.is_empty_in(space)
     }
 }
 
@@ -2243,8 +2243,8 @@ pub fn is_instantiable(cx: &ctxt, r_ty: t) -> bool {
     fn type_requires(cx: &ctxt, seen: &mut Vec<DefId>,
                      r_ty: t, ty: t) -> bool {
         debug!("type_requires({}, {})?",
-               ::util::ppaux::ty_to_str(cx, r_ty),
-               ::util::ppaux::ty_to_str(cx, ty));
+               ::util::ppaux::ty_to_string(cx, r_ty),
+               ::util::ppaux::ty_to_string(cx, ty));
 
         let r = {
             get(r_ty).sty == get(ty).sty ||
@@ -2252,8 +2252,8 @@ fn type_requires(cx: &ctxt, seen: &mut Vec<DefId>,
         };
 
         debug!("type_requires({}, {})? {}",
-               ::util::ppaux::ty_to_str(cx, r_ty),
-               ::util::ppaux::ty_to_str(cx, ty),
+               ::util::ppaux::ty_to_string(cx, r_ty),
+               ::util::ppaux::ty_to_string(cx, ty),
                r);
         return r;
     }
@@ -2261,8 +2261,8 @@ fn type_requires(cx: &ctxt, seen: &mut Vec<DefId>,
     fn subtypes_require(cx: &ctxt, seen: &mut Vec<DefId>,
                         r_ty: t, ty: t) -> bool {
         debug!("subtypes_require({}, {})?",
-               ::util::ppaux::ty_to_str(cx, r_ty),
-               ::util::ppaux::ty_to_str(cx, ty));
+               ::util::ppaux::ty_to_string(cx, r_ty),
+               ::util::ppaux::ty_to_string(cx, ty));
 
         let r = match get(ty).sty {
             // fixed length vectors need special treatment compared to
@@ -2337,8 +2337,8 @@ fn subtypes_require(cx: &ctxt, seen: &mut Vec<DefId>,
         };
 
         debug!("subtypes_require({}, {})? {}",
-               ::util::ppaux::ty_to_str(cx, r_ty),
-               ::util::ppaux::ty_to_str(cx, ty),
+               ::util::ppaux::ty_to_string(cx, r_ty),
+               ::util::ppaux::ty_to_string(cx, ty),
                r);
 
         return r;
@@ -2381,7 +2381,7 @@ fn find_nonrepresentable<It: Iterator<t>>(cx: &ctxt, sp: Span, seen: &mut Vec<De
     fn type_structurally_recursive(cx: &ctxt, sp: Span, seen: &mut Vec<DefId>,
                                    ty: t) -> Representability {
         debug!("type_structurally_recursive: {}",
-               ::util::ppaux::ty_to_str(cx, ty));
+               ::util::ppaux::ty_to_string(cx, ty));
 
         // Compare current type to previously seen types
         match get(ty).sty {
@@ -2441,7 +2441,7 @@ fn type_structurally_recursive(cx: &ctxt, sp: Span, seen: &mut Vec<DefId>,
     }
 
     debug!("is_type_representable: {}",
-           ::util::ppaux::ty_to_str(cx, ty));
+           ::util::ppaux::ty_to_string(cx, ty));
 
     // To avoid a stack overflow when checking an enum variant or struct that
     // contains a different, structurally recursive type, maintain a stack
@@ -2595,7 +2595,7 @@ pub fn node_id_to_trait_ref(cx: &ctxt, id: ast::NodeId) -> Rc<ty::TraitRef> {
         Some(t) => t.clone(),
         None => cx.sess.bug(
             format!("node_id_to_trait_ref: no trait ref for node `{}`",
-                    cx.map.node_to_str(id)).as_slice())
+                    cx.map.node_to_string(id)).as_slice())
     }
 }
 
@@ -2608,7 +2608,7 @@ pub fn node_id_to_type(cx: &ctxt, id: ast::NodeId) -> t {
        Some(t) => t,
        None => cx.sess.bug(
            format!("node_id_to_type: no type for node `{}`",
-                   cx.map.node_to_str(id)).as_slice())
+                   cx.map.node_to_string(id)).as_slice())
     }
 }
 
@@ -2842,7 +2842,7 @@ pub fn adjust_ty(cx: &ctxt,
                                         format!("the {}th autoderef failed: \
                                                 {}",
                                                 i,
-                                                ty_to_str(cx, adjusted_ty))
+                                                ty_to_string(cx, adjusted_ty))
                                                           .as_slice());
                                 }
                             }
@@ -3030,6 +3030,9 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
             // the deref method invoked for `*a` always yields an `&T`
             ast::ExprUnary(ast::UnDeref, _) => LvalueExpr,
 
+            // the index method invoked for `a[i]` always yields an `&T`
+            ast::ExprIndex(..) => LvalueExpr,
+
             // in the general case, result could be any type, use DPS
             _ => RvalueDpsExpr
         };
@@ -3217,11 +3220,11 @@ pub fn param_tys_in_type(ty: t) -> Vec<ParamTy> {
     rslt
 }
 
-pub fn ty_sort_str(cx: &ctxt, t: t) -> String {
+pub fn ty_sort_string(cx: &ctxt, t: t) -> String {
     match get(t).sty {
         ty_nil | ty_bot | ty_bool | ty_char | ty_int(_) |
         ty_uint(_) | ty_float(_) | ty_str => {
-            ::util::ppaux::ty_to_str(cx, t)
+            ::util::ppaux::ty_to_string(cx, t)
         }
 
         ty_enum(id, _) => format!("enum {}", item_path_str(cx, id)),
@@ -3274,18 +3277,18 @@ fn tstore_to_closure(s: &TraitStore) -> String {
         terr_mismatch => "types differ".to_string(),
         terr_fn_style_mismatch(values) => {
             format!("expected {} fn but found {} fn",
-                    values.expected.to_str(),
-                    values.found.to_str())
+                    values.expected.to_string(),
+                    values.found.to_string())
         }
         terr_abi_mismatch(values) => {
             format!("expected {} fn but found {} fn",
-                    values.expected.to_str(),
-                    values.found.to_str())
+                    values.expected.to_string(),
+                    values.found.to_string())
         }
         terr_onceness_mismatch(values) => {
             format!("expected {} fn but found {} fn",
-                    values.expected.to_str(),
-                    values.found.to_str())
+                    values.expected.to_string(),
+                    values.found.to_string())
         }
         terr_sigil_mismatch(values) => {
             format!("expected {}, found {}",
@@ -3341,22 +3344,22 @@ fn tstore_to_closure(s: &TraitStore) -> String {
         terr_regions_insufficiently_polymorphic(br, _) => {
             format!("expected bound lifetime parameter {}, \
                      but found concrete lifetime",
-                    bound_region_ptr_to_str(cx, br))
+                    bound_region_ptr_to_string(cx, br))
         }
         terr_regions_overly_polymorphic(br, _) => {
             format!("expected concrete lifetime, \
                      but found bound lifetime parameter {}",
-                    bound_region_ptr_to_str(cx, br))
+                    bound_region_ptr_to_string(cx, br))
         }
         terr_trait_stores_differ(_, ref values) => {
             format!("trait storage differs: expected `{}` but found `{}`",
-                    trait_store_to_str(cx, (*values).expected),
-                    trait_store_to_str(cx, (*values).found))
+                    trait_store_to_string(cx, (*values).expected),
+                    trait_store_to_string(cx, (*values).found))
         }
         terr_sorts(values) => {
             format!("expected {} but found {}",
-                    ty_sort_str(cx, values.expected),
-                    ty_sort_str(cx, values.found))
+                    ty_sort_string(cx, values.expected),
+                    ty_sort_string(cx, values.found))
         }
         terr_traits(values) => {
             format!("expected trait `{}` but found trait `{}`",
@@ -3381,13 +3384,13 @@ fn tstore_to_closure(s: &TraitStore) -> String {
         }
         terr_int_mismatch(ref values) => {
             format!("expected `{}` but found `{}`",
-                    values.expected.to_str(),
-                    values.found.to_str())
+                    values.expected.to_string(),
+                    values.found.to_string())
         }
         terr_float_mismatch(ref values) => {
             format!("expected `{}` but found `{}`",
-                    values.expected.to_str(),
-                    values.found.to_str())
+                    values.expected.to_string(),
+                    values.found.to_string())
         }
         terr_variadic_mismatch(ref values) => {
             format!("expected {} fn but found {} function",
@@ -3698,7 +3701,7 @@ pub fn substd_enum_variants(cx: &ctxt,
 }
 
 pub fn item_path_str(cx: &ctxt, id: ast::DefId) -> String {
-    with_path(cx, id, |path| ast_map::path_to_str(path)).to_string()
+    with_path(cx, id, |path| ast_map::path_to_string(path)).to_string()
 }
 
 pub enum DtorKind {
@@ -3970,7 +3973,7 @@ fn each_super_struct(cx: &ctxt, mut did: ast::DefId, f: |ast::DefId|) {
             None => {
                 cx.sess.bug(
                     format!("ID not mapped to super-struct: {}",
-                            cx.map.node_to_str(did.node)).as_slice());
+                            cx.map.node_to_string(did.node)).as_slice());
             }
         }
     }
@@ -3992,7 +3995,7 @@ pub fn lookup_struct_fields(cx: &ctxt, did: ast::DefId) -> Vec<field_ty> {
                 _ => {
                     cx.sess.bug(
                         format!("ID not mapped to struct fields: {}",
-                                cx.map.node_to_str(did.node)).as_slice());
+                                cx.map.node_to_string(did.node)).as_slice());
                 }
             }
         });
@@ -4618,7 +4621,7 @@ pub fn hash_crate_independent(tcx: &ctxt, t: t, svh: &Svh) -> u64 {
 }
 
 impl Variance {
-    pub fn to_str(self) -> &'static str {
+    pub fn to_string(self) -> &'static str {
         match self {
             Covariant => "+",
             Contravariant => "-",
@@ -4644,14 +4647,14 @@ pub fn construct_parameter_environment(
     let mut types = VecPerParamSpace::empty();
     for &space in subst::ParamSpace::all().iter() {
         push_types_from_defs(tcx, &mut types, space,
-                             generics.types.get_vec(space));
+                             generics.types.get_slice(space));
     }
 
     // map bound 'a => free 'a
     let mut regions = VecPerParamSpace::empty();
     for &space in subst::ParamSpace::all().iter() {
         push_region_params(&mut regions, space, free_id,
-                           generics.regions.get_vec(space));
+                           generics.regions.get_slice(space));
     }
 
     let free_substs = Substs {
@@ -4666,7 +4669,7 @@ pub fn construct_parameter_environment(
     let mut bounds = VecPerParamSpace::empty();
     for &space in subst::ParamSpace::all().iter() {
         push_bounds_from_defs(tcx, &mut bounds, space, &free_substs,
-                              generics.types.get_vec(space));
+                              generics.types.get_slice(space));
     }
 
     debug!("construct_parameter_environment: free_id={} \
@@ -4684,7 +4687,7 @@ pub fn construct_parameter_environment(
     fn push_region_params(regions: &mut VecPerParamSpace<ty::Region>,
                           space: subst::ParamSpace,
                           free_id: ast::NodeId,
-                          region_params: &Vec<RegionParameterDef>)
+                          region_params: &[RegionParameterDef])
     {
         for r in region_params.iter() {
             regions.push(space, ty::free_region_from_def(free_id, r));
@@ -4694,7 +4697,7 @@ fn push_region_params(regions: &mut VecPerParamSpace<ty::Region>,
     fn push_types_from_defs(tcx: &ty::ctxt,
                             types: &mut subst::VecPerParamSpace<ty::t>,
                             space: subst::ParamSpace,
-                            defs: &Vec<TypeParameterDef>) {
+                            defs: &[TypeParameterDef]) {
         for (i, def) in defs.iter().enumerate() {
             let ty = ty::mk_param(tcx, space, i, def.def_id);
             types.push(space, ty);
@@ -4705,7 +4708,7 @@ fn push_bounds_from_defs(tcx: &ty::ctxt,
                              bounds: &mut subst::VecPerParamSpace<ParamBounds>,
                              space: subst::ParamSpace,
                              free_substs: &subst::Substs,
-                             defs: &Vec<TypeParameterDef>) {
+                             defs: &[TypeParameterDef]) {
         for def in defs.iter() {
             let b = (*def.bounds).subst(tcx, free_substs);
             bounds.push(space, b);
index 1ad15e536ecc474f5f8cc71ec10a351729f371bf..d565f144f36567cc4231239605d627928b1bd643 100644 (file)
@@ -66,7 +66,7 @@
 use syntax::{ast, ast_util};
 use syntax::codemap::Span;
 use syntax::owned_slice::OwnedSlice;
-use syntax::print::pprust::{lifetime_to_str, path_to_str};
+use syntax::print::pprust::{lifetime_to_string, path_to_string};
 
 pub trait AstConv {
     fn tcx<'a>(&'a self) -> &'a ty::ctxt;
@@ -108,7 +108,7 @@ pub fn ast_region_to_region(tcx: &ty::ctxt, lifetime: &ast::Lifetime)
     };
 
     debug!("ast_region_to_region(lifetime={} id={}) yields {}",
-            lifetime_to_str(lifetime),
+            lifetime_to_string(lifetime),
             lifetime.id, r.repr(tcx));
 
     r
@@ -142,7 +142,7 @@ pub fn opt_ast_region_to_region<AC:AstConv,RS:RegionScope>(
     };
 
     debug!("opt_ast_region_to_region(opt_lifetime={:?}) yields {}",
-            opt_lifetime.as_ref().map(|e| lifetime_to_str(e)),
+            opt_lifetime.as_ref().map(|e| lifetime_to_string(e)),
             r.repr(this.tcx()));
 
     r
@@ -203,7 +203,7 @@ fn ast_path_substs<AC:AstConv,RS:RegionScope>(
     };
 
     // Convert the type parameters supplied by the user.
-    let ty_param_defs = decl_generics.types.get_vec(TypeSpace);
+    let ty_param_defs = decl_generics.types.get_slice(TypeSpace);
     let supplied_ty_param_count = path.segments.iter().flat_map(|s| s.types.iter()).count();
     let formal_ty_param_count = ty_param_defs.len();
     let required_ty_param_count = ty_param_defs.iter()
@@ -331,7 +331,7 @@ pub fn ast_ty_to_prim_ty(tcx: &ty::ctxt, ast_ty: &ast::Ty) -> Option<ty::t> {
                 None => {
                     tcx.sess.span_bug(ast_ty.span,
                                       format!("unbound path {}",
-                                              path_to_str(path)).as_slice())
+                                              path_to_string(path)).as_slice())
                 }
                 Some(&d) => d
             };
@@ -394,7 +394,7 @@ pub fn ast_ty_to_builtin_ty<AC:AstConv,
                         .sess
                         .span_bug(ast_ty.span,
                                   format!("unbound path {}",
-                                          path_to_str(path)).as_slice())
+                                          path_to_string(path)).as_slice())
                 }
                 Some(&d) => d
             };
@@ -793,7 +793,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
                         tcx.sess
                            .span_bug(ast_ty.span,
                                      format!("unbound path {}",
-                                             path_to_str(path)).as_slice())
+                                             path_to_string(path)).as_slice())
                     }
                     Some(&d) => d
                 };
@@ -808,7 +808,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
                 }
                 match a_def {
                     def::DefTrait(_) => {
-                        let path_str = path_to_str(path);
+                        let path_str = path_to_string(path);
                         tcx.sess.span_err(
                             ast_ty.span,
                             format!("reference to trait `{name}` where a \
@@ -835,7 +835,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
                     def::DefMod(id) => {
                         tcx.sess.span_fatal(ast_ty.span,
                             format!("found module name used as a type: {}",
-                                    tcx.map.node_to_str(id.node)).as_slice());
+                                    tcx.map.node_to_string(id.node)).as_slice());
                     }
                     def::DefPrimTy(_) => {
                         fail!("DefPrimTy arm missed in previous ast_ty_to_prim_ty call");
index 697c5d367ee5a51ab3a65cd2a6945de0d3ae5db6..2232cc4965785fcab7d6aa3b4f787a27c6665c48 100644 (file)
@@ -362,36 +362,16 @@ pub fn check_struct_pat_fields(pcx: &pat_ctxt,
     }
 }
 
-pub fn check_struct_pat(pcx: &pat_ctxt, pat_id: ast::NodeId, span: Span,
-                        expected: ty::t, path: &ast::Path,
+pub fn check_struct_pat(pcx: &pat_ctxt, _pat_id: ast::NodeId, span: Span,
+                        _expected: ty::t, _path: &ast::Path,
                         fields: &[ast::FieldPat], etc: bool,
                         struct_id: ast::DefId,
                         substitutions: &subst::Substs) {
-    let fcx = pcx.fcx;
+    let _fcx = pcx.fcx;
     let tcx = pcx.fcx.ccx.tcx;
 
     let class_fields = ty::lookup_struct_fields(tcx, struct_id);
 
-    // Check to ensure that the struct is the one specified.
-    match tcx.def_map.borrow().find(&pat_id) {
-        Some(&def::DefStruct(supplied_def_id))
-                if supplied_def_id == struct_id => {
-            // OK.
-        }
-        Some(&def::DefStruct(..)) | Some(&def::DefVariant(..)) => {
-            let name = pprust::path_to_str(path);
-            tcx.sess
-               .span_err(span,
-                         format!("mismatched types: expected `{}` but found \
-                                  `{}`",
-                                 fcx.infcx().ty_to_str(expected),
-                                 name).as_slice());
-        }
-        _ => {
-            tcx.sess.span_bug(span, "resolve didn't write in struct ID");
-        }
-    }
-
     check_struct_pat_fields(pcx, span, fields, class_fields, struct_id,
                             substitutions, etc);
 }
@@ -419,11 +399,11 @@ pub fn check_struct_like_enum_variant_pat(pcx: &pat_ctxt,
                                     variant_id, substitutions, etc);
         }
         Some(&def::DefStruct(..)) | Some(&def::DefVariant(..)) => {
-            let name = pprust::path_to_str(path);
+            let name = pprust::path_to_string(path);
             tcx.sess.span_err(span,
                               format!("mismatched types: expected `{}` but \
                                        found `{}`",
-                                      fcx.infcx().ty_to_str(expected),
+                                      fcx.infcx().ty_to_string(expected),
                                       name).as_slice());
         }
         _ => {
@@ -535,6 +515,21 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
         let mut error_happened = false;
         match *structure {
             ty::ty_struct(cid, ref substs) => {
+                // Verify that the pattern named the right structure.
+                let item_did = tcx.def_map.borrow().get(&pat.id).def_id();
+                let struct_did =
+                    ty::ty_to_def_id(
+                        ty::lookup_item_type(tcx, item_did).ty).unwrap();
+                if struct_did != cid {
+                    tcx.sess
+                       .span_err(path.span,
+                                 format!("`{}` does not name the \
+                                          structure `{}`",
+                                         pprust::path_to_string(path),
+                                         fcx.infcx()
+                                            .ty_to_string(expected)).as_slice())
+                }
+
                 check_struct_pat(pcx, pat.id, pat.span, expected, path,
                                  fields.as_slice(), etc, cid, substs);
             }
@@ -562,7 +557,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
                             "a structure pattern".to_string(),
                             None);
                 match tcx.def_map.borrow().find(&pat.id) {
-                    Some(&def::DefStruct(supplied_def_id)) => {
+                    Some(def) => {
                          check_struct_pat(pcx,
                                           pat.id,
                                           pat.span,
@@ -570,10 +565,14 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
                                           path,
                                           fields.as_slice(),
                                           etc,
-                                          supplied_def_id,
+                                          def.def_id(),
                                           &subst::Substs::empty());
                     }
-                    _ => () // Error, but we're already in an error case
+                    None => {
+                        tcx.sess.span_bug(pat.span,
+                                          "whoops, looks like resolve didn't \
+                                           write a def in here")
+                    }
                 }
                 error_happened = true;
             }
@@ -748,7 +747,7 @@ fn check_pointer_pat(pcx: &pat_ctxt,
                 tcx.sess.span_err(
                     span,
                     format!("type `{}` cannot be dereferenced",
-                            fcx.infcx().ty_to_str(expected)).as_slice());
+                            fcx.infcx().ty_to_string(expected)).as_slice());
                 fcx.write_error(pat_id);
             }
             _ => {
index c3b2756bdbff2f7f165af2718ec6a1fe293a7452..c1a000841a4d1f4cfb274c2ead2798896d6279d8 100644 (file)
@@ -30,14 +30,14 @@ impl like `impl Foo` are inherent methods.  Nothing needs to be
 module as the type itself).
 
 Inherent candidates are not always derived from impls.  If you have a
-trait instance, such as a value of type `Box<ToStr>`, then the trait
-methods (`to_str()`, in this case) are inherently associated with it.
+trait instance, such as a value of type `Box<ToString>`, then the trait
+methods (`to_string()`, in this case) are inherently associated with it.
 Another case is type parameters, in which case the methods of their
 bounds are inherent.
 
 Extension candidates are derived from imported traits.  If I have the
-trait `ToStr` imported, and I call `to_str()` on a value of type `T`,
-then we will go off to find out whether there is an impl of `ToStr`
+trait `ToString` imported, and I call `to_string()` on a value of type `T`,
+then we will go off to find out whether there is an impl of `ToString`
 for `T`.  These kinds of method calls are called "extension methods".
 They can be defined in any module, not only the one that defined `T`.
 Furthermore, you must import the trait to call such a method.
@@ -264,7 +264,7 @@ fn construct_transformed_self_ty_for_object(
     // The subst we get in has Err as the "Self" type. For an object
     // type, we don't put any type into the Self paramspace, so let's
     // make a copy of rcvr_substs that has the Self paramspace empty.
-    obj_substs.types.get_mut_vec(subst::SelfSpace).pop().unwrap();
+    obj_substs.types.pop(subst::SelfSpace).unwrap();
 
     match method_ty.explicit_self {
         ast::SelfStatic => {
@@ -376,7 +376,7 @@ fn search_step(&self,
                    autoderefs: uint)
                    -> Option<Option<MethodCallee>> {
         debug!("search_step: self_ty={} autoderefs={}",
-               self.ty_to_str(self_ty), autoderefs);
+               self.ty_to_string(self_ty), autoderefs);
 
         match self.deref_args {
             check::DontDerefArgs => {
@@ -508,7 +508,7 @@ fn push_inherent_candidates_from_object(&mut self,
                                             did: DefId,
                                             substs: &subst::Substs) {
         debug!("push_inherent_candidates_from_object(did={}, substs={})",
-               self.did_to_str(did),
+               self.did_to_string(did),
                substs.repr(self.tcx()));
         let _indenter = indenter();
         let tcx = self.tcx();
@@ -733,7 +733,7 @@ fn search_for_autoderefd_method(&self,
             None => None,
             Some(method) => {
                 debug!("(searching for autoderef'd method) writing \
-                       adjustment {:?} for {}", adjustment, self.ty_to_str( self_ty));
+                       adjustment {:?} for {}", adjustment, self.ty_to_string( self_ty));
                 match adjustment {
                     Some((self_expr_id, adj)) => {
                         self.fcx.write_adjustment(self_expr_id, adj);
@@ -809,7 +809,7 @@ fn default_method_hack(self_mt: ty::mt) -> bool {
 
     fn auto_slice_vec(&self, mt: ty::mt, autoderefs: uint) -> Option<MethodCallee> {
         let tcx = self.tcx();
-        debug!("auto_slice_vec {}", ppaux::ty_to_str(tcx, mt.ty));
+        debug!("auto_slice_vec {}", ppaux::ty_to_string(tcx, mt.ty));
 
         // First try to borrow to a slice
         let entry = self.search_for_some_kind_of_autorefd_method(
@@ -886,7 +886,7 @@ fn search_for_autosliced_method(&self,
          * `~[]` to `&[]`.
          */
 
-        debug!("search_for_autosliced_method {}", ppaux::ty_to_str(self.tcx(), self_ty));
+        debug!("search_for_autosliced_method {}", ppaux::ty_to_string(self.tcx(), self_ty));
 
         let sty = ty::get(self_ty).sty.clone();
         match sty {
@@ -939,7 +939,7 @@ fn search_for_autoptrd_method(&self, self_ty: ty::t, autoderefs: uint)
 
             ty_infer(TyVar(_)) => {
                 self.bug(format!("unexpected type: {}",
-                                 self.ty_to_str(self_ty)).as_slice());
+                                 self.ty_to_string(self_ty)).as_slice());
             }
         }
     }
@@ -993,7 +993,7 @@ fn search_for_some_kind_of_autorefd_method(
     }
 
     fn search_for_method(&self, rcvr_ty: ty::t) -> Option<MethodCallee> {
-        debug!("search_for_method(rcvr_ty={})", self.ty_to_str(rcvr_ty));
+        debug!("search_for_method(rcvr_ty={})", self.ty_to_string(rcvr_ty));
         let _indenter = indenter();
 
         // I am not sure that inherent methods should have higher
@@ -1094,7 +1094,7 @@ fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
         let tcx = self.tcx();
 
         debug!("confirm_candidate(rcvr_ty={}, candidate={})",
-               self.ty_to_str(rcvr_ty),
+               self.ty_to_string(rcvr_ty),
                candidate.repr(self.tcx()));
 
         self.enforce_object_limitations(candidate);
@@ -1133,7 +1133,7 @@ fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
         let m_regions =
             self.fcx.infcx().region_vars_for_defs(
                 self.span,
-                candidate.method_ty.generics.regions.get_vec(subst::FnSpace));
+                candidate.method_ty.generics.regions.get_slice(subst::FnSpace));
 
         let all_substs = candidate.rcvr_substs.clone().with_method(m_types, m_regions);
 
@@ -1177,7 +1177,7 @@ fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
             fn_style: bare_fn_ty.fn_style,
             abi: bare_fn_ty.abi.clone(),
         });
-        debug!("after replacing bound regions, fty={}", self.ty_to_str(fty));
+        debug!("after replacing bound regions, fty={}", self.ty_to_string(fty));
 
         // Before, we only checked whether self_ty could be a subtype
         // of rcvr_ty; now we actually make it so (this may cause
@@ -1191,8 +1191,8 @@ fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
             Err(_) => {
                 self.bug(format!(
                         "{} was a subtype of {} but now is not?",
-                        self.ty_to_str(rcvr_ty),
-                        self.ty_to_str(transformed_self_ty)).as_slice());
+                        self.ty_to_string(rcvr_ty),
+                        self.ty_to_string(transformed_self_ty)).as_slice());
             }
         }
 
@@ -1288,7 +1288,7 @@ fn enforce_drop_trait_limitations(&self, candidate: &Candidate) {
     // candidate method's `self_ty`.
     fn is_relevant(&self, rcvr_ty: ty::t, candidate: &Candidate) -> bool {
         debug!("is_relevant(rcvr_ty={}, candidate={})",
-               self.ty_to_str(rcvr_ty), candidate.repr(self.tcx()));
+               self.ty_to_string(rcvr_ty), candidate.repr(self.tcx()));
 
         return match candidate.method_ty.explicit_self {
             SelfStatic => {
@@ -1457,11 +1457,11 @@ fn tcx(&self) -> &'a ty::ctxt {
         self.fcx.tcx()
     }
 
-    fn ty_to_str(&self, t: ty::t) -> String {
-        self.fcx.infcx().ty_to_str(t)
+    fn ty_to_string(&self, t: ty::t) -> String {
+        self.fcx.infcx().ty_to_string(t)
     }
 
-    fn did_to_str(&self, did: DefId) -> String {
+    fn did_to_string(&self, did: DefId) -> String {
         ty::item_path_str(self.tcx(), did)
     }
 
index b68991aed70963c53c341788689c4f11e1652a7a..9f5fcb61f5fd0e9646416a7d13f12b9c1853376d 100644 (file)
@@ -397,8 +397,8 @@ fn visit_local(&mut self, local: &ast::Local, _: ()) {
         };
         self.assign(local.id, o_ty);
         debug!("Local variable {} is assigned type {}",
-               self.fcx.pat_to_str(&*local.pat),
-               self.fcx.infcx().ty_to_str(
+               self.fcx.pat_to_string(&*local.pat),
+               self.fcx.infcx().ty_to_string(
                    self.fcx.inh.locals.borrow().get_copy(&local.id)));
         visit::walk_local(self, local, ());
     }
@@ -411,7 +411,7 @@ fn visit_pat(&mut self, p: &ast::Pat, _: ()) {
                 self.assign(p.id, None);
                 debug!("Pattern binding {} is assigned to {}",
                        token::get_ident(path1.node),
-                       self.fcx.infcx().ty_to_str(
+                       self.fcx.infcx().ty_to_string(
                            self.fcx.inh.locals.borrow().get_copy(&p.id)));
               }
               _ => {}
@@ -534,7 +534,7 @@ fn span_for_field(tcx: &ty::ctxt, field: &ty::field_ty, struct_id: ast::DefId) -
     let item = match tcx.map.find(struct_id.node) {
         Some(ast_map::NodeItem(item)) => item,
         None => fail!("node not in ast map: {}", struct_id.node),
-        _ => fail!("expected item, found {}", tcx.map.node_to_str(struct_id.node))
+        _ => fail!("expected item, found {}", tcx.map.node_to_string(struct_id.node))
     };
 
     match item.node {
@@ -803,7 +803,7 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
                     format!(
                         "method `{}` is not a member of trait `{}`",
                         token::get_ident(impl_method_ty.ident),
-                        pprust::path_to_str(&ast_trait_ref.path)).as_slice());
+                        pprust::path_to_string(&ast_trait_ref.path)).as_slice());
             }
         }
     }
@@ -870,7 +870,7 @@ fn compare_impl_method(tcx: &ty::ctxt,
                 format!("method `{}` has a `{}` declaration in the impl, \
                         but not in the trait",
                         token::get_ident(trait_m.ident),
-                        pprust::explicit_self_to_str(
+                        pprust::explicit_self_to_string(
                             impl_m.explicit_self)).as_slice());
             return;
         }
@@ -880,7 +880,7 @@ fn compare_impl_method(tcx: &ty::ctxt,
                 format!("method `{}` has a `{}` declaration in the trait, \
                         but not in the impl",
                         token::get_ident(trait_m.ident),
-                        pprust::explicit_self_to_str(
+                        pprust::explicit_self_to_string(
                             trait_m.explicit_self)).as_slice());
             return;
         }
@@ -917,8 +917,8 @@ fn compare_impl_method(tcx: &ty::ctxt,
         return;
     }
 
-    let it = trait_m.generics.types.get_vec(subst::FnSpace).iter()
-        .zip(impl_m.generics.types.get_vec(subst::FnSpace).iter());
+    let it = trait_m.generics.types.get_slice(subst::FnSpace).iter()
+        .zip(impl_m.generics.types.get_slice(subst::FnSpace).iter());
 
     // This code is best explained by example. Consider a trait:
     //
@@ -989,8 +989,8 @@ fn compare_impl_method(tcx: &ty::ctxt,
     let trait_to_skol_substs =
         trait_to_impl_substs
         .subst(tcx, &impl_to_skol_substs)
-        .with_method(skol_tps.get_vec(subst::FnSpace).clone(),
-                     skol_regions.get_vec(subst::FnSpace).clone());
+        .with_method(Vec::from_slice(skol_tps.get_slice(subst::FnSpace)),
+                     Vec::from_slice(skol_regions.get_slice(subst::FnSpace)));
     let trait_fty = ty::mk_bare_fn(tcx, trait_m.fty.clone());
     let trait_fty = trait_fty.subst(tcx, &trait_to_skol_substs);
 
@@ -1051,7 +1051,7 @@ fn compare_impl_method(tcx: &ty::ctxt,
                                            declaration",
                                           token::get_ident(trait_m.ident),
                                           i,
-                                          ppaux::trait_ref_to_str(
+                                          ppaux::trait_ref_to_string(
                                               tcx,
                                               &*impl_trait_bound)).as_slice())
             }
@@ -1101,8 +1101,8 @@ fn check_cast(fcx: &FnCtxt,
 
     let t_e = fcx.expr_ty(e);
 
-    debug!("t_1={}", fcx.infcx().ty_to_str(t_1));
-    debug!("t_e={}", fcx.infcx().ty_to_str(t_e));
+    debug!("t_1={}", fcx.infcx().ty_to_string(t_1));
+    debug!("t_e={}", fcx.infcx().ty_to_string(t_e));
 
     if ty::type_is_error(t_e) {
         fcx.write_error(id);
@@ -1126,13 +1126,13 @@ fn check_cast(fcx: &FnCtxt,
         fcx.type_error_message(span, |actual| {
             format!("cast from nil: `{}` as `{}`",
                     actual,
-                    fcx.infcx().ty_to_str(t_1))
+                    fcx.infcx().ty_to_string(t_1))
         }, t_e, None);
     } else if ty::type_is_nil(t_1) {
         fcx.type_error_message(span, |actual| {
             format!("cast to nil: `{}` as `{}`",
                     actual,
-                    fcx.infcx().ty_to_str(t_1))
+                    fcx.infcx().ty_to_string(t_1))
         }, t_e, None);
     }
 
@@ -1149,7 +1149,7 @@ fn check_cast(fcx: &FnCtxt,
                 format!("illegal cast; cast through an \
                          integer first: `{}` as `{}`",
                         actual,
-                        fcx.infcx().ty_to_str(t_1))
+                        fcx.infcx().ty_to_string(t_1))
             }, t_e, None);
         }
         // casts from C-like enums are allowed
@@ -1217,7 +1217,7 @@ fn types_compatible(fcx: &FnCtxt, sp: Span,
         fcx.type_error_message(span, |actual| {
             format!("non-scalar cast: `{}` as `{}`",
                     actual,
-                    fcx.infcx().ty_to_str(t_1))
+                    fcx.infcx().ty_to_string(t_1))
         }, t_e, None);
     }
 
@@ -1286,7 +1286,7 @@ pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> ty::t {
     #[inline]
     pub fn write_ty(&self, node_id: ast::NodeId, ty: ty::t) {
         debug!("write_ty({}, {}) in fcx {}",
-               node_id, ppaux::ty_to_str(self.tcx(), ty), self.tag());
+               node_id, ppaux::ty_to_string(self.tcx(), ty), self.tag());
         self.inh.node_types.borrow_mut().insert(node_id, ty);
     }
 
@@ -1343,7 +1343,7 @@ pub fn to_ty(&self, ast_t: &ast::Ty) -> ty::t {
         ast_ty_to_ty(self, self.infcx(), ast_t)
     }
 
-    pub fn pat_to_str(&self, pat: &ast::Pat) -> String {
+    pub fn pat_to_string(&self, pat: &ast::Pat) -> String {
         pat.repr(self.tcx())
     }
 
@@ -1363,7 +1363,7 @@ pub fn node_ty(&self, id: ast::NodeId) -> ty::t {
             None => {
                 self.tcx().sess.bug(
                     format!("no type for node {}: {} in fcx {}",
-                            id, self.tcx().map.node_to_str(id),
+                            id, self.tcx().map.node_to_string(id),
                             self.tag()).as_slice());
             }
         }
@@ -1375,7 +1375,7 @@ pub fn method_ty_substs(&self, id: ast::NodeId) -> subst::Substs {
             None => {
                 self.tcx().sess.bug(
                     format!("no method entry for node {}: {} in fcx {}",
-                            id, self.tcx().map.node_to_str(id),
+                            id, self.tcx().map.node_to_string(id),
                             self.tag()).as_slice());
             }
         }
@@ -1629,6 +1629,76 @@ fn try_overloaded_deref(fcx: &FnCtxt,
     }
 }
 
+fn try_overloaded_index(fcx: &FnCtxt,
+                        method_call: Option<MethodCall>,
+                        expr: &ast::Expr,
+                        base_expr: Gc<ast::Expr>,
+                        base_ty: ty::t,
+                        index_expr: Gc<ast::Expr>,
+                        lvalue_pref: LvaluePreference)
+                        -> Option<ty::mt> {
+    // Try `IndexMut` first, if preferred.
+    let method = match (lvalue_pref, fcx.tcx().lang_items.index_mut_trait()) {
+        (PreferMutLvalue, Some(trait_did)) => {
+            method::lookup_in_trait(fcx,
+                                    expr.span,
+                                    Some(&*base_expr),
+                                    token::intern("index_mut"),
+                                    trait_did,
+                                    base_ty,
+                                    [],
+                                    DontAutoderefReceiver,
+                                    IgnoreStaticMethods)
+        }
+        _ => None,
+    };
+
+    // Otherwise, fall back to `Index`.
+    let method = match (method, fcx.tcx().lang_items.index_trait()) {
+        (None, Some(trait_did)) => {
+            method::lookup_in_trait(fcx,
+                                    expr.span,
+                                    Some(&*base_expr),
+                                    token::intern("index"),
+                                    trait_did,
+                                    base_ty,
+                                    [],
+                                    DontAutoderefReceiver,
+                                    IgnoreStaticMethods)
+        }
+        (method, _) => method,
+    };
+
+    // Regardless of whether the lookup succeeds, check the method arguments
+    // so that we have *some* type for each argument.
+    let method_type = match method {
+        Some(ref method) => method.ty,
+        None => ty::mk_err()
+    };
+    check_method_argument_types(fcx,
+                                expr.span,
+                                method_type,
+                                expr,
+                                [base_expr, index_expr],
+                                DoDerefArgs,
+                                DontTupleArguments);
+
+    match method {
+        Some(method) => {
+            let ref_ty = ty::ty_fn_ret(method.ty);
+            match method_call {
+                Some(method_call) => {
+                    fcx.inh.method_map.borrow_mut().insert(method_call,
+                                                           method);
+                }
+                None => {}
+            }
+            ty::deref(ref_ty, true)
+        }
+        None => None,
+    }
+}
+
 fn check_method_argument_types(fcx: &FnCtxt,
                                sp: Span,
                                method_fn_ty: ty::t,
@@ -1772,7 +1842,7 @@ fn check_argument_types(fcx: &FnCtxt,
     };
 
     debug!("check_argument_types: formal_tys={:?}",
-           formal_tys.iter().map(|t| fcx.infcx().ty_to_str(*t)).collect::<Vec<String>>());
+           formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
 
     // Check the arguments.
     // We do this in a pretty awful way: first we typecheck any arguments
@@ -2002,7 +2072,7 @@ pub fn impl_self_ty(vcx: &VtableContext,
     let ity = ty::lookup_item_type(tcx, did);
     let (n_tps, rps, raw_ty) =
         (ity.generics.types.len(subst::TypeSpace),
-         ity.generics.regions.get_vec(subst::TypeSpace),
+         ity.generics.regions.get_slice(subst::TypeSpace),
          ity.ty);
 
     let rps = vcx.infcx.region_vars_for_defs(span, rps);
@@ -2340,7 +2410,7 @@ fn check_binop(fcx: &FnCtxt,
                                              operation `{}` not \
                                              supported for floating \
                                              point SIMD vector `{}`",
-                                            ast_util::binop_to_str(op),
+                                            ast_util::binop_to_string(op),
                                             actual)
                                 },
                                 lhs_t,
@@ -2370,7 +2440,7 @@ fn check_binop(fcx: &FnCtxt,
                                    |actual| {
                     format!("binary operation `{}` cannot be applied \
                              to type `{}`",
-                            ast_util::binop_to_str(op),
+                            ast_util::binop_to_string(op),
                             actual)
                 },
                 lhs_t,
@@ -2387,7 +2457,7 @@ fn check_binop(fcx: &FnCtxt,
                                                  operation `{}=` \
                                                  cannot be applied to \
                                                  type `{}`",
-                                                ast_util::binop_to_str(op),
+                                                ast_util::binop_to_string(op),
                                                 actual)
                                    },
                                    lhs_t,
@@ -2436,7 +2506,7 @@ fn check_user_binop(fcx: &FnCtxt,
                          trait_did, [lhs_expr, rhs], DontAutoderefReceiver, || {
             fcx.type_error_message(ex.span, |actual| {
                 format!("binary operation `{}` cannot be applied to type `{}`",
-                        ast_util::binop_to_str(op),
+                        ast_util::binop_to_string(op),
                         actual)
             }, lhs_resolved_t, None)
         })
@@ -2524,7 +2594,7 @@ fn check_expr_fn(fcx: &FnCtxt,
                                            expected_sig);
         let fty_sig = fn_ty.sig.clone();
         let fty = ty::mk_closure(tcx, fn_ty);
-        debug!("check_expr_fn fty={}", fcx.infcx().ty_to_str(fty));
+        debug!("check_expr_fn fty={}", fcx.infcx().ty_to_string(fty));
 
         fcx.write_ty(expr.id, fty);
 
@@ -2558,7 +2628,7 @@ fn check_field(fcx: &FnCtxt,
             autoderef(fcx, expr.span, expr_t, Some(base.id), lvalue_pref, |base_t, _| {
                 match ty::get(base_t).sty {
                     ty::ty_struct(base_id, ref substs) => {
-                        debug!("struct named {}", ppaux::ty_to_str(tcx, base_t));
+                        debug!("struct named {}", ppaux::ty_to_string(tcx, base_t));
                         let fields = ty::lookup_struct_fields(tcx, base_id);
                         lookup_field_ty(tcx, base_id, fields.as_slice(),
                                         field.node.name, &(*substs))
@@ -3296,17 +3366,34 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
         // Resolve the path.
         let def = tcx.def_map.borrow().find(&id).map(|i| *i);
         match def {
-            Some(def::DefStruct(type_def_id)) => {
-                check_struct_constructor(fcx, id, expr.span, type_def_id,
-                                         fields.as_slice(), base_expr);
-            }
             Some(def::DefVariant(enum_id, variant_id, _)) => {
                 check_struct_enum_variant(fcx, id, expr.span, enum_id,
                                           variant_id, fields.as_slice());
             }
+            Some(def) => {
+                // Verify that this was actually a struct.
+                let typ = ty::lookup_item_type(fcx.ccx.tcx, def.def_id());
+                match ty::get(typ.ty).sty {
+                    ty::ty_struct(struct_did, _) => {
+                        check_struct_constructor(fcx,
+                                                 id,
+                                                 expr.span,
+                                                 struct_did,
+                                                 fields.as_slice(),
+                                                 base_expr);
+                    }
+                    _ => {
+                        tcx.sess
+                           .span_err(path.span,
+                                     format!("`{}` does not name a structure",
+                                             pprust::path_to_string(
+                                                 path)).as_slice())
+                    }
+                }
+            }
             _ => {
                 tcx.sess.span_bug(path.span,
-                                  "structure constructor does not name a structure type");
+                                  "structure constructor wasn't resolved")
             }
         }
       }
@@ -3323,7 +3410,7 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
           } else if ty::type_is_error(idx_t) || ty::type_is_bot(idx_t) {
               fcx.write_ty(id, idx_t);
           } else {
-              let (base_t, autoderefs, field_ty) =
+              let (_, autoderefs, field_ty) =
                 autoderef(fcx, expr.span, raw_base_t, Some(base.id),
                           lvalue_pref, |base_t, _| ty::index(base_t));
               match field_ty {
@@ -3333,27 +3420,33 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
                       fcx.write_autoderef_adjustment(base.id, autoderefs);
                   }
                   None => {
-                      let resolved = structurally_resolved_type(fcx,
-                                                                expr.span,
-                                                                raw_base_t);
-                      let ret_ty = lookup_op_method(fcx,
-                                                    expr,
-                                                    resolved,
-                                                    token::intern("index"),
-                                                    tcx.lang_items.index_trait(),
-                                                    [base.clone(), idx.clone()],
-                                                    AutoderefReceiver,
-                                                    || {
-                        fcx.type_error_message(expr.span,
-                                               |actual| {
-                                                    format!("cannot index a \
-                                                             value of type \
-                                                             `{}`", actual)
-                                               },
-                                               base_t,
-                                               None);
-                      });
-                      fcx.write_ty(id, ret_ty);
+                      // This is an overloaded method.
+                      let base_t = structurally_resolved_type(fcx,
+                                                              expr.span,
+                                                              raw_base_t);
+                      let method_call = MethodCall::expr(expr.id);
+                      match try_overloaded_index(fcx,
+                                                 Some(method_call),
+                                                 expr,
+                                                 *base,
+                                                 base_t,
+                                                 *idx,
+                                                 lvalue_pref) {
+                          Some(mt) => fcx.write_ty(id, mt.ty),
+                          None => {
+                                fcx.type_error_message(expr.span,
+                                                       |actual| {
+                                                        format!("cannot \
+                                                                 index a \
+                                                                 value of \
+                                                                 type `{}`",
+                                                                actual)
+                                                       },
+                                                       base_t,
+                                                       None);
+                                fcx.write_ty(id, ty::mk_err())
+                          }
+                      }
                   }
               }
           }
@@ -3361,10 +3454,10 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
     }
 
     debug!("type of expr({}) {} is...", expr.id,
-           syntax::print::pprust::expr_to_str(expr));
+           syntax::print::pprust::expr_to_string(expr));
     debug!("... {}, expected is {}",
-           ppaux::ty_to_str(tcx, fcx.expr_ty(expr)),
-           expected.repr(tcx))
+           ppaux::ty_to_string(tcx, fcx.expr_ty(expr)),
+           expected.repr(tcx));
 
     unifier();
 }
@@ -3699,7 +3792,7 @@ pub fn check_instantiable(tcx: &ty::ctxt,
                      format!("this type cannot be instantiated without an \
                               instance of itself; consider using \
                               `Option<{}>`",
-                             ppaux::ty_to_str(tcx, item_ty)).as_slice());
+                             ppaux::ty_to_string(tcx, item_ty)).as_slice());
         false
     } else {
         true
@@ -3760,7 +3853,7 @@ pub fn check_enum_variants_sized(ccx: &CrateCtxt,
                                         dynamically sized types may only \
                                         appear as the final type in a \
                                         variant",
-                                       ppaux::ty_to_str(ccx.tcx,
+                                       ppaux::ty_to_string(ccx.tcx,
                                                         *t)).as_slice());
                     }
                 }
@@ -3825,7 +3918,7 @@ fn do_check(ccx: &CrateCtxt,
 
             match v.node.disr_expr {
                 Some(e) => {
-                    debug!("disr expr, checking {}", pprust::expr_to_str(&*e));
+                    debug!("disr expr, checking {}", pprust::expr_to_string(&*e));
 
                     let inh = blank_inherited_fields(ccx);
                     let fcx = blank_fn_ctxt(ccx, &inh, rty, e.id);
@@ -4126,12 +4219,10 @@ pub fn instantiate_path(fcx: &FnCtxt,
     // a problem.
     for &space in ParamSpace::all().iter() {
         adjust_type_parameters(fcx, span, space, type_defs, &mut substs);
-        assert_eq!(substs.types.get_vec(space).len(),
-                   type_defs.get_vec(space).len());
+        assert_eq!(substs.types.len(space), type_defs.len(space));
 
         adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
-        assert_eq!(substs.regions().get_vec(space).len(),
-                   region_defs.get_vec(space).len());
+        assert_eq!(substs.regions().len(space), region_defs.len(space));
     }
 
     fcx.write_ty_substs(node_id, polytype.ty, ty::ItemSubsts {
@@ -4183,8 +4274,8 @@ fn push_explicit_parameters_from_segment_to_substs(
          */
 
         {
-            let type_count = type_defs.get_vec(space).len();
-            assert_eq!(substs.types.get_vec(space).len(), 0);
+            let type_count = type_defs.len(space);
+            assert_eq!(substs.types.len(space), 0);
             for (i, &typ) in segment.types.iter().enumerate() {
                 let t = fcx.to_ty(&*typ);
                 if i < type_count {
@@ -4198,14 +4289,14 @@ fn push_explicit_parameters_from_segment_to_substs(
                              but found {} parameter(s)",
                             type_count,
                             segment.types.len()).as_slice());
-                    substs.types.get_mut_vec(space).truncate(0);
+                    substs.types.truncate(space, 0);
                 }
             }
         }
 
         {
-            let region_count = region_defs.get_vec(space).len();
-            assert_eq!(substs.regions().get_vec(space).len(), 0);
+            let region_count = region_defs.len(space);
+            assert_eq!(substs.regions().len(space), 0);
             for (i, lifetime) in segment.lifetimes.iter().enumerate() {
                 let r = ast_region_to_region(fcx.tcx(), lifetime);
                 if i < region_count {
@@ -4218,7 +4309,7 @@ fn push_explicit_parameters_from_segment_to_substs(
                              expected {} parameter(s) but found {} parameter(s)",
                             region_count,
                             segment.lifetimes.len()).as_slice());
-                    substs.mut_regions().get_mut_vec(space).truncate(0);
+                    substs.mut_regions().truncate(space, 0);
                 }
             }
         }
@@ -4231,8 +4322,8 @@ fn adjust_type_parameters(
         defs: &VecPerParamSpace<ty::TypeParameterDef>,
         substs: &mut Substs)
     {
-        let provided_len = substs.types.get_vec(space).len();
-        let desired = defs.get_vec(space).as_slice();
+        let provided_len = substs.types.len(space);
+        let desired = defs.get_slice(space);
         let required_len = desired.iter()
                               .take_while(|d| d.default.is_none())
                               .count();
@@ -4252,8 +4343,8 @@ fn adjust_type_parameters(
         // Nothing specified at all: supply inference variables for
         // everything.
         if provided_len == 0 {
-            let provided = substs.types.get_mut_vec(space);
-            *provided = fcx.infcx().next_ty_vars(desired.len());
+            substs.types.replace(space,
+                                 fcx.infcx().next_ty_vars(desired.len()));
             return;
         }
 
@@ -4270,8 +4361,8 @@ fn adjust_type_parameters(
                             qualifier,
                             required_len,
                             provided_len).as_slice());
-            let provided = substs.types.get_mut_vec(space);
-            *provided = Vec::from_elem(desired.len(), ty::mk_err());
+            substs.types.replace(space,
+                                 Vec::from_elem(desired.len(), ty::mk_err()));
             return;
         }
 
@@ -4287,7 +4378,7 @@ fn adjust_type_parameters(
             let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
             substs.types.push(space, default);
         }
-        assert_eq!(substs.types.get_vec(space).len(), desired.len());
+        assert_eq!(substs.types.len(space), desired.len());
 
         debug!("Final substs: {}", substs.repr(fcx.tcx()));
     }
@@ -4299,20 +4390,22 @@ fn adjust_region_parameters(
         defs: &VecPerParamSpace<ty::RegionParameterDef>,
         substs: &mut Substs)
     {
-        let provided = substs.mut_regions().get_mut_vec(space);
-        let desired = defs.get_vec(space);
+        let provided_len = substs.mut_regions().len(space);
+        let desired = defs.get_slice(space);
 
         // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
-        assert!(provided.len() <= desired.len());
+        assert!(provided_len <= desired.len());
 
         // If nothing was provided, just use inference variables.
-        if provided.len() == 0 {
-            *provided = fcx.infcx().region_vars_for_defs(span, desired);
+        if provided_len == 0 {
+            substs.mut_regions().replace(
+                space,
+                fcx.infcx().region_vars_for_defs(span, desired));
             return;
         }
 
         // If just the right number were provided, everybody is happy.
-        if provided.len() == desired.len() {
+        if provided_len == desired.len() {
             return;
         }
 
@@ -4325,9 +4418,11 @@ fn adjust_region_parameters(
                          expected {} parameter(s) \
                          but found {} parameter(s)",
                 desired.len(),
-                provided.len()).as_slice());
+                provided_len).as_slice());
 
-        *provided = fcx.infcx().region_vars_for_defs(span, desired);
+        substs.mut_regions().replace(
+            space,
+            fcx.infcx().region_vars_for_defs(span, desired));
     }
 }
 
@@ -4427,7 +4522,7 @@ pub fn check_bounds_are_used(ccx: &CrateCtxt,
                              tps: &OwnedSlice<ast::TyParam>,
                              ty: ty::t) {
     debug!("check_bounds_are_used(n_tps={}, ty={})",
-           tps.len(), ppaux::ty_to_str(ccx.tcx, ty));
+           tps.len(), ppaux::ty_to_string(ccx.tcx, ty));
 
     // make a vector of booleans initially false, set to true when used
     if tps.len() == 0u { return; }
@@ -4745,7 +4840,7 @@ fn param(ccx: &CrateCtxt, n: uint) -> ty::t {
                            fty,
                            || {
                 format!("intrinsic has wrong type: expected `{}`",
-                        ppaux::ty_to_str(ccx.tcx, fty))
+                        ppaux::ty_to_string(ccx.tcx, fty))
             });
     }
 }
index 07fb43d0d34dfdb824b55b89e123f6ee9b4769c3..924934e4bcdc5e34eac00cc6af2f3b450e597988 100644 (file)
@@ -133,7 +133,7 @@ fn get_i(x: &'a Bar) -> &'a int {
 use middle::typeck::MethodCall;
 use middle::pat_util;
 use util::nodemap::NodeMap;
-use util::ppaux::{ty_to_str, region_to_str, Repr};
+use util::ppaux::{ty_to_string, region_to_string, Repr};
 
 use syntax::ast;
 use syntax::codemap::Span;
@@ -876,7 +876,7 @@ fn constrain_autoderefs(rcx: &mut Rcx,
     let r_deref_expr = ty::ReScope(deref_expr.id);
     for i in range(0u, derefs) {
         debug!("constrain_autoderefs(deref_expr=?, derefd_ty={}, derefs={:?}/{:?}",
-               rcx.fcx.infcx().ty_to_str(derefd_ty),
+               rcx.fcx.infcx().ty_to_string(derefd_ty),
                i, derefs);
 
         let method_call = MethodCall::autoderef(deref_expr.id, i);
@@ -948,7 +948,7 @@ fn constrain_index(rcx: &mut Rcx,
      */
 
     debug!("constrain_index(index_expr=?, indexed_ty={}",
-           rcx.fcx.infcx().ty_to_str(indexed_ty));
+           rcx.fcx.infcx().ty_to_string(indexed_ty));
 
     let r_index_expr = ty::ReScope(index_expr.id);
     match ty::get(indexed_ty).sty {
@@ -984,7 +984,7 @@ fn constrain_regions_in_type_of_node(
                            |method_call| rcx.resolve_method_type(method_call));
     debug!("constrain_regions_in_type_of_node(\
             ty={}, ty0={}, id={}, minimum_lifetime={:?})",
-           ty_to_str(tcx, ty), ty_to_str(tcx, ty0),
+           ty_to_string(tcx, ty), ty_to_string(tcx, ty0),
            id, minimum_lifetime);
     constrain_regions_in_type(rcx, minimum_lifetime, origin, ty);
 }
@@ -1011,8 +1011,8 @@ fn constrain_regions_in_type(
     let tcx = rcx.fcx.ccx.tcx;
 
     debug!("constrain_regions_in_type(minimum_lifetime={}, ty={})",
-           region_to_str(tcx, "", false, minimum_lifetime),
-           ty_to_str(tcx, ty));
+           region_to_string(tcx, "", false, minimum_lifetime),
+           ty_to_string(tcx, ty));
 
     relate_nested_regions(tcx, Some(minimum_lifetime), ty, |r_sub, r_sup| {
         debug!("relate_nested_regions(r_sub={}, r_sup={})",
@@ -1190,7 +1190,7 @@ fn link_region_from_node_type(rcx: &Rcx,
     let rptr_ty = rcx.resolve_node_type(id);
     if !ty::type_is_bot(rptr_ty) && !ty::type_is_error(rptr_ty) {
         let tcx = rcx.fcx.ccx.tcx;
-        debug!("rptr_ty={}", ty_to_str(tcx, rptr_ty));
+        debug!("rptr_ty={}", ty_to_string(tcx, rptr_ty));
         let r = ty::ty_region(tcx, span, rptr_ty);
         link_region(rcx, span, r, ty::BorrowKind::from_mutbl(mutbl),
                     cmt_borrowed);
index 146b42a00ffafe191df5e4aa002c8c694f9481ba..53e26f8696f61fe9e2f964bef5d03e41fccb2e25 100644 (file)
@@ -30,7 +30,7 @@ pub fn replace_late_bound_regions_in_fn_sig(
     let mut map = HashMap::new();
     let fn_sig = {
         let mut f = ty_fold::RegionFolder::regions(tcx, |r| {
-            debug!("region r={}", r.to_str());
+            debug!("region r={}", r.to_string());
             match r {
                 ty::ReLateBound(s, br) if s == fn_sig.binder_id => {
                     *map.find_or_insert_with(br, |_| mapf(br))
@@ -153,7 +153,7 @@ pub fn relate_free_regions(tcx: &ty::ctxt, fn_sig: &ty::FnSig) {
     }
 
     for &t in all_tys.iter() {
-        debug!("relate_free_regions(t={})", ppaux::ty_to_str(tcx, t));
+        debug!("relate_free_regions(t={})", ppaux::ty_to_string(tcx, t));
         relate_nested_regions(tcx, None, t, |a, b| {
             match (&a, &b) {
                 (&ty::ReFree(free_a), &ty::ReFree(free_b)) => {
index bda47d99ed7146d0ec7b12ab9dd292a8d19df9ae..d2a1ef786bd29f209ed1bba40cfa5dd3e5539cab 100644 (file)
@@ -16,7 +16,7 @@
 use middle::typeck::check::{FnCtxt, impl_self_ty};
 use middle::typeck::check::{structurally_resolved_type};
 use middle::typeck::check::writeback;
-use middle::typeck::infer::fixup_err_to_str;
+use middle::typeck::infer::fixup_err_to_string;
 use middle::typeck::infer::{resolve_and_force_all_but_regions, resolve_type};
 use middle::typeck::infer;
 use middle::typeck::{vtable_origin, vtable_res, vtable_param_res};
@@ -35,7 +35,7 @@
 use syntax::ast;
 use syntax::ast_util;
 use syntax::codemap::Span;
-use syntax::print::pprust::expr_to_str;
+use syntax::print::pprust::expr_to_string;
 use syntax::visit;
 use syntax::visit::Visitor;
 
@@ -154,8 +154,8 @@ fn lookup_vtables_for_param(vcx: &VtableContext,
                 vcx.tcx().sess.span_fatal(span,
                     format!("failed to find an implementation of \
                           trait {} for {}",
-                         vcx.infcx.trait_ref_to_str(&*trait_ref),
-                         vcx.infcx.ty_to_str(ty)).as_slice());
+                         vcx.infcx.trait_ref_to_string(&*trait_ref),
+                         vcx.infcx.ty_to_string(ty)).as_slice());
             }
         }
         true
@@ -205,8 +205,8 @@ fn relate_trait_refs(vcx: &VtableContext,
                 let tcx = vcx.tcx();
                 tcx.sess.span_err(span,
                     format!("expected {}, but found {} ({})",
-                            ppaux::trait_ref_to_str(tcx, &r_exp_trait_ref),
-                            ppaux::trait_ref_to_str(tcx, &r_act_trait_ref),
+                            ppaux::trait_ref_to_string(tcx, &r_exp_trait_ref),
+                            ppaux::trait_ref_to_string(tcx, &r_act_trait_ref),
                             ty::type_err_to_str(tcx, err)).as_slice());
             }
         }
@@ -385,8 +385,8 @@ fn search_for_vtable(vcx: &VtableContext,
 
         debug!("(checking vtable) num 2 relating trait \
                 ty {} to of_trait_ref {}",
-               vcx.infcx.trait_ref_to_str(&*trait_ref),
-               vcx.infcx.trait_ref_to_str(&*of_trait_ref));
+               vcx.infcx.trait_ref_to_string(&*trait_ref),
+               vcx.infcx.trait_ref_to_string(&*of_trait_ref));
 
         relate_trait_refs(vcx, span, of_trait_ref, trait_ref.clone());
 
@@ -488,7 +488,7 @@ fn fixup_ty(vcx: &VtableContext,
             tcx.sess.span_fatal(span,
                 format!("cannot determine a type for this bounded type \
                          parameter: {}",
-                        fixup_err_to_str(e)).as_slice())
+                        fixup_err_to_string(e)).as_slice())
         }
         Err(_) => {
             None
@@ -527,7 +527,7 @@ fn mutability_allowed(a_mutbl: ast::Mutability,
     }
 
     debug!("vtable: early_resolve_expr() ex with id {:?} (early: {}): {}",
-           ex.id, is_early, expr_to_str(ex));
+           ex.id, is_early, expr_to_string(ex));
     let _indent = indenter();
 
     let cx = fcx.ccx;
@@ -626,7 +626,7 @@ fn mutability_allowed(a_mutbl: ast::Mutability,
                           ex.span,
                           format!("can only cast an boxed pointer \
                                    to a boxed object, not a {}",
-                               ty::ty_sort_str(fcx.tcx(), src_ty)).as_slice());
+                               ty::ty_sort_string(fcx.tcx(), src_ty)).as_slice());
                   }
                   _ => {}
               }
@@ -639,7 +639,7 @@ fn mutability_allowed(a_mutbl: ast::Mutability,
                           ex.span,
                           format!("can only cast an &-pointer \
                                    to an &-object, not a {}",
-                                  ty::ty_sort_str(fcx.tcx(), src_ty)).as_slice());
+                                  ty::ty_sort_string(fcx.tcx(), src_ty)).as_slice());
                   }
                   _ => {}
               }
@@ -657,7 +657,7 @@ fn mutability_allowed(a_mutbl: ast::Mutability,
             let did = def.def_id();
             let item_ty = ty::lookup_item_type(cx.tcx, did);
             debug!("early resolve expr: def {:?} {:?}, {:?}, {}", ex.id, did, def,
-                   fcx.infcx().ty_to_str(item_ty.ty));
+                   fcx.infcx().ty_to_string(item_ty.ty));
             debug!("early_resolve_expr: looking up vtables for type params {}",
                    item_ty.generics.types.repr(fcx.tcx()));
             let vcx = fcx.vtable_context();
index eb43144571e2abc9173e58c0aa05507250fd4f4e..59b65fdbec790231b0b999bf282a642c21834278 100644 (file)
@@ -31,7 +31,7 @@
 
 use syntax::ast;
 use syntax::codemap::Span;
-use syntax::print::pprust::pat_to_str;
+use syntax::print::pprust::pat_to_string;
 use syntax::visit;
 use syntax::visit::Visitor;
 
@@ -159,7 +159,7 @@ fn visit_pat(&mut self, p: &ast::Pat, _: ()) {
         self.visit_node_id(ResolvingPattern(p.span), p.id);
 
         debug!("Type for pattern binding {} (id {}) resolved to {}",
-               pat_to_str(p),
+               pat_to_string(p),
                p.id,
                ty::node_id_to_type(self.tcx(), p.id).repr(self.tcx()));
 
@@ -403,7 +403,7 @@ fn report_error(&self, e: infer::fixup_err) {
                         span,
                         format!("cannot determine a type for \
                                  this expression: {}",
-                                infer::fixup_err_to_str(e)).as_slice())
+                                infer::fixup_err_to_string(e)).as_slice())
                 }
 
                 ResolvingLocal(span) => {
@@ -411,7 +411,7 @@ fn report_error(&self, e: infer::fixup_err) {
                         span,
                         format!("cannot determine a type for \
                                  this local variable: {}",
-                                infer::fixup_err_to_str(e)).as_slice())
+                                infer::fixup_err_to_string(e)).as_slice())
                 }
 
                 ResolvingPattern(span) => {
@@ -419,7 +419,7 @@ fn report_error(&self, e: infer::fixup_err) {
                         span,
                         format!("cannot determine a type for \
                                  this pattern binding: {}",
-                                infer::fixup_err_to_str(e)).as_slice())
+                                infer::fixup_err_to_string(e)).as_slice())
                 }
 
                 ResolvingUpvar(upvar_id) => {
@@ -430,8 +430,8 @@ fn report_error(&self, e: infer::fixup_err) {
                                  captured variable `{}`: {}",
                                 ty::local_var_name_str(
                                     self.tcx,
-                                    upvar_id.var_id).get().to_str(),
-                                infer::fixup_err_to_str(e)).as_slice());
+                                    upvar_id.var_id).get().to_string(),
+                                infer::fixup_err_to_string(e)).as_slice());
                 }
 
                 ResolvingImplRes(span) => {
index 32e34d1320eb55b809b017c5fc3b5eeb06d653bc..b9bf8e37dead8c926faaa328412dd77a5e90edbc 100644 (file)
@@ -735,12 +735,12 @@ pub fn make_substs_for_receiver_types(tcx: &ty::ctxt,
      */
 
     let meth_tps: Vec<ty::t> =
-        method.generics.types.get_vec(subst::FnSpace)
+        method.generics.types.get_slice(subst::FnSpace)
               .iter()
               .map(|def| ty::mk_param_from_def(tcx, def))
               .collect();
     let meth_regions: Vec<ty::Region> =
-        method.generics.regions.get_vec(subst::FnSpace)
+        method.generics.regions.get_slice(subst::FnSpace)
               .iter()
               .map(|def| ty::ReEarlyBound(def.def_id.node, def.space,
                                           def.index, def.name))
@@ -767,10 +767,12 @@ fn subst_receiver_types_in_method_ty(tcx: &ty::ctxt,
     // replace the type parameters declared on the trait with those
     // from the impl
     for &space in [subst::TypeSpace, subst::SelfSpace].iter() {
-        *method_generics.types.get_mut_vec(space) =
-            impl_poly_type.generics.types.get_vec(space).clone();
-        *method_generics.regions.get_mut_vec(space) =
-            impl_poly_type.generics.regions.get_vec(space).clone();
+        method_generics.types.replace(
+            space,
+            Vec::from_slice(impl_poly_type.generics.types.get_slice(space)));
+        method_generics.regions.replace(
+            space,
+            Vec::from_slice(impl_poly_type.generics.regions.get_slice(space)));
     }
 
     debug!("subst_receiver_types_in_method_ty: method_generics={}",
index bf88ec5c438f28a62e3d52f61327a2b1dbb2b6af..b6cdeb92aa3a3eed8ab15b28d7c76a96adf1195e 100644 (file)
@@ -63,7 +63,7 @@
 use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token::special_idents;
 use syntax::parse::token;
-use syntax::print::pprust::{path_to_str};
+use syntax::print::pprust::{path_to_string};
 use syntax::visit;
 
 struct CollectItemTypesVisitor<'a> {
@@ -665,7 +665,7 @@ pub fn instantiate_trait_ref(ccx: &CrateCtxt,
             ccx.tcx.sess.span_fatal(
                 ast_trait_ref.path.span,
                 format!("`{}` is not a trait",
-                        path_to_str(&ast_trait_ref.path)).as_slice());
+                        path_to_string(&ast_trait_ref.path)).as_slice());
         }
     }
 }
@@ -692,9 +692,9 @@ pub fn trait_def_of_item(ccx: &CrateCtxt, it: &ast::Item) -> Rc<ty::TraitDef> {
         _ => {}
     }
 
-    let (generics, sized, supertraits) = match it.node {
-        ast::ItemTrait(ref generics, sized, ref supertraits, _) => {
-            (generics, sized, supertraits)
+    let (generics, unbound, supertraits) = match it.node {
+        ast::ItemTrait(ref generics, ref unbound, ref supertraits, _) => {
+            (generics, unbound, supertraits)
         }
         ref s => {
             tcx.sess.span_bug(
@@ -711,7 +711,7 @@ pub fn trait_def_of_item(ccx: &CrateCtxt, it: &ast::Item) -> Rc<ty::TraitDef> {
                                             generics);
 
     let builtin_bounds =
-        ensure_supertraits(ccx, it.id, it.span, supertraits, sized);
+        ensure_supertraits(ccx, it.id, it.span, supertraits, unbound);
 
     let substs = mk_item_substs(ccx, &ty_generics);
     let trait_def = Rc::new(ty::TraitDef {
@@ -759,7 +759,7 @@ fn ensure_supertraits(ccx: &CrateCtxt,
                           id: ast::NodeId,
                           sp: codemap::Span,
                           ast_trait_refs: &Vec<ast::TraitRef>,
-                          sized: ast::Sized)
+                          unbound: &Option<ast::TyParamBound>)
                           -> ty::BuiltinBounds
     {
         let tcx = ccx.tcx;
@@ -798,15 +798,7 @@ fn ensure_supertraits(ccx: &CrateCtxt,
             }
         }
 
-        if sized == ast::StaticSize {
-            match tcx.lang_items.require(SizedTraitLangItem) {
-                Ok(def_id) => {
-                    ty::try_add_builtin_trait(tcx, def_id, &mut bounds);
-                }
-                Err(s) => tcx.sess.err(s.as_slice()),
-            };
-        }
-
+        add_unsized_bound(ccx, unbound, &mut bounds, "trait", sp);
         tcx.supertraits.borrow_mut().insert(local_def(id),
                                             Rc::new(ty_trait_refs));
         bounds
@@ -844,7 +836,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::Item)
             debug!("type of {} (id {}) is {}",
                     token::get_ident(it.ident),
                     it.id,
-                    ppaux::ty_to_str(tcx, pty.ty));
+                    ppaux::ty_to_string(tcx, pty.ty));
 
             ccx.tcx.tcache.borrow_mut().insert(local_def(it.id), pty.clone());
             return pty;
@@ -974,6 +966,43 @@ fn ty_generics_for_fn_or_method(ccx: &CrateCtxt,
                 &generics.ty_params, base_generics)
 }
 
+// Add the Sized bound, unless the type parameter is marked as `Sized?`.
+fn add_unsized_bound(ccx: &CrateCtxt,
+                     unbound: &Option<ast::TyParamBound>,
+                     bounds: &mut ty::BuiltinBounds,
+                     desc: &str,
+                     span: Span) {
+    let kind_id = ccx.tcx.lang_items.require(SizedTraitLangItem);
+    match unbound {
+        &Some(TraitTyParamBound(ref tpb)) => {
+            // #FIXME(8559) currently requires the unbound to be built-in.
+            let trait_def_id = ty::trait_ref_to_def_id(ccx.tcx, tpb);
+            match kind_id {
+                Ok(kind_id) if trait_def_id != kind_id => {
+                    ccx.tcx.sess.span_warn(span,
+                                           format!("default bound relaxed \
+                                                    for a {}, but this does \
+                                                    nothing because the given \
+                                                    bound is not a default. \
+                                                    Only `Sized?` is supported.",
+                                                   desc).as_slice());
+                    ty::try_add_builtin_trait(ccx.tcx,
+                                              kind_id,
+                                              bounds);
+                }
+                _ => {}
+            }
+        }
+        _ if kind_id.is_ok() => {
+            ty::try_add_builtin_trait(ccx.tcx,
+                                      kind_id.unwrap(),
+                                      bounds);
+        }
+        // No lang item for Sized, so we can't add it as a bound.
+        _ => {}
+    }
+}
+
 fn ty_generics(ccx: &CrateCtxt,
                space: subst::ParamSpace,
                lifetimes: &Vec<ast::Lifetime>,
@@ -1016,7 +1045,7 @@ fn get_or_create_type_parameter_def(ccx: &CrateCtxt,
         let bounds = Rc::new(compute_bounds(ccx,
                                             param_ty,
                                             &param.bounds,
-                                            param.sized,
+                                            &param.unbound,
                                             param.ident,
                                             param.span));
         let default = param.default.map(|path| {
@@ -1056,7 +1085,7 @@ fn compute_bounds(
         ccx: &CrateCtxt,
         param_ty: ty::ParamTy,
         ast_bounds: &OwnedSlice<ast::TyParamBound>,
-        sized: ast::Sized,
+        unbound: &Option<ast::TyParamBound>,
         ident: ast::Ident,
         span: Span) -> ty::ParamBounds
     {
@@ -1113,15 +1142,11 @@ fn compute_bounds(
             }
         }
 
-        if sized == ast::StaticSize {
-            match ccx.tcx.lang_items.require(SizedTraitLangItem) {
-                Ok(def_id) => { ty::try_add_builtin_trait(ccx.tcx,
-                                                          def_id,
-                                                          &mut param_bounds.builtin_bounds); },
-                // Fixme(13367) after `type` makes it into the snapshot, we can check this properly
-                Err(_s) => {}, //ccx.tcx.sess.err(s),
-            }
-        }
+        add_unsized_bound(ccx,
+                          unbound,
+                          &mut param_bounds.builtin_bounds,
+                          "type parameter",
+                          span);
 
         check_bounds_compatible(ccx.tcx, &param_bounds, ident, span);
 
@@ -1144,7 +1169,7 @@ fn check_bounds_compatible(tcx: &ty::ctxt,
                         format!("incompatible bounds on type parameter {}, \
                                  bound {} does not allow unsized type",
                         token::get_ident(ident),
-                        ppaux::trait_ref_to_str(tcx,
+                        ppaux::trait_ref_to_string(tcx,
                                                 &*trait_ref)).as_slice());
                 }
                 true
index 2984ea086efc59064d00919ddf70c15ccf5ffa64..1e33b1d5d0ebd5368044a1a6c51a5c273a95ed64 100644 (file)
@@ -115,32 +115,30 @@ fn substs(&self,
         let mut substs = subst::Substs::empty();
 
         for &space in subst::ParamSpace::all().iter() {
-            let a_tps = a_subst.types.get_vec(space);
-            let b_tps = b_subst.types.get_vec(space);
-            let tps = if_ok!(self.tps(space,
-                                      a_tps.as_slice(),
-                                      b_tps.as_slice()));
-
-            let a_regions = a_subst.regions().get_vec(space);
-            let b_regions = b_subst.regions().get_vec(space);
-            let r_variances = variances.regions.get_vec(space);
+            let a_tps = a_subst.types.get_slice(space);
+            let b_tps = b_subst.types.get_slice(space);
+            let tps = if_ok!(self.tps(space, a_tps, b_tps));
+
+            let a_regions = a_subst.regions().get_slice(space);
+            let b_regions = b_subst.regions().get_slice(space);
+            let r_variances = variances.regions.get_slice(space);
             let regions = if_ok!(relate_region_params(self,
                                                       item_def_id,
                                                       r_variances,
                                                       a_regions,
                                                       b_regions));
 
-            *substs.types.get_mut_vec(space) = tps;
-            *substs.mut_regions().get_mut_vec(space) = regions;
+            substs.types.replace(space, tps);
+            substs.mut_regions().replace(space, regions);
         }
 
         return Ok(substs);
 
         fn relate_region_params<C:Combine>(this: &C,
                                            item_def_id: ast::DefId,
-                                           variances: &Vec<ty::Variance>,
-                                           a_rs: &Vec<ty::Region>,
-                                           b_rs: &Vec<ty::Region>)
+                                           variances: &[ty::Variance],
+                                           a_rs: &[ty::Region],
+                                           b_rs: &[ty::Region])
                                            -> cres<Vec<ty::Region>>
         {
             let tcx = this.infcx().tcx;
@@ -160,9 +158,9 @@ fn relate_region_params<C:Combine>(this: &C,
             assert_eq!(num_region_params, b_rs.len());
             let mut rs = vec!();
             for i in range(0, num_region_params) {
-                let a_r = *a_rs.get(i);
-                let b_r = *b_rs.get(i);
-                let variance = *variances.get(i);
+                let a_r = a_rs[i];
+                let b_r = b_rs[i];
+                let variance = variances[i];
                 let r = match variance {
                     ty::Invariant => {
                         eq_regions(this, a_r, b_r)
index a5bdea72da2302f1e9906fde9326260b32413c88..cdd51c4fa71265d68bd9aa27c3bd354fd1743345 100644 (file)
@@ -90,7 +90,7 @@
 use syntax::parse::token;
 use syntax::print::pprust;
 use util::ppaux::UserString;
-use util::ppaux::bound_region_to_str;
+use util::ppaux::bound_region_to_string;
 use util::ppaux::note_and_explain_region;
 
 pub trait ErrorReporting {
@@ -442,7 +442,7 @@ fn report_concrete_failure(&self,
                             ty::local_var_name_str(self.tcx,
                                                    upvar_id.var_id)
                                 .get()
-                                .to_str()).as_slice());
+                                .to_string()).as_slice());
                 note_and_explain_region(
                     self.tcx,
                     "...the borrowed pointer is valid for ",
@@ -454,7 +454,7 @@ fn report_concrete_failure(&self,
                             ty::local_var_name_str(self.tcx,
                                                    upvar_id.var_id)
                                 .get()
-                                .to_str()).as_slice(),
+                                .to_string()).as_slice(),
                     sup,
                     "");
             }
@@ -500,7 +500,7 @@ fn report_concrete_failure(&self,
                             outlive the enclosing closure",
                             ty::local_var_name_str(self.tcx,
                                                    id).get()
-                                                      .to_str()).as_slice());
+                                                      .to_string()).as_slice());
                 note_and_explain_region(
                     self.tcx,
                     "captured variable is valid for ",
@@ -676,10 +676,10 @@ fn report_processed_errors(&self,
                                var_origins: &[RegionVariableOrigin],
                                trace_origins: &[(TypeTrace, ty::type_err)],
                                same_regions: &[SameRegions]) {
-        self.give_suggestion(same_regions);
         for vo in var_origins.iter() {
             self.report_inference_failure(vo.clone());
         }
+        self.give_suggestion(same_regions);
         for &(ref trace, terr) in trace_origins.iter() {
             self.report_type_error(trace.clone(), &terr);
         }
@@ -895,9 +895,9 @@ fn rebuild_ty_params(&self,
                 ident: ty_param.ident,
                 id: ty_param.id,
                 bounds: bounds,
+                unbound: ty_param.unbound.clone(),
                 default: ty_param.default,
                 span: ty_param.span,
-                sized: ty_param.sized,
             }
         })
     }
@@ -1046,7 +1046,7 @@ fn rebuild_arg_ty_or_output(&self,
                                 .sess
                                 .fatal(format!(
                                         "unbound path {}",
-                                        pprust::path_to_str(path)).as_slice())
+                                        pprust::path_to_string(path)).as_slice())
                         }
                         Some(&d) => d
                     };
@@ -1231,7 +1231,7 @@ fn give_expl_lifetime_param(&self,
                                 opt_explicit_self: Option<ast::ExplicitSelf_>,
                                 generics: &ast::Generics,
                                 span: codemap::Span) {
-        let suggested_fn = pprust::fun_to_str(decl, fn_style, ident,
+        let suggested_fn = pprust::fun_to_string(decl, fn_style, ident,
                                               opt_explicit_self, generics);
         let msg = format!("consider using an explicit lifetime \
                            parameter as shown: {}", suggested_fn);
@@ -1249,11 +1249,11 @@ fn report_inference_failure(&self,
             infer::Coercion(_) => " for automatic coercion".to_string(),
             infer::LateBoundRegion(_, br) => {
                 format!(" for {}in function call",
-                        bound_region_to_str(self.tcx, "lifetime parameter ", true, br))
+                        bound_region_to_string(self.tcx, "lifetime parameter ", true, br))
             }
             infer::BoundRegionInFnType(_, br) => {
                 format!(" for {}in function type",
-                        bound_region_to_str(self.tcx, "lifetime parameter ", true, br))
+                        bound_region_to_string(self.tcx, "lifetime parameter ", true, br))
             }
             infer::EarlyBoundRegion(_, name) => {
                 format!(" for lifetime parameter `{}",
@@ -1265,7 +1265,7 @@ fn report_inference_failure(&self,
             }
             infer::UpvarRegion(ref upvar_id, _) => {
                 format!(" for capture of `{}` by closure",
-                        ty::local_var_name_str(self.tcx, upvar_id.var_id).get().to_str())
+                        ty::local_var_name_str(self.tcx, upvar_id.var_id).get().to_string())
             }
         };
 
@@ -1334,7 +1334,7 @@ fn note_region_origin(&self, origin: SubregionOrigin) {
                         "...so that closure can access `{}`",
                         ty::local_var_name_str(self.tcx, upvar_id.var_id)
                             .get()
-                            .to_str()).as_slice())
+                            .to_string()).as_slice())
             }
             infer::InfStackClosure(span) => {
                 self.tcx.sess.span_note(
@@ -1359,7 +1359,7 @@ fn note_region_origin(&self, origin: SubregionOrigin) {
                             does not outlive the enclosing closure",
                             ty::local_var_name_str(
                                 self.tcx,
-                                id).get().to_str()).as_slice());
+                                id).get().to_string()).as_slice());
             }
             infer::IndexSlice(span) => {
                 self.tcx.sess.span_note(
@@ -1508,7 +1508,7 @@ fn give_lifetime(&self) -> ast::Lifetime {
         let mut lifetime;
         loop {
             let mut s = String::from_str("'");
-            s.push_str(num_to_str(self.counter.get()).as_slice());
+            s.push_str(num_to_string(self.counter.get()).as_slice());
             if !self.taken.contains(&s) {
                 lifetime = name_to_dummy_lifetime(
                                     token::str_to_ident(s.as_slice()).name);
@@ -1521,7 +1521,7 @@ fn give_lifetime(&self) -> ast::Lifetime {
         return lifetime;
 
         // 0 .. 25 generates a .. z, 26 .. 51 generates aa .. zz, and so on
-        fn num_to_str(counter: uint) -> String {
+        fn num_to_string(counter: uint) -> String {
             let mut s = String::new();
             let (n, r) = (counter/26 + 1, counter % 26);
             let letter: char = from_u32((r+97) as u32).unwrap();
index d2c27330a94ade27e266e64a360615ac46b8d28a..b6628c22ae60ae2961b34a5c911e34a21f773d3e 100644 (file)
@@ -26,7 +26,7 @@
 use syntax::ast::{Onceness, FnStyle};
 use std::collections::HashMap;
 use util::common::{indenter};
-use util::ppaux::mt_to_str;
+use util::ppaux::mt_to_string;
 use util::ppaux::Repr;
 
 pub struct Glb<'f>(pub CombineFields<'f>);  // "greatest lower bound" (common subtype)
@@ -50,8 +50,8 @@ fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres<ty::mt> {
 
         debug!("{}.mts({}, {})",
                self.tag(),
-               mt_to_str(tcx, a),
-               mt_to_str(tcx, b));
+               mt_to_string(tcx, a),
+               mt_to_string(tcx, b));
 
         match (a.mutbl, b.mutbl) {
           // If one side or both is mut, then the GLB must use
index 1b3d96e474e4b5f051aae01b892f3eb4c9a959fd..708eb498f8421ea5fb059a08ccf5b109b9a2459d 100644 (file)
@@ -39,7 +39,7 @@
 use middle::typeck::infer::combine::*;
 use middle::typeck::infer::glb::Glb;
 use middle::typeck::infer::lub::Lub;
-use middle::typeck::infer::unify::{Root, UnifyKey};
+use middle::typeck::infer::unify::*;
 use middle::typeck::infer::sub::Sub;
 use util::ppaux::Repr;
 
@@ -436,8 +436,7 @@ pub enum LatticeVarResult<K,T> {
  * - If the variables do not both have an upper bound, we will unify
  *   the variables and return the unified variable, in which case the
  *   result is a variable.  This is indicated with a `VarResult`
- *   return.
- */
+ *   return. */
 pub fn lattice_vars<L:LatticeDir+Combine,
                     T:LatticeValue,
                     K:UnifyKey<Bounds<T>>>(
index 7ccffdfeb062fc1ffa4ba2d735784ba41798c354..6a50038afe77fc20ea89f51d6648952e9ea1972c 100644 (file)
@@ -25,7 +25,7 @@
 use syntax::ast::{NormalFn, UnsafeFn};
 use syntax::ast::{Onceness, FnStyle};
 use syntax::ast::{MutMutable, MutImmutable};
-use util::ppaux::mt_to_str;
+use util::ppaux::mt_to_string;
 use util::ppaux::Repr;
 
 pub struct Lub<'f>(pub CombineFields<'f>);  // least-upper-bound: common supertype
@@ -49,8 +49,8 @@ fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres<ty::mt> {
 
         debug!("{}.mts({}, {})",
                self.tag(),
-               mt_to_str(tcx, a),
-               mt_to_str(tcx, b));
+               mt_to_string(tcx, a),
+               mt_to_string(tcx, b));
 
         if a.mutbl != b.mutbl {
             return Err(ty::terr_mutability)
index bc02297b5b1f3cd27d89a55b4fb4890ab96cf9c7..16e758df9dbbd2ad7c3354f7d716bace80d93f5b 100644 (file)
@@ -44,7 +44,7 @@
 use syntax::codemap;
 use syntax::codemap::Span;
 use util::common::indent;
-use util::ppaux::{bound_region_to_str, ty_to_str, trait_ref_to_str, Repr};
+use util::ppaux::{bound_region_to_string, ty_to_string, trait_ref_to_string, Repr};
 
 pub mod doc;
 pub mod macros;
@@ -245,7 +245,7 @@ pub enum fixup_err {
     region_var_bound_by_region_var(RegionVid, RegionVid)
 }
 
-pub fn fixup_err_to_str(f: fixup_err) -> String {
+pub fn fixup_err_to_string(f: fixup_err) -> String {
     match f {
       unresolved_int_ty(_) => {
           "cannot determine the type of this integer; add a suffix to \
@@ -624,7 +624,7 @@ pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region {
 
     pub fn region_vars_for_defs(&self,
                                 span: Span,
-                                defs: &Vec<ty::RegionParameterDef>)
+                                defs: &[ty::RegionParameterDef])
                                 -> Vec<ty::Region> {
         defs.iter()
             .map(|d| self.next_region_var(EarlyBoundRegion(span, d.name)))
@@ -647,7 +647,7 @@ pub fn fresh_substs_for_type(&self,
         assert!(generics.regions.len(subst::FnSpace) == 0);
 
         let type_parameter_count = generics.types.len(subst::TypeSpace);
-        let region_param_defs = generics.regions.get_vec(subst::TypeSpace);
+        let region_param_defs = generics.regions.get_slice(subst::TypeSpace);
         let regions = self.region_vars_for_defs(span, region_param_defs);
         let type_parameters = self.next_ty_vars(type_parameter_count);
         subst::Substs::new_type(type_parameters, regions)
@@ -662,19 +662,19 @@ pub fn resolve_regions_and_report_errors(&self) {
         self.report_region_errors(&errors); // see error_reporting.rs
     }
 
-    pub fn ty_to_str(&self, t: ty::t) -> String {
-        ty_to_str(self.tcx,
+    pub fn ty_to_string(&self, t: ty::t) -> String {
+        ty_to_string(self.tcx,
                   self.resolve_type_vars_if_possible(t))
     }
 
-    pub fn tys_to_str(&self, ts: &[ty::t]) -> String {
-        let tstrs: Vec<String> = ts.iter().map(|t| self.ty_to_str(*t)).collect();
+    pub fn tys_to_string(&self, ts: &[ty::t]) -> String {
+        let tstrs: Vec<String> = ts.iter().map(|t| self.ty_to_string(*t)).collect();
         format!("({})", tstrs.connect(", "))
     }
 
-    pub fn trait_ref_to_str(&self, t: &ty::TraitRef) -> String {
+    pub fn trait_ref_to_string(&self, t: &ty::TraitRef) -> String {
         let t = self.resolve_type_vars_in_trait_ref_if_possible(t);
-        trait_ref_to_str(self.tcx, &t)
+        trait_ref_to_string(self.tcx, &t)
     }
 
     pub fn resolve_type_vars_if_possible(&self, typ: ty::t) -> ty::t {
@@ -707,8 +707,8 @@ pub fn resolve_type_vars_in_trait_ref_if_possible(&self,
                 self.tcx.sess.bug(
                     format!("resolve_type_vars_if_possible() yielded {} \
                              when supplied with {}",
-                            self.ty_to_str(dummy0),
-                            self.ty_to_str(dummy1)).as_slice());
+                            self.ty_to_string(dummy0),
+                            self.ty_to_string(dummy1)).as_slice());
             }
         }
     }
@@ -761,7 +761,7 @@ pub fn type_error_message_str_with_expected(&self,
                 Some(e) => {
                     self.tcx.sess.span_err(sp,
                         format!("{}{}",
-                                mk_msg(Some(self.ty_to_str(e)), actual_ty),
+                                mk_msg(Some(self.ty_to_string(e)), actual_ty),
                                 error_str).as_slice());
                 }
             }
@@ -783,7 +783,7 @@ pub fn type_error_message(&self,
             return;
         }
 
-        self.type_error_message_str(sp, |_e, a| { mk_msg(a) }, self.ty_to_str(actual_ty), err);
+        self.type_error_message_str(sp, |_e, a| { mk_msg(a) }, self.ty_to_string(actual_ty), err);
     }
 
     pub fn report_mismatched_types(&self,
@@ -800,7 +800,7 @@ pub fn report_mismatched_types(&self,
                 // if I leave out : String, it infers &str and complains
                 |actual: String| {
                     format!("mismatched types: expected `{}` but found `{}`",
-                            self.ty_to_str(resolved_expected),
+                            self.ty_to_string(resolved_expected),
                             actual)
                 }
             }
@@ -819,7 +819,7 @@ pub fn replace_late_bound_regions_with_fresh_regions(&self,
                 let rvar = self.next_region_var(
                     BoundRegionInFnType(trace.origin.span(), br));
                 debug!("Bound region {} maps to {:?}",
-                       bound_region_to_str(self.tcx, "", false, br),
+                       bound_region_to_string(self.tcx, "", false, br),
                        rvar);
                 rvar
             });
index adfbe9de2d5bf8b72769c6784a879a16dd64b702..2ae95309d41d98a76e6c00b8f254ddffd415a08c 100644 (file)
@@ -56,7 +56,7 @@
 use middle::typeck::infer::{unresolved_ty};
 use syntax::codemap::Span;
 use util::common::indent;
-use util::ppaux::{Repr, ty_to_str};
+use util::ppaux::{Repr, ty_to_string};
 
 pub static resolve_nested_tvar: uint = 0b0000000001;
 pub static resolve_rvar: uint        = 0b0000000010;
@@ -121,7 +121,7 @@ pub fn resolve_type_chk(&mut self,
         self.err = None;
 
         debug!("Resolving {} (modes={:x})",
-               ty_to_str(self.infcx.tcx, typ),
+               ty_to_string(self.infcx.tcx, typ),
                self.modes);
 
         // n.b. This is a hokey mess because the current fold doesn't
@@ -133,8 +133,8 @@ pub fn resolve_type_chk(&mut self,
         match self.err {
           None => {
             debug!("Resolved to {} + {} (modes={:x})",
-                   ty_to_str(self.infcx.tcx, rty),
-                   ty_to_str(self.infcx.tcx, rty),
+                   ty_to_string(self.infcx.tcx, rty),
+                   ty_to_string(self.infcx.tcx, rty),
                    self.modes);
             return Ok(rty);
           }
index 856237c4bcaa4c3634468e23839267db6a4d74f3..44c147bfe7f62f962b75c813b4e608b4136d5deb 100644 (file)
@@ -22,7 +22,7 @@
 use middle::typeck::infer::then;
 use middle::typeck::infer::{TypeTrace, Subtype};
 use util::common::{indenter};
-use util::ppaux::{bound_region_to_str, Repr};
+use util::ppaux::{bound_region_to_string, Repr};
 
 use syntax::ast::{Onceness, FnStyle, MutImmutable, MutMutable};
 
@@ -176,7 +176,7 @@ fn fn_sigs(&self, a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig> {
             replace_late_bound_regions_in_fn_sig(self.get_ref().infcx.tcx, b, |br| {
                 let skol = self.get_ref().infcx.region_vars.new_skolemized(br);
                 debug!("Bound region {} skolemized to {:?}",
-                       bound_region_to_str(self.get_ref().infcx.tcx, "", false, br),
+                       bound_region_to_string(self.get_ref().infcx.tcx, "", false, br),
                        skol);
                 skol
             })
index 5ae469c41f2dfa39ed0f37b06b50454db956cf3c..e66dcd118c92892186cb85857d2e6a4b4ef801c7 100644 (file)
@@ -37,8 +37,7 @@
 use syntax::codemap::{Span, CodeMap, DUMMY_SP};
 use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note};
 use syntax::ast;
-use syntax::crateid::CrateId;
-use util::ppaux::{ty_to_str, UserString};
+use util::ppaux::{ty_to_string, UserString};
 
 struct Env<'a> {
     krate: ast::Crate,
@@ -116,11 +115,8 @@ fn test_env(_test_name: &str,
     let krate_config = Vec::new();
     let input = driver::StrInput(source_string.to_owned());
     let krate = driver::phase_1_parse_input(&sess, krate_config, &input);
-    let krate_id = CrateId { path: "test".to_owned(),
-                             name: "test".to_owned(),
-                             version: None };
     let (krate, ast_map) =
-        driver::phase_2_configure_and_expand(&sess, krate, &krate_id)
+        driver::phase_2_configure_and_expand(&sess, krate, "test")
             .expect("phase 2 aborted");
 
     // run just enough stuff to build a tcx:
@@ -229,16 +225,16 @@ pub fn is_subtype(&self, a: ty::t, b: ty::t) -> bool {
     pub fn assert_subtype(&self, a: ty::t, b: ty::t) {
         if !self.is_subtype(a, b) {
             fail!("{} is not a subtype of {}, but it should be",
-                  self.ty_to_str(a),
-                  self.ty_to_str(b));
+                  self.ty_to_string(a),
+                  self.ty_to_string(b));
         }
     }
 
     pub fn assert_not_subtype(&self, a: ty::t, b: ty::t) {
         if self.is_subtype(a, b) {
             fail!("{} is a subtype of {}, but it shouldn't be",
-                  self.ty_to_str(a),
-                  self.ty_to_str(b));
+                  self.ty_to_string(a),
+                  self.ty_to_string(b));
         }
     }
 
@@ -247,8 +243,8 @@ pub fn assert_eq(&self, a: ty::t, b: ty::t) {
         self.assert_subtype(b, a);
     }
 
-    pub fn ty_to_str(&self, a: ty::t) -> String {
-        ty_to_str(self.tcx, a)
+    pub fn ty_to_string(&self, a: ty::t) -> String {
+        ty_to_string(self.tcx, a)
     }
 
     pub fn t_fn(&self,
@@ -332,9 +328,9 @@ pub fn check_lub(&self, t1: ty::t, t2: ty::t, t_lub: ty::t) {
     /// Checks that `GLB(t1,t2) == t_glb`
     pub fn check_glb(&self, t1: ty::t, t2: ty::t, t_glb: ty::t) {
         debug!("check_glb(t1={}, t2={}, t_glb={})",
-               self.ty_to_str(t1),
-               self.ty_to_str(t2),
-               self.ty_to_str(t_glb));
+               self.ty_to_string(t1),
+               self.ty_to_string(t2),
+               self.ty_to_string(t_glb));
         match self.glb().tys(t1, t2) {
             Err(e) => {
                 fail!("unexpected error computing LUB: {:?}", e)
@@ -354,7 +350,7 @@ pub fn check_no_lub(&self, t1: ty::t, t2: ty::t) {
         match self.lub().tys(t1, t2) {
             Err(_) => {}
             Ok(t) => {
-                fail!("unexpected success computing LUB: {}", self.ty_to_str(t))
+                fail!("unexpected success computing LUB: {}", self.ty_to_string(t))
             }
         }
     }
@@ -364,7 +360,7 @@ pub fn check_no_glb(&self, t1: ty::t, t2: ty::t) {
         match self.glb().tys(t1, t2) {
             Err(_) => {}
             Ok(t) => {
-                fail!("unexpected success computing GLB: {}", self.ty_to_str(t))
+                fail!("unexpected success computing GLB: {}", self.ty_to_string(t))
             }
         }
     }
index 7b6935df42079a561fd0e8a12006937679511f71..ad6864ba487921680001aa59e6b180a3032207ac 100644 (file)
@@ -276,7 +276,7 @@ pub struct CrateCtxt<'a> {
 
 // Functions that write types into the node type table
 pub fn write_ty_to_tcx(tcx: &ty::ctxt, node_id: ast::NodeId, ty: ty::t) {
-    debug!("write_ty_to_tcx({}, {})", node_id, ppaux::ty_to_str(tcx, ty));
+    debug!("write_ty_to_tcx({}, {})", node_id, ppaux::ty_to_string(tcx, ty));
     assert!(!ty::type_needs_infer(ty));
     tcx.node_types.borrow_mut().insert(node_id as uint, ty);
 }
@@ -383,14 +383,14 @@ fn check_main_fn_ty(ccx: &CrateCtxt,
             require_same_types(tcx, None, false, main_span, main_t, se_ty,
                 || {
                     format!("main function expects type: `{}`",
-                            ppaux::ty_to_str(ccx.tcx, se_ty))
+                            ppaux::ty_to_string(ccx.tcx, se_ty))
                 });
         }
         _ => {
             tcx.sess.span_bug(main_span,
                               format!("main has a non-function type: found \
                                        `{}`",
-                                      ppaux::ty_to_str(tcx,
+                                      ppaux::ty_to_string(tcx,
                                                        main_t)).as_slice());
         }
     }
@@ -436,7 +436,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
             require_same_types(tcx, None, false, start_span, start_t, se_ty,
                 || {
                     format!("start function expects type: `{}`",
-                            ppaux::ty_to_str(ccx.tcx, se_ty))
+                            ppaux::ty_to_string(ccx.tcx, se_ty))
                 });
 
         }
@@ -444,7 +444,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
             tcx.sess.span_bug(start_span,
                               format!("start has a non-function type: found \
                                        `{}`",
-                                      ppaux::ty_to_str(tcx,
+                                      ppaux::ty_to_string(tcx,
                                                        start_t)).as_slice());
         }
     }
index 0a60a5ce0e9fa3900a5d8b7d031f189f45e17aa8..8b5d16620b0f5898d02a5f0b89bdea289b6a34c2 100644 (file)
@@ -547,7 +547,7 @@ fn inferred_index(&self, param_id: ast::NodeId) -> InferredIndex {
             None => {
                 self.tcx().sess.bug(format!(
                         "no inferred index entry for {}",
-                        self.tcx().map.node_to_str(param_id)).as_slice());
+                        self.tcx().map.node_to_string(param_id)).as_slice());
             }
         }
     }
@@ -588,8 +588,8 @@ fn is_to_be_inferred(&self, param_id: ast::NodeId) -> bool {
             let is_inferred;
             macro_rules! cannot_happen { () => { {
                 fail!("invalid parent: {:s} for {:s}",
-                      tcx.map.node_to_str(parent_id),
-                      tcx.map.node_to_str(param_id));
+                      tcx.map.node_to_string(parent_id),
+                      tcx.map.node_to_string(param_id));
             } } }
 
             match parent {
@@ -658,7 +658,7 @@ fn add_constraint(&mut self,
                       InferredIndex(index): InferredIndex,
                       variance: VarianceTermPtr<'a>) {
         debug!("add_constraint(index={}, variance={})",
-                index, variance.to_str());
+                index, variance.to_string());
         self.constraints.push(Constraint { inferred: InferredIndex(index),
                                            variance: variance });
     }
@@ -749,15 +749,15 @@ fn add_constraints_from_ty(&mut self,
 
                 // All type parameters on enums and structs should be
                 // in the TypeSpace.
-                assert!(generics.types.get_vec(subst::SelfSpace).is_empty());
-                assert!(generics.types.get_vec(subst::FnSpace).is_empty());
-                assert!(generics.regions.get_vec(subst::SelfSpace).is_empty());
-                assert!(generics.regions.get_vec(subst::FnSpace).is_empty());
+                assert!(generics.types.is_empty_in(subst::SelfSpace));
+                assert!(generics.types.is_empty_in(subst::FnSpace));
+                assert!(generics.regions.is_empty_in(subst::SelfSpace));
+                assert!(generics.regions.is_empty_in(subst::FnSpace));
 
                 self.add_constraints_from_substs(
                     def_id,
-                    generics.types.get_vec(subst::TypeSpace),
-                    generics.regions.get_vec(subst::TypeSpace),
+                    generics.types.get_slice(subst::TypeSpace),
+                    generics.regions.get_slice(subst::TypeSpace),
                     substs,
                     variance);
             }
@@ -768,22 +768,22 @@ fn add_constraints_from_ty(&mut self,
 
                 // Traits DO have a Self type parameter, but it is
                 // erased from object types.
-                assert!(!generics.types.get_vec(subst::SelfSpace).is_empty() &&
-                        substs.types.get_vec(subst::SelfSpace).is_empty());
+                assert!(!generics.types.is_empty_in(subst::SelfSpace) &&
+                        substs.types.is_empty_in(subst::SelfSpace));
 
                 // Traits never declare region parameters in the self
                 // space.
-                assert!(generics.regions.get_vec(subst::SelfSpace).is_empty());
+                assert!(generics.regions.is_empty_in(subst::SelfSpace));
 
                 // Traits never declare type/region parameters in the
                 // fn space.
-                assert!(generics.types.get_vec(subst::FnSpace).is_empty());
-                assert!(generics.regions.get_vec(subst::FnSpace).is_empty());
+                assert!(generics.types.is_empty_in(subst::FnSpace));
+                assert!(generics.regions.is_empty_in(subst::FnSpace));
 
                 self.add_constraints_from_substs(
                     def_id,
-                    generics.types.get_vec(subst::TypeSpace),
-                    generics.regions.get_vec(subst::TypeSpace),
+                    generics.types.get_slice(subst::TypeSpace),
+                    generics.regions.get_slice(subst::TypeSpace),
                     substs,
                     variance);
             }
@@ -832,8 +832,8 @@ fn add_constraints_from_ty(&mut self,
     /// object, etc) appearing in a context with ambient variance `variance`
     fn add_constraints_from_substs(&mut self,
                                    def_id: ast::DefId,
-                                   type_param_defs: &Vec<ty::TypeParameterDef>,
-                                   region_param_defs: &Vec<ty::RegionParameterDef>,
+                                   type_param_defs: &[ty::TypeParameterDef],
+                                   region_param_defs: &[ty::RegionParameterDef],
                                    substs: &subst::Substs,
                                    variance: VarianceTermPtr<'a>) {
         debug!("add_constraints_from_substs(def_id={:?})", def_id);
@@ -975,7 +975,7 @@ fn solve(&mut self) {
                                 .param_id,
                             old_value,
                             new_value,
-                            term.to_str());
+                            term.to_string());
 
                     *self.solutions.get_mut(inferred) = new_value;
                     changed = true;
index fa353652fe1ec21ae311ae6ea866a417df431ade..542bc68ef738cf260464a69e20e1160bab7206f8 100644 (file)
@@ -16,8 +16,7 @@
 use middle::ty::{BoundRegion, BrAnon, BrNamed};
 use middle::ty::{BrFresh, ctxt};
 use middle::ty::{mt, t, ParamTy};
-use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region,
-                 ReEmpty};
+use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region, ReEmpty};
 use middle::ty::{ty_bool, ty_char, ty_bot, ty_box, ty_struct, ty_enum};
 use middle::ty::{ty_err, ty_str, ty_vec, ty_float, ty_bare_fn, ty_closure};
 use middle::ty::{ty_nil, ty_param, ty_ptr, ty_rptr, ty_tup};
@@ -106,7 +105,7 @@ pub fn explain_region_and_span(cx: &ctxt, region: ty::Region)
           BrFresh(_) => "an anonymous lifetime defined on".to_string(),
           _ => {
               format!("the lifetime {} as defined on",
-                      bound_region_ptr_to_str(cx, fr.bound_region))
+                      bound_region_ptr_to_string(cx, fr.bound_region))
           }
         };
 
@@ -146,11 +145,11 @@ fn explain_span(cx: &ctxt, heading: &str, span: Span)
     }
 }
 
-pub fn bound_region_ptr_to_str(cx: &ctxt, br: BoundRegion) -> String {
-    bound_region_to_str(cx, "", false, br)
+pub fn bound_region_ptr_to_string(cx: &ctxt, br: BoundRegion) -> String {
+    bound_region_to_string(cx, "", false, br)
 }
 
-pub fn bound_region_to_str(cx: &ctxt,
+pub fn bound_region_to_string(cx: &ctxt,
                            prefix: &str, space: bool,
                            br: BoundRegion) -> String {
     let space_str = if space { " " } else { "" };
@@ -171,11 +170,11 @@ pub fn bound_region_to_str(cx: &ctxt,
 // In general, if you are giving a region error message,
 // you should use `explain_region()` or, better yet,
 // `note_and_explain_region()`
-pub fn region_ptr_to_str(cx: &ctxt, region: Region) -> String {
-    region_to_str(cx, "&", true, region)
+pub fn region_ptr_to_string(cx: &ctxt, region: Region) -> String {
+    region_to_string(cx, "&", true, region)
 }
 
-pub fn region_to_str(cx: &ctxt, prefix: &str, space: bool, region: Region) -> String {
+pub fn region_to_string(cx: &ctxt, prefix: &str, space: bool, region: Region) -> String {
     let space_str = if space { " " } else { "" };
 
     if cx.sess.verbose() {
@@ -191,10 +190,10 @@ pub fn region_to_str(cx: &ctxt, prefix: &str, space: bool, region: Region) -> St
         ty::ReEarlyBound(_, _, _, name) => {
             token::get_name(name).get().to_string()
         }
-        ty::ReLateBound(_, br) => bound_region_to_str(cx, prefix, space, br),
-        ty::ReFree(ref fr) => bound_region_to_str(cx, prefix, space, fr.bound_region),
+        ty::ReLateBound(_, br) => bound_region_to_string(cx, prefix, space, br),
+        ty::ReFree(ref fr) => bound_region_to_string(cx, prefix, space, fr.bound_region),
         ty::ReInfer(ReSkolemized(_, br)) => {
-            bound_region_to_str(cx, prefix, space, br)
+            bound_region_to_string(cx, prefix, space, br)
         }
         ty::ReInfer(ReVar(_)) => prefix.to_string(),
         ty::ReStatic => format!("{}'static{}", prefix, space_str),
@@ -202,45 +201,55 @@ pub fn region_to_str(cx: &ctxt, prefix: &str, space: bool, region: Region) -> St
     }
 }
 
-pub fn mutability_to_str(m: ast::Mutability) -> String {
+pub fn mutability_to_string(m: ast::Mutability) -> String {
     match m {
         ast::MutMutable => "mut ".to_string(),
         ast::MutImmutable => "".to_string(),
     }
 }
 
-pub fn mt_to_str(cx: &ctxt, m: &mt) -> String {
-    format!("{}{}", mutability_to_str(m.mutbl), ty_to_str(cx, m.ty))
+pub fn mt_to_string(cx: &ctxt, m: &mt) -> String {
+    format!("{}{}", mutability_to_string(m.mutbl), ty_to_string(cx, m.ty))
 }
 
+#[cfg(stage0)]
 pub fn trait_store_to_str(cx: &ctxt, s: ty::TraitStore) -> String {
+    trait_store_to_string(cx, s)
+}
+
+pub fn trait_store_to_string(cx: &ctxt, s: ty::TraitStore) -> String {
     match s {
         ty::UniqTraitStore => "Box ".to_string(),
         ty::RegionTraitStore(r, m) => {
-            format!("{}{}", region_ptr_to_str(cx, r), mutability_to_str(m))
+            format!("{}{}", region_ptr_to_string(cx, r), mutability_to_string(m))
         }
     }
 }
 
-pub fn vec_map_to_str<T>(ts: &[T], f: |t: &T| -> String) -> String {
+pub fn vec_map_to_string<T>(ts: &[T], f: |t: &T| -> String) -> String {
     let tstrs = ts.iter().map(f).collect::<Vec<String>>();
     format!("[{}]", tstrs.connect(", "))
 }
 
-pub fn fn_sig_to_str(cx: &ctxt, typ: &ty::FnSig) -> String {
+pub fn fn_sig_to_string(cx: &ctxt, typ: &ty::FnSig) -> String {
     format!("fn{}{} -> {}", typ.binder_id, typ.inputs.repr(cx),
             typ.output.repr(cx))
 }
 
-pub fn trait_ref_to_str(cx: &ctxt, trait_ref: &ty::TraitRef) -> String {
+pub fn trait_ref_to_string(cx: &ctxt, trait_ref: &ty::TraitRef) -> String {
     trait_ref.user_string(cx).to_string()
 }
 
+#[cfg(stage0)]
 pub fn ty_to_str(cx: &ctxt, typ: t) -> String {
-    fn fn_input_to_str(cx: &ctxt, input: ty::t) -> String {
-        ty_to_str(cx, input).to_string()
+    ty_to_string(cx, typ)
+}
+
+pub fn ty_to_string(cx: &ctxt, typ: t) -> String {
+    fn fn_input_to_string(cx: &ctxt, input: ty::t) -> String {
+        ty_to_string(cx, input).to_string()
     }
-    fn bare_fn_to_str(cx: &ctxt,
+    fn bare_fn_to_string(cx: &ctxt,
                       fn_style: ast::FnStyle,
                       abi: abi::Abi,
                       ident: Option<ast::Ident>,
@@ -250,13 +259,13 @@ fn bare_fn_to_str(cx: &ctxt,
         match fn_style {
             ast::NormalFn => {}
             _ => {
-                s.push_str(fn_style.to_str().as_slice());
+                s.push_str(fn_style.to_string().as_slice());
                 s.push_char(' ');
             }
         };
 
         if abi != abi::Rust {
-            s.push_str(format!("extern {} ", abi.to_str()).as_slice());
+            s.push_str(format!("extern {} ", abi.to_string()).as_slice());
         };
 
         s.push_str("fn");
@@ -269,25 +278,25 @@ fn bare_fn_to_str(cx: &ctxt,
             _ => { }
         }
 
-        push_sig_to_str(cx, &mut s, '(', ')', sig);
+        push_sig_to_string(cx, &mut s, '(', ')', sig);
 
         s
     }
 
-    fn closure_to_str(cx: &ctxt, cty: &ty::ClosureTy) -> String {
+    fn closure_to_string(cx: &ctxt, cty: &ty::ClosureTy) -> String {
         let mut s = String::new();
 
         match cty.store {
             ty::UniqTraitStore => {}
             ty::RegionTraitStore(region, _) => {
-                s.push_str(region_to_str(cx, "", true, region).as_slice());
+                s.push_str(region_to_string(cx, "", true, region).as_slice());
             }
         }
 
         match cty.fn_style {
             ast::NormalFn => {}
             _ => {
-                s.push_str(cty.fn_style.to_str().as_slice());
+                s.push_str(cty.fn_style.to_string().as_slice());
                 s.push_char(' ');
             }
         };
@@ -296,14 +305,14 @@ fn closure_to_str(cx: &ctxt, cty: &ty::ClosureTy) -> String {
             ty::UniqTraitStore => {
                 assert_eq!(cty.onceness, ast::Once);
                 s.push_str("proc");
-                push_sig_to_str(cx, &mut s, '(', ')', &cty.sig);
+                push_sig_to_string(cx, &mut s, '(', ')', &cty.sig);
             }
             ty::RegionTraitStore(..) => {
                 match cty.onceness {
                     ast::Many => {}
                     ast::Once => s.push_str("once ")
                 }
-                push_sig_to_str(cx, &mut s, '|', '|', &cty.sig);
+                push_sig_to_string(cx, &mut s, '|', '|', &cty.sig);
             }
         }
 
@@ -315,13 +324,13 @@ fn closure_to_str(cx: &ctxt, cty: &ty::ClosureTy) -> String {
         s
     }
 
-    fn push_sig_to_str(cx: &ctxt,
+    fn push_sig_to_string(cx: &ctxt,
                        s: &mut String,
                        bra: char,
                        ket: char,
                        sig: &ty::FnSig) {
         s.push_char(bra);
-        let strs: Vec<String> = sig.inputs.iter().map(|a| fn_input_to_str(cx, *a)).collect();
+        let strs: Vec<String> = sig.inputs.iter().map(|a| fn_input_to_string(cx, *a)).collect();
         s.push_str(strs.connect(", ").as_slice());
         if sig.variadic {
             s.push_str(", ...");
@@ -333,7 +342,7 @@ fn push_sig_to_str(cx: &ctxt,
             if ty::type_is_bot(sig.output) {
                 s.push_char('!');
             } else {
-                s.push_str(ty_to_str(cx, sig.output).as_slice());
+                s.push_str(ty_to_string(cx, sig.output).as_slice());
             }
         }
     }
@@ -350,33 +359,33 @@ fn push_sig_to_str(cx: &ctxt,
       ty_bot => "!".to_string(),
       ty_bool => "bool".to_string(),
       ty_char => "char".to_string(),
-      ty_int(t) => ast_util::int_ty_to_str(t, None).to_string(),
-      ty_uint(t) => ast_util::uint_ty_to_str(t, None).to_string(),
-      ty_float(t) => ast_util::float_ty_to_str(t).to_string(),
-      ty_box(typ) => format!("Gc<{}>", ty_to_str(cx, typ)),
-      ty_uniq(typ) => format!("Box<{}>", ty_to_str(cx, typ)),
+      ty_int(t) => ast_util::int_ty_to_string(t, None).to_string(),
+      ty_uint(t) => ast_util::uint_ty_to_string(t, None).to_string(),
+      ty_float(t) => ast_util::float_ty_to_string(t).to_string(),
+      ty_box(typ) => format!("Gc<{}>", ty_to_string(cx, typ)),
+      ty_uniq(typ) => format!("Box<{}>", ty_to_string(cx, typ)),
       ty_ptr(ref tm) => {
           format!("*{} {}", match tm.mutbl {
               ast::MutMutable => "mut",
               ast::MutImmutable => "const",
-          }, ty_to_str(cx, tm.ty))
+          }, ty_to_string(cx, tm.ty))
       }
       ty_rptr(r, ref tm) => {
-          let mut buf = region_ptr_to_str(cx, r);
-          buf.push_str(mt_to_str(cx, tm).as_slice());
+          let mut buf = region_ptr_to_string(cx, r);
+          buf.push_str(mt_to_string(cx, tm).as_slice());
           buf
       }
       ty_tup(ref elems) => {
-        let strs: Vec<String> = elems.iter().map(|elem| ty_to_str(cx, *elem)).collect();
+        let strs: Vec<String> = elems.iter().map(|elem| ty_to_string(cx, *elem)).collect();
         format!("({})", strs.connect(","))
       }
       ty_closure(ref f) => {
-          closure_to_str(cx, *f)
+          closure_to_string(cx, *f)
       }
       ty_bare_fn(ref f) => {
-          bare_fn_to_str(cx, f.fn_style, f.abi, None, &f.sig)
+          bare_fn_to_string(cx, f.fn_style, f.abi, None, &f.sig)
       }
-      ty_infer(infer_ty) => infer_ty.to_str(),
+      ty_infer(infer_ty) => infer_ty.to_string(),
       ty_err => "[type error]".to_string(),
       ty_param(ParamTy {idx: id, def_id: did, ..}) => {
           let ident = match cx.ty_param_defs.borrow().find(&did.node) {
@@ -414,9 +423,9 @@ fn push_sig_to_str(cx: &ctxt,
       ty_vec(ref mt, sz) => {
           match sz {
               Some(n) => {
-                  format!("[{}, .. {}]", mt_to_str(cx, mt), n)
+                  format!("[{}, .. {}]", mt_to_string(cx, mt), n)
               }
-              None => format!("[{}]", ty_to_str(cx, mt.ty)),
+              None => format!("[{}]", ty_to_string(cx, mt.ty)),
           }
       }
     }
@@ -434,7 +443,7 @@ pub fn parameterized(cx: &ctxt,
         subst::ErasedRegions => { }
         subst::NonerasedRegions(ref regions) => {
             for &r in regions.iter() {
-                let s = region_to_str(cx, "", false, r);
+                let s = region_to_string(cx, "", false, r);
                 if !s.is_empty() {
                     strs.push(s)
                 } else {
@@ -449,8 +458,8 @@ pub fn parameterized(cx: &ctxt,
         }
     }
 
-    let tps = substs.types.get_vec(subst::TypeSpace);
-    let ty_params = generics.types.get_vec(subst::TypeSpace);
+    let tps = substs.types.get_slice(subst::TypeSpace);
+    let ty_params = generics.types.get_slice(subst::TypeSpace);
     let has_defaults = ty_params.last().map_or(false, |def| def.default.is_some());
     let num_defaults = if has_defaults && !cx.sess.verbose() {
         ty_params.iter().zip(tps.iter()).rev().take_while(|&(def, &actual)| {
@@ -464,11 +473,11 @@ pub fn parameterized(cx: &ctxt,
     };
 
     for t in tps.slice_to(tps.len() - num_defaults).iter() {
-        strs.push(ty_to_str(cx, *t))
+        strs.push(ty_to_string(cx, *t))
     }
 
     if cx.sess.verbose() {
-        for t in substs.types.get_vec(subst::SelfSpace).iter() {
+        for t in substs.types.get_slice(subst::SelfSpace).iter() {
             strs.push(format!("for {}", t.repr(cx)));
         }
     }
@@ -531,7 +540,7 @@ fn repr(&self, tcx: &ctxt) -> String {
 }
 
 fn repr_vec<T:Repr>(tcx: &ctxt, v: &[T]) -> String {
-    vec_map_to_str(v, |t| t.repr(tcx))
+    vec_map_to_string(v, |t| t.repr(tcx))
 }
 
 impl<'a, T:Repr> Repr for &'a [T] {
@@ -577,13 +586,13 @@ fn repr(&self, _tcx: &ctxt) -> String {
 
 impl Repr for ty::t {
     fn repr(&self, tcx: &ctxt) -> String {
-        ty_to_str(tcx, *self)
+        ty_to_string(tcx, *self)
     }
 }
 
 impl Repr for ty::mt {
     fn repr(&self, tcx: &ctxt) -> String {
-        mt_to_str(tcx, self)
+        mt_to_string(tcx, self)
     }
 }
 
@@ -598,9 +607,9 @@ fn repr(&self, tcx: &ctxt) -> String {
 impl<T:Repr> Repr for subst::VecPerParamSpace<T> {
     fn repr(&self, tcx: &ctxt) -> String {
         format!("[{};{};{}]",
-                       self.get_vec(subst::TypeSpace).repr(tcx),
-                       self.get_vec(subst::SelfSpace).repr(tcx),
-                       self.get_vec(subst::FnSpace).repr(tcx))
+                       self.get_slice(subst::TypeSpace).repr(tcx),
+                       self.get_slice(subst::SelfSpace).repr(tcx),
+                       self.get_slice(subst::FnSpace).repr(tcx))
     }
 }
 
@@ -640,25 +649,25 @@ fn repr(&self, tcx: &ctxt) -> String {
 
 impl Repr for ty::TraitRef {
     fn repr(&self, tcx: &ctxt) -> String {
-        trait_ref_to_str(tcx, self)
+        trait_ref_to_string(tcx, self)
     }
 }
 
 impl Repr for ast::Expr {
     fn repr(&self, _tcx: &ctxt) -> String {
-        format!("expr({}: {})", self.id, pprust::expr_to_str(self))
+        format!("expr({}: {})", self.id, pprust::expr_to_string(self))
     }
 }
 
 impl Repr for ast::Path {
     fn repr(&self, _tcx: &ctxt) -> String {
-        format!("path({})", pprust::path_to_str(self))
+        format!("path({})", pprust::path_to_string(self))
     }
 }
 
 impl Repr for ast::Item {
     fn repr(&self, tcx: &ctxt) -> String {
-        format!("item({})", tcx.map.node_to_str(self.id))
+        format!("item({})", tcx.map.node_to_string(self.id))
     }
 }
 
@@ -666,13 +675,13 @@ impl Repr for ast::Stmt {
     fn repr(&self, _tcx: &ctxt) -> String {
         format!("stmt({}: {})",
                 ast_util::stmt_id(self),
-                pprust::stmt_to_str(self))
+                pprust::stmt_to_string(self))
     }
 }
 
 impl Repr for ast::Pat {
     fn repr(&self, _tcx: &ctxt) -> String {
-        format!("pat({}: {})", self.id, pprust::pat_to_str(self))
+        format!("pat({}: {})", self.id, pprust::pat_to_string(self))
     }
 }
 
@@ -788,10 +797,10 @@ fn repr(&self, tcx: &ctxt) -> String {
 
 impl Repr for ty::Variance {
     fn repr(&self, _: &ctxt) -> String {
-        // The first `.to_str()` returns a &'static str (it is not an implementation
-        // of the ToStr trait). Because of that, we need to call `.to_str()` again
+        // The first `.to_string()` returns a &'static str (it is not an implementation
+        // of the ToString trait). Because of that, we need to call `.to_string()` again
         // if we want to have a `String`.
-        self.to_str().to_str()
+        self.to_string().to_string()
     }
 }
 
@@ -836,14 +845,14 @@ impl Repr for ty::BareFnTy {
     fn repr(&self, tcx: &ctxt) -> String {
         format!("BareFnTy {{fn_style: {:?}, abi: {}, sig: {}}}",
                 self.fn_style,
-                self.abi.to_str(),
+                self.abi.to_string(),
                 self.sig.repr(tcx))
     }
 }
 
 impl Repr for ty::FnSig {
     fn repr(&self, tcx: &ctxt) -> String {
-        fn_sig_to_str(tcx, self)
+        fn_sig_to_string(tcx, self)
     }
 }
 
@@ -893,7 +902,7 @@ fn repr(&self, tcx: &ctxt) -> String {
 
 impl Repr for ty::TraitStore {
     fn repr(&self, tcx: &ctxt) -> String {
-        trait_store_to_str(tcx, *self)
+        trait_store_to_string(tcx, *self)
     }
 }
 
@@ -923,7 +932,7 @@ fn repr(&self, tcx: &ctxt) -> String {
 
 impl Repr for Span {
     fn repr(&self, tcx: &ctxt) -> String {
-        tcx.sess.codemap().span_to_str(*self).to_string()
+        tcx.sess.codemap().span_to_string(*self).to_string()
     }
 }
 
@@ -954,7 +963,7 @@ fn user_string(&self, tcx: &ctxt) -> String {
 
 impl UserString for ty::t {
     fn user_string(&self, tcx: &ctxt) -> String {
-        ty_to_str(tcx, *self)
+        ty_to_string(tcx, *self)
     }
 }
 
@@ -966,13 +975,13 @@ fn user_string(&self, _tcx: &ctxt) -> String {
 
 impl Repr for abi::Abi {
     fn repr(&self, _tcx: &ctxt) -> String {
-        self.to_str()
+        self.to_string()
     }
 }
 
 impl UserString for abi::Abi {
     fn user_string(&self, _tcx: &ctxt) -> String {
-        self.to_str()
+        self.to_string()
     }
 }
 
index 2d498e7f302d3fca3330b0182ea547608eac6c68..b3891432e2146e280317216cdedcb4f2aa877c16 100644 (file)
@@ -99,7 +99,7 @@ fn try_inline_def(cx: &core::DocContext,
     cx.inlined.borrow_mut().get_mut_ref().insert(did);
     ret.push(clean::Item {
         source: clean::Span::empty(),
-        name: Some(fqn.last().unwrap().to_str()),
+        name: Some(fqn.last().unwrap().to_string()),
         attrs: load_attrs(tcx, did),
         inner: inner,
         visibility: Some(ast::Public),
@@ -136,7 +136,7 @@ pub fn record_extern_fqn(cx: &core::DocContext,
     match cx.maybe_typed {
         core::Typed(ref tcx) => {
             let fqn = csearch::get_item_path(tcx, did);
-            let fqn = fqn.move_iter().map(|i| i.to_str()).collect();
+            let fqn = fqn.move_iter().map(|i| i.to_string()).collect();
             cx.external_paths.borrow_mut().get_mut_ref().insert(did, (fqn, kind));
         }
         core::NotTyped(..) => {}
index 4808cbdb4b09b332986c01c64214088562e7a098..6c40ee21040ad2f41c0c6c2c0548cd90d5dba1bd 100644 (file)
@@ -119,13 +119,7 @@ fn clean(&self) -> Crate {
 
         // Figure out the name of this crate
         let input = driver::FileInput(cx.src.clone());
-        let t_outputs = driver::build_output_filenames(&input,
-                                                       &None,
-                                                       &None,
-                                                       self.attrs.as_slice(),
-                                                       cx.sess());
-        let id = link::find_crate_id(self.attrs.as_slice(),
-                                     t_outputs.out_filestem.as_slice());
+        let name = link::find_crate_name(None, self.attrs.as_slice(), &input);
 
         // Clean the crate, translating the entire libsyntax AST to one that is
         // understood by rustdoc.
@@ -188,7 +182,7 @@ fn clean(&self) -> Crate {
         }
 
         Crate {
-            name: id.name.to_string(),
+            name: name.to_string(),
             module: Some(module),
             externs: externs,
             primitives: primitives,
@@ -414,7 +408,7 @@ fn clean(&self) -> Attribute {
                 List(s.get().to_string(), l.clean().move_iter().collect())
             }
             ast::MetaNameValue(ref s, ref v) => {
-                NameValue(s.get().to_string(), lit_to_str(v))
+                NameValue(s.get().to_string(), lit_to_string(v))
             }
         }
     }
@@ -505,11 +499,12 @@ fn clean(&self) -> TyParamBound {
 }
 
 fn external_path(name: &str, substs: &subst::Substs) -> Path {
-    let lifetimes = substs.regions().get_vec(subst::TypeSpace)
+    let lifetimes = substs.regions().get_slice(subst::TypeSpace)
                     .iter()
                     .filter_map(|v| v.clean())
                     .collect();
-    let types = substs.types.get_vec(subst::TypeSpace).clean();
+    let types = Vec::from_slice(substs.types.get_slice(subst::TypeSpace));
+    let types = types.clean();
     Path {
         global: false,
         segments: vec![PathSegment {
@@ -544,7 +539,7 @@ fn clean(&self) -> TyParamBound {
                  external_path("Share", &empty)),
         };
         let fqn = csearch::get_item_path(tcx, did);
-        let fqn = fqn.move_iter().map(|i| i.to_str()).collect();
+        let fqn = fqn.move_iter().map(|i| i.to_string()).collect();
         cx.external_paths.borrow_mut().get_mut_ref().insert(did,
                                                             (fqn, TypeTrait));
         TraitBound(ResolvedPath {
@@ -563,7 +558,7 @@ fn clean(&self) -> TyParamBound {
             core::NotTyped(_) => return RegionBound,
         };
         let fqn = csearch::get_item_path(tcx, self.def_id);
-        let fqn = fqn.move_iter().map(|i| i.to_str())
+        let fqn = fqn.move_iter().map(|i| i.to_string())
                      .collect::<Vec<String>>();
         let path = external_path(fqn.last().unwrap().as_slice(),
                                  &self.substs);
@@ -674,8 +669,8 @@ fn clean(&self) -> Generics {
         // is implicit.
 
         let space = {
-            if !self.types.get_vec(subst::FnSpace).is_empty() ||
-                !self.regions.get_vec(subst::FnSpace).is_empty()
+            if !self.types.is_empty_in(subst::FnSpace) ||
+                !self.regions.is_empty_in(subst::FnSpace)
             {
                 subst::FnSpace
             } else {
@@ -684,8 +679,8 @@ fn clean(&self) -> Generics {
         };
 
         Generics {
-            type_params: self.types.get_vec(space).clean(),
-            lifetimes: self.regions.get_vec(space).clean(),
+            type_params: Vec::from_slice(self.types.get_slice(space)).clean(),
+            lifetimes: Vec::from_slice(self.regions.get_slice(space)).clean(),
         }
     }
 }
@@ -1142,7 +1137,7 @@ fn find(attrs: &[Attribute]) -> Option<Primitive> {
         return None
     }
 
-    pub fn to_str(&self) -> &'static str {
+    pub fn to_string(&self) -> &'static str {
         match *self {
             Int => "int",
             I8 => "i8",
@@ -1168,7 +1163,7 @@ pub fn to_str(&self) -> &'static str {
     pub fn to_url_str(&self) -> &'static str {
         match *self {
             Unit => "unit",
-            other => other.to_str(),
+            other => other.to_string(),
         }
     }
 
@@ -1247,7 +1242,7 @@ fn clean(&self) -> Type {
                     lifetimes: Vec::new(), type_params: Vec::new()
                 },
                 decl: (ast_util::local_def(0), &fty.sig).clean(),
-                abi: fty.abi.to_str(),
+                abi: fty.abi.to_string(),
             }),
             ty::ty_closure(ref fty) => {
                 let decl = box ClosureDecl {
@@ -1267,14 +1262,14 @@ fn clean(&self) -> Type {
             ty::ty_trait(box ty::TyTrait { def_id: did, ref substs, .. }) => {
                 let fqn = csearch::get_item_path(get_cx().tcx(), did);
                 let fqn: Vec<String> = fqn.move_iter().map(|i| {
-                    i.to_str()
+                    i.to_string()
                 }).collect();
                 let kind = match ty::get(*self).sty {
                     ty::ty_struct(..) => TypeStruct,
                     ty::ty_trait(..) => TypeTrait,
                     _ => TypeEnum,
                 };
-                let path = external_path(fqn.last().unwrap().to_str().as_slice(),
+                let path = external_path(fqn.last().unwrap().to_string().as_slice(),
                                          substs);
                 get_cx().external_paths.borrow_mut().get_mut_ref()
                                        .insert(did, (fqn, kind));
@@ -1582,7 +1577,7 @@ fn clean(&self) -> PathSegment {
     }
 }
 
-fn path_to_str(p: &ast::Path) -> String {
+fn path_to_string(p: &ast::Path) -> String {
     let mut s = String::new();
     let mut first = true;
     for i in p.segments.iter().map(|x| token::get_ident(x.identifier)) {
@@ -1648,7 +1643,7 @@ fn clean(&self) -> BareFunctionDecl {
                 type_params: Vec::new(),
             },
             decl: self.decl.clean(),
-            abi: self.abi.to_str(),
+            abi: self.abi.to_string(),
         }
     }
 }
@@ -1921,7 +1916,7 @@ fn to_src(&self) -> String {
     }
 }
 
-fn lit_to_str(lit: &ast::Lit) -> String {
+fn lit_to_string(lit: &ast::Lit) -> String {
     match lit.node {
         ast::LitStr(ref st, _) => st.get().to_string(),
         ast::LitBinary(ref data) => format!("{:?}", data.as_slice()),
@@ -1934,12 +1929,12 @@ fn lit_to_str(lit: &ast::Lit) -> String {
             res
         },
         ast::LitChar(c) => format!("'{}'", c),
-        ast::LitInt(i, _t) => i.to_str(),
-        ast::LitUint(u, _t) => u.to_str(),
-        ast::LitIntUnsuffixed(i) => i.to_str(),
+        ast::LitInt(i, _t) => i.to_string(),
+        ast::LitUint(u, _t) => u.to_string(),
+        ast::LitIntUnsuffixed(i) => i.to_string(),
         ast::LitFloat(ref f, _t) => f.get().to_string(),
         ast::LitFloatUnsuffixed(ref f) => f.get().to_string(),
-        ast::LitBool(b) => b.to_str(),
+        ast::LitBool(b) => b.to_string(),
         ast::LitNil => "".to_string(),
     }
 }
@@ -1952,7 +1947,7 @@ fn name_from_pat(p: &ast::Pat) -> String {
         PatWild => "_".to_string(),
         PatWildMulti => "..".to_string(),
         PatIdent(_, ref p, _) => token::get_ident(p.node).get().to_string(),
-        PatEnum(ref p, _) => path_to_str(p),
+        PatEnum(ref p, _) => path_to_string(p),
         PatStruct(..) => fail!("tried to get argument name from pat_struct, \
                                 which is not allowed in function arguments"),
         PatTup(..) => "(tuple arg NYI)".to_string(),
index 245b2d162a77b02c76632dd77042628834119b65..9ef671ef2fcbbddc79e6fc125b6492fd330b29f0 100644 (file)
@@ -12,6 +12,7 @@
 use rustc::{driver, middle};
 use rustc::middle::{privacy, ty};
 use rustc::lint;
+use rustc::back::link;
 
 use syntax::ast;
 use syntax::parse::token;
@@ -115,13 +116,17 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>)
     }
 
     let krate = phase_1_parse_input(&sess, cfg, &input);
+
+    let name = link::find_crate_name(Some(&sess), krate.attrs.as_slice(),
+                                     &input);
+
     let (krate, ast_map)
-        = phase_2_configure_and_expand(&sess, krate, &from_str("rustdoc").unwrap())
+        = phase_2_configure_and_expand(&sess, krate, name.as_slice())
             .expect("phase_2_configure_and_expand aborted in rustdoc!");
 
     let driver::driver::CrateAnalysis {
         exported_items, public_items, ty_cx, ..
-    } = phase_3_run_analysis_passes(sess, &krate, ast_map);
+    } = phase_3_run_analysis_passes(sess, &krate, ast_map, name);
 
     debug!("crate: {:?}", krate);
     (DocContext {
index cec665768d1ee86ab4aad758480f60792d7f5283..382e299d28d9690b81c40315d1ab228f9850b6b3 100644 (file)
@@ -351,7 +351,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                 tybounds(f, typarams)
             }
             clean::Self(..) => f.write("Self".as_bytes()),
-            clean::Primitive(prim) => primitive_link(f, prim, prim.to_str()),
+            clean::Primitive(prim) => primitive_link(f, prim, prim.to_string()),
             clean::Closure(ref decl, ref region) => {
                 write!(f, "{style}{lifetimes}|{args}|{bounds}{arrow}",
                        style = FnStyleSpace(decl.fn_style),
@@ -405,7 +405,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                        } else {
                            let mut m = decl.bounds
                                            .iter()
-                                           .map(|s| s.to_str());
+                                           .map(|s| s.to_string());
                            format!(
                                ": {}",
                                m.collect::<Vec<String>>().connect(" + "))
@@ -607,7 +607,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *stab {
             Some(ref stability) => {
                 write!(f, "<a class='stability {lvl}' title='{reason}'>{lvl}</a>",
-                       lvl = stability.level.to_str(),
+                       lvl = stability.level.to_string(),
                        reason = stability.text)
             }
             None => Ok(())
@@ -621,7 +621,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *stab {
             Some(ref stability) => {
                 write!(f, "<a class='stability {lvl}' title='{lvl}{colon}{reason}'></a>",
-                       lvl = stability.level.to_str(),
+                       lvl = stability.level.to_string(),
                        colon = if stability.text.len() > 0 { ": " } else { "" },
                        reason = stability.text)
             }
index daa9ee3da844f88568d20df17b8eccece1425cd5..82bb1bd58a6d32f5164d8b630f46156a1f6542cd 100644 (file)
@@ -110,7 +110,7 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
             // miscellaneous, no highlighting
             t::DOT | t::DOTDOT | t::DOTDOTDOT | t::COMMA | t::SEMI |
                 t::COLON | t::MOD_SEP | t::LARROW | t::LPAREN |
-                t::RPAREN | t::LBRACKET | t::LBRACE | t::RBRACE => "",
+                t::RPAREN | t::LBRACKET | t::LBRACE | t::RBRACE | t::QUESTION => "",
             t::DOLLAR => {
                 if t::is_ident(&lexer.peek().tok) {
                     is_macro_nonterminal = true;
index de4bbeb6e30c8a6439c31d1f46424392796f15cf..19a9bcb9a17ab97878d6d73fe031bb47df1c0da1 100644 (file)
@@ -229,7 +229,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
         // Transform the contents of the header into a hyphenated string
         let id = s.as_slice().words().map(|s| {
             match s.to_ascii_opt() {
-                Some(s) => s.to_lower().into_str(),
+                Some(s) => s.to_lower().into_string(),
                 None => s.to_string()
             }
         }).collect::<Vec<String>>().connect("-");
index 917eab4eeb9918e547fc2e42f105b85c83c2d516..eeeee8cedf1831a1c5cc07c590140abd90cd472e 100644 (file)
@@ -428,7 +428,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::IoResult<String>
         }
         try!(write!(&mut w, r#"[{:u},"{}","{}",{}"#,
                     item.ty, item.name, path,
-                    item.desc.to_json().to_str()));
+                    item.desc.to_json().to_string()));
         match item.parent {
             Some(nodeid) => {
                 let pathid = *nodeid_to_pathid.find(&nodeid).unwrap();
index d878313ee28995c0e8e2f9507ff7d540ed3ad957..b53363738ac94f59c5c8ab26281052b73b78de60 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id = "rustdoc#0.11.0"]
+#![crate_id = "rustdoc#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "rustdoc"]
 #![experimental]
 #![desc = "rustdoc, the Rust documentation extractor"]
 #![license = "MIT/ASL2"]
 #![crate_type = "dylib"]
 #![crate_type = "rlib"]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 #![feature(globs, struct_variant, managed_boxes, macro_rules, phase)]
 
@@ -365,7 +367,7 @@ fn json_input(input: &str) -> Result<Output, String> {
         }
     };
     match json::from_reader(&mut input) {
-        Err(s) => Err(s.to_str()),
+        Err(s) => Err(s.to_string()),
         Ok(json::Object(obj)) => {
             let mut obj = obj;
             // Make sure the schema is what we expect
index 7e7f10f71783dd9d07171e2512dcfbda8e774b89..18f823317808156b88ac86cf49d0af4be814d089 100644 (file)
@@ -69,7 +69,7 @@ pub fn run(input: &str,
     }));
     let krate = driver::phase_1_parse_input(&sess, cfg, &input);
     let (krate, _) = driver::phase_2_configure_and_expand(&sess, krate,
-            &from_str("rustdoc-test").unwrap())
+                                                          "rustdoc-test")
         .expect("phase_2_configure_and_expand aborted in rustdoc!");
 
     let ctx = box(GC) core::DocContext {
index 161d3ed5e65e1cf70b259481e2321f7b2ebbb754..06f4e71871d40ba4c3d36a483a1d62b8abcd5ef3 100644 (file)
@@ -804,7 +804,7 @@ fn check(s: &str, c_str: *const libc::c_char) {
         Mary had a little lamb, Little lamb
         Mary had a little lamb, Little lamb";
 
-    fn bench_to_str(b: &mut Bencher, s: &str) {
+    fn bench_to_string(b: &mut Bencher, s: &str) {
         b.iter(|| {
             let c_str = s.to_c_str();
             check(s, c_str.as_ptr());
@@ -813,17 +813,17 @@ fn bench_to_str(b: &mut Bencher, s: &str) {
 
     #[bench]
     fn bench_to_c_str_short(b: &mut Bencher) {
-        bench_to_str(b, s_short)
+        bench_to_string(b, s_short)
     }
 
     #[bench]
     fn bench_to_c_str_medium(b: &mut Bencher) {
-        bench_to_str(b, s_medium)
+        bench_to_string(b, s_medium)
     }
 
     #[bench]
     fn bench_to_c_str_long(b: &mut Bencher) {
-        bench_to_str(b, s_long)
+        bench_to_string(b, s_long)
     }
 
     fn bench_to_c_str_unchecked(b: &mut Bencher, s: &str) {
index fabef24e06ac724f5e7d2f5a0f839dabcafff553..1a67f6d86bae64e11bdf4c70e26fd92b5dd88f27 100644 (file)
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id = "rustrt#0.11.0"]
+#![crate_id = "rustrt#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "rustrt"]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
@@ -20,6 +21,7 @@
 #![feature(linkage, lang_items, unsafe_destructor)]
 #![no_std]
 #![experimental]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 #[phase(plugin, link)] extern crate core;
 extern crate alloc;
index c13263680aac7986a93ef11601c0e124866d3a03..972a28dda62bb8dbffa0cde586e61493cf087ad0 100644 (file)
@@ -34,7 +34,8 @@
 
 */
 
-#![crate_id = "rustuv#0.11.0"]
+#![crate_id = "rustuv#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "rustuv"]
 #![experimental]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
@@ -47,6 +48,7 @@
 #![feature(macro_rules, unsafe_destructor)]
 #![deny(unused_result, unused_must_use)]
 #![allow(visible_private_types)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 #[cfg(test)] extern crate green;
 #[cfg(test)] extern crate debug;
@@ -391,7 +393,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 #[test]
 fn error_smoke_test() {
     let err: UvError = UvError(uvll::EOF);
-    assert_eq!(err.to_str(), "EOF: end of file".to_string());
+    assert_eq!(err.to_string(), "EOF: end of file".to_string());
 }
 
 #[cfg(unix)]
index ddcaeccbc190f9927235259a31b0f3fddba16032..45f93d9d1289801e52a1cd5c66b9acdab06aba3b 100644 (file)
@@ -676,7 +676,7 @@ fn send_to(&mut self, buf: &[u8], dst: rtio::SocketAddr) -> Result<(), IoError>
     fn join_multicast(&mut self, multi: rtio::IpAddr) -> Result<(), IoError> {
         let _m = self.fire_homing_missile();
         status_to_io_result(unsafe {
-            multi.to_str().with_c_str(|m_addr| {
+            multi.to_string().with_c_str(|m_addr| {
                 uvll::uv_udp_set_membership(self.handle,
                                             m_addr, ptr::null(),
                                             uvll::UV_JOIN_GROUP)
@@ -687,7 +687,7 @@ fn join_multicast(&mut self, multi: rtio::IpAddr) -> Result<(), IoError> {
     fn leave_multicast(&mut self, multi: rtio::IpAddr) -> Result<(), IoError> {
         let _m = self.fire_homing_missile();
         status_to_io_result(unsafe {
-            multi.to_str().with_c_str(|m_addr| {
+            multi.to_string().with_c_str(|m_addr| {
                 uvll::uv_udp_set_membership(self.handle,
                                             m_addr, ptr::null(),
                                             uvll::UV_LEAVE_GROUP)
index fc8aa8ac257a76f2769355979280750791041caa..95eac25ab5bd126247ec9f7860b026a1ab9fc6c7 100644 (file)
@@ -28,7 +28,8 @@
 //! An example version number with all five components is
 //! `0.8.1-rc.3.0+20130922.linux`.
 
-#![crate_id = "semver#0.11.0"]
+#![crate_id = "semver#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "semver"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
@@ -36,6 +37,7 @@
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 use std::char;
 use std::cmp;
@@ -268,7 +270,7 @@ pub fn parse(s: &str) -> Option<Version> {
     let v = parse_iter(&mut s.chars());
     match v {
         Some(v) => {
-            if v.to_str().equiv(&s) {
+            if v.to_string().equiv(&s) {
                 Some(v)
             } else {
                 None
@@ -389,11 +391,11 @@ fn test_show() {
 }
 
 #[test]
-fn test_to_str() {
-    assert_eq!(parse("1.2.3").unwrap().to_str(), "1.2.3".to_string());
-    assert_eq!(parse("1.2.3-alpha1").unwrap().to_str(), "1.2.3-alpha1".to_string());
-    assert_eq!(parse("1.2.3+build.42").unwrap().to_str(), "1.2.3+build.42".to_string());
-    assert_eq!(parse("1.2.3-alpha1+42").unwrap().to_str(), "1.2.3-alpha1+42".to_string());
+fn test_to_string() {
+    assert_eq!(parse("1.2.3").unwrap().to_string(), "1.2.3".to_string());
+    assert_eq!(parse("1.2.3-alpha1").unwrap().to_string(), "1.2.3-alpha1".to_string());
+    assert_eq!(parse("1.2.3+build.42").unwrap().to_string(), "1.2.3+build.42".to_string());
+    assert_eq!(parse("1.2.3-alpha1+42").unwrap().to_string(), "1.2.3-alpha1+42".to_string());
 }
 
 #[test]
index 832bc9c4e10cbb2c8f6085a2303aaaa92900e8d2..df4d3437b1ce673b9385e2c829cff26325d03b7f 100644 (file)
@@ -130,7 +130,7 @@ fn main() {
     // Serialize using `ToJson`
     let test2 = TestStruct1 {data_int: 1, data_str:"toto".to_string(), data_vector:vec![2,3,4,5]};
     let tjson: json::Json = test2.to_json();
-    let json_str: String = tjson.to_str();
+    let json_str: String = tjson.to_string();
 
     // Deserialize like before
     let decoded: TestStruct1 = json::decode(json_str.as_slice()).unwrap();
@@ -256,22 +256,63 @@ fn io_error_to_error(io: io::IoError) -> ParserError {
 pub type EncodeResult = io::IoResult<()>;
 pub type DecodeResult<T> = Result<T, DecoderError>;
 
-fn escape_str(s: &str) -> String {
-    let mut escaped = String::from_str("\"");
-    for c in s.chars() {
-        match c {
-            '"' => escaped.push_str("\\\""),
-            '\\' => escaped.push_str("\\\\"),
-            '\x08' => escaped.push_str("\\b"),
-            '\x0c' => escaped.push_str("\\f"),
-            '\n' => escaped.push_str("\\n"),
-            '\r' => escaped.push_str("\\r"),
-            '\t' => escaped.push_str("\\t"),
-            _ => escaped.push_char(c),
+pub fn escape_bytes(wr: &mut io::Writer, bytes: &[u8]) -> Result<(), io::IoError> {
+    try!(wr.write_str("\""));
+
+    let mut start = 0;
+
+    for (i, byte) in bytes.iter().enumerate() {
+        let escaped = match *byte {
+            b'"' => "\\\"",
+            b'\\' => "\\\\",
+            b'\x08' => "\\b",
+            b'\x0c' => "\\f",
+            b'\n' => "\\n",
+            b'\r' => "\\r",
+            b'\t' => "\\t",
+            _ => { continue; }
+        };
+
+        if start < i {
+            try!(wr.write(bytes.slice(start, i)));
         }
-    };
-    escaped.push_char('"');
-    escaped
+
+        try!(wr.write_str(escaped));
+
+        start = i + 1;
+    }
+
+    if start != bytes.len() {
+        try!(wr.write(bytes.slice_from(start)));
+    }
+
+    wr.write_str("\"")
+}
+
+fn escape_str(writer: &mut io::Writer, v: &str) -> Result<(), io::IoError> {
+    escape_bytes(writer, v.as_bytes())
+}
+
+fn escape_char(writer: &mut io::Writer, v: char) -> Result<(), io::IoError> {
+    let mut buf = [0, .. 4];
+    v.encode_utf8(buf);
+    escape_bytes(writer, buf)
+}
+
+fn spaces(wr: &mut io::Writer, mut n: uint) -> Result<(), io::IoError> {
+    static len: uint = 16;
+    static buf: [u8, ..len] = [b' ', ..len];
+
+    while n >= len {
+        try!(wr.write(buf));
+        n -= len;
+    }
+
+    if n > 0 {
+        wr.write(buf.slice_to(n))
+    } else {
+        Ok(())
+    }
 }
 
 fn fmt_number_or_null(v: f64) -> String {
@@ -281,10 +322,6 @@ fn fmt_number_or_null(v: f64) -> String {
     }
 }
 
-fn spaces(n: uint) -> String {
-    String::from_char(n, ' ')
-}
-
 /// A structure for implementing serialization to JSON.
 pub struct Encoder<'a> {
     writer: &'a mut io::Writer,
@@ -348,10 +385,10 @@ fn emit_f64(&mut self, v: f64) -> EncodeResult {
     fn emit_f32(&mut self, v: f32) -> EncodeResult { self.emit_f64(v as f64) }
 
     fn emit_char(&mut self, v: char) -> EncodeResult {
-        self.emit_str(str::from_char(v).as_slice())
+        escape_char(self.writer, v)
     }
     fn emit_str(&mut self, v: &str) -> EncodeResult {
-        write!(self.writer, "{}", escape_str(v))
+        escape_str(self.writer, v)
     }
 
     fn emit_enum(&mut self, _name: &str, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
@@ -367,10 +404,10 @@ fn emit_enum_variant(&mut self,
         // Bunny => "Bunny"
         // Kangaroo(34,"William") => {"variant": "Kangaroo", "fields": [34,"William"]}
         if cnt == 0 {
-            write!(self.writer, "{}", escape_str(name))
+            escape_str(self.writer, name)
         } else {
             try!(write!(self.writer, "{{\"variant\":"));
-            try!(write!(self.writer, "{}", escape_str(name)));
+            try!(escape_str(self.writer, name));
             try!(write!(self.writer, ",\"fields\":["));
             try!(f(self));
             write!(self.writer, "]}}")
@@ -415,7 +452,8 @@ fn emit_struct_field(&mut self,
                          idx: uint,
                          f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
         if idx != 0 { try!(write!(self.writer, ",")); }
-        try!(write!(self.writer, "{}:", escape_str(name)));
+        try!(escape_str(self.writer, name));
+        try!(write!(self.writer, ":"));
         f(self)
     }
 
@@ -541,10 +579,10 @@ fn emit_f32(&mut self, v: f32) -> EncodeResult {
     }
 
     fn emit_char(&mut self, v: char) -> EncodeResult {
-        self.emit_str(str::from_char(v).as_slice())
+        escape_char(self.writer, v)
     }
     fn emit_str(&mut self, v: &str) -> EncodeResult {
-        write!(self.writer, "{}", escape_str(v))
+        escape_str(self.writer, v)
     }
 
     fn emit_enum(&mut self,
@@ -559,14 +597,18 @@ fn emit_enum_variant(&mut self,
                          cnt: uint,
                          f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
         if cnt == 0 {
-            write!(self.writer, "{}", escape_str(name))
+            escape_str(self.writer, name)
         } else {
             self.indent += 2;
-            try!(write!(self.writer, "[\n{}{},\n", spaces(self.indent),
-                          escape_str(name)));
+            try!(write!(self.writer, "[\n"));
+            try!(spaces(self.writer, self.indent));
+            try!(escape_str(self.writer, name));
+            try!(write!(self.writer, ",\n"));
             try!(f(self));
             self.indent -= 2;
-            write!(self.writer, "\n{}]", spaces(self.indent))
+            try!(write!(self.writer, "\n"));
+            try!(spaces(self.writer, self.indent));
+            write!(self.writer, "]")
         }
     }
 
@@ -576,7 +618,7 @@ fn emit_enum_variant_arg(&mut self,
         if idx != 0 {
             try!(write!(self.writer, ",\n"));
         }
-        try!(write!(self.writer, "{}", spaces(self.indent)));
+        try!(spaces(self.writer, self.indent));
         f(self)
     }
 
@@ -607,7 +649,9 @@ fn emit_struct(&mut self,
             self.indent += 2;
             try!(f(self));
             self.indent -= 2;
-            write!(self.writer, "\n{}}}", spaces(self.indent))
+            try!(write!(self.writer, "\n"));
+            try!(spaces(self.writer, self.indent));
+            write!(self.writer, "}}")
         }
     }
 
@@ -620,7 +664,9 @@ fn emit_struct_field(&mut self,
         } else {
             try!(write!(self.writer, ",\n"));
         }
-        try!(write!(self.writer, "{}{}: ", spaces(self.indent), escape_str(name)));
+        try!(spaces(self.writer, self.indent));
+        try!(escape_str(self.writer, name));
+        try!(write!(self.writer, ": "));
         f(self)
     }
 
@@ -665,7 +711,9 @@ fn emit_seq(&mut self,
             self.indent += 2;
             try!(f(self));
             self.indent -= 2;
-            write!(self.writer, "\n{}]", spaces(self.indent))
+            try!(write!(self.writer, "\n"));
+            try!(spaces(self.writer, self.indent));
+            write!(self.writer, "]")
         }
     }
 
@@ -677,7 +725,7 @@ fn emit_seq_elt(&mut self,
         } else {
             try!(write!(self.writer, ",\n"));
         }
-        try!(write!(self.writer, "{}", spaces(self.indent)));
+        try!(spaces(self.writer, self.indent));
         f(self)
     }
 
@@ -691,7 +739,9 @@ fn emit_map(&mut self,
             self.indent += 2;
             try!(f(self));
             self.indent -= 2;
-            write!(self.writer, "\n{}}}", spaces(self.indent))
+            try!(write!(self.writer, "\n"));
+            try!(spaces(self.writer, self.indent));
+            write!(self.writer, "}}")
         }
     }
 
@@ -703,7 +753,7 @@ fn emit_map_elt_key(&mut self,
         } else {
             try!(write!(self.writer, ",\n"));
         }
-        try!(write!(self.writer, "{}", spaces(self.indent)));
+        try!(spaces(self.writer, self.indent));
         // ref #12967, make sure to wrap a key in double quotes,
         // in the event that its of a type that omits them (eg numbers)
         let mut buf = MemWriter::new();
@@ -1118,7 +1168,7 @@ pub fn new(rdr: T) -> Parser<T> {
     /// Provides access to the current position in the logical structure of the
     /// JSON stream.
     pub fn stack<'l>(&'l self) -> &'l Stack {
-        return &'l self.stack;
+        return &self.stack;
     }
 
     fn eof(&self) -> bool { self.ch.is_none() }
@@ -2152,59 +2202,59 @@ fn test_from_str_trait() {
 
     #[test]
     fn test_write_null() {
-        assert_eq!(Null.to_str().into_string(), "null".to_string());
+        assert_eq!(Null.to_string().into_string(), "null".to_string());
         assert_eq!(Null.to_pretty_str().into_string(), "null".to_string());
     }
 
 
     #[test]
     fn test_write_number() {
-        assert_eq!(Number(3.0).to_str().into_string(), "3".to_string());
+        assert_eq!(Number(3.0).to_string().into_string(), "3".to_string());
         assert_eq!(Number(3.0).to_pretty_str().into_string(), "3".to_string());
 
-        assert_eq!(Number(3.1).to_str().into_string(), "3.1".to_string());
+        assert_eq!(Number(3.1).to_string().into_string(), "3.1".to_string());
         assert_eq!(Number(3.1).to_pretty_str().into_string(), "3.1".to_string());
 
-        assert_eq!(Number(-1.5).to_str().into_string(), "-1.5".to_string());
+        assert_eq!(Number(-1.5).to_string().into_string(), "-1.5".to_string());
         assert_eq!(Number(-1.5).to_pretty_str().into_string(), "-1.5".to_string());
 
-        assert_eq!(Number(0.5).to_str().into_string(), "0.5".to_string());
+        assert_eq!(Number(0.5).to_string().into_string(), "0.5".to_string());
         assert_eq!(Number(0.5).to_pretty_str().into_string(), "0.5".to_string());
 
-        assert_eq!(Number(f64::NAN).to_str().into_string(), "null".to_string());
+        assert_eq!(Number(f64::NAN).to_string().into_string(), "null".to_string());
         assert_eq!(Number(f64::NAN).to_pretty_str().into_string(), "null".to_string());
 
-        assert_eq!(Number(f64::INFINITY).to_str().into_string(), "null".to_string());
+        assert_eq!(Number(f64::INFINITY).to_string().into_string(), "null".to_string());
         assert_eq!(Number(f64::INFINITY).to_pretty_str().into_string(), "null".to_string());
 
-        assert_eq!(Number(f64::NEG_INFINITY).to_str().into_string(), "null".to_string());
+        assert_eq!(Number(f64::NEG_INFINITY).to_string().into_string(), "null".to_string());
         assert_eq!(Number(f64::NEG_INFINITY).to_pretty_str().into_string(), "null".to_string());
     }
 
     #[test]
     fn test_write_str() {
-        assert_eq!(String("".to_string()).to_str().into_string(), "\"\"".to_string());
+        assert_eq!(String("".to_string()).to_string().into_string(), "\"\"".to_string());
         assert_eq!(String("".to_string()).to_pretty_str().into_string(), "\"\"".to_string());
 
-        assert_eq!(String("foo".to_string()).to_str().into_string(), "\"foo\"".to_string());
+        assert_eq!(String("foo".to_string()).to_string().into_string(), "\"foo\"".to_string());
         assert_eq!(String("foo".to_string()).to_pretty_str().into_string(), "\"foo\"".to_string());
     }
 
     #[test]
     fn test_write_bool() {
-        assert_eq!(Boolean(true).to_str().into_string(), "true".to_string());
+        assert_eq!(Boolean(true).to_string().into_string(), "true".to_string());
         assert_eq!(Boolean(true).to_pretty_str().into_string(), "true".to_string());
 
-        assert_eq!(Boolean(false).to_str().into_string(), "false".to_string());
+        assert_eq!(Boolean(false).to_string().into_string(), "false".to_string());
         assert_eq!(Boolean(false).to_pretty_str().into_string(), "false".to_string());
     }
 
     #[test]
     fn test_write_list() {
-        assert_eq!(List(vec![]).to_str().into_string(), "[]".to_string());
+        assert_eq!(List(vec![]).to_string().into_string(), "[]".to_string());
         assert_eq!(List(vec![]).to_pretty_str().into_string(), "[]".to_string());
 
-        assert_eq!(List(vec![Boolean(true)]).to_str().into_string(), "[true]".to_string());
+        assert_eq!(List(vec![Boolean(true)]).to_string().into_string(), "[true]".to_string());
         assert_eq!(
             List(vec![Boolean(true)]).to_pretty_str().into_string(),
             "\
@@ -2218,7 +2268,7 @@ fn test_write_list() {
             Null,
             List(vec![String("foo\nbar".to_string()), Number(3.5)])]);
 
-        assert_eq!(long_test_list.to_str().into_string(),
+        assert_eq!(long_test_list.to_string().into_string(),
             "[false,null,[\"foo\\nbar\",3.5]]".to_string());
         assert_eq!(
             long_test_list.to_pretty_str().into_string(),
@@ -2236,13 +2286,13 @@ fn test_write_list() {
 
     #[test]
     fn test_write_object() {
-        assert_eq!(mk_object([]).to_str().into_string(), "{}".to_string());
+        assert_eq!(mk_object([]).to_string().into_string(), "{}".to_string());
         assert_eq!(mk_object([]).to_pretty_str().into_string(), "{}".to_string());
 
         assert_eq!(
             mk_object([
                 ("a".to_string(), Boolean(true))
-            ]).to_str().into_string(),
+            ]).to_string().into_string(),
             "{\"a\":true}".to_string()
         );
         assert_eq!(
@@ -2261,7 +2311,7 @@ fn test_write_object() {
             ]);
 
         assert_eq!(
-            complex_obj.to_str().into_string(),
+            complex_obj.to_string().into_string(),
             "{\
                 \"b\":[\
                     {\"c\":\"\\f\\r\"},\
@@ -2294,7 +2344,7 @@ fn test_write_object() {
 
         // We can't compare the strings directly because the object fields be
         // printed in a different order.
-        assert_eq!(a.clone(), from_str(a.to_str().as_slice()).unwrap());
+        assert_eq!(a.clone(), from_str(a.to_string().as_slice()).unwrap());
         assert_eq!(a.clone(),
                    from_str(a.to_pretty_str().as_slice()).unwrap());
     }
index a2a504132363332e60cffd698e95b38945388cb7..f635c3f4150996427fb2b7ef4bd65b41100b0a7c 100644 (file)
@@ -14,7 +14,8 @@
 Core encoding and decoding interfaces.
 */
 
-#![crate_id = "serialize#0.11.0"]
+#![crate_id = "serialize#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "serialize"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
@@ -24,6 +25,7 @@
        html_root_url = "http://doc.rust-lang.org/0.11.0/",
        html_playground_url = "http://play.rust-lang.org/")]
 #![feature(macro_rules, managed_boxes, default_type_params, phase)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 // test harness access
 #[cfg(test)]
index 0ed555e392fa1f0e1643eb1be47465e882f9159e..03d9445b9b94bae73032dd1e2bfdd73f43b38177 100644 (file)
@@ -17,6 +17,7 @@
 use std::path;
 use std::rc::Rc;
 use std::gc::{Gc, GC};
+use std::cell::{Cell, RefCell};
 
 pub trait Encoder<E> {
     // Primitive types:
@@ -536,6 +537,35 @@ fn decode(d: &mut D) -> Result<path::windows::Path, E> {
     }
 }
 
+impl<E, S: Encoder<E>, T: Encodable<S, E> + Copy> Encodable<S, E> for Cell<T> {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
+        self.get().encode(s)
+    }
+}
+
+impl<E, D: Decoder<E>, T: Decodable<D, E> + Copy> Decodable<D, E> for Cell<T> {
+    fn decode(d: &mut D) -> Result<Cell<T>, E> {
+        Ok(Cell::new(try!(Decodable::decode(d))))
+    }
+}
+
+// FIXME: #15036
+// Should use `try_borrow`, returning a
+// `encoder.error("attempting to Encode borrowed RefCell")`
+// from `encode` when `try_borrow` returns `None`.
+
+impl<E, S: Encoder<E>, T: Encodable<S, E>> Encodable<S, E> for RefCell<T> {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
+        self.borrow().encode(s)
+    }
+}
+
+impl<E, D: Decoder<E>, T: Decodable<D, E>> Decodable<D, E> for RefCell<T> {
+    fn decode(d: &mut D) -> Result<RefCell<T>, E> {
+        Ok(RefCell::new(try!(Decodable::decode(d))))
+    }
+}
+
 // ___________________________________________________________________________
 // Helper routines
 //
index fae1b933210d52a9c2f8f49499583eeb03f49873..796147ce7a05dd0c14a52806c93ceade93da5b45 100644 (file)
@@ -345,10 +345,10 @@ fn eq_ignore_case(self, other: &[Ascii]) -> bool {
 
 impl IntoStr for Vec<Ascii> {
     #[inline]
-    fn into_str(self) -> String {
+    fn into_string(self) -> String {
         unsafe {
             let s: &str = mem::transmute(self.as_slice());
-            s.to_string()
+            String::from_str(s)
         }
     }
 }
@@ -438,12 +438,12 @@ unsafe fn str_map_bytes(string: String, map: &'static [u8]) -> String {
         *b = map[*b as uint];
     }
 
-    str::from_utf8(bytes.as_slice()).unwrap().to_string()
+    String::from_str(str::from_utf8(bytes.as_slice()).unwrap())
 }
 
 #[inline]
 unsafe fn str_copy_map_bytes(string: &str, map: &'static [u8]) -> String {
-    let mut s = string.to_string();
+    let mut s = String::from_str(string);
     for b in s.as_mut_bytes().mut_iter() {
         *b = map[*b as uint];
     }
@@ -578,12 +578,12 @@ fn test_ascii_vec() {
         assert_eq!(v.as_slice().to_ascii(), v2ascii!([40, 32, 59]));
         assert_eq!("( ;".to_string().as_slice().to_ascii(), v2ascii!([40, 32, 59]));
 
-        assert_eq!("abCDef&?#".to_ascii().to_lower().into_str(), "abcdef&?#".to_string());
-        assert_eq!("abCDef&?#".to_ascii().to_upper().into_str(), "ABCDEF&?#".to_string());
+        assert_eq!("abCDef&?#".to_ascii().to_lower().into_string(), "abcdef&?#".to_string());
+        assert_eq!("abCDef&?#".to_ascii().to_upper().into_string(), "ABCDEF&?#".to_string());
 
-        assert_eq!("".to_ascii().to_lower().into_str(), "".to_string());
-        assert_eq!("YMCA".to_ascii().to_lower().into_str(), "ymca".to_string());
-        assert_eq!("abcDEFxyz:.;".to_ascii().to_upper().into_str(), "ABCDEFXYZ:.;".to_string());
+        assert_eq!("".to_ascii().to_lower().into_string(), "".to_string());
+        assert_eq!("YMCA".to_ascii().to_lower().into_string(), "ymca".to_string());
+        assert_eq!("abcDEFxyz:.;".to_ascii().to_upper().into_string(), "ABCDEFXYZ:.;".to_string());
 
         assert!("aBcDeF&?#".to_ascii().eq_ignore_case("AbCdEf&?#".to_ascii()));
 
@@ -595,11 +595,11 @@ fn test_ascii_vec() {
 
     #[test]
     fn test_ascii_vec_ng() {
-        assert_eq!("abCDef&?#".to_ascii().to_lower().into_str(), "abcdef&?#".to_string());
-        assert_eq!("abCDef&?#".to_ascii().to_upper().into_str(), "ABCDEF&?#".to_string());
-        assert_eq!("".to_ascii().to_lower().into_str(), "".to_string());
-        assert_eq!("YMCA".to_ascii().to_lower().into_str(), "ymca".to_string());
-        assert_eq!("abcDEFxyz:.;".to_ascii().to_upper().into_str(), "ABCDEFXYZ:.;".to_string());
+        assert_eq!("abCDef&?#".to_ascii().to_lower().into_string(), "abcdef&?#".to_string());
+        assert_eq!("abCDef&?#".to_ascii().to_upper().into_string(), "ABCDEF&?#".to_string());
+        assert_eq!("".to_ascii().to_lower().into_string(), "".to_string());
+        assert_eq!("YMCA".to_ascii().to_lower().into_string(), "ymca".to_string());
+        assert_eq!("abcDEFxyz:.;".to_ascii().to_upper().into_string(), "ABCDEFXYZ:.;".to_string());
     }
 
     #[test]
@@ -615,9 +615,9 @@ fn test_ascii_as_str() {
     }
 
     #[test]
-    fn test_ascii_into_str() {
-        assert_eq!(vec2ascii![40, 32, 59].into_str(), "( ;".to_string());
-        assert_eq!(vec2ascii!(40, 32, 59).into_str(), "( ;".to_string());
+    fn test_ascii_into_string() {
+        assert_eq!(vec2ascii![40, 32, 59].into_string(), "( ;".to_string());
+        assert_eq!(vec2ascii!(40, 32, 59).into_string(), "( ;".to_string());
     }
 
     #[test]
@@ -757,8 +757,8 @@ fn test_eq_ignore_ascii_case() {
     }
 
     #[test]
-    fn test_to_str() {
-        let s = Ascii{ chr: 't' as u8 }.to_str();
+    fn test_to_string() {
+        let s = Ascii{ chr: 't' as u8 }.to_string();
         assert_eq!(s, "t".to_string());
     }
 
index 7c01a0342edc71b30bbcaf89597f1bfc10240b4c..098e87243b69cfe8d75824de5e7cc91e744f0748 100644 (file)
@@ -294,8 +294,7 @@ pub fn read<'a>(&'a self, index: &FullIndex) -> (&'a K, &'a V) {
 
             unsafe {
                 debug_assert!(*self.hashes.offset(idx) != EMPTY_BUCKET);
-                (&'a *self.keys.offset(idx),
-                 &'a *self.vals.offset(idx))
+                (&*self.keys.offset(idx), &*self.vals.offset(idx))
             }
         }
 
@@ -306,8 +305,7 @@ pub fn read_mut<'a>(&'a mut self, index: &FullIndex) -> (&'a K, &'a mut V) {
 
             unsafe {
                 debug_assert!(*self.hashes.offset(idx) != EMPTY_BUCKET);
-                (&'a     *self.keys.offset(idx),
-                 &'a mut *self.vals.offset(idx))
+                (&*self.keys.offset(idx), &mut *self.vals.offset(idx))
             }
         }
 
@@ -319,8 +317,7 @@ pub fn read_all_mut<'a>(&'a mut self, index: &FullIndex)
             unsafe {
                 debug_assert!(*self.hashes.offset(idx) != EMPTY_BUCKET);
                 (transmute(self.hashes.offset(idx)),
-                 &'a mut *self.keys.offset(idx),
-                 &'a mut *self.vals.offset(idx))
+                 &mut *self.keys.offset(idx), &mut *self.vals.offset(idx))
             }
         }
 
index 08f11581e838a17a74f5ee8badd66b350e230066..a02402271d08383bdc76faa2ebd942459e7f444e 100644 (file)
@@ -319,20 +319,20 @@ fn test_change_capacity() {
     }
 
     #[test]
-    fn test_to_str() {
+    fn test_to_string() {
         let mut cache: LruCache<int, int> = LruCache::new(3);
         cache.put(1, 10);
         cache.put(2, 20);
         cache.put(3, 30);
-        assert_eq!(cache.to_str(), "{3: 30, 2: 20, 1: 10}".to_string());
+        assert_eq!(cache.to_string(), "{3: 30, 2: 20, 1: 10}".to_string());
         cache.put(2, 22);
-        assert_eq!(cache.to_str(), "{2: 22, 3: 30, 1: 10}".to_string());
+        assert_eq!(cache.to_string(), "{2: 22, 3: 30, 1: 10}".to_string());
         cache.put(6, 60);
-        assert_eq!(cache.to_str(), "{6: 60, 2: 22, 3: 30}".to_string());
+        assert_eq!(cache.to_string(), "{6: 60, 2: 22, 3: 30}".to_string());
         cache.get(&3);
-        assert_eq!(cache.to_str(), "{3: 30, 6: 60, 2: 22}".to_string());
+        assert_eq!(cache.to_string(), "{3: 30, 6: 60, 2: 22}".to_string());
         cache.change_capacity(2);
-        assert_eq!(cache.to_str(), "{3: 30, 6: 60}".to_string());
+        assert_eq!(cache.to_string(), "{3: 30, 6: 60}".to_string());
     }
 
     #[test]
@@ -343,6 +343,6 @@ fn test_clear() {
         cache.clear();
         assert!(cache.get(&1).is_none());
         assert!(cache.get(&2).is_none());
-        assert_eq!(cache.to_str(), "{}".to_string());
+        assert_eq!(cache.to_string(), "{}".to_string());
     }
 }
index 728875ce2601012f3d25b645de37fddae4212a36..86283f03381dd1c68d4c7130f49bd726c57ff3f1 100644 (file)
@@ -209,13 +209,11 @@ fn test_errors_do_not_crash() {
 #[cfg(target_os = "ios")]
 #[cfg(target_os = "freebsd")]
 pub mod dl {
-    use prelude::*;
 
     use c_str::{CString, ToCStr};
     use libc;
     use ptr;
     use result::*;
-    use str::StrAllocating;
     use string::String;
 
     pub unsafe fn open_external<T: ToCStr>(filename: T) -> *mut u8 {
@@ -243,9 +241,8 @@ pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, String> {
             let ret = if ptr::null() == last_error {
                 Ok(result)
             } else {
-                Err(CString::new(last_error, false).as_str()
-                                                   .unwrap()
-                                                   .to_string())
+                Err(String::from_str(CString::new(last_error, false).as_str()
+                    .unwrap()))
             };
 
             ret
index 1ca72bca20bdb5cbec9b983e2e90f7f8e7991262..21b1e0560a5dba49ff6d0b715196d0f4d91ba957 100644 (file)
@@ -14,7 +14,6 @@
 
 use option::{Option, Some, None};
 use string::String;
-use str::StrAllocating;
 
 /// A trait to abstract the idea of creating a new instance of a type from a
 /// string.
@@ -55,7 +54,7 @@ fn from_str(s: &str) -> Option<bool> {
 impl FromStr for String {
     #[inline]
     fn from_str(s: &str) -> Option<String> {
-        Some(s.to_string())
+        Some(String::from_str(s))
     }
 }
 
index 277aca2332d475cb1b42a9852f0f59b793d2d505..ca3eee01575fd3aca54bbddd85bb875925a0a69b 100644 (file)
@@ -508,14 +508,15 @@ mod bench {
     use prelude::*;
     use self::test::Bencher;
 
+    // why is this a macro? wouldn't an inlined function work just as well?
     macro_rules! u64_from_be_bytes_bench_impl(
-        ($size:expr, $stride:expr, $start_index:expr) =>
+        ($b:expr, $size:expr, $stride:expr, $start_index:expr) =>
         ({
             use super::u64_from_be_bytes;
 
             let data = Vec::from_fn($stride*100+$start_index, |i| i as u8);
             let mut sum = 0u64;
-            b.iter(|| {
+            $b.iter(|| {
                 let mut i = $start_index;
                 while i < data.len() {
                     sum += u64_from_be_bytes(data.as_slice(), i, $size);
@@ -527,31 +528,31 @@ macro_rules! u64_from_be_bytes_bench_impl(
 
     #[bench]
     fn u64_from_be_bytes_4_aligned(b: &mut Bencher) {
-        u64_from_be_bytes_bench_impl!(4, 4, 0);
+        u64_from_be_bytes_bench_impl!(b, 4, 4, 0);
     }
 
     #[bench]
     fn u64_from_be_bytes_4_unaligned(b: &mut Bencher) {
-        u64_from_be_bytes_bench_impl!(4, 4, 1);
+        u64_from_be_bytes_bench_impl!(b, 4, 4, 1);
     }
 
     #[bench]
     fn u64_from_be_bytes_7_aligned(b: &mut Bencher) {
-        u64_from_be_bytes_bench_impl!(7, 8, 0);
+        u64_from_be_bytes_bench_impl!(b, 7, 8, 0);
     }
 
     #[bench]
     fn u64_from_be_bytes_7_unaligned(b: &mut Bencher) {
-        u64_from_be_bytes_bench_impl!(7, 8, 1);
+        u64_from_be_bytes_bench_impl!(b, 7, 8, 1);
     }
 
     #[bench]
     fn u64_from_be_bytes_8_aligned(b: &mut Bencher) {
-        u64_from_be_bytes_bench_impl!(8, 8, 0);
+        u64_from_be_bytes_bench_impl!(b, 8, 8, 0);
     }
 
     #[bench]
     fn u64_from_be_bytes_8_unaligned(b: &mut Bencher) {
-        u64_from_be_bytes_bench_impl!(8, 8, 1);
+        u64_from_be_bytes_bench_impl!(b, 8, 8, 1);
     }
 }
index e7f26c7bd910e5d21d61de30a703734684f9f1a4..ed183cbf3bc2191dac321c7a6f582144080f4d9c 100644 (file)
@@ -915,7 +915,7 @@ macro_rules! check( ($e:expr) => (
     macro_rules! error( ($e:expr, $s:expr) => (
         match $e {
             Ok(val) => fail!("Should have been an error, was {:?}", val),
-            Err(ref err) => assert!(err.to_str().as_slice().contains($s.as_slice()),
+            Err(ref err) => assert!(err.to_string().as_slice().contains($s.as_slice()),
                                     format!("`{}` did not contain `{}`", err, $s))
         }
     ) )
@@ -1167,7 +1167,7 @@ pub fn tmpdir() -> TempDir {
         for n in range(0i,3) {
             let f = dir.join(format!("{}.txt", n));
             let mut w = check!(File::create(&f));
-            let msg_str = format!("{}{}", prefix, n.to_str());
+            let msg_str = format!("{}{}", prefix, n.to_string());
             let msg = msg_str.as_slice().as_bytes();
             check!(w.write(msg));
         }
index 3443a85b46819a41a7619ce9f74b64223f2010b5..7d293f363f0dd48331c655fcdfa4d551e0a214e9 100644 (file)
@@ -532,7 +532,7 @@ fn test_write_strings() {
         writer.write_line("testing").unwrap();
         writer.write_str("testing").unwrap();
         let mut r = BufReader::new(writer.get_ref());
-        assert_eq!(r.read_to_str().unwrap(), "testingtesting\ntesting".to_string());
+        assert_eq!(r.read_to_string().unwrap(), "testingtesting\ntesting".to_string());
     }
 
     #[test]
@@ -542,14 +542,14 @@ fn test_write_char() {
         writer.write_char('\n').unwrap();
         writer.write_char('ệ').unwrap();
         let mut r = BufReader::new(writer.get_ref());
-        assert_eq!(r.read_to_str().unwrap(), "a\nệ".to_string());
+        assert_eq!(r.read_to_string().unwrap(), "a\nệ".to_string());
     }
 
     #[test]
     fn test_read_whole_string_bad() {
         let buf = [0xff];
         let mut r = BufReader::new(buf);
-        match r.read_to_str() {
+        match r.read_to_string() {
             Ok(..) => fail!(),
             Err(..) => {}
         }
index 1d339b03af6717d9eb68e4908f3e6e4e7333bbf8..fe9016453f78eb726f9cf03d3dd3cd84c75bfc30 100644 (file)
@@ -233,7 +233,7 @@ fn file_product(p: &Path) -> IoResult<u32> {
 use result::{Ok, Err, Result};
 use rt::rtio;
 use slice::{Vector, MutableVector, ImmutableVector};
-use str::{Str, StrSlice, StrAllocating};
+use str::{Str, StrSlice};
 use str;
 use string::String;
 use uint;
@@ -566,7 +566,7 @@ pub trait Reader {
     fn read_at_least(&mut self, min: uint, buf: &mut [u8]) -> IoResult<uint> {
         if min > buf.len() {
             return Err(IoError {
-                detail: Some("the buffer is too short".to_string()),
+                detail: Some(String::from_str("the buffer is too short")),
                 ..standard_error(InvalidInput)
             });
         }
@@ -634,7 +634,7 @@ fn push(&mut self, len: uint, buf: &mut Vec<u8>) -> IoResult<uint> {
     fn push_at_least(&mut self, min: uint, len: uint, buf: &mut Vec<u8>) -> IoResult<uint> {
         if min > len {
             return Err(IoError {
-                detail: Some("the buffer is too short".to_string()),
+                detail: Some(String::from_str("the buffer is too short")),
                 ..standard_error(InvalidInput)
             });
         }
@@ -702,10 +702,10 @@ fn read_to_end(&mut self) -> IoResult<Vec<u8>> {
     /// This function returns all of the same errors as `read_to_end` with an
     /// additional error if the reader's contents are not a valid sequence of
     /// UTF-8 bytes.
-    fn read_to_str(&mut self) -> IoResult<String> {
+    fn read_to_string(&mut self) -> IoResult<String> {
         self.read_to_end().and_then(|s| {
             match str::from_utf8(s.as_slice()) {
-                Some(s) => Ok(s.to_string()),
+                Some(s) => Ok(String::from_str(s)),
                 None => Err(standard_error(InvalidInput)),
             }
         })
@@ -1440,7 +1440,7 @@ pub trait Buffer: Reader {
     fn read_line(&mut self) -> IoResult<String> {
         self.read_until('\n' as u8).and_then(|line|
             match str::from_utf8(line.as_slice()) {
-                Some(s) => Ok(s.to_string()),
+                Some(s) => Ok(String::from_str(s)),
                 None => Err(standard_error(InvalidInput)),
             }
         )
index ca59849202b08677e03943747fb2617d6eb6a687..79caded6711a22219d7c97af256b9df07da58653 100644 (file)
@@ -443,10 +443,11 @@ fn test_from_str_socket_addr() {
     }
 
     #[test]
-    fn ipv6_addr_to_str() {
+    fn ipv6_addr_to_string() {
         let a1 = Ipv6Addr(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x280);
-        assert!(a1.to_str() == "::ffff:192.0.2.128".to_string() ||
-                a1.to_str() == "::FFFF:192.0.2.128".to_string());
-        assert_eq!(Ipv6Addr(8, 9, 10, 11, 12, 13, 14, 15).to_str(), "8:9:a:b:c:d:e:f".to_string());
+        assert!(a1.to_string() == "::ffff:192.0.2.128".to_string() ||
+                a1.to_string() == "::FFFF:192.0.2.128".to_string());
+        assert_eq!(Ipv6Addr(8, 9, 10, 11, 12, 13, 14, 15).to_string(),
+                   "8:9:a:b:c:d:e:f".to_string());
     }
 }
index baf53251fbe082e5e485ac2df70e64d7dc36c72d..49322098348ff830bd0fb09528de975bb3d20158 100644 (file)
@@ -467,7 +467,7 @@ mod test {
 
     iotest!(fn listen_ip4_localhost() {
         let socket_addr = next_test_ip4();
-        let ip_str = socket_addr.ip.to_str();
+        let ip_str = socket_addr.ip.to_string();
         let port = socket_addr.port;
         let listener = TcpListener::bind(ip_str.as_slice(), port);
         let mut acceptor = listener.listen();
@@ -485,7 +485,7 @@ mod test {
 
     iotest!(fn connect_localhost() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -502,7 +502,7 @@ mod test {
 
     iotest!(fn connect_ip4_loopback() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -519,7 +519,7 @@ mod test {
 
     iotest!(fn connect_ip6_loopback() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -536,7 +536,7 @@ mod test {
 
     iotest!(fn smoke_test_ip4() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -553,7 +553,7 @@ mod test {
 
     iotest!(fn smoke_test_ip6() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -570,7 +570,7 @@ mod test {
 
     iotest!(fn read_eof_ip4() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -587,7 +587,7 @@ mod test {
 
     iotest!(fn read_eof_ip6() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -604,7 +604,7 @@ mod test {
 
     iotest!(fn read_eof_twice_ip4() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -629,7 +629,7 @@ mod test {
 
     iotest!(fn read_eof_twice_ip6() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -654,7 +654,7 @@ mod test {
 
     iotest!(fn write_close_ip4() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -681,7 +681,7 @@ mod test {
 
     iotest!(fn write_close_ip6() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -708,7 +708,7 @@ mod test {
 
     iotest!(fn multiple_connect_serial_ip4() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let max = 10u;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
@@ -729,7 +729,7 @@ mod test {
 
     iotest!(fn multiple_connect_serial_ip6() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let max = 10u;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
@@ -750,7 +750,7 @@ mod test {
 
     iotest!(fn multiple_connect_interleaved_greedy_schedule_ip4() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         static MAX: int = 10;
         let acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
@@ -772,7 +772,7 @@ mod test {
         connect(0, addr);
 
         fn connect(i: int, addr: SocketAddr) {
-            let ip_str = addr.ip.to_str();
+            let ip_str = addr.ip.to_string();
             let port = addr.port;
             if i == MAX { return }
 
@@ -789,7 +789,7 @@ fn connect(i: int, addr: SocketAddr) {
 
     iotest!(fn multiple_connect_interleaved_greedy_schedule_ip6() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         static MAX: int = 10;
         let acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
@@ -811,7 +811,7 @@ fn connect(i: int, addr: SocketAddr) {
         connect(0, addr);
 
         fn connect(i: int, addr: SocketAddr) {
-            let ip_str = addr.ip.to_str();
+            let ip_str = addr.ip.to_string();
             let port = addr.port;
             if i == MAX { return }
 
@@ -829,7 +829,7 @@ fn connect(i: int, addr: SocketAddr) {
     iotest!(fn multiple_connect_interleaved_lazy_schedule_ip4() {
         static MAX: int = 10;
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -850,7 +850,7 @@ fn connect(i: int, addr: SocketAddr) {
         connect(0, addr);
 
         fn connect(i: int, addr: SocketAddr) {
-            let ip_str = addr.ip.to_str();
+            let ip_str = addr.ip.to_string();
             let port = addr.port;
             if i == MAX { return }
 
@@ -868,7 +868,7 @@ fn connect(i: int, addr: SocketAddr) {
     iotest!(fn multiple_connect_interleaved_lazy_schedule_ip6() {
         static MAX: int = 10;
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -889,7 +889,7 @@ fn connect(i: int, addr: SocketAddr) {
         connect(0, addr);
 
         fn connect(i: int, addr: SocketAddr) {
-            let ip_str = addr.ip.to_str();
+            let ip_str = addr.ip.to_string();
             let port = addr.port;
             if i == MAX { return }
 
@@ -905,7 +905,7 @@ fn connect(i: int, addr: SocketAddr) {
     })
 
     pub fn socket_name(addr: SocketAddr) {
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut listener = TcpListener::bind(ip_str.as_slice(), port).unwrap();
 
@@ -917,7 +917,7 @@ pub fn socket_name(addr: SocketAddr) {
     }
 
     pub fn peer_name(addr: SocketAddr) {
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
         spawn(proc() {
@@ -954,7 +954,7 @@ pub fn peer_name(addr: SocketAddr) {
         let port = addr.port;
         let (tx, rx) = channel();
         spawn(proc() {
-            let ip_str = addr.ip.to_str();
+            let ip_str = addr.ip.to_string();
             let mut srv = TcpListener::bind(ip_str.as_slice(), port).listen().unwrap();
             tx.send(());
             let mut cl = srv.accept().unwrap();
@@ -965,7 +965,7 @@ pub fn peer_name(addr: SocketAddr) {
         });
 
         rx.recv();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let mut c = TcpStream::connect(ip_str.as_slice(), port).unwrap();
         let mut b = [0, ..10];
         assert_eq!(c.read(b), Ok(1));
@@ -975,7 +975,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn double_bind() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let listener = TcpListener::bind(ip_str.as_slice(), port).unwrap().listen();
         assert!(listener.is_ok());
@@ -994,7 +994,7 @@ pub fn peer_name(addr: SocketAddr) {
         let (tx, rx) = channel();
 
         spawn(proc() {
-            let ip_str = addr.ip.to_str();
+            let ip_str = addr.ip.to_string();
             rx.recv();
             let _stream = TcpStream::connect(ip_str.as_slice(), port).unwrap();
             // Close
@@ -1002,7 +1002,7 @@ pub fn peer_name(addr: SocketAddr) {
         });
 
         {
-            let ip_str = addr.ip.to_str();
+            let ip_str = addr.ip.to_string();
             let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
             tx.send(());
             {
@@ -1012,12 +1012,12 @@ pub fn peer_name(addr: SocketAddr) {
             }
             // Close listener
         }
-        let _listener = TcpListener::bind(addr.ip.to_str().as_slice(), port);
+        let _listener = TcpListener::bind(addr.ip.to_string().as_slice(), port);
     })
 
     iotest!(fn tcp_clone_smoke() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -1048,7 +1048,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn tcp_clone_two_read() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
         let (tx1, rx) = channel();
@@ -1082,7 +1082,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn tcp_clone_two_write() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -1111,7 +1111,7 @@ pub fn peer_name(addr: SocketAddr) {
         use rt::rtio::RtioTcpStream;
 
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let a = TcpListener::bind(ip_str.as_slice(), port).unwrap().listen();
         spawn(proc() {
@@ -1129,7 +1129,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn accept_timeout() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut a = TcpListener::bind(ip_str.as_slice(), port).unwrap().listen().unwrap();
 
@@ -1150,7 +1150,7 @@ pub fn peer_name(addr: SocketAddr) {
         if !cfg!(target_os = "freebsd") {
             let (tx, rx) = channel();
             spawn(proc() {
-                tx.send(TcpStream::connect(addr.ip.to_str().as_slice(),
+                tx.send(TcpStream::connect(addr.ip.to_string().as_slice(),
                                            port).unwrap());
             });
             let _l = rx.recv();
@@ -1168,7 +1168,7 @@ 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.ip.to_str().as_slice(),
+            drop(TcpStream::connect(addr.ip.to_string().as_slice(),
                                     port).unwrap());
         });
         a.accept().unwrap();
@@ -1176,7 +1176,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn close_readwrite_smoke() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let a = TcpListener::bind(ip_str.as_slice(), port).listen().unwrap();
         let (_tx, rx) = channel::<()>();
@@ -1214,7 +1214,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn close_read_wakes_up() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let a = TcpListener::bind(ip_str.as_slice(), port).listen().unwrap();
         let (_tx, rx) = channel::<()>();
@@ -1241,7 +1241,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn readwrite_timeouts() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut a = TcpListener::bind(ip_str.as_slice(), port).listen().unwrap();
         let (tx, rx) = channel::<()>();
@@ -1275,7 +1275,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn read_timeouts() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut a = TcpListener::bind(ip_str.as_slice(), port).listen().unwrap();
         let (tx, rx) = channel::<()>();
@@ -1305,7 +1305,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn write_timeouts() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut a = TcpListener::bind(ip_str.as_slice(), port).listen().unwrap();
         let (tx, rx) = channel::<()>();
@@ -1334,7 +1334,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn timeout_concurrent_read() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut a = TcpListener::bind(ip_str.as_slice(), port).listen().unwrap();
         let (tx, rx) = channel::<()>();
@@ -1363,7 +1363,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn clone_while_reading() {
         let addr = next_test_ip6();
-        let listen = TcpListener::bind(addr.ip.to_str().as_slice(), addr.port);
+        let listen = TcpListener::bind(addr.ip.to_string().as_slice(), addr.port);
         let mut accept = listen.listen().unwrap();
 
         // Enqueue a task to write to a socket
@@ -1371,7 +1371,7 @@ pub fn peer_name(addr: SocketAddr) {
         let (txdone, rxdone) = channel();
         let txdone2 = txdone.clone();
         spawn(proc() {
-            let mut tcp = TcpStream::connect(addr.ip.to_str().as_slice(),
+            let mut tcp = TcpStream::connect(addr.ip.to_string().as_slice(),
                                              addr.port).unwrap();
             rx.recv();
             tcp.write_u8(0).unwrap();
index 8e1747146e42eb31b9048b4d1daed112f13492f0..8f1046b62fd91040f188e07b661df518f2d44b6f 100644 (file)
@@ -615,7 +615,7 @@ mod tests {
     })
 
     pub fn read_all(input: &mut Reader) -> String {
-        input.read_to_str().unwrap()
+        input.read_to_string().unwrap()
     }
 
     pub fn run_output(cmd: Command) -> String {
index e5a64f785ce9640643911ef9c55fb8a76f44b77c..cdd083202e085217d3bf74583694dd3d245b11b3 100644 (file)
@@ -391,7 +391,7 @@ mod tests {
             set_stdout(box w);
             println!("hello!");
         });
-        assert_eq!(r.read_to_str().unwrap(), "hello!\n".to_string());
+        assert_eq!(r.read_to_string().unwrap(), "hello!\n".to_string());
     })
 
     iotest!(fn capture_stderr() {
@@ -404,7 +404,7 @@ mod tests {
             ::realstd::io::stdio::set_stderr(box w);
             fail!("my special message");
         });
-        let s = r.read_to_str().unwrap();
+        let s = r.read_to_string().unwrap();
         assert!(s.as_slice().contains("my special message"));
     })
 }
index 83a01feee9017865f0c13878ca2282b28f805be2..2acf12b76c00adea15f127673a8277222759d125 100644 (file)
@@ -379,21 +379,21 @@ fn limit_reader_buffer() {
         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.read_line(), Ok("012".to_string()));
             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.read_line(), Ok("3456789\n".to_string()));
             assert_eq!(r.limit(), 1);
-            assert_eq!(r.read_line(), Ok("0".to_str()));
+            assert_eq!(r.read_line(), Ok("0".to_string()));
         }
         {
             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()));
+            assert_eq!(r.read_line(), Ok("23456789\n".to_string()));
         }
     }
 
index 0e6f848fce85ab19fa9fc3d5b1d6aceba1db522c..928a1088d0efa29e4708cccf8dba8431b574c06f 100644 (file)
@@ -94,7 +94,8 @@
 //! all the standard macros, such as `assert!`, `fail!`, `println!`,
 //! and `format!`, also available to all Rust code.
 
-#![crate_id = "std#0.11.0"]
+#![crate_id = "std#0.11.0"] // NOTE: remove after stage0 snap
+#![crate_name = "std"]
 #![unstable]
 #![comment = "The Rust standard library"]
 #![license = "MIT/ASL2"]
 
 #![feature(macro_rules, globs, managed_boxes, linkage)]
 #![feature(default_type_params, phase, lang_items, unsafe_destructor)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 // Don't link to std. We are std.
 #![no_std]
index 2b2ffb9f4e281706052a95a1797d3c10b984cf00..680620f5a752fdd0e455d7578d0b81c18006bf96 100644 (file)
@@ -245,7 +245,7 @@ fn atanh(self) -> f32 {
 ///
 /// * num - The float value
 #[inline]
-pub fn to_str(num: f32) -> String {
+pub fn to_string(num: f32) -> String {
     let (r, _) = strconv::float_to_str_common(
         num, 10u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false);
     r
index e156d2ce553240b629b6594429b60ef3eb303725..3180ee28c6fee19442d8278894c852f3ff556dbb 100644 (file)
@@ -253,7 +253,7 @@ fn atanh(self) -> f64 {
 ///
 /// * num - The float value
 #[inline]
-pub fn to_str(num: f64) -> String {
+pub fn to_string(num: f64) -> String {
     let (r, _) = strconv::float_to_str_common(
         num, 10u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false);
     r
index a4200b55a5906f575aa1bc6942f6a7a7f7cc4a47..3c01edf233925986005a4803c3dd1148191fd4e3 100644 (file)
@@ -55,7 +55,7 @@ fn from_str_radix(s: &str, radix: uint) -> Option<$T> {
 
 /// Convert to a string as a byte slice in a given base.
 ///
-/// Use in place of x.to_str() when you do not need to store the string permanently
+/// Use in place of x.to_string() when you do not need to store the string permanently
 ///
 /// # Examples
 ///
@@ -143,7 +143,7 @@ fn test_parse_bytes() {
     }
 
     #[test]
-    fn test_to_str() {
+    fn test_to_string() {
         assert_eq!((0 as $T).to_str_radix(10u), "0".to_string());
         assert_eq!((1 as $T).to_str_radix(10u), "1".to_string());
         assert_eq!((-1 as $T).to_str_radix(10u), "-1".to_string());
@@ -155,28 +155,28 @@ fn test_to_str() {
     #[test]
     fn test_int_to_str_overflow() {
         let mut i8_val: i8 = 127_i8;
-        assert_eq!(i8_val.to_str(), "127".to_string());
+        assert_eq!(i8_val.to_string(), "127".to_string());
 
         i8_val += 1 as i8;
-        assert_eq!(i8_val.to_str(), "-128".to_string());
+        assert_eq!(i8_val.to_string(), "-128".to_string());
 
         let mut i16_val: i16 = 32_767_i16;
-        assert_eq!(i16_val.to_str(), "32767".to_string());
+        assert_eq!(i16_val.to_string(), "32767".to_string());
 
         i16_val += 1 as i16;
-        assert_eq!(i16_val.to_str(), "-32768".to_string());
+        assert_eq!(i16_val.to_string(), "-32768".to_string());
 
         let mut i32_val: i32 = 2_147_483_647_i32;
-        assert_eq!(i32_val.to_str(), "2147483647".to_string());
+        assert_eq!(i32_val.to_string(), "2147483647".to_string());
 
         i32_val += 1 as i32;
-        assert_eq!(i32_val.to_str(), "-2147483648".to_string());
+        assert_eq!(i32_val.to_string(), "-2147483648".to_string());
 
         let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
-        assert_eq!(i64_val.to_str(), "9223372036854775807".to_string());
+        assert_eq!(i64_val.to_string(), "9223372036854775807".to_string());
 
         i64_val += 1 as i64;
-        assert_eq!(i64_val.to_str(), "-9223372036854775808".to_string());
+        assert_eq!(i64_val.to_string(), "-9223372036854775808".to_string());
     }
 
     #[test]
index 5028987f44fdd239e85d9421e6867e5482d68fb1..88fc6e1ffd85f743be2e01d6365887f3643ecbf7 100644 (file)
@@ -146,7 +146,7 @@ impl NumStrConv for $t {
 /**
  * Converts an integral number to its string representation as a byte vector.
  * This is meant to be a common base implementation for all integral string
- * conversion functions like `to_str()` or `to_str_radix()`.
+ * conversion functions like `to_string()` or `to_str_radix()`.
  *
  * # Arguments
  * - `num`           - The number to convert. Accepts any number that
@@ -226,7 +226,7 @@ pub fn int_to_str_bytes_common<T: Int>(num: T, radix: uint, sign: SignFormat, f:
 /**
  * Converts a number to its string representation as a byte vector.
  * This is meant to be a common base implementation for all numeric string
- * conversion functions like `to_str()` or `to_str_radix()`.
+ * conversion functions like `to_string()` or `to_str_radix()`.
  *
  * # Arguments
  * - `num`           - The number to convert. Accepts any number that
@@ -894,9 +894,9 @@ mod f64 {
         use f64;
 
         #[bench]
-        fn float_to_str(b: &mut Bencher) {
+        fn float_to_string(b: &mut Bencher) {
             let mut rng = weak_rng();
-            b.iter(|| { f64::to_str(rng.gen()); })
+            b.iter(|| { f64::to_string(rng.gen()); })
         }
     }
 }
index 7f2efe034a24a77b8c4acb8ae83e1abef89eff64..cfcaf0fa8daa35d61ebaa203ecaf86446964fa0e 100644 (file)
@@ -56,7 +56,7 @@ fn from_str_radix(s: &str, radix: uint) -> Option<$T> {
 
 /// Convert to a string as a byte slice in a given base.
 ///
-/// Use in place of x.to_str() when you do not need to store the string permanently
+/// Use in place of x.to_string() when you do not need to store the string permanently
 ///
 /// # Examples
 ///
@@ -101,7 +101,7 @@ mod tests {
     use u16;
 
     #[test]
-    pub fn test_to_str() {
+    pub fn test_to_string() {
         assert_eq!((0 as $T).to_str_radix(10u), "0".to_string());
         assert_eq!((1 as $T).to_str_radix(10u), "1".to_string());
         assert_eq!((2 as $T).to_str_radix(10u), "2".to_string());
@@ -141,28 +141,28 @@ pub fn test_parse_bytes() {
     #[test]
     fn test_uint_to_str_overflow() {
         let mut u8_val: u8 = 255_u8;
-        assert_eq!(u8_val.to_str(), "255".to_string());
+        assert_eq!(u8_val.to_string(), "255".to_string());
 
         u8_val += 1 as u8;
-        assert_eq!(u8_val.to_str(), "0".to_string());
+        assert_eq!(u8_val.to_string(), "0".to_string());
 
         let mut u16_val: u16 = 65_535_u16;
-        assert_eq!(u16_val.to_str(), "65535".to_string());
+        assert_eq!(u16_val.to_string(), "65535".to_string());
 
         u16_val += 1 as u16;
-        assert_eq!(u16_val.to_str(), "0".to_string());
+        assert_eq!(u16_val.to_string(), "0".to_string());
 
         let mut u32_val: u32 = 4_294_967_295_u32;
-        assert_eq!(u32_val.to_str(), "4294967295".to_string());
+        assert_eq!(u32_val.to_string(), "4294967295".to_string());
 
         u32_val += 1 as u32;
-        assert_eq!(u32_val.to_str(), "0".to_string());
+        assert_eq!(u32_val.to_string(), "0".to_string());
 
         let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
-        assert_eq!(u64_val.to_str(), "18446744073709551615".to_string());
+        assert_eq!(u64_val.to_string(), "18446744073709551615".to_string());
 
         u64_val += 1 as u64;
-        assert_eq!(u64_val.to_str(), "0".to_string());
+        assert_eq!(u64_val.to_string(), "0".to_string());
     }
 
     #[test]
index b3f25914c8f568768c22fd62c6523e837895e9c0..db56b387f8d023965888ad71043105c3a46e6248 100644 (file)
@@ -223,8 +223,8 @@ fn with_env_lock<T>(f: || -> T) -> T {
 /// ```
 pub fn env() -> Vec<(String,String)> {
     env_as_bytes().move_iter().map(|(k,v)| {
-        let k = str::from_utf8_lossy(k.as_slice()).to_string();
-        let v = str::from_utf8_lossy(v.as_slice()).to_string();
+        let k = String::from_str(str::from_utf8_lossy(k.as_slice()).as_slice());
+        let v = String::from_str(str::from_utf8_lossy(v.as_slice()).as_slice());
         (k,v)
     }).collect()
 }
@@ -334,7 +334,7 @@ fn env_convert(input: Vec<Vec<u8>>) -> Vec<(Vec<u8>, Vec<u8>)> {
 /// }
 /// ```
 pub fn getenv(n: &str) -> Option<String> {
-    getenv_as_bytes(n).map(|v| str::from_utf8_lossy(v.as_slice()).to_string())
+    getenv_as_bytes(n).map(|v| String::from_str(str::from_utf8_lossy(v.as_slice()).as_slice()))
 }
 
 #[cfg(unix)]
index d98cfb7d8eece0c35396db2b1a5dd2cb48614a6e..5c6e140bd29b30aa2827273f5882a9f95719bea6 100644 (file)
@@ -545,7 +545,7 @@ macro_rules! t(
             ($path:expr, $disp:ident, $exp:expr) => (
                 {
                     let path = Path::new($path);
-                    assert!(path.$disp().to_str().as_slice() == $exp);
+                    assert!(path.$disp().to_string().as_slice() == $exp);
                 }
             )
         )
index 113b0410875af7ad0d068d0b394554320715de96..206f75739e82d1e2f72f8ae7d8a9455964f92fd4 100644 (file)
@@ -1314,9 +1314,9 @@ fn test_not_utf8_fail() {
     #[test]
     fn test_display_str() {
         let path = Path::new("foo");
-        assert_eq!(path.display().to_str(), "foo".to_string());
+        assert_eq!(path.display().to_string(), "foo".to_string());
         let path = Path::new(b"\\");
-        assert_eq!(path.filename_display().to_str(), "".to_string());
+        assert_eq!(path.filename_display().to_string(), "".to_string());
 
         let path = Path::new("foo");
         let mo = path.display().as_maybe_owned();
index 61e8b63af359ef6d042d511d7b785a049a82f0c3..6d60fc19d5dc9b7e45951f37d3432c4b82367cc2 100644 (file)
@@ -44,7 +44,8 @@
 #[doc(no_inline)] pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
 #[doc(no_inline)] pub use ops::{BitAnd, BitOr, BitXor};
 #[doc(no_inline)] pub use ops::{Drop, Deref, DerefMut};
-#[doc(no_inline)] pub use ops::{Shl, Shr, Index};
+#[doc(no_inline)] pub use ops::{Shl, Shr};
+#[doc(no_inline)] #[cfg(not(stage0))] pub use ops::{Index, IndexMut};
 #[doc(no_inline)] pub use option::{Option, Some, None};
 #[doc(no_inline)] pub use result::{Result, Ok, Err};
 
@@ -77,7 +78,7 @@
 #[doc(no_inline)] pub use io::{Buffer, Writer, Reader, Seek};
 #[doc(no_inline)] pub use str::{Str, StrVector, StrSlice, OwnedStr};
 #[doc(no_inline)] pub use str::{IntoMaybeOwned, StrAllocating};
-#[doc(no_inline)] pub use to_str::{ToStr, IntoStr};
+#[doc(no_inline)] pub use to_str::{ToString, IntoStr};
 #[doc(no_inline)] pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4};
 #[doc(no_inline)] pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8};
 #[doc(no_inline)] pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12};
index 2e0dcdd8eb69f83588a353615eba5a3cb8f7e344..404887823cbf8d0888db5b440c62b6473171ff37 100644 (file)
@@ -261,7 +261,7 @@ pub fn write(w: &mut Writer) -> IoResult<()> {
         use slice::{MutableVector};
 
         extern {
-            fn backtrace(buf: *mut *const libc::c_void,
+            fn backtrace(buf: *mut *mut libc::c_void,
                          sz: libc::c_int) -> libc::c_int;
         }
 
@@ -274,7 +274,7 @@ fn backtrace(buf: *mut *const libc::c_void,
         try!(writeln!(w, "stack backtrace:"));
         // 100 lines should be enough
         static SIZE: libc::c_int = 100;
-        let mut buf: [*const libc::c_void, ..SIZE] = unsafe {mem::zeroed()};
+        let mut buf: [*mut libc::c_void, ..SIZE] = unsafe {mem::zeroed()};
         let cnt = unsafe { backtrace(buf.as_mut_ptr(), SIZE) as uint};
 
         // skipping the first one as it is write itself
index c20cbea0ae7cced97332673d8e1eda74ea934486..72cc596085e075ff7fbd7dd6b7f1f3dcc6528c1a 100644 (file)
@@ -638,7 +638,7 @@ fn test_stdout() {
             });
         assert!(r.is_ok());
 
-        let output = reader.read_to_str().unwrap();
+        let output = reader.read_to_string().unwrap();
         assert_eq!(output, "Hello, world!".to_string());
     }
 
index e51e2c4d9ce5e5acbff2437c02d9e37d26bc2a2e..c19fd81b5705667185f8a8a9391fca11a9114dba 100644 (file)
@@ -10,7 +10,7 @@
 
 /*!
 
-The `ToStr` trait for converting to strings
+The `ToString` trait for converting to strings
 
 */
 
 use string::String;
 
 /// A generic trait for converting a value to a string
-pub trait ToStr {
+pub trait ToString {
     /// Converts the value of `self` to an owned string
-    fn to_str(&self) -> String;
+    fn to_string(&self) -> String;
 }
 
 /// Trait for converting a type to a string, consuming it in the process.
 pub trait IntoStr {
     /// Consume and convert to a string.
-    fn into_str(self) -> String;
+    fn into_string(self) -> String;
 }
 
-impl<T: fmt::Show> ToStr for T {
-    fn to_str(&self) -> String {
+impl<T: fmt::Show> ToString for T {
+    fn to_string(&self) -> String {
         format!("{}", *self)
     }
 }
@@ -44,23 +44,23 @@ mod tests {
 
     #[test]
     fn test_simple_types() {
-        assert_eq!(1i.to_str(), "1".to_string());
-        assert_eq!((-1i).to_str(), "-1".to_string());
-        assert_eq!(200u.to_str(), "200".to_string());
-        assert_eq!(2u8.to_str(), "2".to_string());
-        assert_eq!(true.to_str(), "true".to_string());
-        assert_eq!(false.to_str(), "false".to_string());
-        assert_eq!(().to_str(), "()".to_string());
-        assert_eq!(("hi".to_string()).to_str(), "hi".to_string());
+        assert_eq!(1i.to_string(), "1".to_string());
+        assert_eq!((-1i).to_string(), "-1".to_string());
+        assert_eq!(200u.to_string(), "200".to_string());
+        assert_eq!(2u8.to_string(), "2".to_string());
+        assert_eq!(true.to_string(), "true".to_string());
+        assert_eq!(false.to_string(), "false".to_string());
+        assert_eq!(().to_string(), "()".to_string());
+        assert_eq!(("hi".to_string()).to_string(), "hi".to_string());
     }
 
     #[test]
     fn test_vectors() {
         let x: Vec<int> = vec![];
-        assert_eq!(x.to_str(), "[]".to_string());
-        assert_eq!((vec![1i]).to_str(), "[1]".to_string());
-        assert_eq!((vec![1i, 2, 3]).to_str(), "[1, 2, 3]".to_string());
-        assert!((vec![vec![], vec![1i], vec![1i, 1]]).to_str() ==
+        assert_eq!(x.to_string(), "[]".to_string());
+        assert_eq!((vec![1i]).to_string(), "[1]".to_string());
+        assert_eq!((vec![1i, 2, 3]).to_string(), "[1, 2, 3]".to_string());
+        assert!((vec![vec![], vec![1i], vec![1i, 1]]).to_string() ==
                "[[], [1], [1, 1]]".to_string());
     }
 }
index 4f6d1a261c4917696b56d99a628f7a4cbb69333c..c0d62caaa6b5b75384a6edc14bf00ec32fc7d8dc 100644 (file)
@@ -17,7 +17,8 @@
 //! use this crate specifically. Instead, its functionality is reexported
 //! through `std::sync`.
 
-#![crate_id = "sync#0.11.0"]
+#![crate_id = "sync#0.11.0"] // NOTE: remove after stage0 snap
+#![crate_name = "sync"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
@@ -30,6 +31,7 @@
 #![feature(phase, globs, macro_rules, unsafe_destructor)]
 #![deny(missing_doc)]
 #![no_std]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 #[phase(plugin, link)] extern crate core;
 extern crate alloc;
index 237d0660a41dcca5edb5f15875cd41bdc5fd2f5a..d98ae9f0e33a001323aa2ce38eb8e94f2adf4d5c 100644 (file)
@@ -184,12 +184,14 @@ pub enum TyParamBound {
 pub struct TyParam {
     pub ident: Ident,
     pub id: NodeId,
-    pub sized: Sized,
     pub bounds: OwnedSlice<TyParamBound>,
+    pub unbound: Option<TyParamBound>,
     pub default: Option<P<Ty>>,
     pub span: Span
 }
 
+/// Represents lifetimes and type parameters attached to a declaration
+/// of a function, enum, trait, etc.
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub struct Generics {
     pub lifetimes: Vec<Lifetime>,
@@ -288,7 +290,7 @@ pub enum Pat_ {
     PatWild,
     PatWildMulti,
     // A PatIdent may either be a new bound variable,
-    // or a nullary enum (in which case the second field
+    // or a nullary enum (in which case the third field
     // is None).
     // In the nullary enum case, the parser can't determine
     // which it is. The resolver determines this, and
@@ -453,10 +455,10 @@ pub enum Expr_ {
     ExprCast(Gc<Expr>, P<Ty>),
     ExprIf(Gc<Expr>, P<Block>, Option<Gc<Expr>>),
     ExprWhile(Gc<Expr>, P<Block>),
-    // FIXME #6993: change to Option<Name>
+    // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
     ExprForLoop(Gc<Pat>, Gc<Expr>, P<Block>, Option<Ident>),
     // Conditionless loop (can be exited with break, cont, or ret)
-    // FIXME #6993: change to Option<Name>
+    // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
     ExprLoop(P<Block>, Option<Ident>),
     ExprMatch(Gc<Expr>, Vec<Arm>),
     ExprFnBlock(P<FnDecl>, P<Block>),
@@ -468,9 +470,8 @@ pub enum Expr_ {
     ExprField(Gc<Expr>, SpannedIdent, Vec<P<Ty>>),
     ExprIndex(Gc<Expr>, Gc<Expr>),
 
-    /// Expression that looks like a "name". For example,
-    /// `std::slice::from_elem::<uint>` is an ExprPath that's the "name" part
-    /// of a function call.
+    /// Variable reference, possibly containing `::` and/or
+    /// type parameters, e.g. foo::bar::<baz>
     ExprPath(Path),
 
     ExprAddrOf(Mutability, Gc<Expr>),
@@ -643,6 +644,8 @@ pub struct TypeField {
     pub span: Span,
 }
 
+/// Represents a required method in a trait declaration,
+/// one without a default implementation
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub struct TypeMethod {
     pub ident: Ident,
@@ -656,6 +659,8 @@ pub struct TypeMethod {
     pub vis: Visibility,
 }
 
+/// Represents a method declaration in a trait declaration, possibly
+/// including a default implementation
 // A trait method is either required (meaning it doesn't have an
 // implementation, just a signature) or provided (meaning it has a default
 // implementation).
@@ -676,7 +681,7 @@ pub enum IntTy {
 
 impl fmt::Show for IntTy {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{}", ast_util::int_ty_to_str(*self, None))
+        write!(f, "{}", ast_util::int_ty_to_string(*self, None))
     }
 }
 
@@ -691,7 +696,7 @@ pub enum UintTy {
 
 impl fmt::Show for UintTy {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{}", ast_util::uint_ty_to_str(*self, None))
+        write!(f, "{}", ast_util::uint_ty_to_string(*self, None))
     }
 }
 
@@ -703,7 +708,7 @@ pub enum FloatTy {
 
 impl fmt::Show for FloatTy {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{}", ast_util::float_ty_to_str(*self))
+        write!(f, "{}", ast_util::float_ty_to_string(*self))
     }
 }
 
@@ -741,6 +746,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+/// Represents the type of a closure
 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
 pub struct ClosureTy {
     pub lifetimes: Vec<Lifetime>,
@@ -809,6 +815,7 @@ pub struct InlineAsm {
     pub dialect: AsmDialect
 }
 
+/// represents an argument in a function header
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub struct Arg {
     pub ty: P<Ty>,
@@ -836,7 +843,7 @@ pub fn new_self(span: Span, mutability: Mutability) -> Arg {
     }
 }
 
-// represents the header (not the body) of a function declaration
+/// represents the header (not the body) of a function declaration
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub struct FnDecl {
     pub inputs: Vec<Arg>,
@@ -1034,12 +1041,6 @@ pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility {
     }
 }
 
-#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
-pub enum Sized {
-    DynSize,
-    StaticSize,
-}
-
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub struct StructField_ {
     pub kind: StructFieldKind,
@@ -1107,7 +1108,12 @@ pub enum Item_ {
     ItemTy(P<Ty>, Generics),
     ItemEnum(EnumDef, Generics),
     ItemStruct(Gc<StructDef>, Generics),
-    ItemTrait(Generics, Sized, Vec<TraitRef> , Vec<TraitMethod> ),
+    /// Represents a Trait Declaration
+    ItemTrait(Generics,
+              Option<TyParamBound>, // (optional) default bound not required for Self.
+                                    // Currently, only Sized makes sense here.
+              Vec<TraitRef> ,
+              Vec<TraitMethod>),
     ItemImpl(Generics,
              Option<TraitRef>, // (optional) trait this impl implements
              P<Ty>, // self
index 1a9a910f38c07a9e64e8b5fa2f924e28436843f9..c95ea4a24aadb98256ae59c47fe60c79c7396817 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) -> String {
+pub fn path_to_string<PI: Iterator<PathElem>>(mut path: PI) -> String {
     let itr = token::get_ident_interner();
 
     path.fold(String::new(), |mut s, e| {
@@ -250,7 +250,7 @@ pub fn get_foreign_abi(&self, id: NodeId) -> abi::Abi {
         match abi {
             Some(abi) => abi,
             None => fail!("expected foreign mod or inlined parent, found {}",
-                          self.node_to_str(parent))
+                          self.node_to_string(parent))
         }
     }
 
@@ -265,7 +265,7 @@ pub fn get_foreign_vis(&self, id: NodeId) -> Visibility {
     pub fn expect_item(&self, id: NodeId) -> Gc<Item> {
         match self.find(id) {
             Some(NodeItem(item)) => item,
-            _ => fail!("expected item, found {}", self.node_to_str(id))
+            _ => fail!("expected item, found {}", self.node_to_string(id))
         }
     }
 
@@ -283,21 +283,21 @@ pub fn expect_struct(&self, id: NodeId) -> Gc<StructDef> {
                     _ => fail!("struct ID bound to enum variant that isn't struct-like"),
                 }
             }
-            _ => fail!(format!("expected struct, found {}", self.node_to_str(id))),
+            _ => fail!(format!("expected struct, found {}", self.node_to_string(id))),
         }
     }
 
     pub fn expect_variant(&self, id: NodeId) -> P<Variant> {
         match self.find(id) {
             Some(NodeVariant(variant)) => variant,
-            _ => fail!(format!("expected variant, found {}", self.node_to_str(id))),
+            _ => fail!(format!("expected variant, found {}", self.node_to_string(id))),
         }
     }
 
     pub fn expect_foreign_item(&self, id: NodeId) -> Gc<ForeignItem> {
         match self.find(id) {
             Some(NodeForeignItem(item)) => item,
-            _ => fail!("expected foreign item, found {}", self.node_to_str(id))
+            _ => fail!("expected foreign item, found {}", self.node_to_string(id))
         }
     }
 
@@ -326,13 +326,13 @@ 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) -> String {
-        self.with_path(id, |path| path_to_str(path))
+    pub fn path_to_string(&self, id: NodeId) -> String {
+        self.with_path(id, |path| path_to_string(path))
     }
 
     fn path_to_str_with_ident(&self, id: NodeId, i: Ident) -> String {
         self.with_path(id, |path| {
-            path_to_str(path.chain(Some(PathName(i.name)).move_iter()))
+            path_to_string(path.chain(Some(PathName(i.name)).move_iter()))
         })
     }
 
@@ -416,8 +416,8 @@ pub fn span(&self, id: NodeId) -> Span {
             .unwrap_or_else(|| fail!("AstMap.span: could not find span for id {}", id))
     }
 
-    pub fn node_to_str(&self, id: NodeId) -> String {
-        node_id_to_str(self, id)
+    pub fn node_to_string(&self, id: NodeId) -> String {
+        node_id_to_string(self, id)
     }
 }
 
@@ -664,7 +664,7 @@ pub fn map_decoded_item<F: FoldOps>(map: &Map,
     ii
 }
 
-fn node_id_to_str(map: &Map, id: NodeId) -> String {
+fn node_id_to_string(map: &Map, id: NodeId) -> String {
     match map.find(id) {
         Some(NodeItem(item)) => {
             let path_str = map.path_to_str_with_ident(id, item.ident);
@@ -689,43 +689,43 @@ fn node_id_to_str(map: &Map, id: NodeId) -> String {
         Some(NodeMethod(m)) => {
             format!("method {} in {} (id={})",
                     token::get_ident(m.ident),
-                    map.path_to_str(id), id)
+                    map.path_to_string(id), id)
         }
         Some(NodeTraitMethod(ref tm)) => {
             let m = ast_util::trait_method_to_ty_method(&**tm);
             format!("method {} in {} (id={})",
                     token::get_ident(m.ident),
-                    map.path_to_str(id), id)
+                    map.path_to_string(id), id)
         }
         Some(NodeVariant(ref variant)) => {
             format!("variant {} in {} (id={})",
                     token::get_ident(variant.node.name),
-                    map.path_to_str(id), id)
+                    map.path_to_string(id), id)
         }
         Some(NodeExpr(ref expr)) => {
-            format!("expr {} (id={})", pprust::expr_to_str(&**expr), id)
+            format!("expr {} (id={})", pprust::expr_to_string(&**expr), id)
         }
         Some(NodeStmt(ref stmt)) => {
-            format!("stmt {} (id={})", pprust::stmt_to_str(&**stmt), id)
+            format!("stmt {} (id={})", pprust::stmt_to_string(&**stmt), id)
         }
         Some(NodeArg(ref pat)) => {
-            format!("arg {} (id={})", pprust::pat_to_str(&**pat), id)
+            format!("arg {} (id={})", pprust::pat_to_string(&**pat), id)
         }
         Some(NodeLocal(ref pat)) => {
-            format!("local {} (id={})", pprust::pat_to_str(&**pat), id)
+            format!("local {} (id={})", pprust::pat_to_string(&**pat), id)
         }
         Some(NodePat(ref pat)) => {
-            format!("pat {} (id={})", pprust::pat_to_str(&**pat), id)
+            format!("pat {} (id={})", pprust::pat_to_string(&**pat), id)
         }
         Some(NodeBlock(ref block)) => {
-            format!("block {} (id={})", pprust::block_to_str(&**block), id)
+            format!("block {} (id={})", pprust::block_to_string(&**block), id)
         }
         Some(NodeStructCtor(_)) => {
-            format!("struct_ctor {} (id={})", map.path_to_str(id), id)
+            format!("struct_ctor {} (id={})", map.path_to_string(id), id)
         }
         Some(NodeLifetime(ref l)) => {
             format!("lifetime {} (id={})",
-                    pprust::lifetime_to_str(&**l), id)
+                    pprust::lifetime_to_string(&**l), id)
         }
         None => {
             format!("unknown node (id={})", id)
index 036d6b4b43adc62d537c8c0f9dfc745964d6bca3..57c60b4a9490351b611b6699dbb87e7294d262cc 100644 (file)
@@ -48,7 +48,7 @@ pub fn stmt_id(s: &Stmt) -> NodeId {
     }
 }
 
-pub fn binop_to_str(op: BinOp) -> &'static str {
+pub fn binop_to_string(op: BinOp) -> &'static str {
     match op {
         BiAdd => "+",
         BiSub => "-",
@@ -87,7 +87,7 @@ pub fn is_shift_binop(b: BinOp) -> bool {
     }
 }
 
-pub fn unop_to_str(op: UnOp) -> &'static str {
+pub fn unop_to_string(op: UnOp) -> &'static str {
     match op {
       UnBox => "box(GC) ",
       UnUniq => "box() ",
@@ -103,7 +103,7 @@ pub fn is_path(e: Gc<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>) -> String {
+pub fn int_ty_to_string(t: IntTy, val: Option<i64>) -> String {
     let s = match t {
         TyI if val.is_some() => "i",
         TyI => "int",
@@ -133,7 +133,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>) -> String {
+pub fn uint_ty_to_string(t: UintTy, val: Option<u64>) -> String {
     let s = match t {
         TyU if val.is_some() => "u",
         TyU => "uint",
@@ -158,7 +158,7 @@ pub fn uint_ty_max(t: UintTy) -> u64 {
     }
 }
 
-pub fn float_ty_to_str(t: FloatTy) -> String {
+pub fn float_ty_to_string(t: FloatTy) -> String {
     match t {
         TyF32 => "f32".to_string(),
         TyF64 => "f64".to_string(),
@@ -229,11 +229,11 @@ pub fn unguarded_pat(a: &Arm) -> Option<Vec<Gc<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 = pprust::ty_to_str(ty);
+    let mut pretty = pprust::ty_to_string(ty);
     match *trait_ref {
         Some(ref trait_ref) => {
             pretty.push_char('.');
-            pretty.push_str(pprust::path_to_str(&trait_ref.path).as_slice());
+            pretty.push_str(pprust::path_to_string(&trait_ref.path).as_slice());
         }
         None => {}
     }
index a037c0ac07e0e14864a0612ac902c60ec8208f6a..3b2ee4e2a6134a02c32aa27fb98991e834fc3296 100644 (file)
@@ -18,7 +18,6 @@
 use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
 use parse::token::InternedString;
 use parse::token;
-use crateid::CrateId;
 
 use std::collections::HashSet;
 use std::collections::BitvSet;
@@ -271,11 +270,8 @@ pub fn sort_meta_items(items: &[Gc<MetaItem>]) -> Vec<Gc<MetaItem>> {
     }).collect()
 }
 
-pub fn find_crateid(attrs: &[Attribute]) -> Option<CrateId> {
-    match first_attr_value_str_by_name(attrs, "crate_id") {
-        None => None,
-        Some(id) => from_str::<CrateId>(id.get()),
-    }
+pub fn find_crate_name(attrs: &[Attribute]) -> Option<InternedString> {
+    first_attr_value_str_by_name(attrs, "crate_name")
 }
 
 #[deriving(PartialEq)]
index c917198e7d4714fa31ab8ac82bee0e3687f7daf8..b3adf1daf418ca84e72afc556c55e3be95255a00 100644 (file)
@@ -367,7 +367,7 @@ pub fn lookup_char_pos_adj(&self, pos: BytePos) -> LocWithOpt {
         }
     }
 
-    pub fn span_to_str(&self, sp: Span) -> String {
+    pub fn span_to_string(&self, sp: Span) -> String {
         if self.files.borrow().len() == 0 && sp == DUMMY_SP {
             return "no-location".to_string();
         }
@@ -687,7 +687,7 @@ fn t9() {
         // Test span_to_str for a span ending at the end of filemap
         let cm = init_code_map();
         let span = Span {lo: BytePos(12), hi: BytePos(23), expn_info: None};
-        let sstr =  cm.span_to_str(span);
+        let sstr =  cm.span_to_string(span);
 
         assert_eq!(sstr, "blork.rs:2:1: 2:12".to_string());
     }
index dfaa9fb5fcb09507f31144396946f7708b588c40..3805390776e8da9b4ec168743047c18fb78158c2 100644 (file)
@@ -269,7 +269,7 @@ fn print_diagnostic(dst: &mut EmitterWriter,
     }
 
     try!(print_maybe_styled(dst,
-                            format!("{}: ", lvl.to_str()).as_slice(),
+                            format!("{}: ", lvl.to_string()).as_slice(),
                             term::attr::ForegroundColor(lvl.color())));
     try!(print_maybe_styled(dst,
                             format!("{}\n", msg).as_slice(),
@@ -349,14 +349,14 @@ fn custom_emit(&mut self, cm: &codemap::CodeMap,
 fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan,
         msg: &str, lvl: Level, custom: bool) -> io::IoResult<()> {
     let sp = rsp.span();
-    let ss = cm.span_to_str(sp);
+    let ss = cm.span_to_string(sp);
     let lines = cm.span_to_lines(sp);
     if custom {
         // we want to tell compiletest/runtest to look at the last line of the
         // span (since `custom_highlight_lines` displays an arrow to the end of
         // 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);
+        let ses = cm.span_to_string(span_end);
         try!(print_diagnostic(dst, ses.as_slice(), lvl, msg));
         if rsp.is_full_span() {
             try!(custom_highlight_lines(dst, cm, sp, lvl, lines));
@@ -493,7 +493,7 @@ fn print_macro_backtrace(w: &mut EmitterWriter,
         let ss = ei.callee
                    .span
                    .as_ref()
-                   .map_or("".to_string(), |span| cm.span_to_str(*span));
+                   .map_or("".to_string(), |span| cm.span_to_string(*span));
         let (pre, post) = match ei.callee.format {
             codemap::MacroAttribute => ("#[", "]"),
             codemap::MacroBang => ("", "!")
@@ -502,7 +502,7 @@ fn print_macro_backtrace(w: &mut EmitterWriter,
                               format!("in expansion of {}{}{}", pre,
                                       ei.callee.name,
                                       post).as_slice()));
-        let ss = cm.span_to_str(ei.call_site);
+        let ss = cm.span_to_string(ei.call_site);
         try!(print_diagnostic(w, ss.as_slice(), Note, "expansion site"));
         try!(print_macro_backtrace(w, cm, ei.call_site));
     }
index f0494e181201375096c9e0417a84bce1ba43fb07..13738e658e9f97fd7edd5563cab06ec71cf1e8b6 100644 (file)
@@ -64,7 +64,7 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     'statement: loop {
         match state {
             Asm => {
-                let (s, style) = match expr_to_str(cx, p.parse_expr(),
+                let (s, style) = match expr_to_string(cx, p.parse_expr(),
                                                    "inline assembly must be a string literal.") {
                     Some((s, st)) => (s, st),
                     // let compilation continue
@@ -205,7 +205,7 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     // Append an input operand, with the form of ("0", expr)
     // that links to an output operand.
     for &(i, out) in read_write_operands.iter() {
-        inputs.push((token::intern_and_get_ident(i.to_str().as_slice()),
+        inputs.push((token::intern_and_get_ident(i.to_string().as_slice()),
                                                  out));
     }
 
index d2e69204d333cb5cb0374857bdf9c456a0d22492..a540b23551b534437a80684cc0d1df3e6762a758 100644 (file)
@@ -19,6 +19,7 @@
 use parse::token;
 use parse::token::{InternedString, intern, str_to_ident};
 use util::small_vector::SmallVector;
+use ext::mtwt;
 
 use std::collections::HashMap;
 use std::gc::{Gc, GC};
@@ -273,7 +274,7 @@ pub struct BlockInfo {
     // should macros escape from this scope?
     pub macros_escape: bool,
     // what are the pending renames?
-    pub pending_renames: RenameList,
+    pub pending_renames: mtwt::RenameList,
 }
 
 impl BlockInfo {
@@ -285,9 +286,6 @@ pub fn new() -> BlockInfo {
     }
 }
 
-// a list of ident->name renamings
-pub type RenameList = Vec<(ast::Ident, Name)>;
-
 // The base map of methods for expanding syntax extension
 // AST nodes into full ASTs
 pub fn syntax_expander_table() -> SyntaxEnv {
@@ -454,7 +452,7 @@ pub fn backtrace(&self) -> Option<Gc<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.as_slice()));
+        v.push(token::str_to_ident(self.ecfg.crate_name.as_slice()));
         v.extend(self.mod_path.iter().map(|a| *a));
         return v;
     }
@@ -535,7 +533,7 @@ pub fn ident_of(&self, st: &str) -> ast::Ident {
 /// Extract a string literal from the macro expanded version of `expr`,
 /// emitting `err_msg` if `expr` is not a string literal. This does not stop
 /// compilation on error, merely emits a non-fatal error and returns None.
-pub fn expr_to_str(cx: &mut ExtCtxt, expr: Gc<ast::Expr>, err_msg: &str)
+pub fn expr_to_string(cx: &mut ExtCtxt, expr: Gc<ast::Expr>, err_msg: &str)
                    -> Option<(InternedString, ast::StrStyle)> {
     // we want to be able to handle e.g. concat("foo", "bar")
     let expr = cx.expand_expr(expr);
index 46bc4ec11ce4f044ac14b35d1f603042558bf089..4d79ff3257a9a20cd3b58cd5e330ff923a019e97 100644 (file)
@@ -66,8 +66,8 @@ fn ty_rptr(&self, span: Span,
     fn typaram(&self,
                span: Span,
                id: ast::Ident,
-               sized: ast::Sized,
                bounds: OwnedSlice<ast::TyParamBound>,
+               unbound: Option<ast::TyParamBound>,
                default: Option<P<ast::Ty>>) -> ast::TyParam;
 
     fn trait_ref(&self, path: ast::Path) -> ast::TraitRef;
@@ -396,14 +396,14 @@ fn ty_nil(&self) -> P<ast::Ty> {
     fn typaram(&self,
                span: Span,
                id: ast::Ident,
-               sized: ast::Sized,
                bounds: OwnedSlice<ast::TyParamBound>,
+               unbound: Option<ast::TyParamBound>,
                default: Option<P<ast::Ty>>) -> ast::TyParam {
         ast::TyParam {
             ident: id,
             id: ast::DUMMY_NODE_ID,
-            sized: sized,
             bounds: bounds,
+            unbound: unbound,
             default: default,
             span: span
         }
@@ -423,7 +423,7 @@ fn ty_vars_global(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>
 
     fn strip_bounds(&self, generics: &Generics) -> Generics {
         let new_params = generics.ty_params.map(|ty_param| {
-            ast::TyParam { bounds: OwnedSlice::empty(), ..*ty_param }
+            ast::TyParam { bounds: OwnedSlice::empty(), unbound: None, ..*ty_param }
         });
         Generics {
             ty_params: new_params,
index 0c23d65fde046e788da842b10c50008c0160d1b1..6da5f1e2700f1a969c5cb962f22a06697171dea9 100644 (file)
@@ -13,7 +13,6 @@
 encodable.rs for more.
 */
 
-use ast;
 use ast::{MetaItem, Item, Expr, MutMutable, Ident};
 use codemap::Span;
 use ext::base::ExtCtxt;
@@ -39,10 +38,10 @@ pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
         additional_bounds: Vec::new(),
         generics: LifetimeBounds {
             lifetimes: Vec::new(),
-            bounds: vec!(("__D", ast::StaticSize, vec!(Path::new_(
+            bounds: vec!(("__D", None, vec!(Path::new_(
                             vec!("serialize", "Decoder"), None,
                             vec!(box Literal(Path::new_local("__E"))), true))),
-                         ("__E", ast::StaticSize, vec!()))
+                         ("__E", None, vec!()))
         },
         methods: vec!(
             MethodDef {
index f57670af1999b3c90be860f84f67907ba012f91a..652d593c0042ca97d973fafa124646403755bc19 100644 (file)
@@ -82,7 +82,6 @@ fn decode(d: &D) -> spanned<T> {
 ```
 */
 
-use ast;
 use ast::{MetaItem, Item, Expr, ExprRet, MutMutable, LitNil};
 use codemap::Span;
 use ext::base::ExtCtxt;
@@ -107,10 +106,10 @@ pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
         additional_bounds: Vec::new(),
         generics: LifetimeBounds {
             lifetimes: Vec::new(),
-            bounds: vec!(("__S", ast::StaticSize, vec!(Path::new_(
+            bounds: vec!(("__S", None, vec!(Path::new_(
                             vec!("serialize", "Encoder"), None,
                             vec!(box Literal(Path::new_local("__E"))), true))),
-                         ("__E", ast::StaticSize, vec!()))
+                         ("__E", None, vec!()))
         },
         methods: vec!(
             MethodDef {
index 157b64fb47c0a7fa3d699681bb0d223d7a718f46..7ad11b186f5004a3f0891983d79d0b87ff6fe003 100644 (file)
@@ -406,8 +406,8 @@ fn create_derived_impl(&self,
 
             cx.typaram(self.span,
                        ty_param.ident,
-                       ty_param.sized,
                        OwnedSlice::from_vec(bounds),
+                       ty_param.unbound.clone(),
                        None)
         }));
         let trait_generics = Generics {
index 7501b950770c2e0c96f603d7d536a612792265c3..28f39a4cb8c0fd470cf5b31ebd613a9dad6eb262 100644 (file)
@@ -188,17 +188,18 @@ pub fn to_path(&self,
 }
 
 
-fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str, sized: ast::Sized, bounds: &[Path],
+fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str,
+               bounds: &[Path], unbound: Option<ast::TyParamBound>,
                self_ident: Ident, self_generics: &Generics) -> ast::TyParam {
     let bounds =
         bounds.iter().map(|b| {
             let path = b.to_path(cx, span, self_ident, self_generics);
             cx.typarambound(path)
         }).collect();
-    cx.typaram(span, cx.ident_of(name), sized, bounds, None)
+    cx.typaram(span, cx.ident_of(name), bounds, unbound, None)
 }
 
-fn mk_generics(lifetimes: Vec<ast::Lifetime> ,  ty_params: Vec<ast::TyParam> ) -> Generics {
+fn mk_generics(lifetimes: Vec<ast::Lifetime>, ty_params: Vec<ast::TyParam> ) -> Generics {
     Generics {
         lifetimes: lifetimes,
         ty_params: OwnedSlice::from_vec(ty_params)
@@ -208,7 +209,7 @@ fn mk_generics(lifetimes: Vec<ast::Lifetime> ,  ty_params: Vec<ast::TyParam> ) -
 /// Lifetimes and bounds on type parameters
 pub struct LifetimeBounds<'a> {
     pub lifetimes: Vec<&'a str>,
-    pub bounds: Vec<(&'a str, ast::Sized, Vec<Path<'a>>)>,
+    pub bounds: Vec<(&'a str, Option<ast::TyParamBound>, Vec<Path<'a>>)>,
 }
 
 impl<'a> LifetimeBounds<'a> {
@@ -228,12 +229,12 @@ pub fn to_generics(&self,
         }).collect();
         let ty_params = self.bounds.iter().map(|t| {
             match t {
-                &(ref name, sized, ref bounds) => {
+                &(ref name, ref unbound, ref bounds) => {
                     mk_ty_param(cx,
                                 span,
                                 *name,
-                                sized,
                                 bounds.as_slice(),
+                                unbound.clone(),
                                 self_ty,
                                 self_generics)
                 }
index 77fb013b269a222331a368e933bdedbb83e2946b..1b3ac47092a2d2e4dde17efc74a904ff3af74774 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use ast;
 use ast::{MetaItem, Item, Expr, MutMutable};
 use codemap::Span;
 use ext::base::ExtCtxt;
@@ -30,7 +29,7 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt,
                     vec!(box Literal(Path::new_local("__S"))), true),
          LifetimeBounds {
              lifetimes: Vec::new(),
-             bounds: vec!(("__S", ast::StaticSize,
+             bounds: vec!(("__S", None,
                            vec!(Path::new(vec!("std", "hash", "Writer"))))),
          },
          Path::new_local("__S"))
index f6a15ea917e187c74910ce9563da32f02e07e655..34b5f120d6ab8a62c4e094b30da52323b0960eba 100644 (file)
@@ -35,7 +35,7 @@ pub fn expand_deriving_rand(cx: &mut ExtCtxt,
                 generics: LifetimeBounds {
                     lifetimes: Vec::new(),
                     bounds: vec!(("R",
-                                  ast::StaticSize,
+                                  None,
                                   vec!( Path::new(vec!("std", "rand", "Rng")) )))
                 },
                 explicit_self: None,
index 9ef7241ca24842ed38292aa1b3c27f7a563b1c85..b24cfb85794edcf2c5754f128f933243429e12d6 100644 (file)
@@ -70,7 +70,7 @@ pub fn expand_env(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
         Some(exprs) => exprs
     };
 
-    let var = match expr_to_str(cx,
+    let var = match expr_to_string(cx,
                                 *exprs.get(0),
                                 "expected string literal") {
         None => return DummyResult::expr(sp),
@@ -83,7 +83,7 @@ pub fn expand_env(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                                                 var).as_slice())
         }
         2 => {
-            match expr_to_str(cx, *exprs.get(1), "expected string literal") {
+            match expr_to_string(cx, *exprs.get(1), "expected string literal") {
                 None => return DummyResult::expr(sp),
                 Some((s, _style)) => s
             }
index c3413293e52ae4b1ac664de13b7246ccffdd5070..74cede2a125add771ed548a336517dc45d83e104 100644 (file)
@@ -19,8 +19,8 @@
 use attr::AttrMetaMethods;
 use codemap;
 use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
-use crateid::CrateId;
 use ext::base::*;
+use fold;
 use fold::*;
 use parse;
 use parse::token::{fresh_mark, fresh_name, intern};
@@ -228,6 +228,20 @@ pub fn expand_expr(e: Gc<ast::Expr>, fld: &mut MacroExpander) -> Gc<ast::Expr> {
             fld.cx.expr(e.span, ast::ExprLoop(loop_block, opt_ident))
         }
 
+        ast::ExprFnBlock(fn_decl, block) => {
+            let (rewritten_fn_decl, rewritten_block)
+                = expand_and_rename_fn_decl_and_block(fn_decl, block, fld);
+            let new_node = ast::ExprFnBlock(rewritten_fn_decl, rewritten_block);
+            box(GC) ast::Expr{id:e.id, node: new_node, span: fld.new_span(e.span)}
+        }
+
+        ast::ExprProc(fn_decl, block) => {
+            let (rewritten_fn_decl, rewritten_block)
+                = expand_and_rename_fn_decl_and_block(fn_decl, block, fld);
+            let new_node = ast::ExprProc(rewritten_fn_decl, rewritten_block);
+            box(GC) ast::Expr{id:e.id, node: new_node, span: fld.new_span(e.span)}
+        }
+
         _ => noop_fold_expr(e, fld)
     }
 }
@@ -267,7 +281,8 @@ fn expand_loop_block(loop_block: P<Block>,
     }
 }
 
-// eval $e with a new exts frame:
+// eval $e with a new exts frame.
+// must be a macro so that $e isn't evaluated too early.
 macro_rules! with_exts_frame (
     ($extsboxexpr:expr,$macros_escape:expr,$e:expr) =>
     ({$extsboxexpr.push_frame();
@@ -342,15 +357,16 @@ fn expand_item(it: Gc<ast::Item>, fld: &mut MacroExpander)
 
 fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander)
                          -> Gc<ast::Item> {
-    let (modifiers, attrs) = it.attrs.partitioned(|attr| {
+    // partition the attributes into ItemModifiers and others
+    let (modifiers, other_attrs) = it.attrs.partitioned(|attr| {
         match fld.extsbox.find(&intern(attr.name().get())) {
             Some(&ItemModifier(_)) => true,
             _ => false
         }
     });
-
+    // update the attrs, leave everything else alone. Is this mutation really a good idea?
     it = box(GC) ast::Item {
-        attrs: attrs,
+        attrs: other_attrs,
         ..(*it).clone()
     };
 
@@ -383,6 +399,19 @@ fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander)
     expand_item_modifiers(it, fld)
 }
 
+/// Expand item_underscore
+fn expand_item_underscore(item: &ast::Item_, fld: &mut MacroExpander) -> ast::Item_ {
+    match *item {
+        ast::ItemFn(decl, fn_style, abi, ref generics, body) => {
+            let (rewritten_fn_decl, rewritten_body)
+                = expand_and_rename_fn_decl_and_block(decl,body,fld);
+            let expanded_generics = fold::fold_generics(generics,fld);
+            ast::ItemFn(rewritten_fn_decl, fn_style, abi, expanded_generics, rewritten_body)
+        }
+        _ => noop_fold_item_underscore(&*item, fld)
+    }
+}
+
 // does this attribute list contain "macro_escape" ?
 fn contains_macro_escape(attrs: &[ast::Attribute]) -> bool {
     attr::contains_name(attrs, "macro_escape")
@@ -609,7 +638,7 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
                     } = **local;
                     // expand the pat (it might contain macro uses):
                     let expanded_pat = fld.fold_pat(pat);
-                    // find the pat_idents in the pattern:
+                    // find the PatIdents in the pattern:
                     // oh dear heaven... this is going to include the enum
                     // names, as well... but that should be okay, as long as
                     // the new names are gensyms for the old ones.
@@ -653,6 +682,7 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
     }
 }
 
+// expand the arm of a 'match', renaming for macro hygiene
 fn expand_arm(arm: &ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
     // expand pats... they might contain macro uses:
     let expanded_pats : Vec<Gc<ast::Pat>> = arm.pats.iter().map(|pat| fld.fold_pat(*pat)).collect();
@@ -662,22 +692,15 @@ fn expand_arm(arm: &ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
     // all of the pats must have the same set of bindings, so use the
     // first one to extract them and generate new names:
     let first_pat = expanded_pats.get(0);
-    // code duplicated from 'let', above. Perhaps this can be lifted
-    // into a separate function:
     let idents = pattern_bindings(*first_pat);
-    let mut new_pending_renames =
+    let new_renames =
         idents.iter().map(|id| (*id,fresh_name(id))).collect();
-    // rewrite all of the patterns using the new names (the old
-    // ones have already been applied). Note that we depend here
-    // on the guarantee that after expansion, there can't be any
-    // Path expressions (a.k.a. varrefs) left in the pattern. If
-    // this were false, we'd need to apply this renaming only to
-    // the bindings, and not to the varrefs, using a more targeted
-    // fold-er.
-    let mut rename_fld = IdentRenamer{renames:&mut new_pending_renames};
+    // apply the renaming, but only to the PatIdents:
+    let mut rename_pats_fld = PatIdentRenamer{renames:&new_renames};
     let rewritten_pats =
-        expanded_pats.iter().map(|pat| rename_fld.fold_pat(*pat)).collect();
+        expanded_pats.iter().map(|pat| rename_pats_fld.fold_pat(*pat)).collect();
     // apply renaming and then expansion to the guard and the body:
+    let mut rename_fld = IdentRenamer{renames:&new_renames};
     let rewritten_guard =
         arm.guard.map(|g| fld.fold_expr(rename_fld.fold_expr(g)));
     let rewritten_body = fld.fold_expr(rename_fld.fold_expr(arm.body));
@@ -689,45 +712,47 @@ fn expand_arm(arm: &ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
     }
 }
 
-
-
-// a visitor that extracts the pat_ident (binding) paths
-// from a given thingy and puts them in a mutable
-// array
+/// A visitor that extracts the PatIdent (binding) paths
+/// from a given thingy and puts them in a mutable
+/// array
 #[deriving(Clone)]
-struct NameFinderContext {
+struct PatIdentFinder {
     ident_accumulator: Vec<ast::Ident> ,
 }
 
-impl Visitor<()> for NameFinderContext {
+impl Visitor<()> for PatIdentFinder {
     fn visit_pat(&mut self, pattern: &ast::Pat, _: ()) {
         match *pattern {
-            // we found a pat_ident!
-            ast::Pat {
-                id: _,
-                node: ast::PatIdent(_, ref path1, ref inner),
-                span: _
-            } => {
+            ast::Pat { id: _, node: ast::PatIdent(_, ref path1, ref inner), span: _ } => {
                 self.ident_accumulator.push(path1.node);
-                // visit optional subpattern of pat_ident:
+                // visit optional subpattern of PatIdent:
                 for subpat in inner.iter() {
                     self.visit_pat(&**subpat, ())
                 }
             }
-            // use the default traversal for non-pat_idents
+            // use the default traversal for non-PatIdents
             _ => visit::walk_pat(self, pattern, ())
         }
     }
 
 }
 
-// find the pat_ident paths in a pattern
+/// find the PatIdent paths in a pattern
 fn pattern_bindings(pat : &ast::Pat) -> Vec<ast::Ident> {
-    let mut name_finder = NameFinderContext{ident_accumulator:Vec::new()};
+    let mut name_finder = PatIdentFinder{ident_accumulator:Vec::new()};
     name_finder.visit_pat(pat,());
     name_finder.ident_accumulator
 }
 
+/// find the PatIdent paths in a
+fn fn_decl_arg_bindings(fn_decl: &ast::FnDecl) -> Vec<ast::Ident> {
+    let mut pat_idents = PatIdentFinder{ident_accumulator:Vec::new()};
+    for arg in fn_decl.inputs.iter() {
+        pat_idents.visit_pat(arg.pat,());
+    }
+    pat_idents.ident_accumulator
+}
+
 // expand a block. pushes a new exts_frame, then calls expand_block_elts
 fn expand_block(blk: &Block, fld: &mut MacroExpander) -> P<Block> {
     // see note below about treatment of exts table
@@ -844,34 +869,71 @@ fn expand_pat(p: Gc<ast::Pat>, fld: &mut MacroExpander) -> Gc<ast::Pat> {
     }
 }
 
-// a tree-folder that applies every rename in its (mutable) list
-// to every identifier, including both bindings and varrefs
-// (and lots of things that will turn out to be neither)
+/// A tree-folder that applies every rename in its (mutable) list
+/// to every identifier, including both bindings and varrefs
+/// (and lots of things that will turn out to be neither)
 pub struct IdentRenamer<'a> {
-    renames: &'a mut RenameList,
+    renames: &'a mtwt::RenameList,
 }
 
 impl<'a> Folder for IdentRenamer<'a> {
     fn fold_ident(&mut self, id: Ident) -> Ident {
-        let new_ctxt = self.renames.iter().fold(id.ctxt, |ctxt, &(from, to)| {
-            mtwt::new_rename(from, to, ctxt)
-        });
         Ident {
             name: id.name,
-            ctxt: new_ctxt,
+            ctxt: mtwt::apply_renames(self.renames, id.ctxt),
         }
     }
 }
 
-fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
-    /* this discards information in the case of macro-defining macros */
-    Span {
-        lo: sp.lo,
-        hi: sp.hi,
-        expn_info: cx.backtrace(),
+/// A tree-folder that applies every rename in its list to
+/// the idents that are in PatIdent patterns. This is more narrowly
+/// focused than IdentRenamer, and is needed for FnDecl,
+/// where we want to rename the args but not the fn name or the generics etc.
+pub struct PatIdentRenamer<'a> {
+    renames: &'a mtwt::RenameList,
+}
+
+impl<'a> Folder for PatIdentRenamer<'a> {
+    fn fold_pat(&mut self, pat: Gc<ast::Pat>) -> Gc<ast::Pat> {
+        match pat.node {
+            ast::PatIdent(binding_mode, Spanned{span: ref sp, node: id}, ref sub) => {
+                let new_ident = Ident{name: id.name,
+                                      ctxt: mtwt::apply_renames(self.renames, id.ctxt)};
+                let new_node =
+                    ast::PatIdent(binding_mode,
+                                  Spanned{span: self.new_span(*sp), node: new_ident},
+                                  sub.map(|p| self.fold_pat(p)));
+                box(GC) ast::Pat {
+                    id: pat.id,
+                    span: self.new_span(pat.span),
+                    node: new_node,
+                }
+            },
+            _ => noop_fold_pat(pat, self)
+        }
     }
 }
 
+/// Given a fn_decl and a block and a MacroExpander, expand the fn_decl, then use the
+/// PatIdents in its arguments to perform renaming in the FnDecl and
+/// the block, returning both the new FnDecl and the new Block.
+fn expand_and_rename_fn_decl_and_block(fn_decl: &ast::FnDecl, block: Gc<ast::Block>,
+                                       fld: &mut MacroExpander)
+    -> (Gc<ast::FnDecl>, Gc<ast::Block>) {
+    let expanded_decl = fld.fold_fn_decl(fn_decl);
+    let idents = fn_decl_arg_bindings(expanded_decl);
+    let renames =
+        idents.iter().map(|id : &ast::Ident| (*id,fresh_name(id))).collect();
+    // first, a renamer for the PatIdents, for the fn_decl:
+    let mut rename_pat_fld = PatIdentRenamer{renames: &renames};
+    let rewritten_fn_decl = rename_pat_fld.fold_fn_decl(expanded_decl);
+    // now, a renamer for *all* idents, for the body:
+    let mut rename_fld = IdentRenamer{renames: &renames};
+    let rewritten_body = fld.fold_block(rename_fld.fold_block(block));
+    (rewritten_fn_decl,rewritten_body)
+}
+
+/// A tree-folder that performs macro expansion
 pub struct MacroExpander<'a, 'b> {
     pub extsbox: SyntaxEnv,
     pub cx: &'a mut ExtCtxt<'b>,
@@ -890,6 +952,10 @@ fn fold_item(&mut self, item: Gc<ast::Item>) -> SmallVector<Gc<ast::Item>> {
         expand_item(item, self)
     }
 
+    fn fold_item_underscore(&mut self, item: &ast::Item_) -> ast::Item_ {
+        expand_item_underscore(item, self)
+    }
+
     fn fold_stmt(&mut self, stmt: &ast::Stmt) -> SmallVector<Gc<ast::Stmt>> {
         expand_stmt(stmt, self)
     }
@@ -907,9 +973,18 @@ fn new_span(&mut self, span: Span) -> Span {
     }
 }
 
+fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
+    /* this discards information in the case of macro-defining macros */
+    Span {
+        lo: sp.lo,
+        hi: sp.hi,
+        expn_info: cx.backtrace(),
+    }
+}
+
 pub struct ExpansionConfig {
     pub deriving_hash_type_parameter: bool,
-    pub crate_id: CrateId,
+    pub crate_name: String,
 }
 
 pub struct ExportedMacros {
@@ -966,7 +1041,7 @@ impl Folder for Marker {
     fn fold_ident(&mut self, id: Ident) -> Ident {
         ast::Ident {
             name: id.name,
-            ctxt: mtwt::new_mark(self.mark, id.ctxt)
+            ctxt: mtwt::apply_mark(self.mark, id.ctxt)
         }
     }
     fn fold_mac(&mut self, m: &ast::Mac) -> ast::Mac {
@@ -974,7 +1049,7 @@ fn fold_mac(&mut self, m: &ast::Mac) -> ast::Mac {
             MacInvocTT(ref path, ref tts, ctxt) => {
                 MacInvocTT(self.fold_path(path),
                            fold_tts(tts.as_slice(), self),
-                           mtwt::new_mark(self.mark, ctxt))
+                           mtwt::apply_mark(self.mark, ctxt))
             }
         };
         Spanned {
@@ -1028,13 +1103,14 @@ fn original_span(cx: &ExtCtxt) -> Gc<codemap::ExpnInfo> {
 #[cfg(test)]
 mod test {
     use super::{pattern_bindings, expand_crate, contains_macro_escape};
-    use super::{NameFinderContext};
+    use super::{PatIdentFinder, IdentRenamer, PatIdentRenamer};
     use ast;
     use ast::{Attribute_, AttrOuter, MetaWord};
     use attr;
     use codemap;
     use codemap::Spanned;
     use ext::mtwt;
+    use fold::Folder;
     use parse;
     use parse::token;
     use util::parser_testing::{string_to_parser};
@@ -1072,7 +1148,24 @@ fn crate_varrefs(the_crate : &ast::Crate) -> Vec<ast::Path> {
         path_finder.path_accumulator
     }
 
+    /// A Visitor that extracts the identifiers from a thingy.
+    // as a side note, I'm starting to want to abstract over these....
+    struct IdentFinder{
+        ident_accumulator: Vec<ast::Ident>
+    }
+
+    impl Visitor<()> for IdentFinder {
+        fn visit_ident(&mut self, _: codemap::Span, id: ast::Ident, _: ()){
+            self.ident_accumulator.push(id);
+        }
+    }
 
+    /// Find the idents in a crate
+    fn crate_idents(the_crate: &ast::Crate) -> Vec<ast::Ident> {
+        let mut ident_finder = IdentFinder{ident_accumulator: Vec::new()};
+        visit::walk_crate(&mut ident_finder, the_crate, ());
+        ident_finder.ident_accumulator
+    }
 
     // these following tests are quite fragile, in that they don't test what
     // *kind* of failure occurs.
@@ -1090,7 +1183,7 @@ fn crate_varrefs(the_crate : &ast::Crate) -> Vec<ast::Path> {
         // should fail:
         let cfg = ::syntax::ext::expand::ExpansionConfig {
             deriving_hash_type_parameter: false,
-            crate_id: from_str("test").unwrap(),
+            crate_name: "test".to_string(),
         };
         expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
     }
@@ -1107,7 +1200,7 @@ fn crate_varrefs(the_crate : &ast::Crate) -> Vec<ast::Path> {
             Vec::new(), &sess);
         let cfg = ::syntax::ext::expand::ExpansionConfig {
             deriving_hash_type_parameter: false,
-            crate_id: from_str("test").unwrap(),
+            crate_name: "test".to_string(),
         };
         expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
     }
@@ -1123,7 +1216,7 @@ fn crate_varrefs(the_crate : &ast::Crate) -> Vec<ast::Path> {
             Vec::new(), &sess);
         let cfg = ::syntax::ext::expand::ExpansionConfig {
             deriving_hash_type_parameter: false,
-            crate_id: from_str("test").unwrap(),
+            crate_name: "test".to_string(),
         };
         expand_crate(&sess, cfg, vec!(), vec!(), crate_ast);
     }
@@ -1160,19 +1253,18 @@ fn expand_crate_str(crate_str: String) -> ast::Crate {
         // the cfg argument actually does matter, here...
         let cfg = ::syntax::ext::expand::ExpansionConfig {
             deriving_hash_type_parameter: false,
-            crate_id: from_str("test").unwrap(),
+            crate_name: "test".to_string(),
         };
         expand_crate(&ps,cfg,vec!(),vec!(),crate_ast)
     }
 
     // find the pat_ident paths in a crate
     fn crate_bindings(the_crate : &ast::Crate) -> Vec<ast::Ident> {
-        let mut name_finder = NameFinderContext{ident_accumulator:Vec::new()};
+        let mut name_finder = PatIdentFinder{ident_accumulator:Vec::new()};
         visit::walk_crate(&mut name_finder, the_crate, ());
         name_finder.ident_accumulator
     }
 
-
     //fn expand_and_resolve(crate_str: @str) -> ast::crate {
         //let expanded_ast = expand_crate_str(crate_str);
         // println!("expanded: {:?}\n",expanded_ast);
@@ -1180,7 +1272,7 @@ fn crate_bindings(the_crate : &ast::Crate) -> Vec<ast::Ident> {
     //}
     //fn expand_and_resolve_and_pretty_print (crate_str: @str) -> String {
         //let resolved_ast = expand_and_resolve(crate_str);
-        //pprust::to_str(&resolved_ast,fake_print_crate,get_ident_interner())
+        //pprust::to_string(&resolved_ast,fake_print_crate,get_ident_interner())
     //}
 
     #[test] fn macro_tokens_should_match(){
@@ -1298,18 +1390,37 @@ macro_rules! outer ( ($e:pat ) => (inner!($e)))
     // but *shouldn't* bind because it was inserted by a different macro....
     // can't write this test case until we have macro-generating macros.
 
-    // FIXME #9383 : lambda var hygiene
-    // interesting... can't even write this test, yet, because the name-finder
-    // only finds pattern vars. Time to upgrade test framework.
-    /*#[test]
-    fn issue_9383(){
+    // item fn hygiene
+    // expands to fn q(x_1:int){fn g(x_2:int){x_2 + x_1};}
+    #[test] fn issue_9383(){
         run_renaming_test(
-            &("macro_rules! bad_macro (($ex:expr) => ({(|_x| { $ex }) (9) }))
-              fn takes_x(_x : int) { assert_eq!(bad_macro!(_x),8); }
-              fn main() { takes_x(8); }",
-              vec!(vec!()),false),
+            &("macro_rules! bad_macro (($ex:expr) => (fn g(x:int){ x + $ex }))
+              fn q(x:int) { bad_macro!(x); }",
+              vec!(vec!(1),vec!(0)),true),
             0)
-    }*/
+    }
+
+    // closure arg hygiene (ExprFnBlock)
+    // expands to fn f(){(|x_1 : int| {(x_2 + x_1)})(3);}
+    #[test] fn closure_arg_hygiene(){
+        run_renaming_test(
+            &("macro_rules! inject_x (()=>(x))
+            fn f(){(|x : int| {(inject_x!() + x)})(3);}",
+              vec!(vec!(1)),
+              true),
+            0)
+    }
+
+    // closure arg hygiene (ExprProc)
+    // expands to fn f(){(proc(x_1 : int) {(x_2 + x_1)})(3);}
+    #[test] fn closure_arg_hygiene_2(){
+        run_renaming_test(
+            &("macro_rules! inject_x (()=>(x))
+              fn f(){ (proc(x : int){(inject_x!() + x)})(3); }",
+              vec!(vec!(1)),
+              true),
+            0)
+    }
 
     // run one of the renaming tests
     fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
@@ -1359,9 +1470,9 @@ fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
                         assert_eq!(varref_marks,binding_marks.clone());
                     }
                 } else {
+                    let varref_name = mtwt::resolve(varref.segments.get(0).identifier);
                     let fail = (varref.segments.len() == 1)
-                        && (mtwt::resolve(varref.segments.get(0).identifier)
-                            == binding_name);
+                        && (varref_name == binding_name);
                     // temp debugging:
                     if fail {
                         let varref_idents : Vec<ast::Ident>
@@ -1372,7 +1483,8 @@ fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
                         println!("text of test case: \"{}\"", teststr);
                         println!("");
                         println!("uh oh, matches but shouldn't:");
-                        println!("varref: {}",varref_idents);
+                        println!("varref #{}: {}, resolves to {}",idx, varref_idents,
+                                 varref_name);
                         // good lord, you can't make a path with 0 segments, can you?
                         let string = token::get_ident(varref.segments
                                                             .get(0)
@@ -1380,7 +1492,9 @@ fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
                         println!("varref's first segment's uint: {}, and string: \"{}\"",
                                  varref.segments.get(0).identifier.name,
                                  string.get());
-                        println!("binding: {}", *bindings.get(binding_idx));
+                        println!("binding #{}: {}, resolves to {}",
+                                 binding_idx, *bindings.get(binding_idx),
+                                 binding_name);
                         mtwt::with_sctable(|x| mtwt::display_sctable(x));
                     }
                     assert!(!fail);
@@ -1390,7 +1504,7 @@ fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
     }
 
     #[test] fn fmt_in_macro_used_inside_module_macro() {
-        let crate_str = "macro_rules! fmt_wrap(($b:expr)=>($b.to_str()))
+        let crate_str = "macro_rules! fmt_wrap(($b:expr)=>($b.to_string()))
 macro_rules! foo_module (() => (mod generated { fn a() { let xx = 147; fmt_wrap!(xx);}}))
 foo_module!()
 ".to_string();
@@ -1443,13 +1557,43 @@ fn pat_idents(){
     // 'None' is listed as an identifier pattern because we don't yet know that
     // it's the name of a 0-ary variant, and that 'i' appears twice in succession.
     #[test]
-    fn crate_idents(){
+    fn crate_bindings_test(){
         let the_crate = string_to_crate("fn main (a : int) -> int {|b| {
         match 34 {None => 3, Some(i) | i => j, Foo{k:z,l:y} => \"banana\"}} }".to_string());
         let idents = crate_bindings(&the_crate);
         assert_eq!(idents, strs_to_idents(vec!("a","b","None","i","i","z","y")));
     }
 
-    //
+    // test the IdentRenamer directly
+    #[test]
+    fn ident_renamer_test () {
+        let the_crate = string_to_crate("fn f(x : int){let x = x; x}".to_string());
+        let f_ident = token::str_to_ident("f");
+        let x_ident = token::str_to_ident("x");
+        let int_ident = token::str_to_ident("int");
+        let renames = vec!((x_ident,16));
+        let mut renamer = IdentRenamer{renames: &renames};
+        let renamed_crate = renamer.fold_crate(the_crate);
+        let idents = crate_idents(&renamed_crate);
+        let resolved : Vec<ast::Name> = idents.iter().map(|id| mtwt::resolve(*id)).collect();
+        assert_eq!(resolved,vec!(f_ident.name,16,int_ident.name,16,16,16));
+    }
+
+    // test the PatIdentRenamer; only PatIdents get renamed
+    #[test]
+    fn pat_ident_renamer_test () {
+        let the_crate = string_to_crate("fn f(x : int){let x = x; x}".to_string());
+        let f_ident = token::str_to_ident("f");
+        let x_ident = token::str_to_ident("x");
+        let int_ident = token::str_to_ident("int");
+        let renames = vec!((x_ident,16));
+        let mut renamer = PatIdentRenamer{renames: &renames};
+        let renamed_crate = renamer.fold_crate(the_crate);
+        let idents = crate_idents(&renamed_crate);
+        let resolved : Vec<ast::Name> = idents.iter().map(|id| mtwt::resolve(*id)).collect();
+        let x_name = x_ident.name;
+        assert_eq!(resolved,vec!(f_ident.name,16,int_ident.name,16,x_name,x_name));
+    }
+
 
 }
index f39e50ad1313f63501394e1a31da42b528c2a396..f486d2de3398bd564e6d787435d663d8d8422102 100644 (file)
@@ -126,7 +126,7 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool,
                 _ => {
                     ecx.span_err(p.span,
                                  format!("expected ident for named argument, but found `{}`",
-                                         p.this_token_to_str()).as_slice());
+                                         p.this_token_to_string()).as_slice());
                     return (invocation, None);
                 }
             };
@@ -690,7 +690,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
         fmtsp: sp,
     };
     cx.fmtsp = efmt.span;
-    let fmt = match expr_to_str(cx.ecx,
+    let fmt = match expr_to_string(cx.ecx,
                                 efmt,
                                 "format argument must be a string literal.") {
         Some((fmt, _)) => fmt,
index 486d060da77bedbefc596b6f70529a6cead6c517..1f4d087abd0fe1669513151ea3f88b3e1688ec5b 100644 (file)
@@ -21,7 +21,7 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
                          -> Box<base::MacResult> {
 
     cx.print_backtrace();
-    println!("{}", print::pprust::tt_to_str(&ast::TTDelim(
+    println!("{}", print::pprust::tt_to_string(&ast::TTDelim(
                 Rc::new(tt.iter().map(|x| (*x).clone()).collect()))));
 
     // any so that `log_syntax` can be invoked as an expression and item.
index 48895d34022c4c28b9459b2c1b23d48102730073..18466e381a58ba2d5d4baa0984037ae35da5ae60 100644 (file)
@@ -54,38 +54,51 @@ pub enum SyntaxContext_ {
     IllegalCtxt
 }
 
+/// A list of ident->name renamings
+pub type RenameList = Vec<(Ident, Name)>;
+
 /// Extend a syntax context with a given mark
-pub fn new_mark(m: Mrk, tail: SyntaxContext) -> SyntaxContext {
-    with_sctable(|table| new_mark_internal(m, tail, table))
+pub fn apply_mark(m: Mrk, ctxt: SyntaxContext) -> SyntaxContext {
+    with_sctable(|table| apply_mark_internal(m, ctxt, table))
 }
 
-// Extend a syntax context with a given mark and table
-fn new_mark_internal(m: Mrk, tail: SyntaxContext, table: &SCTable) -> SyntaxContext {
-    let key = (tail, m);
+// Extend a syntax context with a given mark and sctable (explicit memoization)
+fn apply_mark_internal(m: Mrk, ctxt: SyntaxContext, table: &SCTable) -> SyntaxContext {
+    let key = (ctxt, m);
     let new_ctxt = |_: &(SyntaxContext, Mrk)|
-                   idx_push(&mut *table.table.borrow_mut(), Mark(m, tail));
+                   idx_push(&mut *table.table.borrow_mut(), Mark(m, ctxt));
 
     *table.mark_memo.borrow_mut().find_or_insert_with(key, new_ctxt)
 }
 
 /// Extend a syntax context with a given rename
-pub fn new_rename(id: Ident, to:Name,
-                  tail: SyntaxContext) -> SyntaxContext {
-    with_sctable(|table| new_rename_internal(id, to, tail, table))
+pub fn apply_rename(id: Ident, to:Name,
+                  ctxt: SyntaxContext) -> SyntaxContext {
+    with_sctable(|table| apply_rename_internal(id, to, ctxt, table))
 }
 
-// Extend a syntax context with a given rename and sctable
-fn new_rename_internal(id: Ident,
+// Extend a syntax context with a given rename and sctable (explicit memoization)
+fn apply_rename_internal(id: Ident,
                        to: Name,
-                       tail: SyntaxContext,
+                       ctxt: SyntaxContext,
                        table: &SCTable) -> SyntaxContext {
-    let key = (tail,id,to);
+    let key = (ctxt,id,to);
     let new_ctxt = |_: &(SyntaxContext, Ident, Mrk)|
-                   idx_push(&mut *table.table.borrow_mut(), Rename(id, to, tail));
+                   idx_push(&mut *table.table.borrow_mut(), Rename(id, to, ctxt));
 
     *table.rename_memo.borrow_mut().find_or_insert_with(key, new_ctxt)
 }
 
+/// Apply a list of renamings to a context
+// if these rename lists get long, it would make sense
+// to consider memoizing this fold. This may come up
+// when we add hygiene to item names.
+pub fn apply_renames(renames: &RenameList, ctxt: SyntaxContext) -> SyntaxContext {
+    renames.iter().fold(ctxt, |ctxt, &(from, to)| {
+        apply_rename(from, to, ctxt)
+    })
+}
+
 /// Fetch the SCTable from TLS, create one if it doesn't yet exist.
 pub fn with_sctable<T>(op: |&SCTable| -> T) -> T {
     local_data_key!(sctable_key: Rc<SCTable>)
@@ -263,9 +276,9 @@ fn xor_push(marks: &mut Vec<Mrk>, mark: Mrk) {
 
 #[cfg(test)]
 mod tests {
-    use ast::*;
-    use super::{resolve, xor_push, new_mark_internal, new_sctable_internal};
-    use super::{new_rename_internal, marksof_internal, resolve_internal};
+    use ast::{EMPTY_CTXT, Ident, Mrk, Name, SyntaxContext};
+    use super::{resolve, xor_push, apply_mark_internal, new_sctable_internal};
+    use super::{apply_rename_internal, apply_renames, marksof_internal, resolve_internal};
     use super::{SCTable, EmptyCtxt, Mark, Rename, IllegalCtxt};
     use std::collections::HashMap;
 
@@ -306,8 +319,8 @@ fn unfold_test_sc(tscs : Vec<TestSC> , tail: SyntaxContext, table: &SCTable)
         -> SyntaxContext {
         tscs.iter().rev().fold(tail, |tail : SyntaxContext, tsc : &TestSC|
                   {match *tsc {
-                      M(mrk) => new_mark_internal(mrk,tail,table),
-                      R(ident,name) => new_rename_internal(ident,name,tail,table)}})
+                      M(mrk) => apply_mark_internal(mrk,tail,table),
+                      R(ident,name) => apply_rename_internal(ident,name,tail,table)}})
     }
 
     // gather a SyntaxContext back into a vector of TestSCs
@@ -352,7 +365,7 @@ fn test_unfold_refold(){
     fn unfold_marks(mrks: Vec<Mrk> , tail: SyntaxContext, table: &SCTable)
                     -> SyntaxContext {
         mrks.iter().rev().fold(tail, |tail:SyntaxContext, mrk:&Mrk|
-                   {new_mark_internal(*mrk,tail,table)})
+                   {apply_mark_internal(*mrk,tail,table)})
     }
 
     #[test] fn unfold_marks_test() {
@@ -384,13 +397,13 @@ fn test_marksof () {
         // rename where stop doesn't match:
         { let chain = vec!(M(9),
                         R(id(name1,
-                             new_mark_internal (4, EMPTY_CTXT,&mut t)),
+                             apply_mark_internal (4, EMPTY_CTXT,&mut t)),
                           100101102),
                         M(14));
          let ans = unfold_test_sc(chain,EMPTY_CTXT,&mut t);
          assert_eq! (marksof_internal (ans, stopname, &t), vec!(9,14));}
         // rename where stop does match
-        { let name1sc = new_mark_internal(4, EMPTY_CTXT, &mut t);
+        { let name1sc = apply_mark_internal(4, EMPTY_CTXT, &mut t);
          let chain = vec!(M(9),
                        R(id(name1, name1sc),
                          stopname),
@@ -414,7 +427,7 @@ fn resolve_tests () {
         { let sc = unfold_test_sc(vec!(R(id(50,EMPTY_CTXT),51),M(12)),EMPTY_CTXT,&mut t);
          assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt),a);}
         // - rename where names do match, but marks don't
-        { let sc1 = new_mark_internal(1,EMPTY_CTXT,&mut t);
+        { let sc1 = apply_mark_internal(1,EMPTY_CTXT,&mut t);
          let sc = unfold_test_sc(vec!(R(id(a,sc1),50),
                                    M(1),
                                    M(2)),
@@ -437,11 +450,11 @@ fn resolve_tests () {
                                   EMPTY_CTXT,&mut t);
          assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt), 51); }
         // the simplest double-rename:
-        { let a_to_a50 = new_rename_internal(id(a,EMPTY_CTXT),50,EMPTY_CTXT,&mut t);
-         let a50_to_a51 = new_rename_internal(id(a,a_to_a50),51,a_to_a50,&mut t);
+        { let a_to_a50 = apply_rename_internal(id(a,EMPTY_CTXT),50,EMPTY_CTXT,&mut t);
+         let a50_to_a51 = apply_rename_internal(id(a,a_to_a50),51,a_to_a50,&mut t);
          assert_eq!(resolve_internal(id(a,a50_to_a51),&mut t, &mut rt),51);
          // mark on the outside doesn't stop rename:
-         let sc = new_mark_internal(9,a50_to_a51,&mut t);
+         let sc = apply_mark_internal(9,a50_to_a51,&mut t);
          assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt),51);
          // but mark on the inside does:
          let a50_to_a51_b = unfold_test_sc(vec!(R(id(a,a_to_a50),51),
@@ -461,10 +474,10 @@ fn mtwt_resolve_test(){
     #[test]
     fn hashing_tests () {
         let mut t = new_sctable_internal();
-        assert_eq!(new_mark_internal(12,EMPTY_CTXT,&mut t),2);
-        assert_eq!(new_mark_internal(13,EMPTY_CTXT,&mut t),3);
+        assert_eq!(apply_mark_internal(12,EMPTY_CTXT,&mut t),2);
+        assert_eq!(apply_mark_internal(13,EMPTY_CTXT,&mut t),3);
         // using the same one again should result in the same index:
-        assert_eq!(new_mark_internal(12,EMPTY_CTXT,&mut t),2);
+        assert_eq!(apply_mark_internal(12,EMPTY_CTXT,&mut t),2);
         // I'm assuming that the rename table will behave the same....
     }
 
@@ -480,4 +493,13 @@ fn resolve_table_hashing_tests() {
         resolve_internal(id(30,EMPTY_CTXT),&mut t, &mut rt);
         assert_eq!(rt.len(),2);
     }
+
+    #[test]
+    fn new_resolves_test() {
+        let renames = vec!((Ident{name:23,ctxt:EMPTY_CTXT},24),
+                           (Ident{name:29,ctxt:EMPTY_CTXT},29));
+        let new_ctxt1 = apply_renames(&renames,EMPTY_CTXT);
+        assert_eq!(resolve(Ident{name:23,ctxt:new_ctxt1}),24);
+        assert_eq!(resolve(Ident{name:29,ctxt:new_ctxt1}),29);
+    }
 }
index 7b24b97d5da4dd6be7557657bb8019f0ba816103..a3c901904a9484d940b856e4a086b2b59141b3f9 100644 (file)
@@ -128,13 +128,13 @@ fn to_source(&self) -> String {
         }
     }
 
-    impl_to_source!(ast::Ty, ty_to_str)
-    impl_to_source!(ast::Block, block_to_str)
-    impl_to_source!(ast::Arg, arg_to_str)
-    impl_to_source!(Generics, generics_to_str)
-    impl_to_source!(Gc<ast::Item>, item_to_str)
-    impl_to_source!(Gc<ast::Expr>, expr_to_str)
-    impl_to_source!(Gc<ast::Pat>, pat_to_str)
+    impl_to_source!(ast::Ty, ty_to_string)
+    impl_to_source!(ast::Block, block_to_string)
+    impl_to_source!(ast::Arg, arg_to_string)
+    impl_to_source!(Generics, generics_to_string)
+    impl_to_source!(Gc<ast::Item>, item_to_string)
+    impl_to_source!(Gc<ast::Expr>, expr_to_string)
+    impl_to_source!(Gc<ast::Pat>, pat_to_string)
     impl_to_source_slice!(ast::Ty, ", ")
     impl_to_source_slice!(Gc<ast::Item>, "\n\n")
 
@@ -142,7 +142,7 @@ impl<'a> ToSource for &'a str {
         fn to_source(&self) -> String {
             let lit = dummy_spanned(ast::LitStr(
                     token::intern_and_get_ident(*self), ast::CookedStr));
-            pprust::lit_to_str(&lit)
+            pprust::lit_to_string(&lit)
         }
     }
 
@@ -155,14 +155,14 @@ fn to_source(&self) -> String {
     impl ToSource for bool {
         fn to_source(&self) -> String {
             let lit = dummy_spanned(ast::LitBool(*self));
-            pprust::lit_to_str(&lit)
+            pprust::lit_to_string(&lit)
         }
     }
 
     impl ToSource for char {
         fn to_source(&self) -> String {
             let lit = dummy_spanned(ast::LitChar(*self));
-            pprust::lit_to_str(&lit)
+            pprust::lit_to_string(&lit)
         }
     }
 
@@ -171,7 +171,7 @@ macro_rules! impl_to_source_int(
             impl ToSource for $t {
                 fn to_source(&self) -> String {
                     let lit = dummy_spanned(ast::LitInt(*self as i64, ast::$tag));
-                    pprust::lit_to_str(&lit)
+                    pprust::lit_to_string(&lit)
                 }
             }
         );
@@ -179,7 +179,7 @@ fn to_source(&self) -> String {
             impl ToSource for $t {
                 fn to_source(&self) -> String {
                     let lit = dummy_spanned(ast::LitUint(*self as u64, ast::$tag));
-                    pprust::lit_to_str(&lit)
+                    pprust::lit_to_string(&lit)
                 }
             }
         );
index 915fc16c15660a05368690c7e770dc05a0bcb81c..8922f423aad31e493fae828cdee470fbcaf0d2d9 100644 (file)
@@ -64,7 +64,7 @@ pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
 
 pub fn expand_stringify(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                         -> Box<base::MacResult> {
-    let s = pprust::tts_to_str(tts);
+    let s = pprust::tts_to_string(tts);
     base::MacExpr::new(cx.expr_str(sp,
                                    token::intern_and_get_ident(s.as_slice())))
 }
@@ -126,7 +126,7 @@ 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_string();
             let interned = token::intern_and_get_ident(src);
             cx.codemap().new_filemap(filename, src.to_string());
 
index 86fbc8cec2a347f9f4108196fab5a4b3a5201d40..913e0427bda221ee3e25bc3540eb0f1f9ea47515 100644 (file)
@@ -395,7 +395,7 @@ pub fn parse(sess: &ParseSess,
                     nts, next_eis.len()).to_string());
             } else if bb_eis.len() == 0u && next_eis.len() == 0u {
                 return Failure(sp, format!("no rules expected the token `{}`",
-                            token::to_str(&tok)).to_string());
+                            token::to_string(&tok)).to_string());
             } else if next_eis.len() > 0u {
                 /* Now process the next token */
                 while next_eis.len() > 0u {
@@ -442,7 +442,7 @@ pub fn parse_nt(p: &mut Parser, name: &str) -> Nonterminal {
       "ident" => match p.token {
         token::IDENT(sn,b) => { p.bump(); token::NtIdent(box sn,b) }
         _ => {
-            let token_str = token::to_str(&p.token);
+            let token_str = token::to_string(&p.token);
             p.fatal((format!("expected ident, found {}",
                              token_str.as_slice())).as_slice())
         }
index 72c578b87699c5b0f335ee3bad3395cc6e4fd818..2b481cb0596e7590e011aa0174007b5918df4ecb 100644 (file)
@@ -48,7 +48,7 @@ fn ensure_complete_parse(&self, allow_semi: bool) {
             parser.bump()
         }
         if parser.token != EOF {
-            let token_str = parser.this_token_to_str();
+            let token_str = parser.this_token_to_string();
             let msg = format!("macro expansion ignores token `{}` and any \
                                following",
                               token_str);
@@ -131,7 +131,7 @@ fn generic_extension(cx: &ExtCtxt,
         println!("{}! {} {} {}",
                  token::get_ident(name),
                  "{",
-                 print::pprust::tt_to_str(&TTDelim(Rc::new(arg.iter()
+                 print::pprust::tt_to_string(&TTDelim(Rc::new(arg.iter()
                                                               .map(|x| (*x).clone())
                                                               .collect()))),
                  "}");
@@ -254,7 +254,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_string(),
             ext: NormalTT(exp, Some(sp))
         }))
     } as Box<MacResult>
index f9d7078da3dcbe4377132259c3c5699ae66fca36..ee4810b4b54305ce9a624d130302ecd1fe02df0e 100644 (file)
@@ -491,8 +491,8 @@ pub fn fold_ty_param<T: Folder>(tp: &TyParam, fld: &mut T) -> TyParam {
     TyParam {
         ident: tp.ident,
         id: id,
-        sized: tp.sized,
         bounds: tp.bounds.map(|x| fold_ty_param_bound(x, fld)),
+        unbound: tp.unbound.as_ref().map(|x| fold_ty_param_bound(x, fld)),
         default: tp.default.map(|x| fld.fold_ty(x)),
         span: tp.span
     }
@@ -666,7 +666,7 @@ pub fn noop_fold_item_underscore<T: Folder>(i: &Item_, folder: &mut T) -> Item_
                      methods.iter().map(|x| folder.fold_method(*x)).collect()
             )
         }
-        ItemTrait(ref generics, ref sized, ref traits, ref methods) => {
+        ItemTrait(ref generics, ref unbound, ref traits, ref methods) => {
             let methods = methods.iter().map(|method| {
                 match *method {
                     Required(ref m) => Required(folder.fold_type_method(m)),
@@ -674,7 +674,7 @@ pub fn noop_fold_item_underscore<T: Folder>(i: &Item_, folder: &mut T) -> Item_
                 }
             }).collect();
             ItemTrait(fold_generics(generics, folder),
-                      *sized,
+                      unbound.clone(),
                       traits.iter().map(|p| fold_trait_ref(p, folder)).collect(),
                       methods)
         }
@@ -794,7 +794,7 @@ pub fn noop_fold_pat<T: Folder>(p: Gc<Pat>, folder: &mut T) -> Gc<Pat> {
         PatIdent(binding_mode, ref pth1, ref sub) => {
             PatIdent(binding_mode,
                      Spanned{span: folder.new_span(pth1.span),
-                                       node: folder.fold_ident(pth1.node)},
+                             node: folder.fold_ident(pth1.node)},
                      sub.map(|x| folder.fold_pat(x)))
         }
         PatLit(e) => PatLit(folder.fold_expr(e)),
@@ -1026,7 +1026,7 @@ macro_rules! assert_pred (
         assert_pred!(
             matches_codepattern,
             "matches_codepattern",
-            pprust::to_str(|s| fake_print_crate(s, &folded_crate)),
+            pprust::to_string(|s| fake_print_crate(s, &folded_crate)),
             "#[a]mod zz{fn zz(zz:zz,zz:zz){zz!(zz,zz,zz);zz;zz}}".to_string());
     }
 
@@ -1040,7 +1040,7 @@ macro_rules! assert_pred (
         assert_pred!(
             matches_codepattern,
             "matches_codepattern",
-            pprust::to_str(|s| fake_print_crate(s, &folded_crate)),
+            pprust::to_string(|s| fake_print_crate(s, &folded_crate)),
             "zz!zz((zz$zz:zz$(zz $zz:zz)zz+=>(zz$(zz$zz$zz)+)))".to_string());
     }
 }
index ce63d2bb7311acfece0c700fc8a478208822edbf..6df91c66a25e84f96c2fbac772d56d7888edcfaf 100644 (file)
@@ -18,7 +18,8 @@
 
 */
 
-#![crate_id = "syntax#0.11.0"]
+#![crate_id = "syntax#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "syntax"]
 #![experimental]
 #![license = "MIT/ASL2"]
 #![crate_type = "dylib"]
@@ -30,6 +31,7 @@
 #![feature(macro_rules, globs, managed_boxes, default_type_params, phase)]
 #![feature(quote, unsafe_destructor)]
 #![allow(deprecated)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 extern crate serialize;
 extern crate term;
index e47080dadfd72361dd5eb1cfc94b62e5b5b13736..53489e32837668c2231c936b2f81f3669dd0f396 100644 (file)
@@ -91,7 +91,7 @@ fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute {
                 (mk_sp(lo, hi), meta_item, style)
             }
             _ => {
-                let token_str = self.this_token_to_str();
+                let token_str = self.this_token_to_string();
                 self.fatal(format!("expected `#` but found `{}`",
                                    token_str).as_slice());
             }
index f00c1ab44551f63010491a027efe80d06ba6e840..73e5bb97f51d0a2b375bc25eccb03b68cacbcdfb 100644 (file)
@@ -369,7 +369,7 @@ pub fn gather_comments_and_literals(span_diagnostic: &diagnostic::SpanHandler,
                 literals.push(Literal {lit: s.to_string(), pos: sp.lo});
             })
         } else {
-            debug!("tok: {}", token::to_str(&tok));
+            debug!("tok: {}", token::to_string(&tok));
         }
         first_read = false;
     }
index 0f188fdf18a5a80c06ee94126b1ac47e16198674..1e72b2de20f732a024eec3d8fea49c0d845dfaf9 100644 (file)
@@ -849,6 +849,7 @@ fn next_token_inner(&mut self) -> token::Token {
           '@' => { self.bump(); return token::AT; }
           '#' => { self.bump(); return token::POUND; }
           '~' => { self.bump(); return token::TILDE; }
+          '?' => { self.bump(); return token::QUESTION; }
           ':' => {
             self.bump();
             if self.curr_is(':') {
index 4b5252bfba3118eb081d8a1783d18631a265b9bc..fb4a23cf326ec10b7beabc4b4f632b94f243f7f1 100644 (file)
@@ -278,11 +278,7 @@ pub fn maybe_aborted<T>(result: T, mut p: Parser) -> T {
 #[cfg(test)]
 mod test {
     use super::*;
-    use serialize::{json, Encodable};
-    use std::io;
-    use std::io::MemWriter;
-    use std::mem::transmute;
-    use std::str;
+    use serialize::json;
     use std::gc::GC;
     use codemap::{Span, BytePos, Spanned};
     use owned_slice::OwnedSlice;
@@ -296,16 +292,6 @@ 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) -> String {
-        let mut writer = MemWriter::new();
-        // FIXME(14302) remove the transmute and unsafe block.
-        unsafe {
-            let mut encoder = json::Encoder::new(&mut writer as &mut io::Writer);
-            let _ = val.encode(transmute(&mut encoder));
-        }
-        str::from_utf8(writer.unwrap().as_slice()).unwrap().to_string()
-    }
-
     // produce a codemap::span
     fn sp(a: u32, b: u32) -> Span {
         Span{lo:BytePos(a),hi:BytePos(b),expn_info:None}
@@ -415,7 +401,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_string());
-        assert_eq!(to_json_str(&tts),
+        assert_eq!(json::encode(&tts),
         "[\
     {\
         \"variant\":\"TTTok\",\
index f3789e25bc8a7e5e39bc1e1ded000561e43c4578..a3917e93197985fc34724947126a20c90350b181 100644 (file)
@@ -42,7 +42,6 @@
 use ast::{PatTup, PatBox, PatWild, PatWildMulti};
 use ast::{BiRem, Required};
 use ast::{RetStyle, Return, BiShl, BiShr, Stmt, StmtDecl};
-use ast::{Sized, DynSize, StaticSize};
 use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField};
 use ast::{StructVariantKind, BiSub};
 use ast::StrStyle;
@@ -363,24 +362,24 @@ pub fn new(sess: &'a ParseSess, cfg: ast::CrateConfig,
         }
     }
     // convert a token to a string using self's reader
-    pub fn token_to_str(token: &token::Token) -> String {
-        token::to_str(token)
+    pub fn token_to_string(token: &token::Token) -> String {
+        token::to_string(token)
     }
 
     // convert the current token to a string using self's reader
-    pub fn this_token_to_str(&mut self) -> String {
-        Parser::token_to_str(&self.token)
+    pub fn this_token_to_string(&mut self) -> String {
+        Parser::token_to_string(&self.token)
     }
 
     pub fn unexpected_last(&mut self, t: &token::Token) -> ! {
-        let token_str = Parser::token_to_str(t);
+        let token_str = Parser::token_to_string(t);
         let last_span = self.last_span;
         self.span_fatal(last_span, format!("unexpected token: `{}`",
                                                 token_str).as_slice());
     }
 
     pub fn unexpected(&mut self) -> ! {
-        let this_token = self.this_token_to_str();
+        let this_token = self.this_token_to_string();
         self.fatal(format!("unexpected token: `{}`", this_token).as_slice());
     }
 
@@ -390,8 +389,8 @@ pub fn expect(&mut self, t: &token::Token) {
         if self.token == *t {
             self.bump();
         } else {
-            let token_str = Parser::token_to_str(t);
-            let this_token_str = self.this_token_to_str();
+            let token_str = Parser::token_to_string(t);
+            let this_token_str = self.this_token_to_string();
             self.fatal(format!("expected `{}` but found `{}`",
                                token_str,
                                this_token_str).as_slice())
@@ -404,15 +403,15 @@ 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]) -> String {
+        fn tokens_to_string(tokens: &[token::Token]) -> String {
             let mut i = tokens.iter();
             // This might be a sign we need a connect method on Iterator.
             let b = i.next()
-                     .map_or("".to_string(), |t| Parser::token_to_str(t));
+                     .map_or("".to_string(), |t| Parser::token_to_string(t));
             i.fold(b, |b,a| {
                 let mut b = b;
                 b.push_str("`, `");
-                b.push_str(Parser::token_to_str(a).as_slice());
+                b.push_str(Parser::token_to_string(a).as_slice());
                 b
             })
         }
@@ -422,8 +421,8 @@ fn tokens_to_str(tokens: &[token::Token]) -> String {
             // leave it in the input
         } else {
             let expected = edible.iter().map(|x| (*x).clone()).collect::<Vec<_>>().append(inedible);
-            let expect = tokens_to_str(expected.as_slice());
-            let actual = self.this_token_to_str();
+            let expect = tokens_to_string(expected.as_slice());
+            let actual = self.this_token_to_string();
             self.fatal(
                 (if expected.len() != 1 {
                     (format!("expected one of `{}` but found `{}`",
@@ -512,7 +511,7 @@ pub fn parse_ident(&mut self) -> ast::Ident {
                 self.bug("ident interpolation not converted to real token");
             }
             _ => {
-                let token_str = self.this_token_to_str();
+                let token_str = self.this_token_to_string();
                 self.fatal((format!("expected ident, found `{}`",
                                     token_str)).as_slice())
             }
@@ -556,7 +555,7 @@ pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> bool {
     pub fn expect_keyword(&mut self, kw: keywords::Keyword) {
         if !self.eat_keyword(kw) {
             let id_interned_str = token::get_ident(kw.to_ident());
-            let token_str = self.this_token_to_str();
+            let token_str = self.this_token_to_string();
             self.fatal(format!("expected `{}`, found `{}`",
                                id_interned_str, token_str).as_slice())
         }
@@ -565,7 +564,7 @@ pub fn expect_keyword(&mut self, kw: keywords::Keyword) {
     // signal an error if the given string is a strict keyword
     pub fn check_strict_keywords(&mut self) {
         if token::is_strict_keyword(&self.token) {
-            let token_str = self.this_token_to_str();
+            let token_str = self.this_token_to_string();
             let span = self.span;
             self.span_err(span,
                           format!("found `{}` in ident position",
@@ -576,7 +575,7 @@ pub fn check_strict_keywords(&mut self) {
     // signal an error if the current token is a reserved keyword
     pub fn check_reserved_keywords(&mut self) {
         if token::is_reserved_keyword(&self.token) {
-            let token_str = self.this_token_to_str();
+            let token_str = self.this_token_to_string();
             self.fatal(format!("`{}` is a reserved keyword",
                                token_str).as_slice())
         }
@@ -593,9 +592,9 @@ fn expect_and(&mut self) {
                 self.replace_token(token::BINOP(token::AND), lo, span.hi)
             }
             _ => {
-                let token_str = self.this_token_to_str();
+                let token_str = self.this_token_to_string();
                 let found_token =
-                    Parser::token_to_str(&token::BINOP(token::AND));
+                    Parser::token_to_string(&token::BINOP(token::AND));
                 self.fatal(format!("expected `{}`, found `{}`",
                                    found_token,
                                    token_str).as_slice())
@@ -614,9 +613,9 @@ fn expect_or(&mut self) {
                 self.replace_token(token::BINOP(token::OR), lo, span.hi)
             }
             _ => {
-                let found_token = self.this_token_to_str();
+                let found_token = self.this_token_to_string();
                 let token_str =
-                    Parser::token_to_str(&token::BINOP(token::OR));
+                    Parser::token_to_string(&token::BINOP(token::OR));
                 self.fatal(format!("expected `{}`, found `{}`",
                                    token_str,
                                    found_token).as_slice())
@@ -667,8 +666,8 @@ fn eat_lt(&mut self, force: bool) -> bool {
 
     fn expect_lt(&mut self) {
         if !self.eat_lt(true) {
-            let found_token = self.this_token_to_str();
-            let token_str = Parser::token_to_str(&token::LT);
+            let found_token = self.this_token_to_string();
+            let token_str = Parser::token_to_string(&token::LT);
             self.fatal(format!("expected `{}`, found `{}`",
                                token_str,
                                found_token).as_slice())
@@ -718,8 +717,8 @@ pub fn expect_gt(&mut self) {
                 self.replace_token(token::EQ, lo, span.hi)
             }
             _ => {
-                let gt_str = Parser::token_to_str(&token::GT);
-                let this_token_str = self.this_token_to_str();
+                let gt_str = Parser::token_to_string(&token::GT);
+                let this_token_str = self.this_token_to_string();
                 self.fatal(format!("expected `{}`, found `{}`",
                                    gt_str,
                                    this_token_str).as_slice())
@@ -1247,7 +1246,7 @@ pub fn parse_trait_methods(&mut self) -> Vec<TraitMethod> {
               }
 
               _ => {
-                  let token_str = p.this_token_to_str();
+                  let token_str = p.this_token_to_string();
                   p.fatal((format!("expected `;` or `{{` but found `{}`",
                                    token_str)).as_slice())
               }
@@ -2231,7 +2230,7 @@ fn parse_non_delim_tt_tok(p: &mut Parser) -> TokenTree {
                       None => {}
                       Some(&sp) => p.span_note(sp, "unclosed delimiter"),
                   };
-                  let token_str = p.this_token_to_str();
+                  let token_str = p.this_token_to_string();
                   p.fatal(format!("incorrect close delimiter: `{}`",
                                   token_str).as_slice())
               },
@@ -2400,7 +2399,6 @@ pub fn parse_prefix_expr(&mut self) -> Gc<Expr> {
           }
           token::BINOP(token::AND) | token::ANDAND => {
             self.expect_and();
-            let _lt = self.parse_opt_lifetime();
             let m = self.parse_mutability();
             let e = self.parse_prefix_expr();
             hi = e.span.hi;
@@ -2823,7 +2821,7 @@ fn parse_pat_fields(&mut self) -> (Vec<ast::FieldPat> , bool) {
             if self.token == token::DOTDOT {
                 self.bump();
                 if self.token != token::RBRACE {
-                    let token_str = self.this_token_to_str();
+                    let token_str = self.this_token_to_string();
                     self.fatal(format!("expected `{}`, found `{}`", "}",
                                        token_str).as_slice())
                 }
@@ -2844,7 +2842,7 @@ fn parse_pat_fields(&mut self) -> (Vec<ast::FieldPat> , bool) {
             let subpat = if self.token == token::COLON {
                 match bind_type {
                     BindByRef(..) | BindByValue(MutMutable) => {
-                        let token_str = self.this_token_to_str();
+                        let token_str = self.this_token_to_string();
                         self.fatal(format!("unexpected `{}`",
                                            token_str).as_slice())
                     }
@@ -3119,8 +3117,9 @@ fn parse_pat_ident(&mut self,
             self.span_fatal(last_span,
                             "expected identifier, found path");
         }
-        // why a path here, and not just an identifier?
-        let name = codemap::Spanned{span: self.last_span, node: self.parse_ident()};
+        let ident = self.parse_ident();
+        let last_span = self.last_span;
+        let name = codemap::Spanned{span: last_span, node: ident};
         let sub = if self.eat(&token::AT) {
             Some(self.parse_pat())
         } else {
@@ -3253,7 +3252,7 @@ fn check_expected_item(p: &mut Parser, found_attrs: bool) {
                     } else {
                         ""
                     };
-                    let tok_str = self.this_token_to_str();
+                    let tok_str = self.this_token_to_string();
                     self.fatal(format!("expected {}`(` or `{{`, but found `{}`",
                                        ident_str,
                                        tok_str).as_slice())
@@ -3564,11 +3563,40 @@ fn parse_ty_param_bounds(&mut self, allow_any_lifetime: bool)
         return (ret_lifetime, OwnedSlice::from_vec(result));
     }
 
-    // matches typaram = type? IDENT optbounds ( EQ ty )?
+    fn trait_ref_from_ident(ident: Ident, span: Span) -> ast::TraitRef {
+        let segment = ast::PathSegment {
+            identifier: ident,
+            lifetimes: Vec::new(),
+            types: OwnedSlice::empty(),
+        };
+        let path = ast::Path {
+            span: span,
+            global: false,
+            segments: vec![segment],
+        };
+        ast::TraitRef {
+            path: path,
+            ref_id: ast::DUMMY_NODE_ID,
+        }
+    }
+
+    // matches typaram = (unbound`?`)? IDENT optbounds ( EQ ty )?
     fn parse_ty_param(&mut self) -> TyParam {
-        let sized = self.parse_sized();
-        let span = self.span;
-        let ident = self.parse_ident();
+        // This is a bit hacky. Currently we are only interested in a single
+        // unbound, and it may only be `Sized`. To avoid backtracking and other
+        // complications, we parse an ident, then check for `?`. If we find it,
+        // we use the ident as the unbound, otherwise, we use it as the name of
+        // type param.
+        let mut span = self.span;
+        let mut ident = self.parse_ident();
+        let mut unbound = None;
+        if self.eat(&token::QUESTION) {
+            let tref = Parser::trait_ref_from_ident(ident, span);
+            unbound = Some(TraitTyParamBound(tref));
+            span = self.span;
+            ident = self.parse_ident();
+        }
+
         let opt_bounds = {
             if self.eat(&token::COLON) {
                 let (_, bounds) = self.parse_ty_param_bounds(false);
@@ -3589,8 +3617,8 @@ fn parse_ty_param(&mut self) -> TyParam {
         TyParam {
             ident: ident,
             id: ast::DUMMY_NODE_ID,
-            sized: sized,
             bounds: bounds,
+            unbound: unbound,
             default: default,
             span: span,
         }
@@ -3714,7 +3742,7 @@ fn is_self_ident(&mut self) -> bool {
 
     fn expect_self_ident(&mut self) {
         if !self.is_self_ident() {
-            let token_str = self.this_token_to_str();
+            let token_str = self.this_token_to_string();
             self.fatal(format!("expected `self` but found `{}`",
                                token_str).as_slice())
         }
@@ -3847,7 +3875,7 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
                     vec!(Arg::new_self(explicit_self_sp, mutbl_self))
                 }
                 _ => {
-                    let token_str = self.this_token_to_str();
+                    let token_str = self.this_token_to_string();
                     self.fatal(format!("expected `,` or `)`, found `{}`",
                                        token_str).as_slice())
                 }
@@ -4016,7 +4044,7 @@ fn parse_item_trait(&mut self) -> ItemInfo {
 
     // Parses two variants (with the region/type params always optional):
     //    impl<T> Foo { ... }
-    //    impl<T> ToStr for ~[T] { ... }
+    //    impl<T> ToString for ~[T] { ... }
     fn parse_item_impl(&mut self) -> ItemInfo {
         // First, parse type parameters if necessary.
         let generics = self.parse_generics();
@@ -4151,7 +4179,7 @@ fn parse_item_struct(&mut self, is_virtual: bool) -> ItemInfo {
             is_tuple_like = true;
             fields = Vec::new();
         } else {
-            let token_str = self.this_token_to_str();
+            let token_str = self.this_token_to_string();
             self.fatal(format!("expected `{}`, `(`, or `;` after struct \
                                 name but found `{}`", "{",
                                token_str).as_slice())
@@ -4182,7 +4210,7 @@ pub fn parse_single_struct_field(&mut self,
             token::RBRACE => {}
             _ => {
                 let span = self.span;
-                let token_str = self.this_token_to_str();
+                let token_str = self.this_token_to_string();
                 self.span_fatal(span,
                                 format!("expected `,`, or `}}` but found `{}`",
                                         token_str).as_slice())
@@ -4209,21 +4237,19 @@ fn parse_visibility(&mut self) -> Visibility {
         else { Inherited }
     }
 
-    fn parse_sized(&mut self) -> Sized {
-        if self.eat_keyword(keywords::Type) { DynSize }
-        else { StaticSize }
-    }
-
-    fn parse_for_sized(&mut self) -> Sized {
+    fn parse_for_sized(&mut self) -> Option<ast::TyParamBound> {
         if self.eat_keyword(keywords::For) {
-            if !self.eat_keyword(keywords::Type) {
-                let last_span = self.last_span;
-                self.span_err(last_span,
-                    "expected 'type' after for in trait item");
+            let span = self.span;
+            let ident = self.parse_ident();
+            if !self.eat(&token::QUESTION) {
+                self.span_err(span,
+                    "expected 'Sized?' after `for` in trait item");
+                return None;
             }
-            DynSize
+            let tref = Parser::trait_ref_from_ident(ident, span);
+            Some(TraitTyParamBound(tref))
         } else {
-            StaticSize
+            None
         }
     }
 
@@ -4265,7 +4291,7 @@ fn parse_mod_items(&mut self,
                                  the module");
               }
               _ => {
-                  let token_str = self.this_token_to_str();
+                  let token_str = self.this_token_to_string();
                   self.fatal(format!("expected item but found `{}`",
                                      token_str).as_slice())
               }
@@ -4545,7 +4571,7 @@ fn parse_item_extern_crate(&mut self,
             }
             _ => {
                 let span = self.span;
-                let token_str = self.this_token_to_str();
+                let token_str = self.this_token_to_string();
                 self.span_fatal(span,
                                 format!("expected extern crate name but \
                                          found `{}`",
@@ -4803,7 +4829,7 @@ fn parse_item_or_view_item(&mut self,
             }
 
             let span = self.span;
-            let token_str = self.this_token_to_str();
+            let token_str = self.this_token_to_string();
             self.span_fatal(span,
                             format!("expected `{}` or `fn` but found `{}`", "{",
                                     token_str).as_slice());
index a93e8270d9866c0b12fe791ab2127411b3a43ffb..84834f54a04eb10680a6be9082dfed5943b71289 100644 (file)
@@ -76,6 +76,7 @@ pub enum Token {
     RBRACE,
     POUND,
     DOLLAR,
+    QUESTION,
 
     /* Literals */
     LIT_BYTE(u8),
@@ -140,7 +141,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-pub fn binop_to_str(o: BinOp) -> &'static str {
+pub fn binop_to_string(o: BinOp) -> &'static str {
     match o {
       PLUS => "+",
       MINUS => "-",
@@ -155,7 +156,7 @@ pub fn binop_to_str(o: BinOp) -> &'static str {
     }
 }
 
-pub fn to_str(t: &Token) -> String {
+pub fn to_string(t: &Token) -> String {
     match *t {
       EQ => "=".to_string(),
       LT => "<".to_string(),
@@ -168,9 +169,9 @@ pub fn to_str(t: &Token) -> String {
       TILDE => "~".to_string(),
       OROR => "||".to_string(),
       ANDAND => "&&".to_string(),
-      BINOP(op) => binop_to_str(op).to_string(),
+      BINOP(op) => binop_to_string(op).to_string(),
       BINOPEQ(op) => {
-          let mut s = binop_to_str(op).to_string();
+          let mut s = binop_to_string(op).to_string();
           s.push_str("=");
           s
       }
@@ -195,6 +196,7 @@ pub fn to_str(t: &Token) -> String {
       RBRACE => "}".to_string(),
       POUND => "#".to_string(),
       DOLLAR => "$".to_string(),
+      QUESTION => "?".to_string(),
 
       /* Literals */
       LIT_BYTE(b) => {
@@ -213,15 +215,15 @@ pub fn to_str(t: &Token) -> String {
           res.push_char('\'');
           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 as u64).to_str() }
+      LIT_INT(i, t) => ast_util::int_ty_to_string(t, Some(i)),
+      LIT_UINT(u, t) => ast_util::uint_ty_to_string(t, Some(u)),
+      LIT_INT_UNSUFFIXED(i) => { (i as u64).to_string() }
       LIT_FLOAT(s, t) => {
         let mut body = String::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).as_slice());
+        body.push_str(ast_util::float_ty_to_string(t).as_slice());
         body
       }
       LIT_FLOAT_UNSUFFIXED(s) => {
@@ -260,8 +262,8 @@ pub fn to_str(t: &Token) -> String {
       EOF => "<eof>".to_string(),
       INTERPOLATED(ref nt) => {
         match nt {
-            &NtExpr(ref e) => ::print::pprust::expr_to_str(&**e),
-            &NtMeta(ref e) => ::print::pprust::meta_item_to_str(&**e),
+            &NtExpr(ref e) => ::print::pprust::expr_to_string(&**e),
+            &NtMeta(ref e) => ::print::pprust::meta_item_to_string(&**e),
             _ => {
                 let mut s = "an interpolated ".to_string();
                 match *nt {
@@ -691,7 +693,7 @@ pub fn gensym_ident(s: &str) -> ast::Ident {
 }
 
 // create a fresh name that maps to the same string as the old one.
-// note that this guarantees that str_ptr_eq(ident_to_str(src),interner_get(fresh_name(src)));
+// note that this guarantees that str_ptr_eq(ident_to_string(src),interner_get(fresh_name(src)));
 // that is, that the new name and the old one are connected to ptr_eq strings.
 pub fn fresh_name(src: &ast::Ident) -> Name {
     let interner = get_ident_interner();
@@ -700,7 +702,7 @@ pub fn fresh_name(src: &ast::Ident) -> Name {
     // good error messages and uses of struct names in ambiguous could-be-binding
     // locations. Also definitely destroys the guarantee given above about ptr_eq.
     /*let num = rand::task_rng().gen_uint_range(0,0xffff);
-    gensym(format!("{}_{}",ident_to_str(src),num))*/
+    gensym(format!("{}_{}",ident_to_string(src),num))*/
 }
 
 // create a fresh mark.
@@ -765,7 +767,7 @@ mod test {
     use ext::mtwt;
 
     fn mark_ident(id : ast::Ident, m : ast::Mrk) -> ast::Ident {
-        ast::Ident{name:id.name,ctxt:mtwt::new_mark(m,id.ctxt)}
+        ast::Ident{name:id.name,ctxt:mtwt::apply_mark(m,id.ctxt)}
     }
 
     #[test] fn mtwt_token_eq_test() {
index 4660bb337ab23e1d46c4d8ad2fb608a214d5804c..e695241472b09edafd9e0c456a29639f86697abc 100644 (file)
@@ -128,6 +128,126 @@ pub fn print_crate<'a>(cm: &'a CodeMap,
     eof(&mut s.s)
 }
 
+pub fn to_string(f: |&mut State| -> IoResult<()>) -> String {
+    let mut s = rust_printer(box MemWriter::new());
+    f(&mut s).unwrap();
+    eof(&mut s.s).unwrap();
+    unsafe {
+        // FIXME(pcwalton): A nasty function to extract the string from an `io::Writer`
+        // that we "know" to be a `MemWriter` that works around the lack of checked
+        // downcasts.
+        let (_, wr): (uint, Box<MemWriter>) = mem::transmute_copy(&s.s.out);
+        let result =
+            str::from_utf8_owned(Vec::from_slice(wr.get_ref())).unwrap();
+        mem::forget(wr);
+        result.to_string()
+    }
+}
+
+pub fn ty_to_string(ty: &ast::Ty) -> String {
+    to_string(|s| s.print_type(ty))
+}
+
+pub fn pat_to_string(pat: &ast::Pat) -> String {
+    to_string(|s| s.print_pat(pat))
+}
+
+pub fn expr_to_string(e: &ast::Expr) -> String {
+    to_string(|s| s.print_expr(e))
+}
+
+pub fn lifetime_to_string(e: &ast::Lifetime) -> String {
+    to_string(|s| s.print_lifetime(e))
+}
+
+pub fn tt_to_string(tt: &ast::TokenTree) -> String {
+    to_string(|s| s.print_tt(tt))
+}
+
+pub fn tts_to_string(tts: &[ast::TokenTree]) -> String {
+    to_string(|s| s.print_tts(tts))
+}
+
+pub fn stmt_to_string(stmt: &ast::Stmt) -> String {
+    to_string(|s| s.print_stmt(stmt))
+}
+
+pub fn item_to_string(i: &ast::Item) -> String {
+    to_string(|s| s.print_item(i))
+}
+
+pub fn generics_to_string(generics: &ast::Generics) -> String {
+    to_string(|s| s.print_generics(generics))
+}
+
+pub fn ty_method_to_string(p: &ast::TypeMethod) -> String {
+    to_string(|s| s.print_ty_method(p))
+}
+
+pub fn method_to_string(p: &ast::Method) -> String {
+    to_string(|s| s.print_method(p))
+}
+
+pub fn fn_block_to_string(p: &ast::FnDecl) -> String {
+    to_string(|s| s.print_fn_block_args(p))
+}
+
+pub fn path_to_string(p: &ast::Path) -> String {
+    to_string(|s| s.print_path(p, false))
+}
+
+pub fn ident_to_string(id: &ast::Ident) -> String {
+    to_string(|s| s.print_ident(*id))
+}
+
+pub fn fun_to_string(decl: &ast::FnDecl, fn_style: ast::FnStyle, name: ast::Ident,
+                  opt_explicit_self: Option<ast::ExplicitSelf_>,
+                  generics: &ast::Generics) -> String {
+    to_string(|s| {
+        try!(s.print_fn(decl, Some(fn_style), abi::Rust,
+                        name, generics, opt_explicit_self, ast::Inherited));
+        try!(s.end()); // Close the head box
+        s.end() // Close the outer box
+    })
+}
+
+pub fn block_to_string(blk: &ast::Block) -> String {
+    to_string(|s| {
+        // containing cbox, will be closed by print-block at }
+        try!(s.cbox(indent_unit));
+        // head-ibox, will be closed by print-block after {
+        try!(s.ibox(0u));
+        s.print_block(blk)
+    })
+}
+
+pub fn meta_item_to_string(mi: &ast::MetaItem) -> String {
+    to_string(|s| s.print_meta_item(mi))
+}
+
+pub fn attribute_to_string(attr: &ast::Attribute) -> String {
+    to_string(|s| s.print_attribute(attr))
+}
+
+pub fn lit_to_string(l: &ast::Lit) -> String {
+    to_string(|s| s.print_literal(l))
+}
+
+pub fn explicit_self_to_string(explicit_self: ast::ExplicitSelf_) -> String {
+    to_string(|s| s.print_explicit_self(explicit_self, ast::MutImmutable).map(|_| {}))
+}
+
+pub fn variant_to_string(var: &ast::Variant) -> String {
+    to_string(|s| s.print_variant(var))
+}
+
+pub fn arg_to_string(arg: &ast::Arg) -> String {
+    to_string(|s| s.print_arg(arg))
+}
+
+
+
+#[cfg(stage0)]
 pub fn to_str(f: |&mut State| -> IoResult<()>) -> String {
     let mut s = rust_printer(box MemWriter::new());
     f(&mut s).unwrap();
@@ -144,62 +264,72 @@ pub fn to_str(f: |&mut State| -> IoResult<()>) -> String {
     }
 }
 
+#[cfg(stage0)]
 pub fn ty_to_str(ty: &ast::Ty) -> String {
     to_str(|s| s.print_type(ty))
 }
 
+#[cfg(stage0)]
 pub fn pat_to_str(pat: &ast::Pat) -> String {
     to_str(|s| s.print_pat(pat))
 }
 
+#[cfg(stage0)]
 pub fn expr_to_str(e: &ast::Expr) -> String {
     to_str(|s| s.print_expr(e))
 }
 
+#[cfg(stage0)]
 pub fn lifetime_to_str(e: &ast::Lifetime) -> String {
     to_str(|s| s.print_lifetime(e))
 }
 
+#[cfg(stage0)]
 pub fn tt_to_str(tt: &ast::TokenTree) -> String {
     to_str(|s| s.print_tt(tt))
 }
 
+#[cfg(stage0)]
 pub fn tts_to_str(tts: &[ast::TokenTree]) -> String {
     to_str(|s| s.print_tts(tts))
 }
 
+#[cfg(stage0)]
 pub fn stmt_to_str(stmt: &ast::Stmt) -> String {
     to_str(|s| s.print_stmt(stmt))
 }
 
+#[cfg(stage0)]
 pub fn item_to_str(i: &ast::Item) -> String {
     to_str(|s| s.print_item(i))
 }
 
+#[cfg(stage0)]
 pub fn generics_to_str(generics: &ast::Generics) -> String {
     to_str(|s| s.print_generics(generics))
 }
 
+#[cfg(stage0)]
 pub fn ty_method_to_str(p: &ast::TypeMethod) -> String {
     to_str(|s| s.print_ty_method(p))
 }
 
+#[cfg(stage0)]
 pub fn method_to_str(p: &ast::Method) -> String {
     to_str(|s| s.print_method(p))
 }
 
+#[cfg(stage0)]
 pub fn fn_block_to_str(p: &ast::FnDecl) -> String {
     to_str(|s| s.print_fn_block_args(p))
 }
 
+#[cfg(stage0)]
 pub fn path_to_str(p: &ast::Path) -> String {
     to_str(|s| s.print_path(p, false))
 }
 
-pub fn ident_to_str(id: &ast::Ident) -> String {
-    to_str(|s| s.print_ident(*id))
-}
-
+#[cfg(stage0)]
 pub fn fun_to_str(decl: &ast::FnDecl, fn_style: ast::FnStyle, name: ast::Ident,
                   opt_explicit_self: Option<ast::ExplicitSelf_>,
                   generics: &ast::Generics) -> String {
@@ -211,6 +341,7 @@ pub fn fun_to_str(decl: &ast::FnDecl, fn_style: ast::FnStyle, name: ast::Ident,
     })
 }
 
+#[cfg(stage0)]
 pub fn block_to_str(blk: &ast::Block) -> String {
     to_str(|s| {
         // containing cbox, will be closed by print-block at }
@@ -221,30 +352,39 @@ pub fn block_to_str(blk: &ast::Block) -> String {
     })
 }
 
+#[cfg(stage0)]
 pub fn meta_item_to_str(mi: &ast::MetaItem) -> String {
     to_str(|s| s.print_meta_item(mi))
 }
 
+#[cfg(stage0)]
 pub fn attribute_to_str(attr: &ast::Attribute) -> String {
     to_str(|s| s.print_attribute(attr))
 }
 
+#[cfg(stage0)]
 pub fn lit_to_str(l: &ast::Lit) -> String {
     to_str(|s| s.print_literal(l))
 }
 
+#[cfg(stage0)]
 pub fn explicit_self_to_str(explicit_self: ast::ExplicitSelf_) -> String {
     to_str(|s| s.print_explicit_self(explicit_self, ast::MutImmutable).map(|_| {}))
 }
 
+#[cfg(stage0)]
 pub fn variant_to_str(var: &ast::Variant) -> String {
     to_str(|s| s.print_variant(var))
 }
 
+#[cfg(stage0)]
 pub fn arg_to_str(arg: &ast::Arg) -> String {
     to_str(|s| s.print_arg(arg))
 }
 
+
+
+
 pub fn visibility_qualified(vis: ast::Visibility, s: &str) -> String {
     match vis {
         ast::Public => format!("pub {}", s),
@@ -674,7 +814,7 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
             }
             ast::ItemForeignMod(ref nmod) => {
                 try!(self.head("extern"));
-                try!(self.word_nbsp(nmod.abi.to_str().as_slice()));
+                try!(self.word_nbsp(nmod.abi.to_string().as_slice()));
                 try!(self.bopen());
                 try!(self.print_foreign_mod(nmod, item.attrs.as_slice()));
                 try!(self.bclose(item.span));
@@ -740,14 +880,19 @@ 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) => {
+            ast::ItemTrait(ref generics, ref unbound, ref traits, ref methods) => {
                 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 {
-                    try!(space(&mut self.s));
-                    try!(word(&mut self.s, "for type"));
+                match unbound {
+                    &Some(TraitTyParamBound(ref tref)) => {
+                        try!(space(&mut self.s));
+                        try!(self.word_space("for"));
+                        try!(self.print_trait_ref(tref));
+                        try!(word(&mut self.s, "?"));
+                    }
+                    _ => {}
                 }
                 if traits.len() != 0u {
                     try!(word(&mut self.s, ":"));
@@ -893,7 +1038,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) => {
-                try!(word(&mut self.s, parse::token::to_str(tk).as_slice()));
+                try!(word(&mut self.s, parse::token::to_string(tk).as_slice()));
                 match *tk {
                     parse::token::DOC_COMMENT(..) => {
                         hardbreak(&mut self.s)
@@ -910,7 +1055,7 @@ pub fn print_tt(&mut self, tt: &ast::TokenTree) -> IoResult<()> {
                 match *sep {
                     Some(ref tk) => {
                         try!(word(&mut self.s,
-                                  parse::token::to_str(tk).as_slice()));
+                                  parse::token::to_string(tk).as_slice()));
                     }
                     None => ()
                 }
@@ -1308,11 +1453,11 @@ pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> {
             ast::ExprBinary(op, ref lhs, ref rhs) => {
                 try!(self.print_expr(&**lhs));
                 try!(space(&mut self.s));
-                try!(self.word_space(ast_util::binop_to_str(op)));
+                try!(self.word_space(ast_util::binop_to_string(op)));
                 try!(self.print_expr(&**rhs));
             }
             ast::ExprUnary(op, ref expr) => {
-                try!(word(&mut self.s, ast_util::unop_to_str(op)));
+                try!(word(&mut self.s, ast_util::unop_to_string(op)));
                 try!(self.print_expr_maybe_paren(&**expr));
             }
             ast::ExprAddrOf(m, ref expr) => {
@@ -1488,7 +1633,7 @@ pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> {
             ast::ExprAssignOp(op, ref lhs, ref rhs) => {
                 try!(self.print_expr(&**lhs));
                 try!(space(&mut self.s));
-                try!(word(&mut self.s, ast_util::binop_to_str(op)));
+                try!(word(&mut self.s, ast_util::binop_to_string(op)));
                 try!(self.word_space("="));
                 try!(self.print_expr(&**rhs));
             }
@@ -1745,13 +1890,14 @@ pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> {
             }
             ast::PatStruct(ref path, ref fields, etc) => {
                 try!(self.print_path(path, true));
-                try!(word(&mut self.s, "{"));
+                try!(self.nbsp());
+                try!(self.word_space("{"));
                 try!(self.commasep_cmnt(
                     Consistent, fields.as_slice(),
                     |s, f| {
                         try!(s.cbox(indent_unit));
                         try!(s.print_ident(f.ident));
-                        try!(s.word_space(":"));
+                        try!(s.word_nbsp(":"));
                         try!(s.print_pat(&*f.pat));
                         s.end()
                     },
@@ -1760,6 +1906,7 @@ pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> {
                     if fields.len() != 0u { try!(self.word_space(",")); }
                     try!(word(&mut self.s, ".."));
                 }
+                try!(space(&mut self.s));
                 try!(word(&mut self.s, "}"));
             }
             ast::PatTup(ref elts) => {
@@ -2027,8 +2174,12 @@ pub fn print_generics(&mut self,
                     } else {
                         let idx = idx - generics.lifetimes.len();
                         let param = generics.ty_params.get(idx);
-                        if param.sized == ast::DynSize {
-                            try!(s.word_space("type"));
+                        match param.unbound {
+                            Some(TraitTyParamBound(ref tref)) => {
+                                try!(s.print_trait_ref(tref));
+                                try!(s.word_space("?"));
+                            }
+                            _ => {}
                         }
                         try!(s.print_ident(param.ident));
                         try!(s.print_bounds(&None,
@@ -2326,11 +2477,11 @@ pub fn print_literal(&mut self, lit: &ast::Lit) -> IoResult<()> {
             }
             ast::LitInt(i, t) => {
                 word(&mut self.s,
-                     ast_util::int_ty_to_str(t, Some(i)).as_slice())
+                     ast_util::int_ty_to_string(t, Some(i)).as_slice())
             }
             ast::LitUint(u, t) => {
                 word(&mut self.s,
-                     ast_util::uint_ty_to_str(t, Some(u)).as_slice())
+                     ast_util::uint_ty_to_string(t, Some(u)).as_slice())
             }
             ast::LitIntUnsuffixed(i) => {
                 word(&mut self.s, format!("{}", i).as_slice())
@@ -2340,7 +2491,7 @@ pub fn print_literal(&mut self, lit: &ast::Lit) -> IoResult<()> {
                      format!(
                          "{}{}",
                          f.get(),
-                         ast_util::float_ty_to_str(t).as_slice()).as_slice())
+                         ast_util::float_ty_to_string(t).as_slice()).as_slice())
             }
             ast::LitFloatUnsuffixed(ref f) => word(&mut self.s, f.get()),
             ast::LitNil => word(&mut self.s, "()"),
@@ -2478,7 +2629,7 @@ pub fn print_opt_abi_and_extern_if_nondefault(&mut self,
             Some(abi::Rust) => Ok(()),
             Some(abi) => {
                 try!(self.word_nbsp("extern"));
-                self.word_nbsp(abi.to_str().as_slice())
+                self.word_nbsp(abi.to_string().as_slice())
             }
             None => Ok(())
         }
@@ -2489,7 +2640,7 @@ pub fn print_extern_opt_abi(&mut self,
         match opt_abi {
             Some(abi) => {
                 try!(self.word_nbsp("extern"));
-                self.word_nbsp(abi.to_str().as_slice())
+                self.word_nbsp(abi.to_string().as_slice())
             }
             None => Ok(())
         }
@@ -2505,7 +2656,7 @@ pub fn print_fn_header_info(&mut self,
 
         if abi != abi::Rust {
             try!(self.word_nbsp("extern"));
-            try!(self.word_nbsp(abi.to_str().as_slice()));
+            try!(self.word_nbsp(abi.to_string().as_slice()));
         }
 
         word(&mut self.s, "fn")
@@ -2536,7 +2687,7 @@ mod test {
     use parse::token;
 
     #[test]
-    fn test_fun_to_str() {
+    fn test_fun_to_string() {
         let abba_ident = token::str_to_ident("abba");
 
         let decl = ast::FnDecl {
@@ -2548,13 +2699,13 @@ fn test_fun_to_str() {
             variadic: false
         };
         let generics = ast_util::empty_generics();
-        assert_eq!(&fun_to_str(&decl, ast::NormalFn, abba_ident,
+        assert_eq!(&fun_to_string(&decl, ast::NormalFn, abba_ident,
                                None, &generics),
                    &"fn abba()".to_string());
     }
 
     #[test]
-    fn test_variant_to_str() {
+    fn test_variant_to_string() {
         let ident = token::str_to_ident("principal_skinner");
 
         let var = codemap::respan(codemap::DUMMY_SP, ast::Variant_ {
@@ -2567,7 +2718,7 @@ fn test_variant_to_str() {
             vis: ast::Public,
         });
 
-        let varstr = variant_to_str(&var);
+        let varstr = variant_to_string(&var);
         assert_eq!(&varstr,&"pub principal_skinner".to_string());
     }
 }
index 56694e28b666227e1a87c513d83c40c119e3c99e..cdd067cef5b03cd6a8a7addb3dffd81ceabbffe6 100644 (file)
@@ -38,7 +38,8 @@
 //! [win]: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010%28v=vs.85%29.aspx
 //! [ti]: https://en.wikipedia.org/wiki/Terminfo
 
-#![crate_id = "term#0.11.0"]
+#![crate_id = "term#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "term"]
 #![experimental]
 #![comment = "Simple ANSI color library"]
 #![license = "MIT/ASL2"]
@@ -48,6 +49,7 @@
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/0.11.0/",
        html_playground_url = "http://play.rust-lang.org/")]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 #![feature(macro_rules, phase)]
 
index 71fdea9b9ec8e80f3aaec65dbaa4dda624b10c95..9467eb699217074217d016d55405352385b8b43a 100644 (file)
@@ -19,7 +19,7 @@
 
 // These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable.
 
-pub static boolfnames: &'static[&'static str] = &'static["auto_left_margin", "auto_right_margin",
+pub static boolfnames: &'static[&'static str] = &["auto_left_margin", "auto_right_margin",
     "no_esc_ctlc", "ceol_standout_glitch", "eat_newline_glitch", "erase_overstrike", "generic_type",
     "hard_copy", "has_meta_key", "has_status_line", "insert_null_glitch", "memory_above",
     "memory_below", "move_insert_mode", "move_standout_mode", "over_strike", "status_line_esc_ok",
     "no_correctly_working_cr", "gnu_has_meta_key", "linefeed_is_newline", "has_hardware_tabs",
     "return_does_clr_eol"];
 
-pub static boolnames: &'static[&'static str] = &'static["bw", "am", "xsb", "xhp", "xenl", "eo",
+pub static boolnames: &'static[&'static str] = &["bw", "am", "xsb", "xhp", "xenl", "eo",
     "gn", "hc", "km", "hs", "in", "db", "da", "mir", "msgr", "os", "eslok", "xt", "hz", "ul", "xon",
     "nxon", "mc5i", "chts", "nrrmc", "npc", "ndscr", "ccc", "bce", "hls", "xhpa", "crxm", "daisy",
     "xvpa", "sam", "cpix", "lpix", "OTbs", "OTns", "OTnc", "OTMT", "OTNL", "OTpt", "OTxr"];
 
-pub static numfnames: &'static[&'static str] = &'static[ "columns", "init_tabs", "lines",
+pub static numfnames: &'static[&'static str] = &[ "columns", "init_tabs", "lines",
     "lines_of_memory", "magic_cookie_glitch", "padding_baud_rate", "virtual_terminal",
     "width_status_line", "num_labels", "label_height", "label_width", "max_attributes",
     "maximum_windows", "max_colors", "max_pairs", "no_color_video", "buffer_capacity",
     "bit_image_entwining", "bit_image_type", "magic_cookie_glitch_ul", "carriage_return_delay",
     "new_line_delay", "backspace_delay", "horizontal_tab_delay", "number_of_function_keys"];
 
-pub static numnames: &'static[&'static str] = &'static[ "cols", "it", "lines", "lm", "xmc", "pb",
+pub static numnames: &'static[&'static str] = &[ "cols", "it", "lines", "lm", "xmc", "pb",
     "vt", "wsl", "nlab", "lh", "lw", "ma", "wnum", "colors", "pairs", "ncv", "bufsz", "spinv",
     "spinh", "maddr", "mjump", "mcs", "mls", "npins", "orc", "orl", "orhi", "orvi", "cps", "widcs",
     "btns", "bitwin", "bitype", "UTug", "OTdC", "OTdN", "OTdB", "OTdT", "OTkn"];
 
-pub static stringfnames: &'static[&'static str] = &'static[ "back_tab", "bell", "carriage_return",
+pub static stringfnames: &'static[&'static str] = &[ "back_tab", "bell", "carriage_return",
     "change_scroll_region", "clear_all_tabs", "clear_screen", "clr_eol", "clr_eos",
     "column_address", "command_character", "cursor_address", "cursor_down", "cursor_home",
     "cursor_invisible", "cursor_left", "cursor_mem_address", "cursor_normal", "cursor_right",
     "acs_lrcorner", "acs_ltee", "acs_rtee", "acs_btee", "acs_ttee", "acs_hline", "acs_vline",
     "acs_plus", "memory_lock", "memory_unlock", "box_chars_1"];
 
-pub static stringnames: &'static[&'static str] = &'static[ "cbt", "_", "cr", "csr", "tbc", "clear",
+pub static stringnames: &'static[&'static str] = &[ "cbt", "_", "cr", "csr", "tbc", "clear",
     "_", "_", "hpa", "cmdch", "cup", "cud1", "home", "civis", "cub1", "mrcup", "cnorm", "cuf1",
     "ll", "cuu1", "cvvis", "dch1", "dl1", "dsl", "hd", "smacs", "blink", "bold", "smcup", "smdc",
     "dim", "smir", "invis", "prot", "rev", "smso", "smul", "ech", "rmacs", "sgr0", "rmcup", "rmdc",
index 02f7ebc6d21c816d007b4a4f3c1cabb7e8c67172..b80f47e6c934ee49914a8641244d26c404a56912 100644 (file)
@@ -23,7 +23,8 @@
 // running tests while providing a base that other test frameworks may
 // build off of.
 
-#![crate_id = "test#0.11.0"]
+#![crate_id = "test#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "test"] // NOTE: remove after stage0
 #![experimental]
 #![comment = "Rust internal test library only used by rustc"]
 #![license = "MIT/ASL2"]
@@ -32,6 +33,7 @@
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 #![feature(asm, macro_rules, phase)]
 
@@ -368,7 +370,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
     let matches =
         match getopts::getopts(args_.as_slice(), optgroups().as_slice()) {
           Ok(m) => m,
-          Err(f) => return Some(Err(f.to_str()))
+          Err(f) => return Some(Err(f.to_string()))
         };
 
     if matches.opt_present("h") { usage(args[0].as_slice()); return None; }
@@ -632,7 +634,7 @@ pub fn write_failures(&mut self) -> io::IoResult<()> {
         let mut failures = Vec::new();
         let mut fail_out = String::new();
         for &(ref f, ref stdout) in self.failures.iter() {
-            failures.push(f.name.to_str());
+            failures.push(f.name.to_string());
             if stdout.len() > 0 {
                 fail_out.push_str(format!("---- {} stdout ----\n\t",
                                           f.name.as_slice()).as_slice());
@@ -1520,7 +1522,7 @@ pub fn filter_for_ignored_option() {
         let filtered = filter_tests(&opts, tests);
 
         assert_eq!(filtered.len(), 1);
-        assert_eq!(filtered.get(0).desc.name.to_str(),
+        assert_eq!(filtered.get(0).desc.name.to_string(),
                    "1".to_string());
         assert!(filtered.get(0).desc.ignore == false);
     }
@@ -1571,7 +1573,7 @@ fn testfn() { }
                  "test::sort_tests".to_string());
 
         for (a, b) in expected.iter().zip(filtered.iter()) {
-            assert!(*a == b.desc.name.to_str());
+            assert!(*a == b.desc.name.to_string());
         }
     }
 
index 8db9a4f53aa9bc8a8dab871729aa6839c46d2c20..325582ff99c98a6370effc3bf2ede983b6579e10 100644 (file)
@@ -385,8 +385,8 @@ pub fn write_boxplot<T: Float + Show + FromPrimitive>(
 
     let range = hi - lo;
 
-    let lostr = lo.to_str();
-    let histr = hi.to_str();
+    let lostr = lo.to_string();
+    let histr = hi.to_string();
 
     let overhead_width = lostr.len() + histr.len() + 4;
     let range_width = width_hint - overhead_width;
index 0e4de41959a33de9717bb41f8d73cdefac62a9a0..9ed46d7a49b7e12ab4f9caeac3cdb1ab31e61ae9 100644 (file)
@@ -10,7 +10,8 @@
 
 //! Simple time handling.
 
-#![crate_id = "time#0.11.0"]
+#![crate_id = "time#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "time"]
 #![experimental]
 
 #![crate_type = "rlib"]
@@ -21,6 +22,7 @@
        html_root_url = "http://doc.rust-lang.org/0.11.0/",
        html_playground_url = "http://play.rust-lang.org/")]
 #![feature(phase)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 #[cfg(test)] extern crate debug;
 #[cfg(test)] #[phase(plugin, link)] extern crate log;
@@ -1037,7 +1039,7 @@ fn parse_type(ch: char, tm: &Tm) -> String {
           'U' => format!("{:02d}", (tm.tm_yday - tm.tm_wday + 7) / 7),
           'u' => {
             let i = tm.tm_wday as int;
-            (if i == 0 { 7 } else { i }).to_str()
+            (if i == 0 { 7 } else { i }).to_string()
           }
           'V' => iso_week('V', tm),
           'v' => {
@@ -1050,8 +1052,8 @@ fn parse_type(ch: char, tm: &Tm) -> String {
               format!("{:02d}",
                              (tm.tm_yday - (tm.tm_wday - 1 + 7) % 7 + 7) / 7)
           }
-          'w' => (tm.tm_wday as int).to_str(),
-          'Y' => (tm.tm_year as int + 1900).to_str(),
+          'w' => (tm.tm_wday as int).to_string(),
+          'Y' => (tm.tm_year as int + 1900).to_string(),
           'y' => format!("{:02d}", (tm.tm_year as int + 1900) % 100),
           'Z' => "".to_string(),    // FIXME(pcwalton): Implement this.
           'z' => {
index a60cc8e992b4d58592ee11818f5a4ee84b90e207..129e3d0bf0ae821137e0582d3930eafc78563d63 100644 (file)
@@ -10,7 +10,8 @@
 
 //! Types/fns concerning URLs (see RFC 3986)
 
-#![crate_id = "url#0.11.0"]
+#![crate_id = "url#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "url"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
        html_root_url = "http://doc.rust-lang.org/0.11.0/",
        html_playground_url = "http://play.rust-lang.org/")]
 #![feature(default_type_params)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 use std::collections::HashMap;
 use std::fmt;
 use std::from_str::FromStr;
 use std::hash;
-use std::io::BufReader;
-use std::string::String;
 use std::uint;
+use std::path::BytesContainer;
 
 /// A Uniform Resource Locator (URL).  A URL is a form of URI (Uniform Resource
 /// Identifier) that includes network location information, such as hostname or
 /// # Example
 ///
 /// ```rust
-/// use url::{Url, UserInfo};
+/// use url::Url;
 ///
-/// let url = Url { scheme: "https".to_string(),
-///                 user: Some(UserInfo { user: "username".to_string(), pass: None }),
-///                 host: "example.com".to_string(),
-///                 port: Some("8080".to_string()),
-///                 path: "/foo/bar".to_string(),
-///                 query: vec!(("baz".to_string(), "qux".to_string())),
-///                 fragment: Some("quz".to_string()) };
-/// // https://username@example.com:8080/foo/bar?baz=qux#quz
+/// let raw = "https://username@example.com:8080/foo/bar?baz=qux#quz";
+/// match Url::parse(raw) {
+///     Ok(u) => println!("Parsed '{}'", u),
+///     Err(e) => println!("Couldn't parse '{}': {}", raw, e),
+/// }
 /// ```
 #[deriving(Clone, PartialEq, Eq)]
 pub struct Url {
@@ -56,26 +54,20 @@ pub struct Url {
     /// A domain name or IP address.  For example, `example.com`.
     pub host: String,
     /// A TCP port number, for example `8080`.
-    pub port: Option<String>,
-    /// The path component of a URL, for example `/foo/bar`.
-    pub path: String,
-    /// The query component of a URL.
-    /// `vec!(("baz".to_string(), "qux".to_string()))` represents the fragment
-    /// `baz=qux` in the above example.
-    pub query: Query,
-    /// The fragment component, such as `quz`.  Doesn't include the leading `#` character.
-    pub fragment: Option<String>
+    pub port: Option<u16>,
+    /// The path component of a URL, for example `/foo/bar?baz=qux#quz`.
+    pub path: Path,
 }
 
-#[deriving(Clone, PartialEq)]
+#[deriving(Clone, PartialEq, Eq)]
 pub struct Path {
     /// The path component of a URL, for example `/foo/bar`.
     pub path: String,
     /// The query component of a URL.
-    /// `vec!(("baz".to_string(), "qux".to_string()))` represents the fragment
+    /// `vec![("baz".to_string(), "qux".to_string())]` represents the fragment
     /// `baz=qux` in the above example.
     pub query: Query,
-    /// The fragment component, such as `quz`.  Doesn't include the leading `#` character.
+    /// The fragment component, such as `quz`. Not including the leading `#` character.
     pub fragment: Option<String>
 }
 
@@ -95,7 +87,7 @@ impl Url {
     pub fn new(scheme: String,
                user: Option<UserInfo>,
                host: String,
-               port: Option<String>,
+               port: Option<u16>,
                path: String,
                query: Query,
                fragment: Option<String>)
@@ -105,11 +97,48 @@ pub fn new(scheme: String,
             user: user,
             host: host,
             port: port,
-            path: path,
-            query: query,
-            fragment: fragment,
+            path: Path::new(path, query, fragment)
         }
     }
+
+    /// Parses a URL, converting it from a string to a `Url` representation.
+    ///
+    /// # Arguments
+    /// * rawurl - a string representing the full URL, including scheme.
+    ///
+    /// # Return value
+    ///
+    /// `Err(e)` if the string did not represent a valid URL, where `e` is a
+    /// `String` error message. Otherwise, `Ok(u)` where `u` is a `Url` struct
+    /// representing the URL.
+    pub fn parse(rawurl: &str) -> DecodeResult<Url> {
+        // scheme
+        let (scheme, rest) = try!(get_scheme(rawurl));
+
+        // authority
+        let (userinfo, host, port, rest) = try!(get_authority(rest));
+
+        // path
+        let has_authority = host.len() > 0;
+        let (path, rest) = try!(get_path(rest, has_authority));
+
+        // query and fragment
+        let (query, fragment) = try!(get_query_fragment(rest));
+
+        let url = Url::new(scheme.to_string(),
+                            userinfo,
+                            host.to_string(),
+                            port,
+                            path,
+                            query,
+                            fragment);
+        Ok(url)
+    }
+}
+
+#[deprecated="use `Url::parse`"]
+pub fn from_str(s: &str) -> Result<Url, String> {
+    Url::parse(s)
 }
 
 impl Path {
@@ -123,6 +152,30 @@ pub fn new(path: String,
             fragment: fragment,
         }
     }
+
+    /// Parses a URL path, converting it from a string to a `Path` representation.
+    ///
+    /// # Arguments
+    /// * rawpath - a string representing the path component of a URL.
+    ///
+    /// # Return value
+    ///
+    /// `Err(e)` if the string did not represent a valid URL path, where `e` is a
+    /// `String` error message. Otherwise, `Ok(p)` where `p` is a `Path` struct
+    /// representing the URL path.
+    pub fn parse(rawpath: &str) -> DecodeResult<Path> {
+        let (path, rest) = try!(get_path(rawpath, false));
+
+        // query and fragment
+        let (query, fragment) = try!(get_query_fragment(rest.as_slice()));
+
+        Ok(Path{ path: path, query: query, fragment: fragment })
+    }
+}
+
+#[deprecated="use `Path::parse`"]
+pub fn path_from_str(s: &str) -> Result<Path, String> {
+    Path::parse(s)
 }
 
 impl UserInfo {
@@ -132,294 +185,221 @@ pub fn new(user: String, pass: Option<String>) -> UserInfo {
     }
 }
 
-fn encode_inner(s: &str, full_url: bool) -> String {
-    let mut rdr = BufReader::new(s.as_bytes());
-    let mut out = String::new();
-
-    loop {
-        let mut buf = [0];
-        let ch = match rdr.read(buf) {
-            Err(..) => break,
-            Ok(..) => buf[0] as char,
+fn encode_inner<T: BytesContainer>(c: T, full_url: bool) -> String {
+    c.container_as_bytes().iter().fold(String::new(), |mut out, &b| {
+        match b as char {
+            // unreserved:
+            'A' .. 'Z'
+            | 'a' .. 'z'
+            | '0' .. '9'
+            | '-' | '.' | '_' | '~' => out.push_char(b as char),
+
+            // gen-delims:
+            ':' | '/' | '?' | '#' | '[' | ']' | '@' |
+            // sub-delims:
+            '!' | '$' | '&' | '"' | '(' | ')' | '*' |
+            '+' | ',' | ';' | '='
+                if full_url => out.push_char(b as char),
+
+            ch => out.push_str(format!("%{:02X}", ch as uint).as_slice()),
         };
 
-        match ch {
-          // unreserved:
-          'A' .. 'Z' |
-          'a' .. 'z' |
-          '0' .. '9' |
-          '-' | '.' | '_' | '~' => {
-            out.push_char(ch);
-          }
-          _ => {
-              if full_url {
-                match ch {
-                  // gen-delims:
-                  ':' | '/' | '?' | '#' | '[' | ']' | '@' |
-
-                  // sub-delims:
-                  '!' | '$' | '&' | '"' | '(' | ')' | '*' |
-                  '+' | ',' | ';' | '=' => {
-                    out.push_char(ch);
-                  }
-
-                  _ => out.push_str(format!("%{:02X}", ch as uint).as_slice())
-                }
-            } else {
-                out.push_str(format!("%{:02X}", ch as uint).as_slice());
-            }
-          }
-        }
-    }
-
-    out
+        out
+    })
 }
 
-/**
- * Encodes a URI by replacing reserved characters with percent-encoded
- * character sequences.
- *
- * This function is compliant with RFC 3986.
- *
- * # Example
- *
- * ```rust
- * use url::encode;
- *
- * let url = encode("https://example.com/Rust (programming language)");
- * println!("{}", url); // https://example.com/Rust%20(programming%20language)
- * ```
- */
-pub fn encode(s: &str) -> String {
-    encode_inner(s, true)
+/// Encodes a URI by replacing reserved characters with percent-encoded
+/// character sequences.
+///
+/// This function is compliant with RFC 3986.
+///
+/// # Example
+///
+/// ```rust
+/// use url::encode;
+///
+/// let url = encode("https://example.com/Rust (programming language)");
+/// println!("{}", url); // https://example.com/Rust%20(programming%20language)
+/// ```
+pub fn encode<T: BytesContainer>(container: T) -> String {
+    encode_inner(container, true)
 }
 
-/**
- * Encodes a URI component by replacing reserved characters with percent-
- * encoded character sequences.
- *
- * This function is compliant with RFC 3986.
- */
 
-pub fn encode_component(s: &str) -> String {
-    encode_inner(s, false)
+/// Encodes a URI component by replacing reserved characters with percent-
+/// encoded character sequences.
+///
+/// This function is compliant with RFC 3986.
+pub fn encode_component<T: BytesContainer>(container: T) -> String {
+    encode_inner(container, false)
 }
 
-fn decode_inner(s: &str, full_url: bool) -> String {
-    let mut rdr = BufReader::new(s.as_bytes());
-    let mut out = String::new();
+pub type DecodeResult<T> = Result<T, String>;
 
-    loop {
-        let mut buf = [0];
-        let ch = match rdr.read(buf) {
-            Err(..) => break,
-            Ok(..) => buf[0] as char
-        };
-        match ch {
-          '%' => {
-            let mut bytes = [0, 0];
-            match rdr.read(bytes) {
-                Ok(2) => {}
-                _ => fail!() // FIXME: malformed url?
-            }
-            let ch = uint::parse_bytes(bytes, 16u).unwrap() as u8 as char;
-
-            if full_url {
-                // Only decode some characters:
-                match ch {
-                  // gen-delims:
-                  ':' | '/' | '?' | '#' | '[' | ']' | '@' |
-
-                  // sub-delims:
-                  '!' | '$' | '&' | '"' | '(' | ')' | '*' |
-                  '+' | ',' | ';' | '=' => {
-                    out.push_char('%');
-                    out.push_char(bytes[0u] as char);
-                    out.push_char(bytes[1u] as char);
-                  }
-
-                  ch => out.push_char(ch)
-                }
-            } else {
-                  out.push_char(ch);
-            }
-          }
-          ch => out.push_char(ch)
-        }
-    }
-
-    out
-}
-
-/**
- * Decodes a percent-encoded string representing a URI.
- *
- * This will only decode escape sequences generated by `encode`.
- *
- * # Example
- *
- * ```rust
- * use url::decode;
- *
- * let url = decode("https://example.com/Rust%20(programming%20language)");
- * println!("{}", url); // https://example.com/Rust (programming language)
- * ```
- */
-pub fn decode(s: &str) -> String {
-    decode_inner(s, true)
+/// Decodes a percent-encoded string representing a URI.
+///
+/// This will only decode escape sequences generated by `encode`.
+///
+/// # Example
+///
+/// ```rust
+/// use url::decode;
+///
+/// let url = decode("https://example.com/Rust%20(programming%20language)");
+/// println!("{}", url); // https://example.com/Rust (programming language)
+/// ```
+pub fn decode<T: BytesContainer>(container: T) -> DecodeResult<String> {
+    decode_inner(container, true)
 }
 
-/**
- * Decode a string encoded with percent encoding.
- */
-pub fn decode_component(s: &str) -> String {
-    decode_inner(s, false)
+/// Decode a string encoded with percent encoding.
+pub fn decode_component<T: BytesContainer>(container: T) -> DecodeResult<String> {
+    decode_inner(container, false)
 }
 
-fn encode_plus(s: &str) -> String {
-    let mut rdr = BufReader::new(s.as_bytes());
+fn decode_inner<T: BytesContainer>(c: T, full_url: bool) -> DecodeResult<String> {
     let mut out = String::new();
+    let mut iter = c.container_as_bytes().iter().map(|&b| b);
 
     loop {
-        let mut buf = [0];
-        let ch = match rdr.read(buf) {
-            Ok(..) => buf[0] as char,
-            Err(..) => break,
-        };
-        match ch {
-          'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_' | '.' | '-' => {
-            out.push_char(ch);
-          }
-          ' ' => out.push_char('+'),
-          _ => out.push_str(format!("%{:X}", ch as uint).as_slice())
+        match iter.next() {
+            Some(b) => match b as char {
+                '%' => {
+                    let bytes = match (iter.next(), iter.next()) {
+                        (Some(one), Some(two)) => [one as u8, two as u8],
+                        _ => return Err(format!("Malformed input: found '%' \
+                                                without two trailing bytes")),
+                    };
+
+                    // Only decode some characters if full_url:
+                    match uint::parse_bytes(bytes, 16u).unwrap() as u8 as char {
+                        // gen-delims:
+                        ':' | '/' | '?' | '#' | '[' | ']' | '@' |
+
+                        // sub-delims:
+                        '!' | '$' | '&' | '"' | '(' | ')' | '*' |
+                        '+' | ',' | ';' | '='
+                            if full_url => {
+                            out.push_char('%');
+                            out.push_char(bytes[0u] as char);
+                            out.push_char(bytes[1u] as char);
+                        }
+
+                        ch => out.push_char(ch)
+                    }
+                }
+                ch => out.push_char(ch)
+            },
+            None => return Ok(out),
         }
     }
-
-    out
 }
 
-/**
- * Encode a hashmap to the 'application/x-www-form-urlencoded' media type.
- */
+/// Encode a hashmap to the 'application/x-www-form-urlencoded' media type.
 pub fn encode_form_urlencoded(m: &HashMap<String, Vec<String>>) -> String {
-    let mut out = String::new();
-    let mut first = true;
+    fn encode_plus<T: Str>(s: &T) -> String {
+        s.as_slice().bytes().fold(String::new(), |mut out, b| {
+            match b as char {
+              'A' .. 'Z'
+              | 'a' .. 'z'
+              | '0' .. '9'
+              | '_' | '.' | '-' => out.push_char(b as char),
+              ' ' => out.push_char('+'),
+              ch => out.push_str(format!("%{:X}", ch as uint).as_slice())
+            }
+
+            out
+        })
+    }
 
-    for (key, values) in m.iter() {
-        let key = encode_plus(key.as_slice());
+    let mut first = true;
+    m.iter().fold(String::new(), |mut out, (key, values)| {
+        let key = encode_plus(key);
 
         for value in values.iter() {
             if first {
                 first = false;
             } else {
                 out.push_char('&');
-                first = false;
             }
 
-            out.push_str(format!("{}={}",
-                                 key,
-                                 encode_plus(value.as_slice())).as_slice());
+            out.push_str(key.as_slice());
+            out.push_char('=');
+            out.push_str(encode_plus(value).as_slice());
         }
-    }
 
-    out
+        out
+    })
 }
 
-/**
- * Decode a string encoded with the 'application/x-www-form-urlencoded' media
- * type into a hashmap.
- */
-#[allow(experimental)]
-pub fn decode_form_urlencoded(s: &[u8]) -> HashMap<String, Vec<String>> {
-    let mut rdr = BufReader::new(s);
-    let mut m: HashMap<String,Vec<String>> = HashMap::new();
+/// Decode a string encoded with the 'application/x-www-form-urlencoded' media
+/// type into a hashmap.
+pub fn decode_form_urlencoded(s: &[u8])
+                            -> DecodeResult<HashMap<String, Vec<String>>> {
+    fn maybe_push_value(map: &mut HashMap<String, Vec<String>>,
+                        key: String,
+                        value: String) {
+        if key.len() > 0 && value.len() > 0 {
+            let values = map.find_or_insert_with(key, |_| vec!());
+            values.push(value);
+        }
+    }
+
+    let mut out = HashMap::new();
+    let mut iter = s.iter().map(|&x| x);
+
     let mut key = String::new();
     let mut value = String::new();
     let mut parsing_key = true;
 
     loop {
-        let mut buf = [0];
-        let ch = match rdr.read(buf) {
-            Ok(..) => buf[0] as char,
-            Err(..) => break,
-        };
-        match ch {
-            '&' | ';' => {
-                if key.len() > 0 && value.len() > 0 {
-                    let mut values = match m.pop_equiv(&key.as_slice()) {
-                        Some(values) => values,
-                        None => vec!(),
-                    };
-
-                    values.push(value);
-                    m.insert(key, values);
+        match iter.next() {
+            Some(b) => match b as char {
+                '&' | ';' => {
+                    maybe_push_value(&mut out, key, value);
+
+                    parsing_key = true;
+                    key = String::new();
+                    value = String::new();
                 }
-
-                parsing_key = true;
-                key = String::new();
-                value = String::new();
-            }
-            '=' => parsing_key = false,
-            ch => {
-                let ch = match ch {
-                    '%' => {
-                        let mut bytes = [0, 0];
-                        match rdr.read(bytes) {
-                            Ok(2) => {}
-                            _ => fail!() // FIXME: malformed?
+                '=' => parsing_key = false,
+                ch => {
+                    let ch = match ch {
+                        '%' => {
+                            let bytes = match (iter.next(), iter.next()) {
+                                (Some(one), Some(two)) => [one as u8, two as u8],
+                                _ => return Err(format!("Malformed input: found \
+                                                '%' without two trailing bytes"))
+                            };
+
+                            uint::parse_bytes(bytes, 16u).unwrap() as u8 as char
                         }
-                        uint::parse_bytes(bytes, 16u).unwrap() as u8 as char
-                    }
-                    '+' => ' ',
-                    ch => ch
-                };
+                        '+' => ' ',
+                        ch => ch
+                    };
 
-                if parsing_key {
-                    key.push_char(ch)
-                } else {
-                    value.push_char(ch)
+                    if parsing_key {
+                        key.push_char(ch)
+                    } else {
+                        value.push_char(ch)
+                    }
                 }
+            },
+            None => {
+                maybe_push_value(&mut out, key, value);
+                return Ok(out)
             }
         }
     }
-
-    if key.len() > 0 && value.len() > 0 {
-        let mut values = match m.pop_equiv(&key.as_slice()) {
-            Some(values) => values,
-            None => vec!(),
-        };
-
-        values.push(value);
-        m.insert(key, values);
-    }
-
-    m
 }
 
+fn split_char_first<'a>(s: &'a str, c: char) -> (&'a str, &'a str) {
+    let mut iter = s.splitn(c, 1);
 
-fn split_char_first(s: &str, c: char) -> (String, String) {
-    let len = s.len();
-    let mut index = len;
-    let mut mat = 0;
-    let mut rdr = BufReader::new(s.as_bytes());
-    loop {
-        let mut buf = [0];
-        let ch = match rdr.read(buf) {
-            Ok(..) => buf[0] as char,
-            Err(..) => break,
-        };
-        if ch == c {
-            // found a match, adjust markers
-            index = (rdr.tell().unwrap() as uint) - 1;
-            mat = 1;
-            break;
-        }
-    }
-    if index+mat == len {
-        return (s.slice(0, index).to_string(), "".to_string());
-    } else {
-        return (s.slice(0, index).to_string(),
-                s.slice(index + mat, s.len()).to_string());
+    match (iter.next(), iter.next()) {
+        (Some(a), Some(b)) => (a, b),
+        (Some(a), None) => (a, ""),
+        (None, _) => unreachable!(),
     }
 }
 
@@ -432,103 +412,86 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-fn query_from_str(rawquery: &str) -> Query {
+fn query_from_str(rawquery: &str) -> DecodeResult<Query> {
     let mut query: Query = vec!();
     if !rawquery.is_empty() {
         for p in rawquery.split('&') {
             let (k, v) = split_char_first(p, '=');
-            query.push((decode_component(k.as_slice()),
-                        decode_component(v.as_slice())));
-        };
+            query.push((try!(decode_component(k)),
+                        try!(decode_component(v))));
+        }
     }
-    return query;
+
+    Ok(query)
 }
 
-/**
- * Converts an instance of a URI `Query` type to a string.
- *
- * # Example
- *
- * ```rust
- * let query = vec!(("title".to_string(), "The Village".to_string()),
- *                  ("north".to_string(), "52.91".to_string()),
- *                  ("west".to_string(), "4.10".to_string()));
- * println!("{}", url::query_to_str(&query));  // title=The%20Village&north=52.91&west=4.10
- * ```
- */
-#[allow(unused_must_use)]
+/// Converts an instance of a URI `Query` type to a string.
+///
+/// # Example
+///
+/// ```rust
+/// let query = vec![("title".to_string(), "The Village".to_string()),
+///                  ("north".to_string(), "52.91".to_string()),
+///                  ("west".to_string(), "4.10".to_string())];
+/// println!("{}", url::query_to_str(&query));  // title=The%20Village&north=52.91&west=4.10
+/// ```
 pub fn query_to_str(query: &Query) -> String {
-    use std::io::MemWriter;
-    use std::str;
-
-    let mut writer = MemWriter::new();
-    for (i, &(ref k, ref v)) in query.iter().enumerate() {
-        if i != 0 { write!(&mut writer, "&"); }
-        write!(&mut writer, "{}={}", encode_component(k.as_slice()),
-               encode_component(v.as_slice()));
-    }
-    str::from_utf8_lossy(writer.unwrap().as_slice()).to_string()
+    query.iter().enumerate().fold(String::new(), |mut out, (i, &(ref k, ref v))| {
+        if i != 0 {
+            out.push_char('&');
+        }
+
+        out.push_str(encode_component(k.as_slice()).as_slice());
+        out.push_char('=');
+        out.push_str(encode_component(v.as_slice()).as_slice());
+        out
+    })
 }
 
-/**
- * Returns a tuple of the URI scheme and the rest of the URI, or a parsing error.
- *
- * Does not include the separating `:` character.
- *
- * # Example
- *
- * ```rust
- * use url::get_scheme;
- *
- * let scheme = match get_scheme("https://example.com/") {
- *     Ok((sch, _)) => sch,
- *     Err(_) => "(None)".to_string(),
- * };
- * println!("Scheme in use: {}.", scheme); // Scheme in use: https.
- * ```
- */
-pub fn get_scheme(rawurl: &str) -> Result<(String, String), String> {
+/// Returns a tuple of the URI scheme and the rest of the URI, or a parsing error.
+///
+/// Does not include the separating `:` character.
+///
+/// # Example
+///
+/// ```rust
+/// use url::get_scheme;
+///
+/// let scheme = match get_scheme("https://example.com/") {
+///     Ok((sch, _)) => sch,
+///     Err(_) => "(None)",
+/// };
+/// println!("Scheme in use: {}.", scheme); // Scheme in use: https.
+/// ```
+pub fn get_scheme<'a>(rawurl: &'a str) -> DecodeResult<(&'a str, &'a str)> {
     for (i,c) in rawurl.chars().enumerate() {
-        match c {
-          'A' .. 'Z' | 'a' .. 'z' => continue,
-          '0' .. '9' | '+' | '-' | '.' => {
-            if i == 0 {
-                return Err("url: Scheme must begin with a \
-                            letter.".to_string());
+        let result = match c {
+            'A' .. 'Z'
+            | 'a' .. 'z' => continue,
+            '0' .. '9' | '+' | '-' | '.' => {
+                if i != 0 { continue }
+
+                Err("url: Scheme must begin with a letter.".to_string())
             }
-            continue;
-          }
-          ':' => {
-            if i == 0 {
-                return Err("url: Scheme cannot be empty.".to_string());
-            } else {
-                return Ok((rawurl.slice(0,i).to_string(),
-                           rawurl.slice(i+1,rawurl.len()).to_string()));
+            ':' => {
+                if i == 0 {
+                    Err("url: Scheme cannot be empty.".to_string())
+                } else {
+                    Ok((rawurl.slice(0,i), rawurl.slice(i+1,rawurl.len())))
+                }
             }
-          }
-          _ => {
-            return Err("url: Invalid character in scheme.".to_string());
-          }
-        }
-    };
-    return Err("url: Scheme must be terminated with a colon.".to_string());
-}
+            _ => Err("url: Invalid character in scheme.".to_string()),
+        };
 
-#[deriving(Clone, PartialEq)]
-enum Input {
-    Digit, // all digits
-    Hex, // digits and letters a-f
-    Unreserved // all other legal characters
+        return result;
+    }
+
+    Err("url: Scheme must be terminated with a colon.".to_string())
 }
 
 // returns userinfo, host, port, and unparsed part, or an error
-fn get_authority(rawurl: &str) ->
-    Result<(Option<UserInfo>, String, Option<String>, String), String> {
-    if !rawurl.starts_with("//") {
-        // there is no authority.
-        return Ok((None, "".to_string(), None, rawurl.to_str()));
-    }
-
+fn get_authority<'a>(rawurl: &'a str) ->
+    DecodeResult<(Option<UserInfo>, &'a str, Option<u16>, &'a str)> {
     enum State {
         Start, // starting state
         PassHostPort, // could be in user or port
@@ -538,12 +501,24 @@ enum State {
         InPort // are in port
     }
 
+    #[deriving(Clone, PartialEq)]
+    enum Input {
+        Digit, // all digits
+        Hex, // digits and letters a-f
+        Unreserved // all other legal characters
+    }
+
+    if !rawurl.starts_with("//") {
+        // there is no authority.
+        return Ok((None, "", None, rawurl));
+    }
+
     let len = rawurl.len();
     let mut st = Start;
     let mut input = Digit; // most restricted, start here.
 
     let mut userinfo = None;
-    let mut host = "".to_string();
+    let mut host = "";
     let mut port = None;
 
     let mut colon_count = 0u;
@@ -551,27 +526,27 @@ enum State {
     let mut begin = 2;
     let mut end = len;
 
-    for (i,c) in rawurl.chars().enumerate() {
-        if i < 2 { continue; } // ignore the leading //
-
+    for (i,c) in rawurl.chars().enumerate()
+                               // ignore the leading '//' handled by early return
+                               .skip(2) {
         // deal with input class first
         match c {
-          '0' .. '9' => (),
-          'A' .. 'F' | 'a' .. 'f' => {
-            if input == Digit {
-                input = Hex;
+            '0' .. '9' => (),
+            'A' .. 'F'
+            | 'a' .. 'f' => {
+                if input == Digit {
+                    input = Hex;
+                }
             }
-          }
-          'G' .. 'Z' | 'g' .. 'z' | '-' | '.' | '_' | '~' | '%' |
-          '&' |'\'' | '(' | ')' | '+' | '!' | '*' | ',' | ';' | '=' => {
-            input = Unreserved;
-          }
-          ':' | '@' | '?' | '#' | '/' => {
-            // separators, don't change anything
-          }
-          _ => {
-            return Err("Illegal character in authority".to_string());
-          }
+            'G' .. 'Z'
+            | 'g' .. 'z'
+            | '-' | '.' | '_' | '~' | '%'
+            | '&' |'\'' | '(' | ')' | '+'
+            | '!' | '*' | ',' | ';' | '=' => input = Unreserved,
+            ':' | '@' | '?' | '#' | '/' => {
+                // separators, don't change anything
+            }
+            _ => return Err("Illegal character in authority".to_string()),
         }
 
         // now process states
@@ -595,7 +570,7 @@ enum State {
                 pos = i;
                 if input == Unreserved {
                     // must be port
-                    host = rawurl.slice(begin, i).to_string();
+                    host = rawurl.slice(begin, i);
                     st = InPort;
                 } else {
                     // can't be sure whether this is an ipv6 address or a port
@@ -604,21 +579,18 @@ enum State {
               }
               Ip6Port => {
                 if input == Unreserved {
-                    return Err("Illegal characters in \
-                                authority.".to_string());
+                    return Err("Illegal characters in authority.".to_string());
                 }
                 st = Ip6Host;
               }
               Ip6Host => {
                 if colon_count > 7 {
-                    host = rawurl.slice(begin, i).to_string();
+                    host = rawurl.slice(begin, i);
                     pos = i;
                     st = InPort;
                 }
               }
-              _ => {
-                return Err("Invalid ':' in authority.".to_string());
-              }
+              _ => return Err("Invalid ':' in authority.".to_string()),
             }
             input = Digit; // reset input class
           }
@@ -638,9 +610,7 @@ enum State {
                 userinfo = Some(UserInfo::new(user, Some(pass)));
                 st = InHost;
               }
-              _ => {
-                return Err("Invalid '@' in authority.".to_string());
-              }
+              _ => return Err("Invalid '@' in authority.".to_string()),
             }
             begin = i+1;
           }
@@ -655,44 +625,53 @@ enum State {
 
     // finish up
     match st {
-      Start => {
-        host = rawurl.slice(begin, end).to_string();
-      }
-      PassHostPort | Ip6Port => {
+      Start => host = rawurl.slice(begin, end),
+      PassHostPort
+      | Ip6Port => {
         if input != Digit {
             return Err("Non-digit characters in port.".to_string());
         }
-        host = rawurl.slice(begin, pos).to_string();
-        port = Some(rawurl.slice(pos+1, end).to_string());
-      }
-      Ip6Host | InHost => {
-        host = rawurl.slice(begin, end).to_string();
+        host = rawurl.slice(begin, pos);
+        port = Some(rawurl.slice(pos+1, end));
       }
+      Ip6Host
+      | InHost => host = rawurl.slice(begin, end),
       InPort => {
         if input != Digit {
             return Err("Non-digit characters in port.".to_string());
         }
-        port = Some(rawurl.slice(pos+1, end).to_string());
+        port = Some(rawurl.slice(pos+1, end));
       }
     }
 
-    let rest = rawurl.slice(end, len).to_string();
-    return Ok((userinfo, host, port, rest));
+    let rest = rawurl.slice(end, len);
+    // If we have a port string, ensure it parses to u16.
+    let port = match port {
+        None => None,
+        opt => match opt.and_then(|p| FromStr::from_str(p)) {
+            None => return Err(format!("Failed to parse port: {}", port)),
+            opt => opt
+        }
+    };
+
+    Ok((userinfo, host, port, rest))
 }
 
 
 // returns the path and unparsed part of url, or an error
-fn get_path(rawurl: &str, authority: bool) ->
-    Result<(String, String), String> {
+fn get_path<'a>(rawurl: &'a str, is_authority: bool)
+                                            -> DecodeResult<(String, &'a str)> {
     let len = rawurl.len();
     let mut end = len;
     for (i,c) in rawurl.chars().enumerate() {
         match c {
-          'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '&' |'\'' | '(' | ')' | '.'
-          | '@' | ':' | '%' | '/' | '+' | '!' | '*' | ',' | ';' | '='
-          | '_' | '-' | '~' => {
-            continue;
-          }
+          'A' .. 'Z'
+          | 'a' .. 'z'
+          | '0' .. '9'
+          | '&' |'\'' | '(' | ')' | '.'
+          | '@' | ':' | '%' | '/' | '+'
+          | '!' | '*' | ',' | ';' | '='
+          | '_' | '-' | '~' => continue,
           '?' | '#' => {
             end = i;
             break;
@@ -701,127 +680,53 @@ fn get_path(rawurl: &str, authority: bool) ->
         }
     }
 
-    if authority {
-        if end != 0 && !rawurl.starts_with("/") {
-            return Err("Non-empty path must begin with\
-                              '/' in presence of authority.".to_string());
-        }
+    if is_authority && end != 0 && !rawurl.starts_with("/") {
+        Err("Non-empty path must begin with \
+            '/' in presence of authority.".to_string())
+    } else {
+        Ok((try!(decode_component(rawurl.slice(0, end))),
+            rawurl.slice(end, len)))
     }
-
-    return Ok((decode_component(rawurl.slice(0, end)),
-                    rawurl.slice(end, len).to_string()));
 }
 
 // returns the parsed query and the fragment, if present
-fn get_query_fragment(rawurl: &str) ->
-    Result<(Query, Option<String>), String> {
-    if !rawurl.starts_with("?") {
-        if rawurl.starts_with("#") {
-            let f = decode_component(rawurl.slice(
-                                                1,
-                                                rawurl.len()));
-            return Ok((vec!(), Some(f)));
-        } else {
-            return Ok((vec!(), None));
-        }
-    }
-    let (q, r) = split_char_first(rawurl.slice(1, rawurl.len()), '#');
-    let f = if r.len() != 0 {
-        Some(decode_component(r.as_slice()))
-    } else {
-        None
-    };
-    return Ok((query_from_str(q.as_slice()), f));
-}
-
-/**
- * Parses a URL, converting it from a string to `Url` representation.
- *
- * # Arguments
- *
- * `rawurl` - a string representing the full URL, including scheme.
- *
- * # Returns
- *
- * A `Url` struct type representing the URL.
- */
-pub fn from_str(rawurl: &str) -> Result<Url, String> {
-    // scheme
-    let (scheme, rest) = match get_scheme(rawurl) {
-        Ok(val) => val,
-        Err(e) => return Err(e),
-    };
-
-    // authority
-    let (userinfo, host, port, rest) = match get_authority(rest.as_slice()) {
-        Ok(val) => val,
-        Err(e) => return Err(e),
-    };
-
-    // path
-    let has_authority = host.len() > 0;
-    let (path, rest) = match get_path(rest.as_slice(), has_authority) {
-        Ok(val) => val,
-        Err(e) => return Err(e),
-    };
-
-    // query and fragment
-    let (query, fragment) = match get_query_fragment(rest.as_slice()) {
-        Ok(val) => val,
-        Err(e) => return Err(e),
-    };
-
-    Ok(Url::new(scheme, userinfo, host, port, path, query, fragment))
-}
-
-pub fn path_from_str(rawpath: &str) -> Result<Path, String> {
-    let (path, rest) = match get_path(rawpath, false) {
-        Ok(val) => val,
-        Err(e) => return Err(e)
-    };
+fn get_query_fragment(rawurl: &str) -> DecodeResult<(Query, Option<String>)> {
+    let (before_fragment, raw_fragment) = split_char_first(rawurl, '#');
 
-    // query and fragment
-    let (query, fragment) = match get_query_fragment(rest.as_slice()) {
-        Ok(val) => val,
-        Err(e) => return Err(e),
+    // Parse the fragment if available
+    let fragment = match raw_fragment {
+        "" => None,
+        raw => Some(try!(decode_component(raw)))
     };
 
-    Ok(Path{ path: path, query: query, fragment: fragment })
+    match before_fragment.slice_shift_char() {
+        (Some('?'), rest) => Ok((try!(query_from_str(rest)), fragment)),
+        (None, "") => Ok((vec!(), fragment)),
+        _ => Err(format!("Query didn't start with '?': '{}..'", before_fragment)),
+    }
 }
 
 impl FromStr for Url {
     fn from_str(s: &str) -> Option<Url> {
-        match from_str(s) {
-            Ok(url) => Some(url),
-            Err(_) => None
-        }
+        Url::parse(s).ok()
     }
 }
 
 impl FromStr for Path {
     fn from_str(s: &str) -> Option<Path> {
-        match path_from_str(s) {
-            Ok(path) => Some(path),
-            Err(_) => None
-        }
+        Path::parse(s).ok()
     }
 }
 
 impl fmt::Show for Url {
-    /**
-     * Converts a URL from `Url` to string representation.
-     *
-     * # Arguments
-     *
-     * `url` - a URL.
-     *
-     * # Returns
-     *
-     * A string that contains the formatted URL. Note that this will usually
-     * be an inverse of `from_str` but might strip out unneeded separators;
-     * for example, "http://somehost.com?", when parsed and formatted, will
-     * result in just "http://somehost.com".
-     */
+    /// Converts a URL from `Url` to string representation.
+    ///
+    /// # Returns
+    ///
+    /// A string that contains the formatted URL. Note that this will usually
+    /// be an inverse of `from_str` but might strip out unneeded separators;
+    /// for example, "http://somehost.com?", when parsed and formatted, will
+    /// result in just "http://somehost.com".
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         try!(write!(f, "{}:", self.scheme));
 
@@ -838,18 +743,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             }
         }
 
-        try!(write!(f, "{}", self.path));
-
-        if !self.query.is_empty() {
-            try!(write!(f, "?{}", query_to_str(&self.query)));
-        }
-
-        match self.fragment {
-            Some(ref fragment) => {
-                write!(f, "#{}", encode_component(fragment.as_slice()))
-            }
-            None => Ok(()),
-        }
+        write!(f, "{}", self.path)
     }
 }
 
@@ -857,7 +751,7 @@ impl fmt::Show for Path {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         try!(write!(f, "{}", self.path));
         if !self.query.is_empty() {
-            try!(write!(f, "?{}", self.query))
+            try!(write!(f, "?{}", query_to_str(&self.query)))
         }
 
         match self.fragment {
@@ -871,13 +765,13 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 impl<S: hash::Writer> hash::Hash<S> for Url {
     fn hash(&self, state: &mut S) {
-        self.to_str().hash(state)
+        self.to_string().hash(state)
     }
 }
 
 impl<S: hash::Writer> hash::Hash<S> for Path {
     fn hash(&self, state: &mut S) {
-        self.to_str().hash(state)
+        self.to_string().hash(state)
     }
 }
 
@@ -887,12 +781,12 @@ fn hash(&self, state: &mut S) {
 #[test]
 fn test_split_char_first() {
     let (u,v) = split_char_first("hello, sweet world", ',');
-    assert_eq!(u, "hello".to_string());
-    assert_eq!(v, " sweet world".to_string());
+    assert_eq!(u, "hello");
+    assert_eq!(v, " sweet world");
 
     let (u,v) = split_char_first("hello sweet world", ',');
-    assert_eq!(u, "hello sweet world".to_string());
-    assert_eq!(v, "".to_string());
+    assert_eq!(u, "hello sweet world");
+    assert_eq!(v, "");
 }
 
 #[test]
@@ -900,40 +794,39 @@ fn test_get_authority() {
     let (u, h, p, r) = get_authority(
         "//user:pass@rust-lang.org/something").unwrap();
     assert_eq!(u, Some(UserInfo::new("user".to_string(), Some("pass".to_string()))));
-    assert_eq!(h, "rust-lang.org".to_string());
+    assert_eq!(h, "rust-lang.org");
     assert!(p.is_none());
-    assert_eq!(r, "/something".to_string());
+    assert_eq!(r, "/something");
 
     let (u, h, p, r) = get_authority(
         "//rust-lang.org:8000?something").unwrap();
     assert!(u.is_none());
-    assert_eq!(h, "rust-lang.org".to_string());
-    assert_eq!(p, Some("8000".to_string()));
-    assert_eq!(r, "?something".to_string());
+    assert_eq!(h, "rust-lang.org");
+    assert_eq!(p, Some(8000));
+    assert_eq!(r, "?something");
 
-    let (u, h, p, r) = get_authority(
-        "//rust-lang.org#blah").unwrap();
+    let (u, h, p, r) = get_authority("//rust-lang.org#blah").unwrap();
     assert!(u.is_none());
-    assert_eq!(h, "rust-lang.org".to_string());
+    assert_eq!(h, "rust-lang.org");
     assert!(p.is_none());
-    assert_eq!(r, "#blah".to_string());
+    assert_eq!(r, "#blah");
 
     // ipv6 tests
     let (_, h, _, _) = get_authority(
         "//2001:0db8:85a3:0042:0000:8a2e:0370:7334#blah").unwrap();
-    assert_eq!(h, "2001:0db8:85a3:0042:0000:8a2e:0370:7334".to_string());
+    assert_eq!(h, "2001:0db8:85a3:0042:0000:8a2e:0370:7334");
 
     let (_, h, p, _) = get_authority(
         "//2001:0db8:85a3:0042:0000:8a2e:0370:7334:8000#blah").unwrap();
-    assert_eq!(h, "2001:0db8:85a3:0042:0000:8a2e:0370:7334".to_string());
-    assert_eq!(p, Some("8000".to_string()));
+    assert_eq!(h, "2001:0db8:85a3:0042:0000:8a2e:0370:7334");
+    assert_eq!(p, Some(8000));
 
     let (u, h, p, _) = get_authority(
         "//us:p@2001:0db8:85a3:0042:0000:8a2e:0370:7334:8000#blah"
     ).unwrap();
     assert_eq!(u, Some(UserInfo::new("us".to_string(), Some("p".to_string()))));
-    assert_eq!(h, "2001:0db8:85a3:0042:0000:8a2e:0370:7334".to_string());
-    assert_eq!(p, Some("8000".to_string()));
+    assert_eq!(h, "2001:0db8:85a3:0042:0000:8a2e:0370:7334");
+    assert_eq!(p, Some(8000));
 
     // invalid authorities;
     assert!(get_authority("//user:pass@rust-lang:something").is_err());
@@ -942,25 +835,27 @@ fn test_get_authority() {
         "//2001:0db8:85a3:0042:0000:8a2e:0370:7334:800a").is_err());
     assert!(get_authority(
         "//2001:0db8:85a3:0042:0000:8a2e:0370:7334:8000:00").is_err());
+    // outside u16 range
+    assert!(get_authority("//user:pass@rust-lang:65536").is_err());
 
     // these parse as empty, because they don't start with '//'
     let (_, h, _, _) = get_authority("user:pass@rust-lang").unwrap();
-    assert_eq!(h, "".to_string());
+    assert_eq!(h, "");
     let (_, h, _, _) = get_authority("rust-lang.org").unwrap();
-    assert_eq!(h, "".to_string());
+    assert_eq!(h, "");
 }
 
 #[test]
 fn test_get_path() {
     let (p, r) = get_path("/something+%20orother", true).unwrap();
     assert_eq!(p, "/something+ orother".to_string());
-    assert_eq!(r, "".to_string());
+    assert_eq!(r, "");
     let (p, r) = get_path("test@email.com#fragment", false).unwrap();
     assert_eq!(p, "test@email.com".to_string());
-    assert_eq!(r, "#fragment".to_string());
+    assert_eq!(r, "#fragment");
     let (p, r) = get_path("/gen/:addr=?q=v", false).unwrap();
     assert_eq!(p, "/gen/:addr=".to_string());
-    assert_eq!(r, "?q=v".to_string());
+    assert_eq!(r, "?q=v");
 
     //failure cases
     assert!(get_path("something?q", true).is_err());
@@ -968,96 +863,95 @@ fn test_get_path() {
 
 #[cfg(test)]
 mod tests {
-    use {encode_form_urlencoded, decode_form_urlencoded,
-         decode, encode, from_str, encode_component, decode_component,
-         path_from_str, UserInfo, get_scheme};
+    use {encode_form_urlencoded, decode_form_urlencoded, decode, encode,
+        encode_component, decode_component, UserInfo, get_scheme, Url, Path};
 
     use std::collections::HashMap;
+    use std::path::BytesContainer;
 
     #[test]
     fn test_url_parse() {
         let url = "http://user:pass@rust-lang.org:8080/doc/~u?s=v#something";
-
-        let up = from_str(url);
-        let u = up.unwrap();
-        assert_eq!(&u.scheme, &"http".to_string());
-        assert_eq!(&u.user, &Some(UserInfo::new("user".to_string(), Some("pass".to_string()))));
-        assert_eq!(&u.host, &"rust-lang.org".to_string());
-        assert_eq!(&u.port, &Some("8080".to_string()));
-        assert_eq!(&u.path, &"/doc/~u".to_string());
-        assert_eq!(&u.query, &vec!(("s".to_string(), "v".to_string())));
-        assert_eq!(&u.fragment, &Some("something".to_string()));
+        let u = from_str::<Url>(url).unwrap();
+
+        assert_eq!(u.scheme, "http".to_string());
+        assert_eq!(u.user, Some(UserInfo::new("user".to_string(), Some("pass".to_string()))));
+        assert_eq!(u.host, "rust-lang.org".to_string());
+        assert_eq!(u.port, Some(8080));
+        assert_eq!(u.path.path, "/doc/~u".to_string());
+        assert_eq!(u.path.query, vec!(("s".to_string(), "v".to_string())));
+        assert_eq!(u.path.fragment, Some("something".to_string()));
     }
 
     #[test]
     fn test_path_parse() {
         let path = "/doc/~u?s=v#something";
+        let u = from_str::<Path>(path).unwrap();
 
-        let up = path_from_str(path);
-        let u = up.unwrap();
-        assert_eq!(&u.path, &"/doc/~u".to_string());
-        assert_eq!(&u.query, &vec!(("s".to_string(), "v".to_string())));
-        assert_eq!(&u.fragment, &Some("something".to_string()));
+        assert_eq!(u.path, "/doc/~u".to_string());
+        assert_eq!(u.query, vec!(("s".to_string(), "v".to_string())));
+        assert_eq!(u.fragment, Some("something".to_string()));
     }
 
     #[test]
     fn test_url_parse_host_slash() {
         let urlstr = "http://0.42.42.42/";
-        let url = from_str(urlstr).unwrap();
-        assert!(url.host == "0.42.42.42".to_string());
-        assert!(url.path == "/".to_string());
+        let url = from_str::<Url>(urlstr).unwrap();
+        assert_eq!(url.host, "0.42.42.42".to_string());
+        assert_eq!(url.path.path, "/".to_string());
     }
 
     #[test]
     fn test_path_parse_host_slash() {
         let pathstr = "/";
-        let path = path_from_str(pathstr).unwrap();
-        assert!(path.path == "/".to_string());
+        let path = from_str::<Path>(pathstr).unwrap();
+        assert_eq!(path.path, "/".to_string());
     }
 
     #[test]
     fn test_url_host_with_port() {
         let urlstr = "scheme://host:1234";
-        let url = from_str(urlstr).unwrap();
-        assert_eq!(&url.scheme, &"scheme".to_string());
-        assert_eq!(&url.host, &"host".to_string());
-        assert_eq!(&url.port, &Some("1234".to_string()));
+        let url = from_str::<Url>(urlstr).unwrap();
+        assert_eq!(url.scheme, "scheme".to_string());
+        assert_eq!(url.host, "host".to_string());
+        assert_eq!(url.port, Some(1234));
         // is empty path really correct? Other tests think so
-        assert_eq!(&url.path, &"".to_string());
+        assert_eq!(url.path.path, "".to_string());
+
         let urlstr = "scheme://host:1234/";
-        let url = from_str(urlstr).unwrap();
-        assert_eq!(&url.scheme, &"scheme".to_string());
-        assert_eq!(&url.host, &"host".to_string());
-        assert_eq!(&url.port, &Some("1234".to_string()));
-        assert_eq!(&url.path, &"/".to_string());
+        let url = from_str::<Url>(urlstr).unwrap();
+        assert_eq!(url.scheme, "scheme".to_string());
+        assert_eq!(url.host, "host".to_string());
+        assert_eq!(url.port, Some(1234));
+        assert_eq!(url.path.path, "/".to_string());
     }
 
     #[test]
     fn test_url_with_underscores() {
         let urlstr = "http://dotcom.com/file_name.html";
-        let url = from_str(urlstr).unwrap();
-        assert!(url.path == "/file_name.html".to_string());
+        let url = from_str::<Url>(urlstr).unwrap();
+        assert_eq!(url.path.path, "/file_name.html".to_string());
     }
 
     #[test]
     fn test_path_with_underscores() {
         let pathstr = "/file_name.html";
-        let path = path_from_str(pathstr).unwrap();
-        assert!(path.path == "/file_name.html".to_string());
+        let path = from_str::<Path>(pathstr).unwrap();
+        assert_eq!(path.path, "/file_name.html".to_string());
     }
 
     #[test]
     fn test_url_with_dashes() {
         let urlstr = "http://dotcom.com/file-name.html";
-        let url = from_str(urlstr).unwrap();
-        assert!(url.path == "/file-name.html".to_string());
+        let url = from_str::<Url>(urlstr).unwrap();
+        assert_eq!(url.path.path, "/file-name.html".to_string());
     }
 
     #[test]
     fn test_path_with_dashes() {
         let pathstr = "/file-name.html";
-        let path = path_from_str(pathstr).unwrap();
-        assert!(path.path == "/file-name.html".to_string());
+        let path = from_str::<Path>(pathstr).unwrap();
+        assert_eq!(path.path, "/file-name.html".to_string());
     }
 
     #[test]
@@ -1067,83 +961,93 @@ fn test_no_scheme() {
 
     #[test]
     fn test_invalid_scheme_errors() {
-        assert!(from_str("99://something").is_err());
-        assert!(from_str("://something").is_err());
+        assert!(Url::parse("99://something").is_err());
+        assert!(Url::parse("://something").is_err());
     }
 
     #[test]
     fn test_full_url_parse_and_format() {
         let url = "http://user:pass@rust-lang.org/doc?s=v#something";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), url);
     }
 
     #[test]
     fn test_userless_url_parse_and_format() {
         let url = "http://rust-lang.org/doc?s=v#something";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), url);
     }
 
     #[test]
     fn test_queryless_url_parse_and_format() {
         let url = "http://user:pass@rust-lang.org/doc#something";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), url);
     }
 
     #[test]
     fn test_empty_query_url_parse_and_format() {
         let url = "http://user:pass@rust-lang.org/doc?#something";
         let should_be = "http://user:pass@rust-lang.org/doc#something";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), should_be);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), should_be);
     }
 
     #[test]
     fn test_fragmentless_url_parse_and_format() {
         let url = "http://user:pass@rust-lang.org/doc?q=v";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), url);
     }
 
     #[test]
     fn test_minimal_url_parse_and_format() {
         let url = "http://rust-lang.org/doc";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), url);
     }
 
     #[test]
     fn test_url_with_port_parse_and_format() {
         let url = "http://rust-lang.org:80/doc";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), url);
     }
 
     #[test]
     fn test_scheme_host_only_url_parse_and_format() {
         let url = "http://rust-lang.org";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), url);
     }
 
     #[test]
     fn test_pathless_url_parse_and_format() {
         let url = "http://user:pass@rust-lang.org?q=v#something";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), url);
     }
 
     #[test]
     fn test_scheme_host_fragment_only_url_parse_and_format() {
         let url = "http://rust-lang.org#something";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), url);
     }
 
     #[test]
     fn test_url_component_encoding() {
         let url = "http://rust-lang.org/doc%20uments?ba%25d%20=%23%26%2B";
-        let u = from_str(url).unwrap();
-        assert!(u.path == "/doc uments".to_string());
-        assert!(u.query == vec!(("ba%d ".to_string(), "#&+".to_string())));
+        let u = from_str::<Url>(url).unwrap();
+        assert!(u.path.path == "/doc uments".to_string());
+        assert!(u.path.query == vec!(("ba%d ".to_string(), "#&+".to_string())));
     }
 
     #[test]
     fn test_path_component_encoding() {
         let path = "/doc%20uments?ba%25d%20=%23%26%2B";
-        let p = path_from_str(path).unwrap();
+        let p = from_str::<Path>(path).unwrap();
         assert!(p.path == "/doc uments".to_string());
         assert!(p.query == vec!(("ba%d ".to_string(), "#&+".to_string())));
     }
@@ -1151,124 +1055,151 @@ fn test_path_component_encoding() {
     #[test]
     fn test_url_without_authority() {
         let url = "mailto:test@email.com";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), url);
     }
 
     #[test]
     fn test_encode() {
-        assert_eq!(encode(""), "".to_string());
-        assert_eq!(encode("http://example.com"), "http://example.com".to_string());
-        assert_eq!(encode("foo bar% baz"), "foo%20bar%25%20baz".to_string());
-        assert_eq!(encode(" "), "%20".to_string());
-        assert_eq!(encode("!"), "!".to_string());
-        assert_eq!(encode("\""), "\"".to_string());
-        assert_eq!(encode("#"), "#".to_string());
-        assert_eq!(encode("$"), "$".to_string());
-        assert_eq!(encode("%"), "%25".to_string());
-        assert_eq!(encode("&"), "&".to_string());
-        assert_eq!(encode("'"), "%27".to_string());
-        assert_eq!(encode("("), "(".to_string());
-        assert_eq!(encode(")"), ")".to_string());
-        assert_eq!(encode("*"), "*".to_string());
-        assert_eq!(encode("+"), "+".to_string());
-        assert_eq!(encode(","), ",".to_string());
-        assert_eq!(encode("/"), "/".to_string());
-        assert_eq!(encode(":"), ":".to_string());
-        assert_eq!(encode(";"), ";".to_string());
-        assert_eq!(encode("="), "=".to_string());
-        assert_eq!(encode("?"), "?".to_string());
-        assert_eq!(encode("@"), "@".to_string());
-        assert_eq!(encode("["), "[".to_string());
-        assert_eq!(encode("]"), "]".to_string());
-        assert_eq!(encode("\0"), "%00".to_string());
-        assert_eq!(encode("\n"), "%0A".to_string());
+        fn t<T: BytesContainer>(input: T, expected: &str) {
+            assert_eq!(encode(input), expected.to_string())
+        }
+
+        t("", "");
+        t("http://example.com", "http://example.com");
+        t("foo bar% baz", "foo%20bar%25%20baz");
+        t(" ", "%20");
+        t("!", "!");
+        t("\"", "\"");
+        t("#", "#");
+        t("$", "$");
+        t("%", "%25");
+        t("&", "&");
+        t("'", "%27");
+        t("(", "(");
+        t(")", ")");
+        t("*", "*");
+        t("+", "+");
+        t(",", ",");
+        t("/", "/");
+        t(":", ":");
+        t(";", ";");
+        t("=", "=");
+        t("?", "?");
+        t("@", "@");
+        t("[", "[");
+        t("]", "]");
+        t("\0", "%00");
+        t("\n", "%0A");
+
+        t(&[0u8, 10, 37], "%00%0A%25");
     }
 
     #[test]
     fn test_encode_component() {
-        assert_eq!(encode_component(""), "".to_string());
-        assert!(encode_component("http://example.com") ==
-            "http%3A%2F%2Fexample.com".to_string());
-        assert!(encode_component("foo bar% baz") ==
-            "foo%20bar%25%20baz".to_string());
-        assert_eq!(encode_component(" "), "%20".to_string());
-        assert_eq!(encode_component("!"), "%21".to_string());
-        assert_eq!(encode_component("#"), "%23".to_string());
-        assert_eq!(encode_component("$"), "%24".to_string());
-        assert_eq!(encode_component("%"), "%25".to_string());
-        assert_eq!(encode_component("&"), "%26".to_string());
-        assert_eq!(encode_component("'"), "%27".to_string());
-        assert_eq!(encode_component("("), "%28".to_string());
-        assert_eq!(encode_component(")"), "%29".to_string());
-        assert_eq!(encode_component("*"), "%2A".to_string());
-        assert_eq!(encode_component("+"), "%2B".to_string());
-        assert_eq!(encode_component(","), "%2C".to_string());
-        assert_eq!(encode_component("/"), "%2F".to_string());
-        assert_eq!(encode_component(":"), "%3A".to_string());
-        assert_eq!(encode_component(";"), "%3B".to_string());
-        assert_eq!(encode_component("="), "%3D".to_string());
-        assert_eq!(encode_component("?"), "%3F".to_string());
-        assert_eq!(encode_component("@"), "%40".to_string());
-        assert_eq!(encode_component("["), "%5B".to_string());
-        assert_eq!(encode_component("]"), "%5D".to_string());
-        assert_eq!(encode_component("\0"), "%00".to_string());
-        assert_eq!(encode_component("\n"), "%0A".to_string());
+        fn t<T: BytesContainer>(input: T, expected: &str) {
+            assert_eq!(encode_component(input), expected.to_string())
+        }
+
+        t("", "");
+        t("http://example.com", "http%3A%2F%2Fexample.com");
+        t("foo bar% baz", "foo%20bar%25%20baz");
+        t(" ", "%20");
+        t("!", "%21");
+        t("#", "%23");
+        t("$", "%24");
+        t("%", "%25");
+        t("&", "%26");
+        t("'", "%27");
+        t("(", "%28");
+        t(")", "%29");
+        t("*", "%2A");
+        t("+", "%2B");
+        t(",", "%2C");
+        t("/", "%2F");
+        t(":", "%3A");
+        t(";", "%3B");
+        t("=", "%3D");
+        t("?", "%3F");
+        t("@", "%40");
+        t("[", "%5B");
+        t("]", "%5D");
+        t("\0", "%00");
+        t("\n", "%0A");
+
+        t(&[0u8, 10, 37], "%00%0A%25");
     }
 
     #[test]
     fn test_decode() {
-        assert_eq!(decode(""), "".to_string());
-        assert_eq!(decode("abc/def 123"), "abc/def 123".to_string());
-        assert_eq!(decode("abc%2Fdef%20123"), "abc%2Fdef 123".to_string());
-        assert_eq!(decode("%20"), " ".to_string());
-        assert_eq!(decode("%21"), "%21".to_string());
-        assert_eq!(decode("%22"), "%22".to_string());
-        assert_eq!(decode("%23"), "%23".to_string());
-        assert_eq!(decode("%24"), "%24".to_string());
-        assert_eq!(decode("%25"), "%".to_string());
-        assert_eq!(decode("%26"), "%26".to_string());
-        assert_eq!(decode("%27"), "'".to_string());
-        assert_eq!(decode("%28"), "%28".to_string());
-        assert_eq!(decode("%29"), "%29".to_string());
-        assert_eq!(decode("%2A"), "%2A".to_string());
-        assert_eq!(decode("%2B"), "%2B".to_string());
-        assert_eq!(decode("%2C"), "%2C".to_string());
-        assert_eq!(decode("%2F"), "%2F".to_string());
-        assert_eq!(decode("%3A"), "%3A".to_string());
-        assert_eq!(decode("%3B"), "%3B".to_string());
-        assert_eq!(decode("%3D"), "%3D".to_string());
-        assert_eq!(decode("%3F"), "%3F".to_string());
-        assert_eq!(decode("%40"), "%40".to_string());
-        assert_eq!(decode("%5B"), "%5B".to_string());
-        assert_eq!(decode("%5D"), "%5D".to_string());
+        fn t<T: BytesContainer>(input: T, expected: &str) {
+            assert_eq!(decode(input), Ok(expected.to_string()))
+        }
+
+        assert!(decode("sadsadsda%").is_err());
+        assert!(decode("waeasd%4").is_err());
+        t("", "");
+        t("abc/def 123", "abc/def 123");
+        t("abc%2Fdef%20123", "abc%2Fdef 123");
+        t("%20", " ");
+        t("%21", "%21");
+        t("%22", "%22");
+        t("%23", "%23");
+        t("%24", "%24");
+        t("%25", "%");
+        t("%26", "%26");
+        t("%27", "'");
+        t("%28", "%28");
+        t("%29", "%29");
+        t("%2A", "%2A");
+        t("%2B", "%2B");
+        t("%2C", "%2C");
+        t("%2F", "%2F");
+        t("%3A", "%3A");
+        t("%3B", "%3B");
+        t("%3D", "%3D");
+        t("%3F", "%3F");
+        t("%40", "%40");
+        t("%5B", "%5B");
+        t("%5D", "%5D");
+
+        t("%00%0A%25".as_bytes(), "\0\n%");
     }
 
     #[test]
     fn test_decode_component() {
-        assert_eq!(decode_component(""), "".to_string());
-        assert_eq!(decode_component("abc/def 123"), "abc/def 123".to_string());
-        assert_eq!(decode_component("abc%2Fdef%20123"), "abc/def 123".to_string());
-        assert_eq!(decode_component("%20"), " ".to_string());
-        assert_eq!(decode_component("%21"), "!".to_string());
-        assert_eq!(decode_component("%22"), "\"".to_string());
-        assert_eq!(decode_component("%23"), "#".to_string());
-        assert_eq!(decode_component("%24"), "$".to_string());
-        assert_eq!(decode_component("%25"), "%".to_string());
-        assert_eq!(decode_component("%26"), "&".to_string());
-        assert_eq!(decode_component("%27"), "'".to_string());
-        assert_eq!(decode_component("%28"), "(".to_string());
-        assert_eq!(decode_component("%29"), ")".to_string());
-        assert_eq!(decode_component("%2A"), "*".to_string());
-        assert_eq!(decode_component("%2B"), "+".to_string());
-        assert_eq!(decode_component("%2C"), ",".to_string());
-        assert_eq!(decode_component("%2F"), "/".to_string());
-        assert_eq!(decode_component("%3A"), ":".to_string());
-        assert_eq!(decode_component("%3B"), ";".to_string());
-        assert_eq!(decode_component("%3D"), "=".to_string());
-        assert_eq!(decode_component("%3F"), "?".to_string());
-        assert_eq!(decode_component("%40"), "@".to_string());
-        assert_eq!(decode_component("%5B"), "[".to_string());
-        assert_eq!(decode_component("%5D"), "]".to_string());
+        fn t<T: BytesContainer>(input: T, expected: &str) {
+            assert_eq!(decode_component(input), Ok(expected.to_string()))
+        }
+
+        assert!(decode_component("asacsa%").is_err());
+        assert!(decode_component("acsas%4").is_err());
+        t("", "");
+        t("abc/def 123", "abc/def 123");
+        t("abc%2Fdef%20123", "abc/def 123");
+        t("%20", " ");
+        t("%21", "!");
+        t("%22", "\"");
+        t("%23", "#");
+        t("%24", "$");
+        t("%25", "%");
+        t("%26", "&");
+        t("%27", "'");
+        t("%28", "(");
+        t("%29", ")");
+        t("%2A", "*");
+        t("%2B", "+");
+        t("%2C", ",");
+        t("%2F", "/");
+        t("%3A", ":");
+        t("%3B", ";");
+        t("%3D", "=");
+        t("%3F", "?");
+        t("%40", "@");
+        t("%5B", "[");
+        t("%5D", "]");
+
+        t("%00%0A%25".as_bytes(), "\0\n%");
     }
 
     #[test]
@@ -1286,16 +1217,16 @@ fn test_encode_form_urlencoded() {
 
         let mut m = HashMap::new();
         m.insert("foo bar".to_string(), vec!("abc".to_string(), "12 = 34".to_string()));
-        assert!(encode_form_urlencoded(&m) ==
-            "foo+bar=abc&foo+bar=12+%3D+34".to_string());
+        assert_eq!(encode_form_urlencoded(&m),
+                    "foo+bar=abc&foo+bar=12+%3D+34".to_string());
     }
 
     #[test]
     fn test_decode_form_urlencoded() {
-        assert_eq!(decode_form_urlencoded([]).len(), 0);
+        assert_eq!(decode_form_urlencoded([]).unwrap().len(), 0);
 
         let s = "a=1&foo+bar=abc&foo+bar=12+%3D+34".as_bytes();
-        let form = decode_form_urlencoded(s);
+        let form = decode_form_urlencoded(s).unwrap();
         assert_eq!(form.len(), 2);
         assert_eq!(form.get(&"a".to_string()), &vec!("1".to_string()));
         assert_eq!(form.get(&"foo bar".to_string()),
index 297afe4aa598e4b21ac30e5c7a55331b1fb6daa5..7d93f1f52cf05b82e2b141e605560bb76534624a 100644 (file)
@@ -33,7 +33,7 @@
 
 fn main() {
     let uuid1 = Uuid::new_v4();
-    println!("{}", uuid1.to_str());
+    println!("{}", uuid1.to_string());
 }
 ```
 
@@ -54,7 +54,8 @@ fn main() {
 
 */
 
-#![crate_id = "uuid#0.11.0"]
+#![crate_id = "uuid#0.11.0"] // NOTE: remove after stage0
+#![crate_name = "uuid"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
@@ -63,6 +64,7 @@ fn main() {
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/0.11.0/",
        html_playground_url = "http://play.rust-lang.org/")]
+#![allow(unused_attribute)] // NOTE: remove after stage0
 
 #![feature(default_type_params)]
 
@@ -620,7 +622,7 @@ fn test_parse_uuid_v4() {
 
         // Round-trip
         let uuid_orig = Uuid::new_v4();
-        let orig_str = uuid_orig.to_str();
+        let orig_str = uuid_orig.to_string();
         let uuid_out = Uuid::parse_string(orig_str.as_slice()).unwrap();
         assert!(uuid_orig == uuid_out);
 
@@ -648,9 +650,9 @@ fn test_to_simple_str() {
     }
 
     #[test]
-    fn test_to_str() {
+    fn test_to_string() {
         let uuid1 = Uuid::new_v4();
-        let s = uuid1.to_str();
+        let s = uuid1.to_string();
 
         assert!(s.len() == 32);
         assert!(s.as_slice().chars().all(|c| c.is_digit_radix(16)));
@@ -683,7 +685,7 @@ fn test_to_str_matching() {
         let uuid1 = Uuid::new_v4();
 
         let hs = uuid1.to_hyphenated_str();
-        let ss = uuid1.to_str();
+        let ss = uuid1.to_string();
 
         let hsn = str::from_chars(hs.as_slice()
                                     .chars()
@@ -702,7 +704,7 @@ fn test_string_roundtrip() {
         let uuid_hs = Uuid::parse_string(hs.as_slice()).unwrap();
         assert!(uuid_hs == uuid);
 
-        let ss = uuid.to_str();
+        let ss = uuid.to_string();
         let uuid_ss = Uuid::parse_string(ss.as_slice()).unwrap();
         assert!(uuid_ss == uuid);
     }
@@ -831,10 +833,10 @@ pub fn create_uuids(b: &mut Bencher) {
     }
 
     #[bench]
-    pub fn uuid_to_str(b: &mut Bencher) {
+    pub fn uuid_to_string(b: &mut Bencher) {
         let u = Uuid::new_v4();
         b.iter(|| {
-            u.to_str();
+            u.to_string();
         })
     }
 
index 5c694b34193ef981489759aba1b064e90c9fd34d..51676ec06e8dd44bfa1bfe0198fd8b421d7b3db4 100644 (file)
@@ -1,3 +1,11 @@
+S 2014-07-05 aaff4e0
+  freebsd-x86_64 10272ca9eb17e1be4a4b172aacfb4b33fffcc8fb
+  linux-i386 72ba9f6e0d096c30f128cb3736ffac0b57530a20
+  linux-x86_64 e5621f84934a7d76002ab95a354fbbb9ae6ebbb1
+  macos-i386 a88fd84ee959e59265de12b8f551ed56c0e943df
+  macos-x86_64 f19d479e5a0d2a6067a05b1910e4a6a544836b0a
+  winnt-i386 0c5a91e422409b89ac22f8c265af66f759d476c8
+
 S 2014-06-25 bab614f
   freebsd-x86_64 14cb361c8fdefa2534bb6776a04815c08680ecd6
   linux-i386 8fec4845626c557431a4aa7bfb2b5cfc65ad9eda
index eddedfa36bb301657b77b5b91a4a6a9053eaeead..e26ea7c4fa6d0b73b79e49c83722512ccd5549fa 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id="crateresolve1#0.1"]
-
+// compile-flags:-C extra-filename=-1
+#![crate_name = "crateresolve1"]
 #![crate_type = "lib"]
 
 pub fn f() -> int { 10 }
index 48042de0bad45830c9bad3e554e266c09c990fbf..715171b143a4a46686e59ad3ab168f2a52a6a272 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id="crateresolve1#0.2"]
-
+// compile-flags:-C extra-filename=-2
+#![crate_name = "crateresolve1"]
 #![crate_type = "lib"]
 
 pub fn f() -> int { 20 }
index c126560fe3eb2cbec9ffbe01433625ecaa4afa40..f733b5b908ab49aff407753905edf2a33317e185 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id="crateresolve1#0.3"]
-
+// compile-flags:-C extra-filename=-3
+#![crate_name = "crateresolve1"]
 #![crate_type = "lib"]
 
 pub fn f() -> int { 30 }
diff --git a/src/test/auxiliary/crateresolve2-1.rs b/src/test/auxiliary/crateresolve2-1.rs
deleted file mode 100644 (file)
index f436e7c..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_id="crateresolve2#0.1"]
-
-#![crate_type = "lib"]
-
-pub fn f() -> int { 10 }
diff --git a/src/test/auxiliary/crateresolve2-2.rs b/src/test/auxiliary/crateresolve2-2.rs
deleted file mode 100644 (file)
index 1f92ce5..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_id="crateresolve2#0.2"]
-
-#![crate_type = "lib"]
-
-pub fn f() -> int { 20 }
diff --git a/src/test/auxiliary/crateresolve2-3.rs b/src/test/auxiliary/crateresolve2-3.rs
deleted file mode 100644 (file)
index fe064b7..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_id="crateresolve2#0.3"]
-
-#![crate_type = "lib"]
-
-pub fn f() -> int { 30 }
index e26f8effb47fc85f852d1d878a7a8d7c0875d0d4..5c83b327912270e6a15c9a7f6b89e154df86a19a 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id="externcallback#0.1"]
+#![crate_name="externcallback"]
 #![crate_type = "lib"]
 
 extern crate libc;
diff --git a/src/test/auxiliary/issue-11908-1.rs b/src/test/auxiliary/issue-11908-1.rs
deleted file mode 100644 (file)
index 8a48e48..0000000
+++ /dev/null
@@ -1,14 +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.
-
-// no-prefer-dynamic
-
-#![crate_id = "url#0.11.0"]
-#![crate_type = "dylib"]
diff --git a/src/test/auxiliary/issue-11908-2.rs b/src/test/auxiliary/issue-11908-2.rs
deleted file mode 100644 (file)
index 0deece5..0000000
+++ /dev/null
@@ -1,14 +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.
-
-// no-prefer-dynamic
-
-#![crate_id = "url#0.11.0"]
-#![crate_type = "rlib"]
diff --git a/src/test/auxiliary/issue2378a.rs b/src/test/auxiliary/issue2378a.rs
deleted file mode 100644 (file)
index 934c4f5..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_type = "lib"]
-
-pub enum maybe<T> { just(T), nothing }
-
-impl <T:Clone> Index<uint,T> for maybe<T> {
-    fn index(&self, _idx: &uint) -> T {
-        match self {
-            &just(ref t) => (*t).clone(),
-            &nothing => { fail!(); }
-        }
-    }
-}
diff --git a/src/test/auxiliary/issue2378b.rs b/src/test/auxiliary/issue2378b.rs
deleted file mode 100644 (file)
index 03f685c..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_type = "lib"]
-
-extern crate issue2378a;
-
-use issue2378a::maybe;
-
-pub struct two_maybes<T> {pub a: maybe<T>, pub b: maybe<T>}
-
-impl<T:Clone> Index<uint,(T,T)> for two_maybes<T> {
-    fn index(&self, idx: &uint) -> (T, T) {
-        (self.a[*idx], self.b[*idx])
-    }
-}
diff --git a/src/test/auxiliary/xcrate_struct_aliases.rs b/src/test/auxiliary/xcrate_struct_aliases.rs
new file mode 100644 (file)
index 0000000..a0ec727
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub struct S {
+    pub x: int,
+    pub y: int,
+}
+
+pub type S2 = S;
+
index c3e877f80817658efea54fe3618ee6687b80d9e3..1d2d02d7d592689de2661c6d4b79b0e877d887a4 100644 (file)
@@ -90,11 +90,11 @@ pub fn bench_str<T:MutableSet<String>,
             let mut set = f();
             timed(&mut self.sequential_strings, || {
                 for i in range(0u, num_keys) {
-                    set.insert(i.to_str());
+                    set.insert(i.to_string());
                 }
 
                 for i in range(0u, num_keys) {
-                    assert!(set.contains(&i.to_str()));
+                    assert!(set.contains(&i.to_string()));
                 }
             })
         }
@@ -103,7 +103,7 @@ pub fn bench_str<T:MutableSet<String>,
             let mut set = f();
             timed(&mut self.random_strings, || {
                 for _ in range(0, num_keys) {
-                    let s = rng.gen::<uint>().to_str();
+                    let s = rng.gen::<uint>().to_string();
                     set.insert(s);
                 }
             })
@@ -112,11 +112,11 @@ pub fn bench_str<T:MutableSet<String>,
         {
             let mut set = f();
             for i in range(0u, num_keys) {
-                set.insert(i.to_str());
+                set.insert(i.to_string());
             }
             timed(&mut self.delete_strings, || {
                 for i in range(0u, num_keys) {
-                    assert!(set.remove(&i.to_str()));
+                    assert!(set.remove(&i.to_string()));
                 }
             })
         }
index 1c51ea055d04e3ab30a09831eee315dd7511fcac..f38517515660970d7b33dbc525567c6449cefae0 100644 (file)
@@ -24,7 +24,7 @@ fn main() {
     let n = from_str::<uint>(args.get(1).as_slice()).unwrap();
 
     for i in range(0u, n) {
-        let x = i.to_str();
+        let x = i.to_string();
         println!("{}", x);
     }
 }
index 8095037662bccf4e95edfe1eac7ecff0ed1a4112..0c76d14852e08695cf9ebc83272b1c2979741080 100644 (file)
@@ -48,7 +48,7 @@ fn show_color_list(set: Vec<Color>) -> String {
     let mut out = String::new();
     for col in set.iter() {
         out.push_char(' ');
-        out.push_str(col.to_str().as_slice());
+        out.push_str(col.to_string().as_slice());
     }
     out
 }
index 195c146c12fe719f26927bef8016837b91852345..b3deb88543ed46bdec52e56732c69bc2d20886fe 100644 (file)
@@ -64,7 +64,7 @@ fn sortKV(mut orig: Vec<(Vec<u8> ,f64)> ) -> Vec<(Vec<u8> ,f64)> {
                                k.as_slice()
                                .to_ascii()
                                .to_upper()
-                               .into_str(), v).as_slice());
+                               .into_string(), v).as_slice());
    }
 
    return buffer
@@ -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: String) -> uint {
-   let key = key.to_owned().into_ascii().as_slice().to_lower().into_str();
+   let key = key.to_owned().into_ascii().as_slice().to_lower().into_string();
    match mm.find_equiv(&key.as_bytes()) {
       option::None      => { return 0u; }
       option::Some(&num) => { return num; }
index 85f035b60cbbe23567357b0207ba71badecc6349..0e0b0b518d587efc815ddadf375e76588cc3a349 100644 (file)
@@ -115,7 +115,7 @@ fn main() {
 
                 let elapsed = stop - start;
 
-                println!("{}\t{}\t{}", n, fibn, elapsed.to_str());
+                println!("{}\t{}\t{}", n, fibn, elapsed.to_string());
             }
         }
     }
index 19b9d5638d0d8f3f034586958591b6322ebacd26..bdf6862d0b133ffa1150b60874e13ba0f14e0952 100644 (file)
@@ -67,7 +67,7 @@ fn main() {
     } else {
         box io::stdin() as Box<io::Reader>
     };
-    let mut seq = rdr.read_to_str().unwrap();
+    let mut seq = rdr.read_to_string().unwrap();
     let ilen = seq.len();
 
     seq = regex!(">[^\n]*\n|\n").replace_all(seq.as_slice(), NoExpand(""));
@@ -109,7 +109,7 @@ fn main() {
     let (mut variant_strs, mut counts) = (vec!(), vec!());
     for variant in variants.move_iter() {
         let seq_arc_copy = seq_arc.clone();
-        variant_strs.push(variant.to_str().to_owned());
+        variant_strs.push(variant.to_string().to_owned());
         counts.push(Future::spawn(proc() {
             count_matches(seq_arc_copy.as_slice(), &variant)
         }));
index 43956752cd9b343fc72ee2f8f375ceab67815498..883bfd035f40abbcba04a8c212b8e4ecdb2890b1 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-extern crate foo = ""; //~ ERROR: malformed crate id
-extern crate bar = "#a"; //~ ERROR: malformed crate id
+extern crate foo = ""; //~ ERROR: crate name must not be empty
 
 fn main() {}
diff --git a/src/test/compile-fail/bad-crate-id2.rs b/src/test/compile-fail/bad-crate-id2.rs
new file mode 100644 (file)
index 0000000..22e98b6
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern crate bar = "#a"; //~ ERROR: invalid character `#` in crate name: `#a`
+
+fn main() {}
+
index 9939fc791907d0fb166247c34f1b86e7563d91aa..1c7516ef7e2bfb2e3189c5e276f4f18d998d7a46 100644 (file)
@@ -32,7 +32,7 @@ enum UnsafeEnum<T> {
 static STATIC2: Unsafe<int> = Unsafe{value: 1, marker1: marker::InvariantType};
 static STATIC3: MyUnsafe<int> = MyUnsafe{value: STATIC2};
 
-static STATIC4: &'static Unsafe<int> = &'static STATIC2;
+static STATIC4: &'static Unsafe<int> = &STATIC2;
 //~^ ERROR borrow of immutable static items with unsafe interior is not allowed
 
 struct Wrap<T> {
diff --git a/src/test/compile-fail/borrowck-overloaded-index.rs b/src/test/compile-fail/borrowck-overloaded-index.rs
new file mode 100644 (file)
index 0000000..d34aa1c
--- /dev/null
@@ -0,0 +1,64 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo {
+    x: int,
+    y: int,
+}
+
+impl Index<String,int> for Foo {
+    fn index<'a>(&'a self, z: &String) -> &'a int {
+        if z.as_slice() == "x" {
+            &self.x
+        } else {
+            &self.y
+        }
+    }
+}
+
+impl IndexMut<String,int> for Foo {
+    fn index_mut<'a>(&'a mut self, z: &String) -> &'a mut int {
+        if z.as_slice() == "x" {
+            &mut self.x
+        } else {
+            &mut self.y
+        }
+    }
+}
+
+struct Bar {
+    x: int,
+}
+
+impl Index<int,int> for Bar {
+    fn index<'a>(&'a self, z: &int) -> &'a int {
+        &self.x
+    }
+}
+
+fn main() {
+    let mut f = Foo {
+        x: 1,
+        y: 2,
+    };
+    let mut s = "hello".to_string();
+    let rs = &mut s;
+    println!("{}", f[s]);
+    //~^ ERROR cannot borrow `s` as immutable because it is also borrowed as mutable
+    f[s] = 10;
+    //~^ ERROR cannot borrow `s` as immutable because it is also borrowed as mutable
+    let s = Bar {
+        x: 1,
+    };
+    s[2] = 20;
+    //~^ ERROR cannot assign to immutable indexed content
+}
+
+
index da5f7680d8ce759488dd30ffc8f446b05232e622..b7344d72a46c4253bbc19487d47ef34d159edc20 100644 (file)
@@ -113,12 +113,12 @@ fn drop(&mut self) {}
     field2: Variant4("str".to_string())
 };
 
-static STATIC15: &'static [Box<MyOwned>] = &'static [box MyOwned, box MyOwned];
+static STATIC15: &'static [Box<MyOwned>] = &[box MyOwned, box MyOwned];
 //~^ ERROR static items are not allowed to have custom pointers
 //~^^ ERROR static items are not allowed to have custom pointers
 
 static STATIC16: (&'static Box<MyOwned>, &'static Box<MyOwned>) =
-    (&'static box MyOwned, &'static box MyOwned);
+    (&box MyOwned, &box MyOwned);
 //~^ ERROR static items are not allowed to have custom pointers
 //~^^ ERROR static items are not allowed to have custom pointers
 
diff --git a/src/test/compile-fail/crateresolve2.rs b/src/test/compile-fail/crateresolve2.rs
deleted file mode 100644 (file)
index c5e9d12..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:crateresolve2-1.rs
-// aux-build:crateresolve2-2.rs
-// aux-build:crateresolve2-3.rs
-// error-pattern:using multiple versions of crate `crateresolve2`
-
-extern crate crateresolve2 = "crateresolve2#0.1";
-
-mod m {
-    pub extern crate crateresolve2 = "crateresolve2#0.2";
-}
-
-fn main() {
-    let x: int = false;
-}
diff --git a/src/test/compile-fail/crateresolve5.rs b/src/test/compile-fail/crateresolve5.rs
deleted file mode 100644 (file)
index 8b48014..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:crateresolve5-1.rs
-// aux-build:crateresolve5-2.rs
-
-extern crate cr5_1 = "crateresolve5#0.1";
-extern crate cr5_2 = "crateresolve5#0.2";
-
-
-fn main() {
-    // Nominal types from two multiple versions of a crate are different types
-    assert!(cr5_1::nominal() == cr5_2::nominal()); //~ ERROR mismatched types: expected
-}
index 064a3b9b168be722c920abca67ac296850515ba1..47b576b2b85e5e0077df880546e2b7a6d2ce7a0e 100644 (file)
@@ -11,9 +11,9 @@
 #![feature(struct_variant)]
 
 enum Foo { C { a: int, b: int } }
-struct C { a: int, b: int }         //~ ERROR error: duplicate definition of type `C`
+struct C { a: int, b: int }         //~ ERROR error: duplicate definition of type or module `C`
 
 struct A { x: int }
-enum Bar { A { x: int } }           //~ ERROR error: duplicate definition of type `A`
+enum Bar { A { x: int } }           //~ ERROR error: duplicate definition of type or module `A`
 
 fn main() {}
diff --git a/src/test/compile-fail/enum-and-module-in-same-scope.rs b/src/test/compile-fail/enum-and-module-in-same-scope.rs
new file mode 100644 (file)
index 0000000..7464764
--- /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.
+
+mod Foo {
+    pub static X: int = 42;
+}
+
+enum Foo {  //~ ERROR duplicate definition of type or module `Foo`
+    X
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-11908-1.rs b/src/test/compile-fail/issue-11908-1.rs
deleted file mode 100644 (file)
index dbedf35..0000000
+++ /dev/null
@@ -1,24 +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.
-
-// aux-build:issue-11908-1.rs
-// ignore-android this test is incompatible with the android test runner
-// error-pattern: multiple dylib candidates for `url` found
-
-// This test ensures that if you have the same rlib or dylib at two locations
-// in the same path that you don't hit an assertion in the compiler.
-//
-// Note that this relies on `liburl` to be in the path somewhere else,
-// and then our aux-built libraries will collide with liburl (they have
-// the same version listed)
-
-extern crate url;
-
-fn main() {}
diff --git a/src/test/compile-fail/issue-11908-2.rs b/src/test/compile-fail/issue-11908-2.rs
deleted file mode 100644 (file)
index 8b916aa..0000000
+++ /dev/null
@@ -1,21 +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.
-
-// aux-build:issue-11908-2.rs
-// no-prefer-dynamic
-// ignore-android this test is incompatible with the android test runner
-// error-pattern: multiple rlib candidates for `url` found
-
-// see comments in issue-11908-1 for what's going on here
-
-extern crate url;
-
-fn main() {}
-
diff --git a/src/test/compile-fail/issue-12187-1.rs b/src/test/compile-fail/issue-12187-1.rs
new file mode 100644 (file)
index 0000000..ce21e33
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn new<T>() -> &'static T {
+    fail!()
+}
+
+fn main() {
+    let &v = new();
+    //~^ ERROR cannot determine a type for this local variable: unconstrained type
+}
diff --git a/src/test/compile-fail/issue-12187-2.rs b/src/test/compile-fail/issue-12187-2.rs
new file mode 100644 (file)
index 0000000..90da109
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn new<'r, T>() -> &'r T {
+    fail!()
+}
+
+fn main() {
+    let &v = new();
+    //~^ ERROR cannot determine a type for this local variable: unconstrained type
+}
index 2dcfeac513c3273c778bb1d8654a08f9e5bd954b..921e331e960dcbf57aa857b2b1b3080eeaabbb7c 100644 (file)
@@ -13,8 +13,8 @@ struct vec3 { y: f32, z: f32 }
 
 fn make(v: vec2) {
     let vec3 { y: _, z: _ } = v;
-    //~^ ERROR mismatched types: expected `vec2` but found `vec3`
+    //~^ ERROR `vec3` does not name the structure `vec2`
     //~^^ ERROR struct `vec2` does not have a field named `z`
 }
 
-fn main() { }
\ No newline at end of file
+fn main() { }
index 2c3dda015471fd265aa9ef2d19dc8797bbf3fbd4..00607f850347cc54c5b1c201d5c098e375470506 100644 (file)
 struct t(Box<t>); //~ ERROR this type cannot be instantiated
 
 trait to_str_2 {
-    fn my_to_str() -> String;
+    fn my_to_string() -> String;
 }
 
 // I use an impl here because it will cause
 // the compiler to attempt autoderef and then
 // try to resolve the method.
 impl to_str_2 for t {
-    fn my_to_str() -> String { "t".to_string() }
+    fn my_to_string() -> String { "t".to_string() }
 }
 
 fn new_t(x: t) {
-    x.my_to_str(); //~ ERROR does not implement
+    x.my_to_string(); //~ ERROR does not implement
 }
 
 fn main() {
index 1b11fcac8a385bb0ba403d17a285e608456eed3e..316199b6730bb2684f1d389345cd081778fe4ea6 100644 (file)
@@ -10,6 +10,6 @@
 
 enum a { b, c }
 
-enum a { d, e } //~ ERROR duplicate definition of type `a`
+enum a { d, e } //~ ERROR duplicate definition of type or module `a`
 
 fn main() {}
index 5502b18f094130910049e6f28d78ae2ce6f3f88e..b3f1b2a32eae3434ccc46c862bdad5e0802f83b1 100644 (file)
@@ -10,6 +10,6 @@
 
 pub mod a {}
 
-pub mod a {} //~ ERROR duplicate definition of module `a`
+pub mod a {} //~ ERROR duplicate definition of type or module `a`
 
 fn main() {}
index 9b77d62a065292f74c68a264fa58da80565db02c..57bc11379125f440caa1fda9f6d262ffffe15a50 100644 (file)
@@ -13,17 +13,17 @@ struct Point {
     y: f64,
 }
 
-trait NewTrait {
-    fn a(&self) -> String;
+trait ToString_ {
+    fn to_string(&self) -> String;
 }
 
-impl NewTrait for Point {
+impl ToString_ for Point {
     fn new(x: f64, y: f64) -> Point {
-    //~^ ERROR method `new` is not a member of trait `NewTrait`
+    //~^ ERROR method `new` is not a member of trait `ToString_`
         Point { x: x, y: y }
     }
 
-    fn a(&self) -> String {
+    fn to_string(&self) -> String {
         format!("({}, {})", self.x, self.y)
     }
 }
@@ -32,5 +32,5 @@ fn main() {
     let p = Point::new(0.0, 0.0);
     //~^ ERROR unresolved name `Point::new`
     //~^^ ERROR failed to resolve. Use of undeclared module `Point`
-    println!("{}", p.a());
+    println!("{}", p.to_string());
 }
index f1b36d719e9591603450e80b089e4a3d031aa4ea..279cf6d94cbf13626c615f6e6a5237d33e62bc82 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-tidy-linelength
+
 #![allow(dead_code)]
 #![deny(uppercase_variables)]
 
@@ -30,7 +32,7 @@ fn main() {
     let mut buff = [0u8, ..16];
     match f.read(buff) {
         Ok(cnt) => println!("read this many bytes: {}", cnt),
-        Err(IoError{ kind: EndOfFile, .. }) => println!("Got end of file: {}", EndOfFile.to_str()),
+        Err(IoError{ kind: EndOfFile, .. }) => println!("Got end of file: {}", EndOfFile.to_string()),
                         //~^ ERROR variable names should start with a lowercase character
     }
 
index 73323def28d78d09e3f1117869c4276a0362b23b..1a2fb33eaabfed231cfcd2a4187c3b1f6d825fc3 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-tidy-linelength
 
 struct S {
     x: Box<E>
@@ -29,7 +30,7 @@ fn main() {
         f(&s, |hellothere| {
             match hellothere.x { //~ ERROR cannot move out
                 box Foo(_) => {}
-                box Bar(x) => println!("{}", x.to_str()), //~ NOTE attempting to move value to here
+                box Bar(x) => println!("{}", x.to_string()), //~ NOTE attempting to move value to here
                 box Baz => {}
             }
         })
index f772b96c697b7b9cc996e9f23584debc18892d31..c7b0bc8822be1dfda61e88f2fb02eed62226f10e 100644 (file)
@@ -12,7 +12,7 @@ struct S {
  y: int
 }
 
-impl Cmp, ToStr for S { //~ ERROR: expected `{` but found `,`
+impl Cmp, ToString for S { //~ ERROR: expected `{` but found `,`
   fn eq(&&other: S) { false }
-  fn to_str(&self) -> String { "hi".to_string() }
+  fn to_string(&self) -> String { "hi".to_string() }
 }
index 779a1ec7a5bf022d5f11d7168f3f9135c8d5242f..2fb097f111db47f98727566112fc8e35047c49f0 100644 (file)
@@ -21,7 +21,7 @@ mod baz {
         impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait
         impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait
         impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait
-        impl ToStr for Test {} //~ ERROR: attempt to implement a nonexistent trait
+        impl ToString for Test {} //~ ERROR: attempt to implement a nonexistent trait
         impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait
 
         fn foo() {
@@ -33,7 +33,7 @@ fn foo() {
     impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait
     impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait
     impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait
-    impl ToStr for Test {} //~ ERROR: attempt to implement a nonexistent trait
+    impl ToString for Test {} //~ ERROR: attempt to implement a nonexistent trait
     impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait
 
     fn foo() {
@@ -48,7 +48,7 @@ mod qux_inner {
         impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait
         impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait
         impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait
-        impl ToStr for Test {} //~ ERROR: attempt to implement a nonexistent trait
+        impl ToString for Test {} //~ ERROR: attempt to implement a nonexistent trait
         impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait
 
         fn foo() {
index fecc597b8fd2fff6ec0fd2acbdb3e647ee1bd1be..c0f7bea25b57ad88fddc5f218e6c75bd06fa1cdb 100644 (file)
@@ -20,7 +20,7 @@
 impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait
 impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait
 impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait
-impl ToStr for Test {} //~ ERROR: attempt to implement a nonexistent trait
+impl ToString for Test {} //~ ERROR: attempt to implement a nonexistent trait
 impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait
 
 fn main() {
index 7fba306d868607103ed3dd124cca1fd481908d1d..6dc5ad8b606c37e7055f17596f5db1b43def01f0 100644 (file)
@@ -23,7 +23,7 @@ enum Color {
 
 fn struct_with_a_nested_enum_and_vector() {
     match (Foo { first: true, second: None }) {
-    //~^ ERROR non-exhaustive patterns: `Foo{first: false, second: Some([_, _, _, _])}` not covered
+//~^ ERROR non-exhaustive patterns: `Foo { first: false, second: Some([_, _, _, _]) }` not covered
         Foo { first: true, second: None } => (),
         Foo { first: true, second: Some(_) } => (),
         Foo { first: false, second: None } => (),
@@ -40,7 +40,7 @@ fn enum_with_multiple_missing_variants() {
 
 fn enum_struct_variant() {
     match Red {
-    //~^ ERROR non-exhaustive patterns: `CustomRGBA{a: true, r: _, g: _, b: _}` not covered
+    //~^ ERROR non-exhaustive patterns: `CustomRGBA { a: true, .. }` not covered
         Red => (),
         Green => (),
         CustomRGBA { a: false, r: _, g: _, b: 0 } => (),
index fad20a7e37374a07f0f15f23a435b35198e77098..9f91337db9f21a6b106e7b93925ede0f0790b4eb 100644 (file)
@@ -11,7 +11,7 @@
 enum E {}
 
 fn f(e: E) {
-    println!("{}", (e as int).to_str());   //~ ERROR non-scalar cast
+    println!("{}", (e as int).to_string());   //~ ERROR non-scalar cast
 }
 
 fn main() {}
index fd09d78a4fa625a4d45ca766482943a6789a728a..6fd749b129819362c479ecf4d9ef759d7df1107e 100644 (file)
@@ -10,5 +10,5 @@
 
 // error-pattern: instantiating a type parameter with an incompatible type
 fn bar<T: Sized>() { }
-fn foo<type T>() { bar::<T>() }
+fn foo<Sized? T>() { bar::<T>() }
 fn main() { }
index f586fbb576b323110c24e5b6d9dac73b489254b4..651eb26cadc6fe268a1526d29dab7ae4fa2b2c61 100644 (file)
@@ -10,5 +10,5 @@
 
 // error-pattern: instantiating a type parameter with an incompatible type
 fn bar<T: Sized>() { }
-fn foo<type T>() { bar::<Option<T>>() }
+fn foo<Sized? T>() { bar::<Option<T>>() }
 fn main() { }
index 9fab3accbb9de8dcb8b7ae03c1e33aebb4ee6916..ec6aafb43f46f5dc04e082838d20b2e64559207c 100644 (file)
@@ -13,5 +13,5 @@
 struct Foo<T> { data: T }
 
 fn bar<T: Sized>() { }
-fn foo<type T>() { bar::<Foo<T>>() }
+fn foo<Sized? T>() { bar::<Foo<T>>() }
 fn main() { }
index c5cc7e8f7163b271d4c4a97535bb173500daf6d7..c07dcf9368385425b6cbd0411a5ac443666075b4 100644 (file)
 
 
 // Unbounded.
-fn f1<type X>(x: &X) {
+fn f1<Sized? X>(x: &X) {
     f2::<X>(x); //~ ERROR instantiating a type parameter with an incompatible type `X`, which does n
 }
 fn f2<X>(x: &X) {
 }
 
 // Bounded.
-trait T for type {}
-fn f3<type X: T>(x: &X) {
+trait T for Sized? {}
+fn f3<Sized? X: T>(x: &X) {
     f4::<X>(x); //~ ERROR instantiating a type parameter with an incompatible type `X`, which does n
 }
 fn f4<X: T>(x: &X) {
 }
 
 // Test with unsized enum.
-enum E<type X> {
+enum E<Sized? X> {
     V(X),
 }
 
 fn f5<Y>(x: &Y) {}
-fn f6<type X>(x: &X) {}
-fn f7<type X>(x1: &E<X>, x2: &E<X>) {
+fn f6<Sized? X>(x: &X) {}
+fn f7<Sized? X>(x1: &E<X>, x2: &E<X>) {
     f5(x1); //~ERROR instantiating a type parameter with an incompatible type `E<X>`, which does not
     f6(x2); // ok
 }
 
 
 // Test with unsized struct.
-struct S<type X> {
+struct S<Sized? X> {
     x: X,
 }
 
-fn f8<type X>(x1: &S<X>, x2: &S<X>) {
+fn f8<Sized? X>(x1: &S<X>, x2: &S<X>) {
     f5(x1); //~ERROR instantiating a type parameter with an incompatible type `S<X>`, which does not
     f6(x2); // ok
 }
 
 // Test some tuples.
-fn f9<type X>(x1: Box<S<X>>, x2: Box<E<X>>) {
+fn f9<Sized? X>(x1: Box<S<X>>, x2: Box<E<X>>) {
     f5(&(*x1, 34i)); //~ERROR instantiating a type parameter with an incompatible type `(S<X>,int)`,
     f5(&(32i, *x2)); //~ERROR instantiating a type parameter with an incompatible type `(int,E<X>)`,
 }
@@ -60,20 +60,20 @@ fn f9<type X>(x1: Box<S<X>>, x2: Box<E<X>>) {
 // impl - bounded
 trait T1<Z: T> {
 }
-struct S3<type Y>;
-impl<type X: T> T1<X> for S3<X> { //ERROR instantiating a type parameter with an incompatible type
+struct S3<Sized? Y>;
+impl<Sized? X: T> T1<X> for S3<X> { //ERROR instantiating a type parameter with an incompatible type
 }
 
 // impl - unbounded
 trait T2<Z> {
 }
-impl<type X> T2<X> for S3<X> { //ERROR instantiating a type parameter with an incompatible type `X`
+impl<Sized? X> T2<X> for S3<X> { //ERROR instantiating a type parameter with an incompatible type `X
 
 // impl - struct
-trait T3<type Z> {
+trait T3<Sized? Z> {
 }
 struct S4<Y>;
-impl<type X> T3<X> for S4<X> { //ERROR instantiating a type parameter with an incompatible type `X`
+impl<Sized? X> T3<X> for S4<X> { //ERROR instantiating a type parameter with an incompatible type `X
 }
 */
 
index 968716320fd5ed6b63f1f842181622bac368729f..e377c9d5f417342f578373fbe512b4a46c1d32f4 100644 (file)
@@ -11,7 +11,7 @@
 // Test that bounds are sized-compatible.
 
 trait T {}
-fn f<type Y: T>() {
+fn f<Sized? Y: T>() {
 //~^ERROR incompatible bounds on type parameter Y, bound T does not allow unsized type
 }
 
index 614b8e3a5ab67904e60ff1acaea0882b0bddca40..7028f7e798b014b99f1a529c7ec795f23281e7e7 100644 (file)
@@ -9,19 +9,19 @@
 // except according to those terms.
 #![feature(struct_variant)]
 
-// Test `type` types not allowed in fields.
+// Test `Sized?` types not allowed in fields.
 
-struct S1<type X> {
+struct S1<Sized? X> {
     f1: X, //~ ERROR type `f1` is dynamically sized. dynamically sized types may only appear as the
     f2: int,
 }
-struct S2<type X> {
+struct S2<Sized? X> {
     f: int,
     g: X, //~ ERROR type `g` is dynamically sized. dynamically sized types may only appear as the ty
     h: int,
 }
 
-enum E<type X> {
+enum E<Sized? X> {
     V1(X, int), //~ERROR type `X` is dynamically sized. dynamically sized types may only appear as t
     V2{f1: X, f: int}, //~ERROR type `f1` is dynamically sized. dynamically sized types may only app
 }
index 061b003b5e3f023360e1e3d64c68437eddb89d15..def1146526b3920ab687411646849e2564fc55bc 100644 (file)
@@ -8,37 +8,37 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Test `type` local variables.
+// Test `Sized?` local variables.
 
 
-trait T for type {}
+trait T for Sized? {}
 
-fn f1<type X>(x: &X) {
+fn f1<Sized? X>(x: &X) {
     let _: X; //~ERROR variable `_` has dynamically sized type `X`
     let _: (int, (X, int)); //~ERROR variable `_` has dynamically sized type `(int,(X,int))`
     let y: X; //~ERROR variable `y` has dynamically sized type `X`
     let y: (int, (X, int)); //~ERROR variable `y` has dynamically sized type `(int,(X,int))`
 }
-fn f2<type X: T>(x: &X) {
+fn f2<Sized? X: T>(x: &X) {
     let _: X; //~ERROR variable `_` has dynamically sized type `X`
     let _: (int, (X, int)); //~ERROR variable `_` has dynamically sized type `(int,(X,int))`
     let y: X; //~ERROR variable `y` has dynamically sized type `X`
     let y: (int, (X, int)); //~ERROR variable `y` has dynamically sized type `(int,(X,int))`
 }
 
-fn f3<type X>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
+fn f3<Sized? X>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
     let y: X = *x1; //~ERROR variable `y` has dynamically sized type `X`
     let y = *x2; //~ERROR variable `y` has dynamically sized type `X`
     let (y, z) = (*x3, 4i); //~ERROR variable `y` has dynamically sized type `X`
 }
-fn f4<type X: T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
+fn f4<Sized? X: T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
     let y: X = *x1;         //~ERROR variable `y` has dynamically sized type `X`
     let y = *x2;            //~ERROR variable `y` has dynamically sized type `X`
     let (y, z) = (*x3, 4i); //~ERROR variable `y` has dynamically sized type `X`
 }
 
-fn g1<type X>(x: X) {} //~ERROR variable `x` has dynamically sized type `X`
-fn g2<type X: T>(x: X) {} //~ERROR variable `x` has dynamically sized type `X`
+fn g1<Sized? X>(x: X) {} //~ERROR variable `x` has dynamically sized type `X`
+fn g2<Sized? X: T>(x: X) {} //~ERROR variable `x` has dynamically sized type `X`
 
 pub fn main() {
 }
index 753c91d1dc9580ffde569ad6e219f1294ca0ea94..043f3a233a6253705718e010b41c340379f7af01 100644 (file)
@@ -23,10 +23,10 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 struct List {
-    list: Vec<Box<ToStr>> }
+    list: Vec<Box<ToString>> }
 
 impl List {
-    fn push(&mut self, n: Box<ToStr>) {
+    fn push(&mut self, n: Box<ToString>) {
         self.list.push(n);
     }
 }
@@ -35,6 +35,6 @@ fn main() {
     let n = box Number { n: 42 };
     let mut l = box List { list: Vec::new() };
     l.push(n);
-    let x = n.to_str();
+    let x = n.to_string();
     //~^ ERROR: use of moved value: `n`
 }
diff --git a/src/test/compile-fail/use-meta.rc b/src/test/compile-fail/use-meta.rc
deleted file mode 100644 (file)
index 9cb84c5..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern:can't find crate for `std`
-
-extern crate std = "std#bogus";
index 47de06c48569643acd172b9eeb9b000d4b558685..8f718add2a312afee49d955138cdd9ad2356d524 100644 (file)
@@ -21,4 +21,4 @@ pub fn p() -> C {
     C
 }
 
-fn main() { }
\ No newline at end of file
+fn main() { }
index 3b28af9b0e83f09c4db60be429cc14b171290f2d..c7753a67464ac64ad0e9b8193c8996632a076f41 100644 (file)
@@ -6,7 +6,6 @@ TARGET_RPATH_DIR:=$(TARGET_RPATH_DIR):$(TMPDIR)
 
 all:
        $(RUSTC) lib.rs
-       ln -nsf $(call DYLIB,boot-*) $(call DYLIB,boot)
        $(CC) main.c -o $(call RUN_BINFILE,main) $(call RPATH_LINK_SEARCH,$(HOST_LIB_DIR)) -lboot
        $(call RUN,main)
        $(call REMOVE_DYLIBS,boot)
index 69c65ef8b037a2869ee00682bf449942c742565d..7f17018c486c0e11ef543dc54e8fa4fa69bff0c9 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id="boot#0.1"]
+#![crate_name="boot"]
 #![crate_type="dylib"]
 
 extern crate rustuv;
index 3b28af9b0e83f09c4db60be429cc14b171290f2d..c7753a67464ac64ad0e9b8193c8996632a076f41 100644 (file)
@@ -6,7 +6,6 @@ TARGET_RPATH_DIR:=$(TARGET_RPATH_DIR):$(TMPDIR)
 
 all:
        $(RUSTC) lib.rs
-       ln -nsf $(call DYLIB,boot-*) $(call DYLIB,boot)
        $(CC) main.c -o $(call RUN_BINFILE,main) $(call RPATH_LINK_SEARCH,$(HOST_LIB_DIR)) -lboot
        $(call RUN,main)
        $(call REMOVE_DYLIBS,boot)
index e743004a9cbc6caf86e4a8ba6395674954f9fc2d..a5b4430ab6a0c30d4a64da45bb359b77e4f65997 100644 (file)
@@ -4,7 +4,6 @@ HOST_LIB_DIR=$(TMPDIR)/../../../stage$(RUST_BUILD_STAGE)/lib
 
 all:
        $(RUSTC) foo.rs
-       ln -s $(call DYLIB,foo-*) $(call DYLIB,foo)
        $(CC) bar.c -lfoo -o $(call RUN_BINFILE,bar) $(call RPATH_LINK_SEARCH,$(HOST_LIB_DIR)) -Wl,-rpath,$(TMPDIR)
        $(call RUN,bar)
        $(call REMOVE_DYLIBS,foo)
index 40b6feac678233f1154f768c1112215bae4a4f94..8a6d6e4dd6d786122f2a338232d128c33cb32532 100644 (file)
@@ -10,7 +10,6 @@ endif
 ifneq ($(shell uname),FreeBSD)
 all:
        $(RUSTC) foo.rs
-       ln -s $(call STATICLIB,foo-*) $(call STATICLIB,foo)
        $(CC) bar.c -lfoo -o $(call RUN_BINFILE,bar) $(EXTRAFLAGS) -lstdc++
        $(call RUN,bar)
        rm $(call STATICLIB,foo*)
index a44481b4b7f23d75f339fa247fe7729c05d8db14..23d155fe23db33ede53de6780c652c98b4c59e83 100644 (file)
@@ -1,10 +1,9 @@
 -include ../tools.mk
 
 all:
-       [ `$(RUSTC) --crate-id crate.rs` = "foo#0.11.0" ]
-       [ `$(RUSTC) --crate-name crate.rs` = "foo" ]
-       [ `$(RUSTC) --crate-file-name crate.rs` = "foo" ]
-       [ `$(RUSTC) --crate-file-name --crate-type=lib --test crate.rs` = "foo" ]
-       [ `$(RUSTC) --crate-file-name --test lib.rs` = "mylib" ]
-       $(RUSTC) --crate-file-name lib.rs
-       $(RUSTC) --crate-file-name rlib.rs
+       [ `$(RUSTC) --print-crate-name crate.rs` = "foo" ]
+       [ `$(RUSTC) --print-file-name crate.rs` = "foo" ]
+       [ `$(RUSTC) --print-file-name --crate-type=lib --test crate.rs` = "foo" ]
+       [ `$(RUSTC) --print-file-name --test lib.rs` = "mylib" ]
+       $(RUSTC) --print-file-name lib.rs
+       $(RUSTC) --print-file-name rlib.rs
index 9faa7c016284bf054eec1849d20b436bb524263a..305b3dc70a625006de0c6f3a198e046bcf6a1ff0 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id = "foo#0.11.0"]
+#![crate_name = "foo"]
 
 // Querying about the crate metadata should *not* parse the entire crate, it
 // only needs the crate attributes (which are guaranteed to be at the top) be
index b40e055b3cba91642646a3aef6228df1e60fef48..639a5d0387b8ea045146515086885abdd0c89e4e 100644 (file)
@@ -8,5 +8,5 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id = "mylib"]
+#![crate_name = "mylib"]
 #![crate_type = "lib"]
index 94b8371e5375790d2bf63bcee91e4db536506e08..4e0937486003c19db4449023356883814c211b55 100644 (file)
@@ -8,5 +8,5 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id = "mylib"]
+#![crate_name = "mylib"]
 #![crate_type = "rlib"]
diff --git a/src/test/run-make/crate-name-priority/Makefile b/src/test/run-make/crate-name-priority/Makefile
new file mode 100644 (file)
index 0000000..2506027
--- /dev/null
@@ -0,0 +1,13 @@
+-include ../tools.mk
+
+all:
+       $(RUSTC) foo.rs
+       rm $(TMPDIR)/$(call BIN,foo)
+       $(RUSTC) foo.rs --crate-name bar
+       rm $(TMPDIR)/$(call BIN,bar)
+       $(RUSTC) foo1.rs
+       rm $(TMPDIR)/$(call BIN,foo)
+       $(RUSTC) foo1.rs --crate-name bar
+       rm $(TMPDIR)/$(call BIN,bar)
+       $(RUSTC) foo1.rs --crate-name bar -o $(TMPDIR)/bar1
+       rm $(TMPDIR)/$(call BIN,bar1)
diff --git a/src/test/run-make/crate-name-priority/foo.rs b/src/test/run-make/crate-name-priority/foo.rs
new file mode 100644 (file)
index 0000000..8ae3d07
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {}
diff --git a/src/test/run-make/crate-name-priority/foo1.rs b/src/test/run-make/crate-name-priority/foo1.rs
new file mode 100644 (file)
index 0000000..0f02f10
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_name = "foo"]
+
+fn main() {}
+
index 4255b1d934d9c668edd49fa6a75944fc5c09d85d..7c15785bbb23d61eaa2a5e6315852dd2e9c2de25 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id="foo#0.1"]
+#![crate_name = "foo"]
 
 pub mod foo;
 pub mod bar;
diff --git a/src/test/run-make/extern-flag-disambiguates/Makefile b/src/test/run-make/extern-flag-disambiguates/Makefile
new file mode 100644 (file)
index 0000000..9b86bf9
--- /dev/null
@@ -0,0 +1,24 @@
+-include ../tools.mk
+
+# Attempt to build this dependency tree:
+#
+#      A.1   A.2
+#       |\    |
+#       | \   |
+#        B  \  C
+#         \ | /
+#          \|/
+#           D
+#
+# Note that A.1 and A.2 are crates with the same name.
+
+all:
+       $(RUSTC) -C metadata=1 -C extra-filename=-1 a.rs
+       $(RUSTC) -C metadata=2 -C extra-filename=-2 a.rs
+       $(RUSTC) b.rs --extern a=$(TMPDIR)/liba-1.rlib
+       $(RUSTC) c.rs --extern a=$(TMPDIR)/liba-2.rlib
+       $(RUSTC) --cfg before d.rs --extern a=$(TMPDIR)/liba-1.rlib
+       $(call RUN,d)
+       $(RUSTC) --cfg after  d.rs --extern a=$(TMPDIR)/liba-1.rlib
+       $(call RUN,d)
+
diff --git a/src/test/run-make/extern-flag-disambiguates/a.rs b/src/test/run-make/extern-flag-disambiguates/a.rs
new file mode 100644 (file)
index 0000000..11b9ba6
--- /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.
+
+#![crate_name = "a"]
+#![crate_type = "rlib"]
+
+static FOO: uint = 3;
+
+pub fn token() -> &'static uint { &FOO }
diff --git a/src/test/run-make/extern-flag-disambiguates/b.rs b/src/test/run-make/extern-flag-disambiguates/b.rs
new file mode 100644 (file)
index 0000000..3156cf0
--- /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.
+
+#![crate_name = "b"]
+#![crate_type = "rlib"]
+
+extern crate a;
+
+static FOO: uint = 3;
+
+pub fn token() -> &'static uint { &FOO }
+pub fn a_token() -> &'static uint { a::token() }
diff --git a/src/test/run-make/extern-flag-disambiguates/c.rs b/src/test/run-make/extern-flag-disambiguates/c.rs
new file mode 100644 (file)
index 0000000..d3bbc76
--- /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.
+
+#![crate_name = "c"]
+#![crate_type = "rlib"]
+
+extern crate a;
+
+static FOO: uint = 3;
+
+pub fn token() -> &'static uint { &FOO }
+pub fn a_token() -> &'static uint { a::token() }
diff --git a/src/test/run-make/extern-flag-disambiguates/d.rs b/src/test/run-make/extern-flag-disambiguates/d.rs
new file mode 100644 (file)
index 0000000..d850daf
--- /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.
+
+#[cfg(before)] extern crate a;
+extern crate b;
+extern crate c;
+#[cfg(after)] extern crate a;
+
+fn t(a: &'static uint) -> uint { a as *const _ as uint }
+
+fn main() {
+    assert!(t(a::token()) == t(b::a_token()));
+    assert!(t(a::token()) != t(c::a_token()));
+}
diff --git a/src/test/run-make/extern-flag-fun/Makefile b/src/test/run-make/extern-flag-fun/Makefile
new file mode 100644 (file)
index 0000000..ca5aa05
--- /dev/null
@@ -0,0 +1,16 @@
+-include ../tools.mk
+
+all:
+       $(RUSTC) bar.rs --crate-type=rlib
+       $(RUSTC) bar.rs --crate-type=rlib -C extra-filename=-a
+       $(RUSTC) foo.rs --extern hello && exit 1 || exit 0
+       $(RUSTC) foo.rs --extern bar=no-exist && exit 1 || exit 0
+       $(RUSTC) foo.rs --extern bar=foo.rs && exit 1 || exit 0
+       $(RUSTC) foo.rs \
+               --extern bar=$(TMPDIR)/libbar.rlib \
+               --extern bar=$(TMPDIR)/libbar-a.rlib \
+               && exit 1 || exit 0
+       $(RUSTC) foo.rs \
+               --extern bar=$(TMPDIR)/libbar.rlib \
+               --extern bar=$(TMPDIR)/libbar.rlib
+       $(RUSTC) foo.rs --extern bar=$(TMPDIR)/libbar.rlib
diff --git a/src/test/run-make/extern-flag-fun/bar.rs b/src/test/run-make/extern-flag-fun/bar.rs
new file mode 100644 (file)
index 0000000..2152aa7
--- /dev/null
@@ -0,0 +1,10 @@
+// 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.
+
diff --git a/src/test/run-make/extern-flag-fun/foo.rs b/src/test/run-make/extern-flag-fun/foo.rs
new file mode 100644 (file)
index 0000000..5274166
--- /dev/null
@@ -0,0 +1,13 @@
+// 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.
+
+extern crate bar;
+
+fn main() {}
index 61b40d68dd1b56431ce2fbd2a9170cbf9dd35d7a..b431476f84a6636a9e3c7613d8546384df033ae8 100644 (file)
@@ -4,8 +4,8 @@ digraph block {
     N2[label="expr 6"];
     N3[label="expr S6{val: 6,}"];
     N4[label="local _x"];
-    N5[label="pat S6{val: _x}"];
-    N6[label="block { let S6{val: _x} = S6{val: 6,}; }"];
+    N5[label="pat S6 { val: _x }"];
+    N6[label="block { let S6 { val: _x } = S6{val: 6,}; }"];
     N0 -> N2;
     N2 -> N3;
     N3 -> N4;
diff --git a/src/test/run-make/issue-11908/Makefile b/src/test/run-make/issue-11908/Makefile
new file mode 100644 (file)
index 0000000..663a9f7
--- /dev/null
@@ -0,0 +1,23 @@
+# This test ensures that if you have the same rlib or dylib at two locations
+# in the same path that you don't hit an assertion in the compiler.
+#
+# Note that this relies on `liburl` to be in the path somewhere else,
+# and then our aux-built libraries will collide with liburl (they have
+# the same version listed)
+
+-include ../tools.mk
+
+all:
+       mkdir $(TMPDIR)/other
+       $(RUSTC) foo.rs --crate-type=dylib
+       mv $(call DYLIB,foo) $(TMPDIR)/other
+       $(RUSTC) foo.rs --crate-type=dylib
+       $(RUSTC) bar.rs -L $(TMPDIR)/other 2>&1 | \
+               grep "multiple dylib candidates"
+       rm -rf $(TMPDIR)
+       mkdir -p $(TMPDIR)/other
+       $(RUSTC) foo.rs --crate-type=rlib
+       mv $(TMPDIR)/libfoo.rlib $(TMPDIR)/other
+       $(RUSTC) foo.rs --crate-type=rlib
+       $(RUSTC) bar.rs -L $(TMPDIR)/other 2>&1 | \
+               grep "multiple rlib candidates"
diff --git a/src/test/run-make/issue-11908/bar.rs b/src/test/run-make/issue-11908/bar.rs
new file mode 100644 (file)
index 0000000..6316cfa
--- /dev/null
@@ -0,0 +1,13 @@
+// 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.
+
+extern crate foo;
+
+fn main() {}
diff --git a/src/test/run-make/issue-11908/foo.rs b/src/test/run-make/issue-11908/foo.rs
new file mode 100644 (file)
index 0000000..0858d3c
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_name = "foo"]
index 9b44c3e582a71da13db68407fedadaaf5435796c..6c7e9aa1d59fda347da1af71ffe94d2dcb5f1e21 100644 (file)
@@ -5,6 +5,5 @@ CC := $(CC:-g=)
 
 all:
        $(RUSTC) foo.rs -Z lto
-       ln -s $(call STATICLIB,foo-*) $(call STATICLIB,foo)
        $(CC) bar.c -lfoo -o $(call RUN_BINFILE,bar) $(EXTRACFLAGS) -lstdc++
        $(call RUN,bar)
index fbe967786e25ecb61c99a398e60a81ef37134689..04d3ae67207228d9bfe4d16f9873b5cd8bbe3f92 100644 (file)
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[crate_type = "rlib"];
+#![crate_type = "rlib"]
diff --git a/src/test/run-make/manual-crate-name/Makefile b/src/test/run-make/manual-crate-name/Makefile
new file mode 100644 (file)
index 0000000..1d14199
--- /dev/null
@@ -0,0 +1,5 @@
+-include ../tools.mk
+
+all:
+       $(RUSTC) --crate-name foo bar.rs
+       rm $(TMPDIR)/libfoo.rlib
diff --git a/src/test/run-make/manual-crate-name/bar.rs b/src/test/run-make/manual-crate-name/bar.rs
new file mode 100644 (file)
index 0000000..04d3ae6
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "rlib"]
diff --git a/src/test/run-make/metadata-flag-frobs-symbols/Makefile b/src/test/run-make/metadata-flag-frobs-symbols/Makefile
new file mode 100644 (file)
index 0000000..09e6ae0
--- /dev/null
@@ -0,0 +1,10 @@
+-include ../tools.mk
+
+all:
+       $(RUSTC) foo.rs -C metadata=a -C extra-filename=-a
+       $(RUSTC) foo.rs -C metadata=b -C extra-filename=-b
+       $(RUSTC) bar.rs \
+               --extern foo1=$(TMPDIR)/libfoo-a.rlib \
+               --extern foo2=$(TMPDIR)/libfoo-b.rlib \
+               -Z print-link-args
+       $(call RUN,bar)
diff --git a/src/test/run-make/metadata-flag-frobs-symbols/bar.rs b/src/test/run-make/metadata-flag-frobs-symbols/bar.rs
new file mode 100644 (file)
index 0000000..44b9e2f
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern crate foo1;
+extern crate foo2;
+
+fn main() {
+    let a = foo1::foo();
+    let b = foo2::foo();
+    assert!(a as *const _ != b as *const _);
+}
diff --git a/src/test/run-make/metadata-flag-frobs-symbols/foo.rs b/src/test/run-make/metadata-flag-frobs-symbols/foo.rs
new file mode 100644 (file)
index 0000000..ed04eed
--- /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.
+
+#![crate_name = "foo"]
+#![crate_type = "rlib"]
+
+static FOO: uint = 3;
+
+pub fn foo() -> &'static uint { &FOO }
diff --git a/src/test/run-make/multiple-versions/Makefile b/src/test/run-make/multiple-versions/Makefile
new file mode 100644 (file)
index 0000000..e60c16a
--- /dev/null
@@ -0,0 +1,9 @@
+-include ../tools.mk
+
+all:
+       $(RUSTC) foo.rs -C metadata=a -C extra-filename=-1 --crate-type=rlib
+       $(RUSTC) foo.rs -C metadata=b -C extra-filename=-2 --crate-type=rlib
+       $(RUSTC) bar.rs \
+               --extern foo1=$(TMPDIR)/libfoo-1.rlib \
+               --extern foo2=$(TMPDIR)/libfoo-2.rlib \
+               2>&1 | grep "using multiple versions of crate .foo."
diff --git a/src/test/run-make/multiple-versions/bar.rs b/src/test/run-make/multiple-versions/bar.rs
new file mode 100644 (file)
index 0000000..262193a
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern crate foo1;
+extern crate foo2;
+
+fn main() {}
diff --git a/src/test/run-make/multiple-versions/foo.rs b/src/test/run-make/multiple-versions/foo.rs
new file mode 100644 (file)
index 0000000..2661b1f
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn foo() {}
index 020fbc3299b6831db6acecb421d34bc2c9706c9c..bb5796bd8737ff3c01d46d8aa588766c672a62ab 100644 (file)
@@ -8,6 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id = "bar"]
+#![crate_name = "bar"]
 
 fn main() {}
index debd89d9929b75784bf89d99ae547e876acca937..5d6e629ffc1d1627dccc0be3042322042e096d0f 100644 (file)
@@ -1,9 +1,12 @@
 -include ../tools.mk
 
 all:
-       $(RUSTC) foo.rs -o $(TMPDIR)/.foo
-       rm $(TMPDIR)/.foo
-       $(RUSTC) foo.rs -o $(TMPDIR)/.foo.bar
-       rm $(TMPDIR)/.foo.bar
-       $(RUSTC) foo.rs -o $(TMPDIR)/+foo+bar
-       rm $(TMPDIR)/$(call BIN,+foo+bar)
+       cp foo.rs $(TMPDIR)/.foo.rs
+       $(RUSTC) $(TMPDIR)/.foo.rs 2>&1 \
+               | grep "invalid character.*in crate name:"
+       cp foo.rs $(TMPDIR)/.foo.bar
+       $(RUSTC) $(TMPDIR)/.foo.bar 2>&1 \
+               | grep "invalid character.*in crate name:"
+       cp foo.rs $(TMPDIR)/+foo+bar
+       $(RUSTC) $(TMPDIR)/+foo+bar 2>&1 \
+               | grep "invalid character.*in crate name:"
index 8c2dba243c87c7da5f95bb6729b942eaef6b6b7f..3823a7033f5a61c536ab9a57ed5a81d5660d8aa7 100644 (file)
@@ -13,8 +13,8 @@
 use std::collections::Bitv;
 
 fn bitv_test() {
-    let mut v1 = box Bitv::new(31, false);
-    let v2 = box Bitv::new(31, true);
+    let mut v1 = box Bitv::with_capacity(31, false);
+    let v2 = box Bitv::with_capacity(31, true);
     v1.union(v2);
 }
 
index cb364d23387cfed7cfb5a9f47893c4d355d4b8f8..91075633ab8d844c5ac9ea84725018ac779d362b 100644 (file)
@@ -49,9 +49,9 @@ fn main() {
     assert_eq!(!true, false);
     assert_eq!(!false, true);
 
-    let s = false.to_str();
+    let s = false.to_string();
     assert_eq!(s.as_slice(), "false");
-    let s = true.to_str();
+    let s = true.to_string();
     assert_eq!(s.as_slice(), "true");
 
     assert!(true > false);
index 1e28c44206ffc9492333bac1ed1ca273935d3c92..ac470268d319fc7f2788fb4e9fd1a99918d80eb2 100644 (file)
@@ -46,6 +46,13 @@ pub fn main() {
         _ => fail!(),
     }
 
+    let buf = vec!(97u8, 98, 99, 100);
+    assert_eq!(match buf.slice(0, 3) {
+         b"def" => 1u,
+         b"abc" => 2u,
+         _ => 3u
+    }, 2);
+
     assert_eq!(BAZ, &[97u8, 92u8, 110u8]);
     assert_eq!(br"a\n", &[97u8, 92u8, 110u8]);
     assert_eq!(br"a\n", b"a\\n");
index 19186f4b46bcef9fb0fd50168477d58c822715f3..33ee2ffd3592ce2f6c708892221f2d79d3724c84 100644 (file)
@@ -45,7 +45,7 @@ fn main() {
         debug!("debug");
         info!("info");
     });
-    let s = r.read_to_str().unwrap();
+    let s = r.read_to_string().unwrap();
     assert!(s.as_slice().contains("info"));
     assert!(!s.as_slice().contains("debug"));
 }
index f3d12d21684e4f9324d9746bf96df4cd7bd712c3..e3dbaa62d353264ed5eb1b40e6bf0e49581a1f1f 100644 (file)
 // aux-build:cci_class_cast.rs
 extern crate cci_class_cast;
 
-use std::to_str::ToStr;
+use std::to_str::ToString;
 use cci_class_cast::kitty::cat;
 
-fn print_out(thing: Box<ToStr>, expected: String) {
-  let actual = thing.to_str();
+fn print_out(thing: Box<ToString>, expected: String) {
+  let actual = thing.to_string();
   println!("{}", actual);
   assert_eq!(actual.to_string(), expected);
 }
 
 pub fn main() {
-  let nyan: Box<ToStr> = box cat(0u, 2, "nyan".to_string()) as Box<ToStr>;
+  let nyan: Box<ToString> = box cat(0u, 2, "nyan".to_string()) as Box<ToString>;
   print_out(nyan, "nyan".to_string());
 }
index 3d486144c3eed8005743ab72f61ce5f117b73210..7143888298072da85d34254ace13f980bf6ceddd 100644 (file)
@@ -57,13 +57,13 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-fn print_out(thing: Box<ToStr>, expected: String) {
-  let actual = thing.to_str();
+fn print_out(thing: Box<ToString>, expected: String) {
+  let actual = thing.to_string();
   println!("{}", actual);
   assert_eq!(actual.to_string(), expected);
 }
 
 pub fn main() {
-  let nyan: Box<ToStr> = box cat(0u, 2, "nyan".to_string()) as Box<ToStr>;
+  let nyan: Box<ToString> = box cat(0u, 2, "nyan".to_string()) as Box<ToString>;
   print_out(nyan, "nyan".to_string());
 }
diff --git a/src/test/run-pass/crateresolve1.rs b/src/test/run-pass/crateresolve1.rs
deleted file mode 100644 (file)
index 61e269b..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:crateresolve1-1.rs
-// aux-build:crateresolve1-2.rs
-// aux-build:crateresolve1-3.rs
-
-extern crate crateresolve1 = "crateresolve1#0.2";
-
-pub fn main() {
-    assert_eq!(crateresolve1::f(), 20);
-}
diff --git a/src/test/run-pass/crateresolve2.rs b/src/test/run-pass/crateresolve2.rs
deleted file mode 100644 (file)
index 5ed1f37..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:crateresolve2-1.rs
-// aux-build:crateresolve2-2.rs
-// aux-build:crateresolve2-3.rs
-
-mod a {
-    extern crate crateresolve2 = "crateresolve2#0.1";
-    pub fn f() { assert!(crateresolve2::f() == 10); }
-}
-
-mod b {
-    extern crate crateresolve2 = "crateresolve2#0.2";
-    pub fn f() { assert!(crateresolve2::f() == 20); }
-}
-
-mod c {
-    extern crate crateresolve2 = "crateresolve2#0.3";
-    pub fn f() { assert!(crateresolve2::f() == 30); }
-}
-
-pub fn main() {
-    a::f();
-    b::f();
-    c::f();
-}
diff --git a/src/test/run-pass/crateresolve3.rs b/src/test/run-pass/crateresolve3.rs
deleted file mode 100644 (file)
index cee9e69..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:crateresolve3-1.rs
-// aux-build:crateresolve3-2.rs
-
-// verify able to link with crates with same name but different versions
-// as long as no name collision on invoked functions.
-
-mod a {
-    extern crate crateresolve3 = "crateresolve3#0.1";
-    pub fn f() { assert!(crateresolve3::f() == 10); }
-}
-
-mod b {
-    extern crate crateresolve3 = "crateresolve3#0.2";
-    pub fn f() { assert!(crateresolve3::g() == 20); }
-}
-
-pub fn main() {
-    a::f();
-    b::f();
-}
diff --git a/src/test/run-pass/crateresolve4.rs b/src/test/run-pass/crateresolve4.rs
deleted file mode 100644 (file)
index c689615..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:crateresolve4a-1.rs
-// aux-build:crateresolve4a-2.rs
-// aux-build:crateresolve4b-1.rs
-// aux-build:crateresolve4b-2.rs
-
-pub mod a {
-    extern crate crateresolve4b = "crateresolve4b#0.1";
-    pub fn f() { assert!(crateresolve4b::f() == 20); }
-}
-
-pub mod b {
-    extern crate crateresolve4b = "crateresolve4b#0.2";
-    pub fn f() { assert!(crateresolve4b::g() == 10); }
-}
-
-pub fn main() {
-    a::f();
-    b::f();
-}
diff --git a/src/test/run-pass/crateresolve5.rs b/src/test/run-pass/crateresolve5.rs
deleted file mode 100644 (file)
index 3f74731..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:crateresolve5-1.rs
-// aux-build:crateresolve5-2.rs
-
-extern crate cr5_1 = "crateresolve5#0.1";
-extern crate cr5_2 = "crateresolve5#0.2";
-
-pub fn main() {
-    // Structural types can be used between two versions of the same crate
-    assert!(cr5_1::struct_nameval().name == cr5_2::struct_nameval().name);
-    assert!(cr5_1::struct_nameval().val == cr5_2::struct_nameval().val);
-    // Make sure these are actually two different crates
-    assert!(cr5_1::f() == 10 && cr5_2::f() == 20);
-}
diff --git a/src/test/run-pass/crateresolve8.rs b/src/test/run-pass/crateresolve8.rs
deleted file mode 100644 (file)
index f04e383..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:crateresolve8-1.rs
-
-#![crate_id="crateresolve8#0.1"]
-
-extern crate crateresolve8 = "crateresolve8#0.1";
-//extern crate crateresolve8(vers = "0.1");
-
-pub fn main() {
-    assert_eq!(crateresolve8::f(), 20);
-}
diff --git a/src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs b/src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs
new file mode 100644 (file)
index 0000000..a7738bb
--- /dev/null
@@ -0,0 +1,55 @@
+// 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 briefuly tests the capability of `Cell` and `RefCell` to implement the
+// `Encodable` and `Decodable` traits via `#[deriving(Encodable, Decodable)]`
+
+extern crate serialize;
+
+use std::cell::{Cell, RefCell};
+use std::io::MemWriter;
+use serialize::{Encodable, Decodable};
+use serialize::ebml;
+use serialize::ebml::writer::Encoder;
+use serialize::ebml::reader::Decoder;
+
+#[deriving(Encodable, Decodable)]
+struct A {
+    baz: int
+}
+
+#[deriving(Encodable, Decodable)]
+struct B {
+    foo: Cell<bool>,
+    bar: RefCell<A>,
+}
+
+fn main() {
+    let obj = B {
+        foo: Cell::new(true),
+        bar: RefCell::new( A { baz: 2 } )
+    };
+    let mut w = MemWriter::new();
+    {
+        let mut e = Encoder::new(&mut w);
+        match obj.encode(&mut e) {
+            Ok(()) => (),
+            Err(e) => fail!("Failed to encode: {}", e)
+        };
+    }
+    let doc = ebml::Doc::new(w.get_ref());
+    let mut dec = Decoder::new(doc);
+    let obj2: B = match Decodable::decode(&mut dec) {
+        Ok(v) => v,
+        Err(e) => fail!("Failed to decode: {}", e)
+    };
+    assert!(obj.foo.get() == obj2.foo.get());
+    assert!(obj.bar.borrow().baz == obj2.bar.borrow().baz);
+}
index a5e86dee18e8cadd5d35dc95dc5c5c0229f782bc..fa82e42d793f03ddc52bcaf00588cdff44ef7418 100644 (file)
@@ -41,15 +41,15 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 pub fn main() {
-    assert_eq!(B1.to_str(), "B1".to_string());
-    assert_eq!(B2.to_str(), "B2".to_string());
-    assert_eq!(C1(3).to_str(), "C1(3)".to_string());
-    assert_eq!(C2(B2).to_str(), "C2(B2)".to_string());
-    assert_eq!(D1{ a: 2 }.to_str(), "D1 { a: 2 }".to_string());
-    assert_eq!(E.to_str(), "E".to_string());
-    assert_eq!(F(3).to_str(), "F(3)".to_string());
-    assert_eq!(G(3, 4).to_str(), "G(3, 4)".to_string());
-    assert_eq!(G(3, 4).to_str(), "G(3, 4)".to_string());
-    assert_eq!(I{ a: 2, b: 4 }.to_str(), "I { a: 2, b: 4 }".to_string());
-    assert_eq!(J(Custom).to_str(), "J(yay)".to_string());
+    assert_eq!(B1.to_string(), "B1".to_string());
+    assert_eq!(B2.to_string(), "B2".to_string());
+    assert_eq!(C1(3).to_string(), "C1(3)".to_string());
+    assert_eq!(C2(B2).to_string(), "C2(B2)".to_string());
+    assert_eq!(D1{ a: 2 }.to_string(), "D1 { a: 2 }".to_string());
+    assert_eq!(E.to_string(), "E".to_string());
+    assert_eq!(F(3).to_string(), "F(3)".to_string());
+    assert_eq!(G(3, 4).to_string(), "G(3, 4)".to_string());
+    assert_eq!(G(3, 4).to_string(), "G(3, 4)".to_string());
+    assert_eq!(I{ a: 2, b: 4 }.to_string(), "I { a: 2, b: 4 }".to_string());
+    assert_eq!(J(Custom).to_string(), "J(yay)".to_string());
 }
diff --git a/src/test/run-pass/enum-null-pointer-opt.rs b/src/test/run-pass/enum-null-pointer-opt.rs
new file mode 100644 (file)
index 0000000..bd9dfc1
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+use std::gc::Gc;
+use std::mem::size_of;
+
+trait Trait {}
+
+fn main() {
+    // Closures - || / proc()
+    assert_eq!(size_of::<proc()>(), size_of::<Option<proc()>>());
+    assert_eq!(size_of::<||>(), size_of::<Option<||>>());
+
+    // Functions
+    assert_eq!(size_of::<fn(int)>(), size_of::<Option<fn(int)>>());
+    assert_eq!(size_of::<extern "C" fn(int)>(), size_of::<Option<extern "C" fn(int)>>());
+
+    // Slices - &str / &[T] / &mut [T]
+    assert_eq!(size_of::<&str>(), size_of::<Option<&str>>());
+    assert_eq!(size_of::<&[int]>(), size_of::<Option<&[int]>>());
+    assert_eq!(size_of::<&mut [int]>(), size_of::<Option<&mut [int]>>());
+
+    // Traits - Box<Trait> / &Trait / &mut Trait
+    assert_eq!(size_of::<Box<Trait>>(), size_of::<Option<Box<Trait>>>());
+    assert_eq!(size_of::<&Trait>(), size_of::<Option<&Trait>>());
+    assert_eq!(size_of::<&mut Trait>(), size_of::<Option<&mut Trait>>());
+
+    // Pointers - Box<T> / Gc<T>
+    assert_eq!(size_of::<Box<int>>(), size_of::<Option<Box<int>>>());
+    assert_eq!(size_of::<Gc<int>>(), size_of::<Option<Gc<int>>>());
+
+}
index bb236638905ba9d47c21d65fa67122ff3176c215..7e71be4114836c30a441552d24dd19f13e717c35 100644 (file)
 #![feature(macro_rules)]
 
 use s = std::num::strconv;
-use to_str = std::num::strconv::float_to_str_common;
+use to_string = std::num::strconv::float_to_str_common;
 
 macro_rules! t(($a:expr, $b:expr) => { { let (r, _) = $a; assert_eq!(r, $b.to_string()) } })
 
 pub fn main() {
     // Basic usage
-    t!(to_str(1.2345678e-5f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpDec, false),
+    t!(to_string(1.2345678e-5f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpDec, false),
              "1.234568e-5")
 
     // Hexadecimal output
-    t!(to_str(7.281738281250e+01f64, 16u, true, s::SignAll, s::DigMax(6), s::ExpBin, false),
+    t!(to_string(7.281738281250e+01f64, 16u, true, s::SignAll, s::DigMax(6), s::ExpBin, false),
               "+1.2345p+6")
-    t!(to_str(-1.777768135071e-02f64, 16u, true, s::SignAll, s::DigMax(6), s::ExpBin, false),
+    t!(to_string(-1.777768135071e-02f64, 16u, true, s::SignAll, s::DigMax(6), s::ExpBin, false),
              "-1.2345p-6")
 
     // Some denormals
-    t!(to_str(4.9406564584124654e-324f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpBin, false),
+    t!(to_string(4.9406564584124654e-324f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpBin, false),
              "1p-1074")
-    t!(to_str(2.2250738585072009e-308f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpBin, false),
+    t!(to_string(2.2250738585072009e-308f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpBin, false),
              "1p-1022")
 }
index 3faf5744199862c9ba9533504c25f459fad7c8ec..5dc25c85325c0f20780e82bf4784a91af87da3d1 100644 (file)
@@ -10,7 +10,7 @@
 
 //aux-build:extern-crosscrate-source.rs
 
-extern crate externcallback = "externcallback#0.1";
+extern crate externcallback;
 
 fn fact(n: uint) -> uint {
     unsafe {
index 62cfd10dbfb468c6a1a298e23f2cc07e24e8dd13..3b7c5083bb48ef1a42e820d111b6db91882f2288 100644 (file)
@@ -17,6 +17,6 @@ struct Struc { a: u8, b: [int, ..3], c: int }
 pub fn main() {
     let arr = [1,2,3];
     let struc = Struc {a: 13u8, b: arr, c: 42};
-    let s = repr::repr_to_str(&struc);
+    let s = repr::repr_to_string(&struc);
     assert_eq!(s, "Struc{a: 13u8, b: [1, 2, 3], c: 42}".to_string());
 }
index c300b8c93359d9ce87f5e58f797d0eae34939e39..10d6e0158f6f225ff2f69cfff12b88d85385b6c8 100644 (file)
 fn main() {
     // Generate sieve of Eratosthenes for n up to 1e6
     let n = 1000000u;
-    let sieve = Bitv::new(n+1, true);
+    let mut sieve = Bitv::with_capacity(n+1, true);
     let limit: uint = (n as f32).sqrt() as uint;
     for i in range(2, limit+1) {
         if sieve[i] {
             let mut j = 0;
             while i*i + j*i <= n {
-                sieve[i*i+j*i] = false;
+                sieve.set(i*i+j*i, false);
                 j += 1;
             }
         }
diff --git a/src/test/run-pass/issue-15487.rs b/src/test/run-pass/issue-15487.rs
new file mode 100644 (file)
index 0000000..ee75958
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-win32
+
+#![feature(link_args)]
+
+#[link_args="-lc  -lm"]
+#[link_args=" -lc"]
+#[link_args="-lc "]
+extern {}
+
+fn main() {}
index d48a944c2f0d8aa060d9d2a4b371fd56cde7923d..4a89d277e9f5634568952f9ca7b0ee1d538d6418 100644 (file)
@@ -79,8 +79,8 @@ fn read_board_grid<rdr:'static + io::Reader>(mut input: rdr)
 
 mod test {
     #[test]
-    pub fn trivial_to_str() {
-        assert!(lambda.to_str() == "\\")
+    pub fn trivial_to_string() {
+        assert!(lambda.to_string() == "\\")
     }
 }
 
index 1d442198aec706084a35842deb24b6d19586259d..1555098f2911be5d5df7100abba6f28eb8ce0fbb 100644 (file)
@@ -10,7 +10,7 @@
 
 enum what { }
 
-fn what_to_str(x: what) -> String
+fn what_to_string(x: what) -> String
 {
     match x {
     }
index 53f92246e54c9966ac9c2de41ada6b4f0b73dd9a..2568d94fcbf9e4f14d62ae0b00bdcb228e0040e2 100644 (file)
@@ -24,6 +24,6 @@ pub fn main() {
     let mut table = HashMap::new();
     table.insert("one".to_string(), 1i);
     table.insert("two".to_string(), 2i);
-    assert!(check_strs(table.to_str().as_slice(), "{one: 1, two: 2}") ||
-            check_strs(table.to_str().as_slice(), "{two: 2, one: 1}"));
+    assert!(check_strs(table.to_string().as_slice(), "{one: 1, two: 2}") ||
+            check_strs(table.to_string().as_slice(), "{two: 2, one: 1}"));
 }
index ac022d5c212388956b446e4ad3992138f25250c9..e38969c25263caada3a4b7fd44ce00e7c3397ef4 100644 (file)
@@ -94,7 +94,7 @@ fn add_pt(&mut self, x: int, y: int) {
     }
 }
 
-// Allows AsciiArt to be converted to a string using the libcore ToStr trait.
+// Allows AsciiArt to be converted to a string using the libcore ToString trait.
 // Note that the %s fmt! specifier will not call this automatically.
 impl fmt::Show for AsciiArt {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -159,7 +159,7 @@ pub fn check_strs(actual: &str, expected: &str) -> bool {
 
 fn test_ascii_art_ctor() {
     let art = AsciiArt(3, 3, '*');
-    assert!(check_strs(art.to_str().as_slice(), "...\n...\n..."));
+    assert!(check_strs(art.to_string().as_slice(), "...\n...\n..."));
 }
 
 
@@ -168,7 +168,7 @@ fn test_add_pt() {
     art.add_pt(0, 0);
     art.add_pt(0, -10);
     art.add_pt(1, 2);
-    assert!(check_strs(art.to_str().as_slice(), "*..\n...\n.*."));
+    assert!(check_strs(art.to_string().as_slice(), "*..\n...\n.*."));
 }
 
 
@@ -176,7 +176,7 @@ fn test_shapes() {
     let mut art = AsciiArt(4, 4, '*');
     art.add_rect(Rect {top_left: Point {x: 0, y: 0}, size: Size {width: 4, height: 4}});
     art.add_point(Point {x: 2, y: 2});
-    assert!(check_strs(art.to_str().as_slice(), "****\n*..*\n*.**\n****"));
+    assert!(check_strs(art.to_string().as_slice(), "****\n*..*\n*.**\n****"));
 }
 
 pub fn main() {
index c9cedc3b7de47ae982a4c5800a26400fcdf16117..3f219da0a879a2e64ea3d5d1e7fafa8db444813f 100644 (file)
 
 pub fn main() {
   trait Text {
-    fn to_str(&self) -> String;
+    fn to_string(&self) -> String;
   }
 
   fn to_string(t: Box<Text>) {
-    println!("{}", t.to_str());
+    println!("{}", t.to_string());
   }
 
 }
index b27720b8579a4b4a51c511d8b366944cbffc0dfd..3ebc3e645737626a839859effb12ba98a3d4a16c 100644 (file)
@@ -96,19 +96,19 @@ enum Result {
     }
 }
 
-priv fn cmd_to_str(cmd: ~[String]) -> String {
+priv fn cmd_to_string(cmd: ~[String]) -> String {
   let mut res = "*".to_string();
-  res.push_str(cmd.len().to_str());
+  res.push_str(cmd.len().to_string());
   res.push_str("\r\n");
     for s in cmd.iter() {
-    res.push_str(["$".to_string(), s.len().to_str(), "\r\n".to_string(),
+    res.push_str(["$".to_string(), s.len().to_string(), "\r\n".to_string(),
                   (*s).clone(), "\r\n".to_string()].concat() );
     }
   res
 }
 
 fn query(cmd: ~[String], sb: TcpSocketBuf) -> Result {
-  let cmd = cmd_to_str(cmd);
+  let cmd = cmd_to_string(cmd);
   //println!("{}", cmd);
   sb.write_str(cmd);
   let res = parse_response(@sb as @io::Reader);
@@ -116,7 +116,7 @@ fn query(cmd: ~[String], sb: TcpSocketBuf) -> Result {
 }
 
 fn query2(cmd: ~[String]) -> Result {
-  let _cmd = cmd_to_str(cmd);
+  let _cmd = cmd_to_string(cmd);
     io::with_str_reader("$3\r\nXXX\r\n".to_string())(|sb| {
     let res = parse_response(@sb as @io::Reader);
     println!("{:?}", res);
index 16fd45a5615f224987bb8d3d316959f4688bd3a1..977cd08ba377082dea01b860d9d12e89ce7e0ff6 100644 (file)
 type FontTableTag = u32;
 
 trait FontTableTagConversions {
-  fn tag_to_str(self);
+  fn tag_to_string(self);
 }
 
 impl FontTableTagConversions for FontTableTag {
-  fn tag_to_str(self) {
+  fn tag_to_string(self) {
     &self;
   }
 }
 
 pub fn main() {
-    5.tag_to_str();
+    5.tag_to_string();
 }
index 543f4bf027bfd10293662e2e1798414a78f6aa9a..5b6012673564d03447fa52a44ef99e7f6a362d11 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 struct T (&'static [int]);
-static t : T = T (&'static [5, 4, 3]);
+static t : T = T (&[5, 4, 3]);
 pub fn main () {
     let T(ref v) = t;
     assert_eq!(v[0], 5);
index 6ceb2cf87b9a3a528cda5430acea8f97e24957e9..275fe740db157ca60c5e136efde82437d80bae4a 100644 (file)
@@ -17,7 +17,7 @@ pub fn default_instance() -> &'static UninterpretedOption_NamePart {
         static instance: UninterpretedOption_NamePart = UninterpretedOption_NamePart {
             name_part: None,
         };
-        &'static instance
+        &instance
     }
 }
 
diff --git a/src/test/run-pass/issue2378c.rs b/src/test/run-pass/issue2378c.rs
deleted file mode 100644 (file)
index c453a53..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:issue2378a.rs
-// aux-build:issue2378b.rs
-
-extern crate issue2378a;
-extern crate issue2378b;
-
-use issue2378a::{just};
-use issue2378b::{two_maybes};
-
-pub fn main() {
-    let x = two_maybes{a: just(3i), b: just(5i)};
-    assert_eq!(x[0u], (3, 5));
-}
diff --git a/src/test/run-pass/match-pattern-bindings.rs b/src/test/run-pass/match-pattern-bindings.rs
new file mode 100644 (file)
index 0000000..61e905e
--- /dev/null
@@ -0,0 +1,38 @@
+// 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 value = Some(1i);
+    assert_eq!(match value {
+        ref a @ Some(_) => a,
+        ref b @ None => b
+    }, &Some(1i));
+    assert_eq!(match value {
+        ref a @ ref _c @ Some(_) => a,
+        ref b @ None => b
+    }, &Some(1i));
+    assert_eq!(match value {
+        _a @ ref c @ Some(_) => c,
+        ref b @ None => b
+    }, &Some(1i));
+    assert_eq!(match "foobarbaz" {
+        _a @ b @ _ => b
+    }, "foobarbaz");
+
+    let a @ b @ c = "foobarbaz";
+    assert_eq!(a, "foobarbaz");
+    assert_eq!(b, "foobarbaz");
+    assert_eq!(c, "foobarbaz");
+    let value = Some(true);
+    let ref a @ b @ ref c = value;
+    assert_eq!(a, &Some(true));
+    assert_eq!(b, Some(true));
+    assert_eq!(c, &Some(true));
+}
index 2b67ef09c59db5152d610b4ee9741dcba2488888..783dc32426a651f6139d0fa615167766861b684d 100644 (file)
@@ -38,7 +38,7 @@ fn bind<B>(&self, f: |&A| -> Option<B>) -> Option<B> {
 }
 
 fn transform(x: Option<int>) -> Option<String> {
-    x.bind(|n| Some(*n + 1) ).bind(|n| Some(n.to_str()) )
+    x.bind(|n| Some(*n + 1) ).bind(|n| Some(n.to_string()) )
 }
 
 pub fn main() {
index e7d679c41e8538e2a724ea53032430091a95600c..92c5e025b9b2149692aa23bb41c73406015de143 100644 (file)
@@ -20,7 +20,7 @@ pub fn append(&mut self, v: &str) {
     }
 }
 
-fn to_str(sb: StringBuffer) -> String {
+fn to_string(sb: StringBuffer) -> String {
     sb.s
 }
 
@@ -30,6 +30,6 @@ pub fn main() {
     };
     sb.append("Hello, ");
     sb.append("World!");
-    let str = to_str(sb);
+    let str = to_string(sb);
     assert_eq!(str.as_slice(), "Hello, World!");
 }
index 9fd6e9616757edbcc5a17b68fc5ae25c53a072f4..8532b5f51dc5e68ebe94cb66623b9b532647e52c 100644 (file)
@@ -32,6 +32,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 pub fn main() {
-    println!("{}", Thingy { x: 1, y: 2 }.to_str());
-    println!("{}", PolymorphicThingy { x: Thingy { x: 1, y: 2 } }.to_str());
+    println!("{}", Thingy { x: 1, y: 2 }.to_string());
+    println!("{}", PolymorphicThingy { x: Thingy { x: 1, y: 2 } }.to_string());
 }
index 00e19b8481f217e2a0414f5b14cd63eb631a2a3c..a36d8132b260a86cd50fed157f02e2184122c1d5 100644 (file)
@@ -43,8 +43,12 @@ fn not(&self) -> Point {
 }
 
 impl ops::Index<bool,int> for Point {
-    fn index(&self, x: &bool) -> int {
-        if *x { self.x } else { self.y }
+    fn index<'a>(&'a self, x: &bool) -> &'a int {
+        if *x {
+            &self.x
+        } else {
+            &self.y
+        }
     }
 }
 
diff --git a/src/test/run-pass/order-drop-with-match.rs b/src/test/run-pass/order-drop-with-match.rs
new file mode 100644 (file)
index 0000000..ed5cff3
--- /dev/null
@@ -0,0 +1,64 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+// Test to make sure the destructors run in the right order.
+// Each destructor sets it's tag in the corresponding entry
+// in ORDER matching up to when it ran.
+// Correct order is: matched, inner, outer
+
+static mut ORDER: [uint, ..3] = [0, 0, 0];
+static mut INDEX: uint = 0;
+
+struct A;
+impl Drop for A {
+    fn drop(&mut self) {
+        unsafe {
+            ORDER[INDEX] = 1;
+            INDEX = INDEX + 1;
+        }
+    }
+}
+
+struct B;
+impl Drop for B {
+    fn drop(&mut self) {
+        unsafe {
+            ORDER[INDEX] = 2;
+            INDEX = INDEX + 1;
+        }
+    }
+}
+
+struct C;
+impl Drop for C {
+    fn drop(&mut self) {
+        unsafe {
+            ORDER[INDEX] = 3;
+            INDEX = INDEX + 1;
+        }
+    }
+}
+
+fn main() {
+    {
+        let matched = A;
+        let _outer = C;
+        {
+            match matched {
+                _s => {}
+            }
+            let _inner = B;
+        }
+    }
+    unsafe {
+        assert_eq!(&[1, 2, 3], ORDER.as_slice());
+    }
+}
index de5456ef1c03f553a4a728f875428f7bc9c4daaa..6b1ac0b821c44646d8adf570f2a3ee37050e9f4e 100644 (file)
@@ -31,10 +31,10 @@ fn push(&mut self, key: K, value: V) {
 }
 
 impl<K:PartialEq,V:Clone> Index<K,V> for AssociationList<K,V> {
-    fn index(&self, index: &K) -> V {
+    fn index<'a>(&'a self, index: &K) -> &'a V {
         for pair in self.pairs.iter() {
             if pair.key == *index {
-                return pair.value.clone();
+                return &pair.value
             }
         }
         fail!("No value found for key: {:?}", index);
index 49edf1bad57f0a9525ed357ea0778e6680b9248f..283c76adf0dafcc2a90d17ba8114c6c16af9270e 100644 (file)
@@ -72,7 +72,7 @@ pub fn main() {
     // N.B. This is required because method lookup hasn't been performed so
     // we don't know whether the called method takes mutable self, before
     // the dereference itself is type-checked (a chicken-and-egg problem).
-    (*n).to_str();
+    (*n).to_string();
     assert_eq!(n.counts(), (2, 4));
 
     // Mutable deref used for calling a method taking &mut self.
diff --git a/src/test/run-pass/overloaded-index.rs b/src/test/run-pass/overloaded-index.rs
new file mode 100644 (file)
index 0000000..9d7c068
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo {
+    x: int,
+    y: int,
+}
+
+impl Index<int,int> for Foo {
+    fn index<'a>(&'a self, z: &int) -> &'a int {
+        if *z == 0 {
+            &self.x
+        } else {
+            &self.y
+        }
+    }
+}
+
+impl IndexMut<int,int> for Foo {
+    fn index_mut<'a>(&'a mut self, z: &int) -> &'a mut int {
+        if *z == 0 {
+            &mut self.x
+        } else {
+            &mut self.y
+        }
+    }
+}
+
+fn main() {
+    let mut f = Foo {
+        x: 1,
+        y: 2,
+    };
+    assert_eq!(f[1], 2);
+    f[0] = 3;
+    assert_eq!(f[0], 3);
+    {
+        let p = &mut f[1];
+        *p = 4;
+    }
+    {
+        let p = &f[1];
+        assert_eq!(*p, 4);
+    }
+}
+
index 68eca8f21a7f5d37c9b4a94e55a96034593bd648..f3a730aa2b39589b823994ebd3c6ab321ff183f7 100644 (file)
@@ -12,7 +12,7 @@
 
 use std::collections::{ Map, MutableMap};
 use std::str::{SendStr, Owned, Slice};
-use std::to_str::ToStr;
+use std::to_str::ToString;
 use self::collections::TreeMap;
 use std::option::Some;
 
index 9267fcac0115aad81645646ef56e5dacf9bcf62c..d0dacc2ff7a9d225a4cec29e68091ac35937b21e 100644 (file)
@@ -31,7 +31,7 @@ trait uint_utils {
 
 impl uint_utils for uint {
     fn str(&self) -> String {
-        self.to_str()
+        self.to_string()
     }
     fn multi(&self, f: |uint|) {
         let mut c = 0u;
diff --git a/src/test/run-pass/struct-aliases-xcrate.rs b/src/test/run-pass/struct-aliases-xcrate.rs
new file mode 100644 (file)
index 0000000..9046caf
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:xcrate_struct_aliases.rs
+extern crate xcrate_struct_aliases;
+
+use xcrate_struct_aliases::{S, S2};
+
+fn main() {
+    let s = S2 {
+        x: 1,
+        y: 2,
+    };
+    match s {
+        S2 {
+            x: x,
+            y: y
+        } => {
+            assert_eq!(x, 1);
+            assert_eq!(y, 2);
+        }
+    }
+}
+
diff --git a/src/test/run-pass/struct-aliases.rs b/src/test/run-pass/struct-aliases.rs
new file mode 100644 (file)
index 0000000..2cf961a
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct S {
+    x: int,
+    y: int,
+}
+
+type S2 = S;
+
+fn main() {
+    let s = S2 {
+        x: 1,
+        y: 2,
+    };
+    match s {
+        S2 {
+            x: x,
+            y: y
+        } => {
+            assert_eq!(x, 1);
+            assert_eq!(y, 2);
+        }
+    }
+}
+
index 6a71f9df6e45ee70eff9b0cbb27d98739774fc29..ceffd1e363667d313ce04f3cf3a4e226a14361a9 100644 (file)
@@ -21,6 +21,6 @@ fn main() {
     });
     assert!(res.is_err());
 
-    let output = reader.read_to_str().unwrap();
+    let output = reader.read_to_string().unwrap();
     assert!(output.as_slice().contains("Hello, world!"));
 }
index ebc720aa0c888d60f2bc5c675709c38d863f564a..d2408509fc5820c0105e083a149060d1ea67333d 100644 (file)
@@ -54,7 +54,7 @@ fn f() $b
 iotest!(fn eventual_timeout() {
     use native;
     let addr = next_test_ip4();
-    let host = addr.ip.to_str();
+    let host = addr.ip.to_string();
     let port = addr.port;
 
     // Use a native task to receive connections because it turns out libuv is
@@ -82,7 +82,7 @@ fn f() $b
 
 iotest!(fn timeout_success() {
     let addr = next_test_ip4();
-    let host = addr.ip.to_str();
+    let host = addr.ip.to_string();
     let port = addr.port;
     let _l = TcpListener::bind(host.as_slice(), port).unwrap().listen();
 
index de3366708c5a0a0e3ebcef92c1279577bfdf3a4a..f52a3455e4157684c16b98c5b29828db88b4f125 100644 (file)
@@ -61,7 +61,7 @@ fn main() {
     for _ in range(0u, 1000) {
         let tx = tx.clone();
         TaskBuilder::new().stack_size(64 * 1024).spawn(proc() {
-            let host = addr.ip.to_str();
+            let host = addr.ip.to_string();
             let port = addr.port;
             match TcpStream::connect(host.as_slice(), port) {
                 Ok(stream) => {
index c3387a963a701d44c8e4d1f84f80394ac8160327..b36fbca2da048a68f9b82af3c19712e00677ec47 100644 (file)
@@ -27,10 +27,10 @@ fn checktests() {
     let tests = __test::TESTS;
 
     assert!(
-        tests.iter().any(|t| t.desc.name.to_str().as_slice() == "shouldignore" &&
+        tests.iter().any(|t| t.desc.name.to_string().as_slice() == "shouldignore" &&
                          t.desc.ignore));
 
     assert!(
-        tests.iter().any(|t| t.desc.name.to_str().as_slice() == "shouldnotignore" &&
+        tests.iter().any(|t| t.desc.name.to_string().as_slice() == "shouldnotignore" &&
                          !t.desc.ignore));
 }
index daab40f5d90d1de7e41c94a1c61fb10bbb7fa98e..43d3b591ffa1b9225e3073ed6e8d7f1877d7b9be 100644 (file)
@@ -39,7 +39,7 @@ fn to_str_(&self) -> String {
 
 impl to_str for int {
     fn to_str_(&self) -> String {
-        self.to_str()
+        self.to_string()
     }
 }
 
index f3f4c556b77292f6208922a1c1fedc6cc86357ff..eeda6e2c88b454e084d07d29811915224e6bd59d 100644 (file)
 
 
 trait to_str {
-    fn to_string(&self) -> String;
+    fn to_string_(&self) -> String;
 }
 impl to_str for int {
-    fn to_string(&self) -> String { self.to_str() }
+    fn to_string_(&self) -> String { self.to_string() }
 }
 impl to_str for String {
-    fn to_string(&self) -> String { self.clone() }
+    fn to_string_(&self) -> String { self.clone() }
 }
 impl to_str for () {
-    fn to_string(&self) -> String { "()".to_string() }
+    fn to_string_(&self) -> String { "()".to_string() }
 }
 
 trait map<T> {
@@ -40,7 +40,7 @@ fn foo<U, T: map<U>>(x: T) -> Vec<String> {
     x.map(|_e| "hi".to_string() )
 }
 fn bar<U:to_str,T:map<U>>(x: T) -> Vec<String> {
-    x.map(|_e| _e.to_string() )
+    x.map(|_e| _e.to_string_() )
 }
 
 pub fn main() {
index 54a21caafa0b187f9d2f1c97f9d6f6627c95f855..fbe40e837de5f04a1d350b134526c2ceede596f2 100644 (file)
 
 
 trait to_str {
-    fn to_string(&self) -> String;
+    fn to_string_(&self) -> String;
 }
 
 impl to_str for int {
-    fn to_string(&self) -> String { self.to_str() }
+    fn to_string_(&self) -> String { self.to_string() }
 }
 
 impl<T:to_str> to_str for Vec<T> {
-    fn to_string(&self) -> String {
+    fn to_string_(&self) -> String {
         format!("[{}]",
                 self.iter()
-                    .map(|e| e.to_string())
+                    .map(|e| e.to_string_())
                     .collect::<Vec<String>>()
                     .connect(", "))
     }
 }
 
 pub fn main() {
-    assert!(1.to_string() == "1".to_string());
-    assert!((vec!(2i, 3, 4)).to_string() == "[2, 3, 4]".to_string());
+    assert!(1.to_string_() == "1".to_string());
+    assert!((vec!(2i, 3, 4)).to_string_() == "[2, 3, 4]".to_string());
 
     fn indirect<T:to_str>(x: T) -> String {
-        format!("{}!", x.to_string())
+        format!("{}!", x.to_string_())
     }
     assert!(indirect(vec!(10i, 20)) == "[10, 20]!".to_string());
 
index c6a3a0b0409aa76ff8b3bf259c8d584905e6f03f..ed4712ff3be9c55bd8ba81e1b64498f0fee7445c 100644 (file)
@@ -43,7 +43,7 @@ fn default_instance() -> &'static Request {
         // size of struct may be not equal to size of struct, and
         // compiler crashes in internal assertion check.
     };
-    &'static instance
+    &instance
 }
 
 fn non_default_instance() -> &'static Request {
@@ -51,7 +51,7 @@ fn non_default_instance() -> &'static Request {
         foo: TestSome(0x1020304050607080),
         bar: 19,
     };
-    &'static instance
+    &instance
 }
 
 pub fn main() {
index 1a79edb30c9c640a36ac2d4e509ef51f623faf95..f95e9ad7d83c98a2d05bcd87aac823e96ca2d2f1 100644 (file)
@@ -11,7 +11,7 @@
 // This test checks that the `_` type placeholder works
 // correctly for enabling type inference.
 
-static CONSTEXPR: *const int = &'static 413 as *const _;
+static CONSTEXPR: *const int = &413 as *const _;
 
 pub fn main() {
     let x: Vec<_> = range(0u, 5).collect();
index db0cc83d7866af826dcdadb3602850083b1b822c..f49e8f46e78e6a476f56f7a5380300789f1ed3f5 100644 (file)
@@ -8,20 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Test syntax checks for `type` keyword.
+// Test syntax checks for `Sized?` syntax.
 
-trait T1 for type {}
-pub trait T2 for type {}
-trait T3<X: T1> for type: T2 {}
-trait T4<type X> {}
-trait T5<type X, Y> {}
-trait T6<Y, type X> {}
-trait T7<type X, type Y> {}
-trait T8<type X: T2> {}
-struct S1<type X>;
-enum E<type X> {}
-impl <type X> T1 for S1<X> {}
-fn f<type X>() {}
+trait T1 for Sized? {}
+pub trait T2 for Sized? {}
+trait T3<X: T1> for Sized?: T2 {}
+trait T4<Sized? X> {}
+trait T5<Sized? X, Y> {}
+trait T6<Y, Sized? X> {}
+trait T7<Sized? X, Sized? Y> {}
+trait T8<Sized? X: T2> {}
+struct S1<Sized? X>;
+enum E<Sized? X> {}
+impl <Sized? X> T1 for S1<X> {}
+fn f<Sized? X>() {}
 
 pub fn main() {
 }
index 53db7f37e8d51309c4d2e6b224dd092a69dc8c09..9703b55cda760855c10c5bc9fd5b07af1190a0a3 100644 (file)
@@ -13,7 +13,7 @@
 // Test sized-ness checking in substitution.
 
 // Unbounded.
-fn f1<type X>(x: &X) {
+fn f1<Sized? X>(x: &X) {
     f1::<X>(x);
 }
 fn f2<X>(x: &X) {
@@ -22,8 +22,8 @@ fn f2<X>(x: &X) {
 }
 
 // Bounded.
-trait T for type {}
-fn f3<type X: T>(x: &X) {
+trait T for Sized? {}
+fn f3<Sized? X: T>(x: &X) {
     f3::<X>(x);
 }
 fn f4<X: T>(x: &X) {
@@ -32,7 +32,7 @@ fn f4<X: T>(x: &X) {
 }
 
 // Self type.
-trait T2 for type {
+trait T2 for Sized? {
     fn f() -> Box<Self>;
 }
 struct S;
@@ -41,14 +41,14 @@ fn f() -> Box<S> {
         box S
     }
 }
-fn f5<type X: T2>(x: &X) {
+fn f5<Sized? X: T2>(x: &X) {
     let _: Box<X> = T2::f();
 }
 fn f6<X: T2>(x: &X) {
     let _: Box<X> = T2::f();
 }
 
-trait T3 for type {
+trait T3 for Sized? {
     fn f() -> Box<Self>;
 }
 impl T3 for S {
@@ -56,7 +56,7 @@ fn f() -> Box<S> {
         box S
     }
 }
-fn f7<type X: T3>(x: &X) {
+fn f7<Sized? X: T3>(x: &X) {
     // This is valid, but the unsized bound on X is irrelevant because any type
     // which implements T3 must have statically known size.
     let _: Box<X> = T3::f();
@@ -66,7 +66,7 @@ trait T4<X> {
     fn m1(x: &T4<X>);
     fn m2(x: &T5<X>);
 }
-trait T5<type X> {
+trait T5<Sized? X> {
     // not an error (for now)
     fn m1(x: &T4<X>);
     fn m2(x: &T5<X>);
@@ -76,21 +76,21 @@ trait T6<X: T> {
     fn m1(x: &T4<X>);
     fn m2(x: &T5<X>);
 }
-trait T7<type X: T> {
+trait T7<Sized? X: T> {
     // not an error (for now)
     fn m1(x: &T4<X>);
     fn m2(x: &T5<X>);
 }
 
 // The last field in a struct or variant may be unsized
-struct S2<type X> {
+struct S2<Sized? X> {
     f: X,
 }
-struct S3<type X> {
+struct S3<Sized? X> {
     f1: int,
     f2: X,
 }
-enum E<type X> {
+enum E<Sized? X> {
     V1(X),
     V2{x: X},
     V3(int, X),
index 3f152cc10610f3ae1894c654f09f4d6a9a9f33ed..dfed391640516d0cf6e6b90e4d65d5c0d685b2f7 100644 (file)
 #![no_std]
 extern crate std;
 extern crate zed = "std";
-extern crate bar = "std#0.11.0";
 
 
 use std::str;
 use x = zed::str;
 mod baz {
-    pub use bar::str;
     pub use x = std::str;
 }
 
index 4d9f80cec6ace370c9957740008af0eca8b8922a..deb08a4608cc0358c533531e7b2d1fff79289caa 100644 (file)
@@ -9,12 +9,12 @@
 // except according to those terms.
 
 pub fn main() {
-    assert_eq!((vec!(0i, 1)).to_str(), "[0, 1]".to_string());
-    assert_eq!((&[1i, 2]).to_str(), "[1, 2]".to_string());
+    assert_eq!((vec!(0i, 1)).to_string(), "[0, 1]".to_string());
+    assert_eq!((&[1i, 2]).to_string(), "[1, 2]".to_string());
 
     let foo = vec!(3i, 4);
     let bar = &[4i, 5];
 
-    assert_eq!(foo.to_str(), "[3, 4]".to_string());
-    assert_eq!(bar.to_str(), "[4, 5]".to_string());
+    assert_eq!(foo.to_string(), "[3, 4]".to_string());
+    assert_eq!(bar.to_string(), "[4, 5]".to_string());
 }