]> git.lizzy.rs Git - rust.git/commitdiff
rollup merge of #20086: shepmaster/random-typo
authorAlex Crichton <alex@alexcrichton.com>
Sun, 21 Dec 2014 08:04:29 +0000 (00:04 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Sun, 21 Dec 2014 17:27:37 +0000 (09:27 -0800)
326 files changed:
mk/crates.mk
mk/docs.mk
mk/tests.mk
src/compiletest/runtest.rs
src/doc/README.md
src/doc/guide-ownership.md
src/doc/guide.md
src/doc/po4a.conf [deleted file]
src/doc/reference.md
src/doc/rust.css
src/etc/rust-lldb
src/liballoc/arc.rs
src/liballoc/boxed.rs
src/liballoc/rc.rs
src/libcollections/bench.rs
src/libcollections/binary_heap.rs
src/libcollections/bit.rs
src/libcollections/btree/map.rs
src/libcollections/btree/node.rs
src/libcollections/btree/set.rs
src/libcollections/dlist.rs
src/libcollections/enum_set.rs
src/libcollections/lib.rs
src/libcollections/ring_buf.rs
src/libcollections/slice.rs
src/libcollections/str.rs
src/libcollections/string.rs
src/libcollections/vec.rs
src/libcollections/vec_map.rs
src/libcore/array.rs
src/libcore/bool.rs [deleted file]
src/libcore/borrow.rs
src/libcore/cell.rs
src/libcore/clone.rs
src/libcore/hash/sip.rs
src/libcore/intrinsics.rs
src/libcore/iter.rs
src/libcore/kinds.rs
src/libcore/lib.rs
src/libcore/num/int.rs
src/libcore/num/int_macros.rs
src/libcore/num/uint.rs
src/libcore/num/uint_macros.rs
src/libcore/option.rs
src/libcore/ptr.rs
src/libcore/result.rs
src/libcore/slice.rs
src/libcore/tuple.rs [new file with mode: 0644]
src/libcore/tuple/mod.rs [deleted file]
src/libcore/tuple/unit.rs [deleted file]
src/libfmt_macros/lib.rs
src/libgetopts/lib.rs
src/librustc/lib.rs
src/librustc/lint/builtin.rs
src/librustc/metadata/creader.rs
src/librustc/metadata/csearch.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/encoder.rs
src/librustc/metadata/loader.rs
src/librustc/metadata/tyencode.rs
src/librustc/middle/cfg/mod.rs
src/librustc/middle/check_match.rs
src/librustc/middle/check_static_recursion.rs
src/librustc/middle/const_eval.rs
src/librustc/middle/def.rs
src/librustc/middle/graph.rs
src/librustc/middle/infer/coercion.rs
src/librustc/middle/infer/freshen.rs
src/librustc/middle/infer/region_inference/graphviz.rs
src/librustc/middle/pat_util.rs
src/librustc/middle/privacy.rs
src/librustc/middle/resolve.rs [deleted file]
src/librustc/middle/resolve_lifetime.rs
src/librustc/middle/stability.rs
src/librustc/middle/traits/fulfill.rs
src/librustc/middle/ty.rs
src/librustc/middle/ty_fold.rs
src/librustc/session/config.rs
src/librustc/util/ppaux.rs
src/librustc_borrowck/borrowck/move_data.rs
src/librustc_borrowck/lib.rs
src/librustc_driver/driver.rs
src/librustc_driver/lib.rs
src/librustc_driver/test.rs
src/librustc_resolve/check_unused.rs [new file with mode: 0644]
src/librustc_resolve/lib.rs [new file with mode: 0644]
src/librustc_resolve/record_exports.rs [new file with mode: 0644]
src/librustc_trans/back/write.rs
src/librustc_trans/lib.rs
src/librustc_trans/trans/_match.rs
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/callee.rs
src/librustc_trans/trans/common.rs
src/librustc_trans/trans/context.rs
src/librustc_trans/trans/controlflow.rs
src/librustc_trans/trans/debuginfo.rs
src/librustc_trans/trans/expr.rs
src/librustc_trans/trans/meth.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/closure.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/check/wf.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/lib.rs
src/librustdoc/clean/mod.rs
src/librustdoc/html/format.rs
src/librustdoc/html/render.rs
src/librustdoc/lib.rs
src/libserialize/json.rs
src/libstd/ascii.rs
src/libstd/bitflags.rs
src/libstd/bool.rs [new file with mode: 0644]
src/libstd/c_str.rs
src/libstd/collections/hash/map.rs
src/libstd/collections/hash/set.rs
src/libstd/collections/hash/table.rs
src/libstd/comm/mod.rs
src/libstd/dynamic_lib.rs
src/libstd/io/buffered.rs
src/libstd/io/comm_adapters.rs
src/libstd/io/fs.rs
src/libstd/io/mem.rs
src/libstd/io/stdio.rs
src/libstd/io/tempfile.rs
src/libstd/io/timer.rs
src/libstd/lib.rs
src/libstd/num/f32.rs
src/libstd/num/f64.rs
src/libstd/num/int.rs
src/libstd/num/strconv.rs
src/libstd/num/uint.rs
src/libstd/os.rs
src/libstd/path/mod.rs
src/libstd/path/posix.rs
src/libstd/path/windows.rs
src/libstd/prelude.rs
src/libstd/rand/os.rs
src/libstd/rt/util.rs
src/libstd/sync/future.rs
src/libstd/sync/task_pool.rs
src/libstd/sys/common/mutex.rs
src/libstd/sys/common/net.rs
src/libstd/sys/unix/backtrace.rs
src/libstd/sys/unix/fs.rs
src/libstd/sys/unix/os.rs
src/libstd/sys/unix/pipe.rs
src/libstd/sys/unix/tcp.rs
src/libstd/sys/unix/timer.rs
src/libstd/sys/windows/condvar.rs
src/libstd/sys/windows/fs.rs
src/libstd/sys/windows/os.rs
src/libstd/sys/windows/process.rs
src/libstd/sys/windows/tcp.rs
src/libstd/sys/windows/timer.rs
src/libstd/thread.rs
src/libstd/tuple.rs [new file with mode: 0644]
src/libstd/unit.rs [new file with mode: 0644]
src/libsyntax/ast.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/deriving/generic/mod.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/format.rs
src/libsyntax/ext/mtwt.rs
src/libsyntax/ext/tt/macro_parser.rs
src/libsyntax/fold.rs
src/libsyntax/lib.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/visit.rs
src/libtest/stats.rs
src/test/auxiliary/nested_item.rs
src/test/bench/noise.rs
src/test/bench/shootout-fannkuch-redux.rs
src/test/bench/shootout-fasta-redux.rs
src/test/bench/shootout-fasta.rs
src/test/bench/shootout-k-nucleotide.rs
src/test/bench/shootout-nbody.rs
src/test/bench/shootout-reverse-complement.rs
src/test/bench/sudoku.rs
src/test/compile-fail/better-expected.rs
src/test/compile-fail/borrowck-for-loop-correct-cmt-for-pattern.rs
src/test/compile-fail/coercion-slice.rs
src/test/compile-fail/const-cast-wrong-type.rs
src/test/compile-fail/dst-bad-coerce1.rs
src/test/compile-fail/dst-bad-coerce2.rs
src/test/compile-fail/dst-bad-coerce3.rs
src/test/compile-fail/dst-bad-coerce4.rs
src/test/compile-fail/dst-bad-deep.rs
src/test/compile-fail/huge-array-simple.rs
src/test/compile-fail/huge-array.rs
src/test/compile-fail/huge-enum.rs
src/test/compile-fail/issue-13446.rs
src/test/compile-fail/issue-13482-2.rs
src/test/compile-fail/issue-13482.rs
src/test/compile-fail/issue-14845.rs
src/test/compile-fail/issue-17252.rs
src/test/compile-fail/issue-17441.rs
src/test/compile-fail/issue-17718-borrow-interior.rs
src/test/compile-fail/issue-19244-1.rs
src/test/compile-fail/issue-19244-2.rs
src/test/compile-fail/issue-19991.rs [new file with mode: 0644]
src/test/compile-fail/issue-2149.rs
src/test/compile-fail/issue-4517.rs
src/test/compile-fail/issue-9957.rs
src/test/compile-fail/lint-uppercase-variables.rs
src/test/compile-fail/move-fragments-9.rs
src/test/compile-fail/moves-based-on-type-exprs.rs
src/test/compile-fail/non-constant-enum-for-vec-repeat.rs
src/test/compile-fail/non-constant-expr-for-fixed-len-vec.rs
src/test/compile-fail/non-constant-expr-for-vec-repeat.rs
src/test/compile-fail/non-exhaustive-pattern-witness.rs
src/test/compile-fail/packed-struct-generic-transmute.rs
src/test/compile-fail/region-lifetime-bounds-on-fns-where-clause.rs [new file with mode: 0644]
src/test/compile-fail/region-multiple-lifetime-bounds-on-fns-where-clause.rs [new file with mode: 0644]
src/test/compile-fail/removed-syntax-fixed-vec.rs
src/test/compile-fail/removed-syntax-mut-vec-expr.rs
src/test/compile-fail/removed-syntax-mut-vec-ty.rs
src/test/compile-fail/repeat-to-run-dtor-twice.rs
src/test/compile-fail/repeat_count.rs
src/test/compile-fail/static-vec-repeat-not-constant.rs
src/test/compile-fail/trailing-comma-array-repeat.rs [deleted file]
src/test/compile-fail/transmute-type-parameters.rs
src/test/compile-fail/vector-cast-weirdness.rs
src/test/compile-fail/visible-private-types-generics.rs
src/test/compile-fail/visible-private-types-supertrait.rs
src/test/compile-fail/where-clause-constraints-are-local-for-inherent-impl.rs [new file with mode: 0644]
src/test/compile-fail/where-clause-constraints-are-local-for-trait-impl.rs [new file with mode: 0644]
src/test/compile-fail/where-clause-method-substituion.rs [new file with mode: 0644]
src/test/compile-fail/where-clauses-method-unsatisfied.rs [new file with mode: 0644]
src/test/compile-fail/where-clauses-not-parameter.rs
src/test/debuginfo/destructured-for-loop-variable.rs [new file with mode: 0644]
src/test/debuginfo/evec-in-struct.rs
src/test/debuginfo/lexical-scope-in-for-loop.rs
src/test/debuginfo/lexical-scopes-in-block-expression.rs
src/test/debuginfo/recursive-struct.rs
src/test/debuginfo/type-names.rs
src/test/debuginfo/vec.rs
src/test/pretty/blank-lines.rs
src/test/pretty/issue-4264.pp
src/test/pretty/where-clauses.rs [new file with mode: 0644]
src/test/run-make/dep-info-custom/Makefile.foo
src/test/run-make/dep-info/Makefile.foo
src/test/run-make/issue-7349/Makefile
src/test/run-make/libs-through-symlinks/Makefile
src/test/run-make/no-stack-check/attr.rs
src/test/run-make/no-stack-check/flag.rs
src/test/run-make/output-type-permutations/Makefile
src/test/run-make/sepcomp-cci-copies/Makefile
src/test/run-make/sepcomp-inlining/Makefile
src/test/run-make/sepcomp-separate/Makefile
src/test/run-make/target-specs/foo.rs
src/test/run-make/version/Makefile
src/test/run-make/volatile-intrinsics/Makefile
src/test/run-pass/cast-in-array-size.rs
src/test/run-pass/check-static-slice.rs
src/test/run-pass/const-autoderef.rs
src/test/run-pass/const-enum-vec-index.rs
src/test/run-pass/const-enum-vector.rs
src/test/run-pass/const-expr-in-fixed-length-vec.rs
src/test/run-pass/const-expr-in-vec-repeat.rs
src/test/run-pass/const-fields-and-indexing.rs
src/test/run-pass/const-region-ptrs-noncopy.rs
src/test/run-pass/const-str-ptr.rs
src/test/run-pass/const-vecs-and-slices.rs
src/test/run-pass/dst-struct.rs
src/test/run-pass/enum-vec-initializer.rs
src/test/run-pass/evec-internal.rs
src/test/run-pass/exponential-notation.rs
src/test/run-pass/huge-largest-array.rs
src/test/run-pass/ifmt.rs
src/test/run-pass/issue-11205.rs
src/test/run-pass/issue-13259-windows-tcb-trash.rs
src/test/run-pass/issue-13763.rs
src/test/run-pass/issue-13837.rs
src/test/run-pass/issue-14254.rs
src/test/run-pass/issue-14940.rs
src/test/run-pass/issue-15673.rs
src/test/run-pass/issue-17302.rs
src/test/run-pass/issue-17877.rs
src/test/run-pass/issue-18425.rs
src/test/run-pass/issue-19244.rs
src/test/run-pass/issue-19811-escape-unicode.rs [new file with mode: 0644]
src/test/run-pass/issue-2904.rs
src/test/run-pass/issue-3656.rs
src/test/run-pass/issue-4387.rs
src/test/run-pass/issue-5688.rs
src/test/run-pass/issue-7784.rs
src/test/run-pass/issue-9942.rs
src/test/run-pass/macro-invocation-in-count-expr-fixed-array-type.rs
src/test/run-pass/match-arm-statics.rs
src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs
src/test/run-pass/method-two-traits-distinguished-via-where-clause.rs
src/test/run-pass/mutability-inherits-through-fixed-length-vec.rs
src/test/run-pass/new-style-fixed-length-vec.rs
src/test/run-pass/nullable-pointer-iotareduction.rs
src/test/run-pass/nullable-pointer-size.rs
src/test/run-pass/order-drop-with-match.rs
src/test/run-pass/out-of-stack-new-thread-no-split.rs
src/test/run-pass/out-of-stack-no-split.rs
src/test/run-pass/out-of-stack.rs
src/test/run-pass/packed-struct-generic-layout.rs
src/test/run-pass/packed-struct-layout.rs
src/test/run-pass/packed-struct-size.rs
src/test/run-pass/packed-struct-vec.rs
src/test/run-pass/packed-tuple-struct-layout.rs
src/test/run-pass/packed-tuple-struct-size.rs
src/test/run-pass/regions-dependent-addr-of.rs
src/test/run-pass/repeat-expr-in-static.rs
src/test/run-pass/repeated-vector-syntax.rs
src/test/run-pass/self-impl.rs [new file with mode: 0644]
src/test/run-pass/uninit-empty-types.rs
src/test/run-pass/unsized3.rs
src/test/run-pass/variadic-ffi.rs
src/test/run-pass/vec-dst.rs
src/test/run-pass/vec-fixed-length.rs
src/test/run-pass/vec-repeat-with-cast.rs
src/test/run-pass/vector-sort-panic-safe.rs
src/test/run-pass/where-clause-early-bound-lifetimes.rs [new file with mode: 0644]
src/test/run-pass/where-clause-method-substituion.rs [new file with mode: 0644]
src/test/run-pass/where-clause-region-outlives.rs [new file with mode: 0644]
src/test/run-pass/where-clauses-method.rs [new file with mode: 0644]
src/test/run-pass/where-clauses-not-parameter.rs [new file with mode: 0644]

index fafe77c78da4e514b8903180e7bc788284b94de9..e20cb06e3a8ca43a21aadb134bbfa52e6c2648a8 100644 (file)
@@ -53,7 +53,8 @@ TARGET_CRATES := libc std flate arena term \
                  serialize getopts collections test time rand \
                  log regex graphviz core rbml alloc \
                  unicode
-RUSTC_CRATES := rustc rustc_typeck rustc_borrowck rustc_driver rustc_trans rustc_back rustc_llvm 
+RUSTC_CRATES := rustc rustc_typeck rustc_borrowck rustc_resolve rustc_driver \
+                rustc_trans rustc_back rustc_llvm
 HOST_CRATES := syntax $(RUSTC_CRATES) rustdoc regex_macros fmt_macros
 CRATES := $(TARGET_CRATES) $(HOST_CRATES)
 TOOLS := compiletest rustdoc rustc
@@ -67,11 +68,12 @@ DEPS_std := core libc rand alloc collections unicode \
 DEPS_graphviz := std
 DEPS_syntax := std term serialize log fmt_macros arena libc
 DEPS_rustc_driver := arena flate getopts graphviz libc rustc rustc_back rustc_borrowck \
-                     rustc_typeck log syntax serialize rustc_llvm rustc_trans
+                     rustc_typeck rustc_resolve log syntax serialize rustc_llvm rustc_trans
 DEPS_rustc_trans := arena flate getopts graphviz libc rustc rustc_back \
                        log syntax serialize rustc_llvm
 DEPS_rustc_typeck := rustc syntax
 DEPS_rustc_borrowck := rustc log graphviz syntax
+DEPS_rustc_resolve := rustc log syntax
 DEPS_rustc := syntax flate arena serialize getopts rbml \
               time log graphviz rustc_llvm rustc_back
 DEPS_rustc_llvm := native:rustllvm libc std
@@ -118,9 +120,11 @@ DOC_CRATES := $(filter-out rustc, \
               $(filter-out rustc_trans, \
               $(filter-out rustc_typeck, \
               $(filter-out rustc_borrowck, \
+              $(filter-out rustc_resolve, \
               $(filter-out rustc_driver, \
-              $(filter-out syntax, $(CRATES)))))))
-COMPILER_DOC_CRATES := rustc rustc_trans rustc_borrowck rustc_typeck rustc_driver syntax
+              $(filter-out syntax, $(CRATES))))))))
+COMPILER_DOC_CRATES := rustc rustc_trans rustc_borrowck rustc_resolve \
+                       rustc_typeck rustc_driver syntax
 
 # This macro creates some simple definitions for each crate being built, just
 # some munging of all of the parameters above.
index 6d1a3bfa7a3263fad2d63b85cc261d7864ed2d4e..9a924916ec8615a3b1ee285468b50ff822ba9547 100644 (file)
@@ -216,36 +216,6 @@ endef
 $(foreach docname,$(DOCS),$(eval $(call DEF_DOC,$(docname))))
 
 
-# Localized documentation
-
-# FIXME: I (huonw) haven't actually been able to test properly, since
-# e.g. (by default) I'm doing an out-of-tree build (#12763), but even
-# adjusting for that, the files are too old(?) and are rejected by
-# po4a.
-#
-# As such, I've attempted to get it working as much as possible (and
-# switching from pandoc to rustdoc), but preserving the old behaviour
-# (e.g. only running on the guide)
-.PHONY: l10n-mds
-l10n-mds: $(D)/po4a.conf \
-               $(foreach lang,$(L10N_LANG),$(D)/po/$(lang)/*.md.po)
-       $(warning WARNING: localized documentation is experimental)
-       po4a --copyright-holder="The Rust Project Developers" \
-               --package-name="Rust" \
-               --package-version="$(CFG_RELEASE)" \
-               -M UTF-8 -L UTF-8 \
-               $(D)/po4a.conf
-
-define DEF_L10N_DOC
-DOC_L10N_TARGETS += doc/l10n/$(1)/$(2).html
-doc/l10n/$(1)/$(2).html: l10n-mds $$(HTML_DEPS) $$(RUSTDOC_DEPS_$(2))
-       @$$(call E, rustdoc: $$@)
-       $$(RUSTDOC) $$(RUSTDOC_HTML_OPTS) $$(RUSTDOC_FLAGS_$(1)) doc/l10n/$(1)/$(2).md
-endef
-
-$(foreach lang,$(L10N_LANGS),$(eval $(call DEF_L10N_DOC,$(lang),guide)))
-
-
 ######################################################################
 # Rustdoc (libstd/extra)
 ######################################################################
@@ -294,7 +264,3 @@ endif
 
 docs: $(DOC_TARGETS)
 compiler-docs: $(COMPILER_DOC_TARGETS)
-
-docs-l10n: $(DOC_L10N_TARGETS)
-
-.PHONY: docs-l10n
index 3340f9b4969ea2d7c12335e120bb9e22cba1ce38..3d66ce86d7b098da4e2942d7af6bacade12ac4f9 100644 (file)
@@ -21,7 +21,8 @@ $(eval $(call RUST_CRATE,coretest))
 
 TEST_TARGET_CRATES = $(filter-out core unicode,$(TARGET_CRATES)) coretest
 TEST_DOC_CRATES = $(DOC_CRATES)
-TEST_HOST_CRATES = $(filter-out rustc_typeck rustc_borrowck rustc_trans,$(HOST_CRATES))
+TEST_HOST_CRATES = $(filter-out rustc_typeck rustc_borrowck rustc_resolve rustc_trans,\
+                     $(HOST_CRATES))
 TEST_CRATES = $(TEST_TARGET_CRATES) $(TEST_HOST_CRATES)
 
 ######################################################################
@@ -73,21 +74,6 @@ endif
 TEST_LOG_FILE=tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).log
 TEST_OK_FILE=tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).ok
 
-TEST_RATCHET_FILE=tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4)-metrics.json
-TEST_RATCHET_NOISE_PERCENT=10.0
-
-# Whether to ratchet or merely save benchmarks
-ifdef CFG_RATCHET_BENCH
-CRATE_TEST_EXTRA_ARGS= \
-  --test $(TEST_BENCH) \
-  --ratchet-metrics $(call TEST_RATCHET_FILE,$(1),$(2),$(3),$(4)) \
-  --ratchet-noise-percent $(TEST_RATCHET_NOISE_PERCENT)
-else
-CRATE_TEST_EXTRA_ARGS= \
-  --test $(TEST_BENCH) \
-  --save-metrics $(call TEST_RATCHET_FILE,$(1),$(2),$(3),$(4))
-endif
-
 # If we're sharding the testsuite between parallel testers,
 # pass this argument along to the compiletest and crate test
 # invocations.
@@ -299,7 +285,7 @@ tidy:
                | xargs -n 10 $(CFG_PYTHON) $(S)src/etc/tidy.py
                $(Q)echo $(ALL_HS) \
                | xargs -n 10 $(CFG_PYTHON) $(S)src/etc/tidy.py
-               $(Q)find $(S)src -type f -perm +a+x \
+               $(Q)find $(S)src -type f -perm /a+x \
                    -not -name '*.rs' -and -not -name '*.py' \
                    -and -not -name '*.sh' \
                | grep '^$(S)src/jemalloc' -v \
@@ -454,7 +440,6 @@ $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \
        $$(Q)touch tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).log
        $$(Q)$(CFG_ADB) pull $(CFG_ADB_TEST_DIR)/check-stage$(1)-T-$(2)-H-$(3)-$(4).log tmp/
        $$(Q)$(CFG_ADB) shell rm $(CFG_ADB_TEST_DIR)/check-stage$(1)-T-$(2)-H-$(3)-$(4).log
-       $$(Q)$(CFG_ADB) pull $(CFG_ADB_TEST_DIR)/$$(call TEST_RATCHET_FILE,$(1),$(2),$(3),$(4)) tmp/
        @if grep -q "result: ok" tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).tmp; \
        then \
                rm tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).tmp; \
@@ -696,7 +681,6 @@ CTEST_ARGS$(1)-T-$(2)-H-$(3)-$(4) := \
         $$(CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3)) \
         --src-base $$(S)src/test/$$(CTEST_SRC_BASE_$(4))/ \
         --build-base $(3)/test/$$(CTEST_BUILD_BASE_$(4))/ \
-        --ratchet-metrics $(call TEST_RATCHET_FILE,$(1),$(2),$(3),$(4)) \
         --mode $$(CTEST_MODE_$(4)) \
        $$(CTEST_RUNTOOL_$(4))
 
index 1b445a6e7367fa77cf6ca20523b1d7e336b2a0fa..567734b0dab7b2b73f5b1397d5e6f3877e115dec 100644 (file)
@@ -1609,7 +1609,7 @@ fn _arm_exec_compiled_test(config: &Config,
                 stderr_out.as_slice());
 
     ProcRes {
-        status: process::ExitStatus(exitcode),
+        status: process::ProcessExit::ExitStatus(exitcode),
         stdout: stdout_out,
         stderr: stderr_out,
         cmdline: cmdline
@@ -1666,7 +1666,7 @@ fn compile_test_and_save_bitcode(config: &Config, props: &TestProps,
     // FIXME (#9639): This needs to handle non-utf8 paths
     let mut link_args = vec!("-L".to_string(),
                              aux_dir.as_str().unwrap().to_string());
-    let llvm_args = vec!("--emit=bc,obj".to_string(),
+    let llvm_args = vec!("--emit=llvm-bc,obj".to_string(),
                          "--crate-type=lib".to_string());
     link_args.extend(llvm_args.into_iter());
     let args = make_compile_args(config,
index 50222973509ad6eccda20b5d280496ed7b8a31b6..3b12ffe8f11e1bf25151fe09760763ef079960ad 100644 (file)
@@ -6,12 +6,6 @@
 document converter, is required to generate docs as HTML from Rust's
 source code.
 
-[po4a](http://po4a.alioth.debian.org/) is required for generating translated
-docs from the master (English) docs.
-
-[GNU gettext](http://www.gnu.org/software/gettext/) is required for managing
-the translation data.
-
 ## Building
 
 To generate all the docs, just run `make docs` from the root of the repository.
@@ -44,43 +38,3 @@ The syntax for pandoc flavored markdown can be found at:
 A nice quick reference (for non-pandoc markdown) is at:
 
 - http://kramdown.gettalong.org/quickref.html
-
-## Notes for translators
-
-Notice: The procedure described below is a work in progress. We are working on
-translation system but the procedure contains some manual operations for now.
-
-To start the translation for a new language, see `po4a.conf` at first.
-
-To generate `.pot` and `.po` files, do something like:
-
-~~~~
-po4a --copyright-holder="The Rust Project Developers" \
-    --package-name="Rust" \
-    --package-version="0.13.0" \
-    -M UTF-8 -L UTF-8 \
-    src/doc/po4a.conf
-~~~~
-
-(the version number must be changed if it is not `0.13.0` now.)
-
-Now you can translate documents with `.po` files, commonly used with gettext. If
-you are not familiar with gettext-based translation, please read the online
-manual linked from http://www.gnu.org/software/gettext/ . We use UTF-8 as the
-file encoding of `.po` files.
-
-When you want to make a commit, do the command below before staging your
-change:
-
-~~~~
-for f in src/doc/po/**/*.po; do
-    msgattrib --translated $f -o $f.strip
-    if [ -e $f.strip ]; then
-       mv $f.strip $f
-    else
-       rm $f
-    fi
-done
-~~~~
-
-This removes untranslated entries from `.po` files to save disk space.
index 1a46970414371fb8708a2cf50d06134cb5110af2..bf750ecaa8f673acd63f36e7822feb6c0c33465f 100644 (file)
@@ -324,7 +324,7 @@ fn main() {
     let f = Foo { x: y }; // -+ f goes into scope
     // stuff              //  |
                           //  |
-}                         // -+ f & y go out of scope
+}                         // -+ f and y go out of scope
 ```
 
 Our `f` lives within the scope of `y`, so everything works. What if it didn't?
@@ -342,7 +342,7 @@ fn main() {
         let y = &5i;          // ---+ y goes into scope
         let f = Foo { x: y }; // ---+ f goes into scope
         x = &f.x;             //  | | error here
-    }                         // ---+ f & y go out of scope
+    }                         // ---+ f and y go out of scope
                               //  |
     println!("{}", x);        //  |
 }                             // -+ x goes out of scope
@@ -395,7 +395,7 @@ struct Wheel {
 }
 
 fn main() {
-    let car = Car { name: "DeLorian".to_string() };
+    let car = Car { name: "DeLorean".to_string() };
 
     for _ in range(0u, 4) {
         Wheel { size: 360, owner: car };
@@ -431,7 +431,7 @@ struct Wheel {
 }
 
 fn main() {
-    let car = Car { name: "DeLorian".to_string() };
+    let car = Car { name: "DeLorean".to_string() };
 
     let car_owner = Rc::new(car);
 
index d739ad105fc873776a9e900088b2f32957acda8c..1cd100e15980719f1ab5392a17de7e55c4db1d2c 100644 (file)
@@ -31,7 +31,6 @@ below.)
 
 If you're on Windows, please download either the [32-bit
 installer](https://static.rust-lang.org/dist/rust-nightly-i686-pc-windows-gnu.exe)
-
 or the [64-bit
 installer](https://static.rust-lang.org/dist/rust-nightly-x86_64-pc-windows-gnu.exe)
 and run it.
@@ -1170,7 +1169,7 @@ enum StringResult {
     ErrorReason(String),
 }
 ```
-Where a `StringResult` is either an `StringOK`, with the result of a computation, or an
+Where a `StringResult` is either a `StringOK`, with the result of a computation, or an
 `ErrorReason` with a `String` explaining what caused the computation to fail. These kinds of
 `enum`s are actually very useful and are even part of the standard library.
 
@@ -1192,7 +1191,7 @@ fn respond(greeting: &str) -> StringResult {
 ```
 
 Notice that we need both the enum name and the variant name: `StringResult::StringOK`, but
-we didn't need to with `Ordering`, we just said `Greater` rather than `Ordering::Greater`.
+we didn't need to with `Ordering` â€“ we just said `Greater` rather than `Ordering::Greater`.
 There's a reason: the Rust prelude imports the variants of `Ordering` as well as the enum
 itself. We can use the `use` keyword to do something similar with `StringResult`:
 
@@ -1223,16 +1222,16 @@ now, rather than the full `StringResult::StringOK`. Importing variants can be co
 also cause name conflicts, so do this with caution. It's considered good style to rarely import
 variants for this reason.
 
-As you can see `enum`s with values are quite a powerful tool for data representation,
-and can be even more useful when they're generic across types. But before we get to
-generics, let's talk about how to use them with pattern matching, a tool that will
+As you can see, `enum`s with values are quite a powerful tool for data representation,
+and can be even more useful when they're generic across types. Before we get to generics,
+though, let's talk about how to use them with pattern matching, a tool that will
 let us deconstruct this sum type (the type theory term for enums) in a very elegant
 way and avoid all these messy `if`/`else`s.
 
 # Match
 
 Often, a simple `if`/`else` isn't enough, because you have more than two
-possible options. And `else` conditions can get incredibly complicated. So
+possible options. Also, `else` conditions can get incredibly complicated, so
 what's the solution?
 
 Rust has a keyword, `match`, that allows you to replace complicated `if`/`else`
@@ -1251,13 +1250,13 @@ match x {
 }
 ```
 
-`match` takes an expression, and then branches based on its value. Each 'arm' of
+`match` takes an expression and then branches based on its value. Each 'arm' of
 the branch is of the form `val => expression`. When the value matches, that arm's
 expression will be evaluated. It's called `match` because of the term 'pattern
-matching,' which `match` is an implementation of.
+matching', which `match` is an implementation of.
 
 So what's the big advantage here? Well, there are a few. First of all, `match`
-enforces 'exhaustiveness checking.' Do you see that last arm, the one with the
+enforces 'exhaustiveness checking'. Do you see that last arm, the one with the
 underscore (`_`)? If we remove that arm, Rust will give us an error:
 
 ```text
@@ -1265,11 +1264,11 @@ error: non-exhaustive patterns: `_` not covered
 ```
 
 In other words, Rust is trying to tell us we forgot a value. Because `x` is an
-integer, Rust knows that it can have a number of different values. For example,
-`6i`. But without the `_`, there is no arm that could match, and so Rust refuses
-to compile. `_` is sort of like a catch-all arm. If none of the other arms match,
-the arm with `_` will. And since we have this catch-all arm, we now have an arm
-for every possible value of `x`, and so our program will now compile.
+integer, Rust knows that it can have a number of different values â€“ for example,
+`6i`. Without the `_`, however, there is no arm that could match, and so Rust refuses
+to compile. `_` acts like a 'catch-all arm'. If none of the other arms match,
+the arm with `_` will, and since we have this catch-all arm, we now have an arm
+for every possible value of `x`, and so our program will compile successfully.
 
 `match` statements also destructure enums, as well. Remember this code from the
 section on enums?
@@ -1350,14 +1349,14 @@ fn main() {
 ```
 
 That is how you can get and use the values contained in `enum`s.
-It can also allow us to treat errors or unexpected computations, for example, a
-function that is not guaranteed to be able to compute a result (an `int` here),
+It can also allow us to handle errors or unexpected computations; for example, a
+function that is not guaranteed to be able to compute a result (an `int` here)
 could return an `OptionalInt`, and we would handle that value with a `match`.
 As you can see, `enum` and `match` used together are quite useful!
 
-`match` is also an expression, which means we can use it on the right
-hand side of a `let` binding or directly where an expression is
-used. We could also implement the previous line like this:
+`match` is also an expression, which means we can use it on the right-hand
+side of a `let` binding or directly where an expression is used. We could
+also implement the previous line like this:
 
 ```{rust}
 fn cmp(a: int, b: int) -> Ordering {
@@ -1389,7 +1388,7 @@ two main looping constructs: `for` and `while`.
 
 The `for` loop is used to loop a particular number of times. Rust's `for` loops
 work a bit differently than in other systems languages, however. Rust's `for`
-loop doesn't look like this "C style" `for` loop:
+loop doesn't look like this "C-style" `for` loop:
 
 ```{c}
 for (x = 0; x < 10; x++) {
@@ -1424,7 +1423,7 @@ In our example, `range` is a function that takes a start and an end position,
 and gives an iterator over those values. The upper bound is exclusive, though,
 so our loop will print `0` through `9`, not `10`.
 
-Rust does not have the "C style" `for` loop on purpose. Manually controlling
+Rust does not have the "C-style" `for` loop on purpose. Manually controlling
 each element of the loop is complicated and error prone, even for experienced C
 developers.
 
@@ -1455,7 +1454,7 @@ If you need an infinite loop, you may be tempted to write this:
 while true {
 ```
 
-Rust has a dedicated keyword, `loop`, to handle this case:
+However, Rust has a dedicated keyword, `loop`, to handle this case:
 
 ```{rust,ignore}
 loop {
@@ -1465,7 +1464,7 @@ Rust's control-flow analysis treats this construct differently than a
 `while true`, since we know that it will always loop. The details of what
 that _means_ aren't super important to understand at this stage, but in
 general, the more information we can give to the compiler, the better it
-can do with safety and code generation. So you should always prefer
+can do with safety and code generation, so you should always prefer
 `loop` when you plan to loop infinitely.
 
 ## Ending iteration early
@@ -1484,7 +1483,7 @@ while !done {
 ```
 
 We had to keep a dedicated `mut` boolean variable binding, `done`, to know
-when we should skip out of the loop. Rust has two keywords to help us with
+when we should exit out of the loop. Rust has two keywords to help us with
 modifying iteration: `break` and `continue`.
 
 In this case, we can write the loop in a better way with `break`:
@@ -1499,10 +1498,10 @@ loop {
 }
 ```
 
-We now loop forever with `loop`, and use `break` to break out early.
+We now loop forever with `loop` and use `break` to break out early.
 
 `continue` is similar, but instead of ending the loop, goes to the next
-iteration: This will only print the odd numbers:
+iteration. This will only print the odd numbers:
 
 ```{rust}
 for x in range(0i, 10i) {
@@ -1519,8 +1518,8 @@ Both `continue` and `break` are valid in both kinds of loops.
 Strings are an important concept for any programmer to master. Rust's string
 handling system is a bit different from other languages, due to its systems
 focus. Any time you have a data structure of variable size, things can get
-tricky, and strings are a re-sizable data structure. That said, Rust's strings
-also work differently than in some other systems languages, such as C.
+tricky, and strings are a re-sizable data structure. That being said, Rust's
+strings also work differently than in some other systems languages, such as C.
 
 Let's dig into the details. A **string** is a sequence of Unicode scalar values
 encoded as a stream of UTF-8 bytes. All strings are guaranteed to be
@@ -1793,22 +1792,22 @@ fn main() {
 }
 ```
 
-We had to match each time, to see if we had a value or not. In this case,
-though, we _know_ that `x` has a `Value`. But `match` forces us to handle
+We had to match each time to see if we had a value or not. In this case,
+though, we _know_ that `x` has a `Value`, but `match` forces us to handle
 the `missing` case. This is what we want 99% of the time, but sometimes, we
 know better than the compiler.
 
 Likewise, `read_line()` does not return a line of input. It _might_ return a
-line of input. It might also fail to do so. This could happen if our program
+line of input, though it might also fail to do so. This could happen if our program
 isn't running in a terminal, but as part of a cron job, or some other context
 where there's no standard input. Because of this, `read_line` returns a type
 very similar to our `OptionalInt`: an `IoResult<T>`. We haven't talked about
 `IoResult<T>` yet because it is the **generic** form of our `OptionalInt`.
-Until then, you can think of it as being the same thing, just for any type, not
-just `int`s.
+Until then, you can think of it as being the same thing, just for any type â€“
+not just `int`s.
 
 Rust provides a method on these `IoResult<T>`s called `ok()`, which does the
-same thing as our `match` statement, but assuming that we have a valid value.
+same thing as our `match` statement but assumes that we have a valid value.
 We then call `expect()` on the result, which will terminate our program if we
 don't have a valid value. In this case, if we can't get input, our program
 doesn't work, so we're okay with that. In most cases, we would want to handle
@@ -1852,7 +1851,7 @@ fn main() {
 }
 ```
 
-Sometimes, this makes things more readable. Sometimes, less. Use your judgment
+Sometimes, this makes things more readable â€“ sometimes, less. Use your judgement
 here.
 
 That's all you need to get basic input from the standard input! It's not too
@@ -1972,10 +1971,8 @@ You can find that page [here](std/index.html). There's a lot of information on
 that page, but the best part is the search bar. Right up at the top, there's
 a box that you can enter in a search term. The search is pretty primitive
 right now, but is getting better all the time. If you type 'random' in that
-box, the page will update to [this
-one](std/index.html?search=random). The very first
-result is a link to
-[std::rand::random](std/rand/fn.random.html). If we
+box, the page will update to [this one](std/index.html?search=random). The very
+first result is a link to [`std::rand::random`](std/rand/fn.random.html). If we
 click on that result, we'll be taken to its documentation page.
 
 This page shows us a few things: the type signature of the function, some
@@ -2039,7 +2036,7 @@ rand::random::<int>();
 ```
 
 This says "please give me a random `int` value." We can change our code to use
-this hint...
+this hint:
 
 ```{rust,no_run}
 use std::io;
@@ -2380,7 +2377,7 @@ fn cmp(a: uint, b: uint) -> Ordering {
 }
 ```
 
-We use a `match` to either give us the `uint` inside of the `Option`, or we
+We use a `match` to either give us the `uint` inside of the `Option`, or else
 print an error message and return. Let's give this a shot:
 
 ```bash
@@ -2398,8 +2395,8 @@ Uh, what? But we did!
 
 ... actually, we didn't. See, when you get a line of input from `stdin()`,
 you get all the input. Including the `\n` character from you pressing Enter.
-So, `from_str()` sees the string `"5\n"` and says "nope, that's not a number,
-there's non-number stuff in there!" Luckily for us, `&str`s have an easy
+Therefore, `from_str()` sees the string `"5\n"` and says "nope, that's not a
+number; there's non-number stuff in there!" Luckily for us, `&str`s have an easy
 method we can use defined on them: `trim()`. One small modification, and our
 code looks like this:
 
@@ -2465,7 +2462,7 @@ out that I guessed 76. Run the program a few times, and verify that guessing
 the number works, as well as guessing a number too small.
 
 The Rust compiler helped us out quite a bit there! This technique is called
-"lean on the compiler," and it's often useful when working on some code. Let
+"lean on the compiler", and it's often useful when working on some code. Let
 the error messages help guide you towards the correct types.
 
 Now we've got most of the game working, but we can only make one guess. Let's
@@ -2473,8 +2470,8 @@ change that by adding loops!
 
 ## Looping
 
-As we already discussed, the `loop` keyword gives us an infinite loop. So
-let's add that in:
+As we already discussed, the `loop` keyword gives us an infinite loop.
+Let's add that in:
 
 ```{rust,no_run}
 use std::io;
@@ -2780,12 +2777,11 @@ $ cargo run
 Hello, world!
 ```
 
-Excellent! So, we already have a single crate here: our `src/main.rs` is a crate.
+Excellent! We already have a single crate here: our `src/main.rs` is a crate.
 Everything in that file is in the crate root. A crate that generates an executable
 defines a `main` function inside its root, as we've done here.
 
-Let's define a new module inside our crate. Edit `src/main.rs` to look
-like this:
+Let's define a new module inside our crate. Edit `src/main.rs` to look like this:
 
 ```
 fn main() {
@@ -2803,7 +2799,7 @@ We now have a module named `hello` inside of our crate root. Modules use
 `snake_case` naming, like functions and variable bindings.
 
 Inside the `hello` module, we've defined a `print_hello` function. This will
-also print out our hello world message. Modules allow you to split up your
+also print out our "hello world" message. Modules allow you to split up your
 program into nice neat boxes of functionality, grouping common things together,
 and keeping different things apart. It's kinda like having a set of shelves:
 a place for everything and everything in its place.
@@ -2963,7 +2959,7 @@ You'll get a warning if you use something marked unstable.
 
 You may have noticed an exclamation point in the `warn` attribute declaration.
 The `!` in this attribute means that this attribute applies to the enclosing
-item, rather than to the item that follows the attribute. So this `warn`
+item, rather than to the item that follows the attribute. This `warn`
 attribute declaration applies to the enclosing crate itself, rather than
 to whatever item statement follows it:
 
@@ -3003,9 +2999,9 @@ Hello, world!
 Great. Rust's infrastructure supports tests in two sorts of places, and they're
 for two kinds of tests: you include **unit test**s inside of the crate itself,
 and you place **integration test**s inside a `tests` directory. "Unit tests"
-are small tests that test one focused unit, "integration tests" tests multiple
-units in integration. That said, this is a social convention, they're no different
-in syntax. Let's make a `tests` directory:
+are small tests that test one focused unit; "integration tests" test multiple
+units in integration. That being said, this is a social convention â€“ they're no
+different in syntax. Let's make a `tests` directory:
 
 ```{bash,ignore}
 $ mkdir tests
@@ -3085,7 +3081,7 @@ test foo ... FAILED
 
 Now we're getting somewhere. Remember when we talked about naming our tests
 with good names? This is why. Here, it says 'test foo' because we called our
-test 'foo.' If we had given it a good name, it'd be more clear which test
+test 'foo'. If we had given it a good name, it'd be more clear which test
 failed, especially as we accumulate more tests.
 
 ```text
@@ -3156,7 +3152,7 @@ our tests, it sets things up so that `cfg(test)` is true. But we want to only
 include `main` when it's _not_ true. So we use `not` to negate things:
 `cfg(not(test))` will only compile our code when the `cfg(test)` is false.
 
-With this attribute we won't get the warning (even
+With this attribute, we won't get the warning (even
 though `src/main.rs` gets recompiled this time):
 
 ```bash
@@ -3200,7 +3196,7 @@ error: aborting due to previous error
 Build failed, waiting for other jobs to finish...
 Could not compile `testing`.
 
-To learn more, run the command again with --verbose.
+To learn more, run the command again with `--verbose`.
 ```
 
 Rust can't find this function. That makes sense, as we didn't write it yet!
@@ -3208,7 +3204,7 @@ Rust can't find this function. That makes sense, as we didn't write it yet!
 In order to share this code with our tests, we'll need to make a library crate.
 This is also just good software design: as we mentioned before, it's a good idea
 to put most of your functionality into a library crate, and have your executable
-crate use that library. This allows for code re-use.
+crate use that library. This allows for code reuse.
 
 To do that, we'll need to make a new module. Make a new file, `src/lib.rs`,
 and put this in it:
@@ -3282,8 +3278,8 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 Great! One test passed. We've got an integration test showing that our public
 method works, but maybe we want to test some of the internal logic as well.
 While this function is simple, if it were more complicated, you can imagine
-we'd need more tests. So let's break it up into two helper functions, and
-write some unit tests to test those.
+we'd need more tests. Let's break it up into two helper functions and write
+some unit tests to test those.
 
 Change your `src/lib.rs` to look like this:
 
@@ -3532,7 +3528,7 @@ error: cannot borrow immutable local variable `x` as mutable
 ```
 
 We don't want a mutable reference to immutable data! This error message uses a
-term we haven't talked about yet, 'borrow.' We'll get to that in just a moment.
+term we haven't talked about yet, 'borrow'. We'll get to that in just a moment.
 
 This simple example actually illustrates a lot of Rust's power: Rust has
 prevented us, at compile time, from breaking our own rules. Because Rust's
@@ -3653,9 +3649,10 @@ all of Rust. Let's see this syntax in action:
 fn foo(x: &int) -> &int { x }
 
 {
-    let x = 5i; // x is the owner of this integer, which is memory on the stack.
+    // x is the owner of the integer, which is memory on the stack.
+    let x = 5i;
 
-    // privilege 2: you may lend that resource, to as many borrowers as you'd like
+    // privilege 2: you may lend that resource to as many borrowers as you like
     let y = &x;
     let z = &x;
 
@@ -3665,10 +3662,11 @@ fn foo(x: &int) -> &int { x }
 }
 
 {
-    let mut x = 5i; // x is the owner of this integer, which is memory on the stack.
+    // x is the owner of this integer, which is memory on the stack.
+    let mut x = 5i;
 
-    let y = &mut x; // privilege 3: you may lend that resource to a single borrower,
-                    // mutably
+    // privilege 3: you may lend that resource to a single borrower, mutably
+    let y = &mut x;
 }
 ```
 
@@ -3684,7 +3682,7 @@ This last requirement can seem odd, but it also makes sense. If you have to
 return something, and you've lent it to someone, they need to give it back to
 you for you to give it back! If we didn't, then the owner could deallocate
 the memory, and the person we've loaned it out to would have a pointer to
-invalid memory. This is called a 'dangling pointer.'
+invalid memory. This is called a 'dangling pointer'.
 
 Let's re-examine the error that led us to talk about all of this, which was a
 violation of the restrictions placed on owners who lend something out mutably.
@@ -3807,8 +3805,8 @@ an integer `5` and makes `x` a pointer to it:
 ```
 
 The great thing about boxes is that we don't have to manually free this
-allocation! Instead, when `x` reaches the end of its lifetime -- in this case,
-when it goes out of scope at the end of the block -- Rust `free`s `x`. This
+allocation! Instead, when `x` reaches the end of its lifetime â€“ in this case,
+when it goes out of scope at the end of the block â€“ Rust `free`s `x`. This
 isn't because Rust has a garbage collector (it doesn't). Instead, by tracking
 the ownership and lifetime of a variable (with a little help from you, the
 programmer), the compiler knows precisely when it is no longer used.
@@ -3873,12 +3871,12 @@ Sometimes you need a variable that is referenced from multiple places
 (immutably!), lasting as long as any of those places, and disappearing when it
 is no longer referenced. For instance, in a graph-like data structure, a node
 might be referenced from all of its neighbors. In this case, it is not possible
-for the compiler to determine ahead of time when the value can be freed -- it
+for the compiler to determine ahead of time when the value can be freed â€“ it
 needs a little run-time support.
 
 Rust's **Rc** type provides shared ownership of a dynamically allocated value
 that is automatically freed at the end of its last owner's lifetime. (`Rc`
-stands for 'reference counted,' referring to the way these library types are
+stands for 'reference counted', referring to the way these library types are
 implemented.) This provides more flexibility than single-owner boxes, but has
 some runtime overhead.
 
@@ -4300,7 +4298,7 @@ This line is more interesting. Here, we call our function, `twice`, and we pass
 it two arguments: an integer, `5`, and our closure, `square`. This is just like
 passing any other two variable bindings to a function, but if you've never
 worked with closures before, it can seem a little complex. Just think: "I'm
-passing two variables, one is an int, and one is a function."
+passing two variables: one is an int, and one is a function."
 
 Next, let's look at how `twice` is defined:
 
@@ -4336,7 +4334,7 @@ fn twice(x: int, f: |int| -> int) -> int {
 ```
 
 Since our closure is named `f`, we can call it just like we called our closures
-before. And we pass in our `x` argument to each one. Hence 'twice.'
+before, and we pass in our `x` argument to each one, hence the name `twice`.
 
 If you do the math, `(5 * 5) + (5 * 5) == 50`, so that's the output we get.
 
@@ -4807,7 +4805,7 @@ enum Result<H, N> {
 ```
 
 if we wanted to. Convention says that the first generic parameter should be
-`T`, for 'type,' and that we use `E` for 'error.' Rust doesn't care, however.
+`T`, for 'type,' and that we use `E` for 'error'. Rust doesn't care, however.
 
 The `Result<T, E>` type is intended to
 be used to return the result of a computation, and to have the ability to
@@ -5212,7 +5210,7 @@ fn main() {
 
 The names don't actually change to this, it's just for illustration. But
 as you can see, there's no overhead of deciding which version to call here,
-hence 'statically dispatched.' The downside is that we have two copies of
+hence 'statically dispatched'. The downside is that we have two copies of
 the same function, so our binary is a little bit larger.
 
 # Tasks
@@ -5412,7 +5410,7 @@ fn main() {
 }
 ```
 
-You can have the macros expanded like this: `rustc print.rs --pretty=expanded` â€“ which will
+You can have the macros expanded like this: `rustc print.rs --pretty=expanded`, which will
 give us this huge result:
 
 ```{rust,ignore}
@@ -5498,7 +5496,6 @@ We covered a lot of ground here. When you've mastered everything in this Guide,
 you will have a firm grasp of basic Rust development. There's a whole lot more
 out there, we've just covered the surface. There's tons of topics that you can
 dig deeper into, and we've built specialized guides for many of them. To learn
-more, dig into the [full documentation
-index](index.html).
+more, dig into the [full documentation index](index.html).
 
 Happy hacking!
diff --git a/src/doc/po4a.conf b/src/doc/po4a.conf
deleted file mode 100644 (file)
index 80f8b74..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-# Add here a list of target languages; po4a will automatically
-# generates .po for them and build .md when translated, eg:
-# [po4a_langs] es fr it pt_BR
-[po4a_langs] ja
-[po4a_paths] doc/po/$master.pot $lang:src/doc/po/$lang/$master.po
-
-# Add here below all source documents to be translated
-[type: text] src/doc/complement-bugreport.md $lang:doc/l10n/$lang/complement-bugreport.md
-[type: text] src/doc/complement-design-faq.md $lang:doc/l10n/$lang/complement-design-faq.md
-[type: text] src/doc/complement-lang-faq.md $lang:doc/l10n/$lang/complement-lang-faq.md
-[type: text] src/doc/complement-project-faq.md $lang:doc/l10n/$lang/complement-project-faq.md
-[type: text] src/doc/guide-container.md $lang:doc/l10n/$lang/guide-container.md
-[type: text] src/doc/guide-ffi.md $lang:doc/l10n/$lang/guide-ffi.md
-[type: text] src/doc/guide-ownership.md $lang:doc/l10n/$lang/guide-ownership.md
-[type: text] src/doc/guide-macros.md $lang:doc/l10n/$lang/guide-macros.md
-[type: text] src/doc/guide-plugin.md $lang:doc/l10n/$lang/guide-plugin.md
-[type: text] src/doc/guide-pointers.md $lang:doc/l10n/$lang/guide-pointers.md
-[type: text] src/doc/guide-strings.md $lang:doc/l10n/$lang/guide-strings.md
-[type: text] src/doc/guide-tasks.md $lang:doc/l10n/$lang/guide-tasks.md
-[type: text] src/doc/guide-testing.md $lang:doc/l10n/$lang/guide-testing.md
-[type: text] src/doc/guide-unsafe.md $lang:doc/l10n/$lang/guide-unsafe.md
-[type: text] src/doc/guide-crates.md $lang:doc/l10n/$lang/guide-crates.md
-[type: text] src/doc/guide-error-handling.md $lang:doc/l10n/$lang/guide-error-handling.md
-[type: text] src/doc/guide.md $lang:doc/l10n/$lang/guide.md
-[type: text] src/doc/index.md $lang:doc/l10n/$lang/index.md
-[type: text] src/doc/intro.md $lang:doc/l10n/$lang/intro.md
-[type: text] src/doc/rust.md $lang:doc/l10n/$lang/rust.md
-[type: text] src/doc/rustdoc.md $lang:doc/l10n/$lang/rustdoc.md
index 3d4791e916e6a4a987826a16f971b37f9d20bcb0..722230d37557cf9559a406330ff2c77bbd6d3ad4 100644 (file)
@@ -518,7 +518,7 @@ This last example is different because it is not possible to use the suffix
 syntax with a floating point literal ending in a period. `2.f64` would attempt
 to call a method named `f64` on `2`.
 
-##### Boolean literals
+#### Boolean literals
 
 The two values of the boolean type are written `true` and `false`.
 
@@ -934,7 +934,7 @@ kinds of view items:
 
 ```{.ebnf .gram}
 extern_crate_decl : "extern" "crate" crate_name
-crate_name: ident | ( string_lit as ident )
+crate_name: ident | ( string_lit "as" ident )
 ```
 
 An _`extern crate` declaration_ specifies a dependency on an external crate.
index 9656d17721e47ca704def34156eb85f95d7ba69b..128d75468e6f4239274d463943b91f784b7ca863 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+ * Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
  * file at the top-level directory of this distribution and at
  * http://rust-lang.org/COPYRIGHT.
  * With elements taken from Bootstrap v3.0.2 (MIT licensed).
@@ -209,7 +209,6 @@ pre {
 code {
     padding: 0 2px;
     color: #8D1A38;
-    white-space: pre-wrap;
 }
 pre code {
     padding: 0;
index 19f36df7dbab4f433b2cd3f90c13e63cd991a29e..42902b06aee13637bc432039a93bcac16123de6b 100755 (executable)
@@ -19,7 +19,7 @@ TMPFILE=`mktemp /tmp/rust-lldb-commands.XXXXXX`
 trap "rm -f $TMPFILE; exit" INT TERM EXIT
 
 # Find out where to look for the pretty printer Python module
-RUSTC_SYSROOT=`rustc -Zprint-sysroot`
+RUSTC_SYSROOT=`rustc --print sysroot`
 
 # Write the LLDB script to the tempfile
 echo "command script import \"$RUSTC_SYSROOT/lib/rustlib/etc/lldb_rust_formatters.py\"" >> $TMPFILE
index e909947ab08b0cb9e55d9915803c3fdf26503119..271cab393c4407a33c6d37198bbc7b599b807b6d 100644 (file)
 
 #![stable]
 
-//! Concurrency-enabled mechanisms for sharing mutable and/or immutable state
-//! between tasks.
+//! Threadsafe reference-counted boxes (the `Arc<T>` type).
+//!
+//! The `Arc<T>` type provides shared ownership of an immutable value. Destruction is
+//! deterministic, and will occur as soon as the last owner is gone. It is marked as `Send` because
+//! it uses atomic reference counting.
+//!
+//! If you do not need thread-safety, and just need shared ownership, consider the [`Rc<T>`
+//! type](../rc/struct.Rc.html). It is the same as `Arc<T>`, but does not use atomics, making it
+//! both thread-unsafe as well as significantly faster when updating the reference count.
+//!
+//! The `downgrade` method can be used to create a non-owning `Weak<T>` pointer to the box. A
+//! `Weak<T>` pointer can be upgraded to an `Arc<T>` pointer, but will return `None` if the value
+//! has already been dropped.
+//!
+//! For example, a tree with parent pointers can be represented by putting the nodes behind strong
+//! `Arc<T>` pointers, and then storing the parent pointers as `Weak<T>` pointers.
+//!
+//! # Examples
+//!
+//! Sharing some immutable data between tasks:
+//!
+//! ```
+//! use std::sync::Arc;
+//!
+//! let five = Arc::new(5i);
+//!
+//! for i in range(0u, 10) {
+//!     let five = five.clone();
+//!
+//!     spawn(move || {
+//!         println!("{}", five);
+//!     });
+//! }
+//! ```
+//!
+//! Sharing mutable data safely between tasks with a `Mutex`:
+//!
+//! ```
+//! use std::sync::Arc;
+//! use std::sync::Mutex;
+//!
+//! let five = Arc::new(Mutex::new(5i));
+//!
+//! for _ in range(0u, 10) {
+//!     let five = five.clone();
+//!
+//!     spawn(move || {
+//!         let mut number = five.lock();
+//!
+//!         number += 1;
+//!
+//!         println!("{}", *number); // prints 6
+//!     });
+//! }
+//! ```
 
 use core::atomic;
 use core::borrow::BorrowFrom;
@@ -33,9 +86,8 @@
 ///
 /// # Example
 ///
-/// In this example, a large vector of floats is shared between several tasks.
-/// With simple pipes, without `Arc`, a copy would have to be made for each
-/// task.
+/// In this example, a large vector of floats is shared between several tasks. With simple pipes,
+/// without `Arc`, a copy would have to be made for each task.
 ///
 /// ```rust
 /// use std::sync::Arc;
@@ -66,8 +118,8 @@ pub struct Arc<T> {
 
 /// A weak pointer to an `Arc`.
 ///
-/// Weak pointers will not keep the data inside of the `Arc` alive, and can be
-/// used to break cycles between `Arc` pointers.
+/// Weak pointers will not keep the data inside of the `Arc` alive, and can be used to break cycles
+/// between `Arc` pointers.
 #[unsafe_no_drop_flag]
 #[experimental = "Weak pointers may not belong in this module."]
 pub struct Weak<T> {
@@ -83,7 +135,15 @@ struct ArcInner<T> {
 }
 
 impl<T: Sync + Send> Arc<T> {
-    /// Creates an atomically reference counted wrapper.
+    /// Constructs a new `Arc<T>`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::sync::Arc;
+    ///
+    /// let five = Arc::new(5i);
+    /// ```
     #[inline]
     #[stable]
     pub fn new(data: T) -> Arc<T> {
@@ -97,11 +157,17 @@ pub fn new(data: T) -> Arc<T> {
         Arc { _ptr: unsafe { mem::transmute(x) } }
     }
 
-    /// Downgrades a strong pointer to a weak pointer.
+    /// Downgrades the `Arc<T>` to a `Weak<T>` reference.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::sync::Arc;
+    ///
+    /// let five = Arc::new(5i);
     ///
-    /// Weak pointers will not keep the data alive. Once all strong references
-    /// to the underlying data have been dropped, the data itself will be
-    /// destroyed.
+    /// let weak_five = five.downgrade();
+    /// ```
     #[experimental = "Weak pointers may not belong in this module."]
     pub fn downgrade(&self) -> Weak<T> {
         // See the clone() impl for why this is relaxed
@@ -113,11 +179,10 @@ pub fn downgrade(&self) -> Weak<T> {
 impl<T> Arc<T> {
     #[inline]
     fn inner(&self) -> &ArcInner<T> {
-        // This unsafety is ok because while this arc is alive we're guaranteed
-        // that the inner pointer is valid. Furthermore, we know that the
-        // `ArcInner` structure itself is `Sync` because the inner data is
-        // `Sync` as well, so we're ok loaning out an immutable pointer to
-        // these contents.
+        // This unsafety is ok because while this arc is alive we're guaranteed that the inner
+        // pointer is valid. Furthermore, we know that the `ArcInner` structure itself is `Sync`
+        // because the inner data is `Sync` as well, so we're ok loaning out an immutable pointer
+        // to these contents.
         unsafe { &*self._ptr }
     }
 }
@@ -132,24 +197,30 @@ pub fn weak_count<T>(this: &Arc<T>) -> uint { this.inner().weak.load(atomic::Seq
 #[experimental]
 pub fn strong_count<T>(this: &Arc<T>) -> uint { this.inner().strong.load(atomic::SeqCst) }
 
-#[unstable = "waiting on stability of Clone"]
+#[stable]
 impl<T> Clone for Arc<T> {
-    /// Duplicate an atomically reference counted wrapper.
+    /// Makes a clone of the `Arc<T>`.
+    ///
+    /// This increases the strong reference count.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::sync::Arc;
+    ///
+    /// let five = Arc::new(5i);
     ///
-    /// The resulting two `Arc` objects will point to the same underlying data
-    /// object. However, one of the `Arc` objects can be sent to another task,
-    /// allowing them to share the underlying data.
+    /// five.clone();
+    /// ```
     #[inline]
     fn clone(&self) -> Arc<T> {
-        // Using a relaxed ordering is alright here, as knowledge of the
-        // original reference prevents other threads from erroneously deleting
-        // the object.
+        // Using a relaxed ordering is alright here, as knowledge of the original reference
+        // prevents other threads from erroneously deleting the object.
         //
-        // As explained in the [Boost documentation][1], Increasing the
-        // reference counter can always be done with memory_order_relaxed: New
-        // references to an object can only be formed from an existing
-        // reference, and passing an existing reference from one thread to
-        // another must already provide any required synchronization.
+        // As explained in the [Boost documentation][1], Increasing the reference counter can
+        // always be done with memory_order_relaxed: New references to an object can only be formed
+        // from an existing reference, and passing an existing reference from one thread to another
+        // must already provide any required synchronization.
         //
         // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
         self.inner().strong.fetch_add(1, atomic::Relaxed);
@@ -172,26 +243,33 @@ fn deref(&self) -> &T {
 }
 
 impl<T: Send + Sync + Clone> Arc<T> {
-    /// Acquires a mutable pointer to the inner contents by guaranteeing that
-    /// the reference count is one (no sharing is possible).
+    /// Make a mutable reference from the given `Arc<T>`.
     ///
-    /// This is also referred to as a copy-on-write operation because the inner
-    /// data is cloned if the reference count is greater than one.
+    /// This is also referred to as a copy-on-write operation because the inner data is cloned if
+    /// the reference count is greater than one.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::sync::Arc;
+    ///
+    /// let mut five = Arc::new(5i);
+    ///
+    /// let mut_five = five.make_unique();
+    /// ```
     #[inline]
     #[experimental]
     pub fn make_unique(&mut self) -> &mut T {
-        // Note that we hold a strong reference, which also counts as
-        // a weak reference, so we only clone if there is an
-        // additional reference of either kind.
+        // Note that we hold a strong reference, which also counts as a weak reference, so we only
+        // clone if there is an additional reference of either kind.
         if self.inner().strong.load(atomic::SeqCst) != 1 ||
            self.inner().weak.load(atomic::SeqCst) != 1 {
             *self = Arc::new((**self).clone())
         }
-        // This unsafety is ok because we're guaranteed that the pointer
-        // returned is the *only* pointer that will ever be returned to T. Our
-        // reference count is guaranteed to be 1 at this point, and we required
-        // the Arc itself to be `mut`, so we're returning the only possible
-        // reference to the inner data.
+        // This unsafety is ok because we're guaranteed that the pointer returned is the *only*
+        // pointer that will ever be returned to T. Our reference count is guaranteed to be 1 at
+        // this point, and we required the Arc itself to be `mut`, so we're returning the only
+        // possible reference to the inner data.
         let inner = unsafe { &mut *self._ptr };
         &mut inner.data
     }
@@ -200,38 +278,59 @@ pub fn make_unique(&mut self) -> &mut T {
 #[unsafe_destructor]
 #[experimental = "waiting on stability of Drop"]
 impl<T: Sync + Send> Drop for Arc<T> {
+    /// Drops the `Arc<T>`.
+    ///
+    /// This will decrement the strong reference count. If the strong reference count becomes zero
+    /// and the only other references are `Weak<T>` ones, `drop`s the inner value.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::sync::Arc;
+    ///
+    /// {
+    ///     let five = Arc::new(5i);
+    ///
+    ///     // stuff
+    ///
+    ///     drop(five); // explict drop
+    /// }
+    /// {
+    ///     let five = Arc::new(5i);
+    ///
+    ///     // stuff
+    ///
+    /// } // implicit drop
+    /// ```
     fn drop(&mut self) {
-        // This structure has #[unsafe_no_drop_flag], so this drop glue may run
-        // more than once (but it is guaranteed to be zeroed after the first if
-        // it's run more than once)
+        // This structure has #[unsafe_no_drop_flag], so this drop glue may run more than once (but
+        // it is guaranteed to be zeroed after the first if it's run more than once)
         if self._ptr.is_null() { return }
 
-        // Because `fetch_sub` is already atomic, we do not need to synchronize
-        // with other threads unless we are going to delete the object. This
-        // same logic applies to the below `fetch_sub` to the `weak` count.
+        // Because `fetch_sub` is already atomic, we do not need to synchronize with other threads
+        // unless we are going to delete the object. This same logic applies to the below
+        // `fetch_sub` to the `weak` count.
         if self.inner().strong.fetch_sub(1, atomic::Release) != 1 { return }
 
-        // This fence is needed to prevent reordering of use of the data and
-        // deletion of the data. Because it is marked `Release`, the
-        // decreasing of the reference count synchronizes with this `Acquire`
-        // fence. This means that use of the data happens before decreasing
-        // the reference count, which happens before this fence, which
-        // happens before the deletion of the data.
+        // This fence is needed to prevent reordering of use of the data and deletion of the data.
+        // Because it is marked `Release`, the decreasing of the reference count synchronizes with
+        // this `Acquire` fence. This means that use of the data happens before decreasing the
+        // reference count, which happens before this fence, which happens before the deletion of
+        // the data.
         //
         // As explained in the [Boost documentation][1],
         //
-        // It is important to enforce any possible access to the object in
-        // one thread (through an existing reference) to *happen before*
-        // deleting the object in a different thread. This is achieved by a
-        // "release" operation after dropping a reference (any access to the
-        // object through this reference must obviously happened before),
-        // and an "acquire" operation before deleting the object.
+        // > It is important to enforce any possible access to the object in one thread (through an
+        // > existing reference) to *happen before* deleting the object in a different thread. This
+        // > is achieved by a "release" operation after dropping a reference (any access to the
+        // > object through this reference must obviously happened before), and an "acquire"
+        // > operation before deleting the object.
         //
         // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
         atomic::fence(atomic::Acquire);
 
-        // Destroy the data at this time, even though we may not free the box
-        // allocation itself (there may still be weak pointers lying around).
+        // Destroy the data at this time, even though we may not free the box allocation itself
+        // (there may still be weak pointers lying around).
         unsafe { drop(ptr::read(&self.inner().data)); }
 
         if self.inner().weak.fetch_sub(1, atomic::Release) == 1 {
@@ -244,14 +343,26 @@ fn drop(&mut self) {
 
 #[experimental = "Weak pointers may not belong in this module."]
 impl<T: Sync + Send> Weak<T> {
-    /// Attempts to upgrade this weak reference to a strong reference.
+    /// Upgrades a weak reference to a strong reference.
+    ///
+    /// Upgrades the `Weak<T>` reference to an `Arc<T>`, if possible.
+    ///
+    /// Returns `None` if there were no strong references and the data was destroyed.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::sync::Arc;
     ///
-    /// This method will not upgrade this reference if the strong reference count has already
-    /// reached 0, but if there are still other active strong references this function will return
-    /// a new strong reference to the data.
+    /// let five = Arc::new(5i);
+    ///
+    /// let weak_five = five.downgrade();
+    ///
+    /// let strong_five: Option<Arc<_>> = weak_five.upgrade();
+    /// ```
     pub fn upgrade(&self) -> Option<Arc<T>> {
-        // We use a CAS loop to increment the strong count instead of a
-        // fetch_add because once the count hits 0 is must never be above 0.
+        // We use a CAS loop to increment the strong count instead of a fetch_add because once the
+        // count hits 0 is must never be above 0.
         let inner = self.inner();
         loop {
             let n = inner.strong.load(atomic::SeqCst);
@@ -270,6 +381,19 @@ fn inner(&self) -> &ArcInner<T> {
 
 #[experimental = "Weak pointers may not belong in this module."]
 impl<T: Sync + Send> Clone for Weak<T> {
+    /// Makes a clone of the `Weak<T>`.
+    ///
+    /// This increases the weak reference count.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::sync::Arc;
+    ///
+    /// let weak_five = Arc::new(5i).downgrade();
+    ///
+    /// weak_five.clone();
+    /// ```
     #[inline]
     fn clone(&self) -> Weak<T> {
         // See comments in Arc::clone() for why this is relaxed
@@ -281,13 +405,37 @@ fn clone(&self) -> Weak<T> {
 #[unsafe_destructor]
 #[experimental = "Weak pointers may not belong in this module."]
 impl<T: Sync + Send> Drop for Weak<T> {
+    /// Drops the `Weak<T>`.
+    ///
+    /// This will decrement the weak reference count.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::sync::Arc;
+    ///
+    /// {
+    ///     let five = Arc::new(5i);
+    ///     let weak_five = five.downgrade();
+    ///
+    ///     // stuff
+    ///
+    ///     drop(weak_five); // explict drop
+    /// }
+    /// {
+    ///     let five = Arc::new(5i);
+    ///     let weak_five = five.downgrade();
+    ///
+    ///     // stuff
+    ///
+    /// } // implicit drop
+    /// ```
     fn drop(&mut self) {
         // see comments above for why this check is here
         if self._ptr.is_null() { return }
 
-        // If we find out that we were the last weak pointer, then its time to
-        // deallocate the data entirely. See the discussion in Arc::drop() about
-        // the memory orderings
+        // If we find out that we were the last weak pointer, then its time to deallocate the data
+        // entirely. See the discussion in Arc::drop() about the memory orderings
         if self.inner().weak.fetch_sub(1, atomic::Release) == 1 {
             atomic::fence(atomic::Acquire);
             unsafe { deallocate(self._ptr as *mut u8, size_of::<ArcInner<T>>(),
@@ -298,18 +446,114 @@ fn drop(&mut self) {
 
 #[unstable = "waiting on PartialEq"]
 impl<T: PartialEq> PartialEq for Arc<T> {
+    /// Equality for two `Arc<T>`s.
+    ///
+    /// Two `Arc<T>`s are equal if their inner value are equal.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::sync::Arc;
+    ///
+    /// let five = Arc::new(5i);
+    ///
+    /// five == Arc::new(5i);
+    /// ```
     fn eq(&self, other: &Arc<T>) -> bool { *(*self) == *(*other) }
+
+    /// Inequality for two `Arc<T>`s.
+    ///
+    /// Two `Arc<T>`s are unequal if their inner value are unequal.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::sync::Arc;
+    ///
+    /// let five = Arc::new(5i);
+    ///
+    /// five != Arc::new(5i);
+    /// ```
     fn ne(&self, other: &Arc<T>) -> bool { *(*self) != *(*other) }
 }
 #[unstable = "waiting on PartialOrd"]
 impl<T: PartialOrd> PartialOrd for Arc<T> {
+    /// Partial comparison for two `Arc<T>`s.
+    ///
+    /// The two are compared by calling `partial_cmp()` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::sync::Arc;
+    ///
+    /// let five = Arc::new(5i);
+    ///
+    /// five.partial_cmp(&Arc::new(5i));
+    /// ```
     fn partial_cmp(&self, other: &Arc<T>) -> Option<Ordering> {
         (**self).partial_cmp(&**other)
     }
+
+    /// Less-than comparison for two `Arc<T>`s.
+    ///
+    /// The two are compared by calling `<` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::sync::Arc;
+    ///
+    /// let five = Arc::new(5i);
+    ///
+    /// five < Arc::new(5i);
+    /// ```
     fn lt(&self, other: &Arc<T>) -> bool { *(*self) < *(*other) }
+
+    /// 'Less-than or equal to' comparison for two `Arc<T>`s.
+    ///
+    /// The two are compared by calling `<=` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::sync::Arc;
+    ///
+    /// let five = Arc::new(5i);
+    ///
+    /// five <= Arc::new(5i);
+    /// ```
     fn le(&self, other: &Arc<T>) -> bool { *(*self) <= *(*other) }
-    fn ge(&self, other: &Arc<T>) -> bool { *(*self) >= *(*other) }
+
+    /// Greater-than comparison for two `Arc<T>`s.
+    ///
+    /// The two are compared by calling `>` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::sync::Arc;
+    ///
+    /// let five = Arc::new(5i);
+    ///
+    /// five > Arc::new(5i);
+    /// ```
     fn gt(&self, other: &Arc<T>) -> bool { *(*self) > *(*other) }
+
+    /// 'Greater-than or equal to' comparison for two `Arc<T>`s.
+    ///
+    /// The two are compared by calling `>=` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::sync::Arc;
+    ///
+    /// let five = Arc::new(5i);
+    ///
+    /// five >= Arc::new(5i);
+    /// ```
+    fn ge(&self, other: &Arc<T>) -> bool { *(*self) >= *(*other) }
 }
 #[unstable = "waiting on Ord"]
 impl<T: Ord> Ord for Arc<T> {
index 879a8cc6951a133063fcb91afe0ae22526144fc7..5fd234192c515f9f879e580748d9c9f149140244 100644 (file)
@@ -22,6 +22,7 @@
 use core::raw::TraitObject;
 use core::result::Result;
 use core::result::Result::{Ok, Err};
+use core::ops::{Deref, DerefMut};
 
 /// A value that represents the global exchange heap. This is the default
 /// place that the `box` keyword allocates into when no place is supplied.
@@ -57,7 +58,7 @@ impl<T> Default for Box<[T]> {
     fn default() -> Box<[T]> { box [] }
 }
 
-#[unstable]
+#[stable]
 impl<T: Clone> Clone for Box<T> {
     /// Returns a copy of the owned box.
     #[inline]
@@ -147,6 +148,14 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+impl<Sized? T> Deref<T> for Box<T> {
+    fn deref(&self) -> &T { &**self }
+}
+
+impl<Sized? T> DerefMut<T> for Box<T> {
+    fn deref_mut(&mut self) -> &mut T { &mut **self }
+}
+
 #[cfg(test)]
 mod test {
     #[test]
@@ -193,4 +202,10 @@ fn test_show() {
         let s = format!("{}", b);
         assert_eq!(s, "&Any");
     }
+
+    #[test]
+    fn deref() {
+        fn homura<T: Deref<i32>>(_: T) { }
+        homura(box 765i32);
+    }
 }
index 0257c640d3ccd58599927f2336a925c4cd815dab..dfa55848c90dadf65bd4bb8ed596b55e3c550115 100644 (file)
@@ -168,12 +168,12 @@ struct RcBox<T> {
 
 /// An immutable reference-counted pointer type.
 ///
-/// See the [module level documentation](../index.html) for more.
+/// See the [module level documentation](../index.html) for more details.
 #[unsafe_no_drop_flag]
 #[stable]
 pub struct Rc<T> {
-    // FIXME #12808: strange names to try to avoid interfering with
-    // field accesses of the contained type via Deref
+    // FIXME #12808: strange names to try to avoid interfering with field accesses of the contained
+    // type via Deref
     _ptr: *mut RcBox<T>,
     _nosend: marker::NoSend,
     _noshare: marker::NoSync
@@ -193,11 +193,9 @@ impl<T> Rc<T> {
     pub fn new(value: T) -> Rc<T> {
         unsafe {
             Rc {
-                // there is an implicit weak pointer owned by all the
-                // strong pointers, which ensures that the weak
-                // destructor never frees the allocation while the
-                // strong destructor is running, even if the weak
-                // pointer is stored inside the strong one.
+                // there is an implicit weak pointer owned by all the strong pointers, which
+                // ensures that the weak destructor never frees the allocation while the strong
+                // destructor is running, even if the weak pointer is stored inside the strong one.
                 _ptr: transmute(box RcBox {
                     value: value,
                     strong: Cell::new(1),
@@ -341,11 +339,10 @@ pub fn make_unique(&mut self) -> &mut T {
         if !is_unique(self) {
             *self = Rc::new((**self).clone())
         }
-        // This unsafety is ok because we're guaranteed that the pointer
-        // returned is the *only* pointer that will ever be returned to T. Our
-        // reference count is guaranteed to be 1 at this point, and we required
-        // the `Rc<T>` itself to be `mut`, so we're returning the only possible
-        // reference to the inner value.
+        // This unsafety is ok because we're guaranteed that the pointer returned is the *only*
+        // pointer that will ever be returned to T. Our reference count is guaranteed to be 1 at
+        // this point, and we required the `Rc<T>` itself to be `mut`, so we're returning the only
+        // possible reference to the inner value.
         let inner = unsafe { &mut *self._ptr };
         &mut inner.value
     }
@@ -399,8 +396,8 @@ fn drop(&mut self) {
                 if self.strong() == 0 {
                     ptr::read(&**self); // destroy the contained object
 
-                    // remove the implicit "strong weak" pointer now
-                    // that we've destroyed the contents.
+                    // remove the implicit "strong weak" pointer now that we've destroyed the
+                    // contents.
                     self.dec_weak();
 
                     if self.weak() == 0 {
@@ -413,7 +410,7 @@ fn drop(&mut self) {
     }
 }
 
-#[unstable = "Clone is unstable."]
+#[stable]
 impl<T> Clone for Rc<T> {
     /// Makes a clone of the `Rc<T>`.
     ///
@@ -687,8 +684,8 @@ fn drop(&mut self) {
         unsafe {
             if !self._ptr.is_null() {
                 self.dec_weak();
-                // the weak count starts at 1, and will only go to
-                // zero if all the strong pointers have disappeared.
+                // the weak count starts at 1, and will only go to zero if all the strong pointers
+                // have disappeared.
                 if self.weak() == 0 {
                     deallocate(self._ptr as *mut u8, size_of::<RcBox<T>>(),
                                min_align_of::<RcBox<T>>())
index 3346e55158a2a178b3db99b6387de9563333a84d..fbaebd0125d0d3e9e1def4d2573c33ab0958a486 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::prelude::*;
+use prelude::*;
 use std::rand;
 use std::rand::Rng;
 use test::Bencher;
index be99c4c0bc724dba40268f44ef60f143988d0e2a..0840e8ec881cd0bde575913f6167d63e5b84cc46 100644 (file)
@@ -239,7 +239,7 @@ pub fn from_vec(xs: Vec<T>) -> BinaryHeap<T> {
     /// }
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
-    pub fn iter<'a>(&'a self) -> Items<'a, T> {
+    pub fn iter(&self) -> Items<T> {
         Items { iter: self.data.iter() }
     }
 
@@ -280,8 +280,8 @@ pub fn into_iter(self) -> MoveItems<T> {
     /// assert_eq!(heap.top(), Some(&5i));
     ///
     /// ```
-    pub fn top<'a>(&'a self) -> Option<&'a T> {
-        if self.is_empty() { None } else { Some(&self.data[0]) }
+    pub fn top(&self) -> Option<&T> {
+        self.data.get(0)
     }
 
     /// Returns the number of elements the queue can hold without reallocating.
@@ -392,9 +392,9 @@ pub fn pop(&mut self) -> Option<T> {
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn push(&mut self, item: T) {
+        let old_len = self.len();
         self.data.push(item);
-        let new_len = self.len() - 1;
-        self.siftup(0, new_len);
+        self.siftup(0, old_len);
     }
 
     /// Pushes an item onto a queue then pops the greatest item off the queue in
@@ -415,10 +415,16 @@ pub fn push(&mut self, item: T) {
     /// assert_eq!(heap.top(), Some(&3i));
     /// ```
     pub fn push_pop(&mut self, mut item: T) -> T {
-        if !self.is_empty() && *self.top().unwrap() > item {
-            swap(&mut item, &mut self.data[0]);
-            self.siftdown(0);
+        match self.data.get_mut(0) {
+            None => return item,
+            Some(top) => if *top > item {
+                swap(&mut item, top);
+            } else {
+                return item;
+            },
         }
+
+        self.siftdown(0);
         item
     }
 
@@ -465,7 +471,7 @@ pub fn replace(&mut self, mut item: T) -> Option<T> {
     ///     println!("{}", x);
     /// }
     /// ```
-    pub fn into_vec(self) -> Vec<T> { let BinaryHeap{data: v} = self; v }
+    pub fn into_vec(self) -> Vec<T> { self.data }
 
     /// Consumes the `BinaryHeap` and returns a vector in sorted
     /// (ascending) order.
@@ -482,15 +488,14 @@ pub fn replace(&mut self, mut item: T) -> Option<T> {
     /// let vec = heap.into_sorted_vec();
     /// assert_eq!(vec, vec![1i, 2, 3, 4, 5, 6, 7]);
     /// ```
-    pub fn into_sorted_vec(self) -> Vec<T> {
-        let mut q = self;
-        let mut end = q.len();
+    pub fn into_sorted_vec(mut self) -> Vec<T> {
+        let mut end = self.len();
         while end > 1 {
             end -= 1;
-            q.data.swap(0, end);
-            q.siftdown_range(0, end)
+            self.data.swap(0, end);
+            self.siftdown_range(0, end)
         }
-        q.into_vec()
+        self.into_vec()
     }
 
     // The implementations of siftup and siftdown use unsafe blocks in
@@ -551,19 +556,28 @@ pub fn len(&self) -> uint { self.data.len() }
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn is_empty(&self) -> bool { self.len() == 0 }
 
+    /// Clears the queue, returning an iterator over the removed elements.
+    #[inline]
+    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    pub fn drain<'a>(&'a mut self) -> Drain<'a, T> {
+        Drain {
+            iter: self.data.drain(),
+        }
+    }
+
     /// Drops all items from the queue.
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
-    pub fn clear(&mut self) { self.data.truncate(0) }
+    pub fn clear(&mut self) { self.drain(); }
 }
 
 /// `BinaryHeap` iterator.
-pub struct Items <'a, T:'a> {
+pub struct Items<'a, T: 'a> {
     iter: slice::Items<'a, T>,
 }
 
 impl<'a, T> Iterator<&'a T> for Items<'a, T> {
     #[inline]
-    fn next(&mut self) -> Option<(&'a T)> { self.iter.next() }
+    fn next(&mut self) -> Option<&'a T> { self.iter.next() }
 
     #[inline]
     fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
@@ -571,7 +585,7 @@ fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
 
 impl<'a, T> DoubleEndedIterator<&'a T> for Items<'a, T> {
     #[inline]
-    fn next_back(&mut self) -> Option<(&'a T)> { self.iter.next_back() }
+    fn next_back(&mut self) -> Option<&'a T> { self.iter.next_back() }
 }
 
 impl<'a, T> ExactSizeIterator<&'a T> for Items<'a, T> {}
@@ -596,10 +610,29 @@ fn next_back(&mut self) -> Option<T> { self.iter.next_back() }
 
 impl<T> ExactSizeIterator<T> for MoveItems<T> {}
 
+/// An iterator that drains a `BinaryHeap`.
+pub struct Drain<'a, T: 'a> {
+    iter: vec::Drain<'a, T>,
+}
+
+impl<'a, T: 'a> Iterator<T> for Drain<'a, T> {
+    #[inline]
+    fn next(&mut self) -> Option<T> { self.iter.next() }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
+}
+
+impl<'a, T: 'a> DoubleEndedIterator<T> for Drain<'a, T> {
+    #[inline]
+    fn next_back(&mut self) -> Option<T> { self.iter.next_back() }
+}
+
+impl<'a, T: 'a> ExactSizeIterator<T> for Drain<'a, T> {}
+
 impl<T: Ord> FromIterator<T> for BinaryHeap<T> {
     fn from_iter<Iter: Iterator<T>>(iter: Iter) -> BinaryHeap<T> {
-        let vec: Vec<T> = iter.collect();
-        BinaryHeap::from_vec(vec)
+        BinaryHeap::from_vec(iter.collect())
     }
 }
 
@@ -617,10 +650,9 @@ fn extend<Iter: Iterator<T>>(&mut self, mut iter: Iter) {
 
 #[cfg(test)]
 mod tests {
-    use std::prelude::*;
+    use prelude::*;
 
     use super::BinaryHeap;
-    use vec::Vec;
 
     #[test]
     fn test_iterator() {
@@ -794,20 +826,20 @@ fn test_to_vec() {
 
     #[test]
     fn test_empty_pop() {
-        let mut heap: BinaryHeap<int> = BinaryHeap::new();
+        let mut heap = BinaryHeap::<int>::new();
         assert!(heap.pop().is_none());
     }
 
     #[test]
     fn test_empty_top() {
-        let empty: BinaryHeap<int> = BinaryHeap::new();
+        let empty = BinaryHeap::<int>::new();
         assert!(empty.top().is_none());
     }
 
     #[test]
     fn test_empty_replace() {
-        let mut heap: BinaryHeap<int> = BinaryHeap::new();
-        heap.replace(5).is_none();
+        let mut heap = BinaryHeap::<int>::new();
+        assert!(heap.replace(5).is_none());
     }
 
     #[test]
@@ -820,4 +852,14 @@ fn test_from_iter() {
             assert_eq!(q.pop().unwrap(), x);
         }
     }
+
+    #[test]
+    fn test_drain() {
+        let mut q: BinaryHeap<_> =
+            [9u, 8, 7, 6, 5, 4, 3, 2, 1].iter().cloned().collect();
+
+        assert_eq!(q.drain().take(5).count(), 5);
+
+        assert!(q.is_empty());
+    }
 }
index 7f78d56607e7ae9503983fe9e515e37f458d0859..17dbf8a2cae9ecf6e6e096a6e7595b10903b2610 100644 (file)
@@ -851,6 +851,7 @@ fn extend<I: Iterator<bool>>(&mut self, mut iterator: I) {
     }
 }
 
+#[stable]
 impl Clone for Bitv {
     #[inline]
     fn clone(&self) -> Bitv {
@@ -1686,16 +1687,15 @@ fn size_hint(&self) -> (uint, Option<uint>) {
 
 #[cfg(test)]
 mod tests {
-    use std::prelude::*;
-    use std::iter::range_step;
+    use prelude::*;
+    use core::iter::range_step;
+    use core::u32;
     use std::rand;
     use std::rand::Rng;
-    use std::u32;
     use test::{Bencher, black_box};
 
     use super::{Bitv, BitvSet, from_fn, from_bytes};
     use bitv;
-    use vec::Vec;
 
     static BENCH_BITS : uint = 1 << 14;
 
@@ -2038,7 +2038,7 @@ fn test_equal_sneaky_big() {
     #[test]
     fn test_from_bytes() {
         let bitv = from_bytes(&[0b10110110, 0b00000000, 0b11111111]);
-        let str = format!("{}{}{}", "10110110", "00000000", "11111111");
+        let str = concat!("10110110", "00000000", "11111111");
         assert_eq!(bitv.to_string(), str);
     }
 
index c7cbb5a1c299e25b59c485b08b3cbebf6e3d80f9..01096c1fd4e9617a8481a511291be1673104c5d4 100644 (file)
@@ -131,12 +131,12 @@ pub enum Entry<'a, K:'a, V:'a> {
 /// A vacant Entry.
 pub struct VacantEntry<'a, K:'a, V:'a> {
     key: K,
-    stack: stack::SearchStack<'a, K, V, node::Edge, node::Leaf>,
+    stack: stack::SearchStack<'a, K, V, node::handle::Edge, node::handle::Leaf>,
 }
 
 /// An occupied Entry.
 pub struct OccupiedEntry<'a, K:'a, V:'a> {
-    stack: stack::SearchStack<'a, K, V, node::KV, node::LeafOrInternal>,
+    stack: stack::SearchStack<'a, K, V, node::handle::KV, node::handle::LeafOrInternal>,
 }
 
 impl<K: Ord, V> BTreeMap<K, V> {
@@ -496,7 +496,8 @@ mod stack {
     use core::kinds::marker;
     use core::mem;
     use super::BTreeMap;
-    use super::super::node::{mod, Node, Fit, Split, KV, Edge, Internal, Leaf, LeafOrInternal};
+    use super::super::node::{mod, Node, Fit, Split, Internal, Leaf};
+    use super::super::node::handle;
     use vec::Vec;
 
     /// A generic mutable reference, identical to `&mut` except for the fact that its lifetime
@@ -520,7 +521,7 @@ fn deref_mut(&mut self) -> &mut T {
         }
     }
 
-    type StackItem<K, V> = node::Handle<*mut Node<K, V>, Edge, Internal>;
+    type StackItem<K, V> = node::Handle<*mut Node<K, V>, handle::Edge, handle::Internal>;
     type Stack<K, V> = Vec<StackItem<K, V>>;
 
     /// A `PartialSearchStack` handles the construction of a search stack.
@@ -595,7 +596,9 @@ impl<'id, 'a, K, V> Pusher<'id, 'a, K, V> {
         /// Pushes the requested child of the stack's current top on top of the stack. If the child
         /// exists, then a new PartialSearchStack is yielded. Otherwise, a VacantSearchStack is
         /// yielded.
-        pub fn push(mut self, mut edge: node::Handle<IdRef<'id, Node<K, V>>, Edge, Internal>)
+        pub fn push(mut self, mut edge: node::Handle<IdRef<'id, Node<K, V>>,
+                                                     handle::Edge,
+                                                     handle::Internal>)
                     -> PartialSearchStack<'a, K, V> {
             self.stack.push(edge.as_raw());
             PartialSearchStack {
@@ -617,7 +620,7 @@ pub fn seal<Type, NodeType>
         }
     }
 
-    impl<'a, K, V, NodeType> SearchStack<'a, K, V, KV, NodeType> {
+    impl<'a, K, V, NodeType> SearchStack<'a, K, V, handle::KV, NodeType> {
         /// Gets a reference to the value the stack points to.
         pub fn peek(&self) -> &V {
             unsafe { self.top.from_raw().into_kv().1 }
@@ -640,7 +643,7 @@ pub fn into_top(mut self) -> &'a mut V {
         }
     }
 
-    impl<'a, K, V> SearchStack<'a, K, V, KV, Leaf> {
+    impl<'a, K, V> SearchStack<'a, K, V, handle::KV, handle::Leaf> {
         /// Removes the key and value in the top element of the stack, then handles underflows as
         /// described in BTree's pop function.
         fn remove_leaf(mut self) -> V {
@@ -686,7 +689,7 @@ fn remove_leaf(mut self) -> V {
         }
     }
 
-    impl<'a, K, V> SearchStack<'a, K, V, KV, LeafOrInternal> {
+    impl<'a, K, V> SearchStack<'a, K, V, handle::KV, handle::LeafOrInternal> {
         /// Removes the key and value in the top element of the stack, then handles underflows as
         /// described in BTree's pop function.
         pub fn remove(self) -> V {
@@ -703,7 +706,7 @@ pub fn remove(self) -> V {
         /// leaves the tree in an inconsistent state that must be repaired by the caller by
         /// removing the entry in question. Specifically the key-value pair and its successor will
         /// become swapped.
-        fn into_leaf(mut self) -> SearchStack<'a, K, V, KV, Leaf> {
+        fn into_leaf(mut self) -> SearchStack<'a, K, V, handle::KV, handle::Leaf> {
             unsafe {
                 let mut top_raw = self.top;
                 let mut top = top_raw.from_raw_mut();
@@ -757,7 +760,7 @@ fn into_leaf(mut self) -> SearchStack<'a, K, V, KV, Leaf> {
         }
     }
 
-    impl<'a, K, V> SearchStack<'a, K, V, Edge, Leaf> {
+    impl<'a, K, V> SearchStack<'a, K, V, handle::Edge, handle::Leaf> {
         /// Inserts the key and value into the top element in the stack, and if that node has to
         /// split recursively inserts the split contents into the next element stack until
         /// splits stop.
@@ -1332,7 +1335,7 @@ pub fn entry<'a>(&'a mut self, mut key: K) -> Entry<'a, K, V> {
 
 #[cfg(test)]
 mod test {
-    use std::prelude::*;
+    use prelude::*;
 
     use super::{BTreeMap, Occupied, Vacant};
 
@@ -1534,7 +1537,7 @@ fn test_entry(){
 
 #[cfg(test)]
 mod bench {
-    use std::prelude::*;
+    use prelude::*;
     use std::rand::{weak_rng, Rng};
     use test::{Bencher, black_box};
 
index 9698b06c7fa0f266c7bd52f89e11d0c541959470..86c7def49b197e002ca3be7dca31f9b7311c71a9 100644 (file)
@@ -34,9 +34,9 @@ pub enum InsertionResult<K, V> {
 /// Represents the result of a search for a key in a single node
 pub enum SearchResult<NodeRef> {
     /// The element was found at the given index
-    Found(Handle<NodeRef, KV, LeafOrInternal>),
+    Found(Handle<NodeRef, handle::KV, handle::LeafOrInternal>),
     /// The element wasn't found, but if it's anywhere, it must be beyond this edge
-    GoDown(Handle<NodeRef, Edge, LeafOrInternal>),
+    GoDown(Handle<NodeRef, handle::Edge, handle::LeafOrInternal>),
 }
 
 /// A B-Tree Node. We keep keys/edges/values separate to optimize searching for keys.
@@ -390,6 +390,7 @@ pub fn edges_mut<'a>(&'a mut self) -> &'a mut [Node<K, V>] {
 }
 
 // FIXME(gereeter) Write an efficient clone_from
+#[stable]
 impl<K: Clone, V: Clone> Clone for Node<K, V> {
     fn clone(&self) -> Node<K, V> {
         let mut ret = if self.is_leaf() {
@@ -494,12 +495,16 @@ pub struct Handle<NodeRef, Type, NodeType> {
     index: uint
 }
 
-pub enum KV {}
-pub enum Edge {}
+pub mod handle {
+    // Handle types.
+    pub enum KV {}
+    pub enum Edge {}
 
-pub enum LeafOrInternal {}
-pub enum Leaf {}
-pub enum Internal {}
+    // Handle node types.
+    pub enum LeafOrInternal {}
+    pub enum Leaf {}
+    pub enum Internal {}
+}
 
 impl<K: Ord, V> Node<K, V> {
     /// Searches for the given key in the node. If it finds an exact match,
@@ -625,7 +630,7 @@ pub unsafe fn from_raw_mut<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, Type,
     }
 }
 
-impl<'a, K: 'a, V: 'a> Handle<&'a Node<K, V>, Edge, Internal> {
+impl<'a, K: 'a, V: 'a> Handle<&'a Node<K, V>, handle::Edge, handle::Internal> {
     /// Turns the handle into a reference to the edge it points at. This is necessary because the
     /// returned pointer has a larger lifetime than what would be returned by `edge` or `edge_mut`,
     /// making it more suitable for moving down a chain of nodes.
@@ -636,7 +641,7 @@ pub fn into_edge(self) -> &'a Node<K, V> {
     }
 }
 
-impl<'a, K: 'a, V: 'a> Handle<&'a mut Node<K, V>, Edge, Internal> {
+impl<'a, K: 'a, V: 'a> Handle<&'a mut Node<K, V>, handle::Edge, handle::Internal> {
     /// Turns the handle into a mutable reference to the edge it points at. This is necessary
     /// because the returned pointer has a larger lifetime than what would be returned by
     /// `edge_mut`, making it more suitable for moving down a chain of nodes.
@@ -647,7 +652,7 @@ pub fn into_edge_mut(self) -> &'a mut Node<K, V> {
     }
 }
 
-impl<K, V, NodeRef: Deref<Node<K, V>>> Handle<NodeRef, Edge, Internal> {
+impl<K, V, NodeRef: Deref<Node<K, V>>> Handle<NodeRef, handle::Edge, handle::Internal> {
     // This doesn't exist because there are no uses for it,
     // but is fine to add, analagous to edge_mut.
     //
@@ -657,11 +662,11 @@ impl<K, V, NodeRef: Deref<Node<K, V>>> Handle<NodeRef, Edge, Internal> {
 }
 
 pub enum ForceResult<NodeRef, Type> {
-    Leaf(Handle<NodeRef, Type, Leaf>),
-    Internal(Handle<NodeRef, Type, Internal>)
+    Leaf(Handle<NodeRef, Type, handle::Leaf>),
+    Internal(Handle<NodeRef, Type, handle::Internal>)
 }
 
-impl<K, V, NodeRef: Deref<Node<K, V>>, Type> Handle<NodeRef, Type, LeafOrInternal> {
+impl<K, V, NodeRef: Deref<Node<K, V>>, Type> Handle<NodeRef, Type, handle::LeafOrInternal> {
     /// Figure out whether this handle is pointing to something in a leaf node or to something in
     /// an internal node, clarifying the type according to the result.
     pub fn force(self) -> ForceResult<NodeRef, Type> {
@@ -679,7 +684,7 @@ pub fn force(self) -> ForceResult<NodeRef, Type> {
     }
 }
 
-impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, Edge, Leaf> {
+impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, handle::Edge, handle::Leaf> {
     /// Tries to insert this key-value pair at the given index in this leaf node
     /// If the node is full, we have to split it.
     ///
@@ -711,7 +716,7 @@ pub fn insert_as_leaf(mut self, key: K, value: V) ->
     }
 }
 
-impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, Edge, Internal> {
+impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, handle::Edge, handle::Internal> {
     /// Returns a mutable reference to the edge pointed-to by this handle. This should not be
     /// confused with `node`, which references the parent node of what is returned here.
     pub fn edge_mut(&mut self) -> &mut Node<K, V> {
@@ -794,11 +799,11 @@ unsafe fn handle_underflow_to_right(&mut self) {
     }
 }
 
-impl<K, V, NodeRef: DerefMut<Node<K, V>>, NodeType> Handle<NodeRef, Edge, NodeType> {
+impl<K, V, NodeRef: DerefMut<Node<K, V>>, NodeType> Handle<NodeRef, handle::Edge, NodeType> {
     /// Gets the handle pointing to the key/value pair just to the left of the pointed-to edge.
     /// This is unsafe because the handle might point to the first edge in the node, which has no
     /// pair to its left.
-    unsafe fn left_kv<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, KV, NodeType> {
+    unsafe fn left_kv<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::KV, NodeType> {
         Handle {
             node: &mut *self.node,
             index: self.index - 1
@@ -808,7 +813,7 @@ unsafe fn left_kv<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, KV, NodeType>
     /// Gets the handle pointing to the key/value pair just to the right of the pointed-to edge.
     /// This is unsafe because the handle might point to the last edge in the node, which has no
     /// pair to its right.
-    unsafe fn right_kv<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, KV, NodeType> {
+    unsafe fn right_kv<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::KV, NodeType> {
         Handle {
             node: &mut *self.node,
             index: self.index
@@ -816,7 +821,7 @@ unsafe fn right_kv<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, KV, NodeType>
     }
 }
 
-impl<'a, K: 'a, V: 'a, NodeType> Handle<&'a Node<K, V>, KV, NodeType> {
+impl<'a, K: 'a, V: 'a, NodeType> Handle<&'a Node<K, V>, handle::KV, NodeType> {
     /// Turns the handle into references to the key and value it points at. This is necessary
     /// because the returned pointers have larger lifetimes than what would be returned by `key`
     /// or `val`.
@@ -831,7 +836,7 @@ pub fn into_kv(self) -> (&'a K, &'a V) {
     }
 }
 
-impl<'a, K: 'a, V: 'a, NodeType> Handle<&'a mut Node<K, V>, KV, NodeType> {
+impl<'a, K: 'a, V: 'a, NodeType> Handle<&'a mut Node<K, V>, handle::KV, NodeType> {
     /// Turns the handle into mutable references to the key and value it points at. This is
     /// necessary because the returned pointers have larger lifetimes than what would be returned
     /// by `key_mut` or `val_mut`.
@@ -848,7 +853,7 @@ pub fn into_kv_mut(self) -> (&'a mut K, &'a mut V) {
     /// Convert this handle into one pointing at the edge immediately to the left of the key/value
     /// pair pointed-to by this handle. This is useful because it returns a reference with larger
     /// lifetime than `left_edge`.
-    pub fn into_left_edge(self) -> Handle<&'a mut Node<K, V>, Edge, NodeType> {
+    pub fn into_left_edge(self) -> Handle<&'a mut Node<K, V>, handle::Edge, NodeType> {
         Handle {
             node: &mut *self.node,
             index: self.index
@@ -856,7 +861,8 @@ pub fn into_left_edge(self) -> Handle<&'a mut Node<K, V>, Edge, NodeType> {
     }
 }
 
-impl<'a, K: 'a, V: 'a, NodeRef: Deref<Node<K, V>> + 'a, NodeType> Handle<NodeRef, KV, NodeType> {
+impl<'a, K: 'a, V: 'a, NodeRef: Deref<Node<K, V>> + 'a, NodeType> Handle<NodeRef, handle::KV,
+                                                                         NodeType> {
     // These are fine to include, but are currently unneeded.
     //
     // /// Returns a reference to the key pointed-to by this handle. This doesn't return a
@@ -874,7 +880,8 @@ impl<'a, K: 'a, V: 'a, NodeRef: Deref<Node<K, V>> + 'a, NodeType> Handle<NodeRef
     // }
 }
 
-impl<'a, K: 'a, V: 'a, NodeRef: DerefMut<Node<K, V>> + 'a, NodeType> Handle<NodeRef, KV, NodeType> {
+impl<'a, K: 'a, V: 'a, NodeRef: DerefMut<Node<K, V>> + 'a, NodeType> Handle<NodeRef, handle::KV,
+                                                                            NodeType> {
     /// Returns a mutable reference to the key pointed-to by this handle. This doesn't return a
     /// reference with a lifetime as large as `into_kv_mut`, but it also does not consume the
     /// handle.
@@ -890,10 +897,10 @@ pub fn val_mut(&'a mut self) -> &'a mut V {
     }
 }
 
-impl<K, V, NodeRef: DerefMut<Node<K, V>>, NodeType> Handle<NodeRef, KV, NodeType> {
+impl<K, V, NodeRef: DerefMut<Node<K, V>>, NodeType> Handle<NodeRef, handle::KV, NodeType> {
     /// Gets the handle pointing to the edge immediately to the left of the key/value pair pointed
     /// to by this handle.
-    pub fn left_edge<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, Edge, NodeType> {
+    pub fn left_edge<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::Edge, NodeType> {
         Handle {
             node: &mut *self.node,
             index: self.index
@@ -902,7 +909,7 @@ pub fn left_edge<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, Edge, NodeType>
 
     /// Gets the handle pointing to the edge immediately to the right of the key/value pair pointed
     /// to by this handle.
-    pub fn right_edge<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, Edge, NodeType> {
+    pub fn right_edge<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::Edge, NodeType> {
         Handle {
             node: &mut *self.node,
             index: self.index + 1
@@ -910,7 +917,7 @@ pub fn right_edge<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, Edge, NodeType
     }
 }
 
-impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, KV, Leaf> {
+impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, handle::KV, handle::Leaf> {
     /// Removes the key/value pair at the handle's location.
     ///
     /// # Panics (in debug build)
@@ -921,7 +928,7 @@ pub fn remove_as_leaf(mut self) -> (K, V) {
     }
 }
 
-impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, KV, Internal> {
+impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, handle::KV, handle::Internal> {
     /// Steal! Stealing is roughly analogous to a binary tree rotation.
     /// In this case, we're "rotating" right.
     unsafe fn steal_rightward(&mut self) {
@@ -1004,7 +1011,8 @@ impl<K, V> Node<K, V> {
     /// # Panics (in debug build)
     ///
     /// Panics if the given index is out of bounds.
-    pub fn kv_handle(&mut self, index: uint) -> Handle<&mut Node<K, V>, KV, LeafOrInternal> {
+    pub fn kv_handle(&mut self, index: uint) -> Handle<&mut Node<K, V>, handle::KV,
+                                                       handle::LeafOrInternal> {
         // Necessary for correctness, but in a private module
         debug_assert!(index < self.len(), "kv_handle index out of bounds");
         Handle {
index 4ef2e681992aed87682b00fde9be91e6b448b549..890d9be39f985a1c23fe87b4444a11b99ddab283 100644 (file)
@@ -726,7 +726,7 @@ fn next(&mut self) -> Option<&'a T> {
 
 #[cfg(test)]
 mod test {
-    use std::prelude::*;
+    use prelude::*;
 
     use super::BTreeSet;
     use std::hash;
index e7454aef51e8e9aac9d7f00478d40b0a26769040..d3c1a0f81a3367678b548c36ca016ae41437c874 100644 (file)
@@ -758,6 +758,7 @@ fn cmp(&self, other: &DList<A>) -> Ordering {
     }
 }
 
+#[stable]
 impl<A: Clone> Clone for DList<A> {
     fn clone(&self) -> DList<A> {
         self.iter().map(|x| x.clone()).collect()
@@ -788,14 +789,14 @@ fn hash(&self, state: &mut S) {
 
 #[cfg(test)]
 mod tests {
-    use std::prelude::*;
+    use prelude::*;
     use std::rand;
     use std::hash;
+    use std::task::spawn;
     use test::Bencher;
     use test;
 
     use super::{DList, Node, ListInsertion};
-    use vec::Vec;
 
     pub fn check_links<T>(list: &DList<T>) {
         let mut len = 0u;
index caa2051c3f9ca9b13d2069106e30e47ff136cc50..ed7516fec16a946c4ed8cd1039dd3c8b266ed735 100644 (file)
@@ -295,9 +295,9 @@ fn extend<I: Iterator<E>>(&mut self, mut iterator: I) {
 
 #[cfg(test)]
 mod test {
-    use std::prelude::*;
     use self::Foo::*;
-    use std::mem;
+    use prelude::*;
+    use core::mem;
 
     use super::{EnumSet, CLike};
 
index a8eb10e51635ff975c8725766a5c075af2fa434a..75d179319f7c03e999dc28341c561e1c4fc8b690 100644 (file)
@@ -23,7 +23,7 @@
 
 #![allow(unknown_features)]
 #![feature(macro_rules, default_type_params, phase, globs)]
-#![feature(unsafe_destructor, import_shadowing, slicing_syntax)]
+#![feature(unsafe_destructor, slicing_syntax)]
 #![feature(unboxed_closures)]
 #![no_std]
 
@@ -95,3 +95,41 @@ mod std {
     pub use core::kinds;    // deriving(Copy)
     pub use core::hash;     // deriving(Hash)
 }
+
+#[cfg(test)]
+mod prelude {
+    // from core.
+    pub use core::borrow::IntoCow;
+    pub use core::char::Char;
+    pub use core::clone::Clone;
+    pub use core::cmp::{PartialEq, Eq, Equiv, PartialOrd, Ord};
+    pub use core::cmp::Ordering::{Less, Equal, Greater};
+    pub use core::iter::range;
+    pub use core::iter::{FromIterator, Extend, IteratorExt};
+    pub use core::iter::{Iterator, DoubleEndedIterator, RandomAccessIterator};
+    pub use core::iter::{IteratorCloneExt, CloneIteratorExt, DoubleEndedIteratorExt};
+    pub use core::iter::{IteratorOrdExt, MutableDoubleEndedIterator, ExactSizeIterator};
+    pub use core::kinds::{Copy, Send, Sized, Sync};
+    pub use core::mem::drop;
+    pub use core::ops::{Drop, Fn, FnMut, FnOnce};
+    pub use core::option::Option;
+    pub use core::option::Option::{Some, None};
+    pub use core::ptr::RawPtr;
+    pub use core::result::Result;
+    pub use core::result::Result::{Ok, Err};
+
+    // in core and collections (may differ).
+    pub use slice::{PartialEqSliceExt, OrdSliceExt};
+    pub use slice::{AsSlice, SliceExt};
+    pub use str::{from_str, Str, StrPrelude};
+
+    // from other crates.
+    pub use alloc::boxed::Box;
+    pub use unicode::char::UnicodeChar;
+
+    // from collections.
+    pub use slice::{CloneSliceExt, VectorVector};
+    pub use str::{IntoMaybeOwned, UnicodeStrPrelude, StrAllocating, StrVector};
+    pub use string::{String, ToString};
+    pub use vec::Vec;
+}
index cdb92d302e9d31ed880c3a21cee4fae0090baa9a..aa0e33248fcc1575e4a539cb9dbb2ad69c51b5ab 100644 (file)
@@ -48,6 +48,7 @@ pub struct RingBuf<T> {
     ptr: *mut T
 }
 
+#[stable]
 impl<T: Clone> Clone for RingBuf<T> {
     fn clone(&self) -> RingBuf<T> {
         self.iter().map(|t| t.clone()).collect()
@@ -78,7 +79,13 @@ fn default() -> RingBuf<T> { RingBuf::new() }
 impl<T> RingBuf<T> {
     /// Turn ptr into a slice
     #[inline]
-    unsafe fn buffer_as_slice(&self) -> &[T] {
+    unsafe fn buffer_as_slice<'a>(&'a self) -> &'a [T] {
+        mem::transmute(RawSlice { data: self.ptr as *const T, len: self.cap })
+    }
+
+    /// Turn ptr into a mut slice
+    #[inline]
+    unsafe fn buffer_as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
         mem::transmute(RawSlice { data: self.ptr as *const T, len: self.cap })
     }
 
@@ -413,6 +420,48 @@ pub fn into_iter(self) -> MoveItems<T> {
         }
     }
 
+    /// Returns a pair of slices which contain, in order, the contents of the
+    /// `RingBuf`.
+    #[inline]
+    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    pub fn as_slices<'a>(&'a self) -> (&'a [T], &'a [T]) {
+        unsafe {
+            let contiguous = self.is_contiguous();
+            let buf = self.buffer_as_slice();
+            if contiguous {
+                let (empty, buf) = buf.split_at(0);
+                (buf[self.tail..self.head], empty)
+            } else {
+                let (mid, right) = buf.split_at(self.tail);
+                let (left, _) = mid.split_at(self.head);
+                (right, left)
+            }
+        }
+    }
+
+    /// Returns a pair of slices which contain, in order, the contents of the
+    /// `RingBuf`.
+    #[inline]
+    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    pub fn as_mut_slices<'a>(&'a mut self) -> (&'a mut [T], &'a mut [T]) {
+        unsafe {
+            let contiguous = self.is_contiguous();
+            let head = self.head;
+            let tail = self.tail;
+            let buf = self.buffer_as_mut_slice();
+
+            if contiguous {
+                let (empty, buf) = buf.split_at_mut(0);
+                (buf[mut tail..head], empty)
+            } else {
+                let (mid, right) = buf.split_at_mut(tail);
+                let (left, _) = mid.split_at_mut(head);
+
+                (right, left)
+            }
+        }
+    }
+
     /// Returns the number of elements in the `RingBuf`.
     ///
     /// # Examples
@@ -443,6 +492,27 @@ pub fn len(&self) -> uint { count(self.tail, self.head, self.cap) }
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn is_empty(&self) -> bool { self.len() == 0 }
 
+    /// Creates a draining iterator that clears the `RingBuf` and iterates over
+    /// the removed items from start to end.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::RingBuf;
+    ///
+    /// let mut v = RingBuf::new();
+    /// v.push_back(1i);
+    /// assert_eq!(v.drain().next(), Some(1));
+    /// assert!(v.is_empty());
+    /// ```
+    #[inline]
+    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    pub fn drain<'a>(&'a mut self) -> Drain<'a, T> {
+        Drain {
+            inner: self,
+        }
+    }
+
     /// Clears the buffer, removing all values.
     ///
     /// # Examples
@@ -456,10 +526,9 @@ pub fn is_empty(&self) -> bool { self.len() == 0 }
     /// assert!(v.is_empty());
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[inline]
     pub fn clear(&mut self) {
-        while self.pop_front().is_some() {}
-        self.head = 0;
-        self.tail = 0;
+        self.drain();
     }
 
     /// Provides a reference to the front element, or `None` if the sequence is
@@ -663,6 +732,11 @@ pub fn pop_back(&mut self) -> Option<T> {
         }
     }
 
+    #[inline]
+    fn is_contiguous(&self) -> bool {
+        self.tail <= self.head
+    }
+
     /// Inserts an element at position `i` within the ringbuf. Whichever
     /// end is closer to the insertion point will be moved to make room,
     /// and all the affected elements will be moved to new positions.
@@ -715,7 +789,7 @@ pub fn insert(&mut self, i: uint, t: T) {
         let distance_to_tail = i;
         let distance_to_head = self.len() - i;
 
-        let contiguous = self.tail <= self.head;
+        let contiguous = self.is_contiguous();
 
         match (contiguous, distance_to_tail <= distance_to_head, idx >= self.tail) {
             (true, true, _) if i == 0 => {
@@ -1177,9 +1251,44 @@ fn next_back(&mut self) -> Option<T> {
     }
 }
 
-
 impl<T> ExactSizeIterator<T> for MoveItems<T> {}
 
+/// A draining RingBuf iterator
+pub struct Drain<'a, T: 'a> {
+    inner: &'a mut RingBuf<T>,
+}
+
+#[unsafe_destructor]
+impl<'a, T: 'a> Drop for Drain<'a, T> {
+    fn drop(&mut self) {
+        for _ in *self {}
+        self.inner.head = 0;
+        self.inner.tail = 0;
+    }
+}
+
+impl<'a, T: 'a> Iterator<T> for Drain<'a, T> {
+    #[inline]
+    fn next(&mut self) -> Option<T> {
+        self.inner.pop_front()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        let len = self.inner.len();
+        (len, Some(len))
+    }
+}
+
+impl<'a, T: 'a> DoubleEndedIterator<T> for Drain<'a, T> {
+    #[inline]
+    fn next_back(&mut self) -> Option<T> {
+        self.inner.pop_back()
+    }
+}
+
+impl<'a, T: 'a> ExactSizeIterator<T> for Drain<'a, T> {}
+
 impl<A: PartialEq> PartialEq for RingBuf<A> {
     fn eq(&self, other: &RingBuf<A>) -> bool {
         self.len() == other.len() &&
@@ -1260,18 +1369,17 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 #[cfg(test)]
 mod tests {
-    use core::iter;
     use self::Taggy::*;
     use self::Taggypar::*;
-    use std::cmp;
+    use prelude::*;
+    use core::cmp;
+    use core::iter;
     use std::fmt::Show;
-    use std::prelude::*;
     use std::hash;
     use test::Bencher;
     use test;
 
     use super::RingBuf;
-    use vec::Vec;
 
     #[test]
     #[allow(deprecated)]
@@ -1789,9 +1897,76 @@ fn test_into_iter() {
         }
     }
 
+    #[test]
+    fn test_drain() {
+
+        // Empty iter
+        {
+            let mut d: RingBuf<int> = RingBuf::new();
+
+            {
+                let mut iter = d.drain();
+
+                assert_eq!(iter.size_hint(), (0, Some(0)));
+                assert_eq!(iter.next(), None);
+                assert_eq!(iter.size_hint(), (0, Some(0)));
+            }
+
+            assert!(d.is_empty());
+        }
+
+        // simple iter
+        {
+            let mut d = RingBuf::new();
+            for i in range(0i, 5) {
+                d.push_back(i);
+            }
+
+            assert_eq!(d.drain().collect::<Vec<int>>(), [0, 1, 2, 3, 4]);
+            assert!(d.is_empty());
+        }
+
+        // wrapped iter
+        {
+            let mut d = RingBuf::new();
+            for i in range(0i, 5) {
+                d.push_back(i);
+            }
+            for i in range(6, 9) {
+                d.push_front(i);
+            }
+
+            assert_eq!(d.drain().collect::<Vec<int>>(), [8,7,6,0,1,2,3,4]);
+            assert!(d.is_empty());
+        }
+
+        // partially used
+        {
+            let mut d = RingBuf::new();
+            for i in range(0i, 5) {
+                d.push_back(i);
+            }
+            for i in range(6, 9) {
+                d.push_front(i);
+            }
+
+            {
+                let mut it = d.drain();
+                assert_eq!(it.size_hint(), (8, Some(8)));
+                assert_eq!(it.next(), Some(8));
+                assert_eq!(it.size_hint(), (7, Some(7)));
+                assert_eq!(it.next_back(), Some(4));
+                assert_eq!(it.size_hint(), (6, Some(6)));
+                assert_eq!(it.next(), Some(7));
+                assert_eq!(it.size_hint(), (5, Some(5)));
+            }
+            assert!(d.is_empty());
+        }
+    }
+
     #[test]
     fn test_from_iter() {
-        use std::iter;
+        use core::iter;
         let v = vec!(1i,2,3,4,5,6,7);
         let deq: RingBuf<int> = v.iter().map(|&x| x).collect();
         let u: Vec<int> = deq.iter().map(|&x| x).collect();
@@ -2132,4 +2307,60 @@ fn test_front() {
         ring.pop_front();
         assert_eq!(ring.front(), None);
     }
+
+    #[test]
+    fn test_as_slices() {
+        let mut ring: RingBuf<int> = RingBuf::with_capacity(127);
+        let cap = ring.capacity() as int;
+        let first = cap/2;
+        let last  = cap - first;
+        for i in range(0, first) {
+            ring.push_back(i);
+
+            let (left, right) = ring.as_slices();
+            let expected: Vec<_> = range(0, i+1).collect();
+            assert_eq!(left, expected);
+            assert_eq!(right, []);
+        }
+
+        for j in range(-last, 0) {
+            ring.push_front(j);
+            let (left, right) = ring.as_slices();
+            let expected_left: Vec<_> = range(-last, j+1).rev().collect();
+            let expected_right: Vec<_> = range(0, first).collect();
+            assert_eq!(left, expected_left);
+            assert_eq!(right, expected_right);
+        }
+
+        assert_eq!(ring.len() as int, cap);
+        assert_eq!(ring.capacity() as int, cap);
+    }
+
+    #[test]
+    fn test_as_mut_slices() {
+        let mut ring: RingBuf<int> = RingBuf::with_capacity(127);
+        let cap = ring.capacity() as int;
+        let first = cap/2;
+        let last  = cap - first;
+        for i in range(0, first) {
+            ring.push_back(i);
+
+            let (left, right) = ring.as_mut_slices();
+            let expected: Vec<_> = range(0, i+1).collect();
+            assert_eq!(left, expected);
+            assert_eq!(right, []);
+        }
+
+        for j in range(-last, 0) {
+            ring.push_front(j);
+            let (left, right) = ring.as_mut_slices();
+            let expected_left: Vec<_> = range(-last, j+1).rev().collect();
+            let expected_right: Vec<_> = range(0, first).collect();
+            assert_eq!(left, expected_left);
+            assert_eq!(right, expected_right);
+        }
+
+        assert_eq!(ring.len() as int, cap);
+        assert_eq!(ring.capacity() as int, cap);
+    }
 }
index 3bf10192e596388758f9b5315174879b1c3fdaf9..16adf6fa224b449cdfe5d1b9e41a7a064b4cafec 100644 (file)
@@ -1343,16 +1343,13 @@ pub mod raw {
 #[cfg(test)]
 mod tests {
     use std::boxed::Box;
-    use std::cell::Cell;
-    use std::default::Default;
-    use std::mem;
-    use std::prelude::*;
+    use prelude::*;
+    use core::cell::Cell;
+    use core::default::Default;
+    use core::mem;
     use std::rand::{Rng, task_rng};
     use std::rc::Rc;
-    use std::rt;
-    use slice::*;
-
-    use vec::Vec;
+    use super::ElementSwaps;
 
     fn square(n: uint) -> uint { n * n }
 
@@ -2764,14 +2761,12 @@ fn test_to_vec() {
 
 #[cfg(test)]
 mod bench {
-    use std::prelude::*;
+    use prelude::*;
+    use core::mem;
+    use core::ptr;
     use std::rand::{weak_rng, Rng};
-    use std::mem;
-    use std::ptr;
     use test::{Bencher, black_box};
 
-    use vec::Vec;
-
     #[bench]
     fn iterator(b: &mut Bencher) {
         // peculiar numbers to stop LLVM from optimising the summation
index 9ac5f04efe5f28759e9e1a905f56dfb30ecaa823..bb03575b3ac271043173bb0c1ea9b77396a80c07 100644 (file)
 
 #![doc(primitive = "str")]
 
-use core::prelude::*;
-
-pub use self::MaybeOwned::*;
+use self::MaybeOwned::*;
 use self::RecompositionState::*;
 use self::DecompositionType::*;
 
 use core::borrow::{BorrowFrom, Cow, ToOwned};
+use core::clone::Clone;
 use core::default::Default;
 use core::fmt;
 use core::hash;
-use core::cmp;
-use core::iter::AdditiveIterator;
+use core::char::Char;
+use core::cmp::{mod, Eq, Equiv, Ord, Ordering, PartialEq, PartialOrd};
+use core::iter::{range, AdditiveIterator, Iterator, IteratorExt};
+use core::kinds::Sized;
+use core::option::Option::{mod, Some, None};
+use core::slice::{AsSlice, SliceExt};
 
 use ring_buf::RingBuf;
 use string::String;
@@ -834,25 +837,12 @@ fn into_string(self) -> String {
 
 #[cfg(test)]
 mod tests {
-    use std::iter::AdditiveIterator;
-    use std::iter::range;
-    use std::default::Default;
-    use std::char::Char;
-    use std::clone::Clone;
-    use std::cmp::{Ord, PartialOrd, Equiv};
-    use std::cmp::Ordering::{Equal, Greater, Less};
-    use std::option::Option;
-    use std::option::Option::{Some, None};
-    use std::ptr::RawPtr;
-    use std::iter::{Iterator, IteratorExt, DoubleEndedIteratorExt};
-
-    use super::*;
-    use std::slice::{AsSlice, SliceExt};
-    use string::String;
-    use vec::Vec;
-    use slice::CloneSliceExt;
-
-    use unicode::char::UnicodeChar;
+    use prelude::*;
+    use core::default::Default;
+    use core::iter::AdditiveIterator;
+    use super::{eq_slice, from_utf8, is_utf8, is_utf16, raw};
+    use super::truncate_utf16_at_nul;
+    use super::MaybeOwned::{Owned, Slice};
 
     #[test]
     fn test_eq_slice() {
@@ -1826,7 +1816,7 @@ fn test_words() {
 
     #[test]
     fn test_lev_distance() {
-        use std::char::{ from_u32, MAX };
+        use core::char::{ from_u32, MAX };
         // Test bytelength agnosticity
         for c in range(0u32, MAX as u32)
                  .filter_map(|i| from_u32(i))
@@ -1936,7 +1926,7 @@ fn test_lines() {
 
     #[test]
     fn test_graphemes() {
-        use std::iter::order;
+        use core::iter::order;
         // official Unicode test data
         // from http://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakTest.txt
         let test_same: [(_, &[_]), .. 325] = [
@@ -2367,7 +2357,7 @@ fn t(s: &str, sep: &str, u: &[&str]) {
 
     #[test]
     fn test_str_default() {
-        use std::default::Default;
+        use core::default::Default;
         fn t<S: Default + Str>() {
             let s: S = Default::default();
             assert_eq!(s.as_slice(), "");
@@ -2467,12 +2457,10 @@ fn test_into_maybe_owned() {
 
 #[cfg(test)]
 mod bench {
+    use prelude::*;
     use test::Bencher;
     use test::black_box;
     use super::*;
-    use std::iter::{IteratorExt, DoubleEndedIteratorExt};
-    use std::str::StrPrelude;
-    use std::slice::SliceExt;
 
     #[bench]
     fn char_iterator(b: &mut Bencher) {
index 38ebd686ddbdd3ee579fd96aa27db22d3e36a90b..76f69dbdb744bdd2c322fb461e7a4cff3023be4c 100644 (file)
@@ -26,7 +26,8 @@
 
 use slice::CloneSliceExt;
 use str;
-use str::{CharRange, CowString, FromStr, StrAllocating, Owned};
+use str::{CharRange, CowString, FromStr, StrAllocating};
+use str::MaybeOwned::Owned;
 use vec::{DerefVec, Vec, as_vec};
 
 /// A growable string stored as a UTF-8 encoded buffer.
@@ -512,6 +513,11 @@ pub fn shrink_to_fit(&mut self) {
     #[inline]
     #[stable = "function just renamed from push_char"]
     pub fn push(&mut self, ch: char) {
+        if (ch as u32) < 0x80 {
+            self.vec.push(ch as u8);
+            return;
+        }
+
         let cur_len = self.len();
         // This may use up to 4 bytes.
         self.vec.reserve(4);
@@ -885,14 +891,6 @@ fn add(mut self, other: &str) -> String {
     }
 }
 
-#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
-impl<'a> Add<String, String> for &'a str {
-    fn add(self, mut other: String) -> String {
-        other.push_str(self);
-        other
-    }
-}
-
 impl ops::Slice<uint, str> for String {
     #[inline]
     fn as_slice_<'a>(&'a self) -> &'a str {
@@ -1040,14 +1038,11 @@ pub unsafe fn from_utf8(bytes: Vec<u8>) -> String {
 
 #[cfg(test)]
 mod tests {
-    use std::prelude::*;
+    use prelude::*;
     use test::Bencher;
 
-    use slice::CloneSliceExt;
-    use str::{Str, StrPrelude};
     use str;
-    use super::{as_string, String, ToString};
-    use vec::Vec;
+    use super::as_string;
 
     #[test]
     fn test_as_string() {
@@ -1411,6 +1406,41 @@ fn bench_push_str(b: &mut Bencher) {
         });
     }
 
+    const REPETITIONS: u64 = 10_000;
+
+    #[bench]
+    fn bench_push_str_one_byte(b: &mut Bencher) {
+        b.bytes = REPETITIONS;
+        b.iter(|| {
+            let mut r = String::new();
+            for _ in range(0, REPETITIONS) {
+                r.push_str("a")
+            }
+        });
+    }
+
+    #[bench]
+    fn bench_push_char_one_byte(b: &mut Bencher) {
+        b.bytes = REPETITIONS;
+        b.iter(|| {
+            let mut r = String::new();
+            for _ in range(0, REPETITIONS) {
+                r.push('a')
+            }
+        });
+    }
+
+    #[bench]
+    fn bench_push_char_two_bytes(b: &mut Bencher) {
+        b.bytes = REPETITIONS * 2;
+        b.iter(|| {
+            let mut r = String::new();
+            for _ in range(0, REPETITIONS) {
+                r.push('â')
+            }
+        });
+    }
+
     #[bench]
     fn from_utf8_lossy_100_ascii(b: &mut Bencher) {
         let s = b"Hello there, the quick brown fox jumped over the lazy dog! \
index e986b2044306f058291a07cb37d1aa01342a9743..73464c1b2fc776c61fe9204d6a242a05b200d27f 100644 (file)
@@ -54,7 +54,6 @@
 use core::fmt;
 use core::hash::{mod, Hash};
 use core::kinds::marker::{ContravariantLifetime, InvariantType};
-use core::kinds::Sized;
 use core::mem;
 use core::num::{Int, UnsignedInt};
 use core::ops;
@@ -412,6 +411,33 @@ pub fn grow(&mut self, n: uint, value: T) {
         }
     }
 
+    /// Resizes the `Vec` in-place so that `len()` is equal to `new_len`.
+    ///
+    /// Calls either `extend()` or `truncate()` depending on whether `new_len`
+    /// is larger than the current value of `len()` or not.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let mut vec = vec!["hello"];
+    /// vec.resize(3, "world");
+    /// assert_eq!(vec, vec!["hello", "world", "world"]);
+    ///
+    /// let mut vec = vec![1i, 2, 3, 4];
+    /// vec.resize(2, 0);
+    /// assert_eq!(vec, vec![1, 2]);
+    /// ```
+    #[unstable = "matches collection reform specification; waiting for dust to settle"]
+    pub fn resize(&mut self, new_len: uint, value: T) {
+        let len = self.len();
+
+        if new_len > len {
+            self.extend(repeat(value).take(new_len - len));
+        } else {
+            self.truncate(new_len);
+        }
+    }
+
     /// Partitions a vector based on a predicate.
     ///
     /// Clones the elements of the vector, partitioning them into two `Vec<T>`s
@@ -443,7 +469,7 @@ pub fn partitioned<F>(&self, mut f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) ->
     }
 }
 
-#[unstable]
+#[stable]
 impl<T:Clone> Clone for Vec<T> {
     fn clone(&self) -> Vec<T> { self.as_slice().to_vec() }
 
@@ -1118,6 +1144,38 @@ pub fn pop(&mut self) -> Option<T> {
         }
     }
 
+    /// Creates a draining iterator that clears the `Vec` and iterates over
+    /// the removed items from start to end.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let mut v = vec!["a".to_string(), "b".to_string()];
+    /// for s in v.drain() {
+    ///     // s has type String, not &String
+    ///     println!("{}", s);
+    /// }
+    /// assert!(v.is_empty());
+    /// ```
+    #[inline]
+    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    pub fn drain<'a>(&'a mut self) -> Drain<'a, T> {
+        unsafe {
+            let begin = self.ptr as *const T;
+            let end = if mem::size_of::<T>() == 0 {
+                (self.ptr as uint + self.len()) as *const T
+            } else {
+                self.ptr.offset(self.len() as int) as *const T
+            };
+            self.set_len(0);
+            Drain {
+                ptr: begin,
+                end: end,
+                marker: ContravariantLifetime,
+            }
+        }
+    }
+
     /// Clears the vector, removing all values.
     ///
     /// # Examples
@@ -1325,15 +1383,6 @@ fn add(mut self, rhs: &[T]) -> Vec<T> {
     }
 }
 
-#[cfg(not(stage0))]  // NOTE(stage0): Remove impl after a snapshot
-impl<'a, T: Clone> Add<Vec<T>, Vec<T>> for &'a [T] {
-    #[inline]
-    fn add(self, mut rhs: Vec<T>) -> Vec<T> {
-        rhs.push_all(self);
-        rhs
-    }
-}
-
 #[unsafe_destructor]
 impl<T> Drop for Vec<T> {
     fn drop(&mut self) {
@@ -1374,8 +1423,9 @@ pub struct MoveItems<T> {
 }
 
 impl<T> MoveItems<T> {
-    #[inline]
     /// Drops all items that have not yet been moved and returns the empty vector.
+    #[inline]
+    #[unstable]
     pub fn into_inner(mut self) -> Vec<T> {
         unsafe {
             for _x in self { }
@@ -1385,8 +1435,8 @@ pub fn into_inner(mut self) -> Vec<T> {
         }
     }
 
-    /// Deprecated, use into_inner() instead
-    #[deprecated = "renamed to into_inner()"]
+    /// Deprecated, use .into_inner() instead
+    #[deprecated = "use .into_inner() instead"]
     pub fn unwrap(self) -> Vec<T> { self.into_inner() }
 }
 
@@ -1462,6 +1512,84 @@ fn drop(&mut self) {
     }
 }
 
+/// An iterator that drains a vector.
+#[unsafe_no_drop_flag]
+pub struct Drain<'a, T> {
+    ptr: *const T,
+    end: *const T,
+    marker: ContravariantLifetime<'a>,
+}
+
+impl<'a, T> Iterator<T> for Drain<'a, T> {
+    #[inline]
+    fn next(&mut self) -> Option<T> {
+        unsafe {
+            if self.ptr == self.end {
+                None
+            } else {
+                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.
+                    self.ptr = mem::transmute(self.ptr as uint + 1);
+
+                    // Use a non-null pointer value
+                    Some(ptr::read(mem::transmute(1u)))
+                } else {
+                    let old = self.ptr;
+                    self.ptr = self.ptr.offset(1);
+
+                    Some(ptr::read(old))
+                }
+            }
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        let diff = (self.end as uint) - (self.ptr as uint);
+        let size = mem::size_of::<T>();
+        let exact = diff / (if size == 0 {1} else {size});
+        (exact, Some(exact))
+    }
+}
+
+impl<'a, T> DoubleEndedIterator<T> for Drain<'a, T> {
+    #[inline]
+    fn next_back(&mut self) -> Option<T> {
+        unsafe {
+            if self.end == self.ptr {
+                None
+            } else {
+                if mem::size_of::<T>() == 0 {
+                    // See above for why 'ptr.offset' isn't used
+                    self.end = mem::transmute(self.end as uint - 1);
+
+                    // Use a non-null pointer value
+                    Some(ptr::read(mem::transmute(1u)))
+                } else {
+                    self.end = self.end.offset(-1);
+
+                    Some(ptr::read(self.end))
+                }
+            }
+        }
+    }
+}
+
+impl<'a, T> ExactSizeIterator<T> for Drain<'a, T> {}
+
+#[unsafe_destructor]
+impl<'a, T> Drop for Drain<'a, T> {
+    fn drop(&mut self) {
+        // self.ptr == self.end == null if drop has already been called,
+        // so we can use #[unsafe_no_drop_flag].
+
+        // destroy the remaining elements
+        for _x in *self {}
+    }
+}
+
 /// Converts an iterator of pairs into a pair of vectors.
 ///
 /// Returns a tuple containing two vectors where the i-th element of the first vector contains the
@@ -1806,12 +1934,10 @@ fn write(&mut self, buf: &[u8]) -> fmt::Result {
 
 #[cfg(test)]
 mod tests {
-    extern crate test;
-
-    use std::prelude::*;
-    use std::mem::size_of;
+    use prelude::*;
+    use core::mem::size_of;
     use test::Bencher;
-    use super::{as_vec, unzip, raw, Vec};
+    use super::{as_vec, unzip, raw};
 
     struct DropCounter<'a> {
         count: &'a mut int
@@ -2270,6 +2396,39 @@ fn test_move_items_zero_sized() {
         assert!(vec2 == vec![(), (), ()]);
     }
 
+    #[test]
+    fn test_drain_items() {
+        let mut vec = vec![1, 2, 3];
+        let mut vec2: Vec<i32> = vec![];
+        for i in vec.drain() {
+            vec2.push(i);
+        }
+        assert_eq!(vec, []);
+        assert_eq!(vec2, [ 1, 2, 3 ]);
+    }
+
+    #[test]
+    fn test_drain_items_reverse() {
+        let mut vec = vec![1, 2, 3];
+        let mut vec2: Vec<i32> = vec![];
+        for i in vec.drain().rev() {
+            vec2.push(i);
+        }
+        assert_eq!(vec, []);
+        assert_eq!(vec2, [ 3, 2, 1 ]);
+    }
+
+    #[test]
+    fn test_drain_items_zero_sized() {
+        let mut vec = vec![(), (), ()];
+        let mut vec2: Vec<()> = vec![];
+        for i in vec.drain() {
+            vec2.push(i);
+        }
+        assert_eq!(vec, []);
+        assert_eq!(vec2, [(), (), ()]);
+    }
+
     #[test]
     fn test_into_boxed_slice() {
         let xs = vec![1u, 2, 3];
index 8faa9c1c522db18f1f9fc1a68a906afe99e2f16c..1babde6066d0622693b8cce2b9df0b451c51c0d3 100644 (file)
@@ -21,7 +21,6 @@
 use core::iter;
 use core::iter::{Enumerate, FilterMap, Map};
 use core::mem::replace;
-use core::ops::FnOnce;
 
 use {vec, slice};
 use vec::Vec;
@@ -673,8 +672,7 @@ fn next_back(&mut self) -> Option<(uint, V)> { self.iter.next_back() }
 
 #[cfg(test)]
 mod test_map {
-    use std::prelude::*;
-    use vec::Vec;
+    use prelude::*;
     use core::hash::hash;
 
     use super::VecMap;
@@ -1047,8 +1045,7 @@ fn test_index_nonexistent() {
 
 #[cfg(test)]
 mod bench {
-    extern crate test;
-    use self::test::Bencher;
+    use test::Bencher;
     use super::VecMap;
     use bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n};
 
index ffaf35414ea0c41d0b3453510b8641da8fee479e..e85a132ed363f5a2e6c85dceef701117913118ef 100644 (file)
@@ -25,7 +25,7 @@
 macro_rules! array_impls {
     ($($N:expr)+) => {
         $(
-            #[unstable = "waiting for Clone to stabilize"]
+            #[stable]
             impl<T:Copy> Clone for [T, ..$N] {
                 fn clone(&self) -> [T, ..$N] {
                     *self
@@ -115,4 +115,3 @@ fn cmp(&self, other: &[T, ..$N]) -> Ordering {
     20 21 22 23 24 25 26 27 28 29
     30 31 32
 }
-
diff --git a/src/libcore/bool.rs b/src/libcore/bool.rs
deleted file mode 100644 (file)
index 9d2ea81..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! The boolean type
-
-#![doc(primitive = "bool")]
-#![unstable = "this module is purely for documentation and it will likely be \
-               removed from the public api"]
-
index b44b87bd938075cc169a57c652a34c8aafc1dd43..9bbcf67773ebbc966bc9081ea1bde77e0dbf34de 100644 (file)
@@ -137,6 +137,7 @@ pub enum Cow<'a, T, Sized? B: 'a> where B: ToOwned<T> {
     Owned(T)
 }
 
+#[stable]
 impl<'a, T, Sized? B> Clone for Cow<'a, T, B> where B: ToOwned<T> {
     fn clone(&self) -> Cow<'a, T, B> {
         match *self {
index 01979e975774c4b491b708b1d8017f843aabc4d4..b45424a5eed3f7d4209e62880fd653eed298cbe5 100644 (file)
 use option::Option::{None, Some};
 
 /// A mutable memory location that admits only `Copy` data.
-#[unstable = "likely to be renamed; otherwise stable"]
+#[stable]
 pub struct Cell<T> {
     value: UnsafeCell<T>,
     noshare: marker::NoSync,
@@ -208,7 +208,7 @@ pub unsafe fn as_unsafe_cell<'a>(&'a self) -> &'a UnsafeCell<T> {
     }
 }
 
-#[unstable = "waiting for `Clone` trait to become stable"]
+#[stable]
 impl<T:Copy> Clone for Cell<T> {
     fn clone(&self) -> Cell<T> {
         Cell::new(self.get())
@@ -231,7 +231,7 @@ fn eq(&self, other: &Cell<T>) -> bool {
 }
 
 /// A mutable memory location with dynamically checked borrow rules
-#[unstable = "likely to be renamed; otherwise stable"]
+#[stable]
 pub struct RefCell<T> {
     value: UnsafeCell<T>,
     borrow: Cell<BorrowFlag>,
@@ -256,7 +256,7 @@ pub fn new(value: T) -> RefCell<T> {
     }
 
     /// Consumes the `RefCell`, returning the wrapped value.
-    #[unstable = "recently renamed per RFC 430"]
+    #[stable]
     pub fn into_inner(self) -> T {
         // Since this function takes `self` (the `RefCell`) by value, the
         // compiler statically verifies that it is not currently borrowed.
@@ -275,7 +275,7 @@ pub fn unwrap(self) -> T { self.into_inner() }
     /// immutable borrows can be taken out at the same time.
     ///
     /// Returns `None` if the value is currently mutably borrowed.
-    #[unstable = "may be renamed, depending on global conventions"]
+    #[unstable = "may be renamed or removed"]
     pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
         match BorrowRef::new(&self.borrow) {
             Some(b) => Some(Ref { _value: unsafe { &*self.value.get() }, _borrow: b }),
@@ -291,7 +291,7 @@ pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
     /// # Panics
     ///
     /// Panics if the value is currently mutably borrowed.
-    #[unstable]
+    #[stable]
     pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
         match self.try_borrow() {
             Some(ptr) => ptr,
@@ -305,7 +305,7 @@ pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
     /// cannot be borrowed while this borrow is active.
     ///
     /// Returns `None` if the value is currently borrowed.
-    #[unstable = "may be renamed, depending on global conventions"]
+    #[unstable = "may be renamed or removed"]
     pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
         match BorrowRefMut::new(&self.borrow) {
             Some(b) => Some(RefMut { _value: unsafe { &mut *self.value.get() }, _borrow: b }),
@@ -321,7 +321,7 @@ pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
     /// # Panics
     ///
     /// Panics if the value is currently borrowed.
-    #[unstable]
+    #[stable]
     pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
         match self.try_borrow_mut() {
             Some(ptr) => ptr,
@@ -341,7 +341,7 @@ pub unsafe fn as_unsafe_cell<'a>(&'a self) -> &'a UnsafeCell<T> {
     }
 }
 
-#[unstable = "waiting for `Clone` to become stable"]
+#[stable]
 impl<T: Clone> Clone for RefCell<T> {
     fn clone(&self) -> RefCell<T> {
         RefCell::new(self.borrow().clone())
@@ -400,7 +400,7 @@ fn clone(&self) -> BorrowRef<'b> {
 }
 
 /// Wraps a borrowed reference to a value in a `RefCell` box.
-#[unstable]
+#[stable]
 pub struct Ref<'b, T:'b> {
     // FIXME #12808: strange name to try to avoid interfering with
     // field accesses of the contained type via Deref
@@ -456,7 +456,7 @@ fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRefMut<'b>> {
 }
 
 /// Wraps a mutable borrowed reference to a value in a `RefCell` box.
-#[unstable]
+#[stable]
 pub struct RefMut<'b, T:'b> {
     // FIXME #12808: strange name to try to avoid interfering with
     // field accesses of the contained type via Deref
@@ -517,7 +517,7 @@ fn deref_mut<'a>(&'a mut self) -> &'a mut T {
 /// is not recommended to access its fields directly, `get` should be used
 /// instead.
 #[lang="unsafe"]
-#[unstable = "this type may be renamed in the future"]
+#[stable]
 pub struct UnsafeCell<T> {
     /// Wrapped value
     ///
@@ -539,22 +539,16 @@ pub fn new(value: T) -> UnsafeCell<T> {
     }
 
     /// Gets a mutable pointer to the wrapped value.
-    ///
-    /// This function is unsafe as the pointer returned is an unsafe pointer and
-    /// no guarantees are made about the aliasing of the pointers being handed
-    /// out in this or other tasks.
     #[inline]
-    #[unstable = "conventions around acquiring an inner reference are still \
-                  under development"]
-    pub unsafe fn get(&self) -> *mut T { &self.value as *const T as *mut T }
+    #[stable]
+    pub fn get(&self) -> *mut T { &self.value as *const T as *mut T }
 
     /// Unwraps the value
     ///
     /// This function is unsafe because there is no guarantee that this or other
     /// tasks are currently inspecting the inner value.
     #[inline]
-    #[unstable = "conventions around the name `unwrap` are still under \
-                  development"]
+    #[stable]
     pub unsafe fn into_inner(self) -> T { self.value }
 
     /// Deprecated, use into_inner() instead
index f6be422813ac592ba0e5be56939a8beac7cf8c79..686ccf6f1a2513c25e2c7dfd5aa2265d11b90ccb 100644 (file)
 //! explicitly, by convention implementing the `Clone` trait and calling
 //! the `clone` method.
 
-#![unstable]
+#![stable]
 
 use kinds::Sized;
 
 /// A common trait for cloning an object.
+#[stable]
 pub trait Clone {
     /// Returns a copy of the value.
+    #[stable]
     fn clone(&self) -> Self;
 
     /// Perform copy-assignment from `source`.
@@ -34,12 +36,13 @@ pub trait Clone {
     /// but can be overridden to reuse the resources of `a` to avoid unnecessary
     /// allocations.
     #[inline(always)]
-    #[experimental = "this function is mostly unused"]
+    #[unstable = "this function rarely unused"]
     fn clone_from(&mut self, source: &Self) {
         *self = source.clone()
     }
 }
 
+#[stable]
 impl<'a, Sized? T> Clone for &'a T {
     /// Return a shallow copy of the reference.
     #[inline]
@@ -48,6 +51,7 @@ fn clone(&self) -> &'a T { *self }
 
 macro_rules! clone_impl {
     ($t:ty) => {
+        #[stable]
         impl Clone for $t {
             /// Return a deep copy of the value.
             #[inline]
@@ -95,4 +99,3 @@ fn clone(&self) -> extern "Rust" fn($($A),*) -> ReturnType { *self }
 extern_fn_clone! { A, B, C, D, E, F }
 extern_fn_clone! { A, B, C, D, E, F, G }
 extern_fn_clone! { A, B, C, D, E, F, G, H }
-
index e10f5a9fed1888ba02b00d26ec92335ea1ff49e2..ab6b0986c686df72b92a04b0aa93a2faa7d06cf6 100644 (file)
@@ -195,6 +195,7 @@ fn write(&mut self, msg: &[u8]) {
     }
 }
 
+#[stable]
 impl Clone for SipState {
     #[inline]
     fn clone(&self) -> SipState {
@@ -271,14 +272,9 @@ pub fn hash_with_keys<Sized? T: Hash<SipState>>(k0: u64, k1: u64, value: &T) ->
 #[cfg(test)]
 mod tests {
     use test::Bencher;
-    use std::prelude::*;
+    use prelude::*;
     use std::fmt;
 
-    use str::Str;
-    use string::String;
-    use slice::{AsSlice, SliceExt};
-    use vec::Vec;
-
     use super::super::{Hash, Writer};
     use super::{SipState, hash, hash_with_keys};
 
index d8f103fa0f3dcd03b4bcdf4593a37aa9ab15be16..950c47c636987082964acdc9c679c0da12994cac 100644 (file)
@@ -222,7 +222,7 @@ pub struct TyDesc {
     /// Both types must have the same size and alignment, and this guarantee
     /// is enforced at compile-time.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```rust
     /// use std::mem;
@@ -253,14 +253,20 @@ pub struct TyDesc {
     /// integer, since the conversion would throw away aliasing information.
     pub fn offset<T>(dst: *const T, offset: int) -> *const T;
 
-    /// Copies data from one location to another.
-    ///
-    /// Copies `count` elements (not bytes) from `src` to `dst`. The source
+    /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
     /// and destination may *not* overlap.
     ///
     /// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`.
     ///
-    /// # Example
+    /// # Safety
+    ///
+    /// Beyond requiring that both regions of memory be allocated, it is Undefined Behaviour
+    /// for source and destination to overlap. Care must also be taken with the ownership of
+    /// `src` and `dst`. This method semantically moves the values of `src` into `dst`.
+    /// However it does not drop the contents of `dst`, or prevent the contents of `src`
+    /// from being dropped or used.
+    ///
+    /// # Examples
     ///
     /// A safe swap function:
     ///
@@ -284,22 +290,22 @@ pub struct TyDesc {
     ///     }
     /// }
     /// ```
-    ///
-    /// # Safety Note
-    ///
-    /// If the source and destination overlap then the behavior of this
-    /// function is undefined.
     #[unstable]
     pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint);
 
-    /// Copies data from one location to another.
-    ///
-    /// Copies `count` elements (not bytes) from `src` to `dst`. The source
+    /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
     /// and destination may overlap.
     ///
     /// `copy_memory` is semantically equivalent to C's `memmove`.
     ///
-    /// # Example
+    /// # Safety
+    ///
+    /// Care must be taken with the ownership of `src` and `dst`.
+    /// This method semantically moves the values of `src` into `dst`.
+    /// However it does not drop the contents of `dst`, or prevent the contents of `src`
+    /// from being dropped or used.
+    ///
+    /// # Examples
     ///
     /// Efficiently create a Rust vector from an unsafe buffer:
     ///
index 1f83aad9c7cdca21768788d3bbf9a6e02c7938d3..b592d1db274f63ec9b5dc37a7c2d2056250ae426 100644 (file)
@@ -1386,6 +1386,7 @@ pub struct Map<A, B, I: Iterator<A>, F: FnMut(A) -> B> {
 }
 
 // FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+#[stable]
 impl<A, B, I, F> Clone for Map<A, B, I, F> where
     I: Clone + Iterator<A>,
     F: Clone + FnMut(A) -> B,
@@ -1460,6 +1461,7 @@ pub struct Filter<A, I, P> where I: Iterator<A>, P: FnMut(&A) -> bool {
 }
 
 // FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+#[stable]
 impl<A, I, P> Clone for Filter<A, I, P> where
     I: Clone + Iterator<A>,
     P: Clone + FnMut(&A) -> bool,
@@ -1518,6 +1520,7 @@ pub struct FilterMap<A, B, I, F> where I: Iterator<A>, F: FnMut(A) -> Option<B>
 }
 
 // FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+#[stable]
 impl<A, B, I, F> Clone for FilterMap<A, B, I, F> where
     I: Clone + Iterator<A>,
     F: Clone + FnMut(A) -> Option<B>,
@@ -1693,6 +1696,7 @@ pub struct SkipWhile<A, I, P> where I: Iterator<A>, P: FnMut(&A) -> bool {
 }
 
 // FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+#[stable]
 impl<A, I, P> Clone for SkipWhile<A, I, P> where
     I: Clone + Iterator<A>,
     P: Clone + FnMut(&A) -> bool,
@@ -1736,6 +1740,7 @@ pub struct TakeWhile<A, I, P> where I: Iterator<A>, P: FnMut(&A) -> bool {
 }
 
 // FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+#[stable]
 impl<A, I, P> Clone for TakeWhile<A, I, P> where
     I: Clone + Iterator<A>,
     P: Clone + FnMut(&A) -> bool,
@@ -1911,6 +1916,7 @@ pub struct Scan<A, B, I, St, F> where I: Iterator<A>, F: FnMut(&mut St, A) -> Op
 }
 
 // FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+#[stable]
 impl<A, B, I, St, F> Clone for Scan<A, B, I, St, F> where
     I: Clone + Iterator<A>,
     St: Clone,
@@ -1955,6 +1961,7 @@ pub struct FlatMap<A, B, I, U, F> where I: Iterator<A>, U: Iterator<B>, F: FnMut
 }
 
 // FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+#[stable]
 impl<A, B, I, U, F> Clone for FlatMap<A, B, I, U, F> where
     I: Clone + Iterator<A>,
     U: Clone + Iterator<B>,
@@ -2115,6 +2122,7 @@ pub struct Inspect<A, I, F> where I: Iterator<A>, F: FnMut(&A) {
 }
 
 // FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+#[stable]
 impl<A, I, F> Clone for Inspect<A, I, F> where
     I: Clone + Iterator<A>,
     F: Clone + FnMut(&A),
@@ -2222,6 +2230,7 @@ pub struct Unfold<A, St, F> where F: FnMut(&mut St) -> Option<A> {
 }
 
 // FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+#[stable]
 impl<A, St, F> Clone for Unfold<A, St, F> where
     F: Clone + FnMut(&mut St) -> Option<A>,
     St: Clone,
index 93fd3f1b9f16ff186b8a4e4d4f7c9c131ec58f05..b0f46e3d68c908a1850962274d83ba5007f03945 100644 (file)
@@ -91,7 +91,8 @@ pub trait Sync for Sized? {
 /// implemented using unsafe code. In that case, you may want to embed
 /// some of the marker types below into your type.
 pub mod marker {
-    use super::Copy;
+    use super::{Copy,Sized};
+    use clone::Clone;
 
     /// A marker type whose type parameter `T` is considered to be
     /// covariant with respect to the type itself. This is (typically)
@@ -131,10 +132,13 @@ pub mod marker {
     /// (for example, `S<&'static int>` is a subtype of `S<&'a int>`
     /// for some lifetime `'a`, but not the other way around).
     #[lang="covariant_type"]
-    #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
-    pub struct CovariantType<T>;
+    #[deriving(PartialEq, Eq, PartialOrd, Ord)]
+    pub struct CovariantType<Sized? T>;
 
-    impl<T> Copy for CovariantType<T> {}
+    impl<Sized? T> Copy for CovariantType<T> {}
+    impl<Sized? T> Clone for CovariantType<T> {
+        fn clone(&self) -> CovariantType<T> { *self }
+    }
 
     /// A marker type whose type parameter `T` is considered to be
     /// contravariant with respect to the type itself. This is (typically)
@@ -176,10 +180,13 @@ impl<T> Copy for CovariantType<T> {}
     /// function requires arguments of type `T`, it must also accept
     /// arguments of type `U`, hence such a conversion is safe.
     #[lang="contravariant_type"]
-    #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
-    pub struct ContravariantType<T>;
+    #[deriving(PartialEq, Eq, PartialOrd, Ord)]
+    pub struct ContravariantType<Sized? T>;
 
-    impl<T> Copy for ContravariantType<T> {}
+    impl<Sized? T> Copy for ContravariantType<T> {}
+    impl<Sized? T> Clone for ContravariantType<T> {
+        fn clone(&self) -> ContravariantType<T> { *self }
+    }
 
     /// A marker type whose type parameter `T` is considered to be
     /// invariant with respect to the type itself. This is (typically)
@@ -203,10 +210,13 @@ impl<T> Copy for ContravariantType<T> {}
     /// never written, but in fact `Cell` uses unsafe code to achieve
     /// interior mutability.
     #[lang="invariant_type"]
-    #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
-    pub struct InvariantType<T>;
+    #[deriving(PartialEq, Eq, PartialOrd, Ord)]
+    pub struct InvariantType<Sized? T>;
 
-    impl<T> Copy for InvariantType<T> {}
+    impl<Sized? T> Copy for InvariantType<T> {}
+    impl<Sized? T> Clone for InvariantType<T> {
+        fn clone(&self) -> InvariantType<T> { *self }
+    }
 
     /// As `CovariantType`, but for lifetime parameters. Using
     /// `CovariantLifetime<'a>` indicates that it is ok to substitute
@@ -252,11 +262,9 @@ impl<T> Copy for InvariantType<T> {}
     /// and this pointer is itself stored in an inherently mutable
     /// location (such as a `Cell`).
     #[lang="invariant_lifetime"]
-    #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
+    #[deriving(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
     pub struct InvariantLifetime<'a>;
 
-    impl<'a> Copy for InvariantLifetime<'a> {}
-
     /// A type which is considered "not sendable", meaning that it cannot
     /// be safely sent between tasks, even if it is owned. This is
     /// typically embedded in other types, such as `Gc`, to ensure that
index 729cb69193e63d06a5dc8698ecae39f2ea4d101c..9b6622a7127d5de26b2e20c4b9f44566cbac6cd1 100644 (file)
 
 pub mod any;
 pub mod atomic;
-pub mod bool;
 pub mod borrow;
 pub mod cell;
 pub mod char;
 pub mod simd;
 pub mod slice;
 pub mod str;
-pub mod tuple;
 pub mod hash;
-// FIXME #15320: primitive documentation needs top-level modules, this
-// should be `core::tuple::unit`.
-#[path = "tuple/unit.rs"]
-pub mod unit;
 pub mod fmt;
 
 // note: does not need to be public
+mod tuple;
 mod array;
 
 #[doc(hidden)]
index a0659d383076486fd2986cdc54b0c432efd8c266..91c5e4163f9e598ded24217da81749c648309a81 100644 (file)
@@ -10,9 +10,8 @@
 
 //! Operations and constants for architecture-sized signed integers (`int` type)
 
-#![unstable]
+#![stable]
 #![doc(primitive = "int")]
 
 #[cfg(target_word_size = "32")] int_module! { int, 32 }
 #[cfg(target_word_size = "64")] int_module! { int, 64 }
-
index 00b9d88abe194d0746a730e9b1e4738a0843c578..522eab9180c86bce7bc2c85d575ccb143c922630 100644 (file)
@@ -24,13 +24,12 @@ macro_rules! int_module { ($T:ty, $bits:expr) => (
 
 // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
 // calling the `Bounded::min_value` function.
-#[unstable]
+#[stable]
 pub const MIN: $T = (-1 as $T) << (BITS - 1);
 // FIXME(#9837): Compute MIN like this so the high bits that shouldn't exist are 0.
 // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
 // calling the `Bounded::max_value` function.
-#[unstable]
+#[stable]
 pub const MAX: $T = !MIN;
 
 ) }
-
index 80d7b0b4ef374697696d148a9c945e1b3593cd50..35739f68da9697af17efd96a5321b23afc112a56 100644 (file)
@@ -10,8 +10,7 @@
 
 //! Operations and constants for architecture-sized unsigned integers (`uint` type)
 
-#![unstable]
+#![stable]
 #![doc(primitive = "uint")]
 
 uint_module! { uint, int, ::int::BITS }
-
index d79cf20fdfa6fe9967e6aab2118175d2485f83f9..82eca0d46598204a08f0aa63ce0f447207f76f10 100644 (file)
@@ -18,10 +18,9 @@ macro_rules! uint_module { ($T:ty, $T_SIGNED:ty, $bits:expr) => (
 #[unstable]
 pub const BYTES : uint = ($bits / 8);
 
-#[unstable]
+#[stable]
 pub const MIN: $T = 0 as $T;
-#[unstable]
+#[stable]
 pub const MAX: $T = 0 as $T - 1 as $T;
 
 ) }
-
index 314b47fc6476becb56a2a59cf473988def0cad10..8adbba8b94b87492f3d16cded48167159bda36b0 100644 (file)
@@ -819,6 +819,7 @@ fn next_back(&mut self) -> Option<&'a A> { self.inner.next_back() }
 
 impl<'a, A> ExactSizeIterator<&'a A> for Iter<'a, A> {}
 
+#[stable]
 impl<'a, A> Clone for Iter<'a, A> {
     fn clone(&self) -> Iter<'a, A> {
         Iter { inner: self.inner.clone() }
index 36c6b9572ea7011558a9f6c2e1aba5ecf4b1eafe..b226d4a6de45d1e5e0e6665a6910e21558db048f 100644 (file)
 use cmp::Ordering;
 use cmp::Ordering::{Less, Equal, Greater};
 
-pub use intrinsics::copy_memory;
+// FIXME #19649: instrinsic docs don't render, so these have no docs :(
+
+#[unstable]
 pub use intrinsics::copy_nonoverlapping_memory;
+
+#[unstable]
+pub use intrinsics::copy_memory;
+
+#[experimental = "uncertain about naming and semantics"]
 pub use intrinsics::set_memory;
 
-/// Create a null pointer.
+/// Creates a null raw pointer.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
 /// use std::ptr;
 #[unstable = "may need a different name after pending changes to pointer types"]
 pub fn null<T>() -> *const T { 0 as *const T }
 
-/// Create an unsafe mutable null pointer.
+/// Creates a null mutable raw pointer.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
 /// use std::ptr;
@@ -129,7 +136,12 @@ pub fn null<T>() -> *const T { 0 as *const T }
 #[unstable = "may need a different name after pending changes to pointer types"]
 pub fn null_mut<T>() -> *mut T { 0 as *mut T }
 
-/// Zeroes out `count * size_of::<T>` bytes of memory at `dst`
+/// Zeroes out `count * size_of::<T>` bytes of memory at `dst`. `count` may be `0`.
+///
+/// # Safety
+///
+/// Beyond accepting a raw pointer, this is unsafe because it will not drop the contents of `dst`,
+/// and may be used to create invalid instances of `T`.
 #[inline]
 #[experimental = "uncertain about naming and semantics"]
 #[allow(experimental)]
@@ -137,8 +149,13 @@ pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {
     set_memory(dst, 0, count);
 }
 
-/// Swap the values at two mutable locations of the same type, without
-/// deinitialising either. They may overlap.
+/// Swaps the values at two mutable locations of the same type, without
+/// deinitialising either. They may overlap, unlike `mem::swap` which is otherwise
+/// equivalent.
+///
+/// # Safety
+///
+/// This is only unsafe because it accepts a raw pointer.
 #[inline]
 #[unstable]
 pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
@@ -156,8 +173,13 @@ pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
     mem::forget(tmp);
 }
 
-/// Replace the value at a mutable location with a new one, returning the old
-/// value, without deinitialising either.
+/// Replaces the value at `dest` with `src`, returning the old
+/// value, without dropping either.
+///
+/// # Safety
+///
+/// This is only unsafe because it accepts a raw pointer.
+/// Otherwise, this operation is identical to `mem::replace`.
 #[inline]
 #[unstable]
 pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
@@ -165,7 +187,17 @@ pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
     src
 }
 
-/// Reads the value from `*src` and returns it.
+/// Reads the value from `src` without dropping it. This leaves the
+/// memory in `src` unchanged.
+///
+/// # Safety
+///
+/// Beyond accepting a raw pointer, this is unsafe because it semantically
+/// moves the value out of `src` without preventing further usage of `src`.
+/// If `T` is not `Copy`, then care must be taken to ensure that the value at
+/// `src` is not used before the data is overwritten again (e.g. with `write`,
+/// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use
+/// because it will attempt to drop the value previously at `*src`.
 #[inline(always)]
 #[unstable]
 pub unsafe fn read<T>(src: *const T) -> T {
@@ -174,8 +206,11 @@ pub unsafe fn read<T>(src: *const T) -> T {
     tmp
 }
 
-/// Reads the value from `*src` and nulls it out.
-/// This currently prevents destructors from executing.
+/// Reads the value from `src` and nulls it out without dropping it.
+///
+/// # Safety
+///
+/// This is unsafe for the same reasons that `read` is unsafe.
 #[inline(always)]
 #[experimental]
 #[allow(experimental)]
@@ -189,12 +224,17 @@ pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
     tmp
 }
 
-/// Unsafely overwrite a memory location with the given value without destroying
+/// Overwrites a memory location with the given value without reading or dropping
 /// the old value.
 ///
-/// This operation is unsafe because it does not destroy the previous value
-/// contained at the location `dst`. This could leak allocations or resources,
-/// so care must be taken to previously deallocate the value at `dst`.
+/// # Safety
+///
+/// Beyond accepting a raw pointer, this operation is unsafe because it does
+/// not drop the contents of `dst`. This could leak allocations or resources,
+/// so care must be taken not to overwrite an object that should be dropped.
+///
+/// This is appropriate for initializing uninitialized memory, or overwritting memory
+/// that has previously been `read` from.
 #[inline]
 #[unstable]
 pub unsafe fn write<T>(dst: *mut T, src: T) {
@@ -203,39 +243,47 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
 
 /// Methods on raw pointers
 pub trait RawPtr<T> {
-    /// Returns the null pointer.
+    /// Returns a null raw pointer.
     fn null() -> Self;
 
-    /// Returns true if the pointer is equal to the null pointer.
+    /// Returns true if the pointer is null.
     fn is_null(&self) -> bool;
 
-    /// Returns true if the pointer is not equal to the null pointer.
+    /// Returns true if the pointer is not null.
     fn is_not_null(&self) -> bool { !self.is_null() }
 
-    /// Returns the value of this pointer (ie, the address it points to)
+    /// Returns the address of the pointer.
     fn to_uint(&self) -> uint;
 
     /// Returns `None` if the pointer is null, or else returns a reference to the
     /// value wrapped in `Some`.
     ///
-    /// # Safety Notes
+    /// # Safety
     ///
     /// While this method and its mutable counterpart are useful for null-safety,
     /// it is important to note that this is still an unsafe operation because
     /// the returned value could be pointing to invalid memory.
     unsafe fn as_ref<'a>(&self) -> Option<&'a T>;
 
-    /// Calculates the offset from a pointer. The offset *must* be in-bounds of
-    /// the object, or one-byte-past-the-end.  `count` is in units of T; e.g. a
+    /// Calculates the offset from a pointer. `count` is in units of T; e.g. a
     /// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes.
+    ///
+    /// # Safety
+    ///
+    /// The offset must be in-bounds of the object, or one-byte-past-the-end. Otherwise
+    /// `offset` invokes Undefined Behaviour, regardless of whether the pointer is used.
     unsafe fn offset(self, count: int) -> Self;
 }
 
 /// Methods on mutable raw pointers
 pub trait RawMutPtr<T>{
     /// Returns `None` if the pointer is null, or else returns a mutable reference
-    /// to the value wrapped in `Some`. As with `as_ref`, this is unsafe because
-    /// it cannot verify the validity of the returned pointer.
+    /// to the value wrapped in `Some`.
+    ///
+    /// # Safety
+    ///
+    /// As with `as_ref`, this is unsafe because it cannot verify the validity
+    /// of the returned pointer.
     unsafe fn as_mut<'a>(&self) -> Option<&'a mut T>;
 }
 
@@ -340,6 +388,7 @@ fn equiv(&self, other: &*const T) -> bool {
     }
 }
 
+#[stable]
 impl<T> Clone for *const T {
     #[inline]
     fn clone(&self) -> *const T {
@@ -347,6 +396,7 @@ fn clone(&self) -> *const T {
     }
 }
 
+#[stable]
 impl<T> Clone for *mut T {
     #[inline]
     fn clone(&self) -> *mut T {
@@ -451,4 +501,3 @@ fn gt(&self, other: &*mut T) -> bool { *self > *other }
     #[inline]
     fn ge(&self, other: &*mut T) -> bool { *self >= *other }
 }
-
index 00a2a3d5854d879fa60ed9a048652ac84be36c26..b59734a7d9881052bc27c1e61c898ed264efb77f 100644 (file)
 
 #![stable]
 
-use self::Result::*;
+use self::Result::{Ok, Err};
 
-use std::fmt::Show;
-use slice;
-use slice::AsSlice;
+use clone::Clone;
+use fmt::Show;
 use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, ExactSizeIterator};
-use option::Option;
-use option::Option::{None, Some};
 use ops::{FnMut, FnOnce};
+use option::Option::{mod, None, Some};
+use slice::AsSlice;
+use slice;
 
 /// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
 ///
 #[stable]
 pub enum Result<T, E> {
     /// Contains the success value
+    #[stable]
     Ok(T),
 
     /// Contains the error value
+    #[stable]
     Err(E)
 }
 
@@ -258,6 +260,7 @@ pub enum Result<T, E> {
 // Type implementation
 /////////////////////////////////////////////////////////////////////////////
 
+#[stable]
 impl<T, E> Result<T, E> {
     /////////////////////////////////////////////////////////////////////////
     // Querying the contained values
@@ -300,7 +303,6 @@ pub fn is_err(&self) -> bool {
         !self.is_ok()
     }
 
-
     /////////////////////////////////////////////////////////////////////////
     // Adapter for each variant
     /////////////////////////////////////////////////////////////////////////
@@ -369,7 +371,7 @@ pub fn err(self) -> Option<E> {
     /// ```
     #[inline]
     #[stable]
-    pub fn as_ref<'r>(&'r self) -> Result<&'r T, &'r E> {
+    pub fn as_ref(&self) -> Result<&T, &E> {
         match *self {
             Ok(ref x) => Ok(x),
             Err(ref x) => Err(x),
@@ -395,8 +397,8 @@ pub fn as_ref<'r>(&'r self) -> Result<&'r T, &'r E> {
     /// assert_eq!(x.unwrap_err(), 0);
     /// ```
     #[inline]
-    #[unstable = "waiting for mut conventions"]
-    pub fn as_mut<'r>(&'r mut self) -> Result<&'r mut T, &'r mut E> {
+    #[stable]
+    pub fn as_mut(&mut self) -> Result<&mut T, &mut E> {
         match *self {
             Ok(ref mut x) => Ok(x),
             Err(ref mut x) => Err(x),
@@ -420,7 +422,7 @@ pub fn as_mut<'r>(&'r mut self) -> Result<&'r mut T, &'r mut E> {
     /// ```
     #[inline]
     #[unstable = "waiting for mut conventions"]
-    pub fn as_mut_slice<'r>(&'r mut self) -> &'r mut [T] {
+    pub fn as_mut_slice(&mut self) -> &mut [T] {
         match *self {
             Ok(ref mut x) => slice::mut_ref_slice(x),
             Err(_) => {
@@ -465,11 +467,11 @@ pub fn as_mut_slice<'r>(&'r mut self) -> &'r mut [T] {
     /// assert!(sum == 10);
     /// ```
     #[inline]
-    #[unstable = "waiting for unboxed closures"]
+    #[stable]
     pub fn map<U, F: FnOnce(T) -> U>(self, op: F) -> Result<U,E> {
         match self {
-          Ok(t) => Ok(op(t)),
-          Err(e) => Err(e)
+            Ok(t) => Ok(op(t)),
+            Err(e) => Err(e)
         }
     }
 
@@ -491,15 +493,14 @@ pub fn map<U, F: FnOnce(T) -> U>(self, op: F) -> Result<U,E> {
     /// assert_eq!(x.map_err(stringify), Err("error code: 13".to_string()));
     /// ```
     #[inline]
-    #[unstable = "waiting for unboxed closures"]
+    #[stable]
     pub fn map_err<F, O: FnOnce(E) -> F>(self, op: O) -> Result<T,F> {
         match self {
-          Ok(t) => Ok(t),
-          Err(e) => Err(op(e))
+            Ok(t) => Ok(t),
+            Err(e) => Err(op(e))
         }
     }
 
-
     /////////////////////////////////////////////////////////////////////////
     // Iterator constructors
     /////////////////////////////////////////////////////////////////////////
@@ -516,9 +517,9 @@ pub fn map_err<F, O: FnOnce(E) -> F>(self, op: O) -> Result<T,F> {
     /// assert_eq!(x.iter().next(), None);
     /// ```
     #[inline]
-    #[unstable = "waiting for iterator conventions"]
-    pub fn iter<'r>(&'r self) -> Item<&'r T> {
-        Item{opt: self.as_ref().ok()}
+    #[stable]
+    pub fn iter(&self) -> Iter<T> {
+        Iter { inner: self.as_ref().ok() }
     }
 
     /// Returns a mutable iterator over the possibly contained value.
@@ -537,9 +538,9 @@ pub fn iter<'r>(&'r self) -> Item<&'r T> {
     /// assert_eq!(x.iter_mut().next(), None);
     /// ```
     #[inline]
-    #[unstable = "waiting for iterator conventions"]
-    pub fn iter_mut<'r>(&'r mut self) -> Item<&'r mut T> {
-        Item{opt: self.as_mut().ok()}
+    #[stable]
+    pub fn iter_mut(&mut self) -> IterMut<T> {
+        IterMut { inner: self.as_mut().ok() }
     }
 
     /// Returns a consuming iterator over the possibly contained value.
@@ -556,9 +557,9 @@ pub fn iter_mut<'r>(&'r mut self) -> Item<&'r mut T> {
     /// assert_eq!(v, vec![]);
     /// ```
     #[inline]
-    #[unstable = "waiting for iterator conventions"]
-    pub fn into_iter(self) -> Item<T> {
-        Item{opt: self.ok()}
+    #[stable]
+    pub fn into_iter(self) -> IntoIter<T> {
+        IntoIter { inner: self.ok() }
     }
 
     ////////////////////////////////////////////////////////////////////////
@@ -611,7 +612,7 @@ pub fn and<U>(self, res: Result<U, E>) -> Result<U, E> {
     /// assert_eq!(Err(3).and_then(sq).and_then(sq), Err(3));
     /// ```
     #[inline]
-    #[unstable = "waiting for unboxed closures"]
+    #[stable]
     pub fn and_then<U, F: FnOnce(T) -> Result<U, E>>(self, op: F) -> Result<U, E> {
         match self {
             Ok(t) => op(t),
@@ -665,7 +666,7 @@ pub fn or(self, res: Result<T, E>) -> Result<T, E> {
     /// assert_eq!(Err(3).or_else(err).or_else(err), Err(3));
     /// ```
     #[inline]
-    #[unstable = "waiting for unboxed closures"]
+    #[stable]
     pub fn or_else<F, O: FnOnce(E) -> Result<T, F>>(self, op: O) -> Result<T, F> {
         match self {
             Ok(t) => Ok(t),
@@ -687,7 +688,7 @@ pub fn or_else<F, O: FnOnce(E) -> Result<T, F>>(self, op: O) -> Result<T, F> {
     /// assert_eq!(x.unwrap_or(optb), optb);
     /// ```
     #[inline]
-    #[unstable = "waiting for conventions"]
+    #[stable]
     pub fn unwrap_or(self, optb: T) -> T {
         match self {
             Ok(t) => t,
@@ -707,7 +708,7 @@ pub fn unwrap_or(self, optb: T) -> T {
     /// assert_eq!(Err("foo").unwrap_or_else(count), 3u);
     /// ```
     #[inline]
-    #[unstable = "waiting for conventions"]
+    #[stable]
     pub fn unwrap_or_else<F: FnOnce(E) -> T>(self, op: F) -> T {
         match self {
             Ok(t) => t,
@@ -716,6 +717,7 @@ pub fn unwrap_or_else<F: FnOnce(E) -> T>(self, op: F) -> T {
     }
 }
 
+#[stable]
 impl<T, E: Show> Result<T, E> {
     /// Unwraps a result, yielding the content of an `Ok`.
     ///
@@ -736,7 +738,7 @@ impl<T, E: Show> Result<T, E> {
     /// x.unwrap(); // panics with `emergency failure`
     /// ```
     #[inline]
-    #[unstable = "waiting for conventions"]
+    #[stable]
     pub fn unwrap(self) -> T {
         match self {
             Ok(t) => t,
@@ -746,6 +748,7 @@ pub fn unwrap(self) -> T {
     }
 }
 
+#[stable]
 impl<T: Show, E> Result<T, E> {
     /// Unwraps a result, yielding the content of an `Err`.
     ///
@@ -766,7 +769,7 @@ impl<T: Show, E> Result<T, E> {
     /// assert_eq!(x.unwrap_err(), "emergency failure");
     /// ```
     #[inline]
-    #[unstable = "waiting for conventions"]
+    #[stable]
     pub fn unwrap_err(self) -> E {
         match self {
             Ok(t) =>
@@ -797,42 +800,75 @@ fn as_slice<'a>(&'a self) -> &'a [T] {
 }
 
 /////////////////////////////////////////////////////////////////////////////
-// The Result Iterator
+// The Result Iterators
 /////////////////////////////////////////////////////////////////////////////
 
-/// A `Result` iterator that yields either one or zero elements
-///
-/// The `Item` iterator is returned by the `iter`, `iter_mut` and `into_iter`
-/// methods on `Result`.
-#[deriving(Clone)]
-#[unstable = "waiting for iterator conventions"]
-pub struct Item<T> {
-    opt: Option<T>
-}
+/// An iterator over a reference to the `Ok` variant of a `Result`.
+#[stable]
+pub struct Iter<'a, T: 'a> { inner: Option<&'a T> }
 
-impl<T> Iterator<T> for Item<T> {
+impl<'a, T> Iterator<&'a T> for Iter<'a, T> {
     #[inline]
-    fn next(&mut self) -> Option<T> {
-        self.opt.take()
+    fn next(&mut self) -> Option<&'a T> { self.inner.take() }
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        let n = if self.inner.is_some() {1} else {0};
+        (n, Some(n))
     }
+}
+
+impl<'a, T> DoubleEndedIterator<&'a T> for Iter<'a, T> {
+    #[inline]
+    fn next_back(&mut self) -> Option<&'a T> { self.inner.take() }
+}
+
+impl<'a, T> ExactSizeIterator<&'a T> for Iter<'a, T> {}
+
+impl<'a, T> Clone for Iter<'a, T> {
+    fn clone(&self) -> Iter<'a, T> { Iter { inner: self.inner } }
+}
+
+/// An iterator over a mutable reference to the `Ok` variant of a `Result`.
+#[stable]
+pub struct IterMut<'a, T: 'a> { inner: Option<&'a mut T> }
 
+impl<'a, T> Iterator<&'a mut T> for IterMut<'a, T> {
+    #[inline]
+    fn next(&mut self) -> Option<&'a mut T> { self.inner.take() }
     #[inline]
     fn size_hint(&self) -> (uint, Option<uint>) {
-        match self.opt {
-            Some(_) => (1, Some(1)),
-            None => (0, Some(0)),
-        }
+        let n = if self.inner.is_some() {1} else {0};
+        (n, Some(n))
     }
 }
 
-impl<A> DoubleEndedIterator<A> for Item<A> {
+impl<'a, T> DoubleEndedIterator<&'a mut T> for IterMut<'a, T> {
     #[inline]
-    fn next_back(&mut self) -> Option<A> {
-        self.opt.take()
+    fn next_back(&mut self) -> Option<&'a mut T> { self.inner.take() }
+}
+
+impl<'a, T> ExactSizeIterator<&'a mut T> for IterMut<'a, T> {}
+
+/// An iterator over the value in a `Ok` variant of a `Result`.
+#[stable]
+pub struct IntoIter<T> { inner: Option<T> }
+
+impl<T> Iterator<T> for IntoIter<T> {
+    #[inline]
+    fn next(&mut self) -> Option<T> { self.inner.take() }
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        let n = if self.inner.is_some() {1} else {0};
+        (n, Some(n))
     }
 }
 
-impl<A> ExactSizeIterator<A> for Item<A> {}
+impl<T> DoubleEndedIterator<T> for IntoIter<T> {
+    #[inline]
+    fn next_back(&mut self) -> Option<T> { self.inner.take() }
+}
+
+impl<T> ExactSizeIterator<T> for IntoIter<T> {}
 
 /////////////////////////////////////////////////////////////////////////////
 // FromIterator
index f5d117bca9fc8f45fd250b5cf4113f090e45e6c1..efc92429afdf1e5f7b0717b70f37de03b5cdbfa2 100644 (file)
@@ -781,7 +781,7 @@ impl<'a,T> Copy for Items<'a,T> {}
 #[experimental = "needs review"]
 impl<'a, T> ExactSizeIterator<&'a T> for Items<'a, T> {}
 
-#[experimental = "needs review"]
+#[stable]
 impl<'a, T> Clone for Items<'a, T> {
     fn clone(&self) -> Items<'a, T> { *self }
 }
@@ -893,6 +893,7 @@ pub struct Splits<'a, T:'a, P> where P: FnMut(&T) -> bool {
 }
 
 // FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+#[stable]
 impl<'a, T, P> Clone for Splits<'a, T, P> where P: Clone + FnMut(&T) -> bool {
     fn clone(&self) -> Splits<'a, T, P> {
         Splits {
@@ -1550,4 +1551,3 @@ macro_rules! impl_int_slice {
 impl_int_slice! { u32,  i32 }
 impl_int_slice! { u64,  i64 }
 impl_int_slice! { uint, int }
-
diff --git a/src/libcore/tuple.rs b/src/libcore/tuple.rs
new file mode 100644 (file)
index 0000000..89aed14
--- /dev/null
@@ -0,0 +1,328 @@
+// 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.
+
+//! Operations on tuples
+//!
+//! To access a single element of a tuple one can use the following
+//! methods:
+//!
+//! * `valN` - returns a value of _N_-th element
+//! * `refN` - returns a reference to _N_-th element
+//! * `mutN` - returns a mutable reference to _N_-th element
+//!
+//! Indexing starts from zero, so `val0` returns first value, `val1`
+//! returns second value, and so on. In general, a tuple with _S_
+//! elements provides aforementioned methods suffixed with numbers
+//! from `0` to `S-1`. Traits which contain these methods are
+//! implemented for tuples with up to 12 elements.
+//!
+//! If every type inside a tuple implements one of the following
+//! traits, then a tuple itself also implements it.
+//!
+//! * `Clone`
+//! * `PartialEq`
+//! * `Eq`
+//! * `PartialOrd`
+//! * `Ord`
+//! * `Default`
+//!
+//! # Examples
+//!
+//! Using methods:
+//!
+//! ```
+//! #[allow(deprecated)]
+//! # fn main() {
+//! let pair = ("pi", 3.14f64);
+//! assert_eq!(pair.val0(), "pi");
+//! assert_eq!(pair.val1(), 3.14f64);
+//! # }
+//! ```
+//!
+//! Using traits implemented for tuples:
+//!
+//! ```
+//! use std::default::Default;
+//!
+//! let a = (1i, 2i);
+//! let b = (3i, 4i);
+//! assert!(a != b);
+//!
+//! let c = b.clone();
+//! assert!(b == c);
+//!
+//! let d : (u32, f32) = Default::default();
+//! assert_eq!(d, (0u32, 0.0f32));
+//! ```
+
+#![stable]
+
+#[unstable = "this is just a documentation module and should not be part \
+              of the public api"]
+
+use clone::Clone;
+use cmp::*;
+use default::Default;
+use option::Option;
+use option::Option::Some;
+
+// FIXME(#19630) Remove this work-around
+macro_rules! e {
+    ($e:expr) => { $e }
+}
+
+// macro for implementing n-ary tuple functions and operations
+macro_rules! tuple_impls {
+    ($(
+        $Tuple:ident {
+            $(($valN:ident, $refN:ident, $mutN:ident, $idx:tt) -> $T:ident)+
+        }
+    )+) => {
+        $(
+            #[allow(missing_docs)]
+            #[deprecated]
+            pub trait $Tuple<$($T),+> {
+                $(
+                    #[deprecated = "use tuple indexing: `tuple.N`"]
+                    fn $valN(self) -> $T;
+                    #[deprecated = "use tuple indexing: `&tuple.N`"]
+                    fn $refN<'a>(&'a self) -> &'a $T;
+                    #[deprecated = "use tuple indexing: `&mut tuple.N`"]
+                    fn $mutN<'a>(&'a mut self) -> &'a mut $T;
+                 )+
+            }
+
+            impl<$($T),+> $Tuple<$($T),+> for ($($T,)+) {
+                $(
+                    #[inline]
+                    #[allow(unused_variables)]
+                    #[deprecated = "use tuple indexing: `tuple.N`"]
+                    fn $valN(self) -> $T {
+                        e!(self.$idx)
+                    }
+
+                    #[inline]
+                    #[allow(unused_variables)]
+                    #[deprecated = "use tuple indexing: `&tuple.N`"]
+                    fn $refN<'a>(&'a self) -> &'a $T {
+                        e!(&self.$idx)
+                    }
+
+                    #[inline]
+                    #[allow(unused_variables)]
+                    #[deprecated = "use tuple indexing: &mut tuple.N"]
+                    fn $mutN<'a>(&'a mut self) -> &'a mut $T {
+                        e!(&mut self.$idx)
+                    }
+                )+
+            }
+
+            #[stable]
+            impl<$($T:Clone),+> Clone for ($($T,)+) {
+                fn clone(&self) -> ($($T,)+) {
+                    ($(e!(self.$idx.clone()),)+)
+                }
+            }
+
+            #[unstable = "waiting for PartialEq to stabilize"]
+            impl<$($T:PartialEq),+> PartialEq for ($($T,)+) {
+                #[inline]
+                fn eq(&self, other: &($($T,)+)) -> bool {
+                    e!($(self.$idx == other.$idx)&&+)
+                }
+                #[inline]
+                fn ne(&self, other: &($($T,)+)) -> bool {
+                    e!($(self.$idx != other.$idx)||+)
+                }
+            }
+
+            #[unstable = "waiting for Eq to stabilize"]
+            impl<$($T:Eq),+> Eq for ($($T,)+) {}
+
+            #[unstable = "waiting for PartialOrd to stabilize"]
+            impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+) {
+                #[inline]
+                fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
+                    lexical_partial_cmp!($(self.$idx, other.$idx),+)
+                }
+                #[inline]
+                fn lt(&self, other: &($($T,)+)) -> bool {
+                    lexical_ord!(lt, $(self.$idx, other.$idx),+)
+                }
+                #[inline]
+                fn le(&self, other: &($($T,)+)) -> bool {
+                    lexical_ord!(le, $(self.$idx, other.$idx),+)
+                }
+                #[inline]
+                fn ge(&self, other: &($($T,)+)) -> bool {
+                    lexical_ord!(ge, $(self.$idx, other.$idx),+)
+                }
+                #[inline]
+                fn gt(&self, other: &($($T,)+)) -> bool {
+                    lexical_ord!(gt, $(self.$idx, other.$idx),+)
+                }
+            }
+
+            #[unstable = "waiting for Ord to stabilize"]
+            impl<$($T:Ord),+> Ord for ($($T,)+) {
+                #[inline]
+                fn cmp(&self, other: &($($T,)+)) -> Ordering {
+                    lexical_cmp!($(self.$idx, other.$idx),+)
+                }
+            }
+
+            #[stable]
+            impl<$($T:Default),+> Default for ($($T,)+) {
+                #[stable]
+                #[inline]
+                fn default() -> ($($T,)+) {
+                    ($({ let x: $T = Default::default(); x},)+)
+                }
+            }
+        )+
+    }
+}
+
+// Constructs an expression that performs a lexical ordering using method $rel.
+// The values are interleaved, so the macro invocation for
+// `(a1, a2, a3) < (b1, b2, b3)` would be `lexical_ord!(lt, a1, b1, a2, b2,
+// a3, b3)` (and similarly for `lexical_cmp`)
+macro_rules! lexical_ord {
+    ($rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
+        if $a != $b { lexical_ord!($rel, $a, $b) }
+        else { lexical_ord!($rel, $($rest_a, $rest_b),+) }
+    };
+    ($rel: ident, $a:expr, $b:expr) => { ($a) . $rel (& $b) };
+}
+
+macro_rules! lexical_partial_cmp {
+    ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
+        match ($a).partial_cmp(&$b) {
+            Some(Equal) => lexical_partial_cmp!($($rest_a, $rest_b),+),
+            ordering   => ordering
+        }
+    };
+    ($a:expr, $b:expr) => { ($a).partial_cmp(&$b) };
+}
+
+macro_rules! lexical_cmp {
+    ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
+        match ($a).cmp(&$b) {
+            Equal => lexical_cmp!($($rest_a, $rest_b),+),
+            ordering   => ordering
+        }
+    };
+    ($a:expr, $b:expr) => { ($a).cmp(&$b) };
+}
+
+tuple_impls! {
+    Tuple1 {
+        (val0, ref0, mut0, 0) -> A
+    }
+    Tuple2 {
+        (val0, ref0, mut0, 0) -> A
+        (val1, ref1, mut1, 1) -> B
+    }
+    Tuple3 {
+        (val0, ref0, mut0, 0) -> A
+        (val1, ref1, mut1, 1) -> B
+        (val2, ref2, mut2, 2) -> C
+    }
+    Tuple4 {
+        (val0, ref0, mut0, 0) -> A
+        (val1, ref1, mut1, 1) -> B
+        (val2, ref2, mut2, 2) -> C
+        (val3, ref3, mut3, 3) -> D
+    }
+    Tuple5 {
+        (val0, ref0, mut0, 0) -> A
+        (val1, ref1, mut1, 1) -> B
+        (val2, ref2, mut2, 2) -> C
+        (val3, ref3, mut3, 3) -> D
+        (val4, ref4, mut4, 4) -> E
+    }
+    Tuple6 {
+        (val0, ref0, mut0, 0) -> A
+        (val1, ref1, mut1, 1) -> B
+        (val2, ref2, mut2, 2) -> C
+        (val3, ref3, mut3, 3) -> D
+        (val4, ref4, mut4, 4) -> E
+        (val5, ref5, mut5, 5) -> F
+    }
+    Tuple7 {
+        (val0, ref0, mut0, 0) -> A
+        (val1, ref1, mut1, 1) -> B
+        (val2, ref2, mut2, 2) -> C
+        (val3, ref3, mut3, 3) -> D
+        (val4, ref4, mut4, 4) -> E
+        (val5, ref5, mut5, 5) -> F
+        (val6, ref6, mut6, 6) -> G
+    }
+    Tuple8 {
+        (val0, ref0, mut0, 0) -> A
+        (val1, ref1, mut1, 1) -> B
+        (val2, ref2, mut2, 2) -> C
+        (val3, ref3, mut3, 3) -> D
+        (val4, ref4, mut4, 4) -> E
+        (val5, ref5, mut5, 5) -> F
+        (val6, ref6, mut6, 6) -> G
+        (val7, ref7, mut7, 7) -> H
+    }
+    Tuple9 {
+        (val0, ref0, mut0, 0) -> A
+        (val1, ref1, mut1, 1) -> B
+        (val2, ref2, mut2, 2) -> C
+        (val3, ref3, mut3, 3) -> D
+        (val4, ref4, mut4, 4) -> E
+        (val5, ref5, mut5, 5) -> F
+        (val6, ref6, mut6, 6) -> G
+        (val7, ref7, mut7, 7) -> H
+        (val8, ref8, mut8, 8) -> I
+    }
+    Tuple10 {
+        (val0, ref0, mut0, 0) -> A
+        (val1, ref1, mut1, 1) -> B
+        (val2, ref2, mut2, 2) -> C
+        (val3, ref3, mut3, 3) -> D
+        (val4, ref4, mut4, 4) -> E
+        (val5, ref5, mut5, 5) -> F
+        (val6, ref6, mut6, 6) -> G
+        (val7, ref7, mut7, 7) -> H
+        (val8, ref8, mut8, 8) -> I
+        (val9, ref9, mut9, 9) -> J
+    }
+    Tuple11 {
+        (val0, ref0, mut0, 0) -> A
+        (val1, ref1, mut1, 1) -> B
+        (val2, ref2, mut2, 2) -> C
+        (val3, ref3, mut3, 3) -> D
+        (val4, ref4, mut4, 4) -> E
+        (val5, ref5, mut5, 5) -> F
+        (val6, ref6, mut6, 6) -> G
+        (val7, ref7, mut7, 7) -> H
+        (val8, ref8, mut8, 8) -> I
+        (val9, ref9, mut9, 9) -> J
+        (val10, ref10, mut10, 10) -> K
+    }
+    Tuple12 {
+        (val0, ref0, mut0, 0) -> A
+        (val1, ref1, mut1, 1) -> B
+        (val2, ref2, mut2, 2) -> C
+        (val3, ref3, mut3, 3) -> D
+        (val4, ref4, mut4, 4) -> E
+        (val5, ref5, mut5, 5) -> F
+        (val6, ref6, mut6, 6) -> G
+        (val7, ref7, mut7, 7) -> H
+        (val8, ref8, mut8, 8) -> I
+        (val9, ref9, mut9, 9) -> J
+        (val10, ref10, mut10, 10) -> K
+        (val11, ref11, mut11, 11) -> L
+    }
+}
diff --git a/src/libcore/tuple/mod.rs b/src/libcore/tuple/mod.rs
deleted file mode 100644 (file)
index 5ea84f7..0000000
+++ /dev/null
@@ -1,331 +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.
-
-//! Operations on tuples
-//!
-//! To access a single element of a tuple one can use the following
-//! methods:
-//!
-//! * `valN` - returns a value of _N_-th element
-//! * `refN` - returns a reference to _N_-th element
-//! * `mutN` - returns a mutable reference to _N_-th element
-//!
-//! Indexing starts from zero, so `val0` returns first value, `val1`
-//! returns second value, and so on. In general, a tuple with _S_
-//! elements provides aforementioned methods suffixed with numbers
-//! from `0` to `S-1`. Traits which contain these methods are
-//! implemented for tuples with up to 12 elements.
-//!
-//! If every type inside a tuple implements one of the following
-//! traits, then a tuple itself also implements it.
-//!
-//! * `Clone`
-//! * `PartialEq`
-//! * `Eq`
-//! * `PartialOrd`
-//! * `Ord`
-//! * `Default`
-//!
-//! # Examples
-//!
-//! Using methods:
-//!
-//! ```
-//! #[allow(deprecated)]
-//! # fn main() {
-//! let pair = ("pi", 3.14f64);
-//! assert_eq!(pair.val0(), "pi");
-//! assert_eq!(pair.val1(), 3.14f64);
-//! # }
-//! ```
-//!
-//! Using traits implemented for tuples:
-//!
-//! ```
-//! use std::default::Default;
-//!
-//! let a = (1i, 2i);
-//! let b = (3i, 4i);
-//! assert!(a != b);
-//!
-//! let c = b.clone();
-//! assert!(b == c);
-//!
-//! let d : (u32, f32) = Default::default();
-//! assert_eq!(d, (0u32, 0.0f32));
-//! ```
-
-#![doc(primitive = "tuple")]
-#![stable]
-
-#[unstable = "this is just a documentation module and should not be part \
-              of the public api"]
-pub use unit;
-
-use clone::Clone;
-use cmp::*;
-use default::Default;
-use option::Option;
-use option::Option::Some;
-
-// FIXME(#19630) Remove this work-around
-macro_rules! e {
-    ($e:expr) => { $e }
-}
-
-// macro for implementing n-ary tuple functions and operations
-macro_rules! tuple_impls {
-    ($(
-        $Tuple:ident {
-            $(($valN:ident, $refN:ident, $mutN:ident, $idx:tt) -> $T:ident)+
-        }
-    )+) => {
-        $(
-            #[allow(missing_docs)]
-            #[deprecated]
-            pub trait $Tuple<$($T),+> {
-                $(
-                    #[deprecated = "use tuple indexing: `tuple.N`"]
-                    fn $valN(self) -> $T;
-                    #[deprecated = "use tuple indexing: `&tuple.N`"]
-                    fn $refN<'a>(&'a self) -> &'a $T;
-                    #[deprecated = "use tuple indexing: `&mut tuple.N`"]
-                    fn $mutN<'a>(&'a mut self) -> &'a mut $T;
-                 )+
-            }
-
-            impl<$($T),+> $Tuple<$($T),+> for ($($T,)+) {
-                $(
-                    #[inline]
-                    #[allow(unused_variables)]
-                    #[deprecated = "use tuple indexing: `tuple.N`"]
-                    fn $valN(self) -> $T {
-                        e!(self.$idx)
-                    }
-
-                    #[inline]
-                    #[allow(unused_variables)]
-                    #[deprecated = "use tuple indexing: `&tuple.N`"]
-                    fn $refN<'a>(&'a self) -> &'a $T {
-                        e!(&self.$idx)
-                    }
-
-                    #[inline]
-                    #[allow(unused_variables)]
-                    #[deprecated = "use tuple indexing: &mut tuple.N"]
-                    fn $mutN<'a>(&'a mut self) -> &'a mut $T {
-                        e!(&mut self.$idx)
-                    }
-                )+
-            }
-
-            #[unstable = "waiting for Clone to stabilize"]
-            impl<$($T:Clone),+> Clone for ($($T,)+) {
-                fn clone(&self) -> ($($T,)+) {
-                    ($(e!(self.$idx.clone()),)+)
-                }
-            }
-
-            #[unstable = "waiting for PartialEq to stabilize"]
-            impl<$($T:PartialEq),+> PartialEq for ($($T,)+) {
-                #[inline]
-                fn eq(&self, other: &($($T,)+)) -> bool {
-                    e!($(self.$idx == other.$idx)&&+)
-                }
-                #[inline]
-                fn ne(&self, other: &($($T,)+)) -> bool {
-                    e!($(self.$idx != other.$idx)||+)
-                }
-            }
-
-            #[unstable = "waiting for Eq to stabilize"]
-            impl<$($T:Eq),+> Eq for ($($T,)+) {}
-
-            #[unstable = "waiting for PartialOrd to stabilize"]
-            impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+) {
-                #[inline]
-                fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
-                    lexical_partial_cmp!($(self.$idx, other.$idx),+)
-                }
-                #[inline]
-                fn lt(&self, other: &($($T,)+)) -> bool {
-                    lexical_ord!(lt, $(self.$idx, other.$idx),+)
-                }
-                #[inline]
-                fn le(&self, other: &($($T,)+)) -> bool {
-                    lexical_ord!(le, $(self.$idx, other.$idx),+)
-                }
-                #[inline]
-                fn ge(&self, other: &($($T,)+)) -> bool {
-                    lexical_ord!(ge, $(self.$idx, other.$idx),+)
-                }
-                #[inline]
-                fn gt(&self, other: &($($T,)+)) -> bool {
-                    lexical_ord!(gt, $(self.$idx, other.$idx),+)
-                }
-            }
-
-            #[unstable = "waiting for Ord to stabilize"]
-            impl<$($T:Ord),+> Ord for ($($T,)+) {
-                #[inline]
-                fn cmp(&self, other: &($($T,)+)) -> Ordering {
-                    lexical_cmp!($(self.$idx, other.$idx),+)
-                }
-            }
-
-            #[stable]
-            impl<$($T:Default),+> Default for ($($T,)+) {
-                #[stable]
-                #[inline]
-                fn default() -> ($($T,)+) {
-                    ($({ let x: $T = Default::default(); x},)+)
-                }
-            }
-        )+
-    }
-}
-
-// Constructs an expression that performs a lexical ordering using method $rel.
-// The values are interleaved, so the macro invocation for
-// `(a1, a2, a3) < (b1, b2, b3)` would be `lexical_ord!(lt, a1, b1, a2, b2,
-// a3, b3)` (and similarly for `lexical_cmp`)
-macro_rules! lexical_ord {
-    ($rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
-        if $a != $b { lexical_ord!($rel, $a, $b) }
-        else { lexical_ord!($rel, $($rest_a, $rest_b),+) }
-    };
-    ($rel: ident, $a:expr, $b:expr) => { ($a) . $rel (& $b) };
-}
-
-macro_rules! lexical_partial_cmp {
-    ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
-        match ($a).partial_cmp(&$b) {
-            Some(Equal) => lexical_partial_cmp!($($rest_a, $rest_b),+),
-            ordering   => ordering
-        }
-    };
-    ($a:expr, $b:expr) => { ($a).partial_cmp(&$b) };
-}
-
-macro_rules! lexical_cmp {
-    ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
-        match ($a).cmp(&$b) {
-            Equal => lexical_cmp!($($rest_a, $rest_b),+),
-            ordering   => ordering
-        }
-    };
-    ($a:expr, $b:expr) => { ($a).cmp(&$b) };
-}
-
-tuple_impls! {
-    Tuple1 {
-        (val0, ref0, mut0, 0) -> A
-    }
-    Tuple2 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-    }
-    Tuple3 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-    }
-    Tuple4 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-    }
-    Tuple5 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-    }
-    Tuple6 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-        (val5, ref5, mut5, 5) -> F
-    }
-    Tuple7 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-        (val5, ref5, mut5, 5) -> F
-        (val6, ref6, mut6, 6) -> G
-    }
-    Tuple8 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-        (val5, ref5, mut5, 5) -> F
-        (val6, ref6, mut6, 6) -> G
-        (val7, ref7, mut7, 7) -> H
-    }
-    Tuple9 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-        (val5, ref5, mut5, 5) -> F
-        (val6, ref6, mut6, 6) -> G
-        (val7, ref7, mut7, 7) -> H
-        (val8, ref8, mut8, 8) -> I
-    }
-    Tuple10 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-        (val5, ref5, mut5, 5) -> F
-        (val6, ref6, mut6, 6) -> G
-        (val7, ref7, mut7, 7) -> H
-        (val8, ref8, mut8, 8) -> I
-        (val9, ref9, mut9, 9) -> J
-    }
-    Tuple11 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-        (val5, ref5, mut5, 5) -> F
-        (val6, ref6, mut6, 6) -> G
-        (val7, ref7, mut7, 7) -> H
-        (val8, ref8, mut8, 8) -> I
-        (val9, ref9, mut9, 9) -> J
-        (val10, ref10, mut10, 10) -> K
-    }
-    Tuple12 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-        (val5, ref5, mut5, 5) -> F
-        (val6, ref6, mut6, 6) -> G
-        (val7, ref7, mut7, 7) -> H
-        (val8, ref8, mut8, 8) -> I
-        (val9, ref9, mut9, 9) -> J
-        (val10, ref10, mut10, 10) -> K
-        (val11, ref11, mut11, 11) -> L
-    }
-}
-
diff --git a/src/libcore/tuple/unit.rs b/src/libcore/tuple/unit.rs
deleted file mode 100644 (file)
index 7f89f0e..0000000
+++ /dev/null
@@ -1,46 +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.
-
-#![doc(primitive = "unit")]
-#![unstable = "this module is purely for documentation and it will likely be \
-               removed from the public api"]
-
-//! The `()` type, sometimes called "unit" or "nil".
-//!
-//! The `()` type has exactly one value `()`, and is used when there
-//! is no other meaningful value that could be returned. `()` is most
-//! commonly seen implicitly: functions without a `-> ...` implicitly
-//! have return type `()`, that is, these are equivalent:
-//!
-//! ```rust
-//! fn long() -> () {}
-//!
-//! fn short() {}
-//! ```
-//!
-//! The semicolon `;` can be used to discard the result of an
-//! expression at the end of a block, making the expression (and thus
-//! the block) evaluate to `()`. For example,
-//!
-//! ```rust
-//! fn returns_i64() -> i64 {
-//!     1i64
-//! }
-//! fn returns_unit() {
-//!     1i64;
-//! }
-//!
-//! let is_i64 = {
-//!     returns_i64()
-//! };
-//! let is_unit = {
-//!     returns_i64();
-//! };
-//! ```
index 3099bf559e4bfa2384a2bc36536106137d99a79c..106e467c1691a4af79a3b15953e8a759d8dc48f9 100644 (file)
@@ -23,7 +23,7 @@
        html_root_url = "http://doc.rust-lang.org/nightly/",
        html_playground_url = "http://play.rust-lang.org/")]
 
-#![feature(macro_rules, globs, import_shadowing)]
+#![feature(macro_rules, globs)]
 pub use self::Piece::*;
 pub use self::Position::*;
 pub use self::Alignment::*;
index b45d0c9b01ecde60392832e736d1d696c817e714..e362c67cc50974d207beb63e591acc4eaafe2a8c 100644 (file)
@@ -86,7 +86,6 @@
        html_root_url = "http://doc.rust-lang.org/nightly/",
        html_playground_url = "http://play.rust-lang.org/")]
 #![feature(globs, phase)]
-#![feature(import_shadowing)]
 #![feature(unboxed_closures)]
 #![deny(missing_docs)]
 
index 90e9973c3f302f9d8ae4c2882f7ea3a114ef9917..463dcddaf94f2c2a2473020d77e1d8d0428dbe82 100644 (file)
@@ -22,7 +22,7 @@
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/")]
 
-#![feature(default_type_params, globs, import_shadowing, macro_rules, phase, quote)]
+#![feature(default_type_params, globs, macro_rules, phase, quote)]
 #![feature(slicing_syntax, unsafe_destructor)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(unboxed_closures)]
@@ -90,7 +90,6 @@ pub mod middle {
     pub mod reachable;
     pub mod region;
     pub mod recursion_limit;
-    pub mod resolve;
     pub mod resolve_lifetime;
     pub mod stability;
     pub mod subst;
index 88b12aa5660c99929c3785e4cd6b72759915f6c8..fddd49c8d88f3d81794b0287ced9a23db9988bf1 100644 (file)
@@ -37,7 +37,7 @@
 use lint::{Context, LintPass, LintArray};
 
 use std::{cmp, slice};
-use std::collections::hash_map::{Occupied, Vacant};
+use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::num::SignedInt;
 use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
 use syntax::{abi, ast, ast_map};
@@ -1157,9 +1157,9 @@ fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
             ast::ExprIf(ref cond, _, _) => (cond, "`if` condition", true),
             ast::ExprWhile(ref cond, _, _) => (cond, "`while` condition", true),
             ast::ExprMatch(ref head, _, source) => match source {
-                ast::MatchNormal => (head, "`match` head expression", true),
-                ast::MatchIfLetDesugar => (head, "`if let` head expression", true),
-                ast::MatchWhileLetDesugar => (head, "`while let` head expression", true),
+                ast::MatchSource::Normal => (head, "`match` head expression", true),
+                ast::MatchSource::IfLetDesugar { .. } => (head, "`if let` head expression", true),
+                ast::MatchSource::WhileLetDesugar => (head, "`while let` head expression", true),
             },
             ast::ExprRet(Some(ref value)) => (value, "`return` value", false),
             ast::ExprAssign(_, ref value) => (value, "assigned value", false),
index 9e87153e64a1580d71faaf8dcb025a202a37e88f..323b084afdc32b77b606fb763a2dec03de7dcfb8 100644 (file)
@@ -23,7 +23,7 @@
 use util::nodemap::FnvHashMap;
 
 use std::rc::Rc;
-use std::collections::hash_map::{Occupied, Vacant};
+use std::collections::hash_map::Entry::{Occupied, Vacant};
 use syntax::ast;
 use syntax::abi;
 use syntax::attr;
index a474af7c6e1ff0dd81173ae09ffce2f8ef91dddc..b702f4925d84739983de49941b63a046b620dddb 100644 (file)
@@ -19,7 +19,6 @@
 use metadata::decoder;
 use middle::def;
 use middle::lang_items;
-use middle::resolve;
 use middle::ty;
 
 use rbml;
@@ -148,7 +147,7 @@ pub fn get_impl_or_trait_item<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId)
 }
 
 pub fn get_trait_item_name_and_kind(cstore: &cstore::CStore, def: ast::DefId)
-                                    -> (ast::Name, resolve::TraitItemKind) {
+                                    -> (ast::Name, def::TraitItemKind) {
     let cdata = cstore.get_crate_data(def.krate);
     decoder::get_trait_item_name_and_kind(cstore.intr.clone(),
                                           &*cdata,
index b89c5dbcd0885af2dc093e0b8777bd61de88e77e..d8168814c6cd0591324f9fadbd96049c063e7140 100644 (file)
@@ -27,7 +27,6 @@
                          parse_predicate_data};
 use middle::def;
 use middle::lang_items;
-use middle::resolve::{TraitItemKind, TypeTraitItemKind};
 use middle::subst;
 use middle::ty::{ImplContainer, TraitContainer};
 use middle::ty::{mod, Ty};
@@ -785,15 +784,15 @@ pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
 pub fn get_trait_item_name_and_kind(intr: Rc<IdentInterner>,
                                     cdata: Cmd,
                                     id: ast::NodeId)
-                                    -> (ast::Name, TraitItemKind) {
+                                    -> (ast::Name, def::TraitItemKind) {
     let doc = lookup_item(id, cdata.data());
     let name = item_name(&*intr, doc);
     match item_sort(doc) {
         'r' | 'p' => {
             let explicit_self = get_explicit_self(doc);
-            (name, TraitItemKind::from_explicit_self_category(explicit_self))
+            (name, def::TraitItemKind::from_explicit_self_category(explicit_self))
         }
-        't' => (name, TypeTraitItemKind),
+        't' => (name, def::TypeTraitItemKind),
         c => {
             panic!("get_trait_item_name_and_kind(): unknown trait item kind \
                    in metadata: `{}`", c)
index cc383aa217a7b8ba459a0b2df375103176fdf3ae..e5dae926db950fd8398cc2458a98b302e2263c6b 100644 (file)
 use metadata::cstore;
 use metadata::decoder;
 use metadata::tyencode;
+use middle::def;
 use middle::ty::{lookup_item_type};
 use middle::ty::{mod, Ty};
 use middle::stability;
-use middle;
 use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
 
 use serialize::Encodable;
@@ -66,7 +66,7 @@ pub enum InlinedItemRef<'a> {
 pub struct EncodeParams<'a, 'tcx: 'a> {
     pub diag: &'a SpanHandler,
     pub tcx: &'a ty::ctxt<'tcx>,
-    pub reexports2: &'a middle::resolve::ExportMap2,
+    pub reexports: &'a def::ExportMap,
     pub item_symbols: &'a RefCell<NodeMap<String>>,
     pub link_meta: &'a LinkMeta,
     pub cstore: &'a cstore::CStore,
@@ -77,7 +77,7 @@ pub struct EncodeParams<'a, 'tcx: 'a> {
 pub struct EncodeContext<'a, 'tcx: 'a> {
     pub diag: &'a SpanHandler,
     pub tcx: &'a ty::ctxt<'tcx>,
-    pub reexports2: &'a middle::resolve::ExportMap2,
+    pub reexports: &'a def::ExportMap,
     pub item_symbols: &'a RefCell<NodeMap<String>>,
     pub link_meta: &'a LinkMeta,
     pub cstore: &'a cstore::CStore,
@@ -379,7 +379,7 @@ fn encode_path<PI: Iterator<PathElem>>(rbml_w: &mut Encoder, path: PI) {
 }
 
 fn encode_reexported_static_method(rbml_w: &mut Encoder,
-                                   exp: &middle::resolve::Export2,
+                                   exp: &def::Export,
                                    method_def_id: DefId,
                                    method_name: ast::Name) {
     debug!("(encode reexported static method) {}::{}",
@@ -398,7 +398,7 @@ fn encode_reexported_static_method(rbml_w: &mut Encoder,
 
 fn encode_reexported_static_base_methods(ecx: &EncodeContext,
                                          rbml_w: &mut Encoder,
-                                         exp: &middle::resolve::Export2)
+                                         exp: &def::Export)
                                          -> bool {
     let impl_items = ecx.tcx.impl_items.borrow();
     match ecx.tcx.inherent_impls.borrow().get(&exp.def_id) {
@@ -428,7 +428,7 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext,
 
 fn encode_reexported_static_trait_methods(ecx: &EncodeContext,
                                           rbml_w: &mut Encoder,
-                                          exp: &middle::resolve::Export2)
+                                          exp: &def::Export)
                                           -> bool {
     match ecx.tcx.trait_items_cache.borrow().get(&exp.def_id) {
         Some(trait_items) => {
@@ -449,10 +449,8 @@ fn encode_reexported_static_trait_methods(ecx: &EncodeContext,
 fn encode_reexported_static_methods(ecx: &EncodeContext,
                                     rbml_w: &mut Encoder,
                                     mod_path: PathElems,
-                                    exp: &middle::resolve::Export2) {
+                                    exp: &def::Export) {
     if let Some(ast_map::NodeItem(item)) = ecx.tcx.map.find(exp.def_id.node) {
-        let original_name = token::get_ident(item.ident);
-
         let path_differs = ecx.tcx.map.with_path(exp.def_id.node, |path| {
             let (mut a, mut b) = (path, mod_path.clone());
             loop {
@@ -474,16 +472,16 @@ fn encode_reexported_static_methods(ecx: &EncodeContext,
         // encoded metadata for static methods relative to Bar,
         // but not yet for Foo.
         //
-        if path_differs || original_name.get() != exp.name {
+        if path_differs || item.ident.name != exp.name {
             if !encode_reexported_static_base_methods(ecx, rbml_w, exp) {
                 if encode_reexported_static_trait_methods(ecx, rbml_w, exp) {
                     debug!("(encode reexported static methods) {} [trait]",
-                           original_name);
+                           item.ident.name);
                 }
             }
             else {
                 debug!("(encode reexported static methods) {} [base]",
-                       original_name);
+                       item.ident.name);
             }
         }
     }
@@ -519,7 +517,7 @@ fn encode_reexports(ecx: &EncodeContext,
                     id: NodeId,
                     path: PathElems) {
     debug!("(encoding info for module) encoding reexports for {}", id);
-    match ecx.reexports2.get(&id) {
+    match ecx.reexports.get(&id) {
         Some(ref exports) => {
             debug!("(encoding info for module) found reexports for {}", id);
             for exp in exports.iter() {
@@ -534,7 +532,7 @@ fn encode_reexports(ecx: &EncodeContext,
                 rbml_w.wr_str(def_to_string(exp.def_id).as_slice());
                 rbml_w.end_tag();
                 rbml_w.start_tag(tag_items_data_item_reexport_name);
-                rbml_w.wr_str(exp.name.as_slice());
+                rbml_w.wr_str(exp.name.as_str());
                 rbml_w.end_tag();
                 rbml_w.end_tag();
                 encode_reexported_static_methods(ecx, rbml_w, path.clone(), exp);
@@ -1480,6 +1478,9 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
         if abi == abi::RustIntrinsic {
             encode_inlined_item(ecx, rbml_w, IIForeignRef(nitem));
         }
+        encode_attributes(rbml_w, &*nitem.attrs);
+        let stab = stability::lookup(ecx.tcx, ast_util::local_def(nitem.id));
+        encode_stability(rbml_w, stab);
         encode_symbol(ecx, rbml_w, nitem.id);
       }
       ast::ForeignItemStatic(_, mutbl) => {
@@ -1490,6 +1491,9 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
         }
         encode_bounds_and_type(rbml_w, ecx,
                                &lookup_item_type(ecx.tcx,local_def(nitem.id)));
+        encode_attributes(rbml_w, &*nitem.attrs);
+        let stab = stability::lookup(ecx.tcx, ast_util::local_def(nitem.id));
+        encode_stability(rbml_w, stab);
         encode_symbol(ecx, rbml_w, nitem.id);
         encode_name(rbml_w, nitem.ident.name);
       }
@@ -2071,7 +2075,7 @@ struct Stats {
         item_symbols,
         diag,
         tcx,
-        reexports2,
+        reexports,
         cstore,
         encode_inlined_item,
         link_meta,
@@ -2081,7 +2085,7 @@ struct Stats {
     let ecx = EncodeContext {
         diag: diag,
         tcx: tcx,
-        reexports2: reexports2,
+        reexports: reexports,
         item_symbols: item_symbols,
         link_meta: link_meta,
         cstore: cstore,
index e83f69b1e318ee5725281202557319ceaebfc930..bc34b0b45e96fbf599dba7eebd07a6f797bdd15f 100644 (file)
 
 use std::c_str::ToCStr;
 use std::cmp;
-use std::collections::hash_map::{Occupied, Vacant};
+use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::collections::{HashMap, HashSet};
 use std::io::fs::PathExtensions;
 use std::io;
index 5d7d85d4679d7c9d8ed6e46913a4467a36dd91e1..ce63c467822db76b070ba7b18f2691e668ab4006 100644 (file)
@@ -55,7 +55,103 @@ pub fn enc_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, t: Ty<'t
         None => {}
     }
     let pos = w.tell().unwrap();
-    enc_sty(w, cx, &t.sty);
+
+    match t.sty {
+        ty::ty_bool => mywrite!(w, "b"),
+        ty::ty_char => mywrite!(w, "c"),
+        ty::ty_int(t) => {
+            match t {
+                ast::TyI => mywrite!(w, "i"),
+                ast::TyI8 => mywrite!(w, "MB"),
+                ast::TyI16 => mywrite!(w, "MW"),
+                ast::TyI32 => mywrite!(w, "ML"),
+                ast::TyI64 => mywrite!(w, "MD")
+            }
+        }
+        ty::ty_uint(t) => {
+            match t {
+                ast::TyU => mywrite!(w, "u"),
+                ast::TyU8 => mywrite!(w, "Mb"),
+                ast::TyU16 => mywrite!(w, "Mw"),
+                ast::TyU32 => mywrite!(w, "Ml"),
+                ast::TyU64 => mywrite!(w, "Md")
+            }
+        }
+        ty::ty_float(t) => {
+            match t {
+                ast::TyF32 => mywrite!(w, "Mf"),
+                ast::TyF64 => mywrite!(w, "MF"),
+            }
+        }
+        ty::ty_enum(def, ref substs) => {
+            mywrite!(w, "t[{}|", (cx.ds)(def));
+            enc_substs(w, cx, substs);
+            mywrite!(w, "]");
+        }
+        ty::ty_trait(box ty::TyTrait { ref principal,
+                                       ref bounds }) => {
+            mywrite!(w, "x[");
+            enc_trait_ref(w, cx, &principal.0);
+            enc_existential_bounds(w, cx, bounds);
+            mywrite!(w, "]");
+        }
+        ty::ty_tup(ref ts) => {
+            mywrite!(w, "T[");
+            for t in ts.iter() { enc_ty(w, cx, *t); }
+            mywrite!(w, "]");
+        }
+        ty::ty_uniq(typ) => { mywrite!(w, "~"); enc_ty(w, cx, typ); }
+        ty::ty_ptr(mt) => { mywrite!(w, "*"); enc_mt(w, cx, mt); }
+        ty::ty_rptr(r, mt) => {
+            mywrite!(w, "&");
+            enc_region(w, cx, r);
+            enc_mt(w, cx, mt);
+        }
+        ty::ty_vec(t, sz) => {
+            mywrite!(w, "V");
+            enc_ty(w, cx, t);
+            mywrite!(w, "/");
+            match sz {
+                Some(n) => mywrite!(w, "{}|", n),
+                None => mywrite!(w, "|"),
+            }
+        }
+        ty::ty_str => {
+            mywrite!(w, "v");
+        }
+        ty::ty_closure(ref f) => {
+            mywrite!(w, "f");
+            enc_closure_ty(w, cx, &**f);
+        }
+        ty::ty_bare_fn(ref f) => {
+            mywrite!(w, "F");
+            enc_bare_fn_ty(w, cx, f);
+        }
+        ty::ty_infer(_) => {
+            cx.diag.handler().bug("cannot encode inference variable types");
+        }
+        ty::ty_param(ParamTy {space, idx: id, def_id: did}) => {
+            mywrite!(w, "p{}|{}|{}|", (cx.ds)(did), id, space.to_uint())
+        }
+        ty::ty_struct(def, ref substs) => {
+            mywrite!(w, "a[{}|", (cx.ds)(def));
+            enc_substs(w, cx, substs);
+            mywrite!(w, "]");
+        }
+        ty::ty_unboxed_closure(def, region, ref substs) => {
+            mywrite!(w, "k[{}|", (cx.ds)(def));
+            enc_region(w, cx, region);
+            enc_substs(w, cx, substs);
+            mywrite!(w, "]");
+        }
+        ty::ty_err => {
+            mywrite!(w, "e");
+        }
+        ty::ty_open(_) => {
+            cx.diag.handler().bug("unexpected type in enc_sty (ty_open)");
+        }
+    }
+
     let end = w.tell().unwrap();
     let len = end - pos;
     fn estimate_sz(u: u64) -> u64 {
@@ -214,105 +310,6 @@ pub fn enc_trait_store(w: &mut SeekableMemWriter, cx: &ctxt, s: ty::TraitStore)
     }
 }
 
-fn enc_sty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
-                     st: &ty::sty<'tcx>) {
-    match *st {
-        ty::ty_bool => mywrite!(w, "b"),
-        ty::ty_char => mywrite!(w, "c"),
-        ty::ty_int(t) => {
-            match t {
-                ast::TyI => mywrite!(w, "i"),
-                ast::TyI8 => mywrite!(w, "MB"),
-                ast::TyI16 => mywrite!(w, "MW"),
-                ast::TyI32 => mywrite!(w, "ML"),
-                ast::TyI64 => mywrite!(w, "MD")
-            }
-        }
-        ty::ty_uint(t) => {
-            match t {
-                ast::TyU => mywrite!(w, "u"),
-                ast::TyU8 => mywrite!(w, "Mb"),
-                ast::TyU16 => mywrite!(w, "Mw"),
-                ast::TyU32 => mywrite!(w, "Ml"),
-                ast::TyU64 => mywrite!(w, "Md")
-            }
-        }
-        ty::ty_float(t) => {
-            match t {
-                ast::TyF32 => mywrite!(w, "Mf"),
-                ast::TyF64 => mywrite!(w, "MF"),
-            }
-        }
-        ty::ty_enum(def, ref substs) => {
-            mywrite!(w, "t[{}|", (cx.ds)(def));
-            enc_substs(w, cx, substs);
-            mywrite!(w, "]");
-        }
-        ty::ty_trait(box ty::TyTrait { ref principal,
-                                       ref bounds }) => {
-            mywrite!(w, "x[");
-            enc_trait_ref(w, cx, &principal.0);
-            enc_existential_bounds(w, cx, bounds);
-            mywrite!(w, "]");
-        }
-        ty::ty_tup(ref ts) => {
-            mywrite!(w, "T[");
-            for t in ts.iter() { enc_ty(w, cx, *t); }
-            mywrite!(w, "]");
-        }
-        ty::ty_uniq(typ) => { mywrite!(w, "~"); enc_ty(w, cx, typ); }
-        ty::ty_ptr(mt) => { mywrite!(w, "*"); enc_mt(w, cx, mt); }
-        ty::ty_rptr(r, mt) => {
-            mywrite!(w, "&");
-            enc_region(w, cx, r);
-            enc_mt(w, cx, mt);
-        }
-        ty::ty_vec(t, sz) => {
-            mywrite!(w, "V");
-            enc_ty(w, cx, t);
-            mywrite!(w, "/");
-            match sz {
-                Some(n) => mywrite!(w, "{}|", n),
-                None => mywrite!(w, "|"),
-            }
-        }
-        ty::ty_str => {
-            mywrite!(w, "v");
-        }
-        ty::ty_closure(ref f) => {
-            mywrite!(w, "f");
-            enc_closure_ty(w, cx, &**f);
-        }
-        ty::ty_bare_fn(ref f) => {
-            mywrite!(w, "F");
-            enc_bare_fn_ty(w, cx, f);
-        }
-        ty::ty_infer(_) => {
-            cx.diag.handler().bug("cannot encode inference variable types");
-        }
-        ty::ty_param(ParamTy {space, idx: id, def_id: did}) => {
-            mywrite!(w, "p{}|{}|{}|", (cx.ds)(did), id, space.to_uint())
-        }
-        ty::ty_struct(def, ref substs) => {
-            mywrite!(w, "a[{}|", (cx.ds)(def));
-            enc_substs(w, cx, substs);
-            mywrite!(w, "]");
-        }
-        ty::ty_unboxed_closure(def, region, ref substs) => {
-            mywrite!(w, "k[{}|", (cx.ds)(def));
-            enc_region(w, cx, region);
-            enc_substs(w, cx, substs);
-            mywrite!(w, "]");
-        }
-        ty::ty_err => {
-            mywrite!(w, "e");
-        }
-        ty::ty_open(_) => {
-            cx.diag.handler().bug("unexpected type in enc_sty (ty_open)");
-        }
-    }
-}
-
 fn enc_unsafety(w: &mut SeekableMemWriter, p: ast::Unsafety) {
     match p {
         ast::Unsafety::Normal => mywrite!(w, "n"),
index a74fff5630bfd0d48301c8bd3037731a2f5a4f88..e1c5906f0fb83f5d49f33959a89b806697f5e60b 100644 (file)
@@ -48,4 +48,8 @@ pub fn new(tcx: &ty::ctxt,
                blk: &ast::Block) -> CFG {
         construct::construct(tcx, blk)
     }
+
+    pub fn node_is_reachable(&self, id: ast::NodeId) -> bool {
+        self.graph.depth_traverse(self.entry).any(|node| node.id == id)
+    }
 }
index 79e776c330884fe44fd93367dff18bc9e50ecb87..9a94eb97931466727b8b81cb16f2e5647240be1c 100644 (file)
@@ -22,7 +22,7 @@
 use middle::mem_categorization::cmt;
 use middle::pat_util::*;
 use middle::ty::*;
-use middle::ty::{mod, Ty};
+use middle::ty;
 use std::fmt;
 use std::iter::AdditiveIterator;
 use std::iter::range_inclusive;
@@ -307,7 +307,7 @@ fn check_arms(cx: &MatchCheckCtxt,
             match is_useful(cx, &seen, v.as_slice(), LeaveOutWitness) {
                 NotUseful => {
                     match source {
-                        ast::MatchIfLetDesugar => {
+                        ast::MatchSource::IfLetDesugar { .. } => {
                             if printed_if_let_err {
                                 // we already printed an irrefutable if-let pattern error.
                                 // We don't want two, that's just confusing.
@@ -321,7 +321,7 @@ fn check_arms(cx: &MatchCheckCtxt,
                             }
                         },
 
-                        ast::MatchWhileLetDesugar => {
+                        ast::MatchSource::WhileLetDesugar => {
                             // find the first arm pattern so we can use its span
                             let &(ref first_arm_pats, _) = &arms[0];
                             let first_pat = &first_arm_pats[0];
@@ -329,7 +329,7 @@ fn check_arms(cx: &MatchCheckCtxt,
                             span_err!(cx.tcx.sess, span, E0165, "irrefutable while-let pattern");
                         },
 
-                        ast::MatchNormal => {
+                        ast::MatchSource::Normal => {
                             span_err!(cx.tcx.sess, pat.span, E0001, "unreachable pattern")
                         },
                     }
index b32eb64025f8800b14e063e9f5f1208cb188499c..90242a3252ec7119f0e80693d627b2f89748ba95 100644 (file)
@@ -12,8 +12,7 @@
 // recursively.
 
 use session::Session;
-use middle::resolve;
-use middle::def::{DefStatic, DefConst};
+use middle::def::{DefStatic, DefConst, DefMap};
 
 use syntax::ast;
 use syntax::{ast_util, ast_map};
@@ -22,7 +21,7 @@
 
 struct CheckCrateVisitor<'a, 'ast: 'a> {
     sess: &'a Session,
-    def_map: &'a resolve::DefMap,
+    def_map: &'a DefMap,
     ast_map: &'a ast_map::Map<'ast>
 }
 
@@ -34,7 +33,7 @@ fn visit_item(&mut self, i: &ast::Item) {
 
 pub fn check_crate<'ast>(sess: &Session,
                          krate: &ast::Crate,
-                         def_map: &resolve::DefMap,
+                         def_map: &DefMap,
                          ast_map: &ast_map::Map<'ast>) {
     let mut visitor = CheckCrateVisitor {
         sess: sess,
@@ -60,7 +59,7 @@ struct CheckItemRecursionVisitor<'a, 'ast: 'a> {
     root_it: &'a ast::Item,
     sess: &'a Session,
     ast_map: &'a ast_map::Map<'ast>,
-    def_map: &'a resolve::DefMap,
+    def_map: &'a DefMap,
     idstack: Vec<ast::NodeId>
 }
 
@@ -68,7 +67,7 @@ struct CheckItemRecursionVisitor<'a, 'ast: 'a> {
 // FIXME: Should use the dependency graph when it's available (#1356)
 pub fn check_item_recursion<'a>(sess: &'a Session,
                                 ast_map: &'a ast_map::Map,
-                                def_map: &'a resolve::DefMap,
+                                def_map: &'a DefMap,
                                 it: &'a ast::Item) {
 
     let mut visitor = CheckItemRecursionVisitor {
index 9b94335654734a8b0786a511846cdce2b8dcb8e7..62f1a30f8e746dbc0fa34555e46e6d802a1cf1ff 100644 (file)
@@ -28,7 +28,7 @@
 use syntax::{ast_map, ast_util, codemap};
 
 use std::rc::Rc;
-use std::collections::hash_map::Vacant;
+use std::collections::hash_map::Entry::Vacant;
 
 //
 // This pass classifies expressions by their constant-ness.
index 20a0dbdc1eefa98dc4b1e9cb25d8e10192baeda9..a582907612fd5bf5f5b441ea7f12c963c7f49a0f 100644 (file)
 
 pub use self::Def::*;
 pub use self::MethodProvenance::*;
+pub use self::TraitItemKind::*;
 
 use middle::subst::ParamSpace;
+use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory};
+use util::nodemap::NodeMap;
 use syntax::ast;
 use syntax::ast_util::local_def;
 
+use std::cell::RefCell;
+
 #[deriving(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum Def {
     DefFn(ast::DefId, bool /* is_ctor */),
@@ -56,6 +61,18 @@ pub enum Def {
     DefMethod(ast::DefId /* method */, Option<ast::DefId> /* trait */, MethodProvenance),
 }
 
+// Definition mapping
+pub type DefMap = RefCell<NodeMap<Def>>;
+// This is the replacement export map. It maps a module to all of the exports
+// within.
+pub type ExportMap = NodeMap<Vec<Export>>;
+
+#[deriving(Copy)]
+pub struct Export {
+    pub name: ast::Name,    // The name of the target.
+    pub def_id: ast::DefId, // The definition of the target.
+}
+
 #[deriving(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum MethodProvenance {
     FromTrait(ast::DefId),
@@ -88,6 +105,25 @@ pub fn def_id(&self) -> ast::DefId {
     }
 }
 
+#[deriving(Clone, Copy, Eq, PartialEq)]
+pub enum TraitItemKind {
+    NonstaticMethodTraitItemKind,
+    StaticMethodTraitItemKind,
+    TypeTraitItemKind,
+}
+
+impl TraitItemKind {
+    pub fn from_explicit_self_category(explicit_self_category:
+                                       ExplicitSelfCategory)
+                                       -> TraitItemKind {
+        if explicit_self_category == StaticExplicitSelfCategory {
+            StaticMethodTraitItemKind
+        } else {
+            NonstaticMethodTraitItemKind
+        }
+    }
+}
+
 impl Def {
     pub fn def_id(&self) -> ast::DefId {
         match *self {
@@ -122,4 +158,3 @@ pub fn variant_def_ids(&self) -> Option<(ast::DefId, ast::DefId)> {
         }
     }
 }
-
index e73fcd93e0504cb1892d724b02ec6562acc27d4b..06e6ef30f74dacadc64ff42e6d1f5e6a3443498d 100644 (file)
@@ -34,6 +34,7 @@
 
 use std::fmt::{Formatter, Error, Show};
 use std::uint;
+use std::collections::BitvSet;
 
 pub struct Graph<N,E> {
     nodes: Vec<Node<N>> ,
@@ -288,6 +289,40 @@ pub fn iterate_until_fixed_point<'a, F>(&'a self, mut op: F) where
             }
         }
     }
+
+    pub fn depth_traverse<'a>(&'a self, start: NodeIndex) -> DepthFirstTraversal<'a, N, E>  {
+        DepthFirstTraversal {
+            graph: self,
+            stack: vec![start],
+            visited: BitvSet::new()
+        }
+    }
+}
+
+pub struct DepthFirstTraversal<'g, N:'g, E:'g> {
+    graph: &'g Graph<N, E>,
+    stack: Vec<NodeIndex>,
+    visited: BitvSet
+}
+
+impl<'g, N, E> Iterator<&'g N> for DepthFirstTraversal<'g, N, E> {
+    fn next(&mut self) -> Option<&'g N> {
+        while let Some(idx) = self.stack.pop() {
+            if !self.visited.insert(idx.node_id()) {
+                continue;
+            }
+            self.graph.each_outgoing_edge(idx, |_, e| -> bool {
+                if !self.visited.contains(&e.target().node_id()) {
+                    self.stack.push(e.target());
+                }
+                true
+            });
+
+            return Some(self.graph.node_data(idx));
+        }
+
+        return None;
+    }
 }
 
 pub fn each_edge_index<F>(max_edge_index: EdgeIndex, mut f: F) where
index 805d4532aa1c49ff802d4ff4c7f16d8ae3e08a17..64bfd1388026d38345c61f386070b11cf62358d4 100644 (file)
@@ -90,8 +90,8 @@ pub fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
                b.repr(self.get_ref().infcx.tcx));
 
         // Consider coercing the subtype to a DST
-        let unsize = self.unpack_actual_value(a, |sty_a| {
-            self.coerce_unsized(a, sty_a, b)
+        let unsize = self.unpack_actual_value(a, |a| {
+            self.coerce_unsized(a, b)
         });
         if unsize.is_ok() {
             return unsize;
@@ -105,14 +105,14 @@ pub fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
             ty::ty_ptr(mt_b) => {
                 match mt_b.ty.sty {
                     ty::ty_str => {
-                        return self.unpack_actual_value(a, |sty_a| {
-                            self.coerce_unsafe_ptr(a, sty_a, b, ast::MutImmutable)
+                        return self.unpack_actual_value(a, |a| {
+                            self.coerce_unsafe_ptr(a, b, ast::MutImmutable)
                         });
                     }
 
                     ty::ty_trait(..) => {
-                        let result = self.unpack_actual_value(a, |sty_a| {
-                            self.coerce_unsafe_object(a, sty_a, b, mt_b.mutbl)
+                        let result = self.unpack_actual_value(a, |a| {
+                            self.coerce_unsafe_object(a, b, mt_b.mutbl)
                         });
 
                         match result {
@@ -122,8 +122,8 @@ pub fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
                     }
 
                     _ => {
-                        return self.unpack_actual_value(a, |sty_a| {
-                            self.coerce_unsafe_ptr(a, sty_a, b, mt_b.mutbl)
+                        return self.unpack_actual_value(a, |a| {
+                            self.coerce_unsafe_ptr(a, b, mt_b.mutbl)
                         });
                     }
                 };
@@ -132,14 +132,14 @@ pub fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
             ty::ty_rptr(_, mt_b) => {
                 match mt_b.ty.sty {
                     ty::ty_str => {
-                        return self.unpack_actual_value(a, |sty_a| {
-                            self.coerce_borrowed_pointer(a, sty_a, b, ast::MutImmutable)
+                        return self.unpack_actual_value(a, |a| {
+                            self.coerce_borrowed_pointer(a, b, ast::MutImmutable)
                         });
                     }
 
                     ty::ty_trait(..) => {
-                        let result = self.unpack_actual_value(a, |sty_a| {
-                            self.coerce_borrowed_object(a, sty_a, b, mt_b.mutbl)
+                        let result = self.unpack_actual_value(a, |a| {
+                            self.coerce_borrowed_object(a, b, mt_b.mutbl)
                         });
 
                         match result {
@@ -149,8 +149,8 @@ pub fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
                     }
 
                     _ => {
-                        return self.unpack_actual_value(a, |sty_a| {
-                            self.coerce_borrowed_pointer(a, sty_a, b, mt_b.mutbl)
+                        return self.unpack_actual_value(a, |a| {
+                            self.coerce_borrowed_pointer(a, b, mt_b.mutbl)
                         });
                     }
                 };
@@ -160,16 +160,16 @@ pub fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
                     store: ty::RegionTraitStore(..),
                     ..
                 }) => {
-                return self.unpack_actual_value(a, |sty_a| {
-                    self.coerce_borrowed_fn(a, sty_a, b)
+                return self.unpack_actual_value(a, |a| {
+                    self.coerce_borrowed_fn(a, b)
                 });
             }
 
             _ => {}
         }
 
-        self.unpack_actual_value(a, |sty_a| {
-            match *sty_a {
+        self.unpack_actual_value(a, |a| {
+            match a.sty {
                 ty::ty_bare_fn(ref a_f) => {
                     // Bare functions are coercible to any closure type.
                     //
@@ -194,20 +194,19 @@ pub fn subtype(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
     }
 
     pub fn unpack_actual_value<T, F>(&self, a: Ty<'tcx>, f: F) -> T where
-        F: FnOnce(&ty::sty<'tcx>) -> T,
+        F: FnOnce(Ty<'tcx>) -> T,
     {
-        f(&self.get_ref().infcx.shallow_resolve(a).sty)
+        f(self.get_ref().infcx.shallow_resolve(a))
     }
 
     // ~T -> &T or &mut T -> &T (including where T = [U] or str)
     pub fn coerce_borrowed_pointer(&self,
                                    a: Ty<'tcx>,
-                                   sty_a: &ty::sty<'tcx>,
                                    b: Ty<'tcx>,
                                    mutbl_b: ast::Mutability)
                                    -> CoerceResult<'tcx> {
-        debug!("coerce_borrowed_pointer(a={}, sty_a={}, b={})",
-               a.repr(self.get_ref().infcx.tcx), sty_a,
+        debug!("coerce_borrowed_pointer(a={}, b={})",
+               a.repr(self.get_ref().infcx.tcx),
                b.repr(self.get_ref().infcx.tcx));
 
         // If we have a parameter of type `&M T_a` and the value
@@ -220,7 +219,7 @@ pub fn coerce_borrowed_pointer(&self,
         let coercion = Coercion(self.get_ref().trace.clone());
         let r_borrow = self.get_ref().infcx.next_region_var(coercion);
 
-        let inner_ty = match *sty_a {
+        let inner_ty = match a.sty {
             ty::ty_uniq(_) => return Err(ty::terr_mismatch),
             ty::ty_rptr(_, mt_a) => mt_a.ty,
             _ => {
@@ -245,11 +244,10 @@ pub fn coerce_borrowed_pointer(&self,
     // or &Concrete -> &Trait, etc.
     fn coerce_unsized(&self,
                       a: Ty<'tcx>,
-                      sty_a: &ty::sty<'tcx>,
                       b: Ty<'tcx>)
                       -> CoerceResult<'tcx> {
-        debug!("coerce_unsized(a={}, sty_a={}, b={})",
-               a.repr(self.get_ref().infcx.tcx), sty_a,
+        debug!("coerce_unsized(a={}, b={})",
+               a.repr(self.get_ref().infcx.tcx),
                b.repr(self.get_ref().infcx.tcx));
 
         // Note, we want to avoid unnecessary unsizing. We don't want to coerce to
@@ -259,11 +257,10 @@ fn coerce_unsized(&self,
 
         let sub = Sub(self.get_ref().clone());
 
-        let sty_b = &b.sty;
-        match (sty_a, sty_b) {
+        match (&a.sty, &b.sty) {
             (&ty::ty_rptr(_, ty::mt{ty: t_a, mutbl: mutbl_a}), &ty::ty_rptr(_, mt_b)) => {
-                self.unpack_actual_value(t_a, |sty_a| {
-                    match self.unsize_ty(t_a, sty_a, mt_b.ty) {
+                self.unpack_actual_value(t_a, |a| {
+                    match self.unsize_ty(t_a, a, mt_b.ty) {
                         Some((ty, kind)) => {
                             if !can_coerce_mutbls(mutbl_a, mt_b.mutbl) {
                                 return Err(ty::terr_mutability);
@@ -288,8 +285,8 @@ fn coerce_unsized(&self,
                 })
             }
             (&ty::ty_rptr(_, ty::mt{ty: t_a, mutbl: mutbl_a}), &ty::ty_ptr(mt_b)) => {
-                self.unpack_actual_value(t_a, |sty_a| {
-                    match self.unsize_ty(t_a, sty_a, mt_b.ty) {
+                self.unpack_actual_value(t_a, |a| {
+                    match self.unsize_ty(t_a, a, mt_b.ty) {
                         Some((ty, kind)) => {
                             if !can_coerce_mutbls(mutbl_a, mt_b.mutbl) {
                                 return Err(ty::terr_mutability);
@@ -311,8 +308,8 @@ fn coerce_unsized(&self,
                 })
             }
             (&ty::ty_uniq(t_a), &ty::ty_uniq(t_b)) => {
-                self.unpack_actual_value(t_a, |sty_a| {
-                    match self.unsize_ty(t_a, sty_a, t_b) {
+                self.unpack_actual_value(t_a, |a| {
+                    match self.unsize_ty(t_a, a, t_b) {
                         Some((ty, kind)) => {
                             let ty = ty::mk_uniq(self.get_ref().infcx.tcx, ty);
                             try!(self.get_ref().infcx.try(|_| sub.tys(ty, b)));
@@ -336,15 +333,15 @@ fn coerce_unsized(&self,
     // E.g., `[T, ..n]` -> `([T], UnsizeLength(n))`
     fn unsize_ty(&self,
                  ty_a: Ty<'tcx>,
-                 sty_a: &ty::sty<'tcx>,
+                 a: Ty<'tcx>,
                  ty_b: Ty<'tcx>)
                  -> Option<(Ty<'tcx>, ty::UnsizeKind<'tcx>)> {
-        debug!("unsize_ty(sty_a={}, ty_b={})", sty_a, ty_b.repr(self.get_ref().infcx.tcx));
+        debug!("unsize_ty(a={}, ty_b={})", a, ty_b.repr(self.get_ref().infcx.tcx));
 
         let tcx = self.get_ref().infcx.tcx;
 
-        self.unpack_actual_value(ty_b, |sty_b|
-            match (sty_a, sty_b) {
+        self.unpack_actual_value(ty_b, |b|
+            match (&a.sty, &b.sty) {
                 (&ty::ty_vec(t_a, Some(len)), &ty::ty_vec(_, None)) => {
                     let ty = ty::mk_vec(tcx, t_a, None);
                     Some((ty, ty::UnsizeLength(len)))
@@ -412,44 +409,41 @@ fn unsize_ty(&self,
 
     fn coerce_borrowed_object(&self,
                               a: Ty<'tcx>,
-                              sty_a: &ty::sty<'tcx>,
                               b: Ty<'tcx>,
                               b_mutbl: ast::Mutability) -> CoerceResult<'tcx>
     {
         let tcx = self.get_ref().infcx.tcx;
 
-        debug!("coerce_borrowed_object(a={}, sty_a={}, b={}, b_mutbl={})",
-               a.repr(tcx), sty_a,
+        debug!("coerce_borrowed_object(a={}, b={}, b_mutbl={})",
+               a.repr(tcx),
                b.repr(tcx), b_mutbl);
 
         let coercion = Coercion(self.get_ref().trace.clone());
         let r_a = self.get_ref().infcx.next_region_var(coercion);
 
-        self.coerce_object(a, sty_a, b, b_mutbl,
+        self.coerce_object(a, b, b_mutbl,
                            |tr| ty::mk_rptr(tcx, r_a, ty::mt{ mutbl: b_mutbl, ty: tr }),
                            || AutoPtr(r_a, b_mutbl, None))
     }
 
     fn coerce_unsafe_object(&self,
                             a: Ty<'tcx>,
-                            sty_a: &ty::sty<'tcx>,
                             b: Ty<'tcx>,
                             b_mutbl: ast::Mutability) -> CoerceResult<'tcx>
     {
         let tcx = self.get_ref().infcx.tcx;
 
-        debug!("coerce_unsafe_object(a={}, sty_a={}, b={}, b_mutbl={})",
-               a.repr(tcx), sty_a,
+        debug!("coerce_unsafe_object(a={}, b={}, b_mutbl={})",
+               a.repr(tcx),
                b.repr(tcx), b_mutbl);
 
-        self.coerce_object(a, sty_a, b, b_mutbl,
+        self.coerce_object(a, b, b_mutbl,
                            |tr| ty::mk_ptr(tcx, ty::mt{ mutbl: b_mutbl, ty: tr }),
                            || AutoUnsafe(b_mutbl, None))
     }
 
     fn coerce_object<F, G>(&self,
                            a: Ty<'tcx>,
-                           sty_a: &ty::sty<'tcx>,
                            b: Ty<'tcx>,
                            b_mutbl: ast::Mutability,
                            mk_ty: F,
@@ -459,7 +453,7 @@ fn coerce_object<F, G>(&self,
     {
         let tcx = self.get_ref().infcx.tcx;
 
-        match *sty_a {
+        match a.sty {
             ty::ty_rptr(_, ty::mt{ty, mutbl}) => match ty.sty {
                 ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => {
                     debug!("mutbl={} b_mutbl={}", mutbl, b_mutbl);
@@ -483,14 +477,13 @@ fn coerce_object<F, G>(&self,
 
     pub fn coerce_borrowed_fn(&self,
                               a: Ty<'tcx>,
-                              sty_a: &ty::sty<'tcx>,
                               b: Ty<'tcx>)
                               -> CoerceResult<'tcx> {
-        debug!("coerce_borrowed_fn(a={}, sty_a={}, b={})",
-               a.repr(self.get_ref().infcx.tcx), sty_a,
+        debug!("coerce_borrowed_fn(a={}, b={})",
+               a.repr(self.get_ref().infcx.tcx),
                b.repr(self.get_ref().infcx.tcx));
 
-        match *sty_a {
+        match a.sty {
             ty::ty_bare_fn(ref f) => {
                 self.coerce_from_bare_fn(a, f, b)
             }
@@ -504,7 +497,7 @@ pub fn coerce_borrowed_fn(&self,
     ///  `proc`.
     fn coerce_from_bare_fn(&self, a: Ty<'tcx>, fn_ty_a: &ty::BareFnTy<'tcx>, b: Ty<'tcx>)
                            -> CoerceResult<'tcx> {
-        self.unpack_actual_value(b, |sty_b| {
+        self.unpack_actual_value(b, |b| {
 
             debug!("coerce_from_bare_fn(a={}, b={})",
                    a.repr(self.get_ref().infcx.tcx), b.repr(self.get_ref().infcx.tcx));
@@ -513,7 +506,7 @@ fn coerce_from_bare_fn(&self, a: Ty<'tcx>, fn_ty_a: &ty::BareFnTy<'tcx>, b: Ty<'
                 return self.subtype(a, b);
             }
 
-            let fn_ty_b = match *sty_b {
+            let fn_ty_b = match b.sty {
                 ty::ty_closure(ref f) => (*f).clone(),
                 _ => return self.subtype(a, b)
             };
@@ -531,15 +524,14 @@ fn coerce_from_bare_fn(&self, a: Ty<'tcx>, fn_ty_a: &ty::BareFnTy<'tcx>, b: Ty<'
 
     pub fn coerce_unsafe_ptr(&self,
                              a: Ty<'tcx>,
-                             sty_a: &ty::sty<'tcx>,
                              b: Ty<'tcx>,
                              mutbl_b: ast::Mutability)
                              -> CoerceResult<'tcx> {
-        debug!("coerce_unsafe_ptr(a={}, sty_a={}, b={})",
-               a.repr(self.get_ref().infcx.tcx), sty_a,
+        debug!("coerce_unsafe_ptr(a={}, b={})",
+               a.repr(self.get_ref().infcx.tcx),
                b.repr(self.get_ref().infcx.tcx));
 
-        let mt_a = match *sty_a {
+        let mt_a = match a.sty {
             ty::ty_rptr(_, mt) | ty::ty_ptr(mt) => mt,
             _ => {
                 return self.subtype(a, b);
index ebff854060caec7cfb107e4ad1db2aeb2b9af9bd..a8bf7546559fdf3835388ce4fc11af17d2bd1251 100644 (file)
@@ -34,7 +34,7 @@
 use middle::ty_fold;
 use middle::ty_fold::TypeFoldable;
 use middle::ty_fold::TypeFolder;
-use std::collections::hash_map;
+use std::collections::hash_map::{mod, Entry};
 
 use super::InferCtxt;
 use super::unify::InferCtxtMethodsForSimplyUnifiableTypes;
@@ -67,8 +67,8 @@ fn freshen<F>(&mut self,
         }
 
         match self.freshen_map.entry(key) {
-            hash_map::Occupied(entry) => *entry.get(),
-            hash_map::Vacant(entry) => {
+            Entry::Occupied(entry) => *entry.get(),
+            Entry::Vacant(entry) => {
                 let index = self.freshen_count;
                 self.freshen_count += 1;
                 let t = ty::mk_infer(self.infcx.tcx, freshener(index));
index 720de357a273d9b155658a85c8cd3012bfb84be3..3e55f6fa896bb6960bb93e0dc5dbbc76fcb9f6f9 100644 (file)
@@ -26,7 +26,7 @@
 use util::nodemap::{FnvHashMap, FnvHashSet};
 use util::ppaux::Repr;
 
-use std::collections::hash_map::Vacant;
+use std::collections::hash_map::Entry::Vacant;
 use std::io::{mod, File};
 use std::os;
 use std::sync::atomic;
index 8ef8e091c94858aeda905d049380ae50944c6c66..0a6c29d1cb65a154e4bf4461d515e4ece52316e6 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 use middle::def::*;
-use middle::resolve;
 use middle::ty;
 use util::nodemap::FnvHashMap;
 
@@ -21,7 +20,7 @@
 
 // This is used because same-named variables in alternative patterns need to
 // use the NodeId of their namesake in the first pattern.
-pub fn pat_id_map(dm: &resolve::DefMap, pat: &ast::Pat) -> PatIdMap {
+pub fn pat_id_map(dm: &DefMap, pat: &ast::Pat) -> PatIdMap {
     let mut map = FnvHashMap::new();
     pat_bindings(dm, pat, |_bm, p_id, _s, path1| {
         map.insert(path1.node, p_id);
@@ -29,7 +28,7 @@ pub fn pat_id_map(dm: &resolve::DefMap, pat: &ast::Pat) -> PatIdMap {
     map
 }
 
-pub fn pat_is_refutable(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
+pub fn pat_is_refutable(dm: &DefMap, pat: &ast::Pat) -> bool {
     match pat.node {
         ast::PatLit(_) | ast::PatRange(_, _) => true,
         ast::PatEnum(_, _) |
@@ -45,7 +44,7 @@ pub fn pat_is_refutable(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
     }
 }
 
-pub fn pat_is_variant_or_struct(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
+pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &ast::Pat) -> bool {
     match pat.node {
         ast::PatEnum(_, _) |
         ast::PatIdent(_, _, None) |
@@ -59,7 +58,7 @@ pub fn pat_is_variant_or_struct(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
     }
 }
 
-pub fn pat_is_const(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
+pub fn pat_is_const(dm: &DefMap, pat: &ast::Pat) -> bool {
     match pat.node {
         ast::PatIdent(_, _, None) | ast::PatEnum(..) => {
             match dm.borrow().get(&pat.id) {
@@ -71,7 +70,7 @@ pub fn pat_is_const(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
     }
 }
 
-pub fn pat_is_binding(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
+pub fn pat_is_binding(dm: &DefMap, pat: &ast::Pat) -> bool {
     match pat.node {
         ast::PatIdent(..) => {
             !pat_is_variant_or_struct(dm, pat) &&
@@ -81,7 +80,7 @@ pub fn pat_is_binding(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
     }
 }
 
-pub fn pat_is_binding_or_wild(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
+pub fn pat_is_binding_or_wild(dm: &DefMap, pat: &ast::Pat) -> bool {
     match pat.node {
         ast::PatIdent(..) => pat_is_binding(dm, pat),
         ast::PatWild(_) => true,
@@ -91,7 +90,7 @@ pub fn pat_is_binding_or_wild(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
 
 /// Call `it` on every "binding" in a pattern, e.g., on `a` in
 /// `match foo() { Some(a) => (), None => () }`
-pub fn pat_bindings<I>(dm: &resolve::DefMap, pat: &ast::Pat, mut it: I) where
+pub fn pat_bindings<I>(dm: &DefMap, pat: &ast::Pat, mut it: I) where
     I: FnMut(ast::BindingMode, ast::NodeId, Span, &ast::SpannedIdent),
 {
     walk_pat(pat, |p| {
@@ -107,7 +106,7 @@ pub fn pat_bindings<I>(dm: &resolve::DefMap, pat: &ast::Pat, mut it: I) where
 
 /// Checks if the pattern contains any patterns that bind something to
 /// an ident, e.g. `foo`, or `Foo(foo)` or `foo @ Bar(..)`.
-pub fn pat_contains_bindings(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
+pub fn pat_contains_bindings(dm: &DefMap, pat: &ast::Pat) -> bool {
     let mut contains_bindings = false;
     walk_pat(pat, |p| {
         if pat_is_binding(dm, p) {
index 8cce1321d728bdc7b9ae770f35cd219b01aaf0c9..f8b4ae73a1cdf95a90732d4c6bda1ef67c91380b 100644 (file)
 //! A pass that checks to make sure private fields and methods aren't used
 //! outside their scopes. This pass will also generate a set of exported items
 //! which are available for use externally when compiled as a library.
+pub use self::PrivateDep::*;
+pub use self::ImportUse::*;
+pub use self::LastPrivate::*;
 use self::PrivacyResult::*;
 use self::FieldName::*;
 
 use std::mem::replace;
 
 use metadata::csearch;
-use middle::{def, resolve};
+use middle::def;
 use middle::ty::{mod, Ty};
 use middle::ty::{MethodCall, MethodMap, MethodOrigin, MethodParam, MethodTypeParam};
 use middle::ty::{MethodStatic, MethodStaticUnboxedClosure, MethodObject, MethodTraitObject};
-use util::nodemap::{NodeMap, NodeSet};
+use util::nodemap::{DefIdSet, NodeMap, NodeSet};
 
 use syntax::{ast, ast_map};
 use syntax::ast_util::{is_local, local_def, PostExpansionMethod};
 use syntax::parse::token;
 use syntax::visit::{mod, Visitor};
 
-type Context<'a, 'tcx> = (&'a MethodMap<'tcx>, &'a resolve::ExportMap2);
+type Context<'a, 'tcx> = (&'a MethodMap<'tcx>, &'a def::ExportMap);
 
 /// A set of AST nodes exported by the crate.
 pub type ExportedItems = NodeSet;
 
+/// A set containing all exported definitions from external crates.
+/// The set does not contain any entries from local crates.
+pub type ExternalExports = DefIdSet;
+
 /// A set of AST nodes that are fully public in the crate. This map is used for
 /// documentation purposes (reexporting a private struct inlines the doc,
 /// reexporting a public struct doesn't inline the doc).
 pub type PublicItems = NodeSet;
 
+// FIXME: dox
+pub type LastPrivateMap = NodeMap<LastPrivate>;
+
+#[deriving(Copy, Show)]
+pub enum LastPrivate {
+    LastMod(PrivateDep),
+    // `use` directives (imports) can refer to two separate definitions in the
+    // type and value namespaces. We record here the last private node for each
+    // and whether the import is in fact used for each.
+    // If the Option<PrivateDep> fields are None, it means there is no definition
+    // in that namespace.
+    LastImport{value_priv: Option<PrivateDep>,
+               value_used: ImportUse,
+               type_priv: Option<PrivateDep>,
+               type_used: ImportUse},
+}
+
+#[deriving(Copy, Show)]
+pub enum PrivateDep {
+    AllPublic,
+    DependsOn(ast::DefId),
+}
+
+// How an import is used.
+#[deriving(Copy, PartialEq, Show)]
+pub enum ImportUse {
+    Unused,       // The import is not used.
+    Used,         // The import is used.
+}
+
+impl LastPrivate {
+    pub fn or(self, other: LastPrivate) -> LastPrivate {
+        match (self, other) {
+            (me, LastMod(AllPublic)) => me,
+            (_, other) => other,
+        }
+    }
+}
+
 /// Result of a checking operation - None => no errors were found. Some => an
 /// error and contains the span and message for reporting that error and
 /// optionally the same for a note about the error.
@@ -136,7 +182,7 @@ fn visit_struct_def(&mut self, s: &ast::StructDef, _: ast::Ident,
 
 struct EmbargoVisitor<'a, 'tcx: 'a> {
     tcx: &'a ty::ctxt<'tcx>,
-    exp_map2: &'a resolve::ExportMap2,
+    export_map: &'a def::ExportMap,
 
     // This flag is an indicator of whether the previous item in the
     // hierarchical chain was exported or not. This is the indicator of whether
@@ -342,8 +388,8 @@ fn visit_mod(&mut self, m: &ast::Mod, _sp: Span, id: ast::NodeId) {
         // This code is here instead of in visit_item so that the
         // crate module gets processed as well.
         if self.prev_exported {
-            assert!(self.exp_map2.contains_key(&id), "wut {}", id);
-            for export in self.exp_map2[id].iter() {
+            assert!(self.export_map.contains_key(&id), "wut {}", id);
+            for export in self.export_map[id].iter() {
                 if is_local(export.def_id) {
                     self.reexports.insert(export.def_id.node);
                 }
@@ -362,8 +408,8 @@ struct PrivacyVisitor<'a, 'tcx: 'a> {
     curitem: ast::NodeId,
     in_foreign: bool,
     parents: NodeMap<ast::NodeId>,
-    external_exports: resolve::ExternalExports,
-    last_private_map: resolve::LastPrivateMap,
+    external_exports: ExternalExports,
+    last_private_map: LastPrivateMap,
 }
 
 enum PrivacyResult {
@@ -719,25 +765,25 @@ fn check_path(&mut self, span: Span, path_id: ast::NodeId, path: &ast::Path) {
             };
 
             match self.last_private_map[path_id] {
-                resolve::LastMod(resolve::AllPublic) => {},
-                resolve::LastMod(resolve::DependsOn(def)) => {
+                LastMod(AllPublic) => {},
+                LastMod(DependsOn(def)) => {
                     self.report_error(ck_public(def));
                 },
-                resolve::LastImport{value_priv,
-                                    value_used: check_value,
-                                    type_priv,
-                                    type_used: check_type} => {
+                LastImport { value_priv,
+                             value_used: check_value,
+                             type_priv,
+                             type_used: check_type } => {
                     // This dance with found_error is because we don't want to report
                     // a privacy error twice for the same directive.
                     let found_error = match (type_priv, check_type) {
-                        (Some(resolve::DependsOn(def)), resolve::Used) => {
+                        (Some(DependsOn(def)), Used) => {
                             !self.report_error(ck_public(def))
                         },
                         _ => false,
                     };
                     if !found_error {
                         match (value_priv, check_value) {
-                            (Some(resolve::DependsOn(def)), resolve::Used) => {
+                            (Some(DependsOn(def)), Used) => {
                                 self.report_error(ck_public(def));
                             },
                             _ => {},
@@ -749,24 +795,24 @@ fn check_path(&mut self, span: Span, path_id: ast::NodeId, path: &ast::Path) {
                     // be illegal. We only report one error, even if it is
                     // illegal to import from both namespaces.
                     match (value_priv, check_value, type_priv, check_type) {
-                        (Some(p), resolve::Unused, None, _) |
-                        (None, _, Some(p), resolve::Unused) => {
+                        (Some(p), Unused, None, _) |
+                        (None, _, Some(p), Unused) => {
                             let p = match p {
-                                resolve::AllPublic => None,
-                                resolve::DependsOn(def) => ck_public(def),
+                                AllPublic => None,
+                                DependsOn(def) => ck_public(def),
                             };
                             if p.is_some() {
                                 self.report_error(p);
                             }
                         },
-                        (Some(v), resolve::Unused, Some(t), resolve::Unused) => {
+                        (Some(v), Unused, Some(t), Unused) => {
                             let v = match v {
-                                resolve::AllPublic => None,
-                                resolve::DependsOn(def) => ck_public(def),
+                                AllPublic => None,
+                                DependsOn(def) => ck_public(def),
                             };
                             let t = match t {
-                                resolve::AllPublic => None,
-                                resolve::DependsOn(def) => ck_public(def),
+                                AllPublic => None,
+                                DependsOn(def) => ck_public(def),
                             };
                             if let (Some(_), Some(t)) = (v, t) {
                                 self.report_error(Some(t));
@@ -1261,13 +1307,13 @@ fn trait_is_public(&self, trait_id: ast::NodeId) -> bool {
     }
 
     fn check_ty_param_bound(&self,
-                            span: Span,
                             ty_param_bound: &ast::TyParamBound) {
         if let ast::TraitTyParamBound(ref trait_ref) = *ty_param_bound {
             if !self.tcx.sess.features.borrow().visible_private_types &&
                 self.path_is_private_type(trait_ref.trait_ref.ref_id) {
+                    let span = trait_ref.trait_ref.path.span;
                     self.tcx.sess.span_err(span,
-                                           "private type in exported type \
+                                           "private trait in exported type \
                                             parameter bound");
             }
         }
@@ -1311,7 +1357,7 @@ fn visit_item(&mut self, item: &ast::Item) {
                 }
 
                 for bound in bounds.iter() {
-                    self.check_ty_param_bound(item.span, bound)
+                    self.check_ty_param_bound(bound)
                 }
             }
 
@@ -1449,16 +1495,17 @@ fn visit_item(&mut self, item: &ast::Item) {
     fn visit_generics(&mut self, generics: &ast::Generics) {
         for ty_param in generics.ty_params.iter() {
             for bound in ty_param.bounds.iter() {
-                self.check_ty_param_bound(ty_param.span, bound)
+                self.check_ty_param_bound(bound)
             }
         }
         for predicate in generics.where_clause.predicates.iter() {
             match predicate {
                 &ast::WherePredicate::BoundPredicate(ref bound_pred) => {
                     for bound in bound_pred.bounds.iter() {
-                        self.check_ty_param_bound(bound_pred.span, bound)
+                        self.check_ty_param_bound(bound)
                     }
                 }
+                &ast::WherePredicate::RegionPredicate(_) => {}
                 &ast::WherePredicate::EqPredicate(ref eq_pred) => {
                     self.visit_ty(&*eq_pred.ty);
                 }
@@ -1520,9 +1567,9 @@ fn visit_expr(&mut self, _: &ast::Expr) {}
 }
 
 pub fn check_crate(tcx: &ty::ctxt,
-                   exp_map2: &resolve::ExportMap2,
-                   external_exports: resolve::ExternalExports,
-                   last_private_map: resolve::LastPrivateMap)
+                   export_map: &def::ExportMap,
+                   external_exports: ExternalExports,
+                   last_private_map: LastPrivateMap)
                    -> (ExportedItems, PublicItems) {
     let krate = tcx.map.krate();
 
@@ -1561,7 +1608,7 @@ pub fn check_crate(tcx: &ty::ctxt,
         exported_items: NodeSet::new(),
         public_items: NodeSet::new(),
         reexports: NodeSet::new(),
-        exp_map2: exp_map2,
+        export_map: export_map,
         prev_exported: true,
         prev_public: true,
     };
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
deleted file mode 100644 (file)
index e1e376c..0000000
+++ /dev/null
@@ -1,6348 +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.
-
-#![allow(non_camel_case_types)]
-
-pub use self::PrivateDep::*;
-pub use self::ImportUse::*;
-pub use self::TraitItemKind::*;
-pub use self::LastPrivate::*;
-use self::PatternBindingMode::*;
-use self::Namespace::*;
-use self::NamespaceError::*;
-use self::NamespaceResult::*;
-use self::NameDefinition::*;
-use self::ImportDirectiveSubclass::*;
-use self::ReducedGraphParent::*;
-use self::ResolveResult::*;
-use self::FallbackSuggestion::*;
-use self::TypeParameters::*;
-use self::RibKind::*;
-use self::MethodSort::*;
-use self::UseLexicalScopeFlag::*;
-use self::ModulePrefixResult::*;
-use self::NameSearchType::*;
-use self::BareIdentifierPatternResolution::*;
-use self::DuplicateCheckingMode::*;
-use self::ParentLink::*;
-use self::ModuleKind::*;
-use self::TraitReferenceType::*;
-use self::FallbackChecks::*;
-
-use session::Session;
-use lint;
-use metadata::csearch;
-use metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
-use middle::def::*;
-use middle::lang_items::LanguageItems;
-use middle::pat_util::pat_bindings;
-use middle::subst::{ParamSpace, FnSpace, TypeSpace};
-use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory};
-use middle::ty::{CaptureModeMap, Freevar, FreevarMap};
-use util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap};
-
-use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
-use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField};
-use syntax::ast::{ExprClosure, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall};
-use syntax::ast::{ExprPath, ExprStruct, FnDecl};
-use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic, Generics};
-use syntax::ast::{Ident, ImplItem, Item, ItemEnum, ItemFn, ItemForeignMod};
-use syntax::ast::{ItemImpl, ItemMac, ItemMod, ItemStatic, ItemStruct};
-use syntax::ast::{ItemTrait, ItemTy, LOCAL_CRATE, Local, ItemConst};
-use syntax::ast::{MethodImplItem, Mod, Name, NamedField, NodeId};
-use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
-use syntax::ast::{PatRange, PatStruct, Path, PathListIdent, PathListMod};
-use syntax::ast::{PolyTraitRef, PrimTy, Public, SelfExplicit, SelfStatic};
-use syntax::ast::{RegionTyParamBound, StmtDecl, StructField};
-use syntax::ast::{StructVariantKind, TraitRef, TraitTyParamBound};
-use syntax::ast::{TupleVariantKind, Ty, TyBool, TyChar, TyClosure, TyF32};
-use syntax::ast::{TyF64, TyFloat, TyI, TyI8, TyI16, TyI32, TyI64, TyInt, TyObjectSum};
-use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyPolyTraitRef, TyQPath};
-use syntax::ast::{TyRptr, TyStr, TyU, TyU8, TyU16, TyU32, TyU64, TyUint};
-use syntax::ast::{TypeImplItem, UnnamedField};
-use syntax::ast::{Variant, ViewItem, ViewItemExternCrate};
-use syntax::ast::{ViewItemUse, ViewPathGlob, ViewPathList, ViewPathSimple};
-use syntax::ast::{Visibility};
-use syntax::ast;
-use syntax::ast_util::{mod, PostExpansionMethod, local_def, walk_pat};
-use syntax::attr::AttrMetaMethods;
-use syntax::ext::mtwt;
-use syntax::parse::token::{mod, special_names, special_idents};
-use syntax::codemap::{Span, DUMMY_SP, Pos};
-use syntax::owned_slice::OwnedSlice;
-use syntax::visit::{mod, Visitor};
-
-use std::collections::{HashMap, HashSet};
-use std::collections::hash_map::{Occupied, Vacant};
-use std::cell::{Cell, RefCell};
-use std::mem::replace;
-use std::rc::{Rc, Weak};
-use std::uint;
-
-// Definition mapping
-pub type DefMap = RefCell<NodeMap<Def>>;
-
-#[deriving(Copy)]
-struct binding_info {
-    span: Span,
-    binding_mode: BindingMode,
-}
-
-// Map from the name in a pattern to its binding mode.
-type BindingMap = HashMap<Name,binding_info>;
-
-// Trait method resolution
-pub type TraitMap = NodeMap<Vec<DefId> >;
-
-// This is the replacement export map. It maps a module to all of the exports
-// within.
-pub type ExportMap2 = NodeMap<Vec<Export2>>;
-
-pub struct Export2 {
-    pub name: String,        // The name of the target.
-    pub def_id: DefId,       // The definition of the target.
-}
-
-// This set contains all exported definitions from external crates. The set does
-// not contain any entries from local crates.
-pub type ExternalExports = DefIdSet;
-
-// FIXME: dox
-pub type LastPrivateMap = NodeMap<LastPrivate>;
-
-#[deriving(Copy, Show)]
-pub enum LastPrivate {
-    LastMod(PrivateDep),
-    // `use` directives (imports) can refer to two separate definitions in the
-    // type and value namespaces. We record here the last private node for each
-    // and whether the import is in fact used for each.
-    // If the Option<PrivateDep> fields are None, it means there is no definition
-    // in that namespace.
-    LastImport{value_priv: Option<PrivateDep>,
-               value_used: ImportUse,
-               type_priv: Option<PrivateDep>,
-               type_used: ImportUse},
-}
-
-#[deriving(Copy, Show)]
-pub enum PrivateDep {
-    AllPublic,
-    DependsOn(DefId),
-}
-
-// How an import is used.
-#[deriving(Copy, PartialEq, Show)]
-pub enum ImportUse {
-    Unused,       // The import is not used.
-    Used,         // The import is used.
-}
-
-impl LastPrivate {
-    fn or(self, other: LastPrivate) -> LastPrivate {
-        match (self, other) {
-            (me, LastMod(AllPublic)) => me,
-            (_, other) => other,
-        }
-    }
-}
-
-#[deriving(Copy, PartialEq)]
-enum PatternBindingMode {
-    RefutableMode,
-    LocalIrrefutableMode,
-    ArgumentIrrefutableMode,
-}
-
-#[deriving(Copy, PartialEq, Eq, Hash, Show)]
-enum Namespace {
-    TypeNS,
-    ValueNS
-}
-
-#[deriving(Copy, PartialEq)]
-enum NamespaceError {
-    NoError,
-    ModuleError,
-    TypeError,
-    ValueError
-}
-
-/// A NamespaceResult represents the result of resolving an import in
-/// a particular namespace. The result is either definitely-resolved,
-/// definitely- unresolved, or unknown.
-#[deriving(Clone)]
-enum NamespaceResult {
-    /// Means that resolve hasn't gathered enough information yet to determine
-    /// whether the name is bound in this namespace. (That is, it hasn't
-    /// resolved all `use` directives yet.)
-    UnknownResult,
-    /// Means that resolve has determined that the name is definitely
-    /// not bound in the namespace.
-    UnboundResult,
-    /// Means that resolve has determined that the name is bound in the Module
-    /// argument, and specified by the NameBindings argument.
-    BoundResult(Rc<Module>, Rc<NameBindings>)
-}
-
-impl NamespaceResult {
-    fn is_unknown(&self) -> bool {
-        match *self {
-            UnknownResult => true,
-            _ => false
-        }
-    }
-    fn is_unbound(&self) -> bool {
-        match *self {
-            UnboundResult => true,
-            _ => false
-        }
-    }
-}
-
-enum NameDefinition {
-    NoNameDefinition,           //< The name was unbound.
-    ChildNameDefinition(Def, LastPrivate), //< The name identifies an immediate child.
-    ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
-}
-
-impl<'a, 'v> Visitor<'v> for Resolver<'a> {
-    fn visit_item(&mut self, item: &Item) {
-        self.resolve_item(item);
-    }
-    fn visit_arm(&mut self, arm: &Arm) {
-        self.resolve_arm(arm);
-    }
-    fn visit_block(&mut self, block: &Block) {
-        self.resolve_block(block);
-    }
-    fn visit_expr(&mut self, expr: &Expr) {
-        self.resolve_expr(expr);
-    }
-    fn visit_local(&mut self, local: &Local) {
-        self.resolve_local(local);
-    }
-    fn visit_ty(&mut self, ty: &Ty) {
-        self.resolve_type(ty);
-    }
-}
-
-/// Contains data for specific types of import directives.
-#[deriving(Copy)]
-enum ImportDirectiveSubclass {
-    SingleImport(Name /* target */, Name /* source */),
-    GlobImport
-}
-
-/// The context that we thread through while building the reduced graph.
-#[deriving(Clone)]
-enum ReducedGraphParent {
-    ModuleReducedGraphParent(Rc<Module>)
-}
-
-impl ReducedGraphParent {
-    fn module(&self) -> Rc<Module> {
-        match *self {
-            ModuleReducedGraphParent(ref m) => {
-                m.clone()
-            }
-        }
-    }
-}
-
-type ErrorMessage = Option<(Span, String)>;
-
-enum ResolveResult<T> {
-    Failed(ErrorMessage),   // Failed to resolve the name, optional helpful error message.
-    Indeterminate,          // Couldn't determine due to unresolved globs.
-    Success(T)              // Successfully resolved the import.
-}
-
-impl<T> ResolveResult<T> {
-    fn indeterminate(&self) -> bool {
-        match *self { Indeterminate => true, _ => false }
-    }
-}
-
-enum FallbackSuggestion {
-    NoSuggestion,
-    Field,
-    Method,
-    TraitItem,
-    StaticMethod(String),
-    TraitMethod(String),
-}
-
-#[deriving(Copy)]
-enum TypeParameters<'a> {
-    NoTypeParameters,
-    HasTypeParameters(
-        // Type parameters.
-        &'a Generics,
-
-        // Identifies the things that these parameters
-        // were declared on (type, fn, etc)
-        ParamSpace,
-
-        // ID of the enclosing item.
-        NodeId,
-
-        // The kind of the rib used for type parameters.
-        RibKind)
-}
-
-// The rib kind controls the translation of local
-// definitions (`DefLocal`) to upvars (`DefUpvar`).
-#[deriving(Copy, Show)]
-enum RibKind {
-    // No translation needs to be applied.
-    NormalRibKind,
-
-    // We passed through a closure scope at the given node ID.
-    // Translate upvars as appropriate.
-    ClosureRibKind(NodeId /* func id */, NodeId /* body id if proc or unboxed */),
-
-    // We passed through an impl or trait and are now in one of its
-    // methods. Allow references to ty params that impl or trait
-    // binds. Disallow any other upvars (including other ty params that are
-    // upvars).
-              // parent;   method itself
-    MethodRibKind(NodeId, MethodSort),
-
-    // We passed through an item scope. Disallow upvars.
-    ItemRibKind,
-
-    // We're in a constant item. Can't refer to dynamic stuff.
-    ConstantItemRibKind
-}
-
-// Methods can be required or provided. RequiredMethod methods only occur in traits.
-#[deriving(Copy, Show)]
-enum MethodSort {
-    RequiredMethod,
-    ProvidedMethod(NodeId)
-}
-
-#[deriving(Copy)]
-enum UseLexicalScopeFlag {
-    DontUseLexicalScope,
-    UseLexicalScope
-}
-
-enum ModulePrefixResult {
-    NoPrefixFound,
-    PrefixFound(Rc<Module>, uint)
-}
-
-#[deriving(Clone, Copy, Eq, PartialEq)]
-pub enum TraitItemKind {
-    NonstaticMethodTraitItemKind,
-    StaticMethodTraitItemKind,
-    TypeTraitItemKind,
-}
-
-impl TraitItemKind {
-    pub fn from_explicit_self_category(explicit_self_category:
-                                       ExplicitSelfCategory)
-                                       -> TraitItemKind {
-        if explicit_self_category == StaticExplicitSelfCategory {
-            StaticMethodTraitItemKind
-        } else {
-            NonstaticMethodTraitItemKind
-        }
-    }
-}
-
-#[deriving(Copy, PartialEq)]
-enum NameSearchType {
-    /// We're doing a name search in order to resolve a `use` directive.
-    ImportSearch,
-
-    /// We're doing a name search in order to resolve a path type, a path
-    /// expression, or a path pattern.
-    PathSearch,
-}
-
-#[deriving(Copy)]
-enum BareIdentifierPatternResolution {
-    FoundStructOrEnumVariant(Def, LastPrivate),
-    FoundConst(Def, LastPrivate),
-    BareIdentifierPatternUnresolved
-}
-
-// Specifies how duplicates should be handled when adding a child item if
-// another item exists with the same name in some namespace.
-#[deriving(Copy, PartialEq)]
-enum DuplicateCheckingMode {
-    ForbidDuplicateModules,
-    ForbidDuplicateTypesAndModules,
-    ForbidDuplicateValues,
-    ForbidDuplicateTypesAndValues,
-    OverwriteDuplicates
-}
-
-/// One local scope.
-#[deriving(Show)]
-struct Rib {
-    bindings: HashMap<Name, DefLike>,
-    kind: RibKind,
-}
-
-impl Rib {
-    fn new(kind: RibKind) -> Rib {
-        Rib {
-            bindings: HashMap::new(),
-            kind: kind
-        }
-    }
-}
-
-/// One import directive.
-struct ImportDirective {
-    module_path: Vec<Name>,
-    subclass: ImportDirectiveSubclass,
-    span: Span,
-    id: NodeId,
-    is_public: bool, // see note in ImportResolution about how to use this
-    shadowable: bool,
-}
-
-impl ImportDirective {
-    fn new(module_path: Vec<Name> ,
-           subclass: ImportDirectiveSubclass,
-           span: Span,
-           id: NodeId,
-           is_public: bool,
-           shadowable: bool)
-           -> ImportDirective {
-        ImportDirective {
-            module_path: module_path,
-            subclass: subclass,
-            span: span,
-            id: id,
-            is_public: is_public,
-            shadowable: shadowable,
-        }
-    }
-}
-
-/// The item that an import resolves to.
-#[deriving(Clone)]
-struct Target {
-    target_module: Rc<Module>,
-    bindings: Rc<NameBindings>,
-    shadowable: bool,
-}
-
-impl Target {
-    fn new(target_module: Rc<Module>,
-           bindings: Rc<NameBindings>,
-           shadowable: bool)
-           -> Target {
-        Target {
-            target_module: target_module,
-            bindings: bindings,
-            shadowable: shadowable,
-        }
-    }
-}
-
-/// An ImportResolution represents a particular `use` directive.
-struct ImportResolution {
-    /// Whether this resolution came from a `use` or a `pub use`. Note that this
-    /// should *not* be used whenever resolution is being performed, this is
-    /// only looked at for glob imports statements currently. Privacy testing
-    /// occurs during a later phase of compilation.
-    is_public: bool,
-
-    // The number of outstanding references to this name. When this reaches
-    // zero, outside modules can count on the targets being correct. Before
-    // then, all bets are off; future imports could override this name.
-    outstanding_references: uint,
-
-    /// The value that this `use` directive names, if there is one.
-    value_target: Option<Target>,
-    /// The source node of the `use` directive leading to the value target
-    /// being non-none
-    value_id: NodeId,
-
-    /// The type that this `use` directive names, if there is one.
-    type_target: Option<Target>,
-    /// The source node of the `use` directive leading to the type target
-    /// being non-none
-    type_id: NodeId,
-}
-
-impl ImportResolution {
-    fn new(id: NodeId, is_public: bool) -> ImportResolution {
-        ImportResolution {
-            type_id: id,
-            value_id: id,
-            outstanding_references: 0,
-            value_target: None,
-            type_target: None,
-            is_public: is_public,
-        }
-    }
-
-    fn target_for_namespace(&self, namespace: Namespace)
-                                -> Option<Target> {
-        match namespace {
-            TypeNS  => self.type_target.clone(),
-            ValueNS => self.value_target.clone(),
-        }
-    }
-
-    fn id(&self, namespace: Namespace) -> NodeId {
-        match namespace {
-            TypeNS  => self.type_id,
-            ValueNS => self.value_id,
-        }
-    }
-}
-
-/// The link from a module up to its nearest parent node.
-#[deriving(Clone)]
-enum ParentLink {
-    NoParentLink,
-    ModuleParentLink(Weak<Module>, Name),
-    BlockParentLink(Weak<Module>, NodeId)
-}
-
-/// The type of module this is.
-#[deriving(Copy, PartialEq)]
-enum ModuleKind {
-    NormalModuleKind,
-    TraitModuleKind,
-    ImplModuleKind,
-    EnumModuleKind,
-    AnonymousModuleKind,
-}
-
-/// One node in the tree of modules.
-struct Module {
-    parent_link: ParentLink,
-    def_id: Cell<Option<DefId>>,
-    kind: Cell<ModuleKind>,
-    is_public: bool,
-
-    children: RefCell<HashMap<Name, Rc<NameBindings>>>,
-    imports: RefCell<Vec<ImportDirective>>,
-
-    // The external module children of this node that were declared with
-    // `extern crate`.
-    external_module_children: RefCell<HashMap<Name, Rc<Module>>>,
-
-    // The anonymous children of this node. Anonymous children are pseudo-
-    // modules that are implicitly created around items contained within
-    // blocks.
-    //
-    // For example, if we have this:
-    //
-    //  fn f() {
-    //      fn g() {
-    //          ...
-    //      }
-    //  }
-    //
-    // There will be an anonymous module created around `g` with the ID of the
-    // entry block for `f`.
-    anonymous_children: RefCell<NodeMap<Rc<Module>>>,
-
-    // The status of resolving each import in this module.
-    import_resolutions: RefCell<HashMap<Name, ImportResolution>>,
-
-    // The number of unresolved globs that this module exports.
-    glob_count: Cell<uint>,
-
-    // The index of the import we're resolving.
-    resolved_import_count: Cell<uint>,
-
-    // Whether this module is populated. If not populated, any attempt to
-    // access the children must be preceded with a
-    // `populate_module_if_necessary` call.
-    populated: Cell<bool>,
-}
-
-impl Module {
-    fn new(parent_link: ParentLink,
-           def_id: Option<DefId>,
-           kind: ModuleKind,
-           external: bool,
-           is_public: bool)
-           -> Module {
-        Module {
-            parent_link: parent_link,
-            def_id: Cell::new(def_id),
-            kind: Cell::new(kind),
-            is_public: is_public,
-            children: RefCell::new(HashMap::new()),
-            imports: RefCell::new(Vec::new()),
-            external_module_children: RefCell::new(HashMap::new()),
-            anonymous_children: RefCell::new(NodeMap::new()),
-            import_resolutions: RefCell::new(HashMap::new()),
-            glob_count: Cell::new(0),
-            resolved_import_count: Cell::new(0),
-            populated: Cell::new(!external),
-        }
-    }
-
-    fn all_imports_resolved(&self) -> bool {
-        self.imports.borrow().len() == self.resolved_import_count.get()
-    }
-}
-
-bitflags! {
-    #[deriving(Show)]
-    flags DefModifiers: u8 {
-        const PUBLIC            = 0b0000_0001,
-        const IMPORTABLE        = 0b0000_0010,
-    }
-}
-
-// Records a possibly-private type definition.
-#[deriving(Clone)]
-struct TypeNsDef {
-    modifiers: DefModifiers, // see note in ImportResolution about how to use this
-    module_def: Option<Rc<Module>>,
-    type_def: Option<Def>,
-    type_span: Option<Span>
-}
-
-// Records a possibly-private value definition.
-#[deriving(Clone, Copy, Show)]
-struct ValueNsDef {
-    modifiers: DefModifiers, // see note in ImportResolution about how to use this
-    def: Def,
-    value_span: Option<Span>,
-}
-
-// Records the definitions (at most one for each namespace) that a name is
-// bound to.
-struct NameBindings {
-    type_def: RefCell<Option<TypeNsDef>>,   //< Meaning in type namespace.
-    value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
-}
-
-/// Ways in which a trait can be referenced
-#[deriving(Copy)]
-enum TraitReferenceType {
-    TraitImplementation,             // impl SomeTrait for T { ... }
-    TraitDerivation,                 // trait T : SomeTrait { ... }
-    TraitBoundingTypeParameter,      // fn f<T:SomeTrait>() { ... }
-    TraitObject,                     // Box<for<'a> SomeTrait>
-    TraitQPath,                      // <T as SomeTrait>::
-}
-
-impl NameBindings {
-    fn new() -> NameBindings {
-        NameBindings {
-            type_def: RefCell::new(None),
-            value_def: RefCell::new(None),
-        }
-    }
-
-    /// Creates a new module in this set of name bindings.
-    fn define_module(&self,
-                     parent_link: ParentLink,
-                     def_id: Option<DefId>,
-                     kind: ModuleKind,
-                     external: bool,
-                     is_public: bool,
-                     sp: Span) {
-        // Merges the module with the existing type def or creates a new one.
-        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
-        let module_ = Rc::new(Module::new(parent_link,
-                                          def_id,
-                                          kind,
-                                          external,
-                                          is_public));
-        let type_def = self.type_def.borrow().clone();
-        match type_def {
-            None => {
-                *self.type_def.borrow_mut() = Some(TypeNsDef {
-                    modifiers: modifiers,
-                    module_def: Some(module_),
-                    type_def: None,
-                    type_span: Some(sp)
-                });
-            }
-            Some(type_def) => {
-                *self.type_def.borrow_mut() = Some(TypeNsDef {
-                    modifiers: modifiers,
-                    module_def: Some(module_),
-                    type_span: Some(sp),
-                    type_def: type_def.type_def
-                });
-            }
-        }
-    }
-
-    /// Sets the kind of the module, creating a new one if necessary.
-    fn set_module_kind(&self,
-                       parent_link: ParentLink,
-                       def_id: Option<DefId>,
-                       kind: ModuleKind,
-                       external: bool,
-                       is_public: bool,
-                       _sp: Span) {
-        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
-        let type_def = self.type_def.borrow().clone();
-        match type_def {
-            None => {
-                let module = Module::new(parent_link,
-                                         def_id,
-                                         kind,
-                                         external,
-                                         is_public);
-                *self.type_def.borrow_mut() = Some(TypeNsDef {
-                    modifiers: modifiers,
-                    module_def: Some(Rc::new(module)),
-                    type_def: None,
-                    type_span: None,
-                });
-            }
-            Some(type_def) => {
-                match type_def.module_def {
-                    None => {
-                        let module = Module::new(parent_link,
-                                                 def_id,
-                                                 kind,
-                                                 external,
-                                                 is_public);
-                        *self.type_def.borrow_mut() = Some(TypeNsDef {
-                            modifiers: modifiers,
-                            module_def: Some(Rc::new(module)),
-                            type_def: type_def.type_def,
-                            type_span: None,
-                        });
-                    }
-                    Some(module_def) => module_def.kind.set(kind),
-                }
-            }
-        }
-    }
-
-    /// Records a type definition.
-    fn define_type(&self, def: Def, sp: Span, modifiers: DefModifiers) {
-        debug!("defining type for def {} with modifiers {}", def, modifiers);
-        // Merges the type with the existing type def or creates a new one.
-        let type_def = self.type_def.borrow().clone();
-        match type_def {
-            None => {
-                *self.type_def.borrow_mut() = Some(TypeNsDef {
-                    module_def: None,
-                    type_def: Some(def),
-                    type_span: Some(sp),
-                    modifiers: modifiers,
-                });
-            }
-            Some(type_def) => {
-                *self.type_def.borrow_mut() = Some(TypeNsDef {
-                    module_def: type_def.module_def,
-                    type_def: Some(def),
-                    type_span: Some(sp),
-                    modifiers: modifiers,
-                });
-            }
-        }
-    }
-
-    /// Records a value definition.
-    fn define_value(&self, def: Def, sp: Span, modifiers: DefModifiers) {
-        debug!("defining value for def {} with modifiers {}", def, modifiers);
-        *self.value_def.borrow_mut() = Some(ValueNsDef {
-            def: def,
-            value_span: Some(sp),
-            modifiers: modifiers,
-        });
-    }
-
-    /// Returns the module node if applicable.
-    fn get_module_if_available(&self) -> Option<Rc<Module>> {
-        match *self.type_def.borrow() {
-            Some(ref type_def) => type_def.module_def.clone(),
-            None => None
-        }
-    }
-
-    /// Returns the module node. Panics if this node does not have a module
-    /// definition.
-    fn get_module(&self) -> Rc<Module> {
-        match self.get_module_if_available() {
-            None => {
-                panic!("get_module called on a node with no module \
-                       definition!")
-            }
-            Some(module_def) => module_def
-        }
-    }
-
-    fn defined_in_namespace(&self, namespace: Namespace) -> bool {
-        match namespace {
-            TypeNS   => return self.type_def.borrow().is_some(),
-            ValueNS  => return self.value_def.borrow().is_some()
-        }
-    }
-
-    fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
-        self.defined_in_namespace_with(namespace, PUBLIC)
-    }
-
-    fn defined_in_namespace_with(&self, namespace: Namespace, modifiers: DefModifiers) -> bool {
-        match namespace {
-            TypeNS => match *self.type_def.borrow() {
-                Some(ref def) => def.modifiers.contains(modifiers), None => false
-            },
-            ValueNS => match *self.value_def.borrow() {
-                Some(ref def) => def.modifiers.contains(modifiers), None => false
-            }
-        }
-    }
-
-    fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
-        match namespace {
-            TypeNS => {
-                match *self.type_def.borrow() {
-                    None => None,
-                    Some(ref type_def) => {
-                        match type_def.type_def {
-                            Some(type_def) => Some(type_def),
-                            None => {
-                                match type_def.module_def {
-                                    Some(ref module) => {
-                                        match module.def_id.get() {
-                                            Some(did) => Some(DefMod(did)),
-                                            None => None,
-                                        }
-                                    }
-                                    None => None,
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-            ValueNS => {
-                match *self.value_def.borrow() {
-                    None => None,
-                    Some(value_def) => Some(value_def.def)
-                }
-            }
-        }
-    }
-
-    fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
-        if self.defined_in_namespace(namespace) {
-            match namespace {
-                TypeNS  => {
-                    match *self.type_def.borrow() {
-                        None => None,
-                        Some(ref type_def) => type_def.type_span
-                    }
-                }
-                ValueNS => {
-                    match *self.value_def.borrow() {
-                        None => None,
-                        Some(ref value_def) => value_def.value_span
-                    }
-                }
-            }
-        } else {
-            None
-        }
-    }
-}
-
-/// Interns the names of the primitive types.
-struct PrimitiveTypeTable {
-    primitive_types: HashMap<Name, PrimTy>,
-}
-
-impl PrimitiveTypeTable {
-    fn new() -> PrimitiveTypeTable {
-        let mut table = PrimitiveTypeTable {
-            primitive_types: HashMap::new()
-        };
-
-        table.intern("bool",    TyBool);
-        table.intern("char",    TyChar);
-        table.intern("f32",     TyFloat(TyF32));
-        table.intern("f64",     TyFloat(TyF64));
-        table.intern("int",     TyInt(TyI));
-        table.intern("i8",      TyInt(TyI8));
-        table.intern("i16",     TyInt(TyI16));
-        table.intern("i32",     TyInt(TyI32));
-        table.intern("i64",     TyInt(TyI64));
-        table.intern("str",     TyStr);
-        table.intern("uint",    TyUint(TyU));
-        table.intern("u8",      TyUint(TyU8));
-        table.intern("u16",     TyUint(TyU16));
-        table.intern("u32",     TyUint(TyU32));
-        table.intern("u64",     TyUint(TyU64));
-
-        table
-    }
-
-    fn intern(&mut self, string: &str, primitive_type: PrimTy) {
-        self.primitive_types.insert(token::intern(string), primitive_type);
-    }
-}
-
-
-fn namespace_error_to_string(ns: NamespaceError) -> &'static str {
-    match ns {
-        NoError                 => "",
-        ModuleError | TypeError => "type or module",
-        ValueError              => "value",
-    }
-}
-
-/// The main resolver class.
-struct Resolver<'a> {
-    session: &'a Session,
-
-    graph_root: NameBindings,
-
-    trait_item_map: FnvHashMap<(Name, DefId), TraitItemKind>,
-
-    structs: FnvHashMap<DefId, Vec<Name>>,
-
-    // The number of imports that are currently unresolved.
-    unresolved_imports: uint,
-
-    // The module that represents the current item scope.
-    current_module: Rc<Module>,
-
-    // The current set of local scopes, for values.
-    // FIXME #4948: Reuse ribs to avoid allocation.
-    value_ribs: Vec<Rib>,
-
-    // The current set of local scopes, for types.
-    type_ribs: Vec<Rib>,
-
-    // The current set of local scopes, for labels.
-    label_ribs: Vec<Rib>,
-
-    // The trait that the current context can refer to.
-    current_trait_ref: Option<(DefId, TraitRef)>,
-
-    // The current self type if inside an impl (used for better errors).
-    current_self_type: Option<Ty>,
-
-    // The ident for the keyword "self".
-    self_name: Name,
-    // The ident for the non-keyword "Self".
-    type_self_name: Name,
-
-    // The idents for the primitive types.
-    primitive_type_table: PrimitiveTypeTable,
-
-    def_map: DefMap,
-    freevars: RefCell<FreevarMap>,
-    freevars_seen: RefCell<NodeMap<NodeSet>>,
-    capture_mode_map: CaptureModeMap,
-    export_map2: ExportMap2,
-    trait_map: TraitMap,
-    external_exports: ExternalExports,
-    last_private: LastPrivateMap,
-
-    // Whether or not to print error messages. Can be set to true
-    // when getting additional info for error message suggestions,
-    // so as to avoid printing duplicate errors
-    emit_errors: bool,
-
-    used_imports: HashSet<(NodeId, Namespace)>,
-    used_crates: HashSet<CrateNum>,
-}
-
-struct BuildReducedGraphVisitor<'a, 'b:'a> {
-    resolver: &'a mut Resolver<'b>,
-    parent: ReducedGraphParent
-}
-
-impl<'a, 'b, 'v> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b> {
-
-    fn visit_item(&mut self, item: &Item) {
-        let p = self.resolver.build_reduced_graph_for_item(item, self.parent.clone());
-        let old_parent = replace(&mut self.parent, p);
-        visit::walk_item(self, item);
-        self.parent = old_parent;
-    }
-
-    fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
-        let parent = self.parent.clone();
-        self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
-                                                           parent.clone(),
-                                                           |r| {
-            let mut v = BuildReducedGraphVisitor {
-                resolver: r,
-                parent: parent.clone()
-            };
-            visit::walk_foreign_item(&mut v, foreign_item);
-        })
-    }
-
-    fn visit_view_item(&mut self, view_item: &ViewItem) {
-        self.resolver.build_reduced_graph_for_view_item(view_item, self.parent.clone());
-    }
-
-    fn visit_block(&mut self, block: &Block) {
-        let np = self.resolver.build_reduced_graph_for_block(block, self.parent.clone());
-        let old_parent = replace(&mut self.parent, np);
-        visit::walk_block(self, block);
-        self.parent = old_parent;
-    }
-
-}
-
-struct UnusedImportCheckVisitor<'a, 'b:'a> {
-    resolver: &'a mut Resolver<'b>
-}
-
-impl<'a, 'b, 'v> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b> {
-    fn visit_view_item(&mut self, vi: &ViewItem) {
-        self.resolver.check_for_item_unused_imports(vi);
-        visit::walk_view_item(self, vi);
-    }
-}
-
-#[deriving(PartialEq)]
-enum FallbackChecks {
-    Everything,
-    OnlyTraitAndStatics
-}
-
-
-impl<'a> Resolver<'a> {
-    fn new(session: &'a Session, crate_span: Span) -> Resolver<'a> {
-        let graph_root = NameBindings::new();
-
-        graph_root.define_module(NoParentLink,
-                                 Some(DefId { krate: 0, node: 0 }),
-                                 NormalModuleKind,
-                                 false,
-                                 true,
-                                 crate_span);
-
-        let current_module = graph_root.get_module();
-
-        Resolver {
-            session: session,
-
-            // The outermost module has def ID 0; this is not reflected in the
-            // AST.
-
-            graph_root: graph_root,
-
-            trait_item_map: FnvHashMap::new(),
-            structs: FnvHashMap::new(),
-
-            unresolved_imports: 0,
-
-            current_module: current_module,
-            value_ribs: Vec::new(),
-            type_ribs: Vec::new(),
-            label_ribs: Vec::new(),
-
-            current_trait_ref: None,
-            current_self_type: None,
-
-            self_name: special_names::self_,
-            type_self_name: special_names::type_self,
-
-            primitive_type_table: PrimitiveTypeTable::new(),
-
-            def_map: RefCell::new(NodeMap::new()),
-            freevars: RefCell::new(NodeMap::new()),
-            freevars_seen: RefCell::new(NodeMap::new()),
-            capture_mode_map: NodeMap::new(),
-            export_map2: NodeMap::new(),
-            trait_map: NodeMap::new(),
-            used_imports: HashSet::new(),
-            used_crates: HashSet::new(),
-            external_exports: DefIdSet::new(),
-            last_private: NodeMap::new(),
-
-            emit_errors: true,
-        }
-    }
-    /// The main name resolution procedure.
-    fn resolve(&mut self, krate: &ast::Crate) {
-        self.build_reduced_graph(krate);
-        self.session.abort_if_errors();
-
-        self.resolve_imports();
-        self.session.abort_if_errors();
-
-        self.record_exports();
-        self.session.abort_if_errors();
-
-        self.resolve_crate(krate);
-        self.session.abort_if_errors();
-
-        self.check_for_unused_imports(krate);
-    }
-
-    //
-    // Reduced graph building
-    //
-    // Here we build the "reduced graph": the graph of the module tree without
-    // any imports resolved.
-    //
-
-    /// Constructs the reduced graph for the entire crate.
-    fn build_reduced_graph(&mut self, krate: &ast::Crate) {
-        let parent = ModuleReducedGraphParent(self.graph_root.get_module());
-        let mut visitor = BuildReducedGraphVisitor {
-            resolver: self,
-            parent: parent
-        };
-        visit::walk_crate(&mut visitor, krate);
-    }
-
-    /// Adds a new child item to the module definition of the parent node and
-    /// returns its corresponding name bindings as well as the current parent.
-    /// Or, if we're inside a block, creates (or reuses) an anonymous module
-    /// corresponding to the innermost block ID and returns the name bindings
-    /// as well as the newly-created parent.
-    ///
-    /// # Panics
-    ///
-    /// Panics if this node does not have a module definition and we are not inside
-    /// a block.
-    fn add_child(&self,
-                 name: Name,
-                 reduced_graph_parent: ReducedGraphParent,
-                 duplicate_checking_mode: DuplicateCheckingMode,
-                 // For printing errors
-                 sp: Span)
-                 -> Rc<NameBindings> {
-        // If this is the immediate descendant of a module, then we add the
-        // child name directly. Otherwise, we create or reuse an anonymous
-        // module and add the child to that.
-
-        let module_ = reduced_graph_parent.module();
-
-        self.check_for_conflicts_between_external_crates_and_items(&*module_,
-                                                                   name,
-                                                                   sp);
-
-        // Add or reuse the child.
-        let child = module_.children.borrow().get(&name).cloned();
-        match child {
-            None => {
-                let child = Rc::new(NameBindings::new());
-                module_.children.borrow_mut().insert(name, child.clone());
-                child
-            }
-            Some(child) => {
-                // Enforce the duplicate checking mode:
-                //
-                // * If we're requesting duplicate module checking, check that
-                //   there isn't a module in the module with the same name.
-                //
-                // * If we're requesting duplicate type checking, check that
-                //   there isn't a type in the module with the same name.
-                //
-                // * If we're requesting duplicate value checking, check that
-                //   there isn't a value in the module with the same name.
-                //
-                // * If we're requesting duplicate type checking and duplicate
-                //   value checking, check that there isn't a duplicate type
-                //   and a duplicate value with the same name.
-                //
-                // * If no duplicate checking was requested at all, do
-                //   nothing.
-
-                let mut duplicate_type = NoError;
-                let ns = match duplicate_checking_mode {
-                    ForbidDuplicateModules => {
-                        if child.get_module_if_available().is_some() {
-                            duplicate_type = ModuleError;
-                        }
-                        Some(TypeNS)
-                    }
-                    ForbidDuplicateTypesAndModules => {
-                        match child.def_for_namespace(TypeNS) {
-                            None => {}
-                            Some(_) if child.get_module_if_available()
-                                            .map(|m| m.kind.get()) ==
-                                       Some(ImplModuleKind) => {}
-                            Some(_) => duplicate_type = TypeError
-                        }
-                        Some(TypeNS)
-                    }
-                    ForbidDuplicateValues => {
-                        if child.defined_in_namespace(ValueNS) {
-                            duplicate_type = ValueError;
-                        }
-                        Some(ValueNS)
-                    }
-                    ForbidDuplicateTypesAndValues => {
-                        let mut n = None;
-                        match child.def_for_namespace(TypeNS) {
-                            Some(DefMod(_)) | None => {}
-                            Some(_) => {
-                                n = Some(TypeNS);
-                                duplicate_type = TypeError;
-                            }
-                        };
-                        if child.defined_in_namespace(ValueNS) {
-                            duplicate_type = ValueError;
-                            n = Some(ValueNS);
-                        }
-                        n
-                    }
-                    OverwriteDuplicates => None
-                };
-                if duplicate_type != NoError {
-                    // Return an error here by looking up the namespace that
-                    // had the duplicate.
-                    let ns = ns.unwrap();
-                    self.resolve_error(sp,
-                        format!("duplicate definition of {} `{}`",
-                             namespace_error_to_string(duplicate_type),
-                             token::get_name(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_string(duplicate_type),
-                                      token::get_name(name)).as_slice());
-                        }
-                    }
-                }
-                child
-            }
-        }
-    }
-
-    fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
-        // If the block has view items, we need an anonymous module.
-        if block.view_items.len() > 0 {
-            return true;
-        }
-
-        // Check each statement.
-        for statement in block.stmts.iter() {
-            match statement.node {
-                StmtDecl(ref declaration, _) => {
-                    match declaration.node {
-                        DeclItem(_) => {
-                            return true;
-                        }
-                        _ => {
-                            // Keep searching.
-                        }
-                    }
-                }
-                _ => {
-                    // Keep searching.
-                }
-            }
-        }
-
-        // If we found neither view items nor items, we don't need to create
-        // an anonymous module.
-
-        return false;
-    }
-
-    fn get_parent_link(&mut self, parent: ReducedGraphParent, name: Name)
-                       -> ParentLink {
-        match parent {
-            ModuleReducedGraphParent(module_) => {
-                return ModuleParentLink(module_.downgrade(), name);
-            }
-        }
-    }
-
-    /// Constructs the reduced graph for one item.
-    fn build_reduced_graph_for_item(&mut self,
-                                    item: &Item,
-                                    parent: ReducedGraphParent)
-                                    -> ReducedGraphParent
-    {
-        let name = item.ident.name;
-        let sp = item.span;
-        let is_public = item.vis == ast::Public;
-        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
-
-        match item.node {
-            ItemMod(..) => {
-                let name_bindings =
-                    self.add_child(name, parent.clone(), ForbidDuplicateModules, sp);
-
-                let parent_link = self.get_parent_link(parent, name);
-                let def_id = DefId { krate: 0, node: item.id };
-                name_bindings.define_module(parent_link,
-                                            Some(def_id),
-                                            NormalModuleKind,
-                                            false,
-                                            item.vis == ast::Public,
-                                            sp);
-
-                ModuleReducedGraphParent(name_bindings.get_module())
-            }
-
-            ItemForeignMod(..) => parent,
-
-            // These items live in the value namespace.
-            ItemStatic(_, m, _) => {
-                let name_bindings =
-                    self.add_child(name, parent.clone(), ForbidDuplicateValues, sp);
-                let mutbl = m == ast::MutMutable;
-
-                name_bindings.define_value
-                    (DefStatic(local_def(item.id), mutbl), sp, modifiers);
-                parent
-            }
-            ItemConst(_, _) => {
-                self.add_child(name, parent.clone(), ForbidDuplicateValues, sp)
-                    .define_value(DefConst(local_def(item.id)),
-                                  sp, modifiers);
-                parent
-            }
-            ItemFn(_, _, _, _, _) => {
-                let name_bindings =
-                    self.add_child(name, parent.clone(), ForbidDuplicateValues, sp);
-
-                let def = DefFn(local_def(item.id), false);
-                name_bindings.define_value(def, sp, modifiers);
-                parent
-            }
-
-            // These items live in the type namespace.
-            ItemTy(..) => {
-                let name_bindings =
-                    self.add_child(name,
-                                   parent.clone(),
-                                   ForbidDuplicateTypesAndModules,
-                                   sp);
-
-                name_bindings.define_type
-                    (DefTy(local_def(item.id), false), sp, modifiers);
-                parent
-            }
-
-            ItemEnum(ref enum_definition, _) => {
-                let name_bindings =
-                    self.add_child(name,
-                                   parent.clone(),
-                                   ForbidDuplicateTypesAndModules,
-                                   sp);
-
-                name_bindings.define_type
-                    (DefTy(local_def(item.id), true), sp, modifiers);
-
-                let parent_link = self.get_parent_link(parent.clone(), name);
-                // We want to make sure the module type is EnumModuleKind
-                // even if there's already an ImplModuleKind module defined,
-                // since that's how we prevent duplicate enum definitions
-                name_bindings.set_module_kind(parent_link,
-                                              Some(local_def(item.id)),
-                                              EnumModuleKind,
-                                              false,
-                                              is_public,
-                                              sp);
-
-                for variant in (*enum_definition).variants.iter() {
-                    self.build_reduced_graph_for_variant(
-                        &**variant,
-                        local_def(item.id),
-                        ModuleReducedGraphParent(name_bindings.get_module()));
-                }
-                parent
-            }
-
-            // These items live in both the type and value namespaces.
-            ItemStruct(ref struct_def, _) => {
-                // 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            => (ForbidDuplicateTypesAndModules, None)
-                };
-
-                let name_bindings = self.add_child(name, parent.clone(), forbid, sp);
-
-                // Define a name in the type namespace.
-                name_bindings.define_type(DefTy(local_def(item.id), false), sp, modifiers);
-
-                // If this is a newtype or unit-like struct, define a name
-                // in the value namespace as well
-                match ctor_id {
-                    Some(cid) => {
-                        name_bindings.define_value(DefStruct(local_def(cid)),
-                                                   sp, modifiers);
-                    }
-                    None => {}
-                }
-
-                // Record the def ID and fields of this struct.
-                let named_fields = struct_def.fields.iter().filter_map(|f| {
-                    match f.node.kind {
-                        NamedField(ident, _) => Some(ident.name),
-                        UnnamedField(_) => None
-                    }
-                }).collect();
-                self.structs.insert(local_def(item.id), named_fields);
-
-                parent
-            }
-
-            ItemImpl(_, _, None, ref ty, ref impl_items) => {
-                // If this implements an anonymous trait, then add all the
-                // methods within to a new module, if the type was defined
-                // within this module.
-
-                let mod_name = match ty.node {
-                    TyPath(ref path, _) if path.segments.len() == 1 => {
-                        // FIXME(18446) we should distinguish between the name of
-                        // a trait and the name of an impl of that trait.
-                        Some(path.segments.last().unwrap().identifier.name)
-                    }
-                    TyObjectSum(ref lhs_ty, _) => {
-                        match lhs_ty.node {
-                            TyPath(ref path, _) if path.segments.len() == 1 => {
-                                Some(path.segments.last().unwrap().identifier.name)
-                            }
-                            _ => {
-                                None
-                            }
-                        }
-                    }
-                    _ => {
-                        None
-                    }
-                };
-
-                match mod_name {
-                    None => {
-                        self.resolve_error(ty.span,
-                                           "inherent implementations may \
-                                            only be implemented in the same \
-                                            module as the type they are \
-                                            implemented for")
-                    }
-                    Some(mod_name) => {
-                        // Create the module and add all methods.
-                        let parent_opt = parent.module().children.borrow()
-                            .get(&mod_name).cloned();
-                        let new_parent = match parent_opt {
-                            // It already exists
-                            Some(ref child) if child.get_module_if_available()
-                                .is_some() &&
-                                (child.get_module().kind.get() == ImplModuleKind ||
-                                 child.get_module().kind.get() == TraitModuleKind) => {
-                                    ModuleReducedGraphParent(child.get_module())
-                                }
-                            Some(ref child) if child.get_module_if_available()
-                                .is_some() &&
-                                child.get_module().kind.get() ==
-                                EnumModuleKind => {
-                                    ModuleReducedGraphParent(child.get_module())
-                                }
-                            // Create the module
-                            _ => {
-                                let name_bindings =
-                                    self.add_child(mod_name,
-                                                   parent.clone(),
-                                                   ForbidDuplicateModules,
-                                                   sp);
-
-                                let parent_link =
-                                    self.get_parent_link(parent.clone(), name);
-                                let def_id = local_def(item.id);
-                                let ns = TypeNS;
-                                let is_public =
-                                    !name_bindings.defined_in_namespace(ns) ||
-                                    name_bindings.defined_in_public_namespace(ns);
-
-                                name_bindings.define_module(parent_link,
-                                                            Some(def_id),
-                                                            ImplModuleKind,
-                                                            false,
-                                                            is_public,
-                                                            sp);
-
-                                ModuleReducedGraphParent(
-                                    name_bindings.get_module())
-                            }
-                        };
-
-                        // For each implementation item...
-                        for impl_item in impl_items.iter() {
-                            match *impl_item {
-                                MethodImplItem(ref method) => {
-                                    // Add the method to the module.
-                                    let name = method.pe_ident().name;
-                                    let method_name_bindings =
-                                        self.add_child(name,
-                                                       new_parent.clone(),
-                                                       ForbidDuplicateValues,
-                                                       method.span);
-                                    let def = match method.pe_explicit_self()
-                                        .node {
-                                            SelfStatic => {
-                                                // Static methods become
-                                                // `DefStaticMethod`s.
-                                                DefStaticMethod(local_def(method.id),
-                                                                FromImpl(local_def(item.id)))
-                                            }
-                                            _ => {
-                                                // Non-static methods become
-                                                // `DefMethod`s.
-                                                DefMethod(local_def(method.id),
-                                                          None,
-                                                          FromImpl(local_def(item.id)))
-                                            }
-                                        };
-
-                                    // NB: not IMPORTABLE
-                                    let modifiers = if method.pe_vis() == ast::Public {
-                                        PUBLIC
-                                    } else {
-                                        DefModifiers::empty()
-                                    };
-                                    method_name_bindings.define_value(
-                                        def,
-                                        method.span,
-                                        modifiers);
-                                }
-                                TypeImplItem(ref typedef) => {
-                                    // Add the typedef to the module.
-                                    let name = typedef.ident.name;
-                                    let typedef_name_bindings =
-                                        self.add_child(
-                                            name,
-                                            new_parent.clone(),
-                                            ForbidDuplicateTypesAndModules,
-                                            typedef.span);
-                                    let def = DefAssociatedTy(local_def(
-                                        typedef.id));
-                                    // NB: not IMPORTABLE
-                                    let modifiers = if typedef.vis == ast::Public {
-                                        PUBLIC
-                                    } else {
-                                        DefModifiers::empty()
-                                    };
-                                    typedef_name_bindings.define_type(
-                                        def,
-                                        typedef.span,
-                                        modifiers);
-                                }
-                            }
-                        }
-                    }
-                }
-
-                parent
-            }
-
-            ItemImpl(_, _, Some(_), _, _) => parent,
-
-            ItemTrait(_, _, _, _, ref items) => {
-                let name_bindings =
-                    self.add_child(name,
-                                   parent.clone(),
-                                   ForbidDuplicateTypesAndModules,
-                                   sp);
-
-                // Add all the items within to a new module.
-                let parent_link = self.get_parent_link(parent.clone(), name);
-                name_bindings.define_module(parent_link,
-                                            Some(local_def(item.id)),
-                                            TraitModuleKind,
-                                            false,
-                                            item.vis == ast::Public,
-                                            sp);
-                let module_parent = ModuleReducedGraphParent(name_bindings.
-                                                             get_module());
-
-                let def_id = local_def(item.id);
-
-                // Add the names of all the items to the trait info.
-                for trait_item in items.iter() {
-                    let (name, kind) = match *trait_item {
-                        ast::RequiredMethod(_) |
-                        ast::ProvidedMethod(_) => {
-                            let ty_m = ast_util::trait_item_to_ty_method(trait_item);
-
-                            let name = ty_m.ident.name;
-
-                            // Add it as a name in the trait module.
-                            let (def, static_flag) = match ty_m.explicit_self
-                                                               .node {
-                                SelfStatic => {
-                                    // Static methods become `DefStaticMethod`s.
-                                    (DefStaticMethod(
-                                            local_def(ty_m.id),
-                                            FromTrait(local_def(item.id))),
-                                     StaticMethodTraitItemKind)
-                                }
-                                _ => {
-                                    // Non-static methods become `DefMethod`s.
-                                    (DefMethod(local_def(ty_m.id),
-                                               Some(local_def(item.id)),
-                                               FromTrait(local_def(item.id))),
-                                     NonstaticMethodTraitItemKind)
-                                }
-                            };
-
-                            let method_name_bindings =
-                                self.add_child(name,
-                                               module_parent.clone(),
-                                               ForbidDuplicateTypesAndValues,
-                                               ty_m.span);
-                            // NB: not IMPORTABLE
-                            method_name_bindings.define_value(def,
-                                                              ty_m.span,
-                                                              PUBLIC);
-
-                            (name, static_flag)
-                        }
-                        ast::TypeTraitItem(ref associated_type) => {
-                            let def = DefAssociatedTy(local_def(
-                                    associated_type.ty_param.id));
-
-                            let name_bindings =
-                                self.add_child(associated_type.ty_param.ident.name,
-                                               module_parent.clone(),
-                                               ForbidDuplicateTypesAndValues,
-                                               associated_type.ty_param.span);
-                            // NB: not IMPORTABLE
-                            name_bindings.define_type(def,
-                                                      associated_type.ty_param.span,
-                                                      PUBLIC);
-
-                            (associated_type.ty_param.ident.name, TypeTraitItemKind)
-                        }
-                    };
-
-                    self.trait_item_map.insert((name, def_id), kind);
-                }
-
-                name_bindings.define_type(DefTrait(def_id), sp, modifiers);
-                parent
-            }
-            ItemMac(..) => parent
-        }
-    }
-
-    // Constructs the reduced graph for one variant. Variants exist in the
-    // type and value namespaces.
-    fn build_reduced_graph_for_variant(&mut self,
-                                       variant: &Variant,
-                                       item_id: DefId,
-                                       parent: ReducedGraphParent) {
-        let name = variant.node.name.name;
-        let is_exported = match variant.node.kind {
-            TupleVariantKind(_) => false,
-            StructVariantKind(_) => {
-                // Not adding fields for variants as they are not accessed with a self receiver
-                self.structs.insert(local_def(variant.node.id), Vec::new());
-                true
-            }
-        };
-
-        let child = self.add_child(name, parent,
-                                   ForbidDuplicateTypesAndValues,
-                                   variant.span);
-        // variants are always treated as importable to allow them to be glob
-        // used
-        child.define_value(DefVariant(item_id,
-                                      local_def(variant.node.id), is_exported),
-                           variant.span, PUBLIC | IMPORTABLE);
-        child.define_type(DefVariant(item_id,
-                                     local_def(variant.node.id), is_exported),
-                          variant.span, PUBLIC | IMPORTABLE);
-    }
-
-    /// Constructs the reduced graph for one 'view item'. View items consist
-    /// of imports and use directives.
-    fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
-                                         parent: ReducedGraphParent) {
-        match view_item.node {
-            ViewItemUse(ref view_path) => {
-                // Extract and intern the module part of the path. For
-                // globs and lists, the path is found directly in the AST;
-                // for simple paths we have to munge the path a little.
-                let module_path = match view_path.node {
-                    ViewPathSimple(_, ref full_path, _) => {
-                        full_path.segments
-                            .init()
-                            .iter().map(|ident| ident.identifier.name)
-                            .collect()
-                    }
-
-                    ViewPathGlob(ref module_ident_path, _) |
-                    ViewPathList(ref module_ident_path, _, _) => {
-                        module_ident_path.segments
-                            .iter().map(|ident| ident.identifier.name).collect()
-                    }
-                };
-
-                // Build up the import directives.
-                let module_ = parent.module();
-                let is_public = view_item.vis == ast::Public;
-                let shadowable =
-                    view_item.attrs
-                             .iter()
-                             .any(|attr| {
-                                 attr.name() == token::get_name(
-                                    special_idents::prelude_import.name)
-                             });
-
-                match view_path.node {
-                    ViewPathSimple(binding, ref full_path, id) => {
-                        let source_name =
-                            full_path.segments.last().unwrap().identifier.name;
-                        if token::get_name(source_name).get() == "mod" {
-                            self.resolve_error(view_path.span,
-                                "`mod` imports are only allowed within a { } list");
-                        }
-
-                        let subclass = SingleImport(binding.name,
-                                                    source_name);
-                        self.build_import_directive(&*module_,
-                                                    module_path,
-                                                    subclass,
-                                                    view_path.span,
-                                                    id,
-                                                    is_public,
-                                                    shadowable);
-                    }
-                    ViewPathList(_, ref source_items, _) => {
-                        // Make sure there's at most one `mod` import in the list.
-                        let mod_spans = source_items.iter().filter_map(|item| match item.node {
-                            PathListMod { .. } => Some(item.span),
-                            _ => None
-                        }).collect::<Vec<Span>>();
-                        if mod_spans.len() > 1 {
-                            self.resolve_error(mod_spans[0],
-                                "`mod` import can only appear once in the list");
-                            for other_span in mod_spans.iter().skip(1) {
-                                self.session.span_note(*other_span,
-                                    "another `mod` import appears here");
-                            }
-                        }
-
-                        for source_item in source_items.iter() {
-                            let (module_path, name) = match source_item.node {
-                                PathListIdent { name, .. } =>
-                                    (module_path.clone(), name.name),
-                                PathListMod { .. } => {
-                                    let name = match module_path.last() {
-                                        Some(name) => *name,
-                                        None => {
-                                            self.resolve_error(source_item.span,
-                                                "`mod` import can only appear in an import list \
-                                                 with a non-empty prefix");
-                                            continue;
-                                        }
-                                    };
-                                    let module_path = module_path.init();
-                                    (module_path.to_vec(), name)
-                                }
-                            };
-                            self.build_import_directive(
-                                &*module_,
-                                module_path,
-                                SingleImport(name, name),
-                                source_item.span,
-                                source_item.node.id(),
-                                is_public,
-                                shadowable);
-                        }
-                    }
-                    ViewPathGlob(_, id) => {
-                        self.build_import_directive(&*module_,
-                                                    module_path,
-                                                    GlobImport,
-                                                    view_path.span,
-                                                    id,
-                                                    is_public,
-                                                    shadowable);
-                    }
-                }
-            }
-
-            ViewItemExternCrate(name, _, node_id) => {
-                // n.b. we don't need to look at the path option here, because cstore already did
-                for &crate_id in self.session.cstore
-                                     .find_extern_mod_stmt_cnum(node_id).iter() {
-                    let def_id = DefId { krate: crate_id, node: 0 };
-                    self.external_exports.insert(def_id);
-                    let parent_link =
-                        ModuleParentLink(parent.module().downgrade(), name.name);
-                    let external_module = Rc::new(Module::new(parent_link,
-                                                              Some(def_id),
-                                                              NormalModuleKind,
-                                                              false,
-                                                              true));
-                    debug!("(build reduced graph for item) found extern `{}`",
-                            self.module_to_string(&*external_module));
-                    self.check_for_conflicts_between_external_crates(
-                        &*parent.module(),
-                        name.name,
-                        view_item.span);
-                    parent.module().external_module_children.borrow_mut()
-                                   .insert(name.name, external_module.clone());
-                    self.build_reduced_graph_for_external_crate(external_module);
-                }
-            }
-        }
-    }
-
-    /// Constructs the reduced graph for one foreign item.
-    fn build_reduced_graph_for_foreign_item<F>(&mut self,
-                                               foreign_item: &ForeignItem,
-                                               parent: ReducedGraphParent,
-                                               f: F) where
-        F: FnOnce(&mut Resolver),
-    {
-        let name = foreign_item.ident.name;
-        let is_public = foreign_item.vis == ast::Public;
-        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
-        let name_bindings =
-            self.add_child(name, parent, ForbidDuplicateValues,
-                           foreign_item.span);
-
-        match foreign_item.node {
-            ForeignItemFn(_, ref generics) => {
-                let def = DefFn(local_def(foreign_item.id), false);
-                name_bindings.define_value(def, foreign_item.span, modifiers);
-
-                self.with_type_parameter_rib(
-                    HasTypeParameters(generics,
-                                      FnSpace,
-                                      foreign_item.id,
-                                      NormalRibKind),
-                    f);
-            }
-            ForeignItemStatic(_, m) => {
-                let def = DefStatic(local_def(foreign_item.id), m);
-                name_bindings.define_value(def, foreign_item.span, modifiers);
-
-                f(self)
-            }
-        }
-    }
-
-    fn build_reduced_graph_for_block(&mut self,
-                                         block: &Block,
-                                         parent: ReducedGraphParent)
-                                            -> ReducedGraphParent
-    {
-        if self.block_needs_anonymous_module(block) {
-            let block_id = block.id;
-
-            debug!("(building reduced graph for block) creating a new \
-                    anonymous module for block {}",
-                   block_id);
-
-            let parent_module = parent.module();
-            let new_module = Rc::new(Module::new(
-                BlockParentLink(parent_module.downgrade(), block_id),
-                None,
-                AnonymousModuleKind,
-                false,
-                false));
-            parent_module.anonymous_children.borrow_mut()
-                         .insert(block_id, new_module.clone());
-            ModuleReducedGraphParent(new_module)
-        } else {
-            parent
-        }
-    }
-
-    fn handle_external_def(&mut self,
-                           def: Def,
-                           vis: Visibility,
-                           child_name_bindings: &NameBindings,
-                           final_ident: &str,
-                           name: Name,
-                           new_parent: ReducedGraphParent) {
-        debug!("(building reduced graph for \
-                external crate) building external def, priv {}",
-               vis);
-        let is_public = vis == ast::Public;
-        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
-        let is_exported = is_public && match new_parent {
-            ModuleReducedGraphParent(ref module) => {
-                match module.def_id.get() {
-                    None => true,
-                    Some(did) => self.external_exports.contains(&did)
-                }
-            }
-        };
-        if is_exported {
-            self.external_exports.insert(def.def_id());
-        }
-
-        let kind = match def {
-            DefTy(_, true) => EnumModuleKind,
-            DefStruct(..) | DefTy(..) => ImplModuleKind,
-            _ => NormalModuleKind
-        };
-
-        match def {
-          DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
-          DefTy(def_id, _) => {
-            let type_def = child_name_bindings.type_def.borrow().clone();
-            match type_def {
-              Some(TypeNsDef { module_def: Some(module_def), .. }) => {
-                debug!("(building reduced graph for external crate) \
-                        already created module");
-                module_def.def_id.set(Some(def_id));
-              }
-              Some(_) | None => {
-                debug!("(building reduced graph for \
-                        external crate) building module \
-                        {}", final_ident);
-                let parent_link = self.get_parent_link(new_parent.clone(), name);
-
-                child_name_bindings.define_module(parent_link,
-                                                  Some(def_id),
-                                                  kind,
-                                                  true,
-                                                  is_public,
-                                                  DUMMY_SP);
-              }
-            }
-          }
-          _ => {}
-        }
-
-        match def {
-          DefMod(_) | DefForeignMod(_) => {}
-          DefVariant(_, variant_id, is_struct) => {
-              debug!("(building reduced graph for external crate) building \
-                      variant {}",
-                      final_ident);
-              // variants are always treated as importable to allow them to be
-              // glob used
-              let modifiers = PUBLIC | IMPORTABLE;
-              if is_struct {
-                  child_name_bindings.define_type(def, DUMMY_SP, modifiers);
-                  // Not adding fields for variants as they are not accessed with a self receiver
-                  self.structs.insert(variant_id, Vec::new());
-              } else {
-                  child_name_bindings.define_value(def, DUMMY_SP, modifiers);
-              }
-          }
-          DefFn(ctor_id, true) => {
-            child_name_bindings.define_value(
-                csearch::get_tuple_struct_definition_if_ctor(&self.session.cstore, ctor_id)
-                    .map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, modifiers);
-          }
-          DefFn(..) | DefStaticMethod(..) | DefStatic(..) | DefConst(..) | DefMethod(..) => {
-            debug!("(building reduced graph for external \
-                    crate) building value (fn/static) {}", final_ident);
-            // impl methods have already been defined with the correct importability modifier
-            let mut modifiers = match *child_name_bindings.value_def.borrow() {
-                Some(ref def) => (modifiers & !IMPORTABLE) | (def.modifiers & IMPORTABLE),
-                None => modifiers
-            };
-            if new_parent.module().kind.get() != NormalModuleKind {
-                modifiers = modifiers & !IMPORTABLE;
-            }
-            child_name_bindings.define_value(def, DUMMY_SP, modifiers);
-          }
-          DefTrait(def_id) => {
-              debug!("(building reduced graph for external \
-                      crate) building type {}", final_ident);
-
-              // If this is a trait, add all the trait item names to the trait
-              // info.
-
-              let trait_item_def_ids =
-                csearch::get_trait_item_def_ids(&self.session.cstore, def_id);
-              for trait_item_def_id in trait_item_def_ids.iter() {
-                  let (trait_item_name, trait_item_kind) =
-                      csearch::get_trait_item_name_and_kind(
-                          &self.session.cstore,
-                          trait_item_def_id.def_id());
-
-                  debug!("(building reduced graph for external crate) ... \
-                          adding trait item '{}'",
-                         token::get_name(trait_item_name));
-
-                  self.trait_item_map.insert((trait_item_name, def_id), trait_item_kind);
-
-                  if is_exported {
-                      self.external_exports
-                          .insert(trait_item_def_id.def_id());
-                  }
-              }
-
-              child_name_bindings.define_type(def, DUMMY_SP, modifiers);
-
-              // Define a module if necessary.
-              let parent_link = self.get_parent_link(new_parent, name);
-              child_name_bindings.set_module_kind(parent_link,
-                                                  Some(def_id),
-                                                  TraitModuleKind,
-                                                  true,
-                                                  is_public,
-                                                  DUMMY_SP)
-          }
-          DefTy(..) | DefAssociatedTy(..) | DefAssociatedPath(..) => {
-              debug!("(building reduced graph for external \
-                      crate) building type {}", final_ident);
-
-              child_name_bindings.define_type(def, DUMMY_SP, modifiers);
-          }
-          DefStruct(def_id) => {
-            debug!("(building reduced graph for external \
-                    crate) building type and value for {}",
-                   final_ident);
-            child_name_bindings.define_type(def, DUMMY_SP, modifiers);
-            let fields = csearch::get_struct_fields(&self.session.cstore, def_id).iter().map(|f| {
-                f.name
-            }).collect::<Vec<_>>();
-
-            if fields.len() == 0 {
-                child_name_bindings.define_value(def, DUMMY_SP, modifiers);
-            }
-
-            // Record the def ID and fields of this struct.
-            self.structs.insert(def_id, fields);
-          }
-          DefLocal(..) | DefPrimTy(..) | DefTyParam(..) |
-          DefUse(..) | DefUpvar(..) | DefRegion(..) |
-          DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
-            panic!("didn't expect `{}`", def);
-          }
-        }
-    }
-
-    /// Builds the reduced graph for a single item in an external crate.
-    fn build_reduced_graph_for_external_crate_def(&mut self,
-                                                  root: Rc<Module>,
-                                                  def_like: DefLike,
-                                                  name: Name,
-                                                  visibility: Visibility) {
-        match def_like {
-            DlDef(def) => {
-                // Add the new child item, if necessary.
-                match def {
-                    DefForeignMod(def_id) => {
-                        // Foreign modules have no names. Recur and populate
-                        // eagerly.
-                        csearch::each_child_of_item(&self.session.cstore,
-                                                    def_id,
-                                                    |def_like,
-                                                     child_name,
-                                                     vis| {
-                            self.build_reduced_graph_for_external_crate_def(
-                                root.clone(),
-                                def_like,
-                                child_name,
-                                vis)
-                        });
-                    }
-                    _ => {
-                        let child_name_bindings =
-                            self.add_child(name,
-                                           ModuleReducedGraphParent(root.clone()),
-                                           OverwriteDuplicates,
-                                           DUMMY_SP);
-
-                        self.handle_external_def(def,
-                                                 visibility,
-                                                 &*child_name_bindings,
-                                                 token::get_name(name).get(),
-                                                 name,
-                                                 ModuleReducedGraphParent(root));
-                    }
-                }
-            }
-            DlImpl(def) => {
-                match csearch::get_type_name_if_impl(&self.session.cstore, def) {
-                    None => {}
-                    Some(final_name) => {
-                        let methods_opt =
-                            csearch::get_methods_if_impl(&self.session.cstore, def);
-                        match methods_opt {
-                            Some(ref methods) if
-                                methods.len() >= 1 => {
-                                debug!("(building reduced graph for \
-                                        external crate) processing \
-                                        static methods for type name {}",
-                                        token::get_name(final_name));
-
-                                let child_name_bindings =
-                                    self.add_child(
-                                        final_name,
-                                        ModuleReducedGraphParent(root.clone()),
-                                        OverwriteDuplicates,
-                                        DUMMY_SP);
-
-                                // Process the static methods. First,
-                                // create the module.
-                                let type_module;
-                                let type_def = child_name_bindings.type_def.borrow().clone();
-                                match type_def {
-                                    Some(TypeNsDef {
-                                        module_def: Some(module_def),
-                                        ..
-                                    }) => {
-                                        // We already have a module. This
-                                        // is OK.
-                                        type_module = module_def;
-
-                                        // Mark it as an impl module if
-                                        // necessary.
-                                        type_module.kind.set(ImplModuleKind);
-                                    }
-                                    Some(_) | None => {
-                                        let parent_link =
-                                            self.get_parent_link(ModuleReducedGraphParent(root),
-                                                                 final_name);
-                                        child_name_bindings.define_module(
-                                            parent_link,
-                                            Some(def),
-                                            ImplModuleKind,
-                                            true,
-                                            true,
-                                            DUMMY_SP);
-                                        type_module =
-                                            child_name_bindings.
-                                                get_module();
-                                    }
-                                }
-
-                                // Add each static method to the module.
-                                let new_parent =
-                                    ModuleReducedGraphParent(type_module);
-                                for method_info in methods.iter() {
-                                    let name = method_info.name;
-                                    debug!("(building reduced graph for \
-                                             external crate) creating \
-                                             static method '{}'",
-                                           token::get_name(name));
-
-                                    let method_name_bindings =
-                                        self.add_child(name,
-                                                       new_parent.clone(),
-                                                       OverwriteDuplicates,
-                                                       DUMMY_SP);
-                                    let def = DefFn(method_info.def_id, false);
-
-                                    // NB: not IMPORTABLE
-                                    let modifiers = if visibility == ast::Public {
-                                        PUBLIC
-                                    } else {
-                                        DefModifiers::empty()
-                                    };
-                                    method_name_bindings.define_value(
-                                        def, DUMMY_SP, modifiers);
-                                }
-                            }
-
-                            // Otherwise, do nothing.
-                            Some(_) | None => {}
-                        }
-                    }
-                }
-            }
-            DlField => {
-                debug!("(building reduced graph for external crate) \
-                        ignoring field");
-            }
-        }
-    }
-
-    /// 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_string(&*module));
-
-        let def_id = match module.def_id.get() {
-            None => {
-                debug!("(populating external module) ... no def ID!");
-                return
-            }
-            Some(def_id) => def_id,
-        };
-
-        csearch::each_child_of_item(&self.session.cstore,
-                                    def_id,
-                                    |def_like, child_name, visibility| {
-            debug!("(populating external module) ... found ident: {}",
-                   token::get_name(child_name));
-            self.build_reduced_graph_for_external_crate_def(module.clone(),
-                                                            def_like,
-                                                            child_name,
-                                                            visibility)
-        });
-        module.populated.set(true)
-    }
-
-    /// Ensures that the reduced graph rooted at the given external module
-    /// is built, building it if it is not.
-    fn populate_module_if_necessary(&mut self, module: &Rc<Module>) {
-        if !module.populated.get() {
-            self.populate_external_module(module.clone())
-        }
-        assert!(module.populated.get())
-    }
-
-    /// Builds the reduced graph rooted at the 'use' directive for an external
-    /// crate.
-    fn build_reduced_graph_for_external_crate(&mut self, root: Rc<Module>) {
-        csearch::each_top_level_item_of_crate(&self.session.cstore,
-                                              root.def_id
-                                                  .get()
-                                                  .unwrap()
-                                                  .krate,
-                                              |def_like, name, visibility| {
-            self.build_reduced_graph_for_external_crate_def(root.clone(),
-                                                            def_like,
-                                                            name,
-                                                            visibility)
-        });
-    }
-
-    /// Creates and adds an import directive to the given module.
-    fn build_import_directive(&mut self,
-                              module_: &Module,
-                              module_path: Vec<Name>,
-                              subclass: ImportDirectiveSubclass,
-                              span: Span,
-                              id: NodeId,
-                              is_public: bool,
-                              shadowable: bool) {
-        module_.imports.borrow_mut().push(ImportDirective::new(module_path,
-                                                               subclass,
-                                                               span,
-                                                               id,
-                                                               is_public,
-                                                               shadowable));
-        self.unresolved_imports += 1;
-        // Bump the reference count on the name. Or, if this is a glob, set
-        // the appropriate flag.
-
-        match subclass {
-            SingleImport(target, _) => {
-                debug!("(building import directive) building import \
-                        directive: {}::{}",
-                       self.names_to_string(module_.imports.borrow().last().unwrap()
-                                                 .module_path.as_slice()),
-                       token::get_name(target));
-
-                let mut import_resolutions = module_.import_resolutions
-                                                    .borrow_mut();
-                match import_resolutions.get_mut(&target) {
-                    Some(resolution) => {
-                        debug!("(building import directive) bumping \
-                                reference");
-                        resolution.outstanding_references += 1;
-
-                        // the source of this name is different now
-                        resolution.type_id = id;
-                        resolution.value_id = id;
-                        resolution.is_public = is_public;
-                        return;
-                    }
-                    None => {}
-                }
-                debug!("(building import directive) creating new");
-                let mut resolution = ImportResolution::new(id, is_public);
-                resolution.outstanding_references = 1;
-                import_resolutions.insert(target, resolution);
-            }
-            GlobImport => {
-                // Set the glob flag. This tells us that we don't know the
-                // module's exports ahead of time.
-
-                module_.glob_count.set(module_.glob_count.get() + 1);
-            }
-        }
-    }
-
-    // Import resolution
-    //
-    // This is a fixed-point algorithm. We resolve imports until our efforts
-    // are stymied by an unresolved import; then we bail out of the current
-    // module and continue. We terminate successfully once no more imports
-    // remain or unsuccessfully when no forward progress in resolving imports
-    // is made.
-
-    /// Resolves all imports for the crate. This method performs the fixed-
-    /// point iteration.
-    fn resolve_imports(&mut self) {
-        let mut i = 0u;
-        let mut prev_unresolved_imports = 0;
-        loop {
-            debug!("(resolving imports) iteration {}, {} imports left",
-                   i, self.unresolved_imports);
-
-            let module_root = self.graph_root.get_module();
-            self.resolve_imports_for_module_subtree(module_root.clone());
-
-            if self.unresolved_imports == 0 {
-                debug!("(resolving imports) success");
-                break;
-            }
-
-            if self.unresolved_imports == prev_unresolved_imports {
-                self.report_unresolved_imports(module_root);
-                break;
-            }
-
-            i += 1;
-            prev_unresolved_imports = self.unresolved_imports;
-        }
-    }
-
-    /// Attempts to resolve imports for the given module and all of its
-    /// submodules.
-    fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
-        debug!("(resolving imports for module subtree) resolving {}",
-               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;
-
-        self.populate_module_if_necessary(&module_);
-        for (_, child_node) in module_.children.borrow().iter() {
-            match child_node.get_module_if_available() {
-                None => {
-                    // Nothing to do.
-                }
-                Some(child_module) => {
-                    self.resolve_imports_for_module_subtree(child_module);
-                }
-            }
-        }
-
-        for (_, child_module) in module_.anonymous_children.borrow().iter() {
-            self.resolve_imports_for_module_subtree(child_module.clone());
-        }
-    }
-
-    /// Attempts to resolve imports for the given module only.
-    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_string(&*module));
-            return;
-        }
-
-        let imports = module.imports.borrow();
-        let import_count = imports.len();
-        while module.resolved_import_count.get() < import_count {
-            let import_index = module.resolved_import_count.get();
-            let import_directive = &(*imports)[import_index];
-            match self.resolve_import_for_module(module.clone(),
-                                                 import_directive) {
-                Failed(err) => {
-                    let (span, help) = match err {
-                        Some((span, msg)) => (span, format!(". {}", msg)),
-                        None => (import_directive.span, String::new())
-                    };
-                    let msg = format!("unresolved import `{}`{}",
-                                      self.import_path_to_string(
-                                          import_directive.module_path
-                                                          .as_slice(),
-                                          import_directive.subclass),
-                                      help);
-                    self.resolve_error(span, msg.as_slice());
-                }
-                Indeterminate => break, // Bail out. We'll come around next time.
-                Success(()) => () // Good. Continue.
-            }
-
-            module.resolved_import_count
-                  .set(module.resolved_import_count.get() + 1);
-        }
-    }
-
-    fn names_to_string(&self, names: &[Name]) -> String {
-        let mut first = true;
-        let mut result = String::new();
-        for name in names.iter() {
-            if first {
-                first = false
-            } else {
-                result.push_str("::")
-            }
-            result.push_str(token::get_name(*name).get());
-        };
-        result
-    }
-
-    fn path_names_to_string(&self, path: &Path) -> String {
-        let names: Vec<ast::Name> = path.segments
-                                        .iter()
-                                        .map(|seg| seg.identifier.name)
-                                        .collect();
-        self.names_to_string(names.as_slice())
-    }
-
-    fn import_directive_subclass_to_string(&mut self,
-                                        subclass: ImportDirectiveSubclass)
-                                        -> String {
-        match subclass {
-            SingleImport(_, source) => {
-                token::get_name(source).get().to_string()
-            }
-            GlobImport => "*".to_string()
-        }
-    }
-
-    fn import_path_to_string(&mut self,
-                          names: &[Name],
-                          subclass: ImportDirectiveSubclass)
-                          -> String {
-        if names.is_empty() {
-            self.import_directive_subclass_to_string(subclass)
-        } else {
-            (format!("{}::{}",
-                     self.names_to_string(names),
-                     self.import_directive_subclass_to_string(
-                         subclass))).to_string()
-        }
-    }
-
-    /// Attempts to resolve the given import. The return value indicates
-    /// failure if we're certain the name does not exist, indeterminate if we
-    /// don't know whether the name exists at the moment due to other
-    /// currently-unresolved imports, or success if we know the name exists.
-    /// If successful, the resolved bindings are written into the module.
-    fn resolve_import_for_module(&mut self,
-                                 module_: Rc<Module>,
-                                 import_directive: &ImportDirective)
-                                 -> ResolveResult<()> {
-        let mut resolution_result = Failed(None);
-        let module_path = &import_directive.module_path;
-
-        debug!("(resolving import for module) resolving import `{}::...` in \
-                `{}`",
-               self.names_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 {
-            // Use the crate root.
-            Some((self.graph_root.get_module(), LastMod(AllPublic)))
-        } else {
-            match self.resolve_module_path(module_.clone(),
-                                           module_path.as_slice(),
-                                           DontUseLexicalScope,
-                                           import_directive.span,
-                                           ImportSearch) {
-                Failed(err) => {
-                    resolution_result = Failed(err);
-                    None
-                },
-                Indeterminate => {
-                    resolution_result = Indeterminate;
-                    None
-                }
-                Success(container) => Some(container),
-            }
-        };
-
-        match container {
-            None => {}
-            Some((containing_module, lp)) => {
-                // We found the module that the target is contained
-                // within. Attempt to resolve the import within it.
-
-                match import_directive.subclass {
-                    SingleImport(target, source) => {
-                        resolution_result =
-                            self.resolve_single_import(&*module_,
-                                                       containing_module,
-                                                       target,
-                                                       source,
-                                                       import_directive,
-                                                       lp);
-                    }
-                    GlobImport => {
-                        resolution_result =
-                            self.resolve_glob_import(&*module_,
-                                                     containing_module,
-                                                     import_directive,
-                                                     lp);
-                    }
-                }
-            }
-        }
-
-        // Decrement the count of unresolved imports.
-        match resolution_result {
-            Success(()) => {
-                assert!(self.unresolved_imports >= 1);
-                self.unresolved_imports -= 1;
-            }
-            _ => {
-                // Nothing to do here; just return the error.
-            }
-        }
-
-        // Decrement the count of unresolved globs if necessary. But only if
-        // the resolution result is indeterminate -- otherwise we'll stop
-        // processing imports here. (See the loop in
-        // resolve_imports_for_module.)
-
-        if !resolution_result.indeterminate() {
-            match import_directive.subclass {
-                GlobImport => {
-                    assert!(module_.glob_count.get() >= 1);
-                    module_.glob_count.set(module_.glob_count.get() - 1);
-                }
-                SingleImport(..) => {
-                    // Ignore.
-                }
-            }
-        }
-
-        return resolution_result;
-    }
-
-    fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
-        NameBindings {
-            type_def: RefCell::new(Some(TypeNsDef {
-                modifiers: IMPORTABLE,
-                module_def: Some(module),
-                type_def: None,
-                type_span: None
-            })),
-            value_def: RefCell::new(None),
-        }
-    }
-
-    fn resolve_single_import(&mut self,
-                             module_: &Module,
-                             containing_module: Rc<Module>,
-                             target: Name,
-                             source: Name,
-                             directive: &ImportDirective,
-                             lp: LastPrivate)
-                                 -> ResolveResult<()> {
-        debug!("(resolving single import) resolving `{}` = `{}::{}` from \
-                `{}` id {}, last private {}",
-               token::get_name(target),
-               self.module_to_string(&*containing_module),
-               token::get_name(source),
-               self.module_to_string(module_),
-               directive.id,
-               lp);
-
-        let lp = match lp {
-            LastMod(lp) => lp,
-            LastImport {..} => {
-                self.session
-                    .span_bug(directive.span,
-                              "not expecting Import here, must be LastMod")
-            }
-        };
-
-        // We need to resolve both namespaces for this to succeed.
-        //
-
-        let mut value_result = UnknownResult;
-        let mut type_result = UnknownResult;
-
-        // Search for direct children of the containing module.
-        self.populate_module_if_necessary(&containing_module);
-
-        match containing_module.children.borrow().get(&source) {
-            None => {
-                // Continue.
-            }
-            Some(ref child_name_bindings) => {
-                if child_name_bindings.defined_in_namespace(ValueNS) {
-                    debug!("(resolving single import) found value binding");
-                    value_result = BoundResult(containing_module.clone(),
-                                               (*child_name_bindings).clone());
-                }
-                if child_name_bindings.defined_in_namespace(TypeNS) {
-                    debug!("(resolving single import) found type binding");
-                    type_result = BoundResult(containing_module.clone(),
-                                              (*child_name_bindings).clone());
-                }
-            }
-        }
-
-        // Unless we managed to find a result in both namespaces (unlikely),
-        // search imports as well.
-        let mut value_used_reexport = false;
-        let mut type_used_reexport = false;
-        match (value_result.clone(), type_result.clone()) {
-            (BoundResult(..), BoundResult(..)) => {} // Continue.
-            _ => {
-                // If there is an unresolved glob at this point in the
-                // containing module, bail out. We don't know enough to be
-                // able to resolve this import.
-
-                if containing_module.glob_count.get() > 0 {
-                    debug!("(resolving single import) unresolved glob; \
-                            bailing out");
-                    return Indeterminate;
-                }
-
-                // Now search the exported imports within the containing module.
-                match containing_module.import_resolutions.borrow().get(&source) {
-                    None => {
-                        debug!("(resolving single import) no import");
-                        // The containing module definitely doesn't have an
-                        // exported import with the name in question. We can
-                        // therefore accurately report that the names are
-                        // unbound.
-
-                        if value_result.is_unknown() {
-                            value_result = UnboundResult;
-                        }
-                        if type_result.is_unknown() {
-                            type_result = UnboundResult;
-                        }
-                    }
-                    Some(import_resolution)
-                            if import_resolution.outstanding_references == 0 => {
-
-                        fn get_binding(this: &mut Resolver,
-                                       import_resolution: &ImportResolution,
-                                       namespace: Namespace)
-                                    -> NamespaceResult {
-
-                            // Import resolutions must be declared with "pub"
-                            // in order to be exported.
-                            if !import_resolution.is_public {
-                                return UnboundResult;
-                            }
-
-                            match import_resolution.
-                                    target_for_namespace(namespace) {
-                                None => {
-                                    return UnboundResult;
-                                }
-                                Some(Target {
-                                    target_module,
-                                    bindings,
-                                    shadowable: _
-                                }) => {
-                                    debug!("(resolving single import) found \
-                                            import in ns {}", namespace);
-                                    let id = import_resolution.id(namespace);
-                                    // track used imports and extern crates as well
-                                    this.used_imports.insert((id, namespace));
-                                    match target_module.def_id.get() {
-                                        Some(DefId{krate: kid, ..}) => {
-                                            this.used_crates.insert(kid);
-                                        },
-                                        _ => {}
-                                    }
-                                    return BoundResult(target_module, bindings);
-                                }
-                            }
-                        }
-
-                        // The name is an import which has been fully
-                        // resolved. We can, therefore, just follow it.
-                        if value_result.is_unknown() {
-                            value_result = get_binding(self, import_resolution,
-                                                       ValueNS);
-                            value_used_reexport = import_resolution.is_public;
-                        }
-                        if type_result.is_unknown() {
-                            type_result = get_binding(self, import_resolution,
-                                                      TypeNS);
-                            type_used_reexport = import_resolution.is_public;
-                        }
-
-                    }
-                    Some(_) => {
-                        // If containing_module is the same module whose import we are resolving
-                        // and there it has an unresolved import with the same name as `source`,
-                        // then the user is actually trying to import an item that is declared
-                        // in the same scope
-                        //
-                        // e.g
-                        // use self::submodule;
-                        // pub mod submodule;
-                        //
-                        // In this case we continue as if we resolved the import and let the
-                        // check_for_conflicts_between_imports_and_items call below handle
-                        // the conflict
-                        match (module_.def_id.get(),  containing_module.def_id.get()) {
-                            (Some(id1), Some(id2)) if id1 == id2  => {
-                                if value_result.is_unknown() {
-                                    value_result = UnboundResult;
-                                }
-                                if type_result.is_unknown() {
-                                    type_result = UnboundResult;
-                                }
-                            }
-                            _ =>  {
-                                // The import is unresolved. Bail out.
-                                debug!("(resolving single import) unresolved import; \
-                                        bailing out");
-                                return Indeterminate;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        // If we didn't find a result in the type namespace, search the
-        // external modules.
-        let mut value_used_public = false;
-        let mut type_used_public = false;
-        match type_result {
-            BoundResult(..) => {}
-            _ => {
-                match containing_module.external_module_children.borrow_mut()
-                                       .get(&source).cloned() {
-                    None => {} // Continue.
-                    Some(module) => {
-                        debug!("(resolving single import) found external \
-                                module");
-                        // track the module as used.
-                        match module.def_id.get() {
-                            Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
-                            _ => {}
-                        }
-                        let name_bindings =
-                            Rc::new(Resolver::create_name_bindings_from_module(
-                                module));
-                        type_result = BoundResult(containing_module.clone(),
-                                                  name_bindings);
-                        type_used_public = true;
-                    }
-                }
-            }
-        }
-
-        // We've successfully resolved the import. Write the results in.
-        let mut import_resolutions = module_.import_resolutions.borrow_mut();
-        let import_resolution = &mut (*import_resolutions)[target];
-
-        match value_result {
-            BoundResult(ref target_module, ref name_bindings) => {
-                debug!("(resolving single import) found value target: {}",
-                       { name_bindings.value_def.borrow().clone().unwrap().def });
-                self.check_for_conflicting_import(
-                    &import_resolution.value_target,
-                    directive.span,
-                    target,
-                    ValueNS);
-
-                self.check_that_import_is_importable(
-                    &**name_bindings,
-                    directive.span,
-                    target,
-                    ValueNS);
-
-                import_resolution.value_target =
-                    Some(Target::new(target_module.clone(),
-                                     name_bindings.clone(),
-                                     directive.shadowable));
-                import_resolution.value_id = directive.id;
-                import_resolution.is_public = directive.is_public;
-                value_used_public = name_bindings.defined_in_public_namespace(ValueNS);
-            }
-            UnboundResult => { /* Continue. */ }
-            UnknownResult => {
-                panic!("value result should be known at this point");
-            }
-        }
-        match type_result {
-            BoundResult(ref target_module, ref name_bindings) => {
-                debug!("(resolving single import) found type target: {}",
-                       { name_bindings.type_def.borrow().clone().unwrap().type_def });
-                self.check_for_conflicting_import(
-                    &import_resolution.type_target,
-                    directive.span,
-                    target,
-                    TypeNS);
-
-                self.check_that_import_is_importable(
-                    &**name_bindings,
-                    directive.span,
-                    target,
-                    TypeNS);
-
-                import_resolution.type_target =
-                    Some(Target::new(target_module.clone(),
-                                     name_bindings.clone(),
-                                     directive.shadowable));
-                import_resolution.type_id = directive.id;
-                import_resolution.is_public = directive.is_public;
-                type_used_public = name_bindings.defined_in_public_namespace(TypeNS);
-            }
-            UnboundResult => { /* Continue. */ }
-            UnknownResult => {
-                panic!("type result should be known at this point");
-            }
-        }
-
-        self.check_for_conflicts_between_imports_and_items(
-            module_,
-            import_resolution,
-            directive.span,
-            target);
-
-        if value_result.is_unbound() && type_result.is_unbound() {
-            let msg = format!("There is no `{}` in `{}`",
-                              token::get_name(source),
-                              self.module_to_string(&*containing_module));
-            return Failed(Some((directive.span, msg)));
-        }
-        let value_used_public = value_used_reexport || value_used_public;
-        let type_used_public = type_used_reexport || type_used_public;
-
-        assert!(import_resolution.outstanding_references >= 1);
-        import_resolution.outstanding_references -= 1;
-
-        // record what this import resolves to for later uses in documentation,
-        // this may resolve to either a value or a type, but for documentation
-        // purposes it's good enough to just favor one over the other.
-        let value_private = match import_resolution.value_target {
-            Some(ref target) => {
-                let def = target.bindings.def_for_namespace(ValueNS).unwrap();
-                self.def_map.borrow_mut().insert(directive.id, def);
-                let did = def.def_id();
-                if value_used_public {Some(lp)} else {Some(DependsOn(did))}
-            },
-            // AllPublic here and below is a dummy value, it should never be used because
-            // _exists is false.
-            None => None,
-        };
-        let type_private = match import_resolution.type_target {
-            Some(ref target) => {
-                let def = target.bindings.def_for_namespace(TypeNS).unwrap();
-                self.def_map.borrow_mut().insert(directive.id, def);
-                let did = def.def_id();
-                if type_used_public {Some(lp)} else {Some(DependsOn(did))}
-            },
-            None => None,
-        };
-
-        self.last_private.insert(directive.id, LastImport{value_priv: value_private,
-                                                          value_used: Used,
-                                                          type_priv: type_private,
-                                                          type_used: Used});
-
-        debug!("(resolving single import) successfully resolved import");
-        return Success(());
-    }
-
-    // Resolves a glob import. Note that this function cannot panic; it either
-    // succeeds or bails out (as importing * from an empty module or a module
-    // that exports nothing is valid).
-    fn resolve_glob_import(&mut self,
-                           module_: &Module,
-                           containing_module: Rc<Module>,
-                           import_directive: &ImportDirective,
-                           lp: LastPrivate)
-                           -> ResolveResult<()> {
-        let id = import_directive.id;
-        let is_public = import_directive.is_public;
-
-        // This function works in a highly imperative manner; it eagerly adds
-        // everything it can to the list of import resolutions of the module
-        // node.
-        debug!("(resolving glob import) resolving glob import {}", id);
-
-        // We must bail out if the node has unresolved imports of any kind
-        // (including globs).
-        if !(*containing_module).all_imports_resolved() {
-            debug!("(resolving glob import) target module has unresolved \
-                    imports; bailing out");
-            return Indeterminate;
-        }
-
-        assert_eq!(containing_module.glob_count.get(), 0);
-
-        // Add all resolved imports from the containing module.
-        let import_resolutions = containing_module.import_resolutions
-                                                  .borrow();
-        for (ident, target_import_resolution) in import_resolutions.iter() {
-            debug!("(resolving glob import) writing module resolution \
-                    {} into `{}`",
-                   target_import_resolution.type_target.is_none(),
-                   self.module_to_string(module_));
-
-            if !target_import_resolution.is_public {
-                debug!("(resolving glob import) nevermind, just kidding");
-                continue
-            }
-
-            // Here we merge two import resolutions.
-            let mut import_resolutions = module_.import_resolutions.borrow_mut();
-            match import_resolutions.get_mut(ident) {
-                Some(dest_import_resolution) => {
-                    // Merge the two import resolutions at a finer-grained
-                    // level.
-
-                    match target_import_resolution.value_target {
-                        None => {
-                            // Continue.
-                        }
-                        Some(ref value_target) => {
-                            dest_import_resolution.value_target =
-                                Some(value_target.clone());
-                        }
-                    }
-                    match target_import_resolution.type_target {
-                        None => {
-                            // Continue.
-                        }
-                        Some(ref type_target) => {
-                            dest_import_resolution.type_target =
-                                Some(type_target.clone());
-                        }
-                    }
-                    dest_import_resolution.is_public = is_public;
-                    continue;
-                }
-                None => {}
-            }
-
-            // Simple: just copy the old import resolution.
-            let mut new_import_resolution = ImportResolution::new(id, is_public);
-            new_import_resolution.value_target =
-                target_import_resolution.value_target.clone();
-            new_import_resolution.type_target =
-                target_import_resolution.type_target.clone();
-
-            import_resolutions.insert(*ident, new_import_resolution);
-        }
-
-        // Add all children from the containing module.
-        self.populate_module_if_necessary(&containing_module);
-
-        for (&name, name_bindings) in containing_module.children
-                                                       .borrow().iter() {
-            self.merge_import_resolution(module_,
-                                         containing_module.clone(),
-                                         import_directive,
-                                         name,
-                                         name_bindings.clone());
-
-        }
-
-        // Add external module children from the containing module.
-        for (&name, module) in containing_module.external_module_children
-                                                .borrow().iter() {
-            let name_bindings =
-                Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
-            self.merge_import_resolution(module_,
-                                         containing_module.clone(),
-                                         import_directive,
-                                         name,
-                                         name_bindings);
-        }
-
-        // Record the destination of this import
-        match containing_module.def_id.get() {
-            Some(did) => {
-                self.def_map.borrow_mut().insert(id, DefMod(did));
-                self.last_private.insert(id, lp);
-            }
-            None => {}
-        }
-
-        debug!("(resolving glob import) successfully resolved import");
-        return Success(());
-    }
-
-    fn merge_import_resolution(&mut self,
-                               module_: &Module,
-                               containing_module: Rc<Module>,
-                               import_directive: &ImportDirective,
-                               name: Name,
-                               name_bindings: Rc<NameBindings>) {
-        let id = import_directive.id;
-        let is_public = import_directive.is_public;
-
-        let mut import_resolutions = module_.import_resolutions.borrow_mut();
-        let dest_import_resolution = match import_resolutions.entry(name) {
-            Occupied(entry) => entry.into_mut(),
-            Vacant(entry) => {
-                // Create a new import resolution from this child.
-                entry.set(ImportResolution::new(id, is_public))
-            }
-        };
-
-        debug!("(resolving glob import) writing resolution `{}` in `{}` \
-               to `{}`",
-               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_namespace_with(ValueNS, IMPORTABLE | PUBLIC) {
-            debug!("(resolving glob import) ... for value target");
-            dest_import_resolution.value_target =
-                Some(Target::new(containing_module.clone(),
-                                 name_bindings.clone(),
-                                 import_directive.shadowable));
-            dest_import_resolution.value_id = id;
-        }
-        if name_bindings.defined_in_namespace_with(TypeNS, IMPORTABLE | PUBLIC) {
-            debug!("(resolving glob import) ... for type target");
-            dest_import_resolution.type_target =
-                Some(Target::new(containing_module,
-                                 name_bindings.clone(),
-                                 import_directive.shadowable));
-            dest_import_resolution.type_id = id;
-        }
-        dest_import_resolution.is_public = is_public;
-
-        self.check_for_conflicts_between_imports_and_items(
-            module_,
-            dest_import_resolution,
-            import_directive.span,
-            name);
-    }
-
-    /// Checks that imported names and items don't have the same name.
-    fn check_for_conflicting_import(&mut self,
-                                    target: &Option<Target>,
-                                    import_span: Span,
-                                    name: Name,
-                                    namespace: Namespace) {
-        if self.session.features.borrow().import_shadowing {
-            return
-        }
-
-        match *target {
-            Some(ref target) if !target.shadowable => {
-                let msg = format!("a {} named `{}` has already been imported \
-                                   in this module",
-                                  match namespace {
-                                    TypeNS => "type",
-                                    ValueNS => "value",
-                                  },
-                                  token::get_name(name).get());
-                self.session.span_err(import_span, msg.as_slice());
-            }
-            Some(_) | None => {}
-        }
-    }
-
-    /// Checks that an import is actually importable
-    fn check_that_import_is_importable(&mut self,
-                                       name_bindings: &NameBindings,
-                                       import_span: Span,
-                                       name: Name,
-                                       namespace: Namespace) {
-        if !name_bindings.defined_in_namespace_with(namespace, IMPORTABLE) {
-            let msg = format!("`{}` is not directly importable",
-                              token::get_name(name));
-            self.session.span_err(import_span, msg.as_slice());
-        }
-    }
-
-    /// Checks that imported names and items don't have the same name.
-    fn check_for_conflicts_between_imports_and_items(&mut self,
-                                                     module: &Module,
-                                                     import_resolution:
-                                                     &ImportResolution,
-                                                     import_span: Span,
-                                                     name: Name) {
-        if self.session.features.borrow().import_shadowing {
-            return
-        }
-
-        // First, check for conflicts between imports and `extern crate`s.
-        if module.external_module_children
-                 .borrow()
-                 .contains_key(&name) {
-            match import_resolution.type_target {
-                Some(ref target) if !target.shadowable => {
-                    let msg = format!("import `{0}` conflicts with imported \
-                                       crate in this module \
-                                       (maybe you meant `use {0}::*`?)",
-                                      token::get_name(name).get());
-                    self.session.span_err(import_span, msg.as_slice());
-                }
-                Some(_) | None => {}
-            }
-        }
-
-        // Check for item conflicts.
-        let children = module.children.borrow();
-        let name_bindings = match children.get(&name) {
-            None => {
-                // There can't be any conflicts.
-                return
-            }
-            Some(ref name_bindings) => (*name_bindings).clone(),
-        };
-
-        match import_resolution.value_target {
-            Some(ref target) if !target.shadowable => {
-                if let Some(ref value) = *name_bindings.value_def.borrow() {
-                    let msg = format!("import `{}` conflicts with value \
-                                       in this module",
-                                      token::get_name(name).get());
-                    self.session.span_err(import_span, msg.as_slice());
-                    if let Some(span) = value.value_span {
-                        self.session.span_note(span,
-                                               "conflicting value here");
-                    }
-                }
-            }
-            Some(_) | None => {}
-        }
-
-        match import_resolution.type_target {
-            Some(ref target) if !target.shadowable => {
-                if let Some(ref ty) = *name_bindings.type_def.borrow() {
-                    match ty.module_def {
-                        None => {
-                            let msg = format!("import `{}` conflicts with type in \
-                                               this module",
-                                              token::get_name(name).get());
-                            self.session.span_err(import_span, msg.as_slice());
-                            if let Some(span) = ty.type_span {
-                                self.session.span_note(span,
-                                                       "note conflicting type here")
-                            }
-                        }
-                        Some(ref module_def) => {
-                            match module_def.kind.get() {
-                                ImplModuleKind => {
-                                    if let Some(span) = ty.type_span {
-                                        let msg = format!("inherent implementations \
-                                                           are only allowed on types \
-                                                           defined in the current module");
-                                        self.session.span_err(span, msg.as_slice());
-                                        self.session.span_note(import_span,
-                                                               "import from other module here")
-                                    }
-                                }
-                                _ => {
-                                    let msg = format!("import `{}` conflicts with existing \
-                                                       submodule",
-                                                      token::get_name(name).get());
-                                    self.session.span_err(import_span, msg.as_slice());
-                                    if let Some(span) = ty.type_span {
-                                        self.session.span_note(span,
-                                                               "note conflicting module here")
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-            Some(_) | None => {}
-        }
-    }
-
-    /// Checks that the names of external crates don't collide with other
-    /// external crates.
-    fn check_for_conflicts_between_external_crates(&self,
-                                                   module: &Module,
-                                                   name: Name,
-                                                   span: Span) {
-        if self.session.features.borrow().import_shadowing {
-            return
-        }
-
-        if module.external_module_children.borrow().contains_key(&name) {
-            self.session
-                .span_err(span,
-                          format!("an external crate named `{}` has already \
-                                   been imported into this module",
-                                  token::get_name(name).get()).as_slice());
-        }
-    }
-
-    /// Checks that the names of items don't collide with external crates.
-    fn check_for_conflicts_between_external_crates_and_items(&self,
-                                                             module: &Module,
-                                                             name: Name,
-                                                             span: Span) {
-        if self.session.features.borrow().import_shadowing {
-            return
-        }
-
-        if module.external_module_children.borrow().contains_key(&name) {
-            self.session
-                .span_err(span,
-                          format!("the name `{}` conflicts with an external \
-                                   crate that has been imported into this \
-                                   module",
-                                  token::get_name(name).get()).as_slice());
-        }
-    }
-
-    /// Resolves the given module path from the given root `module_`.
-    fn resolve_module_path_from_root(&mut self,
-                                     module_: Rc<Module>,
-                                     module_path: &[Name],
-                                     index: uint,
-                                     span: Span,
-                                     name_search_type: NameSearchType,
-                                     lp: LastPrivate)
-                                -> ResolveResult<(Rc<Module>, LastPrivate)> {
-        fn search_parent_externals(needle: Name, module: &Rc<Module>)
-                                -> Option<Rc<Module>> {
-            module.external_module_children.borrow()
-                                            .get(&needle).cloned()
-                                            .map(|_| module.clone())
-                                            .or_else(|| {
-                match module.parent_link.clone() {
-                    ModuleParentLink(parent, _) => {
-                        search_parent_externals(needle,
-                                                &parent.upgrade().unwrap())
-                    }
-                   _ => None
-                }
-            })
-        }
-
-        let mut search_module = module_;
-        let mut index = index;
-        let module_path_len = module_path.len();
-        let mut closest_private = lp;
-
-        // Resolve the module part of the path. This does not involve looking
-        // upward though scope chains; we simply resolve names directly in
-        // modules as we go.
-        while index < module_path_len {
-            let name = module_path[index];
-            match self.resolve_name_in_module(search_module.clone(),
-                                              name,
-                                              TypeNS,
-                                              name_search_type,
-                                              false) {
-                Failed(None) => {
-                    let segment_name = token::get_name(name);
-                    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());
-
-                        match search_parent_externals(name,
-                                                     &self.current_module) {
-                            Some(module) => {
-                                let path_str = self.names_to_string(module_path);
-                                let target_mod_str = self.module_to_string(&*module);
-                                let current_mod_str =
-                                    self.module_to_string(&*self.current_module);
-
-                                let prefix = if target_mod_str == current_mod_str {
-                                    "self::".to_string()
-                                } else {
-                                    format!("{}::", target_mod_str)
-                                };
-
-                                format!("Did you mean `{}{}`?", prefix, path_str)
-                            },
-                            None => format!("Maybe a missing `extern crate {}`?",
-                                            segment_name),
-                        }
-                    } else {
-                        format!("Could not find `{}` in `{}`",
-                                segment_name,
-                                module_name)
-                    };
-
-                    return Failed(Some((span, msg)));
-                }
-                Failed(err) => return Failed(err),
-                Indeterminate => {
-                    debug!("(resolving module path for import) module \
-                            resolution is indeterminate: {}",
-                            token::get_name(name));
-                    return Indeterminate;
-                }
-                Success((target, used_proxy)) => {
-                    // Check to see whether there are type bindings, and, if
-                    // so, whether there is a module within.
-                    match *target.bindings.type_def.borrow() {
-                        Some(ref type_def) => {
-                            match type_def.module_def {
-                                None => {
-                                    let msg = format!("Not a module `{}`",
-                                                        token::get_name(name));
-
-                                    return Failed(Some((span, msg)));
-                                }
-                                Some(ref module_def) => {
-                                    search_module = module_def.clone();
-
-                                    // track extern crates for unused_extern_crate lint
-                                    if let Some(did) = module_def.def_id.get() {
-                                        self.used_crates.insert(did.krate);
-                                    }
-
-                                    // Keep track of the closest
-                                    // private module used when
-                                    // resolving this import chain.
-                                    if !used_proxy && !search_module.is_public {
-                                        if let Some(did) = search_module.def_id.get() {
-                                            closest_private = LastMod(DependsOn(did));
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                        None => {
-                            // There are no type bindings at all.
-                            let msg = format!("Not a module `{}`",
-                                              token::get_name(name));
-                            return Failed(Some((span, msg)));
-                        }
-                    }
-                }
-            }
-
-            index += 1;
-        }
-
-        return Success((search_module, closest_private));
-    }
-
-    /// Attempts to resolve the module part of an import directive or path
-    /// rooted at the given module.
-    ///
-    /// On success, returns the resolved module, and the closest *private*
-    /// module found to the destination when resolving this path.
-    fn resolve_module_path(&mut self,
-                           module_: Rc<Module>,
-                           module_path: &[Name],
-                           use_lexical_scope: UseLexicalScopeFlag,
-                           span: Span,
-                           name_search_type: NameSearchType)
-                           -> ResolveResult<(Rc<Module>, LastPrivate)> {
-        let module_path_len = module_path.len();
-        assert!(module_path_len > 0);
-
-        debug!("(resolving module path for import) processing `{}` rooted at `{}`",
-               self.names_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(),
-                                                              module_path);
-
-        let search_module;
-        let start_index;
-        let last_private;
-        match module_prefix_result {
-            Failed(None) => {
-                let mpath = self.names_to_string(module_path);
-                let mpath = mpath.as_slice();
-                match mpath.rfind(':') {
-                    Some(idx) => {
-                        let msg = format!("Could not find `{}` in `{}`",
-                                            // idx +- 1 to account for the
-                                            // colons on either side
-                                            mpath.slice_from(idx + 1),
-                                            mpath.slice_to(idx - 1));
-                        return Failed(Some((span, msg)));
-                    },
-                    None => {
-                        return Failed(None)
-                    }
-                }
-            }
-            Failed(err) => return Failed(err),
-            Indeterminate => {
-                debug!("(resolving module path for import) indeterminate; \
-                        bailing");
-                return Indeterminate;
-            }
-            Success(NoPrefixFound) => {
-                // There was no prefix, so we're considering the first element
-                // of the path. How we handle this depends on whether we were
-                // instructed to use lexical scope or not.
-                match use_lexical_scope {
-                    DontUseLexicalScope => {
-                        // This is a crate-relative path. We will start the
-                        // resolution process at index zero.
-                        search_module = self.graph_root.get_module();
-                        start_index = 0;
-                        last_private = LastMod(AllPublic);
-                    }
-                    UseLexicalScope => {
-                        // This is not a crate-relative path. We resolve the
-                        // first component of the path in the current lexical
-                        // scope and then proceed to resolve below that.
-                        match self.resolve_module_in_lexical_scope(module_,
-                                                                   module_path[0]) {
-                            Failed(err) => return Failed(err),
-                            Indeterminate => {
-                                debug!("(resolving module path for import) \
-                                        indeterminate; bailing");
-                                return Indeterminate;
-                            }
-                            Success(containing_module) => {
-                                search_module = containing_module;
-                                start_index = 1;
-                                last_private = LastMod(AllPublic);
-                            }
-                        }
-                    }
-                }
-            }
-            Success(PrefixFound(ref containing_module, index)) => {
-                search_module = containing_module.clone();
-                start_index = index;
-                last_private = LastMod(DependsOn(containing_module.def_id
-                                                                  .get()
-                                                                  .unwrap()));
-            }
-        }
-
-        self.resolve_module_path_from_root(search_module,
-                                           module_path,
-                                           start_index,
-                                           span,
-                                           name_search_type,
-                                           last_private)
-    }
-
-    /// Invariant: This must only be called during main resolution, not during
-    /// import resolution.
-    fn resolve_item_in_lexical_scope(&mut self,
-                                     module_: Rc<Module>,
-                                     name: Name,
-                                     namespace: Namespace)
-                                    -> ResolveResult<(Target, bool)> {
-        debug!("(resolving item in lexical scope) resolving `{}` in \
-                namespace {} in `{}`",
-               token::get_name(name),
-               namespace,
-               self.module_to_string(&*module_));
-
-        // The current module node is handled specially. First, check for
-        // its immediate children.
-        self.populate_module_if_necessary(&module_);
-
-        match module_.children.borrow().get(&name) {
-            Some(name_bindings)
-                    if name_bindings.defined_in_namespace(namespace) => {
-                debug!("top name bindings succeeded");
-                return Success((Target::new(module_.clone(),
-                                            name_bindings.clone(),
-                                            false),
-                               false));
-            }
-            Some(_) | None => { /* Not found; continue. */ }
-        }
-
-        // Now check for its import directives. We don't have to have resolved
-        // all its imports in the usual way; this is because chains of
-        // adjacent import statements are processed as though they mutated the
-        // current scope.
-        if let Some(import_resolution) = module_.import_resolutions.borrow().get(&name) {
-            match (*import_resolution).target_for_namespace(namespace) {
-                None => {
-                    // Not found; continue.
-                    debug!("(resolving item in lexical scope) found \
-                            import resolution, but not in namespace {}",
-                           namespace);
-                }
-                Some(target) => {
-                    debug!("(resolving item in lexical scope) using \
-                            import resolution");
-                    // track used imports and extern crates as well
-                    self.used_imports.insert((import_resolution.id(namespace), namespace));
-                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
-                        self.used_crates.insert(kid);
-                    }
-                    return Success((target, false));
-                }
-            }
-        }
-
-        // Search for external modules.
-        if namespace == TypeNS {
-            if let Some(module) = module_.external_module_children.borrow().get(&name).cloned() {
-                let name_bindings =
-                    Rc::new(Resolver::create_name_bindings_from_module(module));
-                debug!("lower name bindings succeeded");
-                return Success((Target::new(module_, name_bindings, false),
-                                false));
-            }
-        }
-
-        // Finally, proceed up the scope chain looking for parent modules.
-        let mut search_module = module_;
-        loop {
-            // Go to the next parent.
-            match search_module.parent_link.clone() {
-                NoParentLink => {
-                    // No more parents. This module was unresolved.
-                    debug!("(resolving item in lexical scope) unresolved \
-                            module");
-                    return Failed(None);
-                }
-                ModuleParentLink(parent_module_node, _) => {
-                    match search_module.kind.get() {
-                        NormalModuleKind => {
-                            // We stop the search here.
-                            debug!("(resolving item in lexical \
-                                    scope) unresolved module: not \
-                                    searching through module \
-                                    parents");
-                            return Failed(None);
-                        }
-                        TraitModuleKind |
-                        ImplModuleKind |
-                        EnumModuleKind |
-                        AnonymousModuleKind => {
-                            search_module = parent_module_node.upgrade().unwrap();
-                        }
-                    }
-                }
-                BlockParentLink(ref parent_module_node, _) => {
-                    search_module = parent_module_node.upgrade().unwrap();
-                }
-            }
-
-            // Resolve the name in the parent module.
-            match self.resolve_name_in_module(search_module.clone(),
-                                              name,
-                                              namespace,
-                                              PathSearch,
-                                              true) {
-                Failed(Some((span, msg))) =>
-                    self.resolve_error(span, format!("failed to resolve. {}",
-                                                     msg)),
-                Failed(None) => (), // Continue up the search chain.
-                Indeterminate => {
-                    // We couldn't see through the higher scope because of an
-                    // unresolved import higher up. Bail.
-
-                    debug!("(resolving item in lexical scope) indeterminate \
-                            higher scope; bailing");
-                    return Indeterminate;
-                }
-                Success((target, used_reexport)) => {
-                    // We found the module.
-                    debug!("(resolving item in lexical scope) found name \
-                            in module, done");
-                    return Success((target, used_reexport));
-                }
-            }
-        }
-    }
-
-    /// Resolves a module name in the current lexical scope.
-    fn resolve_module_in_lexical_scope(&mut self,
-                                       module_: Rc<Module>,
-                                       name: Name)
-                                -> ResolveResult<Rc<Module>> {
-        // If this module is an anonymous module, resolve the item in the
-        // lexical scope. Otherwise, resolve the item from the crate root.
-        let resolve_result = self.resolve_item_in_lexical_scope(module_, name, TypeNS);
-        match resolve_result {
-            Success((target, _)) => {
-                let bindings = &*target.bindings;
-                match *bindings.type_def.borrow() {
-                    Some(ref type_def) => {
-                        match type_def.module_def {
-                            None => {
-                                debug!("!!! (resolving module in lexical \
-                                        scope) module wasn't actually a \
-                                        module!");
-                                return Failed(None);
-                            }
-                            Some(ref module_def) => {
-                                return Success(module_def.clone());
-                            }
-                        }
-                    }
-                    None => {
-                        debug!("!!! (resolving module in lexical scope) module
-                                wasn't actually a module!");
-                        return Failed(None);
-                    }
-                }
-            }
-            Indeterminate => {
-                debug!("(resolving module in lexical scope) indeterminate; \
-                        bailing");
-                return Indeterminate;
-            }
-            Failed(err) => {
-                debug!("(resolving module in lexical scope) failed to resolve");
-                return Failed(err);
-            }
-        }
-    }
-
-    /// Returns the nearest normal module parent of the given module.
-    fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>)
-                                            -> Option<Rc<Module>> {
-        let mut module_ = module_;
-        loop {
-            match module_.parent_link.clone() {
-                NoParentLink => return None,
-                ModuleParentLink(new_module, _) |
-                BlockParentLink(new_module, _) => {
-                    let new_module = new_module.upgrade().unwrap();
-                    match new_module.kind.get() {
-                        NormalModuleKind => return Some(new_module),
-                        TraitModuleKind |
-                        ImplModuleKind |
-                        EnumModuleKind |
-                        AnonymousModuleKind => module_ = new_module,
-                    }
-                }
-            }
-        }
-    }
-
-    /// Returns the nearest normal module parent of the given module, or the
-    /// module itself if it is a normal module.
-    fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>)
-                                                -> Rc<Module> {
-        match module_.kind.get() {
-            NormalModuleKind => return module_,
-            TraitModuleKind |
-            ImplModuleKind |
-            EnumModuleKind |
-            AnonymousModuleKind => {
-                match self.get_nearest_normal_module_parent(module_.clone()) {
-                    None => module_,
-                    Some(new_module) => new_module
-                }
-            }
-        }
-    }
-
-    /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
-    /// (b) some chain of `super::`.
-    /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
-    fn resolve_module_prefix(&mut self,
-                             module_: Rc<Module>,
-                             module_path: &[Name])
-                                 -> ResolveResult<ModulePrefixResult> {
-        // Start at the current module if we see `self` or `super`, or at the
-        // top of the crate otherwise.
-        let mut containing_module;
-        let mut i;
-        let first_module_path_string = token::get_name(module_path[0]);
-        if "self" == first_module_path_string.get() {
-            containing_module =
-                self.get_nearest_normal_module_parent_or_self(module_);
-            i = 1;
-        } else if "super" == first_module_path_string.get() {
-            containing_module =
-                self.get_nearest_normal_module_parent_or_self(module_);
-            i = 0;  // We'll handle `super` below.
-        } else {
-            return Success(NoPrefixFound);
-        }
-
-        // Now loop through all the `super`s we find.
-        while i < module_path.len() {
-            let string = token::get_name(module_path[i]);
-            if "super" != string.get() {
-                break
-            }
-            debug!("(resolving module prefix) resolving `super` at {}",
-                   self.module_to_string(&*containing_module));
-            match self.get_nearest_normal_module_parent(containing_module) {
-                None => return Failed(None),
-                Some(new_module) => {
-                    containing_module = new_module;
-                    i += 1;
-                }
-            }
-        }
-
-        debug!("(resolving module prefix) finished resolving prefix at {}",
-               self.module_to_string(&*containing_module));
-
-        return Success(PrefixFound(containing_module, i));
-    }
-
-    /// Attempts to resolve the supplied name in the given module for the
-    /// given namespace. If successful, returns the target corresponding to
-    /// the name.
-    ///
-    /// The boolean returned on success is an indicator of whether this lookup
-    /// passed through a public re-export proxy.
-    fn resolve_name_in_module(&mut self,
-                              module_: Rc<Module>,
-                              name: Name,
-                              namespace: Namespace,
-                              name_search_type: NameSearchType,
-                              allow_private_imports: bool)
-                              -> ResolveResult<(Target, bool)> {
-        debug!("(resolving name in module) resolving `{}` in `{}`",
-               token::get_name(name).get(),
-               self.module_to_string(&*module_));
-
-        // First, check the direct children of the module.
-        self.populate_module_if_necessary(&module_);
-
-        match module_.children.borrow().get(&name) {
-            Some(name_bindings)
-                    if name_bindings.defined_in_namespace(namespace) => {
-                debug!("(resolving name in module) found node as child");
-                return Success((Target::new(module_.clone(),
-                                            name_bindings.clone(),
-                                            false),
-                               false));
-            }
-            Some(_) | None => {
-                // Continue.
-            }
-        }
-
-        // Next, check the module's imports if necessary.
-
-        // If this is a search of all imports, we should be done with glob
-        // resolution at this point.
-        if name_search_type == PathSearch {
-            assert_eq!(module_.glob_count.get(), 0);
-        }
-
-        // Check the list of resolved imports.
-        match module_.import_resolutions.borrow().get(&name) {
-            Some(import_resolution) if allow_private_imports ||
-                                       import_resolution.is_public => {
-
-                if import_resolution.is_public &&
-                        import_resolution.outstanding_references != 0 {
-                    debug!("(resolving name in module) import \
-                           unresolved; bailing out");
-                    return Indeterminate;
-                }
-                match import_resolution.target_for_namespace(namespace) {
-                    None => {
-                        debug!("(resolving name in module) name found, \
-                                but not in namespace {}",
-                               namespace);
-                    }
-                    Some(target) => {
-                        debug!("(resolving name in module) resolved to \
-                                import");
-                        // track used imports and extern crates as well
-                        self.used_imports.insert((import_resolution.id(namespace), namespace));
-                        if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
-                            self.used_crates.insert(kid);
-                        }
-                        return Success((target, true));
-                    }
-                }
-            }
-            Some(..) | None => {} // Continue.
-        }
-
-        // Finally, search through external children.
-        if namespace == TypeNS {
-            if let Some(module) = module_.external_module_children.borrow().get(&name).cloned() {
-                let name_bindings =
-                    Rc::new(Resolver::create_name_bindings_from_module(module));
-                return Success((Target::new(module_, name_bindings, false),
-                                false));
-            }
-        }
-
-        // We're out of luck.
-        debug!("(resolving name in module) failed to resolve `{}`",
-               token::get_name(name).get());
-        return Failed(None);
-    }
-
-    fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
-        let index = module_.resolved_import_count.get();
-        let imports = module_.imports.borrow();
-        let import_count = imports.len();
-        if index != import_count {
-            let sn = self.session
-                         .codemap()
-                         .span_to_snippet((*imports)[index].span)
-                         .unwrap();
-            if sn.contains("::") {
-                self.resolve_error((*imports)[index].span,
-                                   "unresolved import");
-            } else {
-                let err = format!("unresolved import (maybe you meant `{}::*`?)",
-                                  sn.slice(0, sn.len()));
-                self.resolve_error((*imports)[index].span, err.as_slice());
-            }
-        }
-
-        // Descend into children and anonymous children.
-        self.populate_module_if_necessary(&module_);
-
-        for (_, child_node) in module_.children.borrow().iter() {
-            match child_node.get_module_if_available() {
-                None => {
-                    // Continue.
-                }
-                Some(child_module) => {
-                    self.report_unresolved_imports(child_module);
-                }
-            }
-        }
-
-        for (_, module_) in module_.anonymous_children.borrow().iter() {
-            self.report_unresolved_imports(module_.clone());
-        }
-    }
-
-    // Export recording
-    //
-    // This pass simply determines what all "export" keywords refer to and
-    // writes the results into the export map.
-    //
-    // FIXME #4953 This pass will be removed once exports change to per-item.
-    // Then this operation can simply be performed as part of item (or import)
-    // processing.
-
-    fn record_exports(&mut self) {
-        let root_module = self.graph_root.get_module();
-        self.record_exports_for_module_subtree(root_module);
-    }
-
-    fn record_exports_for_module_subtree(&mut self,
-                                             module_: Rc<Module>) {
-        // If this isn't a local krate, then bail out. We don't need to record
-        // exports for nonlocal crates.
-
-        match module_.def_id.get() {
-            Some(def_id) if def_id.krate == LOCAL_CRATE => {
-                // OK. Continue.
-                debug!("(recording exports for module subtree) recording \
-                        exports for local 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_string(&*module_));
-            }
-            Some(_) => {
-                // Bail out.
-                debug!("(recording exports for module subtree) not recording \
-                        exports for `{}`",
-                       self.module_to_string(&*module_));
-                return;
-            }
-        }
-
-        self.record_exports_for_module(&*module_);
-        self.populate_module_if_necessary(&module_);
-
-        for (_, child_name_bindings) in module_.children.borrow().iter() {
-            match child_name_bindings.get_module_if_available() {
-                None => {
-                    // Nothing to do.
-                }
-                Some(child_module) => {
-                    self.record_exports_for_module_subtree(child_module);
-                }
-            }
-        }
-
-        for (_, child_module) in module_.anonymous_children.borrow().iter() {
-            self.record_exports_for_module_subtree(child_module.clone());
-        }
-    }
-
-    fn record_exports_for_module(&mut self, module_: &Module) {
-        let mut exports2 = Vec::new();
-
-        self.add_exports_for_module(&mut exports2, module_);
-        match module_.def_id.get() {
-            Some(def_id) => {
-                self.export_map2.insert(def_id.node, exports2);
-                debug!("(computing exports) writing exports for {} (some)",
-                       def_id.node);
-            }
-            None => {}
-        }
-    }
-
-    fn add_exports_of_namebindings(&mut self,
-                                   exports2: &mut Vec<Export2> ,
-                                   name: Name,
-                                   namebindings: &NameBindings,
-                                   ns: Namespace) {
-        match namebindings.def_for_namespace(ns) {
-            Some(d) => {
-                let name = token::get_name(name);
-                debug!("(computing exports) YES: export '{}' => {}",
-                       name, d.def_id());
-                exports2.push(Export2 {
-                    name: name.get().to_string(),
-                    def_id: d.def_id()
-                });
-            }
-            d_opt => {
-                debug!("(computing exports) NO: {}", d_opt);
-            }
-        }
-    }
-
-    fn add_exports_for_module(&mut self,
-                              exports2: &mut Vec<Export2> ,
-                              module_: &Module) {
-        for (name, importresolution) in module_.import_resolutions.borrow().iter() {
-            if !importresolution.is_public {
-                continue
-            }
-            let xs = [TypeNS, ValueNS];
-            for &ns in xs.iter() {
-                match importresolution.target_for_namespace(ns) {
-                    Some(target) => {
-                        debug!("(computing exports) maybe export '{}'",
-                               token::get_name(*name));
-                        self.add_exports_of_namebindings(exports2,
-                                                         *name,
-                                                         &*target.bindings,
-                                                         ns)
-                    }
-                    _ => ()
-                }
-            }
-        }
-    }
-
-    // AST resolution
-    //
-    // We maintain a list of value ribs and type ribs.
-    //
-    // Simultaneously, we keep track of the current position in the module
-    // graph in the `current_module` pointer. When we go to resolve a name in
-    // the value or type namespaces, we first look through all the ribs and
-    // then query the module graph. When we resolve a name in the module
-    // namespace, we can skip all the ribs (since nested modules are not
-    // allowed within blocks in Rust) and jump straight to the current module
-    // graph node.
-    //
-    // Named implementations are handled separately. When we find a method
-    // call, we consult the module node to find all of the implementations in
-    // scope. This information is lazily cached in the module node. We then
-    // generate a fake "implementation scope" containing all the
-    // implementations thus found, for compatibility with old resolve pass.
-
-    fn with_scope<F>(&mut self, name: Option<Name>, f: F) where
-        F: FnOnce(&mut Resolver),
-    {
-        let orig_module = self.current_module.clone();
-
-        // Move down in the graph.
-        match name {
-            None => {
-                // Nothing to do.
-            }
-            Some(name) => {
-                self.populate_module_if_necessary(&orig_module);
-
-                match orig_module.children.borrow().get(&name) {
-                    None => {
-                        debug!("!!! (with scope) didn't find `{}` in `{}`",
-                               token::get_name(name),
-                               self.module_to_string(&*orig_module));
-                    }
-                    Some(name_bindings) => {
-                        match (*name_bindings).get_module_if_available() {
-                            None => {
-                                debug!("!!! (with scope) didn't find module \
-                                        for `{}` in `{}`",
-                                       token::get_name(name),
-                                       self.module_to_string(&*orig_module));
-                            }
-                            Some(module_) => {
-                                self.current_module = module_;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        f(self);
-
-        self.current_module = orig_module;
-    }
-
-    /// Wraps the given definition in the appropriate number of `DefUpvar`
-    /// wrappers.
-    fn upvarify(&self,
-                ribs: &[Rib],
-                def_like: DefLike,
-                span: Span)
-                -> Option<DefLike> {
-        match def_like {
-            DlDef(d @ DefUpvar(..)) => {
-                self.session.span_bug(span,
-                    format!("unexpected {} in bindings", d).as_slice())
-            }
-            DlDef(d @ DefLocal(_)) => {
-                let node_id = d.def_id().node;
-                let mut def = d;
-                let mut last_proc_body_id = ast::DUMMY_NODE_ID;
-                for rib in ribs.iter() {
-                    match rib.kind {
-                        NormalRibKind => {
-                            // Nothing to do. Continue.
-                        }
-                        ClosureRibKind(function_id, maybe_proc_body) => {
-                            let prev_def = def;
-                            if maybe_proc_body != ast::DUMMY_NODE_ID {
-                                last_proc_body_id = maybe_proc_body;
-                            }
-                            def = DefUpvar(node_id, function_id, last_proc_body_id);
-
-                            let mut seen = self.freevars_seen.borrow_mut();
-                            let seen = match seen.entry(function_id) {
-                                Occupied(v) => v.into_mut(),
-                                Vacant(v) => v.set(NodeSet::new()),
-                            };
-                            if seen.contains(&node_id) {
-                                continue;
-                            }
-                            match self.freevars.borrow_mut().entry(function_id) {
-                                Occupied(v) => v.into_mut(),
-                                Vacant(v) => v.set(vec![]),
-                            }.push(Freevar { def: prev_def, span: span });
-                            seen.insert(node_id);
-                        }
-                        MethodRibKind(item_id, _) => {
-                            // If the def is a ty param, and came from the parent
-                            // item, it's ok
-                            match def {
-                                DefTyParam(_, did, _) if {
-                                    self.def_map.borrow().get(&did.node).cloned()
-                                        == Some(DefTyParamBinder(item_id))
-                                } => {} // ok
-                                DefSelfTy(did) if did == item_id => {} // ok
-                                _ => {
-                                    // This was an attempt to access an upvar inside a
-                                    // named function item. This is not allowed, so we
-                                    // report an error.
-
-                                    self.resolve_error(
-                                        span,
-                                        "can't capture dynamic environment in a fn item; \
-                                        use the || { ... } closure form instead");
-
-                                    return None;
-                                }
-                            }
-                        }
-                        ItemRibKind => {
-                            // This was an attempt to access an upvar inside a
-                            // named function item. This is not allowed, so we
-                            // report an error.
-
-                            self.resolve_error(
-                                span,
-                                "can't capture dynamic environment in a fn item; \
-                                use the || { ... } closure form instead");
-
-                            return None;
-                        }
-                        ConstantItemRibKind => {
-                            // Still doesn't deal with upvars
-                            self.resolve_error(span,
-                                               "attempt to use a non-constant \
-                                                value in a constant");
-
-                        }
-                    }
-                }
-                Some(DlDef(def))
-            }
-            DlDef(def @ DefTyParam(..)) |
-            DlDef(def @ DefSelfTy(..)) => {
-                for rib in ribs.iter() {
-                    match rib.kind {
-                        NormalRibKind | ClosureRibKind(..) => {
-                            // Nothing to do. Continue.
-                        }
-                        MethodRibKind(item_id, _) => {
-                            // If the def is a ty param, and came from the parent
-                            // item, it's ok
-                            match def {
-                                DefTyParam(_, did, _) if {
-                                    self.def_map.borrow().get(&did.node).cloned()
-                                        == Some(DefTyParamBinder(item_id))
-                                } => {} // ok
-                                DefSelfTy(did) if did == item_id => {} // ok
-
-                                _ => {
-                                    // This was an attempt to use a type parameter outside
-                                    // its scope.
-
-                                    self.resolve_error(span,
-                                                        "can't use type parameters from \
-                                                        outer function; try using a local \
-                                                        type parameter instead");
-
-                                    return None;
-                                }
-                            }
-                        }
-                        ItemRibKind => {
-                            // This was an attempt to use a type parameter outside
-                            // its scope.
-
-                            self.resolve_error(span,
-                                               "can't use type parameters from \
-                                                outer function; try using a local \
-                                                type parameter instead");
-
-                            return None;
-                        }
-                        ConstantItemRibKind => {
-                            // see #9186
-                            self.resolve_error(span,
-                                               "cannot use an outer type \
-                                                parameter in this context");
-
-                        }
-                    }
-                }
-                Some(DlDef(def))
-            }
-            _ => Some(def_like)
-        }
-    }
-
-    fn search_ribs(&self,
-                   ribs: &[Rib],
-                   name: Name,
-                   span: Span)
-                   -> Option<DefLike> {
-        // FIXME #4950: Try caching?
-
-        for (i, rib) in ribs.iter().enumerate().rev() {
-            match rib.bindings.get(&name).cloned() {
-                Some(def_like) => {
-                    return self.upvarify(ribs[i + 1..], def_like, span);
-                }
-                None => {
-                    // Continue.
-                }
-            }
-        }
-
-        None
-    }
-
-    fn resolve_crate(&mut self, krate: &ast::Crate) {
-        debug!("(resolving crate) starting");
-
-        visit::walk_crate(self, krate);
-    }
-
-    fn resolve_item(&mut self, item: &Item) {
-        let name = item.ident.name;
-
-        debug!("(resolving item) resolving {}",
-               token::get_name(name));
-
-        match item.node {
-
-            // enum item: resolve all the variants' discrs,
-            // then resolve the ty params
-            ItemEnum(ref enum_def, ref generics) => {
-                for variant in (*enum_def).variants.iter() {
-                    for dis_expr in variant.node.disr_expr.iter() {
-                        // resolve the discriminator expr
-                        // as a constant
-                        self.with_constant_rib(|this| {
-                            this.resolve_expr(&**dis_expr);
-                        });
-                    }
-                }
-
-                // n.b. the discr expr gets visited twice.
-                // but maybe it's okay since the first time will signal an
-                // error if there is one? -- tjc
-                self.with_type_parameter_rib(HasTypeParameters(generics,
-                                                               TypeSpace,
-                                                               item.id,
-                                                               ItemRibKind),
-                                             |this| {
-                    this.resolve_type_parameters(&generics.ty_params);
-                    this.resolve_where_clause(&generics.where_clause);
-                    visit::walk_item(this, item);
-                });
-            }
-
-            ItemTy(_, ref generics) => {
-                self.with_type_parameter_rib(HasTypeParameters(generics,
-                                                               TypeSpace,
-                                                               item.id,
-                                                               ItemRibKind),
-                                             |this| {
-                    this.resolve_type_parameters(&generics.ty_params);
-                    visit::walk_item(this, item);
-                });
-            }
-
-            ItemImpl(_,
-                     ref generics,
-                     ref implemented_traits,
-                     ref self_type,
-                     ref impl_items) => {
-                self.resolve_implementation(item.id,
-                                            generics,
-                                            implemented_traits,
-                                            &**self_type,
-                                            impl_items.as_slice());
-            }
-
-            ItemTrait(_, ref generics, ref unbound, ref bounds, ref trait_items) => {
-                // Create a new rib for the self type.
-                let mut self_type_rib = Rib::new(ItemRibKind);
-
-                // plain insert (no renaming, types are not currently hygienic....)
-                let name = self.type_self_name;
-                self_type_rib.bindings.insert(name, DlDef(DefSelfTy(item.id)));
-                self.type_ribs.push(self_type_rib);
-
-                // Create a new rib for the trait-wide type parameters.
-                self.with_type_parameter_rib(HasTypeParameters(generics,
-                                                               TypeSpace,
-                                                               item.id,
-                                                               NormalRibKind),
-                                             |this| {
-                    this.resolve_type_parameters(&generics.ty_params);
-                    this.resolve_where_clause(&generics.where_clause);
-
-                    this.resolve_type_parameter_bounds(item.id, bounds,
-                                                       TraitDerivation);
-
-                    match *unbound {
-                        Some(ref tpb) => {
-                            this.resolve_trait_reference(item.id, tpb, TraitDerivation);
-                        }
-                        None => {}
-                    }
-
-                    for trait_item in (*trait_items).iter() {
-                        // Create a new rib for the trait_item-specific type
-                        // parameters.
-                        //
-                        // FIXME #4951: Do we need a node ID here?
-
-                        match *trait_item {
-                          ast::RequiredMethod(ref ty_m) => {
-                            this.with_type_parameter_rib
-                                (HasTypeParameters(&ty_m.generics,
-                                                   FnSpace,
-                                                   item.id,
-                                        MethodRibKind(item.id, RequiredMethod)),
-                                 |this| {
-
-                                // Resolve the method-specific type
-                                // parameters.
-                                this.resolve_type_parameters(
-                                    &ty_m.generics.ty_params);
-                                this.resolve_where_clause(&ty_m.generics
-                                                               .where_clause);
-
-                                for argument in ty_m.decl.inputs.iter() {
-                                    this.resolve_type(&*argument.ty);
-                                }
-
-                                if let SelfExplicit(ref typ, _) = ty_m.explicit_self.node {
-                                    this.resolve_type(&**typ)
-                                }
-
-                                if let ast::Return(ref ret_ty) = ty_m.decl.output {
-                                    this.resolve_type(&**ret_ty);
-                                }
-                            });
-                          }
-                          ast::ProvidedMethod(ref m) => {
-                              this.resolve_method(MethodRibKind(item.id,
-                                                                ProvidedMethod(m.id)),
-                                                  &**m)
-                          }
-                          ast::TypeTraitItem(ref data) => {
-                              this.resolve_type_parameter(&data.ty_param);
-                              visit::walk_trait_item(this, trait_item);
-                          }
-                        }
-                    }
-                });
-
-                self.type_ribs.pop();
-            }
-
-            ItemStruct(ref struct_def, ref generics) => {
-                self.resolve_struct(item.id,
-                                    generics,
-                                    struct_def.fields.as_slice());
-            }
-
-            ItemMod(ref module_) => {
-                self.with_scope(Some(name), |this| {
-                    this.resolve_module(module_, item.span, name,
-                                        item.id);
-                });
-            }
-
-            ItemForeignMod(ref foreign_module) => {
-                self.with_scope(Some(name), |this| {
-                    for foreign_item in foreign_module.items.iter() {
-                        match foreign_item.node {
-                            ForeignItemFn(_, ref generics) => {
-                                this.with_type_parameter_rib(
-                                    HasTypeParameters(
-                                        generics, FnSpace, foreign_item.id,
-                                        ItemRibKind),
-                                    |this| visit::walk_foreign_item(this,
-                                                                    &**foreign_item));
-                            }
-                            ForeignItemStatic(..) => {
-                                visit::walk_foreign_item(this,
-                                                         &**foreign_item);
-                            }
-                        }
-                    }
-                });
-            }
-
-            ItemFn(ref fn_decl, _, _, ref generics, ref block) => {
-                self.resolve_function(ItemRibKind,
-                                      Some(&**fn_decl),
-                                      HasTypeParameters
-                                        (generics,
-                                         FnSpace,
-                                         item.id,
-                                         ItemRibKind),
-                                      &**block);
-            }
-
-            ItemConst(..) | ItemStatic(..) => {
-                self.with_constant_rib(|this| {
-                    visit::walk_item(this, item);
-                });
-            }
-
-           ItemMac(..) => {
-                // do nothing, these are just around to be encoded
-           }
-        }
-    }
-
-    fn with_type_parameter_rib<F>(&mut self, type_parameters: TypeParameters, f: F) where
-        F: FnOnce(&mut Resolver),
-    {
-        match type_parameters {
-            HasTypeParameters(generics, space, node_id, rib_kind) => {
-                let mut function_type_rib = Rib::new(rib_kind);
-                let mut seen_bindings = HashSet::new();
-                for (index, type_parameter) in generics.ty_params.iter().enumerate() {
-                    let name = type_parameter.ident.name;
-                    debug!("with_type_parameter_rib: {} {}", node_id,
-                           type_parameter.id);
-
-                    if seen_bindings.contains(&name) {
-                        self.resolve_error(type_parameter.span,
-                                           format!("the name `{}` is already \
-                                                    used for a type \
-                                                    parameter in this type \
-                                                    parameter list",
-                                                   token::get_name(
-                                                       name)).as_slice())
-                    }
-                    seen_bindings.insert(name);
-
-                    let def_like = DlDef(DefTyParam(space,
-                                                    local_def(type_parameter.id),
-                                                    index));
-                    // Associate this type parameter with
-                    // the item that bound it
-                    self.record_def(type_parameter.id,
-                                    (DefTyParamBinder(node_id), LastMod(AllPublic)));
-                    // plain insert (no renaming)
-                    function_type_rib.bindings.insert(name, def_like);
-                }
-                self.type_ribs.push(function_type_rib);
-            }
-
-            NoTypeParameters => {
-                // Nothing to do.
-            }
-        }
-
-        f(self);
-
-        match type_parameters {
-            HasTypeParameters(..) => { self.type_ribs.pop(); }
-            NoTypeParameters => { }
-        }
-    }
-
-    fn with_label_rib<F>(&mut self, f: F) where
-        F: FnOnce(&mut Resolver),
-    {
-        self.label_ribs.push(Rib::new(NormalRibKind));
-        f(self);
-        self.label_ribs.pop();
-    }
-
-    fn with_constant_rib<F>(&mut self, f: F) where
-        F: FnOnce(&mut Resolver),
-    {
-        self.value_ribs.push(Rib::new(ConstantItemRibKind));
-        self.type_ribs.push(Rib::new(ConstantItemRibKind));
-        f(self);
-        self.type_ribs.pop();
-        self.value_ribs.pop();
-    }
-
-    fn resolve_function(&mut self,
-                        rib_kind: RibKind,
-                        optional_declaration: Option<&FnDecl>,
-                        type_parameters: TypeParameters,
-                        block: &Block) {
-        // Create a value rib for the function.
-        let function_value_rib = Rib::new(rib_kind);
-        self.value_ribs.push(function_value_rib);
-
-        // Create a label rib for the function.
-        let function_label_rib = Rib::new(rib_kind);
-        self.label_ribs.push(function_label_rib);
-
-        // If this function has type parameters, add them now.
-        self.with_type_parameter_rib(type_parameters, |this| {
-            // Resolve the type parameters.
-            match type_parameters {
-                NoTypeParameters => {
-                    // Continue.
-                }
-                HasTypeParameters(ref generics, _, _, _) => {
-                    this.resolve_type_parameters(&generics.ty_params);
-                    this.resolve_where_clause(&generics.where_clause);
-                }
-            }
-
-            // Add each argument to the rib.
-            match optional_declaration {
-                None => {
-                    // Nothing to do.
-                }
-                Some(declaration) => {
-                    let mut bindings_list = HashMap::new();
-                    for argument in declaration.inputs.iter() {
-                        this.resolve_pattern(&*argument.pat,
-                                             ArgumentIrrefutableMode,
-                                             &mut bindings_list);
-
-                        this.resolve_type(&*argument.ty);
-
-                        debug!("(resolving function) recorded argument");
-                    }
-
-                    if let ast::Return(ref ret_ty) = declaration.output {
-                        this.resolve_type(&**ret_ty);
-                    }
-                }
-            }
-
-            // Resolve the function body.
-            this.resolve_block(&*block);
-
-            debug!("(resolving function) leaving function");
-        });
-
-        self.label_ribs.pop();
-        self.value_ribs.pop();
-    }
-
-    fn resolve_type_parameters(&mut self,
-                               type_parameters: &OwnedSlice<TyParam>) {
-        for type_parameter in type_parameters.iter() {
-            self.resolve_type_parameter(type_parameter);
-        }
-    }
-
-    fn resolve_type_parameter(&mut self,
-                              type_parameter: &TyParam) {
-        for bound in type_parameter.bounds.iter() {
-            self.resolve_type_parameter_bound(type_parameter.id, bound,
-                                              TraitBoundingTypeParameter);
-        }
-        match &type_parameter.unbound {
-            &Some(ref unbound) =>
-                self.resolve_trait_reference(
-                    type_parameter.id, unbound, TraitBoundingTypeParameter),
-            &None => {}
-        }
-        match type_parameter.default {
-            Some(ref ty) => self.resolve_type(&**ty),
-            None => {}
-        }
-    }
-
-    fn resolve_type_parameter_bounds(&mut self,
-                                     id: NodeId,
-                                     type_parameter_bounds: &OwnedSlice<TyParamBound>,
-                                     reference_type: TraitReferenceType) {
-        for type_parameter_bound in type_parameter_bounds.iter() {
-            self.resolve_type_parameter_bound(id, type_parameter_bound,
-                                              reference_type);
-        }
-    }
-
-    fn resolve_type_parameter_bound(&mut self,
-                                    id: NodeId,
-                                    type_parameter_bound: &TyParamBound,
-                                    reference_type: TraitReferenceType) {
-        match *type_parameter_bound {
-            TraitTyParamBound(ref tref) => {
-                self.resolve_poly_trait_reference(id, tref, reference_type)
-            }
-            RegionTyParamBound(..) => {}
-        }
-    }
-
-    fn resolve_poly_trait_reference(&mut self,
-                                    id: NodeId,
-                                    poly_trait_reference: &PolyTraitRef,
-                                    reference_type: TraitReferenceType) {
-        self.resolve_trait_reference(id, &poly_trait_reference.trait_ref, reference_type)
-    }
-
-    fn resolve_trait_reference(&mut self,
-                               id: NodeId,
-                               trait_reference: &TraitRef,
-                               reference_type: TraitReferenceType) {
-        match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
-            None => {
-                let path_str = self.path_names_to_string(&trait_reference.path);
-                let usage_str = match reference_type {
-                    TraitBoundingTypeParameter => "bound type parameter with",
-                    TraitImplementation        => "implement",
-                    TraitDerivation            => "derive",
-                    TraitObject                => "reference",
-                    TraitQPath                 => "extract an associated type from",
-                };
-
-                let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
-                self.resolve_error(trait_reference.path.span, msg.as_slice());
-            }
-            Some(def) => {
-                match def {
-                    (DefTrait(_), _) => {
-                        debug!("(resolving trait) found trait def: {}", def);
-                        self.record_def(trait_reference.ref_id, def);
-                    }
-                    (def, _) => {
-                        self.resolve_error(trait_reference.path.span,
-                                           format!("`{}` is not a trait",
-                                                   self.path_names_to_string(
-                                                       &trait_reference.path)));
-
-                        // If it's a typedef, give a note
-                        if let DefTy(..) = def {
-                            self.session.span_note(
-                                trait_reference.path.span,
-                                format!("`type` aliases cannot be used for traits")
-                                    .as_slice());
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    fn resolve_where_clause(&mut self, where_clause: &ast::WhereClause) {
-        for predicate in where_clause.predicates.iter() {
-            match predicate {
-                &ast::WherePredicate::BoundPredicate(ref bound_pred) => {
-                    match self.resolve_identifier(bound_pred.ident,
-                                                  TypeNS,
-                                                  true,
-                                                  bound_pred.span) {
-                        Some((def @ DefTyParam(..), last_private)) => {
-                            self.record_def(bound_pred.id, (def, last_private));
-                        }
-                        _ => {
-                            self.resolve_error(
-                                bound_pred.span,
-                                format!("undeclared type parameter `{}`",
-                                        token::get_ident(
-                                            bound_pred.ident)).as_slice());
-                        }
-                    }
-
-                    for bound in bound_pred.bounds.iter() {
-                        self.resolve_type_parameter_bound(bound_pred.id, bound,
-                                                          TraitBoundingTypeParameter);
-                    }
-                }
-                &ast::WherePredicate::EqPredicate(ref eq_pred) => {
-                    match self.resolve_path(eq_pred.id, &eq_pred.path, TypeNS, true) {
-                        Some((def @ DefTyParam(..), last_private)) => {
-                            self.record_def(eq_pred.id, (def, last_private));
-                        }
-                        _ => {
-                            self.resolve_error(eq_pred.path.span,
-                                               "undeclared associated type");
-                        }
-                    }
-
-                    self.resolve_type(&*eq_pred.ty);
-                }
-            }
-        }
-    }
-
-    fn resolve_struct(&mut self,
-                      id: NodeId,
-                      generics: &Generics,
-                      fields: &[StructField]) {
-        // If applicable, create a rib for the type parameters.
-        self.with_type_parameter_rib(HasTypeParameters(generics,
-                                                       TypeSpace,
-                                                       id,
-                                                       ItemRibKind),
-                                     |this| {
-            // Resolve the type parameters.
-            this.resolve_type_parameters(&generics.ty_params);
-            this.resolve_where_clause(&generics.where_clause);
-
-            // Resolve fields.
-            for field in fields.iter() {
-                this.resolve_type(&*field.node.ty);
-            }
-        });
-    }
-
-    // Does this really need to take a RibKind or is it always going
-    // to be NormalRibKind?
-    fn resolve_method(&mut self,
-                      rib_kind: RibKind,
-                      method: &ast::Method) {
-        let method_generics = method.pe_generics();
-        let type_parameters = HasTypeParameters(method_generics,
-                                                FnSpace,
-                                                method.id,
-                                                rib_kind);
-
-        if let SelfExplicit(ref typ, _) = method.pe_explicit_self().node {
-            self.resolve_type(&**typ);
-        }
-
-        self.resolve_function(rib_kind,
-                              Some(method.pe_fn_decl()),
-                              type_parameters,
-                              method.pe_body());
-    }
-
-    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T where
-        F: FnOnce(&mut Resolver) -> T,
-    {
-        // Handle nested impls (inside fn bodies)
-        let previous_value = replace(&mut self.current_self_type, Some(self_type.clone()));
-        let result = f(self);
-        self.current_self_type = previous_value;
-        result
-    }
-
-    fn with_optional_trait_ref<T, F>(&mut self, id: NodeId,
-                                     opt_trait_ref: &Option<TraitRef>,
-                                     f: F) -> T where
-        F: FnOnce(&mut Resolver) -> T,
-    {
-        let new_val = match *opt_trait_ref {
-            Some(ref trait_ref) => {
-                self.resolve_trait_reference(id, trait_ref, TraitImplementation);
-
-                match self.def_map.borrow().get(&trait_ref.ref_id) {
-                    Some(def) => {
-                        let did = def.def_id();
-                        Some((did, trait_ref.clone()))
-                    }
-                    None => None
-                }
-            }
-            None => None
-        };
-        let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
-        let result = f(self);
-        self.current_trait_ref = original_trait_ref;
-        result
-    }
-
-    fn resolve_implementation(&mut self,
-                              id: NodeId,
-                              generics: &Generics,
-                              opt_trait_reference: &Option<TraitRef>,
-                              self_type: &Ty,
-                              impl_items: &[ImplItem]) {
-        // If applicable, create a rib for the type parameters.
-        self.with_type_parameter_rib(HasTypeParameters(generics,
-                                                       TypeSpace,
-                                                       id,
-                                                       NormalRibKind),
-                                     |this| {
-            // Resolve the type parameters.
-            this.resolve_type_parameters(&generics.ty_params);
-            this.resolve_where_clause(&generics.where_clause);
-
-            // Resolve the trait reference, if necessary.
-            this.with_optional_trait_ref(id, opt_trait_reference, |this| {
-                // Resolve the self type.
-                this.resolve_type(self_type);
-
-                this.with_current_self_type(self_type, |this| {
-                    for impl_item in impl_items.iter() {
-                        match *impl_item {
-                            MethodImplItem(ref method) => {
-                                // If this is a trait impl, ensure the method
-                                // exists in trait
-                                this.check_trait_item(method.pe_ident().name,
-                                                      method.span);
-
-                                // We also need a new scope for the method-
-                                // specific type parameters.
-                                this.resolve_method(
-                                    MethodRibKind(id, ProvidedMethod(method.id)),
-                                    &**method);
-                            }
-                            TypeImplItem(ref typedef) => {
-                                // If this is a trait impl, ensure the method
-                                // exists in trait
-                                this.check_trait_item(typedef.ident.name,
-                                                      typedef.span);
-
-                                this.resolve_type(&*typedef.typ);
-                            }
-                        }
-                    }
-                });
-            });
-        });
-
-        // Check that the current type is indeed a type, if we have an anonymous impl
-        if opt_trait_reference.is_none() {
-            match self_type.node {
-                // TyPath is the only thing that we handled in `build_reduced_graph_for_item`,
-                // where we created a module with the name of the type in order to implement
-                // an anonymous trait. In the case that the path does not resolve to an actual
-                // type, the result will be that the type name resolves to a module but not
-                // a type (shadowing any imported modules or types with this name), leading
-                // to weird user-visible bugs. So we ward this off here. See #15060.
-                TyPath(ref path, path_id) => {
-                    match self.def_map.borrow().get(&path_id) {
-                        // FIXME: should we catch other options and give more precise errors?
-                        Some(&DefMod(_)) => {
-                            self.resolve_error(path.span, "inherent implementations are not \
-                                                           allowed for types not defined in \
-                                                           the current module");
-                        }
-                        _ => {}
-                    }
-                }
-                _ => { }
-            }
-        }
-    }
-
-    fn check_trait_item(&self, name: Name, span: Span) {
-        // If there is a TraitRef in scope for an impl, then the method must be in the trait.
-        for &(did, ref trait_ref) in self.current_trait_ref.iter() {
-            if self.trait_item_map.get(&(name, did)).is_none() {
-                let path_str = self.path_names_to_string(&trait_ref.path);
-                self.resolve_error(span,
-                                    format!("method `{}` is not a member of trait `{}`",
-                                            token::get_name(name),
-                                            path_str).as_slice());
-            }
-        }
-    }
-
-    fn resolve_module(&mut self, module: &Mod, _span: Span,
-                      _name: Name, id: NodeId) {
-        // Write the implementations in scope into the module metadata.
-        debug!("(resolving module) resolving module ID {}", id);
-        visit::walk_mod(self, module);
-    }
-
-    fn resolve_local(&mut self, local: &Local) {
-        // Resolve the type.
-        self.resolve_type(&*local.ty);
-
-        // Resolve the initializer, if necessary.
-        match local.init {
-            None => {
-                // Nothing to do.
-            }
-            Some(ref initializer) => {
-                self.resolve_expr(&**initializer);
-            }
-        }
-
-        // Resolve the pattern.
-        let mut bindings_list = HashMap::new();
-        self.resolve_pattern(&*local.pat,
-                             LocalIrrefutableMode,
-                             &mut bindings_list);
-    }
-
-    // build a map from pattern identifiers to binding-info's.
-    // this is done hygienically. This could arise for a macro
-    // that expands into an or-pattern where one 'x' was from the
-    // user and one 'x' came from the macro.
-    fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
-        let mut result = HashMap::new();
-        pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
-            let name = mtwt::resolve(path1.node);
-            result.insert(name,
-                          binding_info {span: sp,
-                                        binding_mode: binding_mode});
-        });
-        return result;
-    }
-
-    // check that all of the arms in an or-pattern have exactly the
-    // same set of bindings, with the same binding modes for each.
-    fn check_consistent_bindings(&mut self, arm: &Arm) {
-        if arm.pats.len() == 0 {
-            return
-        }
-        let map_0 = self.binding_mode_map(&*arm.pats[0]);
-        for (i, p) in arm.pats.iter().enumerate() {
-            let map_i = self.binding_mode_map(&**p);
-
-            for (&key, &binding_0) in map_0.iter() {
-                match map_i.get(&key) {
-                  None => {
-                    self.resolve_error(
-                        p.span,
-                        format!("variable `{}` from pattern #1 is \
-                                  not bound in pattern #{}",
-                                token::get_name(key),
-                                i + 1).as_slice());
-                  }
-                  Some(binding_i) => {
-                    if binding_0.binding_mode != binding_i.binding_mode {
-                        self.resolve_error(
-                            binding_i.span,
-                            format!("variable `{}` is bound with different \
-                                      mode in pattern #{} than in pattern #1",
-                                    token::get_name(key),
-                                    i + 1).as_slice());
-                    }
-                  }
-                }
-            }
-
-            for (&key, &binding) in map_i.iter() {
-                if !map_0.contains_key(&key) {
-                    self.resolve_error(
-                        binding.span,
-                        format!("variable `{}` from pattern {}{} is \
-                                  not bound in pattern {}1",
-                                token::get_name(key),
-                                "#", i + 1, "#").as_slice());
-                }
-            }
-        }
-    }
-
-    fn resolve_arm(&mut self, arm: &Arm) {
-        self.value_ribs.push(Rib::new(NormalRibKind));
-
-        let mut bindings_list = HashMap::new();
-        for pattern in arm.pats.iter() {
-            self.resolve_pattern(&**pattern, RefutableMode, &mut bindings_list);
-        }
-
-        // This has to happen *after* we determine which
-        // pat_idents are variants
-        self.check_consistent_bindings(arm);
-
-        visit::walk_expr_opt(self, &arm.guard);
-        self.resolve_expr(&*arm.body);
-
-        self.value_ribs.pop();
-    }
-
-    fn resolve_block(&mut self, block: &Block) {
-        debug!("(resolving block) entering block");
-        self.value_ribs.push(Rib::new(NormalRibKind));
-
-        // Move down in the graph, if there's an anonymous module rooted here.
-        let orig_module = self.current_module.clone();
-        match orig_module.anonymous_children.borrow().get(&block.id) {
-            None => { /* Nothing to do. */ }
-            Some(anonymous_module) => {
-                debug!("(resolving block) found anonymous module, moving \
-                        down");
-                self.current_module = anonymous_module.clone();
-            }
-        }
-
-        // Descend into the block.
-        visit::walk_block(self, block);
-
-        // Move back up.
-        self.current_module = orig_module;
-
-        self.value_ribs.pop();
-        debug!("(resolving block) leaving block");
-    }
-
-    fn resolve_type(&mut self, ty: &Ty) {
-        match ty.node {
-            // Like path expressions, the interpretation of path types depends
-            // on whether the path has multiple elements in it or not.
-
-            TyPath(ref path, path_id) => {
-                // This is a path in the type namespace. Walk through scopes
-                // looking for it.
-                let mut result_def = None;
-
-                // First, check to see whether the name is a primitive type.
-                if path.segments.len() == 1 {
-                    let id = path.segments.last().unwrap().identifier;
-
-                    match self.primitive_type_table
-                            .primitive_types
-                            .get(&id.name) {
-
-                        Some(&primitive_type) => {
-                            result_def =
-                                Some((DefPrimTy(primitive_type), LastMod(AllPublic)));
-
-                            if path.segments[0].parameters.has_lifetimes() {
-                                span_err!(self.session, path.span, E0157,
-                                    "lifetime parameters are not allowed on this type");
-                            } else if !path.segments[0].parameters.is_empty() {
-                                span_err!(self.session, path.span, E0153,
-                                    "type parameters are not allowed on this type");
-                            }
-                        }
-                        None => {
-                            // Continue.
-                        }
-                    }
-                }
-
-                match result_def {
-                    None => {
-                        match self.resolve_path(ty.id, path, TypeNS, true) {
-                            Some(def) => {
-                                debug!("(resolving type) resolved `{}` to \
-                                        type {}",
-                                       token::get_ident(path.segments
-                                                            .last().unwrap()
-                                                            .identifier),
-                                       def);
-                                result_def = Some(def);
-                            }
-                            None => {
-                                result_def = None;
-                            }
-                        }
-                    }
-                    Some(_) => {}   // Continue.
-                }
-
-                match result_def {
-                    Some(def) => {
-                        // Write the result into the def map.
-                        debug!("(resolving type) writing resolution for `{}` \
-                                (id {})",
-                               self.path_names_to_string(path),
-                               path_id);
-                        self.record_def(path_id, def);
-                    }
-                    None => {
-                        let msg = format!("use of undeclared type name `{}`",
-                                          self.path_names_to_string(path));
-                        self.resolve_error(ty.span, msg.as_slice());
-                    }
-                }
-            }
-
-            TyObjectSum(ref ty, ref bound_vec) => {
-                self.resolve_type(&**ty);
-                self.resolve_type_parameter_bounds(ty.id, bound_vec,
-                                                       TraitBoundingTypeParameter);
-            }
-
-            TyQPath(ref qpath) => {
-                self.resolve_type(&*qpath.self_type);
-                self.resolve_trait_reference(ty.id, &*qpath.trait_ref, TraitQPath);
-            }
-
-            TyClosure(ref c) => {
-                self.resolve_type_parameter_bounds(
-                    ty.id,
-                    &c.bounds,
-                    TraitBoundingTypeParameter);
-                visit::walk_ty(self, ty);
-            }
-
-            TyPolyTraitRef(ref bounds) => {
-                self.resolve_type_parameter_bounds(
-                    ty.id,
-                    bounds,
-                    TraitObject);
-                visit::walk_ty(self, ty);
-            }
-            _ => {
-                // Just resolve embedded types.
-                visit::walk_ty(self, ty);
-            }
-        }
-    }
-
-    fn resolve_pattern(&mut self,
-                       pattern: &Pat,
-                       mode: PatternBindingMode,
-                       // Maps idents to the node ID for the (outermost)
-                       // pattern that binds them
-                       bindings_list: &mut HashMap<Name, NodeId>) {
-        let pat_id = pattern.id;
-        walk_pat(pattern, |pattern| {
-            match pattern.node {
-                PatIdent(binding_mode, ref path1, _) => {
-
-                    // The meaning of pat_ident with no type parameters
-                    // depends on whether an enum variant or unit-like struct
-                    // with that name is in scope. The probing lookup has to
-                    // be careful not to emit spurious errors. Only matching
-                    // patterns (match) can match nullary variants or
-                    // unit-like structs. For binding patterns (let), matching
-                    // such a value is simply disallowed (since it's rarely
-                    // what you want).
-
-                    let ident = path1.node;
-                    let renamed = mtwt::resolve(ident);
-
-                    match self.resolve_bare_identifier_pattern(ident.name, pattern.span) {
-                        FoundStructOrEnumVariant(ref def, lp)
-                                if mode == RefutableMode => {
-                            debug!("(resolving pattern) resolving `{}` to \
-                                    struct or enum variant",
-                                   token::get_name(renamed));
-
-                            self.enforce_default_binding_mode(
-                                pattern,
-                                binding_mode,
-                                "an enum variant");
-                            self.record_def(pattern.id, (def.clone(), lp));
-                        }
-                        FoundStructOrEnumVariant(..) => {
-                            self.resolve_error(
-                                pattern.span,
-                                format!("declaration of `{}` shadows an enum \
-                                         variant or unit-like struct in \
-                                         scope",
-                                        token::get_name(renamed)).as_slice());
-                        }
-                        FoundConst(ref def, lp) if mode == RefutableMode => {
-                            debug!("(resolving pattern) resolving `{}` to \
-                                    constant",
-                                   token::get_name(renamed));
-
-                            self.enforce_default_binding_mode(
-                                pattern,
-                                binding_mode,
-                                "a constant");
-                            self.record_def(pattern.id, (def.clone(), lp));
-                        }
-                        FoundConst(..) => {
-                            self.resolve_error(pattern.span,
-                                                  "only irrefutable patterns \
-                                                   allowed here");
-                        }
-                        BareIdentifierPatternUnresolved => {
-                            debug!("(resolving pattern) binding `{}`",
-                                   token::get_name(renamed));
-
-                            let def = DefLocal(pattern.id);
-
-                            // Record the definition so that later passes
-                            // will be able to distinguish variants from
-                            // locals in patterns.
-
-                            self.record_def(pattern.id, (def, LastMod(AllPublic)));
-
-                            // Add the binding to the local ribs, if it
-                            // doesn't already exist in the bindings list. (We
-                            // must not add it if it's in the bindings list
-                            // because that breaks the assumptions later
-                            // passes make about or-patterns.)
-                            if !bindings_list.contains_key(&renamed) {
-                                let this = &mut *self;
-                                let last_rib = this.value_ribs.last_mut().unwrap();
-                                last_rib.bindings.insert(renamed, DlDef(def));
-                                bindings_list.insert(renamed, pat_id);
-                            } else if mode == ArgumentIrrefutableMode &&
-                                    bindings_list.contains_key(&renamed) {
-                                // Forbid duplicate bindings in the same
-                                // parameter list.
-                                self.resolve_error(pattern.span,
-                                                   format!("identifier `{}` \
-                                                            is bound more \
-                                                            than once in \
-                                                            this parameter \
-                                                            list",
-                                                           token::get_ident(
-                                                               ident))
-                                                   .as_slice())
-                            } else if bindings_list.get(&renamed) ==
-                                    Some(&pat_id) {
-                                // Then this is a duplicate variable in the
-                                // same disjunction, which is an error.
-                                self.resolve_error(pattern.span,
-                                    format!("identifier `{}` is bound \
-                                             more than once in the same \
-                                             pattern",
-                                            token::get_ident(ident)).as_slice());
-                            }
-                            // Else, not bound in the same pattern: do
-                            // nothing.
-                        }
-                    }
-                }
-
-                PatEnum(ref path, _) => {
-                    // This must be an enum variant, struct or const.
-                    match self.resolve_path(pat_id, path, ValueNS, false) {
-                        Some(def @ (DefVariant(..), _)) |
-                        Some(def @ (DefStruct(..), _))  |
-                        Some(def @ (DefConst(..), _)) => {
-                            self.record_def(pattern.id, def);
-                        }
-                        Some((DefStatic(..), _)) => {
-                            self.resolve_error(path.span,
-                                               "static variables cannot be \
-                                                referenced in a pattern, \
-                                                use a `const` instead");
-                        }
-                        Some(_) => {
-                            self.resolve_error(path.span,
-                                format!("`{}` is not an enum variant, struct or const",
-                                    token::get_ident(
-                                        path.segments
-                                            .last()
-                                            .unwrap()
-                                            .identifier)).as_slice());
-                        }
-                        None => {
-                            self.resolve_error(path.span,
-                                format!("unresolved enum variant, struct or const `{}`",
-                                    token::get_ident(
-                                        path.segments
-                                            .last()
-                                            .unwrap()
-                                            .identifier)).as_slice());
-                        }
-                    }
-
-                    // Check the types in the path pattern.
-                    for ty in path.segments
-                                  .iter()
-                                  .flat_map(|s| s.parameters.types().into_iter()) {
-                        self.resolve_type(&**ty);
-                    }
-                }
-
-                PatLit(ref expr) => {
-                    self.resolve_expr(&**expr);
-                }
-
-                PatRange(ref first_expr, ref last_expr) => {
-                    self.resolve_expr(&**first_expr);
-                    self.resolve_expr(&**last_expr);
-                }
-
-                PatStruct(ref path, _, _) => {
-                    match self.resolve_path(pat_id, path, TypeNS, false) {
-                        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_names_to_string(path));
-                            self.resolve_error(path.span, msg.as_slice());
-                        }
-                    }
-                }
-
-                _ => {
-                    // Nothing to do.
-                }
-            }
-            true
-        });
-    }
-
-    fn resolve_bare_identifier_pattern(&mut self, name: Name, span: Span)
-                                       -> BareIdentifierPatternResolution {
-        let module = self.current_module.clone();
-        match self.resolve_item_in_lexical_scope(module,
-                                                 name,
-                                                 ValueNS) {
-            Success((target, _)) => {
-                debug!("(resolve bare identifier pattern) succeeded in \
-                         finding {} at {}",
-                        token::get_name(name),
-                        target.bindings.value_def.borrow());
-                match *target.bindings.value_def.borrow() {
-                    None => {
-                        panic!("resolved name in the value namespace to a \
-                              set of name bindings with no def?!");
-                    }
-                    Some(def) => {
-                        // For the two success cases, this lookup can be
-                        // considered as not having a private component because
-                        // the lookup happened only within the current module.
-                        match def.def {
-                            def @ DefVariant(..) | def @ DefStruct(..) => {
-                                return FoundStructOrEnumVariant(def, LastMod(AllPublic));
-                            }
-                            def @ DefConst(..) => {
-                                return FoundConst(def, LastMod(AllPublic));
-                            }
-                            DefStatic(..) => {
-                                self.resolve_error(span,
-                                                   "static variables cannot be \
-                                                    referenced in a pattern, \
-                                                    use a `const` instead");
-                                return BareIdentifierPatternUnresolved;
-                            }
-                            _ => {
-                                return BareIdentifierPatternUnresolved;
-                            }
-                        }
-                    }
-                }
-            }
-
-            Indeterminate => {
-                panic!("unexpected indeterminate result");
-            }
-            Failed(err) => {
-                match err {
-                    Some((span, msg)) => {
-                        self.resolve_error(span, format!("failed to resolve: {}",
-                                                         msg));
-                    }
-                    None => ()
-                }
-
-                debug!("(resolve bare identifier pattern) failed to find {}",
-                        token::get_name(name));
-                return BareIdentifierPatternUnresolved;
-            }
-        }
-    }
-
-    /// If `check_ribs` is true, checks the local definitions first; i.e.
-    /// doesn't skip straight to the containing module.
-    fn resolve_path(&mut self,
-                    id: NodeId,
-                    path: &Path,
-                    namespace: Namespace,
-                    check_ribs: bool) -> Option<(Def, LastPrivate)> {
-        // First, resolve the types and associated type bindings.
-        for ty in path.segments.iter().flat_map(|s| s.parameters.types().into_iter()) {
-            self.resolve_type(&**ty);
-        }
-        for binding in path.segments.iter().flat_map(|s| s.parameters.bindings().into_iter()) {
-            self.resolve_type(&*binding.ty);
-        }
-
-        // A special case for sugared associated type paths `T::A` where `T` is
-        // a type parameter and `A` is an associated type on some bound of `T`.
-        if namespace == TypeNS && path.segments.len() == 2 {
-            match self.resolve_identifier(path.segments[0].identifier,
-                                          TypeNS,
-                                          true,
-                                          path.span) {
-                Some((def, last_private)) => {
-                    match def {
-                        DefTyParam(_, did, _) => {
-                            let def = DefAssociatedPath(TyParamProvenance::FromParam(did),
-                                                        path.segments.last()
-                                                            .unwrap().identifier);
-                            return Some((def, last_private));
-                        }
-                        DefSelfTy(nid) => {
-                            let def = DefAssociatedPath(TyParamProvenance::FromSelf(local_def(nid)),
-                                                        path.segments.last()
-                                                            .unwrap().identifier);
-                            return Some((def, last_private));
-                        }
-                        _ => {}
-                    }
-                }
-                _ => {}
-            }
-        }
-
-        if path.global {
-            return self.resolve_crate_relative_path(path, namespace);
-        }
-
-        // Try to find a path to an item in a module.
-        let unqualified_def =
-                self.resolve_identifier(path.segments
-                                            .last().unwrap()
-                                            .identifier,
-                                        namespace,
-                                        check_ribs,
-                                        path.span);
-
-        if path.segments.len() > 1 {
-            let def = self.resolve_module_relative_path(path, namespace);
-            match (def, unqualified_def) {
-                (Some((ref d, _)), Some((ref ud, _))) if *d == *ud => {
-                    self.session
-                        .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
-                                  id,
-                                  path.span,
-                                  "unnecessary qualification".to_string());
-                }
-                _ => ()
-            }
-
-            return def;
-        }
-
-        return unqualified_def;
-    }
-
-    // resolve a single identifier (used as a varref)
-    fn resolve_identifier(&mut self,
-                          identifier: Ident,
-                          namespace: Namespace,
-                          check_ribs: bool,
-                          span: Span)
-                          -> Option<(Def, LastPrivate)> {
-        if check_ribs {
-            match self.resolve_identifier_in_local_ribs(identifier,
-                                                        namespace,
-                                                        span) {
-                Some(def) => {
-                    return Some((def, LastMod(AllPublic)));
-                }
-                None => {
-                    // Continue.
-                }
-            }
-        }
-
-        return self.resolve_item_by_name_in_lexical_scope(identifier.name, namespace);
-    }
-
-    // FIXME #4952: Merge me with resolve_name_in_module?
-    fn resolve_definition_of_name_in_module(&mut self,
-                                            containing_module: Rc<Module>,
-                                            name: Name,
-                                            namespace: Namespace)
-                                            -> NameDefinition {
-        // First, search children.
-        self.populate_module_if_necessary(&containing_module);
-
-        match containing_module.children.borrow().get(&name) {
-            Some(child_name_bindings) => {
-                match child_name_bindings.def_for_namespace(namespace) {
-                    Some(def) => {
-                        // Found it. Stop the search here.
-                        let p = child_name_bindings.defined_in_public_namespace(
-                                        namespace);
-                        let lp = if p {LastMod(AllPublic)} else {
-                            LastMod(DependsOn(def.def_id()))
-                        };
-                        return ChildNameDefinition(def, lp);
-                    }
-                    None => {}
-                }
-            }
-            None => {}
-        }
-
-        // Next, search import resolutions.
-        match containing_module.import_resolutions.borrow().get(&name) {
-            Some(import_resolution) if import_resolution.is_public => {
-                if let Some(target) = (*import_resolution).target_for_namespace(namespace) {
-                    match target.bindings.def_for_namespace(namespace) {
-                        Some(def) => {
-                            // Found it.
-                            let id = import_resolution.id(namespace);
-                            // track imports and extern crates as well
-                            self.used_imports.insert((id, namespace));
-                            match target.target_module.def_id.get() {
-                                Some(DefId{krate: kid, ..}) => {
-                                    self.used_crates.insert(kid);
-                                },
-                                _ => {}
-                            }
-                            return ImportNameDefinition(def, LastMod(AllPublic));
-                        }
-                        None => {
-                            // This can happen with external impls, due to
-                            // the imperfect way we read the metadata.
-                        }
-                    }
-                }
-            }
-            Some(..) | None => {} // Continue.
-        }
-
-        // Finally, search through external children.
-        if namespace == TypeNS {
-            if let Some(module) = containing_module.external_module_children.borrow()
-                                                   .get(&name).cloned() {
-                if let Some(def_id) = module.def_id.get() {
-                    // track used crates
-                    self.used_crates.insert(def_id.krate);
-                    let lp = if module.is_public {LastMod(AllPublic)} else {
-                        LastMod(DependsOn(def_id))
-                    };
-                    return ChildNameDefinition(DefMod(def_id), lp);
-                }
-            }
-        }
-
-        return NoNameDefinition;
-    }
-
-    // resolve a "module-relative" path, e.g. a::b::c
-    fn resolve_module_relative_path(&mut self,
-                                    path: &Path,
-                                    namespace: Namespace)
-                                    -> Option<(Def, LastPrivate)> {
-        let module_path = path.segments.init().iter()
-                                              .map(|ps| ps.identifier.name)
-                                              .collect::<Vec<_>>();
-
-        let containing_module;
-        let last_private;
-        let module = self.current_module.clone();
-        match self.resolve_module_path(module,
-                                       module_path.as_slice(),
-                                       UseLexicalScope,
-                                       path.span,
-                                       PathSearch) {
-            Failed(err) => {
-                let (span, msg) = match err {
-                    Some((span, msg)) => (span, msg),
-                    None => {
-                        let msg = format!("Use of undeclared type or module `{}`",
-                                          self.names_to_string(module_path.as_slice()));
-                        (path.span, msg)
-                    }
-                };
-
-                self.resolve_error(span, format!("failed to resolve. {}",
-                                                 msg.as_slice()));
-                return None;
-            }
-            Indeterminate => panic!("indeterminate unexpected"),
-            Success((resulting_module, resulting_last_private)) => {
-                containing_module = resulting_module;
-                last_private = resulting_last_private;
-            }
-        }
-
-        let name = path.segments.last().unwrap().identifier.name;
-        let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
-                                                                  name,
-                                                                  namespace) {
-            NoNameDefinition => {
-                // We failed to resolve the name. Report an error.
-                return None;
-            }
-            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
-                (def, last_private.or(lp))
-            }
-        };
-        if let Some(DefId{krate: kid, ..}) = containing_module.def_id.get() {
-            self.used_crates.insert(kid);
-        }
-        return Some(def);
-    }
-
-    /// Invariant: This must be called only during main resolution, not during
-    /// import resolution.
-    fn resolve_crate_relative_path(&mut self,
-                                   path: &Path,
-                                   namespace: Namespace)
-                                       -> Option<(Def, LastPrivate)> {
-        let module_path = path.segments.init().iter()
-                                              .map(|ps| ps.identifier.name)
-                                              .collect::<Vec<_>>();
-
-        let root_module = self.graph_root.get_module();
-
-        let containing_module;
-        let last_private;
-        match self.resolve_module_path_from_root(root_module,
-                                                 module_path.as_slice(),
-                                                 0,
-                                                 path.span,
-                                                 PathSearch,
-                                                 LastMod(AllPublic)) {
-            Failed(err) => {
-                let (span, msg) = match err {
-                    Some((span, msg)) => (span, msg),
-                    None => {
-                        let msg = format!("Use of undeclared module `::{}`",
-                                          self.names_to_string(module_path.as_slice()));
-                        (path.span, msg)
-                    }
-                };
-
-                self.resolve_error(span, format!("failed to resolve. {}",
-                                                 msg.as_slice()));
-                return None;
-            }
-
-            Indeterminate => {
-                panic!("indeterminate unexpected");
-            }
-
-            Success((resulting_module, resulting_last_private)) => {
-                containing_module = resulting_module;
-                last_private = resulting_last_private;
-            }
-        }
-
-        let name = path.segments.last().unwrap().identifier.name;
-        match self.resolve_definition_of_name_in_module(containing_module,
-                                                        name,
-                                                        namespace) {
-            NoNameDefinition => {
-                // We failed to resolve the name. Report an error.
-                return None;
-            }
-            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
-                return Some((def, last_private.or(lp)));
-            }
-        }
-    }
-
-    fn resolve_identifier_in_local_ribs(&mut self,
-                                        ident: Ident,
-                                        namespace: Namespace,
-                                        span: Span)
-                                        -> Option<Def> {
-        // Check the local set of ribs.
-        let search_result = match namespace {
-            ValueNS => {
-                let renamed = mtwt::resolve(ident);
-                self.search_ribs(self.value_ribs.as_slice(), renamed, span)
-            }
-            TypeNS => {
-                let name = ident.name;
-                self.search_ribs(self.type_ribs.as_slice(), name, span)
-            }
-        };
-
-        match search_result {
-            Some(DlDef(def)) => {
-                debug!("(resolving path in local ribs) resolved `{}` to \
-                        local: {}",
-                       token::get_ident(ident),
-                       def);
-                return Some(def);
-            }
-            Some(DlField) | Some(DlImpl(_)) | None => {
-                return None;
-            }
-        }
-    }
-
-    fn resolve_item_by_name_in_lexical_scope(&mut self,
-                                             name: Name,
-                                             namespace: Namespace)
-                                            -> Option<(Def, LastPrivate)> {
-        // Check the items.
-        let module = self.current_module.clone();
-        match self.resolve_item_in_lexical_scope(module,
-                                                 name,
-                                                 namespace) {
-            Success((target, _)) => {
-                match (*target.bindings).def_for_namespace(namespace) {
-                    None => {
-                        // This can happen if we were looking for a type and
-                        // found a module instead. Modules don't have defs.
-                        debug!("(resolving item path by identifier in lexical \
-                                 scope) failed to resolve {} after success...",
-                                 token::get_name(name));
-                        return None;
-                    }
-                    Some(def) => {
-                        debug!("(resolving item path in lexical scope) \
-                                resolved `{}` to item",
-                               token::get_name(name));
-                        // This lookup is "all public" because it only searched
-                        // for one identifier in the current module (couldn't
-                        // have passed through reexports or anything like that.
-                        return Some((def, LastMod(AllPublic)));
-                    }
-                }
-            }
-            Indeterminate => {
-                panic!("unexpected indeterminate result");
-            }
-            Failed(err) => {
-                match err {
-                    Some((span, msg)) =>
-                        self.resolve_error(span, format!("failed to resolve. {}", msg)),
-                    None => ()
-                }
-
-                debug!("(resolving item path by identifier in lexical scope) \
-                         failed to resolve {}", token::get_name(name));
-                return None;
-            }
-        }
-    }
-
-    fn with_no_errors<T, F>(&mut self, f: F) -> T where
-        F: FnOnce(&mut Resolver) -> T,
-    {
-        self.emit_errors = false;
-        let rs = f(self);
-        self.emit_errors = true;
-        rs
-    }
-
-    fn resolve_error<T: Str>(&self, span: Span, s: T) {
-        if self.emit_errors {
-            self.session.span_err(span, s.as_slice());
-        }
-    }
-
-    fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
-        fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
-                                                    -> Option<(Path, NodeId, FallbackChecks)> {
-            match t.node {
-                TyPath(ref path, node_id) => Some((path.clone(), node_id, allow)),
-                TyPtr(ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, OnlyTraitAndStatics),
-                TyRptr(_, ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, allow),
-                // This doesn't handle the remaining `Ty` variants as they are not
-                // that commonly the self_type, it might be interesting to provide
-                // support for those in future.
-                _ => None,
-            }
-        }
-
-        fn get_module(this: &mut Resolver, span: Span, name_path: &[ast::Name])
-                            -> Option<Rc<Module>> {
-            let root = this.current_module.clone();
-            let last_name = name_path.last().unwrap();
-
-            if name_path.len() == 1 {
-                match this.primitive_type_table.primitive_types.get(last_name) {
-                    Some(_) => None,
-                    None => {
-                        match this.current_module.children.borrow().get(last_name) {
-                            Some(child) => child.get_module_if_available(),
-                            None => None
-                        }
-                    }
-                }
-            } else {
-                match this.resolve_module_path(root,
-                                                name_path.as_slice(),
-                                                UseLexicalScope,
-                                                span,
-                                                PathSearch) {
-                    Success((module, _)) => Some(module),
-                    _ => None
-                }
-            }
-        }
-
-        let (path, node_id, allowed) = match self.current_self_type {
-            Some(ref ty) => match extract_path_and_node_id(ty, Everything) {
-                Some(x) => x,
-                None => return NoSuggestion,
-            },
-            None => return NoSuggestion,
-        };
-
-        if allowed == Everything {
-            // Look for a field with the same name in the current self_type.
-            match self.def_map.borrow().get(&node_id) {
-                 Some(&DefTy(did, _))
-                | Some(&DefStruct(did))
-                | Some(&DefVariant(_, did, _)) => match self.structs.get(&did) {
-                    None => {}
-                    Some(fields) => {
-                        if fields.iter().any(|&field_name| name == field_name) {
-                            return Field;
-                        }
-                    }
-                },
-                _ => {} // Self type didn't resolve properly
-            }
-        }
-
-        let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::<Vec<_>>();
-
-        // Look for a method in the current self type's impl module.
-        match get_module(self, path.span, name_path.as_slice()) {
-            Some(module) => match module.children.borrow().get(&name) {
-                Some(binding) => {
-                    let p_str = self.path_names_to_string(&path);
-                    match binding.def_for_namespace(ValueNS) {
-                        Some(DefStaticMethod(_, provenance)) => {
-                            match provenance {
-                                FromImpl(_) => return StaticMethod(p_str),
-                                FromTrait(_) => unreachable!()
-                            }
-                        }
-                        Some(DefMethod(_, None, _)) if allowed == Everything => return Method,
-                        Some(DefMethod(_, Some(_), _)) => return TraitItem,
-                        _ => ()
-                    }
-                }
-                None => {}
-            },
-            None => {}
-        }
-
-        // Look for a method in the current trait.
-        match self.current_trait_ref {
-            Some((did, ref trait_ref)) => {
-                let path_str = self.path_names_to_string(&trait_ref.path);
-
-                match self.trait_item_map.get(&(name, did)) {
-                    Some(&StaticMethodTraitItemKind) => {
-                        return TraitMethod(path_str)
-                    }
-                    Some(_) => return TraitItem,
-                    None => {}
-                }
-            }
-            None => {}
-        }
-
-        NoSuggestion
-    }
-
-    fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
-                                -> Option<String> {
-        let this = &mut *self;
-
-        let mut maybes: Vec<token::InternedString> = Vec::new();
-        let mut values: Vec<uint> = Vec::new();
-
-        for rib in this.value_ribs.iter().rev() {
-            for (&k, _) in rib.bindings.iter() {
-                maybes.push(token::get_name(k));
-                values.push(uint::MAX);
-            }
-        }
-
-        let mut smallest = 0;
-        for (i, other) in maybes.iter().enumerate() {
-            values[i] = name.lev_distance(other.get());
-
-            if values[i] <= values[smallest] {
-                smallest = i;
-            }
-        }
-
-        if values.len() > 0 &&
-            values[smallest] != uint::MAX &&
-            values[smallest] < name.len() + 2 &&
-            values[smallest] <= max_distance &&
-            name != maybes[smallest].get() {
-
-            Some(maybes[smallest].get().to_string())
-
-        } else {
-            None
-        }
-    }
-
-    fn resolve_expr(&mut self, expr: &Expr) {
-        // First, record candidate traits for this expression if it could
-        // result in the invocation of a method call.
-
-        self.record_candidate_traits_for_expr_if_necessary(expr);
-
-        // Next, resolve the node.
-        match expr.node {
-            // The interpretation of paths depends on whether the path has
-            // multiple elements in it or not.
-
-            ExprPath(ref path) => {
-                // This is a local path in the value namespace. Walk through
-                // scopes looking for it.
-
-                let path_name = self.path_names_to_string(path);
-
-                match self.resolve_path(expr.id, path, ValueNS, true) {
-                    // Check if struct variant
-                    Some((DefVariant(_, _, true), _)) => {
-                        self.resolve_error(expr.span,
-                                format!("`{}` is a struct variant name, but \
-                                         this expression \
-                                         uses it like a function name",
-                                        path_name).as_slice());
-
-                        self.session.span_help(expr.span,
-                            format!("Did you mean to write: \
-                                    `{} {{ /* fields */ }}`?",
-                                    path_name).as_slice());
-                    }
-                    Some(def) => {
-                        // Write the result into the def map.
-                        debug!("(resolving expr) resolved `{}`",
-                               path_name);
-
-                        self.record_def(expr.id, def);
-                    }
-                    None => {
-                        // 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
-                        // structs, which wouldn't result in this error.)
-                        match self.with_no_errors(|this|
-                            this.resolve_path(expr.id, path, TypeNS, false)) {
-                            Some((DefTy(struct_id, _), _))
-                              if self.structs.contains_key(&struct_id) => {
-                                self.resolve_error(expr.span,
-                                        format!("`{}` is a structure name, but \
-                                                 this expression \
-                                                 uses it like a function name",
-                                                path_name).as_slice());
-
-                                self.session.span_help(expr.span,
-                                    format!("Did you mean to write: \
-                                            `{} {{ /* fields */ }}`?",
-                                            path_name).as_slice());
-
-                            }
-                            _ => {
-                                let mut method_scope = false;
-                                self.value_ribs.iter().rev().all(|rib| {
-                                    let res = match *rib {
-                                        Rib { bindings: _, kind: MethodRibKind(_, _) } => true,
-                                        Rib { bindings: _, kind: ItemRibKind } => false,
-                                        _ => return true, // Keep advancing
-                                    };
-
-                                    method_scope = res;
-                                    false // Stop advancing
-                                });
-
-                                if method_scope && token::get_name(self.self_name).get()
-                                                                   == path_name {
-                                        self.resolve_error(
-                                            expr.span,
-                                            "`self` is not available \
-                                             in a static method. Maybe a \
-                                             `self` argument is missing?");
-                                } else {
-                                    let last_name = path.segments.last().unwrap().identifier.name;
-                                    let mut msg = match self.find_fallback_in_self_type(last_name) {
-                                        NoSuggestion => {
-                                            // limit search to 5 to reduce the number
-                                            // of stupid suggestions
-                                            self.find_best_match_for_name(path_name.as_slice(), 5)
-                                                                .map_or("".to_string(),
-                                                                        |x| format!("`{}`", x))
-                                        }
-                                        Field =>
-                                            format!("`self.{}`", path_name),
-                                        Method
-                                        | TraitItem =>
-                                            format!("to call `self.{}`", path_name),
-                                        TraitMethod(path_str)
-                                        | StaticMethod(path_str) =>
-                                            format!("to call `{}::{}`", path_str, path_name)
-                                    };
-
-                                    if msg.len() > 0 {
-                                        msg = format!(". Did you mean {}?", msg)
-                                    }
-
-                                    self.resolve_error(
-                                        expr.span,
-                                        format!("unresolved name `{}`{}",
-                                                path_name,
-                                                msg).as_slice());
-                                }
-                            }
-                        }
-                    }
-                }
-
-                visit::walk_expr(self, expr);
-            }
-
-            ExprClosure(capture_clause, _, ref fn_decl, ref block) => {
-                self.capture_mode_map.insert(expr.id, capture_clause);
-                self.resolve_function(ClosureRibKind(expr.id, ast::DUMMY_NODE_ID),
-                                      Some(&**fn_decl), NoTypeParameters,
-                                      &**block);
-            }
-
-            ExprStruct(ref path, _, _) => {
-                // 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(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_names_to_string(path));
-                        self.resolve_error(path.span, msg.as_slice());
-                    }
-                }
-
-                visit::walk_expr(self, expr);
-            }
-
-            ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
-                self.with_label_rib(|this| {
-                    let def_like = DlDef(DefLabel(expr.id));
-
-                    {
-                        let rib = this.label_ribs.last_mut().unwrap();
-                        let renamed = mtwt::resolve(label);
-                        rib.bindings.insert(renamed, def_like);
-                    }
-
-                    visit::walk_expr(this, expr);
-                })
-            }
-
-            ExprForLoop(ref pattern, ref head, ref body, optional_label) => {
-                self.resolve_expr(&**head);
-
-                self.value_ribs.push(Rib::new(NormalRibKind));
-
-                self.resolve_pattern(&**pattern,
-                                     LocalIrrefutableMode,
-                                     &mut HashMap::new());
-
-                match optional_label {
-                    None => {}
-                    Some(label) => {
-                        self.label_ribs
-                            .push(Rib::new(NormalRibKind));
-                        let def_like = DlDef(DefLabel(expr.id));
-
-                        {
-                            let rib = self.label_ribs.last_mut().unwrap();
-                            let renamed = mtwt::resolve(label);
-                            rib.bindings.insert(renamed, def_like);
-                        }
-                    }
-                }
-
-                self.resolve_block(&**body);
-
-                if optional_label.is_some() {
-                    drop(self.label_ribs.pop())
-                }
-
-                self.value_ribs.pop();
-            }
-
-            ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
-                let renamed = mtwt::resolve(label);
-                match self.search_ribs(self.label_ribs.as_slice(),
-                                       renamed, expr.span) {
-                    None => {
-                        self.resolve_error(
-                            expr.span,
-                            format!("use of undeclared label `{}`",
-                                    token::get_ident(label)).as_slice())
-                    }
-                    Some(DlDef(def @ DefLabel(_))) => {
-                        // Since this def is a label, it is never read.
-                        self.record_def(expr.id, (def, LastMod(AllPublic)))
-                    }
-                    Some(_) => {
-                        self.session.span_bug(expr.span,
-                                              "label wasn't mapped to a \
-                                               label def!")
-                    }
-                }
-            }
-
-            _ => {
-                visit::walk_expr(self, expr);
-            }
-        }
-    }
-
-    fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
-        match expr.node {
-            ExprField(_, ident) => {
-                // FIXME(#6890): Even though you can't treat a method like a
-                // field, we need to add any trait methods we find that match
-                // the field name so that we can do some nice error reporting
-                // later on in typeck.
-                let traits = self.search_for_traits_containing_method(ident.node.name);
-                self.trait_map.insert(expr.id, traits);
-            }
-            ExprMethodCall(ident, _, _) => {
-                debug!("(recording candidate traits for expr) recording \
-                        traits for {}",
-                       expr.id);
-                let traits = self.search_for_traits_containing_method(ident.node.name);
-                self.trait_map.insert(expr.id, traits);
-            }
-            _ => {
-                // Nothing to do.
-            }
-        }
-    }
-
-    fn search_for_traits_containing_method(&mut self, name: Name) -> Vec<DefId> {
-        debug!("(searching for traits containing method) looking for '{}'",
-               token::get_name(name));
-
-        fn add_trait_info(found_traits: &mut Vec<DefId>,
-                          trait_def_id: DefId,
-                          name: Name) {
-            debug!("(adding trait info) found trait {}:{} for method '{}'",
-                trait_def_id.krate,
-                trait_def_id.node,
-                token::get_name(name));
-            found_traits.push(trait_def_id);
-        }
-
-        let mut found_traits = Vec::new();
-        let mut search_module = self.current_module.clone();
-        loop {
-            // Look for the current trait.
-            match self.current_trait_ref {
-                Some((trait_def_id, _)) => {
-                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
-                        add_trait_info(&mut found_traits, trait_def_id, name);
-                    }
-                }
-                None => {} // Nothing to do.
-            }
-
-            // Look for trait children.
-            self.populate_module_if_necessary(&search_module);
-
-            {
-                for (_, child_names) in search_module.children.borrow().iter() {
-                    let def = match child_names.def_for_namespace(TypeNS) {
-                        Some(def) => def,
-                        None => continue
-                    };
-                    let trait_def_id = match def {
-                        DefTrait(trait_def_id) => trait_def_id,
-                        _ => continue,
-                    };
-                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
-                        add_trait_info(&mut found_traits, trait_def_id, name);
-                    }
-                }
-            }
-
-            // Look for imports.
-            for (_, import) in search_module.import_resolutions.borrow().iter() {
-                let target = match import.target_for_namespace(TypeNS) {
-                    None => continue,
-                    Some(target) => target,
-                };
-                let did = match target.bindings.def_for_namespace(TypeNS) {
-                    Some(DefTrait(trait_def_id)) => trait_def_id,
-                    Some(..) | None => continue,
-                };
-                if self.trait_item_map.contains_key(&(name, did)) {
-                    add_trait_info(&mut found_traits, did, name);
-                    self.used_imports.insert((import.type_id, TypeNS));
-                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
-                        self.used_crates.insert(kid);
-                    }
-                }
-            }
-
-            match search_module.parent_link.clone() {
-                NoParentLink | ModuleParentLink(..) => break,
-                BlockParentLink(parent_module, _) => {
-                    search_module = parent_module.upgrade().unwrap();
-                }
-            }
-        }
-
-        found_traits
-    }
-
-    fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) {
-        debug!("(recording def) recording {} for {}, last private {}",
-                def, node_id, lp);
-        assert!(match lp {LastImport{..} => false, _ => true},
-                "Import should only be used for `use` directives");
-        self.last_private.insert(node_id, lp);
-
-        match self.def_map.borrow_mut().entry(node_id) {
-            // Resolve appears to "resolve" the same ID multiple
-            // times, so here is a sanity check it at least comes to
-            // the same conclusion! - nmatsakis
-            Occupied(entry) => if def != *entry.get() {
-                self.session
-                    .bug(format!("node_id {} resolved first to {} and \
-                                  then {}",
-                                 node_id,
-                                 *entry.get(),
-                                 def).as_slice());
-            },
-            Vacant(entry) => { entry.set(def); },
-        }
-    }
-
-    fn enforce_default_binding_mode(&mut self,
-                                        pat: &Pat,
-                                        pat_binding_mode: BindingMode,
-                                        descr: &str) {
-        match pat_binding_mode {
-            BindByValue(_) => {}
-            BindByRef(..) => {
-                self.resolve_error(pat.span,
-                                   format!("cannot use `ref` binding mode \
-                                            with {}",
-                                           descr).as_slice());
-            }
-        }
-    }
-
-    //
-    // Unused import checking
-    //
-    // Although this is mostly a lint pass, it lives in here because it depends on
-    // resolve data structures and because it finalises the privacy information for
-    // `use` directives.
-    //
-
-    fn check_for_unused_imports(&mut self, krate: &ast::Crate) {
-        let mut visitor = UnusedImportCheckVisitor{ resolver: self };
-        visit::walk_crate(&mut visitor, krate);
-    }
-
-    fn check_for_item_unused_imports(&mut self, vi: &ViewItem) {
-        // Ignore is_public import statements because there's no way to be sure
-        // whether they're used or not. Also ignore imports with a dummy span
-        // because this means that they were generated in some fashion by the
-        // compiler and we don't need to consider them.
-        if vi.vis == Public { return }
-        if vi.span == DUMMY_SP { return }
-
-        match vi.node {
-            ViewItemExternCrate(_, _, id) => {
-                if let Some(crate_num) = self.session.cstore.find_extern_mod_stmt_cnum(id) {
-                    if !self.used_crates.contains(&crate_num) {
-                        self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATES,
-                                              id,
-                                              vi.span,
-                                              "unused extern crate".to_string());
-                    }
-                }
-            },
-            ViewItemUse(ref p) => {
-                match p.node {
-                    ViewPathSimple(_, _, id) => self.finalize_import(id, p.span),
-
-                    ViewPathList(_, ref list, _) => {
-                        for i in list.iter() {
-                            self.finalize_import(i.node.id(), i.span);
-                        }
-                    },
-                    ViewPathGlob(_, id) => {
-                        if !self.used_imports.contains(&(id, TypeNS)) &&
-                           !self.used_imports.contains(&(id, ValueNS)) {
-                            self.session
-                                .add_lint(lint::builtin::UNUSED_IMPORTS,
-                                          id,
-                                          p.span,
-                                          "unused import".to_string());
-                        }
-                    },
-                }
-            }
-        }
-    }
-
-    // We have information about whether `use` (import) directives are actually used now.
-    // If an import is not used at all, we signal a lint error. If an import is only used
-    // for a single namespace, we remove the other namespace from the recorded privacy
-    // information. That means in privacy.rs, we will only check imports and namespaces
-    // which are used. In particular, this means that if an import could name either a
-    // public or private item, we will check the correct thing, dependent on how the import
-    // is used.
-    fn finalize_import(&mut self, id: NodeId, span: Span) {
-        debug!("finalizing import uses for {}",
-               self.session.codemap().span_to_snippet(span));
-
-        if !self.used_imports.contains(&(id, TypeNS)) &&
-           !self.used_imports.contains(&(id, ValueNS)) {
-            self.session.add_lint(lint::builtin::UNUSED_IMPORTS,
-                                  id,
-                                  span,
-                                  "unused import".to_string());
-        }
-
-        let (v_priv, t_priv) = match self.last_private.get(&id) {
-            Some(&LastImport {
-                value_priv: v,
-                value_used: _,
-                type_priv: t,
-                type_used: _
-            }) => (v, t),
-            Some(_) => {
-                panic!("we should only have LastImport for `use` directives")
-            }
-            _ => return,
-        };
-
-        let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
-            Used
-        } else {
-            Unused
-        };
-        let t_used = if self.used_imports.contains(&(id, TypeNS)) {
-            Used
-        } else {
-            Unused
-        };
-
-        match (v_priv, t_priv) {
-            // Since some items may be both in the value _and_ type namespaces (e.g., structs)
-            // we might have two LastPrivates pointing at the same thing. There is no point
-            // checking both, so lets not check the value one.
-            (Some(DependsOn(def_v)), Some(DependsOn(def_t))) if def_v == def_t => v_used = Unused,
-            _ => {},
-        }
-
-        self.last_private.insert(id, LastImport{value_priv: v_priv,
-                                                value_used: v_used,
-                                                type_priv: t_priv,
-                                                type_used: t_used});
-    }
-
-    //
-    // Diagnostics
-    //
-    // Diagnostics are not particularly efficient, because they're rarely
-    // hit.
-    //
-
-    /// A somewhat inefficient routine to obtain the name of a module.
-    fn module_to_string(&self, module: &Module) -> String {
-        let mut names = Vec::new();
-
-        fn collect_mod(names: &mut Vec<ast::Name>, module: &Module) {
-            match module.parent_link {
-                NoParentLink => {}
-                ModuleParentLink(ref module, name) => {
-                    names.push(name);
-                    collect_mod(names, &*module.upgrade().unwrap());
-                }
-                BlockParentLink(ref module, _) => {
-                    // danger, shouldn't be ident?
-                    names.push(special_idents::opaque.name);
-                    collect_mod(names, &*module.upgrade().unwrap());
-                }
-            }
-        }
-        collect_mod(&mut names, module);
-
-        if names.len() == 0 {
-            return "???".to_string();
-        }
-        self.names_to_string(names.into_iter().rev()
-                                  .collect::<Vec<ast::Name>>()
-                                  .as_slice())
-    }
-
-    #[allow(dead_code)]   // useful for debugging
-    fn dump_module(&mut self, module_: Rc<Module>) {
-        debug!("Dump of module `{}`:", self.module_to_string(&*module_));
-
-        debug!("Children:");
-        self.populate_module_if_necessary(&module_);
-        for (&name, _) in module_.children.borrow().iter() {
-            debug!("* {}", token::get_name(name));
-        }
-
-        debug!("Import resolutions:");
-        let import_resolutions = module_.import_resolutions.borrow();
-        for (&name, import_resolution) in import_resolutions.iter() {
-            let value_repr;
-            match import_resolution.target_for_namespace(ValueNS) {
-                None => { value_repr = "".to_string(); }
-                Some(_) => {
-                    value_repr = " value:?".to_string();
-                    // FIXME #4954
-                }
-            }
-
-            let type_repr;
-            match import_resolution.target_for_namespace(TypeNS) {
-                None => { type_repr = "".to_string(); }
-                Some(_) => {
-                    type_repr = " type:?".to_string();
-                    // FIXME #4954
-                }
-            }
-
-            debug!("* {}:{}{}", token::get_name(name), value_repr, type_repr);
-        }
-    }
-}
-
-pub struct CrateMap {
-    pub def_map: DefMap,
-    pub freevars: RefCell<FreevarMap>,
-    pub capture_mode_map: RefCell<CaptureModeMap>,
-    pub exp_map2: ExportMap2,
-    pub trait_map: TraitMap,
-    pub external_exports: ExternalExports,
-    pub last_private_map: LastPrivateMap,
-}
-
-/// Entry point to crate resolution.
-pub fn resolve_crate(session: &Session,
-                     _: &LanguageItems,
-                     krate: &Crate)
-                  -> CrateMap {
-    let mut resolver = Resolver::new(session, krate.span);
-    resolver.resolve(krate);
-    CrateMap {
-        def_map: resolver.def_map,
-        freevars: resolver.freevars,
-        capture_mode_map: RefCell::new(resolver.capture_mode_map),
-        exp_map2: resolver.export_map2,
-        trait_map: resolver.trait_map,
-        external_exports: resolver.external_exports,
-        last_private_map: resolver.last_private,
-    }
-}
index 2202137d14936cd8fc02e7f0ffbb613ad7c96f5a..be191801626a8495e6de39c48304ac2a75123318 100644 (file)
@@ -19,9 +19,8 @@
 use self::ScopeChain::*;
 
 use session::Session;
-use middle::def;
+use middle::def::{mod, DefMap};
 use middle::region;
-use middle::resolve::DefMap;
 use middle::subst;
 use middle::ty;
 use std::fmt;
@@ -207,13 +206,21 @@ fn visit_generics(&mut self, generics: &ast::Generics) {
         }
         for predicate in generics.where_clause.predicates.iter() {
             match predicate {
-                &ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ ident,
+                &ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ ref bounded_ty,
                                                                                ref bounds,
-                                                                               span,
                                                                                .. }) => {
-                    self.visit_ident(span, ident);
+                    self.visit_ty(&**bounded_ty);
                     visit::walk_ty_param_bounds_helper(self, bounds);
                 }
+                &ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime,
+                                                                                ref bounds,
+                                                                                .. }) => {
+
+                    self.visit_lifetime_ref(lifetime);
+                    for bound in bounds.iter() {
+                        self.visit_lifetime_ref(bound);
+                    }
+                }
                 &ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{ id,
                                                                          ref path,
                                                                          ref ty,
@@ -546,9 +553,21 @@ fn early_bound_lifetime_names(generics: &ast::Generics) -> Vec<ast::Name> {
         }
         for predicate in generics.where_clause.predicates.iter() {
             match predicate {
-                &ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ref bounds, ..}) => {
+                &ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ref bounds,
+                                                                              ref bounded_ty,
+                                                                              ..}) => {
+                    collector.visit_ty(&**bounded_ty);
                     visit::walk_ty_param_bounds_helper(&mut collector, bounds);
                 }
+                &ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime,
+                                                                                ref bounds,
+                                                                                ..}) => {
+                    collector.visit_lifetime_ref(lifetime);
+
+                    for bound in bounds.iter() {
+                        collector.visit_lifetime_ref(bound);
+                    }
+                }
                 &ast::WherePredicate::EqPredicate(_) => unimplemented!()
             }
         }
index ca8029fdfca3b418babf952d150a6c8c9d97343b..9d032df67dc8bcd461a81afe726c291c0f03cfeb 100644 (file)
@@ -43,7 +43,8 @@ struct Annotator {
 impl Annotator {
     // Determine the stability for a node based on its attributes and inherited
     // stability. The stability is recorded in the index and used as the parent.
-    fn annotate<F>(&mut self, id: NodeId, attrs: &Vec<Attribute>, f: F) where
+    fn annotate<F>(&mut self, id: NodeId, use_parent: bool,
+                   attrs: &Vec<Attribute>, f: F) where
         F: FnOnce(&mut Annotator),
     {
         match attr::find_stability(attrs.as_slice()) {
@@ -60,7 +61,9 @@ fn annotate<F>(&mut self, id: NodeId, attrs: &Vec<Attribute>, f: F) where
                 }
             }
             None => {
-                self.parent.clone().map(|stab| self.index.local.insert(id, stab));
+                if use_parent {
+                    self.parent.clone().map(|stab| self.index.local.insert(id, stab));
+                }
                 f(self);
             }
         }
@@ -69,11 +72,24 @@ fn annotate<F>(&mut self, id: NodeId, attrs: &Vec<Attribute>, f: F) where
 
 impl<'v> Visitor<'v> for Annotator {
     fn visit_item(&mut self, i: &Item) {
-        self.annotate(i.id, &i.attrs, |v| visit::walk_item(v, i));
+        // FIXME (#18969): the following is a hack around the fact
+        // that we cannot currently annotate the stability of
+        // `deriving`.  Basically, we do *not* allow stability
+        // inheritance on trait implementations, so that derived
+        // implementations appear to be unannotated. This then allows
+        // derived implementations to be automatically tagged with the
+        // stability of the trait. This is WRONG, but expedient to get
+        // libstd stabilized for the 1.0 release.
+        let use_parent = match i.node {
+            ast::ItemImpl(_, _, Some(_), _, _) => false,
+            _ => true,
+        };
+
+        self.annotate(i.id, use_parent, &i.attrs, |v| visit::walk_item(v, i));
 
         if let ast::ItemStruct(ref sd, _) = i.node {
             sd.ctor_id.map(|id| {
-                self.annotate(id, &i.attrs, |_| {})
+                self.annotate(id, true, &i.attrs, |_| {})
             });
         }
     }
@@ -82,7 +98,7 @@ fn visit_fn(&mut self, fk: FnKind<'v>, _: &'v FnDecl,
                 _: &'v Block, _: Span, _: NodeId) {
         if let FkMethod(_, _, meth) = fk {
             // Methods are not already annotated, so we annotate it
-            self.annotate(meth.id, &meth.attrs, |_| {});
+            self.annotate(meth.id, true, &meth.attrs, |_| {});
         }
         // Items defined in a function body have no reason to have
         // a stability attribute, so we don't recurse.
@@ -101,15 +117,21 @@ fn visit_trait_item(&mut self, t: &TraitItem) {
 
             TypeTraitItem(ref typedef) => (typedef.ty_param.id, &typedef.attrs),
         };
-        self.annotate(id, attrs, |v| visit::walk_trait_item(v, t));
+        self.annotate(id, true, attrs, |v| visit::walk_trait_item(v, t));
     }
 
     fn visit_variant(&mut self, var: &Variant, g: &'v Generics) {
-        self.annotate(var.node.id, &var.node.attrs, |v| visit::walk_variant(v, var, g))
+        self.annotate(var.node.id, true, &var.node.attrs,
+                      |v| visit::walk_variant(v, var, g))
     }
 
     fn visit_struct_field(&mut self, s: &StructField) {
-        self.annotate(s.node.id, &s.node.attrs, |v| visit::walk_struct_field(v, s));
+        self.annotate(s.node.id, true, &s.node.attrs,
+                      |v| visit::walk_struct_field(v, s));
+    }
+
+    fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
+        self.annotate(i.id, &i.attrs, |_| {});
     }
 }
 
@@ -123,7 +145,8 @@ pub fn build(krate: &Crate) -> Index {
             },
             parent: None
         };
-        annotator.annotate(ast::CRATE_NODE_ID, &krate.attrs, |v| visit::walk_crate(v, krate));
+        annotator.annotate(ast::CRATE_NODE_ID, true, &krate.attrs,
+                           |v| visit::walk_crate(v, krate));
         annotator.index
     }
 }
@@ -135,16 +158,29 @@ pub fn lookup(tcx: &ty::ctxt, id: DefId) -> Option<Stability> {
     match ty::trait_item_of_item(tcx, id) {
         Some(ty::MethodTraitItemId(trait_method_id))
                 if trait_method_id != id => {
-            lookup(tcx, trait_method_id)
-        }
-        _ if is_local(id) => {
-            tcx.stability.borrow().local.get(&id.node).cloned()
-        }
-        _ => {
-            let stab = csearch::get_stability(&tcx.sess.cstore, id);
-            let mut index = tcx.stability.borrow_mut();
-            (*index).extern_cache.insert(id, stab.clone());
-            stab
+            return lookup(tcx, trait_method_id)
         }
+        _ => {}
     }
+
+    let item_stab = if is_local(id) {
+        tcx.stability.borrow().local.get(&id.node).cloned()
+    } else {
+        let stab = csearch::get_stability(&tcx.sess.cstore, id);
+        let mut index = tcx.stability.borrow_mut();
+        (*index).extern_cache.insert(id, stab.clone());
+        stab
+    };
+
+    item_stab.or_else(|| {
+        if let Some(trait_id) = ty::trait_id_of_impl(tcx, id) {
+            // FIXME (#18969): for the time being, simply use the
+            // stability of the trait to determine the stability of any
+            // unmarked impls for it. See FIXME above for more details.
+
+            lookup(tcx, trait_id)
+        } else {
+            None
+        }
+    })
 }
index 213d97b4b344aecd851b8bfa1bf6387e49fc891b..72e4eb5d1d63478843221fddd6d6c2e64d5f6aa2 100644 (file)
@@ -12,7 +12,7 @@
 use middle::mem_categorization::Typer;
 use middle::ty::{mod, Ty};
 use std::collections::HashSet;
-use std::collections::hash_map::{Occupied, Vacant};
+use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::default::Default;
 use std::rc::Rc;
 use syntax::ast;
index acf1fced72cae233f12e528eaf19b77cdce495cf..c2edcf1e3e25881c68c3dba256fb75772e44c419 100644 (file)
 use metadata::csearch;
 use middle;
 use middle::const_eval;
-use middle::def;
+use middle::def::{mod, DefMap, ExportMap};
 use middle::dependency_format;
 use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem};
 use middle::lang_items::{FnOnceTraitLangItem, TyDescStructLangItem};
 use middle::mem_categorization as mc;
 use middle::region;
-use middle::resolve;
 use middle::resolve_lifetime;
 use middle::infer;
 use middle::stability;
@@ -78,7 +77,8 @@
 use std::ops;
 use std::rc::Rc;
 use collections::enum_set::{EnumSet, CLike};
-use std::collections::hash_map::{HashMap, Occupied, Vacant};
+use std::collections::hash_map::HashMap;
+use std::collections::hash_map::Entry::{Occupied, Vacant};
 use syntax::abi;
 use syntax::ast::{CrateNum, DefId, DUMMY_NODE_ID, Ident, ItemTrait, LOCAL_CRATE};
 use syntax::ast::{MutImmutable, MutMutable, Name, NamedField, NodeId};
@@ -99,7 +99,7 @@
 /// The complete set of all analyses described in this module. This is
 /// produced by the driver and fed to trans and later passes.
 pub struct CrateAnalysis<'tcx> {
-    pub exp_map2: middle::resolve::ExportMap2,
+    pub export_map: ExportMap,
     pub exported_items: middle::privacy::ExportedItems,
     pub public_items: middle::privacy::PublicItems,
     pub ty_cx: ty::ctxt<'tcx>,
@@ -615,7 +615,7 @@ pub struct ctxt<'tcx> {
     // queried from a HashSet.
     interner: RefCell<FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>>,
     pub sess: Session,
-    pub def_map: resolve::DefMap,
+    pub def_map: DefMap,
 
     pub named_region_map: resolve_lifetime::NamedRegionMap,
 
@@ -1967,7 +1967,7 @@ pub fn trait_did(&self, cx: &ctxt) -> ast::DefId {
 
 pub fn mk_ctxt<'tcx>(s: Session,
                      type_arena: &'tcx TypedArena<TyS<'tcx>>,
-                     dm: resolve::DefMap,
+                     dm: DefMap,
                      named_region_map: resolve_lifetime::NamedRegionMap,
                      map: ast_map::Map<'tcx>,
                      freevars: RefCell<FreevarMap>,
@@ -6263,6 +6263,9 @@ pub struct Freevar {
 
 pub type CaptureModeMap = NodeMap<ast::CaptureClause>;
 
+// Trait method resolution
+pub type TraitMap = NodeMap<Vec<DefId>>;
+
 pub fn with_freevars<T, F>(tcx: &ty::ctxt, fid: ast::NodeId, f: F) -> T where
     F: FnOnce(&[Freevar]) -> T,
 {
index 71e42a9dbb3de8fe72e89685844a5733b85b793b..d69ae96d07eca21907c1b617bb05132d84af33e7 100644 (file)
@@ -82,10 +82,6 @@ fn fold_trait_ref(&mut self, t: &ty::TraitRef<'tcx>) -> ty::TraitRef<'tcx> {
         super_fold_trait_ref(self, t)
     }
 
-    fn fold_sty(&mut self, sty: &ty::sty<'tcx>) -> ty::sty<'tcx> {
-        super_fold_sty(self, sty)
-    }
-
     fn fold_substs(&mut self,
                    substs: &subst::Substs<'tcx>)
                    -> subst::Substs<'tcx> {
@@ -260,12 +256,6 @@ fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::FnSig<'tcx> {
     }
 }
 
-impl<'tcx> TypeFoldable<'tcx> for ty::sty<'tcx> {
-    fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::sty<'tcx> {
-        folder.fold_sty(self)
-    }
-}
-
 impl<'tcx> TypeFoldable<'tcx> for ty::TraitRef<'tcx> {
     fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::TraitRef<'tcx> {
         folder.fold_trait_ref(self)
@@ -521,9 +511,55 @@ fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::OutlivesPredicate
 // They should invoke `foo.fold_with()` to do recursive folding.
 
 pub fn super_fold_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
-                                                t: Ty<'tcx>)
+                                                ty: Ty<'tcx>)
                                                 -> Ty<'tcx> {
-    let sty = t.sty.fold_with(this);
+    let sty = match ty.sty {
+        ty::ty_uniq(typ) => {
+            ty::ty_uniq(typ.fold_with(this))
+        }
+        ty::ty_ptr(ref tm) => {
+            ty::ty_ptr(tm.fold_with(this))
+        }
+        ty::ty_vec(typ, sz) => {
+            ty::ty_vec(typ.fold_with(this), sz)
+        }
+        ty::ty_open(typ) => {
+            ty::ty_open(typ.fold_with(this))
+        }
+        ty::ty_enum(tid, ref substs) => {
+            ty::ty_enum(tid, substs.fold_with(this))
+        }
+        ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => {
+            ty::ty_trait(box ty::TyTrait {
+                principal: (*principal).fold_with(this),
+                bounds: bounds.fold_with(this),
+            })
+        }
+        ty::ty_tup(ref ts) => {
+            ty::ty_tup(ts.fold_with(this))
+        }
+        ty::ty_bare_fn(ref f) => {
+            ty::ty_bare_fn(f.fold_with(this))
+        }
+        ty::ty_closure(ref f) => {
+            ty::ty_closure(box f.fold_with(this))
+        }
+        ty::ty_rptr(r, ref tm) => {
+            ty::ty_rptr(r.fold_with(this), tm.fold_with(this))
+        }
+        ty::ty_struct(did, ref substs) => {
+            ty::ty_struct(did, substs.fold_with(this))
+        }
+        ty::ty_unboxed_closure(did, ref region, ref substs) => {
+            ty::ty_unboxed_closure(did, region.fold_with(this), substs.fold_with(this))
+        }
+        ty::ty_bool | ty::ty_char | ty::ty_str |
+        ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) |
+        ty::ty_err | ty::ty_infer(_) |
+        ty::ty_param(..) => {
+            ty.sty.clone()
+        }
+    };
     ty::mk_t(this.tcx(), sty)
 }
 
@@ -601,58 +637,6 @@ pub fn super_fold_mt<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
             mutbl: mt.mutbl}
 }
 
-pub fn super_fold_sty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
-                                                 sty: &ty::sty<'tcx>)
-                                                 -> ty::sty<'tcx> {
-    match *sty {
-        ty::ty_uniq(typ) => {
-            ty::ty_uniq(typ.fold_with(this))
-        }
-        ty::ty_ptr(ref tm) => {
-            ty::ty_ptr(tm.fold_with(this))
-        }
-        ty::ty_vec(typ, sz) => {
-            ty::ty_vec(typ.fold_with(this), sz)
-        }
-        ty::ty_open(typ) => {
-            ty::ty_open(typ.fold_with(this))
-        }
-        ty::ty_enum(tid, ref substs) => {
-            ty::ty_enum(tid, substs.fold_with(this))
-        }
-        ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => {
-            ty::ty_trait(box ty::TyTrait {
-                principal: (*principal).fold_with(this),
-                bounds: bounds.fold_with(this),
-            })
-        }
-        ty::ty_tup(ref ts) => {
-            ty::ty_tup(ts.fold_with(this))
-        }
-        ty::ty_bare_fn(ref f) => {
-            ty::ty_bare_fn(f.fold_with(this))
-        }
-        ty::ty_closure(ref f) => {
-            ty::ty_closure(box f.fold_with(this))
-        }
-        ty::ty_rptr(r, ref tm) => {
-            ty::ty_rptr(r.fold_with(this), tm.fold_with(this))
-        }
-        ty::ty_struct(did, ref substs) => {
-            ty::ty_struct(did, substs.fold_with(this))
-        }
-        ty::ty_unboxed_closure(did, ref region, ref substs) => {
-            ty::ty_unboxed_closure(did, region.fold_with(this), substs.fold_with(this))
-        }
-        ty::ty_bool | ty::ty_char | ty::ty_str |
-        ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) |
-        ty::ty_err | ty::ty_infer(_) |
-        ty::ty_param(..) => {
-            (*sty).clone()
-        }
-    }
-}
-
 pub fn super_fold_trait_store<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
                                                          trait_store: ty::TraitStore)
                                                          -> ty::TraitStore {
index 0c014d615caf5da0b695c03ef9c2af38de065a52..0652645907bc87ad057f8a081f61af841855a53c 100644 (file)
@@ -18,7 +18,7 @@
 pub use self::OutputType::*;
 pub use self::DebugInfoLevel::*;
 
-use session::{early_error, early_warn, Session};
+use session::{early_error, Session};
 
 use rustc_back::target::Target;
 use lint;
@@ -33,7 +33,7 @@
 use syntax::parse::token::InternedString;
 
 use std::collections::HashMap;
-use std::collections::hash_map::{Occupied, Vacant};
+use std::collections::hash_map::Entry::{Occupied, Vacant};
 use getopts::{optopt, optmulti, optflag, optflagopt};
 use getopts;
 use std::cell::{RefCell};
@@ -69,6 +69,7 @@ pub enum OutputType {
     OutputTypeLlvmAssembly,
     OutputTypeObject,
     OutputTypeExe,
+    OutputTypeDepInfo,
 }
 
 #[deriving(Clone)]
@@ -102,8 +103,7 @@ 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_name, crate_file_name).
-    pub print_metas: (bool, bool),
+    pub prints: Vec<PrintRequest>,
     pub cg: CodegenOptions,
     pub color: ColorConfig,
     pub externs: HashMap<String, Vec<String>>,
@@ -114,6 +114,14 @@ pub struct Options {
     pub alt_std_name: Option<String>
 }
 
+#[deriving(Clone, PartialEq, Eq)]
+#[allow(missing_copy_implementations)]
+pub enum PrintRequest {
+    FileNames,
+    Sysroot,
+    CrateName,
+}
+
 pub enum Input {
     /// Load source from file
     File(Path),
@@ -154,6 +162,7 @@ pub fn temp_path(&self, flavor: OutputType) -> Path {
             OutputTypeAssembly => base.with_extension("s"),
             OutputTypeLlvmAssembly => base.with_extension("ll"),
             OutputTypeObject => base.with_extension("o"),
+            OutputTypeDepInfo => base.with_extension("d"),
             OutputTypeExe => base,
         }
     }
@@ -200,7 +209,7 @@ pub fn basic_options() -> Options {
         no_analysis: false,
         debugging_opts: 0,
         write_dependency_info: (false, None),
-        print_metas: (false, false),
+        prints: Vec::new(),
         cg: basic_codegen_options(),
         color: Auto,
         externs: HashMap::new(),
@@ -266,8 +275,10 @@ macro_rules! debugging_opts {
         FLOWGRAPH_PRINT_MOVES,
         FLOWGRAPH_PRINT_ASSIGNS,
         FLOWGRAPH_PRINT_ALL,
-        PRINT_SYSROOT,
-        PRINT_REGION_GRAPH
+        PRINT_REGION_GRAPH,
+        PARSE_ONLY,
+        NO_TRANS,
+        NO_ANALYSIS
     ]
     0
 }
@@ -312,11 +323,14 @@ pub fn debugging_opts_map() -> Vec<(&'static str, &'static str, u64)> {
                        --pretty flowgraph output", FLOWGRAPH_PRINT_ASSIGNS),
      ("flowgraph-print-all", "Include all dataflow analysis data in \
                        --pretty flowgraph output", FLOWGRAPH_PRINT_ALL),
-     ("print-sysroot", "Print the sysroot as used by this rustc invocation",
-      PRINT_SYSROOT),
      ("print-region-graph", "Prints region inference graph. \
                              Use with RUST_REGION_GRAPH=help for more info",
-      PRINT_REGION_GRAPH)]
+      PRINT_REGION_GRAPH),
+     ("parse-only", "Parse only; do not compile, assemble, or link", PARSE_ONLY),
+     ("no-trans", "Run all passes except translation; no output", NO_TRANS),
+     ("no-analysis", "Parse and expand the source, but run no analysis and",
+      NO_TRANS),
+    ]
 }
 
 #[deriving(Clone)]
@@ -370,6 +384,8 @@ mod cg_type_descs {
         pub const parse_uint: Option<&'static str> = Some("a number");
         pub const parse_passes: Option<&'static str> =
             Some("a space-separated list of passes, or `all`");
+        pub const parse_opt_uint: Option<&'static str> =
+            Some("a number");
     }
 
     mod cgsetters {
@@ -441,6 +457,13 @@ fn parse_uint(slot: &mut uint, v: Option<&str>) -> bool {
             }
         }
 
+        fn parse_opt_uint(slot: &mut Option<uint>, v: Option<&str>) -> bool {
+            match v {
+                Some(s) => { *slot = from_str(s); slot.is_some() }
+                None => { *slot = None; true }
+            }
+        }
+
         fn parse_passes(slot: &mut Passes, v: Option<&str>) -> bool {
             match v {
                 Some("all") => {
@@ -510,6 +533,11 @@ fn parse_passes(slot: &mut Passes, v: Option<&str>) -> bool {
         "print remarks for these optimization passes (space separated, or \"all\")"),
     no_stack_check: bool = (false, parse_bool,
         "disable checks for stack exhaustion (a memory-safety hazard!)"),
+    debuginfo: Option<uint> = (None, parse_opt_uint,
+        "debug info emission level, 0 = no debug info, 1 = line tables only, \
+         2 = full debug info with variable and type information"),
+    opt_level: Option<uint> = (None, parse_opt_uint,
+        "Optimize with possible levels 0-3"),
 }
 
 pub fn build_codegen_options(matches: &getopts::Matches) -> CodegenOptions
@@ -625,9 +653,8 @@ pub fn build_target_config(opts: &Options, sp: &SpanHandler) -> Config {
     }
 }
 
-// rustc command line options
-pub fn optgroups() -> Vec<getopts::OptGroup> {
-    vec!(
+pub fn short_optgroups() -> Vec<getopts::OptGroup> {
+    vec![
         optflag("h", "help", "Display this message"),
         optmulti("", "cfg", "Configure the compilation environment", "SPEC"),
         optmulti("L", "",   "Add a directory to the library search path", "PATH"),
@@ -637,29 +664,68 @@ pub fn optgroups() -> Vec<getopts::OptGroup> {
                              assumed.", "NAME[:KIND]"),
         optmulti("", "crate-type", "Comma separated list of types of crates
                                     for the compiler to emit",
-                 "[bin|lib|rlib|dylib|staticlib]"),
-        optmulti("", "emit", "Comma separated list of types of output for the compiler to emit",
-                 "[asm|bc|ir|obj|link]"),
+                 "[bin|lib|rlib|dylib|staticlib|dep-info]"),
         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"),
+        optmulti("", "emit", "Comma separated list of types of output for \
+                              the compiler to emit",
+                 "[asm|llvm-bc|llvm-ir|obj|link]"),
+        optmulti("", "print", "Comma separated list of compiler information to \
+                               print on stdout",
+                 "[crate-name|output-file-names|sysroot]"),
         optflag("g",  "",  "Equivalent to --debuginfo=2"),
+        optflag("O", "", "Equivalent to --opt-level=2"),
+        optopt("o", "", "Write output to <filename>", "FILENAME"),
+        optopt("",  "out-dir", "Write output to compiler-chosen filename \
+                                in <dir>", "DIR"),
+        optopt("", "explain", "Provide a detailed explanation of an error \
+                               message", "OPT"),
+        optflag("", "test", "Build a test harness"),
+        optopt("", "target", "Target triple cpu-manufacturer-kernel[-os] \
+                              to compile for (see chapter 3.4 of \
+                              http://www.sourceware.org/autobook/
+                              for details)",
+               "TRIPLE"),
+        optmulti("W", "warn", "Set lint warnings", "OPT"),
+        optmulti("A", "allow", "Set lint allowed", "OPT"),
+        optmulti("D", "deny", "Set lint denied", "OPT"),
+        optmulti("F", "forbid", "Set lint forbidden", "OPT"),
+        optmulti("C", "codegen", "Set a codegen option", "OPT[=VALUE]"),
+        optflag("V", "version", "Print version info and exit"),
+        optflag("v", "verbose", "Use verbose output"),
+    ]
+}
+
+// rustc command line options
+pub fn optgroups() -> Vec<getopts::OptGroup> {
+    let mut opts = short_optgroups();
+    opts.push_all(&[
+        optmulti("", "extern", "Specify where an external rust library is \
+                                located",
+                 "NAME=PATH"),
+        optopt("", "opt-level", "Optimize with possible levels 0-3", "LEVEL"),
+        optopt("", "sysroot", "Override the system root", "PATH"),
+        optmulti("Z", "", "Set internal debugging options", "FLAG"),
+        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"),
+
+        // DEPRECATED
+        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"),
         optopt("",  "debuginfo",  "Emit DWARF debug info to the objects created:
              0 = no debug info,
              1 = line-tables only (for stacktraces and breakpoints),
-             2 = full debug info with variable and type information (same as -g)", "LEVEL"),
+             2 = full debug info with variable and type information \
+                    (same as -g)", "LEVEL"),
         optflag("", "no-trans", "Run all passes except translation; no output"),
-        optflag("", "no-analysis",
-              "Parse and expand the source, but run no analysis and produce no output"),
-        optflag("O", "", "Equivalent to --opt-level=2"),
-        optopt("o", "", "Write output to <filename>", "FILENAME"),
-        optopt("", "opt-level", "Optimize with possible levels 0-3", "LEVEL"),
-        optopt( "",  "out-dir", "Write output to compiler-chosen filename in <dir>", "DIR"),
-        optflag("", "parse-only", "Parse only; do not compile, assemble, or link"),
-        optopt("", "explain", "Provide a detailed explanation of an error message", "OPT"),
+        optflag("", "no-analysis", "Parse and expand the source, but run no \
+                                    analysis and produce no output"),
+        optflag("", "parse-only", "Parse only; do not compile, assemble, \
+                                   or link"),
         optflagopt("", "pretty",
                    "Pretty-print the input instead of compiling;
                    valid types are: `normal` (un-annotated source),
@@ -671,25 +737,8 @@ pub fn optgroups() -> Vec<getopts::OptGroup> {
         optflagopt("", "dep-info",
                  "Output dependency info to <filename> after compiling, \
                   in a format suitable for use by Makefiles", "FILENAME"),
-        optopt("", "sysroot", "Override the system root", "PATH"),
-        optflag("", "test", "Build a test harness"),
-        optopt("", "target", "Target triple cpu-manufacturer-kernel[-os]
-                            to compile for (see chapter 3.4 of http://www.sourceware.org/autobook/
-                            for details)", "TRIPLE"),
-        optmulti("W", "warn", "Set lint warnings", "OPT"),
-        optmulti("A", "allow", "Set lint allowed", "OPT"),
-        optmulti("D", "deny", "Set lint denied", "OPT"),
-        optmulti("F", "forbid", "Set lint forbidden", "OPT"),
-        optmulti("C", "codegen", "Set a codegen option", "OPT[=VALUE]"),
-        optmulti("Z", "", "Set internal debugging options", "FLAG"),
-        optflagopt("v", "version", "Print version info and exit", "verbose"),
-        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"),
-        optmulti("", "extern", "Specify where an external rust library is located",
-                 "NAME=PATH"),
-    )
+    ]);
+    opts
 }
 
 
@@ -709,10 +758,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
     let crate_types = parse_crate_types_from_list(unparsed_crate_types)
         .unwrap_or_else(|e| early_error(e.as_slice()));
 
-    let parse_only = matches.opt_present("parse-only");
-    let no_trans = matches.opt_present("no-trans");
-    let no_analysis = matches.opt_present("no-analysis");
-
     let mut lint_opts = vec!();
     let mut describe_lints = false;
 
@@ -744,6 +789,28 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         debugging_opts |= this_bit;
     }
 
+    let parse_only = if matches.opt_present("parse-only") {
+        // FIXME(acrichto) uncomment deprecation warning
+        // early_warn("--parse-only is deprecated in favor of -Z parse-only");
+        true
+    } else {
+        debugging_opts & PARSE_ONLY != 0
+    };
+    let no_trans = if matches.opt_present("no-trans") {
+        // FIXME(acrichto) uncomment deprecation warning
+        // early_warn("--no-trans is deprecated in favor of -Z no-trans");
+        true
+    } else {
+        debugging_opts & NO_TRANS != 0
+    };
+    let no_analysis = if matches.opt_present("no-analysis") {
+        // FIXME(acrichto) uncomment deprecation warning
+        // early_warn("--no-analysis is deprecated in favor of -Z no-analysis");
+        true
+    } else {
+        debugging_opts & NO_ANALYSIS != 0
+    };
+
     if debugging_opts & DEBUG_LLVM != 0 {
         unsafe { llvm::LLVMSetDebug(1); }
     }
@@ -754,11 +821,12 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         for unparsed_output_type in unparsed_output_types.iter() {
             for part in unparsed_output_type.split(',') {
                 let output_type = match part.as_slice() {
-                    "asm"  => OutputTypeAssembly,
-                    "ir"   => OutputTypeLlvmAssembly,
-                    "bc"   => OutputTypeBitcode,
-                    "obj"  => OutputTypeObject,
+                    "asm" => OutputTypeAssembly,
+                    "llvm-ir" => OutputTypeLlvmAssembly,
+                    "llvm-bc" => OutputTypeBitcode,
+                    "obj" => OutputTypeObject,
                     "link" => OutputTypeExe,
+                    "dep-info" => OutputTypeDepInfo,
                     _ => {
                         early_error(format!("unknown emission type: `{}`",
                                             part).as_slice())
@@ -774,6 +842,8 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         output_types.push(OutputTypeExe);
     }
 
+    let cg = build_codegen_options(matches);
+
     let sysroot_opt = matches.opt_str("sysroot").map(|m| Path::new(m));
     let target = matches.opt_str("target").unwrap_or(
         host_triple().to_string());
@@ -782,8 +852,13 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
             if matches.opt_present("opt-level") {
                 early_error("-O and --opt-level both provided");
             }
+            if cg.opt_level.is_some() {
+                early_error("-O and -C opt-level both provided");
+            }
             Default
         } else if matches.opt_present("opt-level") {
+            // FIXME(acrichto) uncomment deprecation warning
+            // early_warn("--opt-level=N is deprecated in favor of -C opt-level=N");
             match matches.opt_str("opt-level").as_ref().map(|s| s.as_slice()) {
                 None      |
                 Some("0") => No,
@@ -797,7 +872,18 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
                 }
             }
         } else {
-            No
+            match cg.opt_level {
+                None => No,
+                Some(0) => No,
+                Some(1) => Less,
+                Some(2) => Default,
+                Some(3) => Aggressive,
+                Some(arg) => {
+                    early_error(format!("optimization level needs to be \
+                                         between 0-3 (instead was `{}`)",
+                                        arg).as_slice());
+                }
+            }
         }
     };
     let gc = debugging_opts & GC != 0;
@@ -805,8 +891,13 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         if matches.opt_present("debuginfo") {
             early_error("-g and --debuginfo both provided");
         }
+        if cg.debuginfo.is_some() {
+            early_error("-g and -C debuginfo both provided");
+        }
         FullDebugInfo
     } else if matches.opt_present("debuginfo") {
+        // FIXME(acrichto) uncomment deprecation warning
+        // early_warn("--debuginfo=N is deprecated in favor of -C debuginfo=N");
         match matches.opt_str("debuginfo").as_ref().map(|s| s.as_slice()) {
             Some("0") => NoDebugInfo,
             Some("1") => LimitedDebugInfo,
@@ -819,7 +910,16 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
             }
         }
     } else {
-        NoDebugInfo
+        match cg.debuginfo {
+            None | Some(0) => NoDebugInfo,
+            Some(1) => LimitedDebugInfo,
+            Some(2) => FullDebugInfo,
+            Some(arg) => {
+                early_error(format!("debug info level needs to be between \
+                                     0-2 (instead was `{}`)",
+                                    arg).as_slice());
+            }
+        }
     };
 
     let addl_lib_search_paths = matches.opt_strs("L").iter().map(|s| {
@@ -845,21 +945,41 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
 
     let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
     let test = matches.opt_present("test");
-    let write_dependency_info = (matches.opt_present("dep-info"),
-                                 matches.opt_str("dep-info")
-                                        .map(|p| Path::new(p)));
-
-    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 write_dependency_info = if matches.opt_present("dep-info") {
+        // FIXME(acrichto) uncomment deprecation warning
+        // early_warn("--dep-info has been deprecated in favor of --emit");
+        (true, matches.opt_str("dep-info").map(|p| Path::new(p)))
+    } else {
+        (output_types.contains(&OutputTypeDepInfo), None)
+    };
+
+    let mut prints = matches.opt_strs("print").into_iter().map(|s| {
+        match s.as_slice() {
+            "crate-name" => PrintRequest::CrateName,
+            "file-names" => PrintRequest::FileNames,
+            "sysroot" => PrintRequest::Sysroot,
+            req => {
+                early_error(format!("unknown print request `{}`", req).as_slice())
+            }
+        }
+    }).collect::<Vec<_>>();
+    if matches.opt_present("print-crate-name") {
+        // FIXME(acrichto) uncomment deprecation warning
+        // early_warn("--print-crate-name has been deprecated in favor of \
+        //             --print crate-name");
+        prints.push(PrintRequest::CrateName);
+    }
+    if matches.opt_present("print-file-name") {
+        // FIXME(acrichto) uncomment deprecation warning
+        // early_warn("--print-file-name has been deprecated in favor of \
+        //             --print file-names");
+        prints.push(PrintRequest::FileNames);
     }
-    let cg = build_codegen_options(matches);
 
     if !cg.remark.is_empty() && debuginfo == NoDebugInfo {
-        early_warn("-C remark will not show source locations without --debuginfo");
+        // FIXME(acrichto) uncomment deprecation warning
+        // early_warn("-C remark will not show source locations without \
+        //             --debuginfo");
     }
 
     let color = match matches.opt_str("color").as_ref().map(|s| s.as_slice()) {
@@ -914,7 +1034,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         no_analysis: no_analysis,
         debugging_opts: debugging_opts,
         write_dependency_info: write_dependency_info,
-        print_metas: print_metas,
+        prints: prints,
         cg: cg,
         color: color,
         externs: externs,
index b0124977c9f1b9ff25a083591fbe11803b8eaf35..34d89162249fa21b4bb848446bc61b64bc35c20f 100644 (file)
@@ -93,8 +93,9 @@ pub fn explain_region_and_span(cx: &ctxt, region: ty::Region)
               ast::ExprMethodCall(..) => {
                 explain_span(cx, "method call", expr.span)
               },
-              ast::ExprMatch(_, _, ast::MatchIfLetDesugar) => explain_span(cx, "if let", expr.span),
-              ast::ExprMatch(_, _, ast::MatchWhileLetDesugar) => {
+              ast::ExprMatch(_, _, ast::MatchSource::IfLetDesugar { .. }) =>
+                  explain_span(cx, "if let", expr.span),
+              ast::ExprMatch(_, _, ast::MatchSource::WhileLetDesugar) => {
                   explain_span(cx, "while let", expr.span)
               },
               ast::ExprMatch(..) => explain_span(cx, "match", expr.span),
@@ -452,7 +453,7 @@ fn infer_ty_to_string(cx: &ctxt, ty: ty::InferTy) -> String {
         ty_vec(t, sz) => {
             let inner_str = ty_to_string(cx, t);
             match sz {
-                Some(n) => format!("[{}, ..{}]", inner_str, n),
+                Some(n) => format!("[{}{}]", inner_str, n),
                 None => format!("[{}]", inner_str),
             }
         }
@@ -532,7 +533,11 @@ pub fn parameterized<'tcx>(cx: &ctxt<'tcx>,
     if cx.lang_items.fn_trait_kind(did).is_some() {
         format!("{}({}){}",
                 base,
-                strs[0][1 .. strs[0].len() - (strs[0].ends_with(",)") as uint+1)],
+                if strs[0].starts_with("(") && strs[0].ends_with(",)") {
+                    strs[0][1 .. strs[0].len() - 2] // Remove '(' and ',)'
+                } else {
+                    strs[0][]
+                },
                 if &*strs[1] == "()" { String::new() } else { format!(" -> {}", strs[1]) })
     } else if strs.len() > 0 {
         format!("{}<{}>", base, strs.connect(", "))
index d033fd808aa40eadedd842cba911b42a4ebf529e..5d2faa52f1ad0f288b33031a1a8039decaf2df24 100644 (file)
@@ -14,8 +14,6 @@
 pub use self::MoveKind::*;
 
 use borrowck::*;
-use borrowck::LoanPathKind::{LpVar, LpUpvar, LpDowncast, LpExtend};
-use borrowck::LoanPathElem::{LpInterior};
 use rustc::middle::cfg;
 use rustc::middle::dataflow::DataFlowContext;
 use rustc::middle::dataflow::BitwiseOperator;
index ffc5a3919b60f96605e9e867bcb6203229e21214..e71e9e5dfea1b87728a9bd6170044e5849471207 100644 (file)
@@ -16,7 +16,7 @@
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/")]
 
-#![feature(default_type_params, globs, import_shadowing, macro_rules, phase, quote)]
+#![feature(default_type_params, globs, macro_rules, phase, quote)]
 #![feature(slicing_syntax, unsafe_destructor)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(unboxed_closures)]
index 9ed4f46c16884ae08e439c6211b127d69a632909..60b890b037095c0f0845a76777d20a9858c81efe 100644 (file)
@@ -20,6 +20,7 @@
 use rustc::plugin;
 use rustc::util::common::time;
 use rustc_borrowck as borrowck;
+use rustc_resolve as resolve;
 use rustc_trans::back::link;
 use rustc_trans::back::write;
 use rustc_trans::save;
@@ -341,17 +342,17 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
     let lang_items = time(time_passes, "language item collection", (), |_|
                           middle::lang_items::collect_language_items(krate, &sess));
 
-    let middle::resolve::CrateMap {
+    let resolve::CrateMap {
         def_map,
         freevars,
         capture_mode_map,
-        exp_map2,
+        export_map,
         trait_map,
         external_exports,
         last_private_map
     } =
-        time(time_passes, "resolution", (), |_|
-             middle::resolve::resolve_crate(&sess, &lang_items, krate));
+        time(time_passes, "resolution", (),
+             |_| resolve::resolve_crate(&sess, &lang_items, krate));
 
     // Discard MTWT tables that aren't required past resolution.
     syntax::ext::mtwt::clear_tables();
@@ -406,7 +407,7 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
     let maps = (external_exports, last_private_map);
     let (exported_items, public_items) =
             time(time_passes, "privacy checking", maps, |(a, b)|
-                 middle::privacy::check_crate(&ty_cx, &exp_map2, a, b));
+                 middle::privacy::check_crate(&ty_cx, &export_map, a, b));
 
     time(time_passes, "intrinsic checking", (), |_|
          middle::intrinsicck::check_crate(&ty_cx));
@@ -447,7 +448,7 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
          lint::check_crate(&ty_cx, &exported_items));
 
     ty::CrateAnalysis {
-        exp_map2: exp_map2,
+        export_map: export_map,
         ty_cx: ty_cx,
         exported_items: exported_items,
         public_items: public_items,
index 120654678e96e9d2b83431b47b60e787f75eecef..6944c733456f6bc919c552a1d4b9fdc4182bbdf9 100644 (file)
@@ -22,7 +22,7 @@
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/")]
 
-#![feature(default_type_params, globs, import_shadowing, macro_rules, phase, quote)]
+#![feature(default_type_params, globs, macro_rules, phase, quote)]
 #![feature(slicing_syntax, unsafe_destructor)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(unboxed_closures)]
@@ -35,6 +35,7 @@
 extern crate rustc;
 extern crate rustc_back;
 extern crate rustc_borrowck;
+extern crate rustc_resolve;
 extern crate rustc_trans;
 extern crate rustc_typeck;
 #[phase(plugin, link)] extern crate log;
@@ -46,7 +47,7 @@
 
 use rustc_trans::back::link;
 use rustc::session::{config, Session, build_session};
-use rustc::session::config::Input;
+use rustc::session::config::{Input, PrintRequest};
 use rustc::lint::Lint;
 use rustc::lint;
 use rustc::metadata;
@@ -101,6 +102,8 @@ fn run_compiler(args: &[String]) {
     }
 
     let sopts = config::build_session_options(&matches);
+    let odir = matches.opt_str("out-dir").map(|o| Path::new(o));
+    let ofile = matches.opt_str("o").map(|o| Path::new(o));
     let (input, input_file_path) = match matches.free.len() {
         0u => {
             if sopts.describe_lints {
@@ -109,13 +112,10 @@ fn run_compiler(args: &[String]) {
                 describe_lints(&ls, false);
                 return;
             }
-
             let sess = build_session(sopts, None, descriptions);
-            if sess.debugging_opt(config::PRINT_SYSROOT) {
-                println!("{}", sess.sysroot().display());
+            if print_crate_info(&sess, None, &odir, &ofile) {
                 return;
             }
-
             early_error("no input filename given");
         }
         1u => {
@@ -133,13 +133,14 @@ fn run_compiler(args: &[String]) {
 
     let sess = build_session(sopts, input_file_path, descriptions);
     let cfg = config::build_configuration(&sess);
-    let odir = matches.opt_str("out-dir").map(|o| Path::new(o));
-    let ofile = matches.opt_str("o").map(|o| Path::new(o));
+    if print_crate_info(&sess, Some(&input), &odir, &ofile) {
+        return
+    }
 
     let pretty = matches.opt_default("pretty", "normal").map(|a| {
         pretty::parse_pretty(&sess, a.as_slice())
     });
-    match pretty {
+    match pretty.into_iter().next() {
         Some((ppm, opt_uii)) => {
             pretty::pretty_print_input(sess, cfg, &input, ppm, opt_uii, ofile);
             return;
@@ -161,10 +162,6 @@ fn run_compiler(args: &[String]) {
         return;
     }
 
-    if print_crate_info(&sess, &input, &odir, &ofile) {
-        return;
-    }
-
     driver::compile_input(sess, cfg, &input, &odir, &ofile, None);
 }
 
@@ -185,12 +182,8 @@ pub fn commit_date_str() -> Option<&'static str> {
 
 /// Prints version information and returns None on success or an error
 /// message on panic.
-pub fn version(binary: &str, matches: &getopts::Matches) -> Option<String> {
-    let verbose = match matches.opt_str("version").as_ref().map(|s| s.as_slice()) {
-        None => false,
-        Some("verbose") => true,
-        Some(s) => return Some(format!("Unrecognized argument: {}", s))
-    };
+pub fn version(binary: &str, matches: &getopts::Matches) {
+    let verbose = matches.opt_present("verbose");
 
     println!("{} {}", binary, option_env!("CFG_VERSION").unwrap_or("unknown version"));
     if verbose {
@@ -201,18 +194,27 @@ fn unw(x: Option<&str>) -> &str { x.unwrap_or("unknown") }
         println!("host: {}", config::host_triple());
         println!("release: {}", unw(release_str()));
     }
-    None
 }
 
-fn usage() {
+fn usage(verbose: bool) {
+    let groups = if verbose {
+        config::optgroups()
+    } else {
+        config::short_optgroups()
+    };
     let message = format!("Usage: rustc [OPTIONS] INPUT");
+    let extra_help = if verbose {
+        ""
+    } else {
+        "\n    --help -v           Print the full set of options rustc accepts"
+    };
     println!("{}\n\
 Additional help:
     -C help             Print codegen options
     -W help             Print 'lint' options and default settings
-    -Z help             Print internal options for debugging rustc\n",
-              getopts::usage(message.as_slice(),
-                             config::optgroups().as_slice()));
+    -Z help             Print internal options for debugging rustc{}\n",
+              getopts::usage(message.as_slice(), groups.as_slice()),
+              extra_help);
 }
 
 fn describe_lints(lint_store: &lint::LintStore, loaded_plugins: bool) {
@@ -360,7 +362,7 @@ pub fn handle_options(mut args: Vec<String>) -> Option<getopts::Matches> {
     let _binary = args.remove(0).unwrap();
 
     if args.is_empty() {
-        usage();
+        usage(false);
         return None;
     }
 
@@ -373,7 +375,7 @@ pub fn handle_options(mut args: Vec<String>) -> Option<getopts::Matches> {
         };
 
     if matches.opt_present("h") || matches.opt_present("help") {
-        usage();
+        usage(matches.opt_present("verbose"));
         return None;
     }
 
@@ -397,49 +399,55 @@ pub fn handle_options(mut args: Vec<String>) -> Option<getopts::Matches> {
     }
 
     if matches.opt_present("version") {
-        match version("rustc", &matches) {
-            Some(err) => early_error(err.as_slice()),
-            None => return None
-        }
+        version("rustc", &matches);
+        return None;
     }
 
     Some(matches)
 }
 
 fn print_crate_info(sess: &Session,
-                    input: &Input,
+                    input: Option<&Input>,
                     odir: &Option<Path>,
                     ofile: &Option<Path>)
                     -> bool {
-    let (crate_name, crate_file_name) = sess.opts.print_metas;
-    // these nasty nested conditions are to avoid doing extra work
-    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_name(Some(sess), attrs.as_slice(), input);
-
-        if crate_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.as_slice(),
-                                                     &t_outputs.with_extension(""));
-                println!("{}", fname.filename_display());
+    if sess.opts.prints.len() == 0 { return false }
+
+    let attrs = input.map(|input| parse_crate_attrs(sess, input));
+    for req in sess.opts.prints.iter() {
+        match *req {
+            PrintRequest::Sysroot => println!("{}", sess.sysroot().display()),
+            PrintRequest::FileNames |
+            PrintRequest::CrateName => {
+                let input = match input {
+                    Some(input) => input,
+                    None => early_error("no input file provided"),
+                };
+                let attrs = attrs.as_ref().unwrap().as_slice();
+                let t_outputs = driver::build_output_filenames(input,
+                                                               odir,
+                                                               ofile,
+                                                               attrs,
+                                                               sess);
+                let id = link::find_crate_name(Some(sess), attrs.as_slice(),
+                                               input);
+                if *req == PrintRequest::CrateName {
+                    println!("{}", id);
+                    continue
+                }
+                let crate_types = driver::collect_crate_types(sess, attrs);
+                let metadata = driver::collect_crate_metadata(sess, attrs);
+                *sess.crate_metadata.borrow_mut() = metadata;
+                for &style in crate_types.iter() {
+                    let fname = link::filename_for_input(sess, style,
+                                                         id.as_slice(),
+                                                         &t_outputs.with_extension(""));
+                    println!("{}", fname.filename_display());
+                }
             }
         }
-
-        true
-    } else {
-        false
     }
+    return true;
 }
 
 fn parse_crate_attrs(sess: &Session, input: &Input) ->
@@ -472,7 +480,7 @@ pub fn list_metadata(sess: &Session, path: &Path,
 /// The diagnostic emitter yielded to the procedure should be used for reporting
 /// errors of the compiler.
 pub fn monitor<F:FnOnce()+Send>(f: F) {
-    static STACK_SIZE: uint = 32000000; // 32MB
+    static STACK_SIZE: uint = 8 * 1024 * 1024; // 8MB
 
     let (tx, rx) = channel();
     let w = io::ChanWriter::new(tx);
index b2c661cc58aa40ef035d6b9412bb892858e1ce60..090d6a7a3caef2d81fb855110bf35e11d12f9e25 100644 (file)
@@ -13,9 +13,9 @@
 use diagnostic;
 use diagnostic::Emitter;
 use driver;
+use rustc_resolve as resolve;
 use rustc_typeck::middle::lang_items;
 use rustc_typeck::middle::region::{mod, CodeExtent};
-use rustc_typeck::middle::resolve;
 use rustc_typeck::middle::resolve_lifetime;
 use rustc_typeck::middle::stability;
 use rustc_typeck::middle::subst;
diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs
new file mode 100644 (file)
index 0000000..39cdf6f
--- /dev/null
@@ -0,0 +1,161 @@
+// 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.
+
+
+//
+// Unused import checking
+//
+// Although this is mostly a lint pass, it lives in here because it depends on
+// resolve data structures and because it finalises the privacy information for
+// `use` directives.
+//
+
+use Resolver;
+use Namespace::{TypeNS, ValueNS};
+
+use rustc::lint;
+use rustc::middle::privacy::{DependsOn, LastImport, Used, Unused};
+use syntax::ast;
+use syntax::ast::{ViewItem, ViewItemExternCrate, ViewItemUse};
+use syntax::ast::{ViewPathGlob, ViewPathList, ViewPathSimple};
+use syntax::codemap::{Span, DUMMY_SP};
+use syntax::visit::{mod, Visitor};
+
+struct UnusedImportCheckVisitor<'a, 'b:'a> {
+    resolver: &'a mut Resolver<'b>
+}
+
+// Deref and DerefMut impls allow treating UnusedImportCheckVisitor as Resolver.
+impl<'a, 'b> Deref<Resolver<'b>> for UnusedImportCheckVisitor<'a, 'b> {
+    fn deref<'c>(&'c self) -> &'c Resolver<'b> {
+        &*self.resolver
+    }
+}
+
+impl<'a, 'b> DerefMut<Resolver<'b>> for UnusedImportCheckVisitor<'a, 'b> {
+    fn deref_mut<'c>(&'c mut self) -> &'c mut Resolver<'b> {
+        &mut *self.resolver
+    }
+}
+
+impl<'a, 'b> UnusedImportCheckVisitor<'a, 'b> {
+    // We have information about whether `use` (import) directives are actually used now.
+    // If an import is not used at all, we signal a lint error. If an import is only used
+    // for a single namespace, we remove the other namespace from the recorded privacy
+    // information. That means in privacy.rs, we will only check imports and namespaces
+    // which are used. In particular, this means that if an import could name either a
+    // public or private item, we will check the correct thing, dependent on how the import
+    // is used.
+    fn finalize_import(&mut self, id: ast::NodeId, span: Span) {
+        debug!("finalizing import uses for {}",
+                self.session.codemap().span_to_snippet(span));
+
+        if !self.used_imports.contains(&(id, TypeNS)) &&
+           !self.used_imports.contains(&(id, ValueNS)) {
+            self.session.add_lint(lint::builtin::UNUSED_IMPORTS,
+                                  id,
+                                  span,
+                                  "unused import".to_string());
+        }
+
+        let (v_priv, t_priv) = match self.last_private.get(&id) {
+            Some(&LastImport {
+                value_priv: v,
+                value_used: _,
+                type_priv: t,
+                type_used: _
+            }) => (v, t),
+            Some(_) => {
+                panic!("we should only have LastImport for `use` directives")
+            }
+            _ => return,
+        };
+
+        let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
+            Used
+        } else {
+            Unused
+        };
+        let t_used = if self.used_imports.contains(&(id, TypeNS)) {
+            Used
+        } else {
+            Unused
+        };
+
+        match (v_priv, t_priv) {
+            // Since some items may be both in the value _and_ type namespaces (e.g., structs)
+            // we might have two LastPrivates pointing at the same thing. There is no point
+            // checking both, so lets not check the value one.
+            (Some(DependsOn(def_v)), Some(DependsOn(def_t))) if def_v == def_t => v_used = Unused,
+            _ => {},
+        }
+
+        self.last_private.insert(id, LastImport{value_priv: v_priv,
+                                                value_used: v_used,
+                                                type_priv: t_priv,
+                                                type_used: t_used});
+    }
+}
+
+impl<'a, 'b, 'v> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b> {
+    fn visit_view_item(&mut self, vi: &ViewItem) {
+        // Ignore is_public import statements because there's no way to be sure
+        // whether they're used or not. Also ignore imports with a dummy span
+        // because this means that they were generated in some fashion by the
+        // compiler and we don't need to consider them.
+        if vi.vis == ast::Public || vi.span == DUMMY_SP {
+            visit::walk_view_item(self, vi);
+            return;
+        }
+
+        match vi.node {
+            ViewItemExternCrate(_, _, id) => {
+                if let Some(crate_num) = self.session.cstore.find_extern_mod_stmt_cnum(id) {
+                    if !self.used_crates.contains(&crate_num) {
+                        self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATES,
+                                              id,
+                                              vi.span,
+                                              "unused extern crate".to_string());
+                    }
+                }
+            },
+            ViewItemUse(ref p) => {
+                match p.node {
+                    ViewPathSimple(_, _, id) => {
+                        self.finalize_import(id, p.span)
+                    }
+
+                    ViewPathList(_, ref list, _) => {
+                        for i in list.iter() {
+                            self.finalize_import(i.node.id(), i.span);
+                        }
+                    }
+                    ViewPathGlob(_, id) => {
+                        if !self.used_imports.contains(&(id, TypeNS)) &&
+                           !self.used_imports.contains(&(id, ValueNS)) {
+                            self.session
+                                .add_lint(lint::builtin::UNUSED_IMPORTS,
+                                          id,
+                                          p.span,
+                                          "unused import".to_string());
+                        }
+                    }
+                }
+            }
+        }
+
+        visit::walk_view_item(self, vi);
+    }
+}
+
+pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) {
+    let mut visitor = UnusedImportCheckVisitor { resolver: resolver };
+    visit::walk_crate(&mut visitor, krate);
+}
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
new file mode 100644 (file)
index 0000000..ac8d5d1
--- /dev/null
@@ -0,0 +1,6027 @@
+// 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.
+
+#![crate_name = "rustc_resolve"]
+#![experimental]
+#![crate_type = "dylib"]
+#![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/nightly/")]
+
+#![feature(globs, phase, slicing_syntax)]
+#![feature(rustc_diagnostic_macros)]
+
+#[phase(plugin, link)] extern crate log;
+#[phase(plugin, link)] extern crate syntax;
+
+extern crate rustc;
+
+use self::PatternBindingMode::*;
+use self::Namespace::*;
+use self::NamespaceError::*;
+use self::NamespaceResult::*;
+use self::NameDefinition::*;
+use self::ImportDirectiveSubclass::*;
+use self::ReducedGraphParent::*;
+use self::ResolveResult::*;
+use self::FallbackSuggestion::*;
+use self::TypeParameters::*;
+use self::RibKind::*;
+use self::MethodSort::*;
+use self::UseLexicalScopeFlag::*;
+use self::ModulePrefixResult::*;
+use self::NameSearchType::*;
+use self::BareIdentifierPatternResolution::*;
+use self::DuplicateCheckingMode::*;
+use self::ParentLink::*;
+use self::ModuleKind::*;
+use self::TraitReferenceType::*;
+use self::FallbackChecks::*;
+
+use rustc::session::Session;
+use rustc::lint;
+use rustc::metadata::csearch;
+use rustc::metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
+use rustc::middle::def::*;
+use rustc::middle::lang_items::LanguageItems;
+use rustc::middle::pat_util::pat_bindings;
+use rustc::middle::privacy::*;
+use rustc::middle::subst::{ParamSpace, FnSpace, TypeSpace};
+use rustc::middle::ty::{CaptureModeMap, Freevar, FreevarMap, TraitMap};
+use rustc::util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap};
+
+use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
+use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField};
+use syntax::ast::{ExprClosure, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall};
+use syntax::ast::{ExprPath, ExprStruct, FnDecl};
+use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic, Generics};
+use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemFn};
+use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
+use syntax::ast::{ItemStruct, ItemTrait, ItemTy, Local};
+use syntax::ast::{MethodImplItem, Mod, Name, NamedField, NodeId};
+use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
+use syntax::ast::{PatRange, PatStruct, Path, PathListIdent, PathListMod};
+use syntax::ast::{PolyTraitRef, PrimTy, Public, SelfExplicit, SelfStatic};
+use syntax::ast::{RegionTyParamBound, StmtDecl, StructField};
+use syntax::ast::{StructVariantKind, TraitRef, TraitTyParamBound};
+use syntax::ast::{TupleVariantKind, Ty, TyBool, TyChar, TyClosure, TyF32};
+use syntax::ast::{TyF64, TyFloat, TyI, TyI8, TyI16, TyI32, TyI64, TyInt, TyObjectSum};
+use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyPolyTraitRef, TyQPath};
+use syntax::ast::{TyRptr, TyStr, TyU, TyU8, TyU16, TyU32, TyU64, TyUint};
+use syntax::ast::{TypeImplItem, UnnamedField};
+use syntax::ast::{Variant, ViewItem, ViewItemExternCrate};
+use syntax::ast::{ViewItemUse, ViewPathGlob, ViewPathList, ViewPathSimple};
+use syntax::ast::{Visibility};
+use syntax::ast;
+use syntax::ast_util::{mod, PostExpansionMethod, local_def, walk_pat};
+use syntax::attr::AttrMetaMethods;
+use syntax::ext::mtwt;
+use syntax::parse::token::{mod, special_names, special_idents};
+use syntax::codemap::{Span, DUMMY_SP, Pos};
+use syntax::owned_slice::OwnedSlice;
+use syntax::visit::{mod, Visitor};
+
+use std::collections::{HashMap, HashSet};
+use std::collections::hash_map::Entry::{Occupied, Vacant};
+use std::cell::{Cell, RefCell};
+use std::mem::replace;
+use std::rc::{Rc, Weak};
+use std::uint;
+
+mod check_unused;
+mod record_exports;
+
+#[deriving(Copy)]
+struct BindingInfo {
+    span: Span,
+    binding_mode: BindingMode,
+}
+
+// Map from the name in a pattern to its binding mode.
+type BindingMap = HashMap<Name, BindingInfo>;
+
+#[deriving(Copy, PartialEq)]
+enum PatternBindingMode {
+    RefutableMode,
+    LocalIrrefutableMode,
+    ArgumentIrrefutableMode,
+}
+
+#[deriving(Copy, PartialEq, Eq, Hash, Show)]
+enum Namespace {
+    TypeNS,
+    ValueNS
+}
+
+#[deriving(Copy, PartialEq)]
+enum NamespaceError {
+    NoError,
+    ModuleError,
+    TypeError,
+    ValueError
+}
+
+/// A NamespaceResult represents the result of resolving an import in
+/// a particular namespace. The result is either definitely-resolved,
+/// definitely- unresolved, or unknown.
+#[deriving(Clone)]
+enum NamespaceResult {
+    /// Means that resolve hasn't gathered enough information yet to determine
+    /// whether the name is bound in this namespace. (That is, it hasn't
+    /// resolved all `use` directives yet.)
+    UnknownResult,
+    /// Means that resolve has determined that the name is definitely
+    /// not bound in the namespace.
+    UnboundResult,
+    /// Means that resolve has determined that the name is bound in the Module
+    /// argument, and specified by the NameBindings argument.
+    BoundResult(Rc<Module>, Rc<NameBindings>)
+}
+
+impl NamespaceResult {
+    fn is_unknown(&self) -> bool {
+        match *self {
+            UnknownResult => true,
+            _ => false
+        }
+    }
+    fn is_unbound(&self) -> bool {
+        match *self {
+            UnboundResult => true,
+            _ => false
+        }
+    }
+}
+
+enum NameDefinition {
+    NoNameDefinition,           //< The name was unbound.
+    ChildNameDefinition(Def, LastPrivate), //< The name identifies an immediate child.
+    ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
+}
+
+impl<'a, 'v> Visitor<'v> for Resolver<'a> {
+    fn visit_item(&mut self, item: &Item) {
+        self.resolve_item(item);
+    }
+    fn visit_arm(&mut self, arm: &Arm) {
+        self.resolve_arm(arm);
+    }
+    fn visit_block(&mut self, block: &Block) {
+        self.resolve_block(block);
+    }
+    fn visit_expr(&mut self, expr: &Expr) {
+        self.resolve_expr(expr);
+    }
+    fn visit_local(&mut self, local: &Local) {
+        self.resolve_local(local);
+    }
+    fn visit_ty(&mut self, ty: &Ty) {
+        self.resolve_type(ty);
+    }
+}
+
+/// Contains data for specific types of import directives.
+#[deriving(Copy)]
+enum ImportDirectiveSubclass {
+    SingleImport(Name /* target */, Name /* source */),
+    GlobImport
+}
+
+/// The context that we thread through while building the reduced graph.
+#[deriving(Clone)]
+enum ReducedGraphParent {
+    ModuleReducedGraphParent(Rc<Module>)
+}
+
+impl ReducedGraphParent {
+    fn module(&self) -> Rc<Module> {
+        match *self {
+            ModuleReducedGraphParent(ref m) => {
+                m.clone()
+            }
+        }
+    }
+}
+
+type ErrorMessage = Option<(Span, String)>;
+
+enum ResolveResult<T> {
+    Failed(ErrorMessage),   // Failed to resolve the name, optional helpful error message.
+    Indeterminate,          // Couldn't determine due to unresolved globs.
+    Success(T)              // Successfully resolved the import.
+}
+
+impl<T> ResolveResult<T> {
+    fn indeterminate(&self) -> bool {
+        match *self { Indeterminate => true, _ => false }
+    }
+}
+
+enum FallbackSuggestion {
+    NoSuggestion,
+    Field,
+    Method,
+    TraitItem,
+    StaticMethod(String),
+    TraitMethod(String),
+}
+
+#[deriving(Copy)]
+enum TypeParameters<'a> {
+    NoTypeParameters,
+    HasTypeParameters(
+        // Type parameters.
+        &'a Generics,
+
+        // Identifies the things that these parameters
+        // were declared on (type, fn, etc)
+        ParamSpace,
+
+        // ID of the enclosing item.
+        NodeId,
+
+        // The kind of the rib used for type parameters.
+        RibKind)
+}
+
+// The rib kind controls the translation of local
+// definitions (`DefLocal`) to upvars (`DefUpvar`).
+#[deriving(Copy, Show)]
+enum RibKind {
+    // No translation needs to be applied.
+    NormalRibKind,
+
+    // We passed through a closure scope at the given node ID.
+    // Translate upvars as appropriate.
+    ClosureRibKind(NodeId /* func id */, NodeId /* body id if proc or unboxed */),
+
+    // We passed through an impl or trait and are now in one of its
+    // methods. Allow references to ty params that impl or trait
+    // binds. Disallow any other upvars (including other ty params that are
+    // upvars).
+              // parent;   method itself
+    MethodRibKind(NodeId, MethodSort),
+
+    // We passed through an item scope. Disallow upvars.
+    ItemRibKind,
+
+    // We're in a constant item. Can't refer to dynamic stuff.
+    ConstantItemRibKind
+}
+
+// Methods can be required or provided. RequiredMethod methods only occur in traits.
+#[deriving(Copy, Show)]
+enum MethodSort {
+    RequiredMethod,
+    ProvidedMethod(NodeId)
+}
+
+#[deriving(Copy)]
+enum UseLexicalScopeFlag {
+    DontUseLexicalScope,
+    UseLexicalScope
+}
+
+enum ModulePrefixResult {
+    NoPrefixFound,
+    PrefixFound(Rc<Module>, uint)
+}
+
+#[deriving(Copy, PartialEq)]
+enum NameSearchType {
+    /// We're doing a name search in order to resolve a `use` directive.
+    ImportSearch,
+
+    /// We're doing a name search in order to resolve a path type, a path
+    /// expression, or a path pattern.
+    PathSearch,
+}
+
+#[deriving(Copy)]
+enum BareIdentifierPatternResolution {
+    FoundStructOrEnumVariant(Def, LastPrivate),
+    FoundConst(Def, LastPrivate),
+    BareIdentifierPatternUnresolved
+}
+
+// Specifies how duplicates should be handled when adding a child item if
+// another item exists with the same name in some namespace.
+#[deriving(Copy, PartialEq)]
+enum DuplicateCheckingMode {
+    ForbidDuplicateModules,
+    ForbidDuplicateTypesAndModules,
+    ForbidDuplicateValues,
+    ForbidDuplicateTypesAndValues,
+    OverwriteDuplicates
+}
+
+/// One local scope.
+#[deriving(Show)]
+struct Rib {
+    bindings: HashMap<Name, DefLike>,
+    kind: RibKind,
+}
+
+impl Rib {
+    fn new(kind: RibKind) -> Rib {
+        Rib {
+            bindings: HashMap::new(),
+            kind: kind
+        }
+    }
+}
+
+/// One import directive.
+struct ImportDirective {
+    module_path: Vec<Name>,
+    subclass: ImportDirectiveSubclass,
+    span: Span,
+    id: NodeId,
+    is_public: bool, // see note in ImportResolution about how to use this
+    shadowable: bool,
+}
+
+impl ImportDirective {
+    fn new(module_path: Vec<Name> ,
+           subclass: ImportDirectiveSubclass,
+           span: Span,
+           id: NodeId,
+           is_public: bool,
+           shadowable: bool)
+           -> ImportDirective {
+        ImportDirective {
+            module_path: module_path,
+            subclass: subclass,
+            span: span,
+            id: id,
+            is_public: is_public,
+            shadowable: shadowable,
+        }
+    }
+}
+
+/// The item that an import resolves to.
+#[deriving(Clone)]
+struct Target {
+    target_module: Rc<Module>,
+    bindings: Rc<NameBindings>,
+    shadowable: bool,
+}
+
+impl Target {
+    fn new(target_module: Rc<Module>,
+           bindings: Rc<NameBindings>,
+           shadowable: bool)
+           -> Target {
+        Target {
+            target_module: target_module,
+            bindings: bindings,
+            shadowable: shadowable,
+        }
+    }
+}
+
+/// An ImportResolution represents a particular `use` directive.
+struct ImportResolution {
+    /// Whether this resolution came from a `use` or a `pub use`. Note that this
+    /// should *not* be used whenever resolution is being performed, this is
+    /// only looked at for glob imports statements currently. Privacy testing
+    /// occurs during a later phase of compilation.
+    is_public: bool,
+
+    // The number of outstanding references to this name. When this reaches
+    // zero, outside modules can count on the targets being correct. Before
+    // then, all bets are off; future imports could override this name.
+    outstanding_references: uint,
+
+    /// The value that this `use` directive names, if there is one.
+    value_target: Option<Target>,
+    /// The source node of the `use` directive leading to the value target
+    /// being non-none
+    value_id: NodeId,
+
+    /// The type that this `use` directive names, if there is one.
+    type_target: Option<Target>,
+    /// The source node of the `use` directive leading to the type target
+    /// being non-none
+    type_id: NodeId,
+}
+
+impl ImportResolution {
+    fn new(id: NodeId, is_public: bool) -> ImportResolution {
+        ImportResolution {
+            type_id: id,
+            value_id: id,
+            outstanding_references: 0,
+            value_target: None,
+            type_target: None,
+            is_public: is_public,
+        }
+    }
+
+    fn target_for_namespace(&self, namespace: Namespace)
+                                -> Option<Target> {
+        match namespace {
+            TypeNS  => self.type_target.clone(),
+            ValueNS => self.value_target.clone(),
+        }
+    }
+
+    fn id(&self, namespace: Namespace) -> NodeId {
+        match namespace {
+            TypeNS  => self.type_id,
+            ValueNS => self.value_id,
+        }
+    }
+}
+
+/// The link from a module up to its nearest parent node.
+#[deriving(Clone)]
+enum ParentLink {
+    NoParentLink,
+    ModuleParentLink(Weak<Module>, Name),
+    BlockParentLink(Weak<Module>, NodeId)
+}
+
+/// The type of module this is.
+#[deriving(Copy, PartialEq)]
+enum ModuleKind {
+    NormalModuleKind,
+    TraitModuleKind,
+    ImplModuleKind,
+    EnumModuleKind,
+    AnonymousModuleKind,
+}
+
+/// One node in the tree of modules.
+struct Module {
+    parent_link: ParentLink,
+    def_id: Cell<Option<DefId>>,
+    kind: Cell<ModuleKind>,
+    is_public: bool,
+
+    children: RefCell<HashMap<Name, Rc<NameBindings>>>,
+    imports: RefCell<Vec<ImportDirective>>,
+
+    // The external module children of this node that were declared with
+    // `extern crate`.
+    external_module_children: RefCell<HashMap<Name, Rc<Module>>>,
+
+    // The anonymous children of this node. Anonymous children are pseudo-
+    // modules that are implicitly created around items contained within
+    // blocks.
+    //
+    // For example, if we have this:
+    //
+    //  fn f() {
+    //      fn g() {
+    //          ...
+    //      }
+    //  }
+    //
+    // There will be an anonymous module created around `g` with the ID of the
+    // entry block for `f`.
+    anonymous_children: RefCell<NodeMap<Rc<Module>>>,
+
+    // The status of resolving each import in this module.
+    import_resolutions: RefCell<HashMap<Name, ImportResolution>>,
+
+    // The number of unresolved globs that this module exports.
+    glob_count: Cell<uint>,
+
+    // The index of the import we're resolving.
+    resolved_import_count: Cell<uint>,
+
+    // Whether this module is populated. If not populated, any attempt to
+    // access the children must be preceded with a
+    // `populate_module_if_necessary` call.
+    populated: Cell<bool>,
+}
+
+impl Module {
+    fn new(parent_link: ParentLink,
+           def_id: Option<DefId>,
+           kind: ModuleKind,
+           external: bool,
+           is_public: bool)
+           -> Module {
+        Module {
+            parent_link: parent_link,
+            def_id: Cell::new(def_id),
+            kind: Cell::new(kind),
+            is_public: is_public,
+            children: RefCell::new(HashMap::new()),
+            imports: RefCell::new(Vec::new()),
+            external_module_children: RefCell::new(HashMap::new()),
+            anonymous_children: RefCell::new(NodeMap::new()),
+            import_resolutions: RefCell::new(HashMap::new()),
+            glob_count: Cell::new(0),
+            resolved_import_count: Cell::new(0),
+            populated: Cell::new(!external),
+        }
+    }
+
+    fn all_imports_resolved(&self) -> bool {
+        self.imports.borrow().len() == self.resolved_import_count.get()
+    }
+}
+
+bitflags! {
+    #[deriving(Show)]
+    flags DefModifiers: u8 {
+        const PUBLIC            = 0b0000_0001,
+        const IMPORTABLE        = 0b0000_0010,
+    }
+}
+
+// Records a possibly-private type definition.
+#[deriving(Clone)]
+struct TypeNsDef {
+    modifiers: DefModifiers, // see note in ImportResolution about how to use this
+    module_def: Option<Rc<Module>>,
+    type_def: Option<Def>,
+    type_span: Option<Span>
+}
+
+// Records a possibly-private value definition.
+#[deriving(Clone, Copy, Show)]
+struct ValueNsDef {
+    modifiers: DefModifiers, // see note in ImportResolution about how to use this
+    def: Def,
+    value_span: Option<Span>,
+}
+
+// Records the definitions (at most one for each namespace) that a name is
+// bound to.
+struct NameBindings {
+    type_def: RefCell<Option<TypeNsDef>>,   //< Meaning in type namespace.
+    value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
+}
+
+/// Ways in which a trait can be referenced
+#[deriving(Copy)]
+enum TraitReferenceType {
+    TraitImplementation,             // impl SomeTrait for T { ... }
+    TraitDerivation,                 // trait T : SomeTrait { ... }
+    TraitBoundingTypeParameter,      // fn f<T:SomeTrait>() { ... }
+    TraitObject,                     // Box<for<'a> SomeTrait>
+    TraitQPath,                      // <T as SomeTrait>::
+}
+
+impl NameBindings {
+    fn new() -> NameBindings {
+        NameBindings {
+            type_def: RefCell::new(None),
+            value_def: RefCell::new(None),
+        }
+    }
+
+    /// Creates a new module in this set of name bindings.
+    fn define_module(&self,
+                     parent_link: ParentLink,
+                     def_id: Option<DefId>,
+                     kind: ModuleKind,
+                     external: bool,
+                     is_public: bool,
+                     sp: Span) {
+        // Merges the module with the existing type def or creates a new one.
+        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
+        let module_ = Rc::new(Module::new(parent_link,
+                                          def_id,
+                                          kind,
+                                          external,
+                                          is_public));
+        let type_def = self.type_def.borrow().clone();
+        match type_def {
+            None => {
+                *self.type_def.borrow_mut() = Some(TypeNsDef {
+                    modifiers: modifiers,
+                    module_def: Some(module_),
+                    type_def: None,
+                    type_span: Some(sp)
+                });
+            }
+            Some(type_def) => {
+                *self.type_def.borrow_mut() = Some(TypeNsDef {
+                    modifiers: modifiers,
+                    module_def: Some(module_),
+                    type_span: Some(sp),
+                    type_def: type_def.type_def
+                });
+            }
+        }
+    }
+
+    /// Sets the kind of the module, creating a new one if necessary.
+    fn set_module_kind(&self,
+                       parent_link: ParentLink,
+                       def_id: Option<DefId>,
+                       kind: ModuleKind,
+                       external: bool,
+                       is_public: bool,
+                       _sp: Span) {
+        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
+        let type_def = self.type_def.borrow().clone();
+        match type_def {
+            None => {
+                let module = Module::new(parent_link,
+                                         def_id,
+                                         kind,
+                                         external,
+                                         is_public);
+                *self.type_def.borrow_mut() = Some(TypeNsDef {
+                    modifiers: modifiers,
+                    module_def: Some(Rc::new(module)),
+                    type_def: None,
+                    type_span: None,
+                });
+            }
+            Some(type_def) => {
+                match type_def.module_def {
+                    None => {
+                        let module = Module::new(parent_link,
+                                                 def_id,
+                                                 kind,
+                                                 external,
+                                                 is_public);
+                        *self.type_def.borrow_mut() = Some(TypeNsDef {
+                            modifiers: modifiers,
+                            module_def: Some(Rc::new(module)),
+                            type_def: type_def.type_def,
+                            type_span: None,
+                        });
+                    }
+                    Some(module_def) => module_def.kind.set(kind),
+                }
+            }
+        }
+    }
+
+    /// Records a type definition.
+    fn define_type(&self, def: Def, sp: Span, modifiers: DefModifiers) {
+        debug!("defining type for def {} with modifiers {}", def, modifiers);
+        // Merges the type with the existing type def or creates a new one.
+        let type_def = self.type_def.borrow().clone();
+        match type_def {
+            None => {
+                *self.type_def.borrow_mut() = Some(TypeNsDef {
+                    module_def: None,
+                    type_def: Some(def),
+                    type_span: Some(sp),
+                    modifiers: modifiers,
+                });
+            }
+            Some(type_def) => {
+                *self.type_def.borrow_mut() = Some(TypeNsDef {
+                    module_def: type_def.module_def,
+                    type_def: Some(def),
+                    type_span: Some(sp),
+                    modifiers: modifiers,
+                });
+            }
+        }
+    }
+
+    /// Records a value definition.
+    fn define_value(&self, def: Def, sp: Span, modifiers: DefModifiers) {
+        debug!("defining value for def {} with modifiers {}", def, modifiers);
+        *self.value_def.borrow_mut() = Some(ValueNsDef {
+            def: def,
+            value_span: Some(sp),
+            modifiers: modifiers,
+        });
+    }
+
+    /// Returns the module node if applicable.
+    fn get_module_if_available(&self) -> Option<Rc<Module>> {
+        match *self.type_def.borrow() {
+            Some(ref type_def) => type_def.module_def.clone(),
+            None => None
+        }
+    }
+
+    /// Returns the module node. Panics if this node does not have a module
+    /// definition.
+    fn get_module(&self) -> Rc<Module> {
+        match self.get_module_if_available() {
+            None => {
+                panic!("get_module called on a node with no module \
+                       definition!")
+            }
+            Some(module_def) => module_def
+        }
+    }
+
+    fn defined_in_namespace(&self, namespace: Namespace) -> bool {
+        match namespace {
+            TypeNS   => return self.type_def.borrow().is_some(),
+            ValueNS  => return self.value_def.borrow().is_some()
+        }
+    }
+
+    fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
+        self.defined_in_namespace_with(namespace, PUBLIC)
+    }
+
+    fn defined_in_namespace_with(&self, namespace: Namespace, modifiers: DefModifiers) -> bool {
+        match namespace {
+            TypeNS => match *self.type_def.borrow() {
+                Some(ref def) => def.modifiers.contains(modifiers), None => false
+            },
+            ValueNS => match *self.value_def.borrow() {
+                Some(ref def) => def.modifiers.contains(modifiers), None => false
+            }
+        }
+    }
+
+    fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
+        match namespace {
+            TypeNS => {
+                match *self.type_def.borrow() {
+                    None => None,
+                    Some(ref type_def) => {
+                        match type_def.type_def {
+                            Some(type_def) => Some(type_def),
+                            None => {
+                                match type_def.module_def {
+                                    Some(ref module) => {
+                                        match module.def_id.get() {
+                                            Some(did) => Some(DefMod(did)),
+                                            None => None,
+                                        }
+                                    }
+                                    None => None,
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            ValueNS => {
+                match *self.value_def.borrow() {
+                    None => None,
+                    Some(value_def) => Some(value_def.def)
+                }
+            }
+        }
+    }
+
+    fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
+        if self.defined_in_namespace(namespace) {
+            match namespace {
+                TypeNS  => {
+                    match *self.type_def.borrow() {
+                        None => None,
+                        Some(ref type_def) => type_def.type_span
+                    }
+                }
+                ValueNS => {
+                    match *self.value_def.borrow() {
+                        None => None,
+                        Some(ref value_def) => value_def.value_span
+                    }
+                }
+            }
+        } else {
+            None
+        }
+    }
+}
+
+/// Interns the names of the primitive types.
+struct PrimitiveTypeTable {
+    primitive_types: HashMap<Name, PrimTy>,
+}
+
+impl PrimitiveTypeTable {
+    fn new() -> PrimitiveTypeTable {
+        let mut table = PrimitiveTypeTable {
+            primitive_types: HashMap::new()
+        };
+
+        table.intern("bool",    TyBool);
+        table.intern("char",    TyChar);
+        table.intern("f32",     TyFloat(TyF32));
+        table.intern("f64",     TyFloat(TyF64));
+        table.intern("int",     TyInt(TyI));
+        table.intern("i8",      TyInt(TyI8));
+        table.intern("i16",     TyInt(TyI16));
+        table.intern("i32",     TyInt(TyI32));
+        table.intern("i64",     TyInt(TyI64));
+        table.intern("str",     TyStr);
+        table.intern("uint",    TyUint(TyU));
+        table.intern("u8",      TyUint(TyU8));
+        table.intern("u16",     TyUint(TyU16));
+        table.intern("u32",     TyUint(TyU32));
+        table.intern("u64",     TyUint(TyU64));
+
+        table
+    }
+
+    fn intern(&mut self, string: &str, primitive_type: PrimTy) {
+        self.primitive_types.insert(token::intern(string), primitive_type);
+    }
+}
+
+
+fn namespace_error_to_string(ns: NamespaceError) -> &'static str {
+    match ns {
+        NoError                 => "",
+        ModuleError | TypeError => "type or module",
+        ValueError              => "value",
+    }
+}
+
+/// The main resolver class.
+struct Resolver<'a> {
+    session: &'a Session,
+
+    graph_root: NameBindings,
+
+    trait_item_map: FnvHashMap<(Name, DefId), TraitItemKind>,
+
+    structs: FnvHashMap<DefId, Vec<Name>>,
+
+    // The number of imports that are currently unresolved.
+    unresolved_imports: uint,
+
+    // The module that represents the current item scope.
+    current_module: Rc<Module>,
+
+    // The current set of local scopes, for values.
+    // FIXME #4948: Reuse ribs to avoid allocation.
+    value_ribs: Vec<Rib>,
+
+    // The current set of local scopes, for types.
+    type_ribs: Vec<Rib>,
+
+    // The current set of local scopes, for labels.
+    label_ribs: Vec<Rib>,
+
+    // The trait that the current context can refer to.
+    current_trait_ref: Option<(DefId, TraitRef)>,
+
+    // The current self type if inside an impl (used for better errors).
+    current_self_type: Option<Ty>,
+
+    // The ident for the keyword "self".
+    self_name: Name,
+    // The ident for the non-keyword "Self".
+    type_self_name: Name,
+
+    // The idents for the primitive types.
+    primitive_type_table: PrimitiveTypeTable,
+
+    def_map: DefMap,
+    freevars: RefCell<FreevarMap>,
+    freevars_seen: RefCell<NodeMap<NodeSet>>,
+    capture_mode_map: CaptureModeMap,
+    export_map: ExportMap,
+    trait_map: TraitMap,
+    external_exports: ExternalExports,
+    last_private: LastPrivateMap,
+
+    // Whether or not to print error messages. Can be set to true
+    // when getting additional info for error message suggestions,
+    // so as to avoid printing duplicate errors
+    emit_errors: bool,
+
+    used_imports: HashSet<(NodeId, Namespace)>,
+    used_crates: HashSet<CrateNum>,
+}
+
+struct BuildReducedGraphVisitor<'a, 'b:'a> {
+    resolver: &'a mut Resolver<'b>,
+    parent: ReducedGraphParent
+}
+
+impl<'a, 'b, 'v> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b> {
+
+    fn visit_item(&mut self, item: &Item) {
+        let p = self.resolver.build_reduced_graph_for_item(item, self.parent.clone());
+        let old_parent = replace(&mut self.parent, p);
+        visit::walk_item(self, item);
+        self.parent = old_parent;
+    }
+
+    fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
+        let parent = self.parent.clone();
+        self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
+                                                           parent.clone(),
+                                                           |r| {
+            let mut v = BuildReducedGraphVisitor {
+                resolver: r,
+                parent: parent.clone()
+            };
+            visit::walk_foreign_item(&mut v, foreign_item);
+        })
+    }
+
+    fn visit_view_item(&mut self, view_item: &ViewItem) {
+        self.resolver.build_reduced_graph_for_view_item(view_item, self.parent.clone());
+    }
+
+    fn visit_block(&mut self, block: &Block) {
+        let np = self.resolver.build_reduced_graph_for_block(block, self.parent.clone());
+        let old_parent = replace(&mut self.parent, np);
+        visit::walk_block(self, block);
+        self.parent = old_parent;
+    }
+
+}
+
+#[deriving(PartialEq)]
+enum FallbackChecks {
+    Everything,
+    OnlyTraitAndStatics
+}
+
+
+impl<'a> Resolver<'a> {
+    fn new(session: &'a Session, crate_span: Span) -> Resolver<'a> {
+        let graph_root = NameBindings::new();
+
+        graph_root.define_module(NoParentLink,
+                                 Some(DefId { krate: 0, node: 0 }),
+                                 NormalModuleKind,
+                                 false,
+                                 true,
+                                 crate_span);
+
+        let current_module = graph_root.get_module();
+
+        Resolver {
+            session: session,
+
+            // The outermost module has def ID 0; this is not reflected in the
+            // AST.
+
+            graph_root: graph_root,
+
+            trait_item_map: FnvHashMap::new(),
+            structs: FnvHashMap::new(),
+
+            unresolved_imports: 0,
+
+            current_module: current_module,
+            value_ribs: Vec::new(),
+            type_ribs: Vec::new(),
+            label_ribs: Vec::new(),
+
+            current_trait_ref: None,
+            current_self_type: None,
+
+            self_name: special_names::self_,
+            type_self_name: special_names::type_self,
+
+            primitive_type_table: PrimitiveTypeTable::new(),
+
+            def_map: RefCell::new(NodeMap::new()),
+            freevars: RefCell::new(NodeMap::new()),
+            freevars_seen: RefCell::new(NodeMap::new()),
+            capture_mode_map: NodeMap::new(),
+            export_map: NodeMap::new(),
+            trait_map: NodeMap::new(),
+            used_imports: HashSet::new(),
+            used_crates: HashSet::new(),
+            external_exports: DefIdSet::new(),
+            last_private: NodeMap::new(),
+
+            emit_errors: true,
+        }
+    }
+
+    //
+    // Reduced graph building
+    //
+    // Here we build the "reduced graph": the graph of the module tree without
+    // any imports resolved.
+    //
+
+    /// Constructs the reduced graph for the entire crate.
+    fn build_reduced_graph(&mut self, krate: &ast::Crate) {
+        let parent = ModuleReducedGraphParent(self.graph_root.get_module());
+        let mut visitor = BuildReducedGraphVisitor {
+            resolver: self,
+            parent: parent
+        };
+        visit::walk_crate(&mut visitor, krate);
+    }
+
+    /// Adds a new child item to the module definition of the parent node and
+    /// returns its corresponding name bindings as well as the current parent.
+    /// Or, if we're inside a block, creates (or reuses) an anonymous module
+    /// corresponding to the innermost block ID and returns the name bindings
+    /// as well as the newly-created parent.
+    ///
+    /// # Panics
+    ///
+    /// Panics if this node does not have a module definition and we are not inside
+    /// a block.
+    fn add_child(&self,
+                 name: Name,
+                 reduced_graph_parent: ReducedGraphParent,
+                 duplicate_checking_mode: DuplicateCheckingMode,
+                 // For printing errors
+                 sp: Span)
+                 -> Rc<NameBindings> {
+        // If this is the immediate descendant of a module, then we add the
+        // child name directly. Otherwise, we create or reuse an anonymous
+        // module and add the child to that.
+
+        let module_ = reduced_graph_parent.module();
+
+        self.check_for_conflicts_between_external_crates_and_items(&*module_,
+                                                                   name,
+                                                                   sp);
+
+        // Add or reuse the child.
+        let child = module_.children.borrow().get(&name).cloned();
+        match child {
+            None => {
+                let child = Rc::new(NameBindings::new());
+                module_.children.borrow_mut().insert(name, child.clone());
+                child
+            }
+            Some(child) => {
+                // Enforce the duplicate checking mode:
+                //
+                // * If we're requesting duplicate module checking, check that
+                //   there isn't a module in the module with the same name.
+                //
+                // * If we're requesting duplicate type checking, check that
+                //   there isn't a type in the module with the same name.
+                //
+                // * If we're requesting duplicate value checking, check that
+                //   there isn't a value in the module with the same name.
+                //
+                // * If we're requesting duplicate type checking and duplicate
+                //   value checking, check that there isn't a duplicate type
+                //   and a duplicate value with the same name.
+                //
+                // * If no duplicate checking was requested at all, do
+                //   nothing.
+
+                let mut duplicate_type = NoError;
+                let ns = match duplicate_checking_mode {
+                    ForbidDuplicateModules => {
+                        if child.get_module_if_available().is_some() {
+                            duplicate_type = ModuleError;
+                        }
+                        Some(TypeNS)
+                    }
+                    ForbidDuplicateTypesAndModules => {
+                        match child.def_for_namespace(TypeNS) {
+                            None => {}
+                            Some(_) if child.get_module_if_available()
+                                            .map(|m| m.kind.get()) ==
+                                       Some(ImplModuleKind) => {}
+                            Some(_) => duplicate_type = TypeError
+                        }
+                        Some(TypeNS)
+                    }
+                    ForbidDuplicateValues => {
+                        if child.defined_in_namespace(ValueNS) {
+                            duplicate_type = ValueError;
+                        }
+                        Some(ValueNS)
+                    }
+                    ForbidDuplicateTypesAndValues => {
+                        let mut n = None;
+                        match child.def_for_namespace(TypeNS) {
+                            Some(DefMod(_)) | None => {}
+                            Some(_) => {
+                                n = Some(TypeNS);
+                                duplicate_type = TypeError;
+                            }
+                        };
+                        if child.defined_in_namespace(ValueNS) {
+                            duplicate_type = ValueError;
+                            n = Some(ValueNS);
+                        }
+                        n
+                    }
+                    OverwriteDuplicates => None
+                };
+                if duplicate_type != NoError {
+                    // Return an error here by looking up the namespace that
+                    // had the duplicate.
+                    let ns = ns.unwrap();
+                    self.resolve_error(sp,
+                        format!("duplicate definition of {} `{}`",
+                             namespace_error_to_string(duplicate_type),
+                             token::get_name(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_string(duplicate_type),
+                                      token::get_name(name)).as_slice());
+                        }
+                    }
+                }
+                child
+            }
+        }
+    }
+
+    fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
+        // If the block has view items, we need an anonymous module.
+        if block.view_items.len() > 0 {
+            return true;
+        }
+
+        // Check each statement.
+        for statement in block.stmts.iter() {
+            match statement.node {
+                StmtDecl(ref declaration, _) => {
+                    match declaration.node {
+                        DeclItem(_) => {
+                            return true;
+                        }
+                        _ => {
+                            // Keep searching.
+                        }
+                    }
+                }
+                _ => {
+                    // Keep searching.
+                }
+            }
+        }
+
+        // If we found neither view items nor items, we don't need to create
+        // an anonymous module.
+
+        return false;
+    }
+
+    fn get_parent_link(&mut self, parent: ReducedGraphParent, name: Name)
+                       -> ParentLink {
+        match parent {
+            ModuleReducedGraphParent(module_) => {
+                return ModuleParentLink(module_.downgrade(), name);
+            }
+        }
+    }
+
+    /// Constructs the reduced graph for one item.
+    fn build_reduced_graph_for_item(&mut self,
+                                    item: &Item,
+                                    parent: ReducedGraphParent)
+                                    -> ReducedGraphParent
+    {
+        let name = item.ident.name;
+        let sp = item.span;
+        let is_public = item.vis == ast::Public;
+        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
+
+        match item.node {
+            ItemMod(..) => {
+                let name_bindings =
+                    self.add_child(name, parent.clone(), ForbidDuplicateModules, sp);
+
+                let parent_link = self.get_parent_link(parent, name);
+                let def_id = DefId { krate: 0, node: item.id };
+                name_bindings.define_module(parent_link,
+                                            Some(def_id),
+                                            NormalModuleKind,
+                                            false,
+                                            item.vis == ast::Public,
+                                            sp);
+
+                ModuleReducedGraphParent(name_bindings.get_module())
+            }
+
+            ItemForeignMod(..) => parent,
+
+            // These items live in the value namespace.
+            ItemStatic(_, m, _) => {
+                let name_bindings =
+                    self.add_child(name, parent.clone(), ForbidDuplicateValues, sp);
+                let mutbl = m == ast::MutMutable;
+
+                name_bindings.define_value
+                    (DefStatic(local_def(item.id), mutbl), sp, modifiers);
+                parent
+            }
+            ItemConst(_, _) => {
+                self.add_child(name, parent.clone(), ForbidDuplicateValues, sp)
+                    .define_value(DefConst(local_def(item.id)),
+                                  sp, modifiers);
+                parent
+            }
+            ItemFn(_, _, _, _, _) => {
+                let name_bindings =
+                    self.add_child(name, parent.clone(), ForbidDuplicateValues, sp);
+
+                let def = DefFn(local_def(item.id), false);
+                name_bindings.define_value(def, sp, modifiers);
+                parent
+            }
+
+            // These items live in the type namespace.
+            ItemTy(..) => {
+                let name_bindings =
+                    self.add_child(name,
+                                   parent.clone(),
+                                   ForbidDuplicateTypesAndModules,
+                                   sp);
+
+                name_bindings.define_type
+                    (DefTy(local_def(item.id), false), sp, modifiers);
+                parent
+            }
+
+            ItemEnum(ref enum_definition, _) => {
+                let name_bindings =
+                    self.add_child(name,
+                                   parent.clone(),
+                                   ForbidDuplicateTypesAndModules,
+                                   sp);
+
+                name_bindings.define_type
+                    (DefTy(local_def(item.id), true), sp, modifiers);
+
+                let parent_link = self.get_parent_link(parent.clone(), name);
+                // We want to make sure the module type is EnumModuleKind
+                // even if there's already an ImplModuleKind module defined,
+                // since that's how we prevent duplicate enum definitions
+                name_bindings.set_module_kind(parent_link,
+                                              Some(local_def(item.id)),
+                                              EnumModuleKind,
+                                              false,
+                                              is_public,
+                                              sp);
+
+                for variant in (*enum_definition).variants.iter() {
+                    self.build_reduced_graph_for_variant(
+                        &**variant,
+                        local_def(item.id),
+                        ModuleReducedGraphParent(name_bindings.get_module()));
+                }
+                parent
+            }
+
+            // These items live in both the type and value namespaces.
+            ItemStruct(ref struct_def, _) => {
+                // 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            => (ForbidDuplicateTypesAndModules, None)
+                };
+
+                let name_bindings = self.add_child(name, parent.clone(), forbid, sp);
+
+                // Define a name in the type namespace.
+                name_bindings.define_type(DefTy(local_def(item.id), false), sp, modifiers);
+
+                // If this is a newtype or unit-like struct, define a name
+                // in the value namespace as well
+                match ctor_id {
+                    Some(cid) => {
+                        name_bindings.define_value(DefStruct(local_def(cid)),
+                                                   sp, modifiers);
+                    }
+                    None => {}
+                }
+
+                // Record the def ID and fields of this struct.
+                let named_fields = struct_def.fields.iter().filter_map(|f| {
+                    match f.node.kind {
+                        NamedField(ident, _) => Some(ident.name),
+                        UnnamedField(_) => None
+                    }
+                }).collect();
+                self.structs.insert(local_def(item.id), named_fields);
+
+                parent
+            }
+
+            ItemImpl(_, _, None, ref ty, ref impl_items) => {
+                // If this implements an anonymous trait, then add all the
+                // methods within to a new module, if the type was defined
+                // within this module.
+
+                let mod_name = match ty.node {
+                    TyPath(ref path, _) if path.segments.len() == 1 => {
+                        // FIXME(18446) we should distinguish between the name of
+                        // a trait and the name of an impl of that trait.
+                        Some(path.segments.last().unwrap().identifier.name)
+                    }
+                    TyObjectSum(ref lhs_ty, _) => {
+                        match lhs_ty.node {
+                            TyPath(ref path, _) if path.segments.len() == 1 => {
+                                Some(path.segments.last().unwrap().identifier.name)
+                            }
+                            _ => {
+                                None
+                            }
+                        }
+                    }
+                    _ => {
+                        None
+                    }
+                };
+
+                match mod_name {
+                    None => {
+                        self.resolve_error(ty.span,
+                                           "inherent implementations may \
+                                            only be implemented in the same \
+                                            module as the type they are \
+                                            implemented for")
+                    }
+                    Some(mod_name) => {
+                        // Create the module and add all methods.
+                        let parent_opt = parent.module().children.borrow()
+                            .get(&mod_name).cloned();
+                        let new_parent = match parent_opt {
+                            // It already exists
+                            Some(ref child) if child.get_module_if_available()
+                                .is_some() &&
+                                (child.get_module().kind.get() == ImplModuleKind ||
+                                 child.get_module().kind.get() == TraitModuleKind) => {
+                                    ModuleReducedGraphParent(child.get_module())
+                                }
+                            Some(ref child) if child.get_module_if_available()
+                                .is_some() &&
+                                child.get_module().kind.get() ==
+                                EnumModuleKind => {
+                                    ModuleReducedGraphParent(child.get_module())
+                                }
+                            // Create the module
+                            _ => {
+                                let name_bindings =
+                                    self.add_child(mod_name,
+                                                   parent.clone(),
+                                                   ForbidDuplicateModules,
+                                                   sp);
+
+                                let parent_link =
+                                    self.get_parent_link(parent.clone(), name);
+                                let def_id = local_def(item.id);
+                                let ns = TypeNS;
+                                let is_public =
+                                    !name_bindings.defined_in_namespace(ns) ||
+                                    name_bindings.defined_in_public_namespace(ns);
+
+                                name_bindings.define_module(parent_link,
+                                                            Some(def_id),
+                                                            ImplModuleKind,
+                                                            false,
+                                                            is_public,
+                                                            sp);
+
+                                ModuleReducedGraphParent(
+                                    name_bindings.get_module())
+                            }
+                        };
+
+                        // For each implementation item...
+                        for impl_item in impl_items.iter() {
+                            match *impl_item {
+                                MethodImplItem(ref method) => {
+                                    // Add the method to the module.
+                                    let name = method.pe_ident().name;
+                                    let method_name_bindings =
+                                        self.add_child(name,
+                                                       new_parent.clone(),
+                                                       ForbidDuplicateValues,
+                                                       method.span);
+                                    let def = match method.pe_explicit_self()
+                                        .node {
+                                            SelfStatic => {
+                                                // Static methods become
+                                                // `DefStaticMethod`s.
+                                                DefStaticMethod(local_def(method.id),
+                                                                FromImpl(local_def(item.id)))
+                                            }
+                                            _ => {
+                                                // Non-static methods become
+                                                // `DefMethod`s.
+                                                DefMethod(local_def(method.id),
+                                                          None,
+                                                          FromImpl(local_def(item.id)))
+                                            }
+                                        };
+
+                                    // NB: not IMPORTABLE
+                                    let modifiers = if method.pe_vis() == ast::Public {
+                                        PUBLIC
+                                    } else {
+                                        DefModifiers::empty()
+                                    };
+                                    method_name_bindings.define_value(
+                                        def,
+                                        method.span,
+                                        modifiers);
+                                }
+                                TypeImplItem(ref typedef) => {
+                                    // Add the typedef to the module.
+                                    let name = typedef.ident.name;
+                                    let typedef_name_bindings =
+                                        self.add_child(
+                                            name,
+                                            new_parent.clone(),
+                                            ForbidDuplicateTypesAndModules,
+                                            typedef.span);
+                                    let def = DefAssociatedTy(local_def(
+                                        typedef.id));
+                                    // NB: not IMPORTABLE
+                                    let modifiers = if typedef.vis == ast::Public {
+                                        PUBLIC
+                                    } else {
+                                        DefModifiers::empty()
+                                    };
+                                    typedef_name_bindings.define_type(
+                                        def,
+                                        typedef.span,
+                                        modifiers);
+                                }
+                            }
+                        }
+                    }
+                }
+
+                parent
+            }
+
+            ItemImpl(_, _, Some(_), _, _) => parent,
+
+            ItemTrait(_, _, _, _, ref items) => {
+                let name_bindings =
+                    self.add_child(name,
+                                   parent.clone(),
+                                   ForbidDuplicateTypesAndModules,
+                                   sp);
+
+                // Add all the items within to a new module.
+                let parent_link = self.get_parent_link(parent.clone(), name);
+                name_bindings.define_module(parent_link,
+                                            Some(local_def(item.id)),
+                                            TraitModuleKind,
+                                            false,
+                                            item.vis == ast::Public,
+                                            sp);
+                let module_parent = ModuleReducedGraphParent(name_bindings.
+                                                             get_module());
+
+                let def_id = local_def(item.id);
+
+                // Add the names of all the items to the trait info.
+                for trait_item in items.iter() {
+                    let (name, kind) = match *trait_item {
+                        ast::RequiredMethod(_) |
+                        ast::ProvidedMethod(_) => {
+                            let ty_m = ast_util::trait_item_to_ty_method(trait_item);
+
+                            let name = ty_m.ident.name;
+
+                            // Add it as a name in the trait module.
+                            let (def, static_flag) = match ty_m.explicit_self
+                                                               .node {
+                                SelfStatic => {
+                                    // Static methods become `DefStaticMethod`s.
+                                    (DefStaticMethod(
+                                            local_def(ty_m.id),
+                                            FromTrait(local_def(item.id))),
+                                     StaticMethodTraitItemKind)
+                                }
+                                _ => {
+                                    // Non-static methods become `DefMethod`s.
+                                    (DefMethod(local_def(ty_m.id),
+                                               Some(local_def(item.id)),
+                                               FromTrait(local_def(item.id))),
+                                     NonstaticMethodTraitItemKind)
+                                }
+                            };
+
+                            let method_name_bindings =
+                                self.add_child(name,
+                                               module_parent.clone(),
+                                               ForbidDuplicateTypesAndValues,
+                                               ty_m.span);
+                            // NB: not IMPORTABLE
+                            method_name_bindings.define_value(def,
+                                                              ty_m.span,
+                                                              PUBLIC);
+
+                            (name, static_flag)
+                        }
+                        ast::TypeTraitItem(ref associated_type) => {
+                            let def = DefAssociatedTy(local_def(
+                                    associated_type.ty_param.id));
+
+                            let name_bindings =
+                                self.add_child(associated_type.ty_param.ident.name,
+                                               module_parent.clone(),
+                                               ForbidDuplicateTypesAndValues,
+                                               associated_type.ty_param.span);
+                            // NB: not IMPORTABLE
+                            name_bindings.define_type(def,
+                                                      associated_type.ty_param.span,
+                                                      PUBLIC);
+
+                            (associated_type.ty_param.ident.name, TypeTraitItemKind)
+                        }
+                    };
+
+                    self.trait_item_map.insert((name, def_id), kind);
+                }
+
+                name_bindings.define_type(DefTrait(def_id), sp, modifiers);
+                parent
+            }
+            ItemMac(..) => parent
+        }
+    }
+
+    // Constructs the reduced graph for one variant. Variants exist in the
+    // type and value namespaces.
+    fn build_reduced_graph_for_variant(&mut self,
+                                       variant: &Variant,
+                                       item_id: DefId,
+                                       parent: ReducedGraphParent) {
+        let name = variant.node.name.name;
+        let is_exported = match variant.node.kind {
+            TupleVariantKind(_) => false,
+            StructVariantKind(_) => {
+                // Not adding fields for variants as they are not accessed with a self receiver
+                self.structs.insert(local_def(variant.node.id), Vec::new());
+                true
+            }
+        };
+
+        let child = self.add_child(name, parent,
+                                   ForbidDuplicateTypesAndValues,
+                                   variant.span);
+        // variants are always treated as importable to allow them to be glob
+        // used
+        child.define_value(DefVariant(item_id,
+                                      local_def(variant.node.id), is_exported),
+                           variant.span, PUBLIC | IMPORTABLE);
+        child.define_type(DefVariant(item_id,
+                                     local_def(variant.node.id), is_exported),
+                          variant.span, PUBLIC | IMPORTABLE);
+    }
+
+    /// Constructs the reduced graph for one 'view item'. View items consist
+    /// of imports and use directives.
+    fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
+                                         parent: ReducedGraphParent) {
+        match view_item.node {
+            ViewItemUse(ref view_path) => {
+                // Extract and intern the module part of the path. For
+                // globs and lists, the path is found directly in the AST;
+                // for simple paths we have to munge the path a little.
+                let module_path = match view_path.node {
+                    ViewPathSimple(_, ref full_path, _) => {
+                        full_path.segments
+                            .init()
+                            .iter().map(|ident| ident.identifier.name)
+                            .collect()
+                    }
+
+                    ViewPathGlob(ref module_ident_path, _) |
+                    ViewPathList(ref module_ident_path, _, _) => {
+                        module_ident_path.segments
+                            .iter().map(|ident| ident.identifier.name).collect()
+                    }
+                };
+
+                // Build up the import directives.
+                let module_ = parent.module();
+                let is_public = view_item.vis == ast::Public;
+                let shadowable =
+                    view_item.attrs
+                             .iter()
+                             .any(|attr| {
+                                 attr.name() == token::get_name(
+                                    special_idents::prelude_import.name)
+                             });
+
+                match view_path.node {
+                    ViewPathSimple(binding, ref full_path, id) => {
+                        let source_name =
+                            full_path.segments.last().unwrap().identifier.name;
+                        if token::get_name(source_name).get() == "mod" {
+                            self.resolve_error(view_path.span,
+                                "`mod` imports are only allowed within a { } list");
+                        }
+
+                        let subclass = SingleImport(binding.name,
+                                                    source_name);
+                        self.build_import_directive(&*module_,
+                                                    module_path,
+                                                    subclass,
+                                                    view_path.span,
+                                                    id,
+                                                    is_public,
+                                                    shadowable);
+                    }
+                    ViewPathList(_, ref source_items, _) => {
+                        // Make sure there's at most one `mod` import in the list.
+                        let mod_spans = source_items.iter().filter_map(|item| match item.node {
+                            PathListMod { .. } => Some(item.span),
+                            _ => None
+                        }).collect::<Vec<Span>>();
+                        if mod_spans.len() > 1 {
+                            self.resolve_error(mod_spans[0],
+                                "`mod` import can only appear once in the list");
+                            for other_span in mod_spans.iter().skip(1) {
+                                self.session.span_note(*other_span,
+                                    "another `mod` import appears here");
+                            }
+                        }
+
+                        for source_item in source_items.iter() {
+                            let (module_path, name) = match source_item.node {
+                                PathListIdent { name, .. } =>
+                                    (module_path.clone(), name.name),
+                                PathListMod { .. } => {
+                                    let name = match module_path.last() {
+                                        Some(name) => *name,
+                                        None => {
+                                            self.resolve_error(source_item.span,
+                                                "`mod` import can only appear in an import list \
+                                                 with a non-empty prefix");
+                                            continue;
+                                        }
+                                    };
+                                    let module_path = module_path.init();
+                                    (module_path.to_vec(), name)
+                                }
+                            };
+                            self.build_import_directive(
+                                &*module_,
+                                module_path,
+                                SingleImport(name, name),
+                                source_item.span,
+                                source_item.node.id(),
+                                is_public,
+                                shadowable);
+                        }
+                    }
+                    ViewPathGlob(_, id) => {
+                        self.build_import_directive(&*module_,
+                                                    module_path,
+                                                    GlobImport,
+                                                    view_path.span,
+                                                    id,
+                                                    is_public,
+                                                    shadowable);
+                    }
+                }
+            }
+
+            ViewItemExternCrate(name, _, node_id) => {
+                // n.b. we don't need to look at the path option here, because cstore already did
+                for &crate_id in self.session.cstore
+                                     .find_extern_mod_stmt_cnum(node_id).iter() {
+                    let def_id = DefId { krate: crate_id, node: 0 };
+                    self.external_exports.insert(def_id);
+                    let parent_link =
+                        ModuleParentLink(parent.module().downgrade(), name.name);
+                    let external_module = Rc::new(Module::new(parent_link,
+                                                              Some(def_id),
+                                                              NormalModuleKind,
+                                                              false,
+                                                              true));
+                    debug!("(build reduced graph for item) found extern `{}`",
+                            self.module_to_string(&*external_module));
+                    self.check_for_conflicts_between_external_crates(
+                        &*parent.module(),
+                        name.name,
+                        view_item.span);
+                    parent.module().external_module_children.borrow_mut()
+                                   .insert(name.name, external_module.clone());
+                    self.build_reduced_graph_for_external_crate(external_module);
+                }
+            }
+        }
+    }
+
+    /// Constructs the reduced graph for one foreign item.
+    fn build_reduced_graph_for_foreign_item<F>(&mut self,
+                                               foreign_item: &ForeignItem,
+                                               parent: ReducedGraphParent,
+                                               f: F) where
+        F: FnOnce(&mut Resolver),
+    {
+        let name = foreign_item.ident.name;
+        let is_public = foreign_item.vis == ast::Public;
+        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
+        let name_bindings =
+            self.add_child(name, parent, ForbidDuplicateValues,
+                           foreign_item.span);
+
+        match foreign_item.node {
+            ForeignItemFn(_, ref generics) => {
+                let def = DefFn(local_def(foreign_item.id), false);
+                name_bindings.define_value(def, foreign_item.span, modifiers);
+
+                self.with_type_parameter_rib(
+                    HasTypeParameters(generics,
+                                      FnSpace,
+                                      foreign_item.id,
+                                      NormalRibKind),
+                    f);
+            }
+            ForeignItemStatic(_, m) => {
+                let def = DefStatic(local_def(foreign_item.id), m);
+                name_bindings.define_value(def, foreign_item.span, modifiers);
+
+                f(self)
+            }
+        }
+    }
+
+    fn build_reduced_graph_for_block(&mut self,
+                                         block: &Block,
+                                         parent: ReducedGraphParent)
+                                            -> ReducedGraphParent
+    {
+        if self.block_needs_anonymous_module(block) {
+            let block_id = block.id;
+
+            debug!("(building reduced graph for block) creating a new \
+                    anonymous module for block {}",
+                   block_id);
+
+            let parent_module = parent.module();
+            let new_module = Rc::new(Module::new(
+                BlockParentLink(parent_module.downgrade(), block_id),
+                None,
+                AnonymousModuleKind,
+                false,
+                false));
+            parent_module.anonymous_children.borrow_mut()
+                         .insert(block_id, new_module.clone());
+            ModuleReducedGraphParent(new_module)
+        } else {
+            parent
+        }
+    }
+
+    fn handle_external_def(&mut self,
+                           def: Def,
+                           vis: Visibility,
+                           child_name_bindings: &NameBindings,
+                           final_ident: &str,
+                           name: Name,
+                           new_parent: ReducedGraphParent) {
+        debug!("(building reduced graph for \
+                external crate) building external def, priv {}",
+               vis);
+        let is_public = vis == ast::Public;
+        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
+        let is_exported = is_public && match new_parent {
+            ModuleReducedGraphParent(ref module) => {
+                match module.def_id.get() {
+                    None => true,
+                    Some(did) => self.external_exports.contains(&did)
+                }
+            }
+        };
+        if is_exported {
+            self.external_exports.insert(def.def_id());
+        }
+
+        let kind = match def {
+            DefTy(_, true) => EnumModuleKind,
+            DefStruct(..) | DefTy(..) => ImplModuleKind,
+            _ => NormalModuleKind
+        };
+
+        match def {
+          DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
+          DefTy(def_id, _) => {
+            let type_def = child_name_bindings.type_def.borrow().clone();
+            match type_def {
+              Some(TypeNsDef { module_def: Some(module_def), .. }) => {
+                debug!("(building reduced graph for external crate) \
+                        already created module");
+                module_def.def_id.set(Some(def_id));
+              }
+              Some(_) | None => {
+                debug!("(building reduced graph for \
+                        external crate) building module \
+                        {}", final_ident);
+                let parent_link = self.get_parent_link(new_parent.clone(), name);
+
+                child_name_bindings.define_module(parent_link,
+                                                  Some(def_id),
+                                                  kind,
+                                                  true,
+                                                  is_public,
+                                                  DUMMY_SP);
+              }
+            }
+          }
+          _ => {}
+        }
+
+        match def {
+          DefMod(_) | DefForeignMod(_) => {}
+          DefVariant(_, variant_id, is_struct) => {
+              debug!("(building reduced graph for external crate) building \
+                      variant {}",
+                      final_ident);
+              // variants are always treated as importable to allow them to be
+              // glob used
+              let modifiers = PUBLIC | IMPORTABLE;
+              if is_struct {
+                  child_name_bindings.define_type(def, DUMMY_SP, modifiers);
+                  // Not adding fields for variants as they are not accessed with a self receiver
+                  self.structs.insert(variant_id, Vec::new());
+              } else {
+                  child_name_bindings.define_value(def, DUMMY_SP, modifiers);
+              }
+          }
+          DefFn(ctor_id, true) => {
+            child_name_bindings.define_value(
+                csearch::get_tuple_struct_definition_if_ctor(&self.session.cstore, ctor_id)
+                    .map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, modifiers);
+          }
+          DefFn(..) | DefStaticMethod(..) | DefStatic(..) | DefConst(..) | DefMethod(..) => {
+            debug!("(building reduced graph for external \
+                    crate) building value (fn/static) {}", final_ident);
+            // impl methods have already been defined with the correct importability modifier
+            let mut modifiers = match *child_name_bindings.value_def.borrow() {
+                Some(ref def) => (modifiers & !IMPORTABLE) | (def.modifiers & IMPORTABLE),
+                None => modifiers
+            };
+            if new_parent.module().kind.get() != NormalModuleKind {
+                modifiers = modifiers & !IMPORTABLE;
+            }
+            child_name_bindings.define_value(def, DUMMY_SP, modifiers);
+          }
+          DefTrait(def_id) => {
+              debug!("(building reduced graph for external \
+                      crate) building type {}", final_ident);
+
+              // If this is a trait, add all the trait item names to the trait
+              // info.
+
+              let trait_item_def_ids =
+                csearch::get_trait_item_def_ids(&self.session.cstore, def_id);
+              for trait_item_def_id in trait_item_def_ids.iter() {
+                  let (trait_item_name, trait_item_kind) =
+                      csearch::get_trait_item_name_and_kind(
+                          &self.session.cstore,
+                          trait_item_def_id.def_id());
+
+                  debug!("(building reduced graph for external crate) ... \
+                          adding trait item '{}'",
+                         token::get_name(trait_item_name));
+
+                  self.trait_item_map.insert((trait_item_name, def_id), trait_item_kind);
+
+                  if is_exported {
+                      self.external_exports
+                          .insert(trait_item_def_id.def_id());
+                  }
+              }
+
+              child_name_bindings.define_type(def, DUMMY_SP, modifiers);
+
+              // Define a module if necessary.
+              let parent_link = self.get_parent_link(new_parent, name);
+              child_name_bindings.set_module_kind(parent_link,
+                                                  Some(def_id),
+                                                  TraitModuleKind,
+                                                  true,
+                                                  is_public,
+                                                  DUMMY_SP)
+          }
+          DefTy(..) | DefAssociatedTy(..) | DefAssociatedPath(..) => {
+              debug!("(building reduced graph for external \
+                      crate) building type {}", final_ident);
+
+              child_name_bindings.define_type(def, DUMMY_SP, modifiers);
+          }
+          DefStruct(def_id) => {
+            debug!("(building reduced graph for external \
+                    crate) building type and value for {}",
+                   final_ident);
+            child_name_bindings.define_type(def, DUMMY_SP, modifiers);
+            let fields = csearch::get_struct_fields(&self.session.cstore, def_id).iter().map(|f| {
+                f.name
+            }).collect::<Vec<_>>();
+
+            if fields.len() == 0 {
+                child_name_bindings.define_value(def, DUMMY_SP, modifiers);
+            }
+
+            // Record the def ID and fields of this struct.
+            self.structs.insert(def_id, fields);
+          }
+          DefLocal(..) | DefPrimTy(..) | DefTyParam(..) |
+          DefUse(..) | DefUpvar(..) | DefRegion(..) |
+          DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
+            panic!("didn't expect `{}`", def);
+          }
+        }
+    }
+
+    /// Builds the reduced graph for a single item in an external crate.
+    fn build_reduced_graph_for_external_crate_def(&mut self,
+                                                  root: Rc<Module>,
+                                                  def_like: DefLike,
+                                                  name: Name,
+                                                  visibility: Visibility) {
+        match def_like {
+            DlDef(def) => {
+                // Add the new child item, if necessary.
+                match def {
+                    DefForeignMod(def_id) => {
+                        // Foreign modules have no names. Recur and populate
+                        // eagerly.
+                        csearch::each_child_of_item(&self.session.cstore,
+                                                    def_id,
+                                                    |def_like,
+                                                     child_name,
+                                                     vis| {
+                            self.build_reduced_graph_for_external_crate_def(
+                                root.clone(),
+                                def_like,
+                                child_name,
+                                vis)
+                        });
+                    }
+                    _ => {
+                        let child_name_bindings =
+                            self.add_child(name,
+                                           ModuleReducedGraphParent(root.clone()),
+                                           OverwriteDuplicates,
+                                           DUMMY_SP);
+
+                        self.handle_external_def(def,
+                                                 visibility,
+                                                 &*child_name_bindings,
+                                                 token::get_name(name).get(),
+                                                 name,
+                                                 ModuleReducedGraphParent(root));
+                    }
+                }
+            }
+            DlImpl(def) => {
+                match csearch::get_type_name_if_impl(&self.session.cstore, def) {
+                    None => {}
+                    Some(final_name) => {
+                        let methods_opt =
+                            csearch::get_methods_if_impl(&self.session.cstore, def);
+                        match methods_opt {
+                            Some(ref methods) if
+                                methods.len() >= 1 => {
+                                debug!("(building reduced graph for \
+                                        external crate) processing \
+                                        static methods for type name {}",
+                                        token::get_name(final_name));
+
+                                let child_name_bindings =
+                                    self.add_child(
+                                        final_name,
+                                        ModuleReducedGraphParent(root.clone()),
+                                        OverwriteDuplicates,
+                                        DUMMY_SP);
+
+                                // Process the static methods. First,
+                                // create the module.
+                                let type_module;
+                                let type_def = child_name_bindings.type_def.borrow().clone();
+                                match type_def {
+                                    Some(TypeNsDef {
+                                        module_def: Some(module_def),
+                                        ..
+                                    }) => {
+                                        // We already have a module. This
+                                        // is OK.
+                                        type_module = module_def;
+
+                                        // Mark it as an impl module if
+                                        // necessary.
+                                        type_module.kind.set(ImplModuleKind);
+                                    }
+                                    Some(_) | None => {
+                                        let parent_link =
+                                            self.get_parent_link(ModuleReducedGraphParent(root),
+                                                                 final_name);
+                                        child_name_bindings.define_module(
+                                            parent_link,
+                                            Some(def),
+                                            ImplModuleKind,
+                                            true,
+                                            true,
+                                            DUMMY_SP);
+                                        type_module =
+                                            child_name_bindings.
+                                                get_module();
+                                    }
+                                }
+
+                                // Add each static method to the module.
+                                let new_parent =
+                                    ModuleReducedGraphParent(type_module);
+                                for method_info in methods.iter() {
+                                    let name = method_info.name;
+                                    debug!("(building reduced graph for \
+                                             external crate) creating \
+                                             static method '{}'",
+                                           token::get_name(name));
+
+                                    let method_name_bindings =
+                                        self.add_child(name,
+                                                       new_parent.clone(),
+                                                       OverwriteDuplicates,
+                                                       DUMMY_SP);
+                                    let def = DefFn(method_info.def_id, false);
+
+                                    // NB: not IMPORTABLE
+                                    let modifiers = if visibility == ast::Public {
+                                        PUBLIC
+                                    } else {
+                                        DefModifiers::empty()
+                                    };
+                                    method_name_bindings.define_value(
+                                        def, DUMMY_SP, modifiers);
+                                }
+                            }
+
+                            // Otherwise, do nothing.
+                            Some(_) | None => {}
+                        }
+                    }
+                }
+            }
+            DlField => {
+                debug!("(building reduced graph for external crate) \
+                        ignoring field");
+            }
+        }
+    }
+
+    /// 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_string(&*module));
+
+        let def_id = match module.def_id.get() {
+            None => {
+                debug!("(populating external module) ... no def ID!");
+                return
+            }
+            Some(def_id) => def_id,
+        };
+
+        csearch::each_child_of_item(&self.session.cstore,
+                                    def_id,
+                                    |def_like, child_name, visibility| {
+            debug!("(populating external module) ... found ident: {}",
+                   token::get_name(child_name));
+            self.build_reduced_graph_for_external_crate_def(module.clone(),
+                                                            def_like,
+                                                            child_name,
+                                                            visibility)
+        });
+        module.populated.set(true)
+    }
+
+    /// Ensures that the reduced graph rooted at the given external module
+    /// is built, building it if it is not.
+    fn populate_module_if_necessary(&mut self, module: &Rc<Module>) {
+        if !module.populated.get() {
+            self.populate_external_module(module.clone())
+        }
+        assert!(module.populated.get())
+    }
+
+    /// Builds the reduced graph rooted at the 'use' directive for an external
+    /// crate.
+    fn build_reduced_graph_for_external_crate(&mut self, root: Rc<Module>) {
+        csearch::each_top_level_item_of_crate(&self.session.cstore,
+                                              root.def_id
+                                                  .get()
+                                                  .unwrap()
+                                                  .krate,
+                                              |def_like, name, visibility| {
+            self.build_reduced_graph_for_external_crate_def(root.clone(),
+                                                            def_like,
+                                                            name,
+                                                            visibility)
+        });
+    }
+
+    /// Creates and adds an import directive to the given module.
+    fn build_import_directive(&mut self,
+                              module_: &Module,
+                              module_path: Vec<Name>,
+                              subclass: ImportDirectiveSubclass,
+                              span: Span,
+                              id: NodeId,
+                              is_public: bool,
+                              shadowable: bool) {
+        module_.imports.borrow_mut().push(ImportDirective::new(module_path,
+                                                               subclass,
+                                                               span,
+                                                               id,
+                                                               is_public,
+                                                               shadowable));
+        self.unresolved_imports += 1;
+        // Bump the reference count on the name. Or, if this is a glob, set
+        // the appropriate flag.
+
+        match subclass {
+            SingleImport(target, _) => {
+                debug!("(building import directive) building import \
+                        directive: {}::{}",
+                       self.names_to_string(module_.imports.borrow().last().unwrap()
+                                                 .module_path.as_slice()),
+                       token::get_name(target));
+
+                let mut import_resolutions = module_.import_resolutions
+                                                    .borrow_mut();
+                match import_resolutions.get_mut(&target) {
+                    Some(resolution) => {
+                        debug!("(building import directive) bumping \
+                                reference");
+                        resolution.outstanding_references += 1;
+
+                        // the source of this name is different now
+                        resolution.type_id = id;
+                        resolution.value_id = id;
+                        resolution.is_public = is_public;
+                        return;
+                    }
+                    None => {}
+                }
+                debug!("(building import directive) creating new");
+                let mut resolution = ImportResolution::new(id, is_public);
+                resolution.outstanding_references = 1;
+                import_resolutions.insert(target, resolution);
+            }
+            GlobImport => {
+                // Set the glob flag. This tells us that we don't know the
+                // module's exports ahead of time.
+
+                module_.glob_count.set(module_.glob_count.get() + 1);
+            }
+        }
+    }
+
+    // Import resolution
+    //
+    // This is a fixed-point algorithm. We resolve imports until our efforts
+    // are stymied by an unresolved import; then we bail out of the current
+    // module and continue. We terminate successfully once no more imports
+    // remain or unsuccessfully when no forward progress in resolving imports
+    // is made.
+
+    /// Resolves all imports for the crate. This method performs the fixed-
+    /// point iteration.
+    fn resolve_imports(&mut self) {
+        let mut i = 0u;
+        let mut prev_unresolved_imports = 0;
+        loop {
+            debug!("(resolving imports) iteration {}, {} imports left",
+                   i, self.unresolved_imports);
+
+            let module_root = self.graph_root.get_module();
+            self.resolve_imports_for_module_subtree(module_root.clone());
+
+            if self.unresolved_imports == 0 {
+                debug!("(resolving imports) success");
+                break;
+            }
+
+            if self.unresolved_imports == prev_unresolved_imports {
+                self.report_unresolved_imports(module_root);
+                break;
+            }
+
+            i += 1;
+            prev_unresolved_imports = self.unresolved_imports;
+        }
+    }
+
+    /// Attempts to resolve imports for the given module and all of its
+    /// submodules.
+    fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
+        debug!("(resolving imports for module subtree) resolving {}",
+               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;
+
+        self.populate_module_if_necessary(&module_);
+        for (_, child_node) in module_.children.borrow().iter() {
+            match child_node.get_module_if_available() {
+                None => {
+                    // Nothing to do.
+                }
+                Some(child_module) => {
+                    self.resolve_imports_for_module_subtree(child_module);
+                }
+            }
+        }
+
+        for (_, child_module) in module_.anonymous_children.borrow().iter() {
+            self.resolve_imports_for_module_subtree(child_module.clone());
+        }
+    }
+
+    /// Attempts to resolve imports for the given module only.
+    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_string(&*module));
+            return;
+        }
+
+        let imports = module.imports.borrow();
+        let import_count = imports.len();
+        while module.resolved_import_count.get() < import_count {
+            let import_index = module.resolved_import_count.get();
+            let import_directive = &(*imports)[import_index];
+            match self.resolve_import_for_module(module.clone(),
+                                                 import_directive) {
+                Failed(err) => {
+                    let (span, help) = match err {
+                        Some((span, msg)) => (span, format!(". {}", msg)),
+                        None => (import_directive.span, String::new())
+                    };
+                    let msg = format!("unresolved import `{}`{}",
+                                      self.import_path_to_string(
+                                          import_directive.module_path
+                                                          .as_slice(),
+                                          import_directive.subclass),
+                                      help);
+                    self.resolve_error(span, msg.as_slice());
+                }
+                Indeterminate => break, // Bail out. We'll come around next time.
+                Success(()) => () // Good. Continue.
+            }
+
+            module.resolved_import_count
+                  .set(module.resolved_import_count.get() + 1);
+        }
+    }
+
+    fn names_to_string(&self, names: &[Name]) -> String {
+        let mut first = true;
+        let mut result = String::new();
+        for name in names.iter() {
+            if first {
+                first = false
+            } else {
+                result.push_str("::")
+            }
+            result.push_str(token::get_name(*name).get());
+        };
+        result
+    }
+
+    fn path_names_to_string(&self, path: &Path) -> String {
+        let names: Vec<ast::Name> = path.segments
+                                        .iter()
+                                        .map(|seg| seg.identifier.name)
+                                        .collect();
+        self.names_to_string(names.as_slice())
+    }
+
+    fn import_directive_subclass_to_string(&mut self,
+                                        subclass: ImportDirectiveSubclass)
+                                        -> String {
+        match subclass {
+            SingleImport(_, source) => {
+                token::get_name(source).get().to_string()
+            }
+            GlobImport => "*".to_string()
+        }
+    }
+
+    fn import_path_to_string(&mut self,
+                          names: &[Name],
+                          subclass: ImportDirectiveSubclass)
+                          -> String {
+        if names.is_empty() {
+            self.import_directive_subclass_to_string(subclass)
+        } else {
+            (format!("{}::{}",
+                     self.names_to_string(names),
+                     self.import_directive_subclass_to_string(
+                         subclass))).to_string()
+        }
+    }
+
+    /// Attempts to resolve the given import. The return value indicates
+    /// failure if we're certain the name does not exist, indeterminate if we
+    /// don't know whether the name exists at the moment due to other
+    /// currently-unresolved imports, or success if we know the name exists.
+    /// If successful, the resolved bindings are written into the module.
+    fn resolve_import_for_module(&mut self,
+                                 module_: Rc<Module>,
+                                 import_directive: &ImportDirective)
+                                 -> ResolveResult<()> {
+        let mut resolution_result = Failed(None);
+        let module_path = &import_directive.module_path;
+
+        debug!("(resolving import for module) resolving import `{}::...` in \
+                `{}`",
+               self.names_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 {
+            // Use the crate root.
+            Some((self.graph_root.get_module(), LastMod(AllPublic)))
+        } else {
+            match self.resolve_module_path(module_.clone(),
+                                           module_path.as_slice(),
+                                           DontUseLexicalScope,
+                                           import_directive.span,
+                                           ImportSearch) {
+                Failed(err) => {
+                    resolution_result = Failed(err);
+                    None
+                },
+                Indeterminate => {
+                    resolution_result = Indeterminate;
+                    None
+                }
+                Success(container) => Some(container),
+            }
+        };
+
+        match container {
+            None => {}
+            Some((containing_module, lp)) => {
+                // We found the module that the target is contained
+                // within. Attempt to resolve the import within it.
+
+                match import_directive.subclass {
+                    SingleImport(target, source) => {
+                        resolution_result =
+                            self.resolve_single_import(&*module_,
+                                                       containing_module,
+                                                       target,
+                                                       source,
+                                                       import_directive,
+                                                       lp);
+                    }
+                    GlobImport => {
+                        resolution_result =
+                            self.resolve_glob_import(&*module_,
+                                                     containing_module,
+                                                     import_directive,
+                                                     lp);
+                    }
+                }
+            }
+        }
+
+        // Decrement the count of unresolved imports.
+        match resolution_result {
+            Success(()) => {
+                assert!(self.unresolved_imports >= 1);
+                self.unresolved_imports -= 1;
+            }
+            _ => {
+                // Nothing to do here; just return the error.
+            }
+        }
+
+        // Decrement the count of unresolved globs if necessary. But only if
+        // the resolution result is indeterminate -- otherwise we'll stop
+        // processing imports here. (See the loop in
+        // resolve_imports_for_module.)
+
+        if !resolution_result.indeterminate() {
+            match import_directive.subclass {
+                GlobImport => {
+                    assert!(module_.glob_count.get() >= 1);
+                    module_.glob_count.set(module_.glob_count.get() - 1);
+                }
+                SingleImport(..) => {
+                    // Ignore.
+                }
+            }
+        }
+
+        return resolution_result;
+    }
+
+    fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
+        NameBindings {
+            type_def: RefCell::new(Some(TypeNsDef {
+                modifiers: IMPORTABLE,
+                module_def: Some(module),
+                type_def: None,
+                type_span: None
+            })),
+            value_def: RefCell::new(None),
+        }
+    }
+
+    fn resolve_single_import(&mut self,
+                             module_: &Module,
+                             containing_module: Rc<Module>,
+                             target: Name,
+                             source: Name,
+                             directive: &ImportDirective,
+                             lp: LastPrivate)
+                                 -> ResolveResult<()> {
+        debug!("(resolving single import) resolving `{}` = `{}::{}` from \
+                `{}` id {}, last private {}",
+               token::get_name(target),
+               self.module_to_string(&*containing_module),
+               token::get_name(source),
+               self.module_to_string(module_),
+               directive.id,
+               lp);
+
+        let lp = match lp {
+            LastMod(lp) => lp,
+            LastImport {..} => {
+                self.session
+                    .span_bug(directive.span,
+                              "not expecting Import here, must be LastMod")
+            }
+        };
+
+        // We need to resolve both namespaces for this to succeed.
+        //
+
+        let mut value_result = UnknownResult;
+        let mut type_result = UnknownResult;
+
+        // Search for direct children of the containing module.
+        self.populate_module_if_necessary(&containing_module);
+
+        match containing_module.children.borrow().get(&source) {
+            None => {
+                // Continue.
+            }
+            Some(ref child_name_bindings) => {
+                if child_name_bindings.defined_in_namespace(ValueNS) {
+                    debug!("(resolving single import) found value binding");
+                    value_result = BoundResult(containing_module.clone(),
+                                               (*child_name_bindings).clone());
+                }
+                if child_name_bindings.defined_in_namespace(TypeNS) {
+                    debug!("(resolving single import) found type binding");
+                    type_result = BoundResult(containing_module.clone(),
+                                              (*child_name_bindings).clone());
+                }
+            }
+        }
+
+        // Unless we managed to find a result in both namespaces (unlikely),
+        // search imports as well.
+        let mut value_used_reexport = false;
+        let mut type_used_reexport = false;
+        match (value_result.clone(), type_result.clone()) {
+            (BoundResult(..), BoundResult(..)) => {} // Continue.
+            _ => {
+                // If there is an unresolved glob at this point in the
+                // containing module, bail out. We don't know enough to be
+                // able to resolve this import.
+
+                if containing_module.glob_count.get() > 0 {
+                    debug!("(resolving single import) unresolved glob; \
+                            bailing out");
+                    return Indeterminate;
+                }
+
+                // Now search the exported imports within the containing module.
+                match containing_module.import_resolutions.borrow().get(&source) {
+                    None => {
+                        debug!("(resolving single import) no import");
+                        // The containing module definitely doesn't have an
+                        // exported import with the name in question. We can
+                        // therefore accurately report that the names are
+                        // unbound.
+
+                        if value_result.is_unknown() {
+                            value_result = UnboundResult;
+                        }
+                        if type_result.is_unknown() {
+                            type_result = UnboundResult;
+                        }
+                    }
+                    Some(import_resolution)
+                            if import_resolution.outstanding_references == 0 => {
+
+                        fn get_binding(this: &mut Resolver,
+                                       import_resolution: &ImportResolution,
+                                       namespace: Namespace)
+                                    -> NamespaceResult {
+
+                            // Import resolutions must be declared with "pub"
+                            // in order to be exported.
+                            if !import_resolution.is_public {
+                                return UnboundResult;
+                            }
+
+                            match import_resolution.
+                                    target_for_namespace(namespace) {
+                                None => {
+                                    return UnboundResult;
+                                }
+                                Some(Target {
+                                    target_module,
+                                    bindings,
+                                    shadowable: _
+                                }) => {
+                                    debug!("(resolving single import) found \
+                                            import in ns {}", namespace);
+                                    let id = import_resolution.id(namespace);
+                                    // track used imports and extern crates as well
+                                    this.used_imports.insert((id, namespace));
+                                    match target_module.def_id.get() {
+                                        Some(DefId{krate: kid, ..}) => {
+                                            this.used_crates.insert(kid);
+                                        },
+                                        _ => {}
+                                    }
+                                    return BoundResult(target_module, bindings);
+                                }
+                            }
+                        }
+
+                        // The name is an import which has been fully
+                        // resolved. We can, therefore, just follow it.
+                        if value_result.is_unknown() {
+                            value_result = get_binding(self, import_resolution,
+                                                       ValueNS);
+                            value_used_reexport = import_resolution.is_public;
+                        }
+                        if type_result.is_unknown() {
+                            type_result = get_binding(self, import_resolution,
+                                                      TypeNS);
+                            type_used_reexport = import_resolution.is_public;
+                        }
+
+                    }
+                    Some(_) => {
+                        // If containing_module is the same module whose import we are resolving
+                        // and there it has an unresolved import with the same name as `source`,
+                        // then the user is actually trying to import an item that is declared
+                        // in the same scope
+                        //
+                        // e.g
+                        // use self::submodule;
+                        // pub mod submodule;
+                        //
+                        // In this case we continue as if we resolved the import and let the
+                        // check_for_conflicts_between_imports_and_items call below handle
+                        // the conflict
+                        match (module_.def_id.get(),  containing_module.def_id.get()) {
+                            (Some(id1), Some(id2)) if id1 == id2  => {
+                                if value_result.is_unknown() {
+                                    value_result = UnboundResult;
+                                }
+                                if type_result.is_unknown() {
+                                    type_result = UnboundResult;
+                                }
+                            }
+                            _ =>  {
+                                // The import is unresolved. Bail out.
+                                debug!("(resolving single import) unresolved import; \
+                                        bailing out");
+                                return Indeterminate;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        // If we didn't find a result in the type namespace, search the
+        // external modules.
+        let mut value_used_public = false;
+        let mut type_used_public = false;
+        match type_result {
+            BoundResult(..) => {}
+            _ => {
+                match containing_module.external_module_children.borrow_mut()
+                                       .get(&source).cloned() {
+                    None => {} // Continue.
+                    Some(module) => {
+                        debug!("(resolving single import) found external \
+                                module");
+                        // track the module as used.
+                        match module.def_id.get() {
+                            Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
+                            _ => {}
+                        }
+                        let name_bindings =
+                            Rc::new(Resolver::create_name_bindings_from_module(
+                                module));
+                        type_result = BoundResult(containing_module.clone(),
+                                                  name_bindings);
+                        type_used_public = true;
+                    }
+                }
+            }
+        }
+
+        // We've successfully resolved the import. Write the results in.
+        let mut import_resolutions = module_.import_resolutions.borrow_mut();
+        let import_resolution = &mut (*import_resolutions)[target];
+
+        match value_result {
+            BoundResult(ref target_module, ref name_bindings) => {
+                debug!("(resolving single import) found value target: {}",
+                       { name_bindings.value_def.borrow().clone().unwrap().def });
+                self.check_for_conflicting_import(
+                    &import_resolution.value_target,
+                    directive.span,
+                    target,
+                    ValueNS);
+
+                self.check_that_import_is_importable(
+                    &**name_bindings,
+                    directive.span,
+                    target,
+                    ValueNS);
+
+                import_resolution.value_target =
+                    Some(Target::new(target_module.clone(),
+                                     name_bindings.clone(),
+                                     directive.shadowable));
+                import_resolution.value_id = directive.id;
+                import_resolution.is_public = directive.is_public;
+                value_used_public = name_bindings.defined_in_public_namespace(ValueNS);
+            }
+            UnboundResult => { /* Continue. */ }
+            UnknownResult => {
+                panic!("value result should be known at this point");
+            }
+        }
+        match type_result {
+            BoundResult(ref target_module, ref name_bindings) => {
+                debug!("(resolving single import) found type target: {}",
+                       { name_bindings.type_def.borrow().clone().unwrap().type_def });
+                self.check_for_conflicting_import(
+                    &import_resolution.type_target,
+                    directive.span,
+                    target,
+                    TypeNS);
+
+                self.check_that_import_is_importable(
+                    &**name_bindings,
+                    directive.span,
+                    target,
+                    TypeNS);
+
+                import_resolution.type_target =
+                    Some(Target::new(target_module.clone(),
+                                     name_bindings.clone(),
+                                     directive.shadowable));
+                import_resolution.type_id = directive.id;
+                import_resolution.is_public = directive.is_public;
+                type_used_public = name_bindings.defined_in_public_namespace(TypeNS);
+            }
+            UnboundResult => { /* Continue. */ }
+            UnknownResult => {
+                panic!("type result should be known at this point");
+            }
+        }
+
+        self.check_for_conflicts_between_imports_and_items(
+            module_,
+            import_resolution,
+            directive.span,
+            target);
+
+        if value_result.is_unbound() && type_result.is_unbound() {
+            let msg = format!("There is no `{}` in `{}`",
+                              token::get_name(source),
+                              self.module_to_string(&*containing_module));
+            return Failed(Some((directive.span, msg)));
+        }
+        let value_used_public = value_used_reexport || value_used_public;
+        let type_used_public = type_used_reexport || type_used_public;
+
+        assert!(import_resolution.outstanding_references >= 1);
+        import_resolution.outstanding_references -= 1;
+
+        // record what this import resolves to for later uses in documentation,
+        // this may resolve to either a value or a type, but for documentation
+        // purposes it's good enough to just favor one over the other.
+        let value_private = match import_resolution.value_target {
+            Some(ref target) => {
+                let def = target.bindings.def_for_namespace(ValueNS).unwrap();
+                self.def_map.borrow_mut().insert(directive.id, def);
+                let did = def.def_id();
+                if value_used_public {Some(lp)} else {Some(DependsOn(did))}
+            },
+            // AllPublic here and below is a dummy value, it should never be used because
+            // _exists is false.
+            None => None,
+        };
+        let type_private = match import_resolution.type_target {
+            Some(ref target) => {
+                let def = target.bindings.def_for_namespace(TypeNS).unwrap();
+                self.def_map.borrow_mut().insert(directive.id, def);
+                let did = def.def_id();
+                if type_used_public {Some(lp)} else {Some(DependsOn(did))}
+            },
+            None => None,
+        };
+
+        self.last_private.insert(directive.id, LastImport{value_priv: value_private,
+                                                          value_used: Used,
+                                                          type_priv: type_private,
+                                                          type_used: Used});
+
+        debug!("(resolving single import) successfully resolved import");
+        return Success(());
+    }
+
+    // Resolves a glob import. Note that this function cannot panic; it either
+    // succeeds or bails out (as importing * from an empty module or a module
+    // that exports nothing is valid).
+    fn resolve_glob_import(&mut self,
+                           module_: &Module,
+                           containing_module: Rc<Module>,
+                           import_directive: &ImportDirective,
+                           lp: LastPrivate)
+                           -> ResolveResult<()> {
+        let id = import_directive.id;
+        let is_public = import_directive.is_public;
+
+        // This function works in a highly imperative manner; it eagerly adds
+        // everything it can to the list of import resolutions of the module
+        // node.
+        debug!("(resolving glob import) resolving glob import {}", id);
+
+        // We must bail out if the node has unresolved imports of any kind
+        // (including globs).
+        if !(*containing_module).all_imports_resolved() {
+            debug!("(resolving glob import) target module has unresolved \
+                    imports; bailing out");
+            return Indeterminate;
+        }
+
+        assert_eq!(containing_module.glob_count.get(), 0);
+
+        // Add all resolved imports from the containing module.
+        let import_resolutions = containing_module.import_resolutions
+                                                  .borrow();
+        for (ident, target_import_resolution) in import_resolutions.iter() {
+            debug!("(resolving glob import) writing module resolution \
+                    {} into `{}`",
+                   target_import_resolution.type_target.is_none(),
+                   self.module_to_string(module_));
+
+            if !target_import_resolution.is_public {
+                debug!("(resolving glob import) nevermind, just kidding");
+                continue
+            }
+
+            // Here we merge two import resolutions.
+            let mut import_resolutions = module_.import_resolutions.borrow_mut();
+            match import_resolutions.get_mut(ident) {
+                Some(dest_import_resolution) => {
+                    // Merge the two import resolutions at a finer-grained
+                    // level.
+
+                    match target_import_resolution.value_target {
+                        None => {
+                            // Continue.
+                        }
+                        Some(ref value_target) => {
+                            dest_import_resolution.value_target =
+                                Some(value_target.clone());
+                        }
+                    }
+                    match target_import_resolution.type_target {
+                        None => {
+                            // Continue.
+                        }
+                        Some(ref type_target) => {
+                            dest_import_resolution.type_target =
+                                Some(type_target.clone());
+                        }
+                    }
+                    dest_import_resolution.is_public = is_public;
+                    continue;
+                }
+                None => {}
+            }
+
+            // Simple: just copy the old import resolution.
+            let mut new_import_resolution = ImportResolution::new(id, is_public);
+            new_import_resolution.value_target =
+                target_import_resolution.value_target.clone();
+            new_import_resolution.type_target =
+                target_import_resolution.type_target.clone();
+
+            import_resolutions.insert(*ident, new_import_resolution);
+        }
+
+        // Add all children from the containing module.
+        self.populate_module_if_necessary(&containing_module);
+
+        for (&name, name_bindings) in containing_module.children
+                                                       .borrow().iter() {
+            self.merge_import_resolution(module_,
+                                         containing_module.clone(),
+                                         import_directive,
+                                         name,
+                                         name_bindings.clone());
+
+        }
+
+        // Add external module children from the containing module.
+        for (&name, module) in containing_module.external_module_children
+                                                .borrow().iter() {
+            let name_bindings =
+                Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
+            self.merge_import_resolution(module_,
+                                         containing_module.clone(),
+                                         import_directive,
+                                         name,
+                                         name_bindings);
+        }
+
+        // Record the destination of this import
+        match containing_module.def_id.get() {
+            Some(did) => {
+                self.def_map.borrow_mut().insert(id, DefMod(did));
+                self.last_private.insert(id, lp);
+            }
+            None => {}
+        }
+
+        debug!("(resolving glob import) successfully resolved import");
+        return Success(());
+    }
+
+    fn merge_import_resolution(&mut self,
+                               module_: &Module,
+                               containing_module: Rc<Module>,
+                               import_directive: &ImportDirective,
+                               name: Name,
+                               name_bindings: Rc<NameBindings>) {
+        let id = import_directive.id;
+        let is_public = import_directive.is_public;
+
+        let mut import_resolutions = module_.import_resolutions.borrow_mut();
+        let dest_import_resolution = match import_resolutions.entry(name) {
+            Occupied(entry) => entry.into_mut(),
+            Vacant(entry) => {
+                // Create a new import resolution from this child.
+                entry.set(ImportResolution::new(id, is_public))
+            }
+        };
+
+        debug!("(resolving glob import) writing resolution `{}` in `{}` \
+               to `{}`",
+               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_namespace_with(ValueNS, IMPORTABLE | PUBLIC) {
+            debug!("(resolving glob import) ... for value target");
+            dest_import_resolution.value_target =
+                Some(Target::new(containing_module.clone(),
+                                 name_bindings.clone(),
+                                 import_directive.shadowable));
+            dest_import_resolution.value_id = id;
+        }
+        if name_bindings.defined_in_namespace_with(TypeNS, IMPORTABLE | PUBLIC) {
+            debug!("(resolving glob import) ... for type target");
+            dest_import_resolution.type_target =
+                Some(Target::new(containing_module,
+                                 name_bindings.clone(),
+                                 import_directive.shadowable));
+            dest_import_resolution.type_id = id;
+        }
+        dest_import_resolution.is_public = is_public;
+
+        self.check_for_conflicts_between_imports_and_items(
+            module_,
+            dest_import_resolution,
+            import_directive.span,
+            name);
+    }
+
+    /// Checks that imported names and items don't have the same name.
+    fn check_for_conflicting_import(&mut self,
+                                    target: &Option<Target>,
+                                    import_span: Span,
+                                    name: Name,
+                                    namespace: Namespace) {
+        if self.session.features.borrow().import_shadowing {
+            return
+        }
+
+        match *target {
+            Some(ref target) if !target.shadowable => {
+                let msg = format!("a {} named `{}` has already been imported \
+                                   in this module",
+                                  match namespace {
+                                    TypeNS => "type",
+                                    ValueNS => "value",
+                                  },
+                                  token::get_name(name).get());
+                self.session.span_err(import_span, msg.as_slice());
+            }
+            Some(_) | None => {}
+        }
+    }
+
+    /// Checks that an import is actually importable
+    fn check_that_import_is_importable(&mut self,
+                                       name_bindings: &NameBindings,
+                                       import_span: Span,
+                                       name: Name,
+                                       namespace: Namespace) {
+        if !name_bindings.defined_in_namespace_with(namespace, IMPORTABLE) {
+            let msg = format!("`{}` is not directly importable",
+                              token::get_name(name));
+            self.session.span_err(import_span, msg.as_slice());
+        }
+    }
+
+    /// Checks that imported names and items don't have the same name.
+    fn check_for_conflicts_between_imports_and_items(&mut self,
+                                                     module: &Module,
+                                                     import_resolution:
+                                                     &ImportResolution,
+                                                     import_span: Span,
+                                                     name: Name) {
+        if self.session.features.borrow().import_shadowing {
+            return
+        }
+
+        // First, check for conflicts between imports and `extern crate`s.
+        if module.external_module_children
+                 .borrow()
+                 .contains_key(&name) {
+            match import_resolution.type_target {
+                Some(ref target) if !target.shadowable => {
+                    let msg = format!("import `{0}` conflicts with imported \
+                                       crate in this module \
+                                       (maybe you meant `use {0}::*`?)",
+                                      token::get_name(name).get());
+                    self.session.span_err(import_span, msg.as_slice());
+                }
+                Some(_) | None => {}
+            }
+        }
+
+        // Check for item conflicts.
+        let children = module.children.borrow();
+        let name_bindings = match children.get(&name) {
+            None => {
+                // There can't be any conflicts.
+                return
+            }
+            Some(ref name_bindings) => (*name_bindings).clone(),
+        };
+
+        match import_resolution.value_target {
+            Some(ref target) if !target.shadowable => {
+                if let Some(ref value) = *name_bindings.value_def.borrow() {
+                    let msg = format!("import `{}` conflicts with value \
+                                       in this module",
+                                      token::get_name(name).get());
+                    self.session.span_err(import_span, msg.as_slice());
+                    if let Some(span) = value.value_span {
+                        self.session.span_note(span,
+                                               "conflicting value here");
+                    }
+                }
+            }
+            Some(_) | None => {}
+        }
+
+        match import_resolution.type_target {
+            Some(ref target) if !target.shadowable => {
+                if let Some(ref ty) = *name_bindings.type_def.borrow() {
+                    match ty.module_def {
+                        None => {
+                            let msg = format!("import `{}` conflicts with type in \
+                                               this module",
+                                              token::get_name(name).get());
+                            self.session.span_err(import_span, msg.as_slice());
+                            if let Some(span) = ty.type_span {
+                                self.session.span_note(span,
+                                                       "note conflicting type here")
+                            }
+                        }
+                        Some(ref module_def) => {
+                            match module_def.kind.get() {
+                                ImplModuleKind => {
+                                    if let Some(span) = ty.type_span {
+                                        let msg = format!("inherent implementations \
+                                                           are only allowed on types \
+                                                           defined in the current module");
+                                        self.session.span_err(span, msg.as_slice());
+                                        self.session.span_note(import_span,
+                                                               "import from other module here")
+                                    }
+                                }
+                                _ => {
+                                    let msg = format!("import `{}` conflicts with existing \
+                                                       submodule",
+                                                      token::get_name(name).get());
+                                    self.session.span_err(import_span, msg.as_slice());
+                                    if let Some(span) = ty.type_span {
+                                        self.session.span_note(span,
+                                                               "note conflicting module here")
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            Some(_) | None => {}
+        }
+    }
+
+    /// Checks that the names of external crates don't collide with other
+    /// external crates.
+    fn check_for_conflicts_between_external_crates(&self,
+                                                   module: &Module,
+                                                   name: Name,
+                                                   span: Span) {
+        if self.session.features.borrow().import_shadowing {
+            return
+        }
+
+        if module.external_module_children.borrow().contains_key(&name) {
+            self.session
+                .span_err(span,
+                          format!("an external crate named `{}` has already \
+                                   been imported into this module",
+                                  token::get_name(name).get()).as_slice());
+        }
+    }
+
+    /// Checks that the names of items don't collide with external crates.
+    fn check_for_conflicts_between_external_crates_and_items(&self,
+                                                             module: &Module,
+                                                             name: Name,
+                                                             span: Span) {
+        if self.session.features.borrow().import_shadowing {
+            return
+        }
+
+        if module.external_module_children.borrow().contains_key(&name) {
+            self.session
+                .span_err(span,
+                          format!("the name `{}` conflicts with an external \
+                                   crate that has been imported into this \
+                                   module",
+                                  token::get_name(name).get()).as_slice());
+        }
+    }
+
+    /// Resolves the given module path from the given root `module_`.
+    fn resolve_module_path_from_root(&mut self,
+                                     module_: Rc<Module>,
+                                     module_path: &[Name],
+                                     index: uint,
+                                     span: Span,
+                                     name_search_type: NameSearchType,
+                                     lp: LastPrivate)
+                                -> ResolveResult<(Rc<Module>, LastPrivate)> {
+        fn search_parent_externals(needle: Name, module: &Rc<Module>)
+                                -> Option<Rc<Module>> {
+            module.external_module_children.borrow()
+                                            .get(&needle).cloned()
+                                            .map(|_| module.clone())
+                                            .or_else(|| {
+                match module.parent_link.clone() {
+                    ModuleParentLink(parent, _) => {
+                        search_parent_externals(needle,
+                                                &parent.upgrade().unwrap())
+                    }
+                   _ => None
+                }
+            })
+        }
+
+        let mut search_module = module_;
+        let mut index = index;
+        let module_path_len = module_path.len();
+        let mut closest_private = lp;
+
+        // Resolve the module part of the path. This does not involve looking
+        // upward though scope chains; we simply resolve names directly in
+        // modules as we go.
+        while index < module_path_len {
+            let name = module_path[index];
+            match self.resolve_name_in_module(search_module.clone(),
+                                              name,
+                                              TypeNS,
+                                              name_search_type,
+                                              false) {
+                Failed(None) => {
+                    let segment_name = token::get_name(name);
+                    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());
+
+                        match search_parent_externals(name,
+                                                     &self.current_module) {
+                            Some(module) => {
+                                let path_str = self.names_to_string(module_path);
+                                let target_mod_str = self.module_to_string(&*module);
+                                let current_mod_str =
+                                    self.module_to_string(&*self.current_module);
+
+                                let prefix = if target_mod_str == current_mod_str {
+                                    "self::".to_string()
+                                } else {
+                                    format!("{}::", target_mod_str)
+                                };
+
+                                format!("Did you mean `{}{}`?", prefix, path_str)
+                            },
+                            None => format!("Maybe a missing `extern crate {}`?",
+                                            segment_name),
+                        }
+                    } else {
+                        format!("Could not find `{}` in `{}`",
+                                segment_name,
+                                module_name)
+                    };
+
+                    return Failed(Some((span, msg)));
+                }
+                Failed(err) => return Failed(err),
+                Indeterminate => {
+                    debug!("(resolving module path for import) module \
+                            resolution is indeterminate: {}",
+                            token::get_name(name));
+                    return Indeterminate;
+                }
+                Success((target, used_proxy)) => {
+                    // Check to see whether there are type bindings, and, if
+                    // so, whether there is a module within.
+                    match *target.bindings.type_def.borrow() {
+                        Some(ref type_def) => {
+                            match type_def.module_def {
+                                None => {
+                                    let msg = format!("Not a module `{}`",
+                                                        token::get_name(name));
+
+                                    return Failed(Some((span, msg)));
+                                }
+                                Some(ref module_def) => {
+                                    search_module = module_def.clone();
+
+                                    // track extern crates for unused_extern_crate lint
+                                    if let Some(did) = module_def.def_id.get() {
+                                        self.used_crates.insert(did.krate);
+                                    }
+
+                                    // Keep track of the closest
+                                    // private module used when
+                                    // resolving this import chain.
+                                    if !used_proxy && !search_module.is_public {
+                                        if let Some(did) = search_module.def_id.get() {
+                                            closest_private = LastMod(DependsOn(did));
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        None => {
+                            // There are no type bindings at all.
+                            let msg = format!("Not a module `{}`",
+                                              token::get_name(name));
+                            return Failed(Some((span, msg)));
+                        }
+                    }
+                }
+            }
+
+            index += 1;
+        }
+
+        return Success((search_module, closest_private));
+    }
+
+    /// Attempts to resolve the module part of an import directive or path
+    /// rooted at the given module.
+    ///
+    /// On success, returns the resolved module, and the closest *private*
+    /// module found to the destination when resolving this path.
+    fn resolve_module_path(&mut self,
+                           module_: Rc<Module>,
+                           module_path: &[Name],
+                           use_lexical_scope: UseLexicalScopeFlag,
+                           span: Span,
+                           name_search_type: NameSearchType)
+                           -> ResolveResult<(Rc<Module>, LastPrivate)> {
+        let module_path_len = module_path.len();
+        assert!(module_path_len > 0);
+
+        debug!("(resolving module path for import) processing `{}` rooted at `{}`",
+               self.names_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(),
+                                                              module_path);
+
+        let search_module;
+        let start_index;
+        let last_private;
+        match module_prefix_result {
+            Failed(None) => {
+                let mpath = self.names_to_string(module_path);
+                let mpath = mpath.as_slice();
+                match mpath.rfind(':') {
+                    Some(idx) => {
+                        let msg = format!("Could not find `{}` in `{}`",
+                                            // idx +- 1 to account for the
+                                            // colons on either side
+                                            mpath.slice_from(idx + 1),
+                                            mpath.slice_to(idx - 1));
+                        return Failed(Some((span, msg)));
+                    },
+                    None => {
+                        return Failed(None)
+                    }
+                }
+            }
+            Failed(err) => return Failed(err),
+            Indeterminate => {
+                debug!("(resolving module path for import) indeterminate; \
+                        bailing");
+                return Indeterminate;
+            }
+            Success(NoPrefixFound) => {
+                // There was no prefix, so we're considering the first element
+                // of the path. How we handle this depends on whether we were
+                // instructed to use lexical scope or not.
+                match use_lexical_scope {
+                    DontUseLexicalScope => {
+                        // This is a crate-relative path. We will start the
+                        // resolution process at index zero.
+                        search_module = self.graph_root.get_module();
+                        start_index = 0;
+                        last_private = LastMod(AllPublic);
+                    }
+                    UseLexicalScope => {
+                        // This is not a crate-relative path. We resolve the
+                        // first component of the path in the current lexical
+                        // scope and then proceed to resolve below that.
+                        match self.resolve_module_in_lexical_scope(module_,
+                                                                   module_path[0]) {
+                            Failed(err) => return Failed(err),
+                            Indeterminate => {
+                                debug!("(resolving module path for import) \
+                                        indeterminate; bailing");
+                                return Indeterminate;
+                            }
+                            Success(containing_module) => {
+                                search_module = containing_module;
+                                start_index = 1;
+                                last_private = LastMod(AllPublic);
+                            }
+                        }
+                    }
+                }
+            }
+            Success(PrefixFound(ref containing_module, index)) => {
+                search_module = containing_module.clone();
+                start_index = index;
+                last_private = LastMod(DependsOn(containing_module.def_id
+                                                                  .get()
+                                                                  .unwrap()));
+            }
+        }
+
+        self.resolve_module_path_from_root(search_module,
+                                           module_path,
+                                           start_index,
+                                           span,
+                                           name_search_type,
+                                           last_private)
+    }
+
+    /// Invariant: This must only be called during main resolution, not during
+    /// import resolution.
+    fn resolve_item_in_lexical_scope(&mut self,
+                                     module_: Rc<Module>,
+                                     name: Name,
+                                     namespace: Namespace)
+                                    -> ResolveResult<(Target, bool)> {
+        debug!("(resolving item in lexical scope) resolving `{}` in \
+                namespace {} in `{}`",
+               token::get_name(name),
+               namespace,
+               self.module_to_string(&*module_));
+
+        // The current module node is handled specially. First, check for
+        // its immediate children.
+        self.populate_module_if_necessary(&module_);
+
+        match module_.children.borrow().get(&name) {
+            Some(name_bindings)
+                    if name_bindings.defined_in_namespace(namespace) => {
+                debug!("top name bindings succeeded");
+                return Success((Target::new(module_.clone(),
+                                            name_bindings.clone(),
+                                            false),
+                               false));
+            }
+            Some(_) | None => { /* Not found; continue. */ }
+        }
+
+        // Now check for its import directives. We don't have to have resolved
+        // all its imports in the usual way; this is because chains of
+        // adjacent import statements are processed as though they mutated the
+        // current scope.
+        if let Some(import_resolution) = module_.import_resolutions.borrow().get(&name) {
+            match (*import_resolution).target_for_namespace(namespace) {
+                None => {
+                    // Not found; continue.
+                    debug!("(resolving item in lexical scope) found \
+                            import resolution, but not in namespace {}",
+                           namespace);
+                }
+                Some(target) => {
+                    debug!("(resolving item in lexical scope) using \
+                            import resolution");
+                    // track used imports and extern crates as well
+                    self.used_imports.insert((import_resolution.id(namespace), namespace));
+                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
+                        self.used_crates.insert(kid);
+                    }
+                    return Success((target, false));
+                }
+            }
+        }
+
+        // Search for external modules.
+        if namespace == TypeNS {
+            if let Some(module) = module_.external_module_children.borrow().get(&name).cloned() {
+                let name_bindings =
+                    Rc::new(Resolver::create_name_bindings_from_module(module));
+                debug!("lower name bindings succeeded");
+                return Success((Target::new(module_, name_bindings, false),
+                                false));
+            }
+        }
+
+        // Finally, proceed up the scope chain looking for parent modules.
+        let mut search_module = module_;
+        loop {
+            // Go to the next parent.
+            match search_module.parent_link.clone() {
+                NoParentLink => {
+                    // No more parents. This module was unresolved.
+                    debug!("(resolving item in lexical scope) unresolved \
+                            module");
+                    return Failed(None);
+                }
+                ModuleParentLink(parent_module_node, _) => {
+                    match search_module.kind.get() {
+                        NormalModuleKind => {
+                            // We stop the search here.
+                            debug!("(resolving item in lexical \
+                                    scope) unresolved module: not \
+                                    searching through module \
+                                    parents");
+                            return Failed(None);
+                        }
+                        TraitModuleKind |
+                        ImplModuleKind |
+                        EnumModuleKind |
+                        AnonymousModuleKind => {
+                            search_module = parent_module_node.upgrade().unwrap();
+                        }
+                    }
+                }
+                BlockParentLink(ref parent_module_node, _) => {
+                    search_module = parent_module_node.upgrade().unwrap();
+                }
+            }
+
+            // Resolve the name in the parent module.
+            match self.resolve_name_in_module(search_module.clone(),
+                                              name,
+                                              namespace,
+                                              PathSearch,
+                                              true) {
+                Failed(Some((span, msg))) =>
+                    self.resolve_error(span, format!("failed to resolve. {}",
+                                                     msg)),
+                Failed(None) => (), // Continue up the search chain.
+                Indeterminate => {
+                    // We couldn't see through the higher scope because of an
+                    // unresolved import higher up. Bail.
+
+                    debug!("(resolving item in lexical scope) indeterminate \
+                            higher scope; bailing");
+                    return Indeterminate;
+                }
+                Success((target, used_reexport)) => {
+                    // We found the module.
+                    debug!("(resolving item in lexical scope) found name \
+                            in module, done");
+                    return Success((target, used_reexport));
+                }
+            }
+        }
+    }
+
+    /// Resolves a module name in the current lexical scope.
+    fn resolve_module_in_lexical_scope(&mut self,
+                                       module_: Rc<Module>,
+                                       name: Name)
+                                -> ResolveResult<Rc<Module>> {
+        // If this module is an anonymous module, resolve the item in the
+        // lexical scope. Otherwise, resolve the item from the crate root.
+        let resolve_result = self.resolve_item_in_lexical_scope(module_, name, TypeNS);
+        match resolve_result {
+            Success((target, _)) => {
+                let bindings = &*target.bindings;
+                match *bindings.type_def.borrow() {
+                    Some(ref type_def) => {
+                        match type_def.module_def {
+                            None => {
+                                debug!("!!! (resolving module in lexical \
+                                        scope) module wasn't actually a \
+                                        module!");
+                                return Failed(None);
+                            }
+                            Some(ref module_def) => {
+                                return Success(module_def.clone());
+                            }
+                        }
+                    }
+                    None => {
+                        debug!("!!! (resolving module in lexical scope) module
+                                wasn't actually a module!");
+                        return Failed(None);
+                    }
+                }
+            }
+            Indeterminate => {
+                debug!("(resolving module in lexical scope) indeterminate; \
+                        bailing");
+                return Indeterminate;
+            }
+            Failed(err) => {
+                debug!("(resolving module in lexical scope) failed to resolve");
+                return Failed(err);
+            }
+        }
+    }
+
+    /// Returns the nearest normal module parent of the given module.
+    fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>)
+                                            -> Option<Rc<Module>> {
+        let mut module_ = module_;
+        loop {
+            match module_.parent_link.clone() {
+                NoParentLink => return None,
+                ModuleParentLink(new_module, _) |
+                BlockParentLink(new_module, _) => {
+                    let new_module = new_module.upgrade().unwrap();
+                    match new_module.kind.get() {
+                        NormalModuleKind => return Some(new_module),
+                        TraitModuleKind |
+                        ImplModuleKind |
+                        EnumModuleKind |
+                        AnonymousModuleKind => module_ = new_module,
+                    }
+                }
+            }
+        }
+    }
+
+    /// Returns the nearest normal module parent of the given module, or the
+    /// module itself if it is a normal module.
+    fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>)
+                                                -> Rc<Module> {
+        match module_.kind.get() {
+            NormalModuleKind => return module_,
+            TraitModuleKind |
+            ImplModuleKind |
+            EnumModuleKind |
+            AnonymousModuleKind => {
+                match self.get_nearest_normal_module_parent(module_.clone()) {
+                    None => module_,
+                    Some(new_module) => new_module
+                }
+            }
+        }
+    }
+
+    /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
+    /// (b) some chain of `super::`.
+    /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
+    fn resolve_module_prefix(&mut self,
+                             module_: Rc<Module>,
+                             module_path: &[Name])
+                                 -> ResolveResult<ModulePrefixResult> {
+        // Start at the current module if we see `self` or `super`, or at the
+        // top of the crate otherwise.
+        let mut containing_module;
+        let mut i;
+        let first_module_path_string = token::get_name(module_path[0]);
+        if "self" == first_module_path_string.get() {
+            containing_module =
+                self.get_nearest_normal_module_parent_or_self(module_);
+            i = 1;
+        } else if "super" == first_module_path_string.get() {
+            containing_module =
+                self.get_nearest_normal_module_parent_or_self(module_);
+            i = 0;  // We'll handle `super` below.
+        } else {
+            return Success(NoPrefixFound);
+        }
+
+        // Now loop through all the `super`s we find.
+        while i < module_path.len() {
+            let string = token::get_name(module_path[i]);
+            if "super" != string.get() {
+                break
+            }
+            debug!("(resolving module prefix) resolving `super` at {}",
+                   self.module_to_string(&*containing_module));
+            match self.get_nearest_normal_module_parent(containing_module) {
+                None => return Failed(None),
+                Some(new_module) => {
+                    containing_module = new_module;
+                    i += 1;
+                }
+            }
+        }
+
+        debug!("(resolving module prefix) finished resolving prefix at {}",
+               self.module_to_string(&*containing_module));
+
+        return Success(PrefixFound(containing_module, i));
+    }
+
+    /// Attempts to resolve the supplied name in the given module for the
+    /// given namespace. If successful, returns the target corresponding to
+    /// the name.
+    ///
+    /// The boolean returned on success is an indicator of whether this lookup
+    /// passed through a public re-export proxy.
+    fn resolve_name_in_module(&mut self,
+                              module_: Rc<Module>,
+                              name: Name,
+                              namespace: Namespace,
+                              name_search_type: NameSearchType,
+                              allow_private_imports: bool)
+                              -> ResolveResult<(Target, bool)> {
+        debug!("(resolving name in module) resolving `{}` in `{}`",
+               token::get_name(name).get(),
+               self.module_to_string(&*module_));
+
+        // First, check the direct children of the module.
+        self.populate_module_if_necessary(&module_);
+
+        match module_.children.borrow().get(&name) {
+            Some(name_bindings)
+                    if name_bindings.defined_in_namespace(namespace) => {
+                debug!("(resolving name in module) found node as child");
+                return Success((Target::new(module_.clone(),
+                                            name_bindings.clone(),
+                                            false),
+                               false));
+            }
+            Some(_) | None => {
+                // Continue.
+            }
+        }
+
+        // Next, check the module's imports if necessary.
+
+        // If this is a search of all imports, we should be done with glob
+        // resolution at this point.
+        if name_search_type == PathSearch {
+            assert_eq!(module_.glob_count.get(), 0);
+        }
+
+        // Check the list of resolved imports.
+        match module_.import_resolutions.borrow().get(&name) {
+            Some(import_resolution) if allow_private_imports ||
+                                       import_resolution.is_public => {
+
+                if import_resolution.is_public &&
+                        import_resolution.outstanding_references != 0 {
+                    debug!("(resolving name in module) import \
+                           unresolved; bailing out");
+                    return Indeterminate;
+                }
+                match import_resolution.target_for_namespace(namespace) {
+                    None => {
+                        debug!("(resolving name in module) name found, \
+                                but not in namespace {}",
+                               namespace);
+                    }
+                    Some(target) => {
+                        debug!("(resolving name in module) resolved to \
+                                import");
+                        // track used imports and extern crates as well
+                        self.used_imports.insert((import_resolution.id(namespace), namespace));
+                        if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
+                            self.used_crates.insert(kid);
+                        }
+                        return Success((target, true));
+                    }
+                }
+            }
+            Some(..) | None => {} // Continue.
+        }
+
+        // Finally, search through external children.
+        if namespace == TypeNS {
+            if let Some(module) = module_.external_module_children.borrow().get(&name).cloned() {
+                let name_bindings =
+                    Rc::new(Resolver::create_name_bindings_from_module(module));
+                return Success((Target::new(module_, name_bindings, false),
+                                false));
+            }
+        }
+
+        // We're out of luck.
+        debug!("(resolving name in module) failed to resolve `{}`",
+               token::get_name(name).get());
+        return Failed(None);
+    }
+
+    fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
+        let index = module_.resolved_import_count.get();
+        let imports = module_.imports.borrow();
+        let import_count = imports.len();
+        if index != import_count {
+            let sn = self.session
+                         .codemap()
+                         .span_to_snippet((*imports)[index].span)
+                         .unwrap();
+            if sn.contains("::") {
+                self.resolve_error((*imports)[index].span,
+                                   "unresolved import");
+            } else {
+                let err = format!("unresolved import (maybe you meant `{}::*`?)",
+                                  sn.slice(0, sn.len()));
+                self.resolve_error((*imports)[index].span, err.as_slice());
+            }
+        }
+
+        // Descend into children and anonymous children.
+        self.populate_module_if_necessary(&module_);
+
+        for (_, child_node) in module_.children.borrow().iter() {
+            match child_node.get_module_if_available() {
+                None => {
+                    // Continue.
+                }
+                Some(child_module) => {
+                    self.report_unresolved_imports(child_module);
+                }
+            }
+        }
+
+        for (_, module_) in module_.anonymous_children.borrow().iter() {
+            self.report_unresolved_imports(module_.clone());
+        }
+    }
+
+    // AST resolution
+    //
+    // We maintain a list of value ribs and type ribs.
+    //
+    // Simultaneously, we keep track of the current position in the module
+    // graph in the `current_module` pointer. When we go to resolve a name in
+    // the value or type namespaces, we first look through all the ribs and
+    // then query the module graph. When we resolve a name in the module
+    // namespace, we can skip all the ribs (since nested modules are not
+    // allowed within blocks in Rust) and jump straight to the current module
+    // graph node.
+    //
+    // Named implementations are handled separately. When we find a method
+    // call, we consult the module node to find all of the implementations in
+    // scope. This information is lazily cached in the module node. We then
+    // generate a fake "implementation scope" containing all the
+    // implementations thus found, for compatibility with old resolve pass.
+
+    fn with_scope<F>(&mut self, name: Option<Name>, f: F) where
+        F: FnOnce(&mut Resolver),
+    {
+        let orig_module = self.current_module.clone();
+
+        // Move down in the graph.
+        match name {
+            None => {
+                // Nothing to do.
+            }
+            Some(name) => {
+                self.populate_module_if_necessary(&orig_module);
+
+                match orig_module.children.borrow().get(&name) {
+                    None => {
+                        debug!("!!! (with scope) didn't find `{}` in `{}`",
+                               token::get_name(name),
+                               self.module_to_string(&*orig_module));
+                    }
+                    Some(name_bindings) => {
+                        match (*name_bindings).get_module_if_available() {
+                            None => {
+                                debug!("!!! (with scope) didn't find module \
+                                        for `{}` in `{}`",
+                                       token::get_name(name),
+                                       self.module_to_string(&*orig_module));
+                            }
+                            Some(module_) => {
+                                self.current_module = module_;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        f(self);
+
+        self.current_module = orig_module;
+    }
+
+    /// Wraps the given definition in the appropriate number of `DefUpvar`
+    /// wrappers.
+    fn upvarify(&self,
+                ribs: &[Rib],
+                def_like: DefLike,
+                span: Span)
+                -> Option<DefLike> {
+        match def_like {
+            DlDef(d @ DefUpvar(..)) => {
+                self.session.span_bug(span,
+                    format!("unexpected {} in bindings", d).as_slice())
+            }
+            DlDef(d @ DefLocal(_)) => {
+                let node_id = d.def_id().node;
+                let mut def = d;
+                let mut last_proc_body_id = ast::DUMMY_NODE_ID;
+                for rib in ribs.iter() {
+                    match rib.kind {
+                        NormalRibKind => {
+                            // Nothing to do. Continue.
+                        }
+                        ClosureRibKind(function_id, maybe_proc_body) => {
+                            let prev_def = def;
+                            if maybe_proc_body != ast::DUMMY_NODE_ID {
+                                last_proc_body_id = maybe_proc_body;
+                            }
+                            def = DefUpvar(node_id, function_id, last_proc_body_id);
+
+                            let mut seen = self.freevars_seen.borrow_mut();
+                            let seen = match seen.entry(function_id) {
+                                Occupied(v) => v.into_mut(),
+                                Vacant(v) => v.set(NodeSet::new()),
+                            };
+                            if seen.contains(&node_id) {
+                                continue;
+                            }
+                            match self.freevars.borrow_mut().entry(function_id) {
+                                Occupied(v) => v.into_mut(),
+                                Vacant(v) => v.set(vec![]),
+                            }.push(Freevar { def: prev_def, span: span });
+                            seen.insert(node_id);
+                        }
+                        MethodRibKind(item_id, _) => {
+                            // If the def is a ty param, and came from the parent
+                            // item, it's ok
+                            match def {
+                                DefTyParam(_, did, _) if {
+                                    self.def_map.borrow().get(&did.node).cloned()
+                                        == Some(DefTyParamBinder(item_id))
+                                } => {} // ok
+                                DefSelfTy(did) if did == item_id => {} // ok
+                                _ => {
+                                    // This was an attempt to access an upvar inside a
+                                    // named function item. This is not allowed, so we
+                                    // report an error.
+
+                                    self.resolve_error(
+                                        span,
+                                        "can't capture dynamic environment in a fn item; \
+                                        use the || { ... } closure form instead");
+
+                                    return None;
+                                }
+                            }
+                        }
+                        ItemRibKind => {
+                            // This was an attempt to access an upvar inside a
+                            // named function item. This is not allowed, so we
+                            // report an error.
+
+                            self.resolve_error(
+                                span,
+                                "can't capture dynamic environment in a fn item; \
+                                use the || { ... } closure form instead");
+
+                            return None;
+                        }
+                        ConstantItemRibKind => {
+                            // Still doesn't deal with upvars
+                            self.resolve_error(span,
+                                               "attempt to use a non-constant \
+                                                value in a constant");
+
+                        }
+                    }
+                }
+                Some(DlDef(def))
+            }
+            DlDef(def @ DefTyParam(..)) |
+            DlDef(def @ DefSelfTy(..)) => {
+                for rib in ribs.iter() {
+                    match rib.kind {
+                        NormalRibKind | ClosureRibKind(..) => {
+                            // Nothing to do. Continue.
+                        }
+                        MethodRibKind(item_id, _) => {
+                            // If the def is a ty param, and came from the parent
+                            // item, it's ok
+                            match def {
+                                DefTyParam(_, did, _) if {
+                                    self.def_map.borrow().get(&did.node).cloned()
+                                        == Some(DefTyParamBinder(item_id))
+                                } => {} // ok
+                                DefSelfTy(did) if did == item_id => {} // ok
+
+                                _ => {
+                                    // This was an attempt to use a type parameter outside
+                                    // its scope.
+
+                                    self.resolve_error(span,
+                                                        "can't use type parameters from \
+                                                        outer function; try using a local \
+                                                        type parameter instead");
+
+                                    return None;
+                                }
+                            }
+                        }
+                        ItemRibKind => {
+                            // This was an attempt to use a type parameter outside
+                            // its scope.
+
+                            self.resolve_error(span,
+                                               "can't use type parameters from \
+                                                outer function; try using a local \
+                                                type parameter instead");
+
+                            return None;
+                        }
+                        ConstantItemRibKind => {
+                            // see #9186
+                            self.resolve_error(span,
+                                               "cannot use an outer type \
+                                                parameter in this context");
+
+                        }
+                    }
+                }
+                Some(DlDef(def))
+            }
+            _ => Some(def_like)
+        }
+    }
+
+    fn search_ribs(&self,
+                   ribs: &[Rib],
+                   name: Name,
+                   span: Span)
+                   -> Option<DefLike> {
+        // FIXME #4950: Try caching?
+
+        for (i, rib) in ribs.iter().enumerate().rev() {
+            match rib.bindings.get(&name).cloned() {
+                Some(def_like) => {
+                    return self.upvarify(ribs[i + 1..], def_like, span);
+                }
+                None => {
+                    // Continue.
+                }
+            }
+        }
+
+        None
+    }
+
+    fn resolve_crate(&mut self, krate: &ast::Crate) {
+        debug!("(resolving crate) starting");
+
+        visit::walk_crate(self, krate);
+    }
+
+    fn resolve_item(&mut self, item: &Item) {
+        let name = item.ident.name;
+
+        debug!("(resolving item) resolving {}",
+               token::get_name(name));
+
+        match item.node {
+
+            // enum item: resolve all the variants' discrs,
+            // then resolve the ty params
+            ItemEnum(ref enum_def, ref generics) => {
+                for variant in (*enum_def).variants.iter() {
+                    for dis_expr in variant.node.disr_expr.iter() {
+                        // resolve the discriminator expr
+                        // as a constant
+                        self.with_constant_rib(|this| {
+                            this.resolve_expr(&**dis_expr);
+                        });
+                    }
+                }
+
+                // n.b. the discr expr gets visited twice.
+                // but maybe it's okay since the first time will signal an
+                // error if there is one? -- tjc
+                self.with_type_parameter_rib(HasTypeParameters(generics,
+                                                               TypeSpace,
+                                                               item.id,
+                                                               ItemRibKind),
+                                             |this| {
+                    this.resolve_type_parameters(&generics.ty_params);
+                    this.resolve_where_clause(&generics.where_clause);
+                    visit::walk_item(this, item);
+                });
+            }
+
+            ItemTy(_, ref generics) => {
+                self.with_type_parameter_rib(HasTypeParameters(generics,
+                                                               TypeSpace,
+                                                               item.id,
+                                                               ItemRibKind),
+                                             |this| {
+                    this.resolve_type_parameters(&generics.ty_params);
+                    visit::walk_item(this, item);
+                });
+            }
+
+            ItemImpl(_,
+                     ref generics,
+                     ref implemented_traits,
+                     ref self_type,
+                     ref impl_items) => {
+                self.resolve_implementation(item.id,
+                                            generics,
+                                            implemented_traits,
+                                            &**self_type,
+                                            impl_items.as_slice());
+            }
+
+            ItemTrait(_, ref generics, ref unbound, ref bounds, ref trait_items) => {
+                // Create a new rib for the self type.
+                let mut self_type_rib = Rib::new(ItemRibKind);
+
+                // plain insert (no renaming, types are not currently hygienic....)
+                let name = self.type_self_name;
+                self_type_rib.bindings.insert(name, DlDef(DefSelfTy(item.id)));
+                self.type_ribs.push(self_type_rib);
+
+                // Create a new rib for the trait-wide type parameters.
+                self.with_type_parameter_rib(HasTypeParameters(generics,
+                                                               TypeSpace,
+                                                               item.id,
+                                                               NormalRibKind),
+                                             |this| {
+                    this.resolve_type_parameters(&generics.ty_params);
+                    this.resolve_where_clause(&generics.where_clause);
+
+                    this.resolve_type_parameter_bounds(item.id, bounds,
+                                                       TraitDerivation);
+
+                    match *unbound {
+                        Some(ref tpb) => {
+                            this.resolve_trait_reference(item.id, tpb, TraitDerivation);
+                        }
+                        None => {}
+                    }
+
+                    for trait_item in (*trait_items).iter() {
+                        // Create a new rib for the trait_item-specific type
+                        // parameters.
+                        //
+                        // FIXME #4951: Do we need a node ID here?
+
+                        match *trait_item {
+                          ast::RequiredMethod(ref ty_m) => {
+                            this.with_type_parameter_rib
+                                (HasTypeParameters(&ty_m.generics,
+                                                   FnSpace,
+                                                   item.id,
+                                        MethodRibKind(item.id, RequiredMethod)),
+                                 |this| {
+
+                                // Resolve the method-specific type
+                                // parameters.
+                                this.resolve_type_parameters(
+                                    &ty_m.generics.ty_params);
+                                this.resolve_where_clause(&ty_m.generics
+                                                               .where_clause);
+
+                                for argument in ty_m.decl.inputs.iter() {
+                                    this.resolve_type(&*argument.ty);
+                                }
+
+                                if let SelfExplicit(ref typ, _) = ty_m.explicit_self.node {
+                                    this.resolve_type(&**typ)
+                                }
+
+                                if let ast::Return(ref ret_ty) = ty_m.decl.output {
+                                    this.resolve_type(&**ret_ty);
+                                }
+                            });
+                          }
+                          ast::ProvidedMethod(ref m) => {
+                              this.resolve_method(MethodRibKind(item.id,
+                                                                ProvidedMethod(m.id)),
+                                                  &**m)
+                          }
+                          ast::TypeTraitItem(ref data) => {
+                              this.resolve_type_parameter(&data.ty_param);
+                              visit::walk_trait_item(this, trait_item);
+                          }
+                        }
+                    }
+                });
+
+                self.type_ribs.pop();
+            }
+
+            ItemStruct(ref struct_def, ref generics) => {
+                self.resolve_struct(item.id,
+                                    generics,
+                                    struct_def.fields.as_slice());
+            }
+
+            ItemMod(ref module_) => {
+                self.with_scope(Some(name), |this| {
+                    this.resolve_module(module_, item.span, name,
+                                        item.id);
+                });
+            }
+
+            ItemForeignMod(ref foreign_module) => {
+                self.with_scope(Some(name), |this| {
+                    for foreign_item in foreign_module.items.iter() {
+                        match foreign_item.node {
+                            ForeignItemFn(_, ref generics) => {
+                                this.with_type_parameter_rib(
+                                    HasTypeParameters(
+                                        generics, FnSpace, foreign_item.id,
+                                        ItemRibKind),
+                                    |this| visit::walk_foreign_item(this,
+                                                                    &**foreign_item));
+                            }
+                            ForeignItemStatic(..) => {
+                                visit::walk_foreign_item(this,
+                                                         &**foreign_item);
+                            }
+                        }
+                    }
+                });
+            }
+
+            ItemFn(ref fn_decl, _, _, ref generics, ref block) => {
+                self.resolve_function(ItemRibKind,
+                                      Some(&**fn_decl),
+                                      HasTypeParameters
+                                        (generics,
+                                         FnSpace,
+                                         item.id,
+                                         ItemRibKind),
+                                      &**block);
+            }
+
+            ItemConst(..) | ItemStatic(..) => {
+                self.with_constant_rib(|this| {
+                    visit::walk_item(this, item);
+                });
+            }
+
+           ItemMac(..) => {
+                // do nothing, these are just around to be encoded
+           }
+        }
+    }
+
+    fn with_type_parameter_rib<F>(&mut self, type_parameters: TypeParameters, f: F) where
+        F: FnOnce(&mut Resolver),
+    {
+        match type_parameters {
+            HasTypeParameters(generics, space, node_id, rib_kind) => {
+                let mut function_type_rib = Rib::new(rib_kind);
+                let mut seen_bindings = HashSet::new();
+                for (index, type_parameter) in generics.ty_params.iter().enumerate() {
+                    let name = type_parameter.ident.name;
+                    debug!("with_type_parameter_rib: {} {}", node_id,
+                           type_parameter.id);
+
+                    if seen_bindings.contains(&name) {
+                        self.resolve_error(type_parameter.span,
+                                           format!("the name `{}` is already \
+                                                    used for a type \
+                                                    parameter in this type \
+                                                    parameter list",
+                                                   token::get_name(
+                                                       name)).as_slice())
+                    }
+                    seen_bindings.insert(name);
+
+                    let def_like = DlDef(DefTyParam(space,
+                                                    local_def(type_parameter.id),
+                                                    index));
+                    // Associate this type parameter with
+                    // the item that bound it
+                    self.record_def(type_parameter.id,
+                                    (DefTyParamBinder(node_id), LastMod(AllPublic)));
+                    // plain insert (no renaming)
+                    function_type_rib.bindings.insert(name, def_like);
+                }
+                self.type_ribs.push(function_type_rib);
+            }
+
+            NoTypeParameters => {
+                // Nothing to do.
+            }
+        }
+
+        f(self);
+
+        match type_parameters {
+            HasTypeParameters(..) => { self.type_ribs.pop(); }
+            NoTypeParameters => { }
+        }
+    }
+
+    fn with_label_rib<F>(&mut self, f: F) where
+        F: FnOnce(&mut Resolver),
+    {
+        self.label_ribs.push(Rib::new(NormalRibKind));
+        f(self);
+        self.label_ribs.pop();
+    }
+
+    fn with_constant_rib<F>(&mut self, f: F) where
+        F: FnOnce(&mut Resolver),
+    {
+        self.value_ribs.push(Rib::new(ConstantItemRibKind));
+        self.type_ribs.push(Rib::new(ConstantItemRibKind));
+        f(self);
+        self.type_ribs.pop();
+        self.value_ribs.pop();
+    }
+
+    fn resolve_function(&mut self,
+                        rib_kind: RibKind,
+                        optional_declaration: Option<&FnDecl>,
+                        type_parameters: TypeParameters,
+                        block: &Block) {
+        // Create a value rib for the function.
+        let function_value_rib = Rib::new(rib_kind);
+        self.value_ribs.push(function_value_rib);
+
+        // Create a label rib for the function.
+        let function_label_rib = Rib::new(rib_kind);
+        self.label_ribs.push(function_label_rib);
+
+        // If this function has type parameters, add them now.
+        self.with_type_parameter_rib(type_parameters, |this| {
+            // Resolve the type parameters.
+            match type_parameters {
+                NoTypeParameters => {
+                    // Continue.
+                }
+                HasTypeParameters(ref generics, _, _, _) => {
+                    this.resolve_type_parameters(&generics.ty_params);
+                    this.resolve_where_clause(&generics.where_clause);
+                }
+            }
+
+            // Add each argument to the rib.
+            match optional_declaration {
+                None => {
+                    // Nothing to do.
+                }
+                Some(declaration) => {
+                    let mut bindings_list = HashMap::new();
+                    for argument in declaration.inputs.iter() {
+                        this.resolve_pattern(&*argument.pat,
+                                             ArgumentIrrefutableMode,
+                                             &mut bindings_list);
+
+                        this.resolve_type(&*argument.ty);
+
+                        debug!("(resolving function) recorded argument");
+                    }
+
+                    if let ast::Return(ref ret_ty) = declaration.output {
+                        this.resolve_type(&**ret_ty);
+                    }
+                }
+            }
+
+            // Resolve the function body.
+            this.resolve_block(&*block);
+
+            debug!("(resolving function) leaving function");
+        });
+
+        self.label_ribs.pop();
+        self.value_ribs.pop();
+    }
+
+    fn resolve_type_parameters(&mut self,
+                               type_parameters: &OwnedSlice<TyParam>) {
+        for type_parameter in type_parameters.iter() {
+            self.resolve_type_parameter(type_parameter);
+        }
+    }
+
+    fn resolve_type_parameter(&mut self,
+                              type_parameter: &TyParam) {
+        for bound in type_parameter.bounds.iter() {
+            self.resolve_type_parameter_bound(type_parameter.id, bound,
+                                              TraitBoundingTypeParameter);
+        }
+        match &type_parameter.unbound {
+            &Some(ref unbound) =>
+                self.resolve_trait_reference(
+                    type_parameter.id, unbound, TraitBoundingTypeParameter),
+            &None => {}
+        }
+        match type_parameter.default {
+            Some(ref ty) => self.resolve_type(&**ty),
+            None => {}
+        }
+    }
+
+    fn resolve_type_parameter_bounds(&mut self,
+                                     id: NodeId,
+                                     type_parameter_bounds: &OwnedSlice<TyParamBound>,
+                                     reference_type: TraitReferenceType) {
+        for type_parameter_bound in type_parameter_bounds.iter() {
+            self.resolve_type_parameter_bound(id, type_parameter_bound,
+                                              reference_type);
+        }
+    }
+
+    fn resolve_type_parameter_bound(&mut self,
+                                    id: NodeId,
+                                    type_parameter_bound: &TyParamBound,
+                                    reference_type: TraitReferenceType) {
+        match *type_parameter_bound {
+            TraitTyParamBound(ref tref) => {
+                self.resolve_poly_trait_reference(id, tref, reference_type)
+            }
+            RegionTyParamBound(..) => {}
+        }
+    }
+
+    fn resolve_poly_trait_reference(&mut self,
+                                    id: NodeId,
+                                    poly_trait_reference: &PolyTraitRef,
+                                    reference_type: TraitReferenceType) {
+        self.resolve_trait_reference(id, &poly_trait_reference.trait_ref, reference_type)
+    }
+
+    fn resolve_trait_reference(&mut self,
+                               id: NodeId,
+                               trait_reference: &TraitRef,
+                               reference_type: TraitReferenceType) {
+        match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
+            None => {
+                let path_str = self.path_names_to_string(&trait_reference.path);
+                let usage_str = match reference_type {
+                    TraitBoundingTypeParameter => "bound type parameter with",
+                    TraitImplementation        => "implement",
+                    TraitDerivation            => "derive",
+                    TraitObject                => "reference",
+                    TraitQPath                 => "extract an associated type from",
+                };
+
+                let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
+                self.resolve_error(trait_reference.path.span, msg.as_slice());
+            }
+            Some(def) => {
+                match def {
+                    (DefTrait(_), _) => {
+                        debug!("(resolving trait) found trait def: {}", def);
+                        self.record_def(trait_reference.ref_id, def);
+                    }
+                    (def, _) => {
+                        self.resolve_error(trait_reference.path.span,
+                                           format!("`{}` is not a trait",
+                                                   self.path_names_to_string(
+                                                       &trait_reference.path)));
+
+                        // If it's a typedef, give a note
+                        if let DefTy(..) = def {
+                            self.session.span_note(
+                                trait_reference.path.span,
+                                format!("`type` aliases cannot be used for traits")
+                                    .as_slice());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    fn resolve_where_clause(&mut self, where_clause: &ast::WhereClause) {
+        for predicate in where_clause.predicates.iter() {
+            match predicate {
+                &ast::WherePredicate::BoundPredicate(ref bound_pred) => {
+                    self.resolve_type(&*bound_pred.bounded_ty);
+
+                    for bound in bound_pred.bounds.iter() {
+                        self.resolve_type_parameter_bound(bound_pred.bounded_ty.id, bound,
+                                                          TraitBoundingTypeParameter);
+                    }
+                }
+                &ast::WherePredicate::RegionPredicate(_) => {}
+                &ast::WherePredicate::EqPredicate(ref eq_pred) => {
+                    match self.resolve_path(eq_pred.id, &eq_pred.path, TypeNS, true) {
+                        Some((def @ DefTyParam(..), last_private)) => {
+                            self.record_def(eq_pred.id, (def, last_private));
+                        }
+                        _ => {
+                            self.resolve_error(eq_pred.path.span,
+                                               "undeclared associated type");
+                        }
+                    }
+
+                    self.resolve_type(&*eq_pred.ty);
+                }
+            }
+        }
+    }
+
+    fn resolve_struct(&mut self,
+                      id: NodeId,
+                      generics: &Generics,
+                      fields: &[StructField]) {
+        // If applicable, create a rib for the type parameters.
+        self.with_type_parameter_rib(HasTypeParameters(generics,
+                                                       TypeSpace,
+                                                       id,
+                                                       ItemRibKind),
+                                     |this| {
+            // Resolve the type parameters.
+            this.resolve_type_parameters(&generics.ty_params);
+            this.resolve_where_clause(&generics.where_clause);
+
+            // Resolve fields.
+            for field in fields.iter() {
+                this.resolve_type(&*field.node.ty);
+            }
+        });
+    }
+
+    // Does this really need to take a RibKind or is it always going
+    // to be NormalRibKind?
+    fn resolve_method(&mut self,
+                      rib_kind: RibKind,
+                      method: &ast::Method) {
+        let method_generics = method.pe_generics();
+        let type_parameters = HasTypeParameters(method_generics,
+                                                FnSpace,
+                                                method.id,
+                                                rib_kind);
+
+        if let SelfExplicit(ref typ, _) = method.pe_explicit_self().node {
+            self.resolve_type(&**typ);
+        }
+
+        self.resolve_function(rib_kind,
+                              Some(method.pe_fn_decl()),
+                              type_parameters,
+                              method.pe_body());
+    }
+
+    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T where
+        F: FnOnce(&mut Resolver) -> T,
+    {
+        // Handle nested impls (inside fn bodies)
+        let previous_value = replace(&mut self.current_self_type, Some(self_type.clone()));
+        let result = f(self);
+        self.current_self_type = previous_value;
+        result
+    }
+
+    fn with_optional_trait_ref<T, F>(&mut self, id: NodeId,
+                                     opt_trait_ref: &Option<TraitRef>,
+                                     f: F) -> T where
+        F: FnOnce(&mut Resolver) -> T,
+    {
+        let new_val = match *opt_trait_ref {
+            Some(ref trait_ref) => {
+                self.resolve_trait_reference(id, trait_ref, TraitImplementation);
+
+                match self.def_map.borrow().get(&trait_ref.ref_id) {
+                    Some(def) => {
+                        let did = def.def_id();
+                        Some((did, trait_ref.clone()))
+                    }
+                    None => None
+                }
+            }
+            None => None
+        };
+        let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
+        let result = f(self);
+        self.current_trait_ref = original_trait_ref;
+        result
+    }
+
+    fn resolve_implementation(&mut self,
+                              id: NodeId,
+                              generics: &Generics,
+                              opt_trait_reference: &Option<TraitRef>,
+                              self_type: &Ty,
+                              impl_items: &[ImplItem]) {
+        // If applicable, create a rib for the type parameters.
+        self.with_type_parameter_rib(HasTypeParameters(generics,
+                                                       TypeSpace,
+                                                       id,
+                                                       NormalRibKind),
+                                     |this| {
+            // Resolve the type parameters.
+            this.resolve_type_parameters(&generics.ty_params);
+            this.resolve_where_clause(&generics.where_clause);
+
+            // Resolve the trait reference, if necessary.
+            this.with_optional_trait_ref(id, opt_trait_reference, |this| {
+                // Resolve the self type.
+                this.resolve_type(self_type);
+
+                this.with_current_self_type(self_type, |this| {
+                    for impl_item in impl_items.iter() {
+                        match *impl_item {
+                            MethodImplItem(ref method) => {
+                                // If this is a trait impl, ensure the method
+                                // exists in trait
+                                this.check_trait_item(method.pe_ident().name,
+                                                      method.span);
+
+                                // We also need a new scope for the method-
+                                // specific type parameters.
+                                this.resolve_method(
+                                    MethodRibKind(id, ProvidedMethod(method.id)),
+                                    &**method);
+                            }
+                            TypeImplItem(ref typedef) => {
+                                // If this is a trait impl, ensure the method
+                                // exists in trait
+                                this.check_trait_item(typedef.ident.name,
+                                                      typedef.span);
+
+                                this.resolve_type(&*typedef.typ);
+                            }
+                        }
+                    }
+                });
+            });
+        });
+
+        // Check that the current type is indeed a type, if we have an anonymous impl
+        if opt_trait_reference.is_none() {
+            match self_type.node {
+                // TyPath is the only thing that we handled in `build_reduced_graph_for_item`,
+                // where we created a module with the name of the type in order to implement
+                // an anonymous trait. In the case that the path does not resolve to an actual
+                // type, the result will be that the type name resolves to a module but not
+                // a type (shadowing any imported modules or types with this name), leading
+                // to weird user-visible bugs. So we ward this off here. See #15060.
+                TyPath(ref path, path_id) => {
+                    match self.def_map.borrow().get(&path_id) {
+                        // FIXME: should we catch other options and give more precise errors?
+                        Some(&DefMod(_)) => {
+                            self.resolve_error(path.span, "inherent implementations are not \
+                                                           allowed for types not defined in \
+                                                           the current module");
+                        }
+                        _ => {}
+                    }
+                }
+                _ => { }
+            }
+        }
+    }
+
+    fn check_trait_item(&self, name: Name, span: Span) {
+        // If there is a TraitRef in scope for an impl, then the method must be in the trait.
+        for &(did, ref trait_ref) in self.current_trait_ref.iter() {
+            if self.trait_item_map.get(&(name, did)).is_none() {
+                let path_str = self.path_names_to_string(&trait_ref.path);
+                self.resolve_error(span,
+                                    format!("method `{}` is not a member of trait `{}`",
+                                            token::get_name(name),
+                                            path_str).as_slice());
+            }
+        }
+    }
+
+    fn resolve_module(&mut self, module: &Mod, _span: Span,
+                      _name: Name, id: NodeId) {
+        // Write the implementations in scope into the module metadata.
+        debug!("(resolving module) resolving module ID {}", id);
+        visit::walk_mod(self, module);
+    }
+
+    fn resolve_local(&mut self, local: &Local) {
+        // Resolve the type.
+        self.resolve_type(&*local.ty);
+
+        // Resolve the initializer, if necessary.
+        match local.init {
+            None => {
+                // Nothing to do.
+            }
+            Some(ref initializer) => {
+                self.resolve_expr(&**initializer);
+            }
+        }
+
+        // Resolve the pattern.
+        let mut bindings_list = HashMap::new();
+        self.resolve_pattern(&*local.pat,
+                             LocalIrrefutableMode,
+                             &mut bindings_list);
+    }
+
+    // build a map from pattern identifiers to binding-info's.
+    // this is done hygienically. This could arise for a macro
+    // that expands into an or-pattern where one 'x' was from the
+    // user and one 'x' came from the macro.
+    fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
+        let mut result = HashMap::new();
+        pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
+            let name = mtwt::resolve(path1.node);
+            result.insert(name, BindingInfo {
+                span: sp,
+                binding_mode: binding_mode
+            });
+        });
+        return result;
+    }
+
+    // check that all of the arms in an or-pattern have exactly the
+    // same set of bindings, with the same binding modes for each.
+    fn check_consistent_bindings(&mut self, arm: &Arm) {
+        if arm.pats.len() == 0 {
+            return
+        }
+        let map_0 = self.binding_mode_map(&*arm.pats[0]);
+        for (i, p) in arm.pats.iter().enumerate() {
+            let map_i = self.binding_mode_map(&**p);
+
+            for (&key, &binding_0) in map_0.iter() {
+                match map_i.get(&key) {
+                  None => {
+                    self.resolve_error(
+                        p.span,
+                        format!("variable `{}` from pattern #1 is \
+                                  not bound in pattern #{}",
+                                token::get_name(key),
+                                i + 1).as_slice());
+                  }
+                  Some(binding_i) => {
+                    if binding_0.binding_mode != binding_i.binding_mode {
+                        self.resolve_error(
+                            binding_i.span,
+                            format!("variable `{}` is bound with different \
+                                      mode in pattern #{} than in pattern #1",
+                                    token::get_name(key),
+                                    i + 1).as_slice());
+                    }
+                  }
+                }
+            }
+
+            for (&key, &binding) in map_i.iter() {
+                if !map_0.contains_key(&key) {
+                    self.resolve_error(
+                        binding.span,
+                        format!("variable `{}` from pattern {}{} is \
+                                  not bound in pattern {}1",
+                                token::get_name(key),
+                                "#", i + 1, "#").as_slice());
+                }
+            }
+        }
+    }
+
+    fn resolve_arm(&mut self, arm: &Arm) {
+        self.value_ribs.push(Rib::new(NormalRibKind));
+
+        let mut bindings_list = HashMap::new();
+        for pattern in arm.pats.iter() {
+            self.resolve_pattern(&**pattern, RefutableMode, &mut bindings_list);
+        }
+
+        // This has to happen *after* we determine which
+        // pat_idents are variants
+        self.check_consistent_bindings(arm);
+
+        visit::walk_expr_opt(self, &arm.guard);
+        self.resolve_expr(&*arm.body);
+
+        self.value_ribs.pop();
+    }
+
+    fn resolve_block(&mut self, block: &Block) {
+        debug!("(resolving block) entering block");
+        self.value_ribs.push(Rib::new(NormalRibKind));
+
+        // Move down in the graph, if there's an anonymous module rooted here.
+        let orig_module = self.current_module.clone();
+        match orig_module.anonymous_children.borrow().get(&block.id) {
+            None => { /* Nothing to do. */ }
+            Some(anonymous_module) => {
+                debug!("(resolving block) found anonymous module, moving \
+                        down");
+                self.current_module = anonymous_module.clone();
+            }
+        }
+
+        // Descend into the block.
+        visit::walk_block(self, block);
+
+        // Move back up.
+        self.current_module = orig_module;
+
+        self.value_ribs.pop();
+        debug!("(resolving block) leaving block");
+    }
+
+    fn resolve_type(&mut self, ty: &Ty) {
+        match ty.node {
+            // Like path expressions, the interpretation of path types depends
+            // on whether the path has multiple elements in it or not.
+
+            TyPath(ref path, path_id) => {
+                // This is a path in the type namespace. Walk through scopes
+                // looking for it.
+                let mut result_def = None;
+
+                // First, check to see whether the name is a primitive type.
+                if path.segments.len() == 1 {
+                    let id = path.segments.last().unwrap().identifier;
+
+                    match self.primitive_type_table
+                            .primitive_types
+                            .get(&id.name) {
+
+                        Some(&primitive_type) => {
+                            result_def =
+                                Some((DefPrimTy(primitive_type), LastMod(AllPublic)));
+
+                            if path.segments[0].parameters.has_lifetimes() {
+                                span_err!(self.session, path.span, E0157,
+                                    "lifetime parameters are not allowed on this type");
+                            } else if !path.segments[0].parameters.is_empty() {
+                                span_err!(self.session, path.span, E0153,
+                                    "type parameters are not allowed on this type");
+                            }
+                        }
+                        None => {
+                            // Continue.
+                        }
+                    }
+                }
+
+                match result_def {
+                    None => {
+                        match self.resolve_path(ty.id, path, TypeNS, true) {
+                            Some(def) => {
+                                debug!("(resolving type) resolved `{}` to \
+                                        type {}",
+                                       token::get_ident(path.segments
+                                                            .last().unwrap()
+                                                            .identifier),
+                                       def);
+                                result_def = Some(def);
+                            }
+                            None => {
+                                result_def = None;
+                            }
+                        }
+                    }
+                    Some(_) => {}   // Continue.
+                }
+
+                match result_def {
+                    Some(def) => {
+                        // Write the result into the def map.
+                        debug!("(resolving type) writing resolution for `{}` \
+                                (id {})",
+                               self.path_names_to_string(path),
+                               path_id);
+                        self.record_def(path_id, def);
+                    }
+                    None => {
+                        let msg = format!("use of undeclared type name `{}`",
+                                          self.path_names_to_string(path));
+                        self.resolve_error(ty.span, msg.as_slice());
+                    }
+                }
+            }
+
+            TyObjectSum(ref ty, ref bound_vec) => {
+                self.resolve_type(&**ty);
+                self.resolve_type_parameter_bounds(ty.id, bound_vec,
+                                                       TraitBoundingTypeParameter);
+            }
+
+            TyQPath(ref qpath) => {
+                self.resolve_type(&*qpath.self_type);
+                self.resolve_trait_reference(ty.id, &*qpath.trait_ref, TraitQPath);
+            }
+
+            TyClosure(ref c) => {
+                self.resolve_type_parameter_bounds(
+                    ty.id,
+                    &c.bounds,
+                    TraitBoundingTypeParameter);
+                visit::walk_ty(self, ty);
+            }
+
+            TyPolyTraitRef(ref bounds) => {
+                self.resolve_type_parameter_bounds(
+                    ty.id,
+                    bounds,
+                    TraitObject);
+                visit::walk_ty(self, ty);
+            }
+            _ => {
+                // Just resolve embedded types.
+                visit::walk_ty(self, ty);
+            }
+        }
+    }
+
+    fn resolve_pattern(&mut self,
+                       pattern: &Pat,
+                       mode: PatternBindingMode,
+                       // Maps idents to the node ID for the (outermost)
+                       // pattern that binds them
+                       bindings_list: &mut HashMap<Name, NodeId>) {
+        let pat_id = pattern.id;
+        walk_pat(pattern, |pattern| {
+            match pattern.node {
+                PatIdent(binding_mode, ref path1, _) => {
+
+                    // The meaning of pat_ident with no type parameters
+                    // depends on whether an enum variant or unit-like struct
+                    // with that name is in scope. The probing lookup has to
+                    // be careful not to emit spurious errors. Only matching
+                    // patterns (match) can match nullary variants or
+                    // unit-like structs. For binding patterns (let), matching
+                    // such a value is simply disallowed (since it's rarely
+                    // what you want).
+
+                    let ident = path1.node;
+                    let renamed = mtwt::resolve(ident);
+
+                    match self.resolve_bare_identifier_pattern(ident.name, pattern.span) {
+                        FoundStructOrEnumVariant(ref def, lp)
+                                if mode == RefutableMode => {
+                            debug!("(resolving pattern) resolving `{}` to \
+                                    struct or enum variant",
+                                   token::get_name(renamed));
+
+                            self.enforce_default_binding_mode(
+                                pattern,
+                                binding_mode,
+                                "an enum variant");
+                            self.record_def(pattern.id, (def.clone(), lp));
+                        }
+                        FoundStructOrEnumVariant(..) => {
+                            self.resolve_error(
+                                pattern.span,
+                                format!("declaration of `{}` shadows an enum \
+                                         variant or unit-like struct in \
+                                         scope",
+                                        token::get_name(renamed)).as_slice());
+                        }
+                        FoundConst(ref def, lp) if mode == RefutableMode => {
+                            debug!("(resolving pattern) resolving `{}` to \
+                                    constant",
+                                   token::get_name(renamed));
+
+                            self.enforce_default_binding_mode(
+                                pattern,
+                                binding_mode,
+                                "a constant");
+                            self.record_def(pattern.id, (def.clone(), lp));
+                        }
+                        FoundConst(..) => {
+                            self.resolve_error(pattern.span,
+                                                  "only irrefutable patterns \
+                                                   allowed here");
+                        }
+                        BareIdentifierPatternUnresolved => {
+                            debug!("(resolving pattern) binding `{}`",
+                                   token::get_name(renamed));
+
+                            let def = DefLocal(pattern.id);
+
+                            // Record the definition so that later passes
+                            // will be able to distinguish variants from
+                            // locals in patterns.
+
+                            self.record_def(pattern.id, (def, LastMod(AllPublic)));
+
+                            // Add the binding to the local ribs, if it
+                            // doesn't already exist in the bindings list. (We
+                            // must not add it if it's in the bindings list
+                            // because that breaks the assumptions later
+                            // passes make about or-patterns.)
+                            if !bindings_list.contains_key(&renamed) {
+                                let this = &mut *self;
+                                let last_rib = this.value_ribs.last_mut().unwrap();
+                                last_rib.bindings.insert(renamed, DlDef(def));
+                                bindings_list.insert(renamed, pat_id);
+                            } else if mode == ArgumentIrrefutableMode &&
+                                    bindings_list.contains_key(&renamed) {
+                                // Forbid duplicate bindings in the same
+                                // parameter list.
+                                self.resolve_error(pattern.span,
+                                                   format!("identifier `{}` \
+                                                            is bound more \
+                                                            than once in \
+                                                            this parameter \
+                                                            list",
+                                                           token::get_ident(
+                                                               ident))
+                                                   .as_slice())
+                            } else if bindings_list.get(&renamed) ==
+                                    Some(&pat_id) {
+                                // Then this is a duplicate variable in the
+                                // same disjunction, which is an error.
+                                self.resolve_error(pattern.span,
+                                    format!("identifier `{}` is bound \
+                                             more than once in the same \
+                                             pattern",
+                                            token::get_ident(ident)).as_slice());
+                            }
+                            // Else, not bound in the same pattern: do
+                            // nothing.
+                        }
+                    }
+                }
+
+                PatEnum(ref path, _) => {
+                    // This must be an enum variant, struct or const.
+                    match self.resolve_path(pat_id, path, ValueNS, false) {
+                        Some(def @ (DefVariant(..), _)) |
+                        Some(def @ (DefStruct(..), _))  |
+                        Some(def @ (DefConst(..), _)) => {
+                            self.record_def(pattern.id, def);
+                        }
+                        Some((DefStatic(..), _)) => {
+                            self.resolve_error(path.span,
+                                               "static variables cannot be \
+                                                referenced in a pattern, \
+                                                use a `const` instead");
+                        }
+                        Some(_) => {
+                            self.resolve_error(path.span,
+                                format!("`{}` is not an enum variant, struct or const",
+                                    token::get_ident(
+                                        path.segments
+                                            .last()
+                                            .unwrap()
+                                            .identifier)).as_slice());
+                        }
+                        None => {
+                            self.resolve_error(path.span,
+                                format!("unresolved enum variant, struct or const `{}`",
+                                    token::get_ident(
+                                        path.segments
+                                            .last()
+                                            .unwrap()
+                                            .identifier)).as_slice());
+                        }
+                    }
+
+                    // Check the types in the path pattern.
+                    for ty in path.segments
+                                  .iter()
+                                  .flat_map(|s| s.parameters.types().into_iter()) {
+                        self.resolve_type(&**ty);
+                    }
+                }
+
+                PatLit(ref expr) => {
+                    self.resolve_expr(&**expr);
+                }
+
+                PatRange(ref first_expr, ref last_expr) => {
+                    self.resolve_expr(&**first_expr);
+                    self.resolve_expr(&**last_expr);
+                }
+
+                PatStruct(ref path, _, _) => {
+                    match self.resolve_path(pat_id, path, TypeNS, false) {
+                        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_names_to_string(path));
+                            self.resolve_error(path.span, msg.as_slice());
+                        }
+                    }
+                }
+
+                _ => {
+                    // Nothing to do.
+                }
+            }
+            true
+        });
+    }
+
+    fn resolve_bare_identifier_pattern(&mut self, name: Name, span: Span)
+                                       -> BareIdentifierPatternResolution {
+        let module = self.current_module.clone();
+        match self.resolve_item_in_lexical_scope(module,
+                                                 name,
+                                                 ValueNS) {
+            Success((target, _)) => {
+                debug!("(resolve bare identifier pattern) succeeded in \
+                         finding {} at {}",
+                        token::get_name(name),
+                        target.bindings.value_def.borrow());
+                match *target.bindings.value_def.borrow() {
+                    None => {
+                        panic!("resolved name in the value namespace to a \
+                              set of name bindings with no def?!");
+                    }
+                    Some(def) => {
+                        // For the two success cases, this lookup can be
+                        // considered as not having a private component because
+                        // the lookup happened only within the current module.
+                        match def.def {
+                            def @ DefVariant(..) | def @ DefStruct(..) => {
+                                return FoundStructOrEnumVariant(def, LastMod(AllPublic));
+                            }
+                            def @ DefConst(..) => {
+                                return FoundConst(def, LastMod(AllPublic));
+                            }
+                            DefStatic(..) => {
+                                self.resolve_error(span,
+                                                   "static variables cannot be \
+                                                    referenced in a pattern, \
+                                                    use a `const` instead");
+                                return BareIdentifierPatternUnresolved;
+                            }
+                            _ => {
+                                return BareIdentifierPatternUnresolved;
+                            }
+                        }
+                    }
+                }
+            }
+
+            Indeterminate => {
+                panic!("unexpected indeterminate result");
+            }
+            Failed(err) => {
+                match err {
+                    Some((span, msg)) => {
+                        self.resolve_error(span, format!("failed to resolve: {}",
+                                                         msg));
+                    }
+                    None => ()
+                }
+
+                debug!("(resolve bare identifier pattern) failed to find {}",
+                        token::get_name(name));
+                return BareIdentifierPatternUnresolved;
+            }
+        }
+    }
+
+    /// If `check_ribs` is true, checks the local definitions first; i.e.
+    /// doesn't skip straight to the containing module.
+    fn resolve_path(&mut self,
+                    id: NodeId,
+                    path: &Path,
+                    namespace: Namespace,
+                    check_ribs: bool) -> Option<(Def, LastPrivate)> {
+        // First, resolve the types and associated type bindings.
+        for ty in path.segments.iter().flat_map(|s| s.parameters.types().into_iter()) {
+            self.resolve_type(&**ty);
+        }
+        for binding in path.segments.iter().flat_map(|s| s.parameters.bindings().into_iter()) {
+            self.resolve_type(&*binding.ty);
+        }
+
+        // A special case for sugared associated type paths `T::A` where `T` is
+        // a type parameter and `A` is an associated type on some bound of `T`.
+        if namespace == TypeNS && path.segments.len() == 2 {
+            match self.resolve_identifier(path.segments[0].identifier,
+                                          TypeNS,
+                                          true,
+                                          path.span) {
+                Some((def, last_private)) => {
+                    match def {
+                        DefTyParam(_, did, _) => {
+                            let def = DefAssociatedPath(TyParamProvenance::FromParam(did),
+                                                        path.segments.last()
+                                                            .unwrap().identifier);
+                            return Some((def, last_private));
+                        }
+                        DefSelfTy(nid) => {
+                            let def = DefAssociatedPath(TyParamProvenance::FromSelf(local_def(nid)),
+                                                        path.segments.last()
+                                                            .unwrap().identifier);
+                            return Some((def, last_private));
+                        }
+                        _ => {}
+                    }
+                }
+                _ => {}
+            }
+        }
+
+        if path.global {
+            return self.resolve_crate_relative_path(path, namespace);
+        }
+
+        // Try to find a path to an item in a module.
+        let unqualified_def =
+                self.resolve_identifier(path.segments
+                                            .last().unwrap()
+                                            .identifier,
+                                        namespace,
+                                        check_ribs,
+                                        path.span);
+
+        if path.segments.len() > 1 {
+            let def = self.resolve_module_relative_path(path, namespace);
+            match (def, unqualified_def) {
+                (Some((ref d, _)), Some((ref ud, _))) if *d == *ud => {
+                    self.session
+                        .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
+                                  id,
+                                  path.span,
+                                  "unnecessary qualification".to_string());
+                }
+                _ => ()
+            }
+
+            return def;
+        }
+
+        return unqualified_def;
+    }
+
+    // resolve a single identifier (used as a varref)
+    fn resolve_identifier(&mut self,
+                          identifier: Ident,
+                          namespace: Namespace,
+                          check_ribs: bool,
+                          span: Span)
+                          -> Option<(Def, LastPrivate)> {
+        if check_ribs {
+            match self.resolve_identifier_in_local_ribs(identifier,
+                                                        namespace,
+                                                        span) {
+                Some(def) => {
+                    return Some((def, LastMod(AllPublic)));
+                }
+                None => {
+                    // Continue.
+                }
+            }
+        }
+
+        return self.resolve_item_by_name_in_lexical_scope(identifier.name, namespace);
+    }
+
+    // FIXME #4952: Merge me with resolve_name_in_module?
+    fn resolve_definition_of_name_in_module(&mut self,
+                                            containing_module: Rc<Module>,
+                                            name: Name,
+                                            namespace: Namespace)
+                                            -> NameDefinition {
+        // First, search children.
+        self.populate_module_if_necessary(&containing_module);
+
+        match containing_module.children.borrow().get(&name) {
+            Some(child_name_bindings) => {
+                match child_name_bindings.def_for_namespace(namespace) {
+                    Some(def) => {
+                        // Found it. Stop the search here.
+                        let p = child_name_bindings.defined_in_public_namespace(
+                                        namespace);
+                        let lp = if p {LastMod(AllPublic)} else {
+                            LastMod(DependsOn(def.def_id()))
+                        };
+                        return ChildNameDefinition(def, lp);
+                    }
+                    None => {}
+                }
+            }
+            None => {}
+        }
+
+        // Next, search import resolutions.
+        match containing_module.import_resolutions.borrow().get(&name) {
+            Some(import_resolution) if import_resolution.is_public => {
+                if let Some(target) = (*import_resolution).target_for_namespace(namespace) {
+                    match target.bindings.def_for_namespace(namespace) {
+                        Some(def) => {
+                            // Found it.
+                            let id = import_resolution.id(namespace);
+                            // track imports and extern crates as well
+                            self.used_imports.insert((id, namespace));
+                            match target.target_module.def_id.get() {
+                                Some(DefId{krate: kid, ..}) => {
+                                    self.used_crates.insert(kid);
+                                },
+                                _ => {}
+                            }
+                            return ImportNameDefinition(def, LastMod(AllPublic));
+                        }
+                        None => {
+                            // This can happen with external impls, due to
+                            // the imperfect way we read the metadata.
+                        }
+                    }
+                }
+            }
+            Some(..) | None => {} // Continue.
+        }
+
+        // Finally, search through external children.
+        if namespace == TypeNS {
+            if let Some(module) = containing_module.external_module_children.borrow()
+                                                   .get(&name).cloned() {
+                if let Some(def_id) = module.def_id.get() {
+                    // track used crates
+                    self.used_crates.insert(def_id.krate);
+                    let lp = if module.is_public {LastMod(AllPublic)} else {
+                        LastMod(DependsOn(def_id))
+                    };
+                    return ChildNameDefinition(DefMod(def_id), lp);
+                }
+            }
+        }
+
+        return NoNameDefinition;
+    }
+
+    // resolve a "module-relative" path, e.g. a::b::c
+    fn resolve_module_relative_path(&mut self,
+                                    path: &Path,
+                                    namespace: Namespace)
+                                    -> Option<(Def, LastPrivate)> {
+        let module_path = path.segments.init().iter()
+                                              .map(|ps| ps.identifier.name)
+                                              .collect::<Vec<_>>();
+
+        let containing_module;
+        let last_private;
+        let module = self.current_module.clone();
+        match self.resolve_module_path(module,
+                                       module_path.as_slice(),
+                                       UseLexicalScope,
+                                       path.span,
+                                       PathSearch) {
+            Failed(err) => {
+                let (span, msg) = match err {
+                    Some((span, msg)) => (span, msg),
+                    None => {
+                        let msg = format!("Use of undeclared type or module `{}`",
+                                          self.names_to_string(module_path.as_slice()));
+                        (path.span, msg)
+                    }
+                };
+
+                self.resolve_error(span, format!("failed to resolve. {}",
+                                                 msg.as_slice()));
+                return None;
+            }
+            Indeterminate => panic!("indeterminate unexpected"),
+            Success((resulting_module, resulting_last_private)) => {
+                containing_module = resulting_module;
+                last_private = resulting_last_private;
+            }
+        }
+
+        let name = path.segments.last().unwrap().identifier.name;
+        let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
+                                                                  name,
+                                                                  namespace) {
+            NoNameDefinition => {
+                // We failed to resolve the name. Report an error.
+                return None;
+            }
+            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
+                (def, last_private.or(lp))
+            }
+        };
+        if let Some(DefId{krate: kid, ..}) = containing_module.def_id.get() {
+            self.used_crates.insert(kid);
+        }
+        return Some(def);
+    }
+
+    /// Invariant: This must be called only during main resolution, not during
+    /// import resolution.
+    fn resolve_crate_relative_path(&mut self,
+                                   path: &Path,
+                                   namespace: Namespace)
+                                       -> Option<(Def, LastPrivate)> {
+        let module_path = path.segments.init().iter()
+                                              .map(|ps| ps.identifier.name)
+                                              .collect::<Vec<_>>();
+
+        let root_module = self.graph_root.get_module();
+
+        let containing_module;
+        let last_private;
+        match self.resolve_module_path_from_root(root_module,
+                                                 module_path.as_slice(),
+                                                 0,
+                                                 path.span,
+                                                 PathSearch,
+                                                 LastMod(AllPublic)) {
+            Failed(err) => {
+                let (span, msg) = match err {
+                    Some((span, msg)) => (span, msg),
+                    None => {
+                        let msg = format!("Use of undeclared module `::{}`",
+                                          self.names_to_string(module_path.as_slice()));
+                        (path.span, msg)
+                    }
+                };
+
+                self.resolve_error(span, format!("failed to resolve. {}",
+                                                 msg.as_slice()));
+                return None;
+            }
+
+            Indeterminate => {
+                panic!("indeterminate unexpected");
+            }
+
+            Success((resulting_module, resulting_last_private)) => {
+                containing_module = resulting_module;
+                last_private = resulting_last_private;
+            }
+        }
+
+        let name = path.segments.last().unwrap().identifier.name;
+        match self.resolve_definition_of_name_in_module(containing_module,
+                                                        name,
+                                                        namespace) {
+            NoNameDefinition => {
+                // We failed to resolve the name. Report an error.
+                return None;
+            }
+            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
+                return Some((def, last_private.or(lp)));
+            }
+        }
+    }
+
+    fn resolve_identifier_in_local_ribs(&mut self,
+                                        ident: Ident,
+                                        namespace: Namespace,
+                                        span: Span)
+                                        -> Option<Def> {
+        // Check the local set of ribs.
+        let search_result = match namespace {
+            ValueNS => {
+                let renamed = mtwt::resolve(ident);
+                self.search_ribs(self.value_ribs.as_slice(), renamed, span)
+            }
+            TypeNS => {
+                let name = ident.name;
+                self.search_ribs(self.type_ribs.as_slice(), name, span)
+            }
+        };
+
+        match search_result {
+            Some(DlDef(def)) => {
+                debug!("(resolving path in local ribs) resolved `{}` to \
+                        local: {}",
+                       token::get_ident(ident),
+                       def);
+                return Some(def);
+            }
+            Some(DlField) | Some(DlImpl(_)) | None => {
+                return None;
+            }
+        }
+    }
+
+    fn resolve_item_by_name_in_lexical_scope(&mut self,
+                                             name: Name,
+                                             namespace: Namespace)
+                                            -> Option<(Def, LastPrivate)> {
+        // Check the items.
+        let module = self.current_module.clone();
+        match self.resolve_item_in_lexical_scope(module,
+                                                 name,
+                                                 namespace) {
+            Success((target, _)) => {
+                match (*target.bindings).def_for_namespace(namespace) {
+                    None => {
+                        // This can happen if we were looking for a type and
+                        // found a module instead. Modules don't have defs.
+                        debug!("(resolving item path by identifier in lexical \
+                                 scope) failed to resolve {} after success...",
+                                 token::get_name(name));
+                        return None;
+                    }
+                    Some(def) => {
+                        debug!("(resolving item path in lexical scope) \
+                                resolved `{}` to item",
+                               token::get_name(name));
+                        // This lookup is "all public" because it only searched
+                        // for one identifier in the current module (couldn't
+                        // have passed through reexports or anything like that.
+                        return Some((def, LastMod(AllPublic)));
+                    }
+                }
+            }
+            Indeterminate => {
+                panic!("unexpected indeterminate result");
+            }
+            Failed(err) => {
+                match err {
+                    Some((span, msg)) =>
+                        self.resolve_error(span, format!("failed to resolve. {}", msg)),
+                    None => ()
+                }
+
+                debug!("(resolving item path by identifier in lexical scope) \
+                         failed to resolve {}", token::get_name(name));
+                return None;
+            }
+        }
+    }
+
+    fn with_no_errors<T, F>(&mut self, f: F) -> T where
+        F: FnOnce(&mut Resolver) -> T,
+    {
+        self.emit_errors = false;
+        let rs = f(self);
+        self.emit_errors = true;
+        rs
+    }
+
+    fn resolve_error<T: Str>(&self, span: Span, s: T) {
+        if self.emit_errors {
+            self.session.span_err(span, s.as_slice());
+        }
+    }
+
+    fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
+        fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
+                                                    -> Option<(Path, NodeId, FallbackChecks)> {
+            match t.node {
+                TyPath(ref path, node_id) => Some((path.clone(), node_id, allow)),
+                TyPtr(ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, OnlyTraitAndStatics),
+                TyRptr(_, ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, allow),
+                // This doesn't handle the remaining `Ty` variants as they are not
+                // that commonly the self_type, it might be interesting to provide
+                // support for those in future.
+                _ => None,
+            }
+        }
+
+        fn get_module(this: &mut Resolver, span: Span, name_path: &[ast::Name])
+                            -> Option<Rc<Module>> {
+            let root = this.current_module.clone();
+            let last_name = name_path.last().unwrap();
+
+            if name_path.len() == 1 {
+                match this.primitive_type_table.primitive_types.get(last_name) {
+                    Some(_) => None,
+                    None => {
+                        match this.current_module.children.borrow().get(last_name) {
+                            Some(child) => child.get_module_if_available(),
+                            None => None
+                        }
+                    }
+                }
+            } else {
+                match this.resolve_module_path(root,
+                                                name_path.as_slice(),
+                                                UseLexicalScope,
+                                                span,
+                                                PathSearch) {
+                    Success((module, _)) => Some(module),
+                    _ => None
+                }
+            }
+        }
+
+        let (path, node_id, allowed) = match self.current_self_type {
+            Some(ref ty) => match extract_path_and_node_id(ty, Everything) {
+                Some(x) => x,
+                None => return NoSuggestion,
+            },
+            None => return NoSuggestion,
+        };
+
+        if allowed == Everything {
+            // Look for a field with the same name in the current self_type.
+            match self.def_map.borrow().get(&node_id) {
+                 Some(&DefTy(did, _))
+                | Some(&DefStruct(did))
+                | Some(&DefVariant(_, did, _)) => match self.structs.get(&did) {
+                    None => {}
+                    Some(fields) => {
+                        if fields.iter().any(|&field_name| name == field_name) {
+                            return Field;
+                        }
+                    }
+                },
+                _ => {} // Self type didn't resolve properly
+            }
+        }
+
+        let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::<Vec<_>>();
+
+        // Look for a method in the current self type's impl module.
+        match get_module(self, path.span, name_path.as_slice()) {
+            Some(module) => match module.children.borrow().get(&name) {
+                Some(binding) => {
+                    let p_str = self.path_names_to_string(&path);
+                    match binding.def_for_namespace(ValueNS) {
+                        Some(DefStaticMethod(_, provenance)) => {
+                            match provenance {
+                                FromImpl(_) => return StaticMethod(p_str),
+                                FromTrait(_) => unreachable!()
+                            }
+                        }
+                        Some(DefMethod(_, None, _)) if allowed == Everything => return Method,
+                        Some(DefMethod(_, Some(_), _)) => return TraitItem,
+                        _ => ()
+                    }
+                }
+                None => {}
+            },
+            None => {}
+        }
+
+        // Look for a method in the current trait.
+        match self.current_trait_ref {
+            Some((did, ref trait_ref)) => {
+                let path_str = self.path_names_to_string(&trait_ref.path);
+
+                match self.trait_item_map.get(&(name, did)) {
+                    Some(&StaticMethodTraitItemKind) => {
+                        return TraitMethod(path_str)
+                    }
+                    Some(_) => return TraitItem,
+                    None => {}
+                }
+            }
+            None => {}
+        }
+
+        NoSuggestion
+    }
+
+    fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
+                                -> Option<String> {
+        let this = &mut *self;
+
+        let mut maybes: Vec<token::InternedString> = Vec::new();
+        let mut values: Vec<uint> = Vec::new();
+
+        for rib in this.value_ribs.iter().rev() {
+            for (&k, _) in rib.bindings.iter() {
+                maybes.push(token::get_name(k));
+                values.push(uint::MAX);
+            }
+        }
+
+        let mut smallest = 0;
+        for (i, other) in maybes.iter().enumerate() {
+            values[i] = name.lev_distance(other.get());
+
+            if values[i] <= values[smallest] {
+                smallest = i;
+            }
+        }
+
+        if values.len() > 0 &&
+            values[smallest] != uint::MAX &&
+            values[smallest] < name.len() + 2 &&
+            values[smallest] <= max_distance &&
+            name != maybes[smallest].get() {
+
+            Some(maybes[smallest].get().to_string())
+
+        } else {
+            None
+        }
+    }
+
+    fn resolve_expr(&mut self, expr: &Expr) {
+        // First, record candidate traits for this expression if it could
+        // result in the invocation of a method call.
+
+        self.record_candidate_traits_for_expr_if_necessary(expr);
+
+        // Next, resolve the node.
+        match expr.node {
+            // The interpretation of paths depends on whether the path has
+            // multiple elements in it or not.
+
+            ExprPath(ref path) => {
+                // This is a local path in the value namespace. Walk through
+                // scopes looking for it.
+
+                let path_name = self.path_names_to_string(path);
+
+                match self.resolve_path(expr.id, path, ValueNS, true) {
+                    // Check if struct variant
+                    Some((DefVariant(_, _, true), _)) => {
+                        self.resolve_error(expr.span,
+                                format!("`{}` is a struct variant name, but \
+                                         this expression \
+                                         uses it like a function name",
+                                        path_name).as_slice());
+
+                        self.session.span_help(expr.span,
+                            format!("Did you mean to write: \
+                                    `{} {{ /* fields */ }}`?",
+                                    path_name).as_slice());
+                    }
+                    Some(def) => {
+                        // Write the result into the def map.
+                        debug!("(resolving expr) resolved `{}`",
+                               path_name);
+
+                        self.record_def(expr.id, def);
+                    }
+                    None => {
+                        // 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
+                        // structs, which wouldn't result in this error.)
+                        match self.with_no_errors(|this|
+                            this.resolve_path(expr.id, path, TypeNS, false)) {
+                            Some((DefTy(struct_id, _), _))
+                              if self.structs.contains_key(&struct_id) => {
+                                self.resolve_error(expr.span,
+                                        format!("`{}` is a structure name, but \
+                                                 this expression \
+                                                 uses it like a function name",
+                                                path_name).as_slice());
+
+                                self.session.span_help(expr.span,
+                                    format!("Did you mean to write: \
+                                            `{} {{ /* fields */ }}`?",
+                                            path_name).as_slice());
+
+                            }
+                            _ => {
+                                let mut method_scope = false;
+                                self.value_ribs.iter().rev().all(|rib| {
+                                    let res = match *rib {
+                                        Rib { bindings: _, kind: MethodRibKind(_, _) } => true,
+                                        Rib { bindings: _, kind: ItemRibKind } => false,
+                                        _ => return true, // Keep advancing
+                                    };
+
+                                    method_scope = res;
+                                    false // Stop advancing
+                                });
+
+                                if method_scope && token::get_name(self.self_name).get()
+                                                                   == path_name {
+                                        self.resolve_error(
+                                            expr.span,
+                                            "`self` is not available \
+                                             in a static method. Maybe a \
+                                             `self` argument is missing?");
+                                } else {
+                                    let last_name = path.segments.last().unwrap().identifier.name;
+                                    let mut msg = match self.find_fallback_in_self_type(last_name) {
+                                        NoSuggestion => {
+                                            // limit search to 5 to reduce the number
+                                            // of stupid suggestions
+                                            self.find_best_match_for_name(path_name.as_slice(), 5)
+                                                                .map_or("".to_string(),
+                                                                        |x| format!("`{}`", x))
+                                        }
+                                        Field =>
+                                            format!("`self.{}`", path_name),
+                                        Method
+                                        | TraitItem =>
+                                            format!("to call `self.{}`", path_name),
+                                        TraitMethod(path_str)
+                                        | StaticMethod(path_str) =>
+                                            format!("to call `{}::{}`", path_str, path_name)
+                                    };
+
+                                    if msg.len() > 0 {
+                                        msg = format!(". Did you mean {}?", msg)
+                                    }
+
+                                    self.resolve_error(
+                                        expr.span,
+                                        format!("unresolved name `{}`{}",
+                                                path_name,
+                                                msg).as_slice());
+                                }
+                            }
+                        }
+                    }
+                }
+
+                visit::walk_expr(self, expr);
+            }
+
+            ExprClosure(capture_clause, _, ref fn_decl, ref block) => {
+                self.capture_mode_map.insert(expr.id, capture_clause);
+                self.resolve_function(ClosureRibKind(expr.id, ast::DUMMY_NODE_ID),
+                                      Some(&**fn_decl), NoTypeParameters,
+                                      &**block);
+            }
+
+            ExprStruct(ref path, _, _) => {
+                // 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(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_names_to_string(path));
+                        self.resolve_error(path.span, msg.as_slice());
+                    }
+                }
+
+                visit::walk_expr(self, expr);
+            }
+
+            ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
+                self.with_label_rib(|this| {
+                    let def_like = DlDef(DefLabel(expr.id));
+
+                    {
+                        let rib = this.label_ribs.last_mut().unwrap();
+                        let renamed = mtwt::resolve(label);
+                        rib.bindings.insert(renamed, def_like);
+                    }
+
+                    visit::walk_expr(this, expr);
+                })
+            }
+
+            ExprForLoop(ref pattern, ref head, ref body, optional_label) => {
+                self.resolve_expr(&**head);
+
+                self.value_ribs.push(Rib::new(NormalRibKind));
+
+                self.resolve_pattern(&**pattern,
+                                     LocalIrrefutableMode,
+                                     &mut HashMap::new());
+
+                match optional_label {
+                    None => {}
+                    Some(label) => {
+                        self.label_ribs
+                            .push(Rib::new(NormalRibKind));
+                        let def_like = DlDef(DefLabel(expr.id));
+
+                        {
+                            let rib = self.label_ribs.last_mut().unwrap();
+                            let renamed = mtwt::resolve(label);
+                            rib.bindings.insert(renamed, def_like);
+                        }
+                    }
+                }
+
+                self.resolve_block(&**body);
+
+                if optional_label.is_some() {
+                    drop(self.label_ribs.pop())
+                }
+
+                self.value_ribs.pop();
+            }
+
+            ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
+                let renamed = mtwt::resolve(label);
+                match self.search_ribs(self.label_ribs.as_slice(),
+                                       renamed, expr.span) {
+                    None => {
+                        self.resolve_error(
+                            expr.span,
+                            format!("use of undeclared label `{}`",
+                                    token::get_ident(label)).as_slice())
+                    }
+                    Some(DlDef(def @ DefLabel(_))) => {
+                        // Since this def is a label, it is never read.
+                        self.record_def(expr.id, (def, LastMod(AllPublic)))
+                    }
+                    Some(_) => {
+                        self.session.span_bug(expr.span,
+                                              "label wasn't mapped to a \
+                                               label def!")
+                    }
+                }
+            }
+
+            _ => {
+                visit::walk_expr(self, expr);
+            }
+        }
+    }
+
+    fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
+        match expr.node {
+            ExprField(_, ident) => {
+                // FIXME(#6890): Even though you can't treat a method like a
+                // field, we need to add any trait methods we find that match
+                // the field name so that we can do some nice error reporting
+                // later on in typeck.
+                let traits = self.search_for_traits_containing_method(ident.node.name);
+                self.trait_map.insert(expr.id, traits);
+            }
+            ExprMethodCall(ident, _, _) => {
+                debug!("(recording candidate traits for expr) recording \
+                        traits for {}",
+                       expr.id);
+                let traits = self.search_for_traits_containing_method(ident.node.name);
+                self.trait_map.insert(expr.id, traits);
+            }
+            _ => {
+                // Nothing to do.
+            }
+        }
+    }
+
+    fn search_for_traits_containing_method(&mut self, name: Name) -> Vec<DefId> {
+        debug!("(searching for traits containing method) looking for '{}'",
+               token::get_name(name));
+
+        fn add_trait_info(found_traits: &mut Vec<DefId>,
+                          trait_def_id: DefId,
+                          name: Name) {
+            debug!("(adding trait info) found trait {}:{} for method '{}'",
+                trait_def_id.krate,
+                trait_def_id.node,
+                token::get_name(name));
+            found_traits.push(trait_def_id);
+        }
+
+        let mut found_traits = Vec::new();
+        let mut search_module = self.current_module.clone();
+        loop {
+            // Look for the current trait.
+            match self.current_trait_ref {
+                Some((trait_def_id, _)) => {
+                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
+                        add_trait_info(&mut found_traits, trait_def_id, name);
+                    }
+                }
+                None => {} // Nothing to do.
+            }
+
+            // Look for trait children.
+            self.populate_module_if_necessary(&search_module);
+
+            {
+                for (_, child_names) in search_module.children.borrow().iter() {
+                    let def = match child_names.def_for_namespace(TypeNS) {
+                        Some(def) => def,
+                        None => continue
+                    };
+                    let trait_def_id = match def {
+                        DefTrait(trait_def_id) => trait_def_id,
+                        _ => continue,
+                    };
+                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
+                        add_trait_info(&mut found_traits, trait_def_id, name);
+                    }
+                }
+            }
+
+            // Look for imports.
+            for (_, import) in search_module.import_resolutions.borrow().iter() {
+                let target = match import.target_for_namespace(TypeNS) {
+                    None => continue,
+                    Some(target) => target,
+                };
+                let did = match target.bindings.def_for_namespace(TypeNS) {
+                    Some(DefTrait(trait_def_id)) => trait_def_id,
+                    Some(..) | None => continue,
+                };
+                if self.trait_item_map.contains_key(&(name, did)) {
+                    add_trait_info(&mut found_traits, did, name);
+                    self.used_imports.insert((import.type_id, TypeNS));
+                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
+                        self.used_crates.insert(kid);
+                    }
+                }
+            }
+
+            match search_module.parent_link.clone() {
+                NoParentLink | ModuleParentLink(..) => break,
+                BlockParentLink(parent_module, _) => {
+                    search_module = parent_module.upgrade().unwrap();
+                }
+            }
+        }
+
+        found_traits
+    }
+
+    fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) {
+        debug!("(recording def) recording {} for {}, last private {}",
+                def, node_id, lp);
+        assert!(match lp {LastImport{..} => false, _ => true},
+                "Import should only be used for `use` directives");
+        self.last_private.insert(node_id, lp);
+
+        match self.def_map.borrow_mut().entry(node_id) {
+            // Resolve appears to "resolve" the same ID multiple
+            // times, so here is a sanity check it at least comes to
+            // the same conclusion! - nmatsakis
+            Occupied(entry) => if def != *entry.get() {
+                self.session
+                    .bug(format!("node_id {} resolved first to {} and \
+                                  then {}",
+                                 node_id,
+                                 *entry.get(),
+                                 def).as_slice());
+            },
+            Vacant(entry) => { entry.set(def); },
+        }
+    }
+
+    fn enforce_default_binding_mode(&mut self,
+                                        pat: &Pat,
+                                        pat_binding_mode: BindingMode,
+                                        descr: &str) {
+        match pat_binding_mode {
+            BindByValue(_) => {}
+            BindByRef(..) => {
+                self.resolve_error(pat.span,
+                                   format!("cannot use `ref` binding mode \
+                                            with {}",
+                                           descr).as_slice());
+            }
+        }
+    }
+
+    //
+    // Diagnostics
+    //
+    // Diagnostics are not particularly efficient, because they're rarely
+    // hit.
+    //
+
+    /// A somewhat inefficient routine to obtain the name of a module.
+    fn module_to_string(&self, module: &Module) -> String {
+        let mut names = Vec::new();
+
+        fn collect_mod(names: &mut Vec<ast::Name>, module: &Module) {
+            match module.parent_link {
+                NoParentLink => {}
+                ModuleParentLink(ref module, name) => {
+                    names.push(name);
+                    collect_mod(names, &*module.upgrade().unwrap());
+                }
+                BlockParentLink(ref module, _) => {
+                    // danger, shouldn't be ident?
+                    names.push(special_idents::opaque.name);
+                    collect_mod(names, &*module.upgrade().unwrap());
+                }
+            }
+        }
+        collect_mod(&mut names, module);
+
+        if names.len() == 0 {
+            return "???".to_string();
+        }
+        self.names_to_string(names.into_iter().rev()
+                                  .collect::<Vec<ast::Name>>()
+                                  .as_slice())
+    }
+
+    #[allow(dead_code)]   // useful for debugging
+    fn dump_module(&mut self, module_: Rc<Module>) {
+        debug!("Dump of module `{}`:", self.module_to_string(&*module_));
+
+        debug!("Children:");
+        self.populate_module_if_necessary(&module_);
+        for (&name, _) in module_.children.borrow().iter() {
+            debug!("* {}", token::get_name(name));
+        }
+
+        debug!("Import resolutions:");
+        let import_resolutions = module_.import_resolutions.borrow();
+        for (&name, import_resolution) in import_resolutions.iter() {
+            let value_repr;
+            match import_resolution.target_for_namespace(ValueNS) {
+                None => { value_repr = "".to_string(); }
+                Some(_) => {
+                    value_repr = " value:?".to_string();
+                    // FIXME #4954
+                }
+            }
+
+            let type_repr;
+            match import_resolution.target_for_namespace(TypeNS) {
+                None => { type_repr = "".to_string(); }
+                Some(_) => {
+                    type_repr = " type:?".to_string();
+                    // FIXME #4954
+                }
+            }
+
+            debug!("* {}:{}{}", token::get_name(name), value_repr, type_repr);
+        }
+    }
+}
+
+pub struct CrateMap {
+    pub def_map: DefMap,
+    pub freevars: RefCell<FreevarMap>,
+    pub capture_mode_map: RefCell<CaptureModeMap>,
+    pub export_map: ExportMap,
+    pub trait_map: TraitMap,
+    pub external_exports: ExternalExports,
+    pub last_private_map: LastPrivateMap,
+}
+
+/// Entry point to crate resolution.
+pub fn resolve_crate(session: &Session,
+                     _: &LanguageItems,
+                     krate: &Crate)
+                  -> CrateMap {
+    let mut resolver = Resolver::new(session, krate.span);
+
+    resolver.build_reduced_graph(krate);
+    session.abort_if_errors();
+
+    resolver.resolve_imports();
+    session.abort_if_errors();
+
+    record_exports::record(&mut resolver);
+    session.abort_if_errors();
+
+    resolver.resolve_crate(krate);
+    session.abort_if_errors();
+
+    check_unused::check_crate(&mut resolver, krate);
+
+    CrateMap {
+        def_map: resolver.def_map,
+        freevars: resolver.freevars,
+        capture_mode_map: RefCell::new(resolver.capture_mode_map),
+        export_map: resolver.export_map,
+        trait_map: resolver.trait_map,
+        external_exports: resolver.external_exports,
+        last_private_map: resolver.last_private,
+    }
+}
diff --git a/src/librustc_resolve/record_exports.rs b/src/librustc_resolve/record_exports.rs
new file mode 100644 (file)
index 0000000..41882a9
--- /dev/null
@@ -0,0 +1,157 @@
+// 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.
+
+
+// Export recording
+//
+// This pass simply determines what all "export" keywords refer to and
+// writes the results into the export map.
+//
+// FIXME #4953 This pass will be removed once exports change to per-item.
+// Then this operation can simply be performed as part of item (or import)
+// processing.
+
+use {Module, NameBindings, Resolver};
+use Namespace::{mod, TypeNS, ValueNS};
+
+use rustc::middle::def::Export;
+use syntax::ast;
+use syntax::parse::token;
+
+use std::rc::Rc;
+
+struct ExportRecorder<'a, 'b:'a> {
+    resolver: &'a mut Resolver<'b>
+}
+
+// Deref and DerefMut impls allow treating ExportRecorder as Resolver.
+impl<'a, 'b> Deref<Resolver<'b>> for ExportRecorder<'a, 'b> {
+    fn deref<'c>(&'c self) -> &'c Resolver<'b> {
+        &*self.resolver
+    }
+}
+
+impl<'a, 'b> DerefMut<Resolver<'b>> for ExportRecorder<'a, 'b> {
+    fn deref_mut<'c>(&'c mut self) -> &'c mut Resolver<'b> {
+        &mut *self.resolver
+    }
+}
+
+impl<'a, 'b> ExportRecorder<'a, 'b> {
+    fn record_exports_for_module_subtree(&mut self,
+                                         module_: Rc<Module>) {
+        // If this isn't a local krate, then bail out. We don't need to record
+        // exports for nonlocal crates.
+
+        match module_.def_id.get() {
+            Some(def_id) if def_id.krate == ast::LOCAL_CRATE => {
+                // OK. Continue.
+                debug!("(recording exports for module subtree) recording \
+                        exports for local 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_string(&*module_));
+            }
+            Some(_) => {
+                // Bail out.
+                debug!("(recording exports for module subtree) not recording \
+                        exports for `{}`",
+                       self.module_to_string(&*module_));
+                return;
+            }
+        }
+
+        self.record_exports_for_module(&*module_);
+        self.populate_module_if_necessary(&module_);
+
+        for (_, child_name_bindings) in module_.children.borrow().iter() {
+            match child_name_bindings.get_module_if_available() {
+                None => {
+                    // Nothing to do.
+                }
+                Some(child_module) => {
+                    self.record_exports_for_module_subtree(child_module);
+                }
+            }
+        }
+
+        for (_, child_module) in module_.anonymous_children.borrow().iter() {
+            self.record_exports_for_module_subtree(child_module.clone());
+        }
+    }
+
+    fn record_exports_for_module(&mut self, module_: &Module) {
+        let mut exports = Vec::new();
+
+        self.add_exports_for_module(&mut exports, module_);
+        match module_.def_id.get() {
+            Some(def_id) => {
+                self.export_map.insert(def_id.node, exports);
+                debug!("(computing exports) writing exports for {} (some)",
+                       def_id.node);
+            }
+            None => {}
+        }
+    }
+
+    fn add_exports_of_namebindings(&mut self,
+                                   exports: &mut Vec<Export>,
+                                   name: ast::Name,
+                                   namebindings: &NameBindings,
+                                   ns: Namespace) {
+        match namebindings.def_for_namespace(ns) {
+            Some(d) => {
+                debug!("(computing exports) YES: export '{}' => {}",
+                       name, d.def_id());
+                exports.push(Export {
+                    name: name,
+                    def_id: d.def_id()
+                });
+            }
+            d_opt => {
+                debug!("(computing exports) NO: {}", d_opt);
+            }
+        }
+    }
+
+    fn add_exports_for_module(&mut self,
+                              exports: &mut Vec<Export>,
+                              module_: &Module) {
+        for (name, importresolution) in module_.import_resolutions.borrow().iter() {
+            if !importresolution.is_public {
+                continue
+            }
+            let xs = [TypeNS, ValueNS];
+            for &ns in xs.iter() {
+                match importresolution.target_for_namespace(ns) {
+                    Some(target) => {
+                        debug!("(computing exports) maybe export '{}'",
+                               token::get_name(*name));
+                        self.add_exports_of_namebindings(exports,
+                                                         *name,
+                                                         &*target.bindings,
+                                                         ns)
+                    }
+                    _ => ()
+                }
+            }
+        }
+    }
+}
+
+pub fn record(resolver: &mut Resolver) {
+    let mut recorder = ExportRecorder { resolver: resolver };
+    let root_module = recorder.graph_root.get_module();
+    recorder.record_exports_for_module_subtree(root_module);
+}
index 489d29492c227827165d597d182262575c2c0b86..60b5b32e89f5a76e524b56a97e5ef6c03a82fcb5 100644 (file)
@@ -605,6 +605,7 @@ pub fn run_passes(sess: &Session,
                 modules_config.emit_obj = true;
                 metadata_config.emit_obj = true;
             },
+            config::OutputTypeDepInfo => {}
         }
     }
 
@@ -777,6 +778,7 @@ pub fn run_passes(sess: &Session,
                     link_obj(&crate_output.temp_path(config::OutputTypeObject));
                 }
             }
+            config::OutputTypeDepInfo => {}
         }
     }
     let user_wants_bitcode = user_wants_bitcode;
index 05b1a86b72b05171a3f88ce1b2408ca3a3c220a8..784002287b7502ee2c99e87bf7785675eced0e63 100644 (file)
@@ -22,7 +22,7 @@
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/")]
 
-#![feature(default_type_params, globs, import_shadowing, macro_rules, phase, quote)]
+#![feature(default_type_params, globs, macro_rules, phase, quote)]
 #![feature(slicing_syntax, unsafe_destructor)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(unboxed_closures)]
index 1401f1ad1f551352fbde3a6a5655ec1082d4f061..2bcd723fc83a422f698574b5523d512f69576700 100644 (file)
 use middle::check_match::StaticInliner;
 use middle::check_match;
 use middle::const_eval;
-use middle::def;
+use middle::def::{mod, DefMap};
 use middle::expr_use_visitor as euv;
 use middle::lang_items::StrEqFnLangItem;
 use middle::mem_categorization as mc;
 use middle::pat_util::*;
-use middle::resolve::DefMap;
 use trans::adt;
 use trans::base::*;
 use trans::build::{AddCase, And, BitCast, Br, CondBr, GEPi, InBoundsGEP, Load};
index 25fbaa6677684af6496ec59333c61721ebe8f071..ca1e0d7de72102c169943d62aa17e1716123b3f0 100644 (file)
@@ -38,6 +38,7 @@
 use llvm;
 use metadata::{csearch, encoder, loader};
 use middle::astencode;
+use middle::cfg;
 use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
 use middle::subst;
 use middle::weak_lang_items;
@@ -1306,47 +1307,33 @@ pub fn make_return_slot_pointer<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>,
     }
 }
 
-struct CheckForNestedReturnsVisitor {
+struct FindNestedReturn {
     found: bool,
-    in_return: bool
 }
 
-impl CheckForNestedReturnsVisitor {
-    fn explicit() -> CheckForNestedReturnsVisitor {
-        CheckForNestedReturnsVisitor { found: false, in_return: false }
-    }
-    fn implicit() -> CheckForNestedReturnsVisitor {
-        CheckForNestedReturnsVisitor { found: false, in_return: true }
+impl FindNestedReturn {
+    fn new() -> FindNestedReturn {
+        FindNestedReturn { found: false }
     }
 }
 
-impl<'v> Visitor<'v> for CheckForNestedReturnsVisitor {
+impl<'v> Visitor<'v> for FindNestedReturn {
     fn visit_expr(&mut self, e: &ast::Expr) {
         match e.node {
             ast::ExprRet(..) => {
-                if self.in_return {
-                    self.found = true;
-                } else {
-                    self.in_return = true;
-                    visit::walk_expr(self, e);
-                    self.in_return = false;
-                }
+                self.found = true;
             }
             _ => visit::walk_expr(self, e)
         }
     }
 }
 
-fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
-    match tcx.map.find(id) {
+fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option<cfg::CFG>) {
+    let blk = match tcx.map.find(id) {
         Some(ast_map::NodeItem(i)) => {
             match i.node {
                 ast::ItemFn(_, _, _, _, ref blk) => {
-                    let mut explicit = CheckForNestedReturnsVisitor::explicit();
-                    let mut implicit = CheckForNestedReturnsVisitor::implicit();
-                    visit::walk_item(&mut explicit, &*i);
-                    visit::walk_expr_opt(&mut implicit, &blk.expr);
-                    explicit.found || implicit.found
+                    blk
                 }
                 _ => tcx.sess.bug("unexpected item variant in has_nested_returns")
             }
@@ -1356,11 +1343,7 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
                 ast::ProvidedMethod(ref m) => {
                     match m.node {
                         ast::MethDecl(_, _, _, _, _, _, ref blk, _) => {
-                            let mut explicit = CheckForNestedReturnsVisitor::explicit();
-                            let mut implicit = CheckForNestedReturnsVisitor::implicit();
-                            visit::walk_method_helper(&mut explicit, &**m);
-                            visit::walk_expr_opt(&mut implicit, &blk.expr);
-                            explicit.found || implicit.found
+                            blk
                         }
                         ast::MethMac(_) => tcx.sess.bug("unexpanded macro")
                     }
@@ -1380,11 +1363,7 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
                 ast::MethodImplItem(ref m) => {
                     match m.node {
                         ast::MethDecl(_, _, _, _, _, _, ref blk, _) => {
-                            let mut explicit = CheckForNestedReturnsVisitor::explicit();
-                            let mut implicit = CheckForNestedReturnsVisitor::implicit();
-                            visit::walk_method_helper(&mut explicit, &**m);
-                            visit::walk_expr_opt(&mut implicit, &blk.expr);
-                            explicit.found || implicit.found
+                            blk
                         }
                         ast::MethMac(_) => tcx.sess.bug("unexpanded macro")
                     }
@@ -1398,24 +1377,58 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
         Some(ast_map::NodeExpr(e)) => {
             match e.node {
                 ast::ExprClosure(_, _, _, ref blk) => {
-                    let mut explicit = CheckForNestedReturnsVisitor::explicit();
-                    let mut implicit = CheckForNestedReturnsVisitor::implicit();
-                    visit::walk_expr(&mut explicit, e);
-                    visit::walk_expr_opt(&mut implicit, &blk.expr);
-                    explicit.found || implicit.found
+                    blk
                 }
                 _ => tcx.sess.bug("unexpected expr variant in has_nested_returns")
             }
         }
-
-        Some(ast_map::NodeVariant(..)) | Some(ast_map::NodeStructCtor(..)) => false,
+        Some(ast_map::NodeVariant(..)) |
+        Some(ast_map::NodeStructCtor(..)) => return (ast::DUMMY_NODE_ID, None),
 
         // glue, shims, etc
-        None if id == ast::DUMMY_NODE_ID => false,
+        None if id == ast::DUMMY_NODE_ID => return (ast::DUMMY_NODE_ID, None),
 
         _ => tcx.sess.bug(format!("unexpected variant in has_nested_returns: {}",
                                   tcx.map.path_to_string(id)).as_slice())
+    };
+
+    (blk.id, Some(cfg::CFG::new(tcx, &**blk)))
+}
+
+// Checks for the presence of "nested returns" in a function.
+// Nested returns are when the inner expression of a return expression
+// (the 'expr' in 'return expr') contains a return expression. Only cases
+// where the outer return is actually reachable are considered. Implicit
+// returns from the end of blocks are considered as well.
+//
+// This check is needed to handle the case where the inner expression is
+// part of a larger expression that may have already partially-filled the
+// return slot alloca. This can cause errors related to clean-up due to
+// the clobbering of the existing value in the return slot.
+fn has_nested_returns(tcx: &ty::ctxt, cfg: &cfg::CFG, blk_id: ast::NodeId) -> bool {
+    for n in cfg.graph.depth_traverse(cfg.entry) {
+        match tcx.map.find(n.id) {
+            Some(ast_map::NodeExpr(ex)) => {
+                if let ast::ExprRet(Some(ref ret_expr)) = ex.node {
+                    let mut visitor = FindNestedReturn::new();
+                    visit::walk_expr(&mut visitor, &**ret_expr);
+                    if visitor.found {
+                        return true;
+                    }
+                }
+            }
+            Some(ast_map::NodeBlock(blk)) if blk.id == blk_id => {
+                let mut visitor = FindNestedReturn::new();
+                visit::walk_expr_opt(&mut visitor, &blk.expr);
+                if visitor.found {
+                    return true;
+                }
+            }
+            _ => {}
+        }
     }
+
+    return false;
 }
 
 // NB: must keep 4 fns in sync:
@@ -1454,7 +1467,12 @@ pub fn new_fn_ctxt<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
         ty::FnDiverging => false
     };
     let debug_context = debuginfo::create_function_debug_context(ccx, id, param_substs, llfndecl);
-    let nested_returns = has_nested_returns(ccx.tcx(), id);
+    let (blk_id, cfg) = build_cfg(ccx.tcx(), id);
+    let nested_returns = if let Some(ref cfg) = cfg {
+        has_nested_returns(ccx.tcx(), cfg, blk_id)
+    } else {
+        false
+    };
 
     let mut fcx = FunctionContext {
           llfn: llfndecl,
@@ -1473,7 +1491,8 @@ pub fn new_fn_ctxt<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
           block_arena: block_arena,
           ccx: ccx,
           debug_context: debug_context,
-          scopes: RefCell::new(Vec::new())
+          scopes: RefCell::new(Vec::new()),
+          cfg: cfg
     };
 
     if has_env {
@@ -2938,7 +2957,7 @@ pub fn crate_ctxt_to_encode_parms<'a, 'tcx>(cx: &'a SharedCrateContext<'tcx>,
     encoder::EncodeParams {
         diag: cx.sess().diagnostic(),
         tcx: cx.tcx(),
-        reexports2: cx.exp_map2(),
+        reexports: cx.export_map(),
         item_symbols: cx.item_symbols(),
         link_meta: cx.link_meta(),
         cstore: &cx.sess().cstore,
@@ -3071,7 +3090,7 @@ fn next(&mut self) -> Option<ValueRef> {
 
 pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
                          -> (ty::ctxt<'tcx>, CrateTranslation) {
-    let ty::CrateAnalysis { ty_cx: tcx, exp_map2, reachable, name, .. } = analysis;
+    let ty::CrateAnalysis { ty_cx: tcx, export_map, reachable, name, .. } = analysis;
     let krate = tcx.map.krate();
 
     // Before we touch LLVM, make sure that multithreading is enabled.
@@ -3098,7 +3117,7 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
     let shared_ccx = SharedCrateContext::new(link_meta.crate_name.as_slice(),
                                              codegen_units,
                                              tcx,
-                                             exp_map2,
+                                             export_map,
                                              Sha256::new(),
                                              link_meta.clone(),
                                              reachable);
index 3376479b7a42dce40792de933778ba630150c132..1a753901f7ea4ca01133168aa7dd0168fe9bd71e 100644 (file)
@@ -487,7 +487,7 @@ pub fn trans_fn_ref_with_substs<'blk, 'tcx>(
 
         let opt_ref_id = match node {
             ExprId(id) => if id != 0 { Some(id) } else { None },
-            MethodCall(_) => None,
+            MethodCallKey(_) => None,
         };
 
         let (val, must_cast) =
@@ -498,7 +498,7 @@ pub fn trans_fn_ref_with_substs<'blk, 'tcx>(
             // are subst'd)
             let ref_ty = match node {
                 ExprId(id) => node_id_type(bcx, id),
-                MethodCall(method_call) => {
+                MethodCallKey(method_call) => {
                     let t = (*bcx.tcx().method_map.borrow())[method_call].ty;
                     monomorphize_type(bcx, t)
                 }
index 4dd4e27c9c0d4255dd052271fbebb39c87139e07..61f27bcfa7ad384e217ef6ee02216abefb6b53c9 100644 (file)
@@ -18,6 +18,7 @@
 use llvm;
 use llvm::{ValueRef, BasicBlockRef, BuilderRef, ContextRef};
 use llvm::{True, False, Bool};
+use middle::cfg;
 use middle::def;
 use middle::infer;
 use middle::lang_items::LangItem;
@@ -262,6 +263,8 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
 
     // Cleanup scopes.
     pub scopes: RefCell<Vec<cleanup::CleanupScope<'a, 'tcx>>>,
+
+    pub cfg: Option<cfg::CFG>,
 }
 
 impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
@@ -867,7 +870,7 @@ pub enum ExprOrMethodCall {
     ExprId(ast::NodeId),
 
     // Type parameters for a method call like `a.foo::<int>()`
-    MethodCall(ty::MethodCall)
+    MethodCallKey(ty::MethodCall)
 }
 
 pub fn node_id_substs<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
@@ -879,7 +882,7 @@ pub fn node_id_substs<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         ExprId(id) => {
             ty::node_id_item_substs(tcx, id).substs
         }
-        MethodCall(method_call) => {
+        MethodCallKey(method_call) => {
             (*tcx.method_map.borrow())[method_call].substs.clone()
         }
     };
index af003b011579f2687e56897f14f841517dd24970..7b962a939906fa5a7882caaec69de29975a00224 100644 (file)
@@ -13,7 +13,7 @@
 use llvm::{TargetData};
 use llvm::mk_target_data;
 use metadata::common::LinkMeta;
-use middle::resolve;
+use middle::def::ExportMap;
 use middle::traits;
 use trans::adt;
 use trans::base;
@@ -61,7 +61,7 @@ pub struct SharedCrateContext<'tcx> {
     metadata_llmod: ModuleRef,
     metadata_llcx: ContextRef,
 
-    exp_map2: resolve::ExportMap2,
+    export_map: ExportMap,
     reachable: NodeSet,
     item_symbols: RefCell<NodeMap<String>>,
     link_meta: LinkMeta,
@@ -238,7 +238,7 @@ impl<'tcx> SharedCrateContext<'tcx> {
     pub fn new(crate_name: &str,
                local_count: uint,
                tcx: ty::ctxt<'tcx>,
-               emap2: resolve::ExportMap2,
+               export_map: ExportMap,
                symbol_hasher: Sha256,
                link_meta: LinkMeta,
                reachable: NodeSet)
@@ -251,7 +251,7 @@ pub fn new(crate_name: &str,
             local_ccxs: Vec::with_capacity(local_count),
             metadata_llmod: metadata_llmod,
             metadata_llcx: metadata_llcx,
-            exp_map2: emap2,
+            export_map: export_map,
             reachable: reachable,
             item_symbols: RefCell::new(NodeMap::new()),
             link_meta: link_meta,
@@ -329,8 +329,8 @@ pub fn metadata_llcx(&self) -> ContextRef {
         self.metadata_llcx
     }
 
-    pub fn exp_map2<'a>(&'a self) -> &'a resolve::ExportMap2 {
-        &self.exp_map2
+    pub fn export_map<'a>(&'a self) -> &'a ExportMap {
+        &self.export_map
     }
 
     pub fn reachable<'a>(&'a self) -> &'a NodeSet {
@@ -553,8 +553,8 @@ pub fn item_vals<'a>(&'a self) -> &'a RefCell<NodeMap<ValueRef>> {
         &self.local.item_vals
     }
 
-    pub fn exp_map2<'a>(&'a self) -> &'a resolve::ExportMap2 {
-        &self.shared.exp_map2
+    pub fn export_map<'a>(&'a self) -> &'a ExportMap {
+        &self.shared.export_map
     }
 
     pub fn reachable<'a>(&'a self) -> &'a NodeSet {
index a1574aa2f0e4339eab45f4bc954a8af131a52ea7..135e192a2fd49d59c3f04d2362b4940a5a9ae3b1 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use llvm::*;
+use llvm::ValueRef;
 use middle::def;
 use middle::lang_items::{PanicFnLangItem, PanicBoundsCheckFnLangItem};
 use trans::_match;
@@ -112,8 +112,17 @@ pub fn trans_block<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     if dest != expr::Ignore {
         let block_ty = node_id_type(bcx, b.id);
+
         if b.expr.is_none() || type_is_zero_size(bcx.ccx(), block_ty) {
             dest = expr::Ignore;
+        } else if b.expr.is_some() {
+            // If the block has an expression, but that expression isn't reachable,
+            // don't save into the destination given, ignore it.
+            if let Some(ref cfg) = bcx.fcx.cfg {
+                if !cfg.node_is_reachable(b.expr.as_ref().unwrap().id) {
+                    dest = expr::Ignore;
+                }
+            }
         }
     }
 
@@ -277,6 +286,7 @@ pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     debug!("iterator type is {}, datum type is {}",
            ppaux::ty_to_string(bcx.tcx(), iterator_type),
            ppaux::ty_to_string(bcx.tcx(), iterator_datum.ty));
+
     let lliterator = load_ty(bcx, iterator_datum.val, iterator_datum.ty);
 
     // Create our basic blocks and set up our loop cleanups.
@@ -356,6 +366,8 @@ pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                                        llpayload,
                                        binding_cleanup_scope_id);
 
+    debuginfo::create_for_loop_var_metadata(body_bcx_in, pat);
+
     // Codegen the body.
     body_bcx_out = trans_block(body_bcx_out, body, expr::Ignore);
     body_bcx_out =
index 9a5e6830da194b33998b58917e5612495bfc5f22..51e3a83f81f5a90c6b9e7c07dff3913a71630b7c 100644 (file)
 //! comparatively expensive to construct, though, `ty::type_id()` is still used
 //! additionally as an optimization for cases where the exact same type has been
 //! seen before (which is most of the time).
-use self::FunctionDebugContextRepr::*;
 use self::VariableAccess::*;
 use self::VariableKind::*;
 use self::MemberOffset::*;
@@ -334,7 +333,7 @@ fn get_unique_type_id_of_type<'a>(&mut self, cx: &CrateContext<'a, 'tcx>,
         // mut ptr (*mut)       -> {*mut :pointee-uid:}
         // unique ptr (~)       -> {~ :pointee-uid:}
         // @-ptr (@)            -> {@ :pointee-uid:}
-        // sized vec ([T, ..x]) -> {[:size:] :element-uid:}
+        // sized vec ([T; x])   -> {[:size:] :element-uid:}
         // unsized vec ([T])    -> {[] :element-uid:}
         // trait (T)            -> {trait_:svh: / :node-id:_<(:param-uid:),*> }
         // closure              -> {<unsafe_> <once_> :store-sigil: |(:param-uid:),* <,_...>| -> \
@@ -679,12 +678,8 @@ pub fn new(llmod: ModuleRef) -> CrateDebugContext<'tcx> {
     }
 }
 
-pub struct FunctionDebugContext {
-    repr: FunctionDebugContextRepr,
-}
-
-enum FunctionDebugContextRepr {
-    DebugInfo(Box<FunctionDebugContextData>),
+pub enum FunctionDebugContext {
+    RegularContext(Box<FunctionDebugContextData>),
     DebugInfoDisabled,
     FunctionWithoutDebugInfo,
 }
@@ -694,13 +689,13 @@ fn get_ref<'a>(&'a self,
                    cx: &CrateContext,
                    span: Span)
                    -> &'a FunctionDebugContextData {
-        match self.repr {
-            DebugInfo(box ref data) => data,
-            DebugInfoDisabled => {
+        match *self {
+            FunctionDebugContext::RegularContext(box ref data) => data,
+            FunctionDebugContext::DebugInfoDisabled => {
                 cx.sess().span_bug(span,
                                    FunctionDebugContext::debuginfo_disabled_message());
             }
-            FunctionWithoutDebugInfo => {
+            FunctionDebugContext::FunctionWithoutDebugInfo => {
                 cx.sess().span_bug(span,
                                    FunctionDebugContext::should_be_ignored_message());
             }
@@ -844,6 +839,8 @@ pub fn create_global_var_metadata(cx: &CrateContext,
 
 /// Creates debug information for the given local variable.
 ///
+/// This function assumes that there's a datum for each pattern component of the
+/// local in `bcx.fcx.lllocals`.
 /// Adds the created metadata nodes directly to the crate's IR.
 pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) {
     if fn_should_be_ignored(bcx.fcx) {
@@ -852,11 +849,10 @@ pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) {
 
     let cx = bcx.ccx();
     let def_map = &cx.tcx().def_map;
+    let locals = bcx.fcx.lllocals.borrow();
 
-    pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, path1| {
-        let var_ident = path1.node;
-
-        let datum = match bcx.fcx.lllocals.borrow().get(&node_id).cloned() {
+    pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, var_ident| {
+        let datum = match locals.get(&node_id) {
             Some(datum) => datum,
             None => {
                 bcx.sess().span_bug(span,
@@ -865,10 +861,15 @@ pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) {
             }
         };
 
+        if unsafe { llvm::LLVMIsAAllocaInst(datum.val) } == ptr::null_mut() {
+            cx.sess().span_bug(span, "debuginfo::create_local_var_metadata() - \
+                                      Referenced variable location is not an alloca!");
+        }
+
         let scope_metadata = scope_metadata(bcx.fcx, node_id, span);
 
         declare_local(bcx,
-                      var_ident,
+                      var_ident.node,
                       datum.ty,
                       scope_metadata,
                       DirectVariable { alloca: datum.val },
@@ -981,7 +982,7 @@ pub fn create_match_binding_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     // for the binding. For ByRef bindings that's a `T*` but for ByMove bindings we
     // actually have `T**`. So to get the actual variable we need to dereference once
     // more. For ByCopy we just use the stack slot we created for the binding.
-    let var_type = match binding.trmode {
+    let var_access = match binding.trmode {
         TrByCopy(llbinding) => DirectVariable {
             alloca: llbinding
         },
@@ -998,27 +999,31 @@ pub fn create_match_binding_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                   variable_ident,
                   binding.ty,
                   scope_metadata,
-                  var_type,
+                  var_access,
                   LocalVariable,
                   binding.span);
 }
 
 /// Creates debug information for the given function argument.
 ///
+/// This function assumes that there's a datum for each pattern component of the
+/// argument in `bcx.fcx.lllocals`.
 /// Adds the created metadata nodes directly to the crate's IR.
 pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) {
     if fn_should_be_ignored(bcx.fcx) {
         return;
     }
 
-    let fcx = bcx.fcx;
-    let cx = fcx.ccx;
+    let def_map = &bcx.tcx().def_map;
+    let scope_metadata = bcx
+                         .fcx
+                         .debug_context
+                         .get_ref(bcx.ccx(), arg.pat.span)
+                         .fn_metadata;
+    let locals = bcx.fcx.lllocals.borrow();
 
-    let def_map = &cx.tcx().def_map;
-    let scope_metadata = bcx.fcx.debug_context.get_ref(cx, arg.pat.span).fn_metadata;
-
-    pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, path1| {
-        let llarg = match bcx.fcx.lllocals.borrow().get(&node_id).cloned() {
+    pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, var_ident| {
+        let datum = match locals.get(&node_id) {
             Some(v) => v,
             None => {
                 bcx.sess().span_bug(span,
@@ -1027,28 +1032,72 @@ pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) {
             }
         };
 
-        if unsafe { llvm::LLVMIsAAllocaInst(llarg.val) } == ptr::null_mut() {
-            cx.sess().span_bug(span, "debuginfo::create_argument_metadata() - \
-                                    Referenced variable location is not an alloca!");
+        if unsafe { llvm::LLVMIsAAllocaInst(datum.val) } == ptr::null_mut() {
+            bcx.sess().span_bug(span, "debuginfo::create_argument_metadata() - \
+                                       Referenced variable location is not an alloca!");
         }
 
         let argument_index = {
-            let counter = &fcx.debug_context.get_ref(cx, span).argument_counter;
+            let counter = &bcx
+                          .fcx
+                          .debug_context
+                          .get_ref(bcx.ccx(), span)
+                          .argument_counter;
             let argument_index = counter.get();
             counter.set(argument_index + 1);
             argument_index
         };
 
         declare_local(bcx,
-                      path1.node,
-                      llarg.ty,
+                      var_ident.node,
+                      datum.ty,
                       scope_metadata,
-                      DirectVariable { alloca: llarg.val },
+                      DirectVariable { alloca: datum.val },
                       ArgumentVariable(argument_index),
                       span);
     })
 }
 
+/// Creates debug information for the given for-loop variable.
+///
+/// This function assumes that there's a datum for each pattern component of the
+/// loop variable in `bcx.fcx.lllocals`.
+/// Adds the created metadata nodes directly to the crate's IR.
+pub fn create_for_loop_var_metadata(bcx: Block, pat: &ast::Pat) {
+    if fn_should_be_ignored(bcx.fcx) {
+        return;
+    }
+
+    let def_map = &bcx.tcx().def_map;
+    let locals = bcx.fcx.lllocals.borrow();
+
+    pat_util::pat_bindings(def_map, pat, |_, node_id, span, var_ident| {
+        let datum = match locals.get(&node_id) {
+            Some(datum) => datum,
+            None => {
+                bcx.sess().span_bug(span,
+                    format!("no entry in lllocals table for {}",
+                            node_id).as_slice());
+            }
+        };
+
+        if unsafe { llvm::LLVMIsAAllocaInst(datum.val) } == ptr::null_mut() {
+            bcx.sess().span_bug(span, "debuginfo::create_for_loop_var_metadata() - \
+                                       Referenced variable location is not an alloca!");
+        }
+
+        let scope_metadata = scope_metadata(bcx.fcx, node_id, span);
+
+        declare_local(bcx,
+                      var_ident.node,
+                      datum.ty,
+                      scope_metadata,
+                      DirectVariable { alloca: datum.val },
+                      LocalVariable,
+                      span);
+    })
+}
+
 pub fn get_cleanup_debug_loc_for_ast_node<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                                     node_id: ast::NodeId,
                                                     node_span: Span,
@@ -1117,13 +1166,13 @@ pub fn get_cleanup_debug_loc_for_ast_node<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 pub fn set_source_location(fcx: &FunctionContext,
                            node_id: ast::NodeId,
                            span: Span) {
-    match fcx.debug_context.repr {
-        DebugInfoDisabled => return,
-        FunctionWithoutDebugInfo => {
+    match fcx.debug_context {
+        FunctionDebugContext::DebugInfoDisabled => return,
+        FunctionDebugContext::FunctionWithoutDebugInfo => {
             set_debug_location(fcx.ccx, UnknownLocation);
             return;
         }
-        DebugInfo(box ref function_debug_context) => {
+        FunctionDebugContext::RegularContext(box ref function_debug_context) => {
             let cx = fcx.ccx;
 
             debug!("set_source_location: {}", cx.sess().codemap().span_to_string(span));
@@ -1160,8 +1209,8 @@ pub fn clear_source_location(fcx: &FunctionContext) {
 /// switches source location emitting on and must therefore be called before the
 /// first real statement/expression of the function is translated.
 pub fn start_emitting_source_locations(fcx: &FunctionContext) {
-    match fcx.debug_context.repr {
-        DebugInfo(box ref data) => {
+    match fcx.debug_context {
+        FunctionDebugContext::RegularContext(box ref data) => {
             data.source_locations_enabled.set(true)
         },
         _ => { /* safe to ignore */ }
@@ -1179,7 +1228,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                                param_substs: &Substs<'tcx>,
                                                llfn: ValueRef) -> FunctionDebugContext {
     if cx.sess().opts.debuginfo == NoDebugInfo {
-        return FunctionDebugContext { repr: DebugInfoDisabled };
+        return FunctionDebugContext::DebugInfoDisabled;
     }
 
     // Clear the debug location so we don't assign them in the function prelude.
@@ -1189,7 +1238,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     if fn_ast_id == ast::DUMMY_NODE_ID {
         // This is a function not linked to any source location, so don't
         // generate debuginfo for it.
-        return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
+        return FunctionDebugContext::FunctionWithoutDebugInfo;
     }
 
     let empty_generics = ast_util::empty_generics();
@@ -1199,7 +1248,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let (ident, fn_decl, generics, top_level_block, span, has_path) = match fnitem {
         ast_map::NodeItem(ref item) => {
             if contains_nodebug_attribute(item.attrs.as_slice()) {
-                return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
+                return FunctionDebugContext::FunctionWithoutDebugInfo;
             }
 
             match item.node {
@@ -1216,9 +1265,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             match **item {
                 ast::MethodImplItem(ref method) => {
                     if contains_nodebug_attribute(method.attrs.as_slice()) {
-                        return FunctionDebugContext {
-                            repr: FunctionWithoutDebugInfo
-                        };
+                        return FunctionDebugContext::FunctionWithoutDebugInfo;
                     }
 
                     (method.pe_ident(),
@@ -1257,9 +1304,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             match **trait_method {
                 ast::ProvidedMethod(ref method) => {
                     if contains_nodebug_attribute(method.attrs.as_slice()) {
-                        return FunctionDebugContext {
-                            repr: FunctionWithoutDebugInfo
-                        };
+                        return FunctionDebugContext::FunctionWithoutDebugInfo;
                     }
 
                     (method.pe_ident(),
@@ -1280,7 +1325,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         ast_map::NodeForeignItem(..) |
         ast_map::NodeVariant(..) |
         ast_map::NodeStructCtor(..) => {
-            return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
+            return FunctionDebugContext::FunctionWithoutDebugInfo;
         }
         _ => cx.sess().bug(format!("create_function_debug_context: \
                                     unexpected sort of node: {}",
@@ -1289,7 +1334,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     // This can be the case for functions inlined from another crate
     if span == codemap::DUMMY_SP {
-        return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
+        return FunctionDebugContext::FunctionWithoutDebugInfo;
     }
 
     let loc = span_start(cx, span);
@@ -1356,22 +1401,23 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         })
     });
 
+    let scope_map = create_scope_map(cx,
+                                     fn_decl.inputs.as_slice(),
+                                     &*top_level_block,
+                                     fn_metadata,
+                                     fn_ast_id);
+
     // Initialize fn debug context (including scope map and namespace map)
     let fn_debug_context = box FunctionDebugContextData {
-        scope_map: RefCell::new(NodeMap::new()),
+        scope_map: RefCell::new(scope_map),
         fn_metadata: fn_metadata,
         argument_counter: Cell::new(1),
         source_locations_enabled: Cell::new(false),
     };
 
-    populate_scope_map(cx,
-                       fn_decl.inputs.as_slice(),
-                       &*top_level_block,
-                       fn_metadata,
-                       fn_ast_id,
-                       &mut *fn_debug_context.scope_map.borrow_mut());
 
-    return FunctionDebugContext { repr: DebugInfo(fn_debug_context) };
+
+    return FunctionDebugContext::RegularContext(fn_debug_context);
 
     fn get_function_signature<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                         fn_ast_id: ast::NodeId,
@@ -3134,8 +3180,8 @@ fn DIB(cx: &CrateContext) -> DIBuilderRef {
 }
 
 fn fn_should_be_ignored(fcx: &FunctionContext) -> bool {
-    match fcx.debug_context.repr {
-        DebugInfo(_) => false,
+    match fcx.debug_context {
+        FunctionDebugContext::RegularContext(_) => false,
         _ => true
     }
 }
@@ -3169,12 +3215,14 @@ fn get_namespace_and_span_for_item(cx: &CrateContext, def_id: ast::DefId)
 // what belongs to which scope, creating DIScope DIEs along the way, and
 // introducing *artificial* lexical scope descriptors where necessary. These
 // artificial scopes allow GDB to correctly handle name shadowing.
-fn populate_scope_map(cx: &CrateContext,
-                      args: &[ast::Arg],
-                      fn_entry_block: &ast::Block,
-                      fn_metadata: DISubprogram,
-                      fn_ast_id: ast::NodeId,
-                      scope_map: &mut NodeMap<DIScope>) {
+fn create_scope_map(cx: &CrateContext,
+                    args: &[ast::Arg],
+                    fn_entry_block: &ast::Block,
+                    fn_metadata: DISubprogram,
+                    fn_ast_id: ast::NodeId)
+                 -> NodeMap<DIScope> {
+    let mut scope_map = NodeMap::new();
+
     let def_map = &cx.tcx().def_map;
 
     struct ScopeStackEntry {
@@ -3200,11 +3248,14 @@ struct ScopeStackEntry {
     with_new_scope(cx,
                    fn_entry_block.span,
                    &mut scope_stack,
-                   scope_map,
+                   &mut scope_map,
                    |cx, scope_stack, scope_map| {
         walk_block(cx, fn_entry_block, scope_stack, scope_map);
     });
 
+    return scope_map;
+
+
     // local helper functions for walking the AST.
     fn with_new_scope<F>(cx: &CrateContext,
                          scope_span: Span,
@@ -3440,7 +3491,7 @@ fn walk_pattern(cx: &CrateContext,
             }
 
             ast::PatMac(_) => {
-                cx.sess().span_bug(pat.span, "debuginfo::populate_scope_map() - \
+                cx.sess().span_bug(pat.span, "debuginfo::create_scope_map() - \
                                               Found unexpanded macro.");
             }
         }
@@ -3526,7 +3577,7 @@ fn walk_expr(cx: &CrateContext,
             }
 
             ast::ExprIfLet(..) => {
-                cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \
+                cx.sess().span_bug(exp.span, "debuginfo::create_scope_map() - \
                                               Found unexpanded if-let.");
             }
 
@@ -3543,7 +3594,7 @@ fn walk_expr(cx: &CrateContext,
             }
 
             ast::ExprWhileLet(..) => {
-                cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \
+                cx.sess().span_bug(exp.span, "debuginfo::create_scope_map() - \
                                               Found unexpanded while-let.");
             }
 
@@ -3568,7 +3619,7 @@ fn walk_expr(cx: &CrateContext,
             }
 
             ast::ExprMac(_) => {
-                cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \
+                cx.sess().span_bug(exp.span, "debuginfo::create_scope_map() - \
                                               Found unexpanded macro.");
             }
 
@@ -3752,7 +3803,7 @@ fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
             match optional_length {
                 Some(len) => {
-                    output.push_str(format!(", ..{}", len).as_slice());
+                    output.push_str(format!("{}", len).as_slice());
                 }
                 None => { /* nothing to do */ }
             };
index dd87879b7375506d7e2a5c4256aafd1b627fb1a5..81892e5fa83219923b1b7a58cfffd6f45d5ca7e6 100644 (file)
@@ -926,7 +926,29 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             controlflow::trans_cont(bcx, expr.id, label_opt)
         }
         ast::ExprRet(ref ex) => {
-            controlflow::trans_ret(bcx, ex.as_ref().map(|e| &**e))
+            // Check to see if the return expression itself is reachable.
+            // This can occur when the inner expression contains a return
+            let reachable = if let Some(ref cfg) = bcx.fcx.cfg {
+                cfg.node_is_reachable(expr.id)
+            } else {
+                true
+            };
+
+            if reachable {
+                controlflow::trans_ret(bcx, ex.as_ref().map(|e| &**e))
+            } else {
+                // If it's not reachable, just translate the inner expression
+                // directly. This avoids having to manage a return slot when
+                // it won't actually be used anyway.
+                if let &Some(ref x) = ex {
+                    bcx = trans_into(bcx, &**x, Ignore);
+                }
+                // Mark the end of the block as unreachable. Once we get to
+                // a return expression, there's no more we should be doing
+                // after this.
+                Unreachable(bcx);
+                bcx
+            }
         }
         ast::ExprWhile(ref cond, ref body, _) => {
             controlflow::trans_while(bcx, expr.id, &**cond, &**body)
index f1c3c9be396af0c93d7d4a17f729b51bf22080ea..15f6d7bc3f42d7d11b7ffe7b5b24cd9dc4480886 100644 (file)
@@ -124,7 +124,7 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 bcx: bcx,
                 data: Fn(callee::trans_fn_ref(bcx,
                                               did,
-                                              MethodCall(method_call))),
+                                              MethodCallKey(method_call))),
             }
         }
 
@@ -344,12 +344,12 @@ fn trans_monomorphized_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             // those from the impl and those from the method:
             let callee_substs =
                 combine_impl_and_methods_tps(
-                    bcx, MethodCall(method_call), vtable_impl.substs);
+                    bcx, MethodCallKey(method_call), vtable_impl.substs);
 
             // translate the function
             let llfn = trans_fn_ref_with_substs(bcx,
                                                 mth_id,
-                                                MethodCall(method_call),
+                                                MethodCallKey(method_call),
                                                 callee_substs);
 
             Callee { bcx: bcx, data: Fn(llfn) }
@@ -359,7 +359,7 @@ fn trans_monomorphized_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             // after passing through fulfill_obligation
             let llfn = trans_fn_ref_with_substs(bcx,
                                                 closure_def_id,
-                                                MethodCall(method_call),
+                                                MethodCallKey(method_call),
                                                 substs);
 
             Callee {
index 4f4bebabead2cf538ed1228faeb71adb8611dcbb..175763c874efa4e70733f461408f1ba1efb40949 100644 (file)
@@ -1437,11 +1437,8 @@ pub fn conv_existential_bounds<'tcx, AC: AstConv<'tcx>, RS:RegionScope>(
     ast_bounds: &[ast::TyParamBound])
     -> ty::ExistentialBounds
 {
-    let ast_bound_refs: Vec<&ast::TyParamBound> =
-        ast_bounds.iter().collect();
-
     let partitioned_bounds =
-        partition_bounds(this.tcx(), span, ast_bound_refs.as_slice());
+        partition_bounds(this.tcx(), span, ast_bounds);
 
     conv_existential_bounds_from_partitioned_bounds(
         this, rscope, span, principal_trait_ref, partitioned_bounds)
@@ -1455,7 +1452,6 @@ fn conv_ty_poly_trait_ref<'tcx, AC, RS>(
     -> Ty<'tcx>
     where AC: AstConv<'tcx>, RS:RegionScope
 {
-    let ast_bounds: Vec<&ast::TyParamBound> = ast_bounds.iter().collect();
     let mut partitioned_bounds = partition_bounds(this.tcx(), span, ast_bounds[]);
 
     let main_trait_bound = match partitioned_bounds.trait_bounds.remove(0) {
@@ -1620,14 +1616,14 @@ pub struct PartitionedBounds<'a> {
 /// general trait bounds, and region bounds.
 pub fn partition_bounds<'a>(tcx: &ty::ctxt,
                             _span: Span,
-                            ast_bounds: &'a [&ast::TyParamBound])
+                            ast_bounds: &'a [ast::TyParamBound])
                             -> PartitionedBounds<'a>
 {
     let mut builtin_bounds = ty::empty_builtin_bounds();
     let mut region_bounds = Vec::new();
     let mut trait_bounds = Vec::new();
     let mut trait_def_ids = DefIdMap::new();
-    for &ast_bound in ast_bounds.iter() {
+    for ast_bound in ast_bounds.iter() {
         match *ast_bound {
             ast::TraitTyParamBound(ref b) => {
                 match ::lookup_def_tcx(tcx, b.trait_ref.path.span, b.trait_ref.ref_id) {
index 44cc5fce53da35c81c0f118e2eff0b7382f2324f..35ffa8ace406f50b4f11a593e494d9f3cc65cde5 100644 (file)
@@ -21,7 +21,7 @@
 use util::ppaux::Repr;
 
 use std::cmp;
-use std::collections::hash_map::{Occupied, Vacant};
+use std::collections::hash_map::Entry::{Occupied, Vacant};
 use syntax::ast;
 use syntax::ast_util;
 use syntax::codemap::{Span, Spanned};
@@ -238,7 +238,8 @@ pub fn check_match<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                              expr: &ast::Expr,
                              discrim: &ast::Expr,
                              arms: &[ast::Arm],
-                             expected: Expectation<'tcx>) {
+                             expected: Expectation<'tcx>,
+                             match_src: ast::MatchSource) {
     let tcx = fcx.ccx.tcx;
 
     let discrim_ty = fcx.infcx().next_ty_var();
@@ -290,12 +291,27 @@ pub fn check_match<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         if ty::type_is_error(result_ty) || ty::type_is_error(bty) {
             ty::mk_err()
         } else {
+            let (origin, expected, found) = match match_src {
+                /* if-let construct without an else block */
+                ast::MatchSource::IfLetDesugar { contains_else_clause }
+                if !contains_else_clause => (
+                    infer::IfExpressionWithNoElse(expr.span),
+                    bty,
+                    result_ty,
+                ),
+                _ => (
+                    infer::MatchExpressionArm(expr.span, arm.body.span),
+                    result_ty,
+                    bty,
+                ),
+            };
+
             infer::common_supertype(
                 fcx.infcx(),
-                infer::MatchExpressionArm(expr.span, arm.body.span),
-                true, // result_ty is "expected" here
-                result_ty,
-                bty
+                origin,
+                true,
+                expected,
+                found,
             )
         }
     });
index 2ade3040d6cff52e4b8382ce47c447b09bca0da8..092260523670745db03f5c5442c27371a7ab82f8 100644 (file)
@@ -261,44 +261,43 @@ fn check_boxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
     // Find the expected input/output types (if any). Substitute
     // fresh bound regions for any bound regions we find in the
     // expected types so as to avoid capture.
-    let expected_sty = expected.map_to_option(fcx, |x| Some((*x).clone()));
-    let (expected_sig,
-         expected_onceness,
-         expected_bounds) = {
-        match expected_sty {
-            Some(ty::ty_closure(ref cenv)) => {
-                let (sig, _) =
-                    ty::replace_late_bound_regions(
-                        tcx,
-                        &cenv.sig,
-                        |_, debruijn| fcx.inh.infcx.fresh_bound_region(debruijn));
-                let onceness = match (&store, &cenv.store) {
-                    // As the closure type and onceness go, only three
-                    // combinations are legit:
-                    //      once closure
-                    //      many closure
-                    //      once proc
-                    // If the actual and expected closure type disagree with
-                    // each other, set expected onceness to be always Once or
-                    // Many according to the actual type. Otherwise, it will
-                    // yield either an illegal "many proc" or a less known
-                    // "once closure" in the error message.
-                    (&ty::UniqTraitStore, &ty::UniqTraitStore) |
-                    (&ty::RegionTraitStore(..), &ty::RegionTraitStore(..)) =>
-                        cenv.onceness,
-                    (&ty::UniqTraitStore, _) => ast::Once,
-                    (&ty::RegionTraitStore(..), _) => ast::Many,
-                };
-                (Some(sig), onceness, cenv.bounds)
-            }
-            _ => {
-                // Not an error! Means we're inferring the closure type
-                let region = fcx.infcx().next_region_var(
-                    infer::AddrOfRegion(expr.span));
-                let bounds = ty::region_existential_bound(region);
-                let onceness = ast::Many;
-                (None, onceness, bounds)
-            }
+    let expected_cenv = expected.map_to_option(fcx, |ty| match ty.sty {
+        ty::ty_closure(ref cenv) => Some(cenv),
+        _ => None
+    });
+    let (expected_sig, expected_onceness, expected_bounds) = match expected_cenv {
+        Some(cenv) => {
+            let (sig, _) =
+                ty::replace_late_bound_regions(
+                    tcx,
+                    &cenv.sig,
+                    |_, debruijn| fcx.inh.infcx.fresh_bound_region(debruijn));
+            let onceness = match (&store, &cenv.store) {
+                // As the closure type and onceness go, only three
+                // combinations are legit:
+                //      once closure
+                //      many closure
+                //      once proc
+                // If the actual and expected closure type disagree with
+                // each other, set expected onceness to be always Once or
+                // Many according to the actual type. Otherwise, it will
+                // yield either an illegal "many proc" or a less known
+                // "once closure" in the error message.
+                (&ty::UniqTraitStore, &ty::UniqTraitStore) |
+                (&ty::RegionTraitStore(..), &ty::RegionTraitStore(..)) =>
+                    cenv.onceness,
+                (&ty::UniqTraitStore, _) => ast::Once,
+                (&ty::RegionTraitStore(..), _) => ast::Many,
+            };
+            (Some(sig), onceness, cenv.bounds)
+        }
+        _ => {
+            // Not an error! Means we're inferring the closure type
+            let region = fcx.infcx().next_region_var(
+                infer::AddrOfRegion(expr.span));
+            let bounds = ty::region_existential_bound(region);
+            let onceness = ast::Many;
+            (None, onceness, bounds)
         }
     };
 
index bbc33826f35519af565553491638aadb448ff99b..cd9a09efe082bc1dafb34f12bdd4ceb82c102c45 100644 (file)
@@ -2042,7 +2042,7 @@ fn try_overloaded_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                  -> bool {
     // Bail out if the callee is a bare function or a closure. We check those
     // manually.
-    match *structure_of(fcx, callee.span, callee_type) {
+    match structurally_resolved_type(fcx, callee.span, callee_type).sty {
         ty::ty_bare_fn(_) | ty::ty_closure(_) => return false,
         _ => {}
     }
@@ -2717,10 +2717,9 @@ fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         ast::LitInt(_, ast::SignedIntLit(t, _)) => ty::mk_mach_int(t),
         ast::LitInt(_, ast::UnsignedIntLit(t)) => ty::mk_mach_uint(t),
         ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
-            let opt_ty = expected.map_to_option(fcx, |sty| {
-                match *sty {
-                    ty::ty_int(i) => Some(ty::mk_mach_int(i)),
-                    ty::ty_uint(i) => Some(ty::mk_mach_uint(i)),
+            let opt_ty = expected.map_to_option(fcx, |ty| {
+                match ty.sty {
+                    ty::ty_int(_) | ty::ty_uint(_) => Some(ty),
                     ty::ty_char => Some(ty::mk_mach_uint(ast::TyU8)),
                     ty::ty_ptr(..) => Some(ty::mk_mach_uint(ast::TyU)),
                     ty::ty_bare_fn(..) => Some(ty::mk_mach_uint(ast::TyU)),
@@ -2732,9 +2731,9 @@ fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         }
         ast::LitFloat(_, t) => ty::mk_mach_float(t),
         ast::LitFloatUnsuffixed(_) => {
-            let opt_ty = expected.map_to_option(fcx, |sty| {
-                match *sty {
-                    ty::ty_float(i) => Some(ty::mk_mach_float(i)),
+            let opt_ty = expected.map_to_option(fcx, |ty| {
+                match ty.sty {
+                    ty::ty_float(_) => Some(ty),
                     _ => None
                 }
             });
@@ -2910,7 +2909,7 @@ fn check_call(fcx: &FnCtxt,
         let fn_ty = fcx.expr_ty(f);
 
         // Extract the function signature from `in_fty`.
-        let fn_sty = structure_of(fcx, f.span, fn_ty);
+        let fn_ty = structurally_resolved_type(fcx, f.span, fn_ty);
 
         // This is the "default" function signature, used in case of error.
         // In that case, we check each argument against "error" in order to
@@ -2921,7 +2920,7 @@ fn check_call(fcx: &FnCtxt,
             variadic: false
         });
 
-        let fn_sig = match *fn_sty {
+        let fn_sig = match fn_ty.sty {
             ty::ty_bare_fn(ty::BareFnTy {ref sig, ..}) |
             ty::ty_closure(box ty::ClosureTy {ref sig, ..}) => sig,
             _ => {
@@ -3655,9 +3654,9 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
         }
       }
       ast::ExprUnary(unop, ref oprnd) => {
-        let expected_inner = expected.map(fcx, |sty| {
+        let expected_inner = expected.map(fcx, |ty| {
             match unop {
-                ast::UnUniq => match *sty {
+                ast::UnUniq => match ty.sty {
                     ty::ty_uniq(ty) => {
                         ExpectHasType(ty)
                     }
@@ -3746,9 +3745,11 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
       }
       ast::ExprAddrOf(mutbl, ref oprnd) => {
         let expected = expected.only_has_type();
-        let hint = expected.map(fcx, |sty| {
-            match *sty { ty::ty_rptr(_, ref mt) | ty::ty_ptr(ref mt) => ExpectHasType(mt.ty),
-                         _ => NoExpectation }
+        let hint = expected.map(fcx, |ty| {
+            match ty.sty {
+                ty::ty_rptr(_, ref mt) | ty::ty_ptr(ref mt) => ExpectHasType(mt.ty),
+                _ => NoExpectation
+            }
         });
         let lvalue_pref = match mutbl {
             ast::MutMutable => PreferMutLvalue,
@@ -3918,8 +3919,8 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
             fcx.write_nil(id);
         }
       }
-      ast::ExprMatch(ref discrim, ref arms, _) => {
-        _match::check_match(fcx, expr, &**discrim, arms.as_slice(), expected);
+      ast::ExprMatch(ref discrim, ref arms, match_src) => {
+        _match::check_match(fcx, expr, &**discrim, arms.as_slice(), expected, match_src);
       }
       ast::ExprClosure(_, opt_kind, ref decl, ref body) => {
           closure::check_expr_closure(fcx, expr, opt_kind, &**decl, &**body, expected);
@@ -4037,9 +4038,9 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
       }
       ast::ExprTup(ref elts) => {
         let expected = expected.only_has_type();
-        let flds = expected.map_to_option(fcx, |sty| {
-            match *sty {
-                ty::ty_tup(ref flds) => Some((*flds).clone()),
+        let flds = expected.map_to_option(fcx, |ty| {
+            match ty.sty {
+                ty::ty_tup(ref flds) => Some(flds[]),
                 _ => None
             }
         });
@@ -4304,20 +4305,20 @@ fn resolve<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
     }
 
     fn map<'a, F>(self, fcx: &FnCtxt<'a, 'tcx>, unpack: F) -> Expectation<'tcx> where
-        F: FnOnce(&ty::sty<'tcx>) -> Expectation<'tcx>
+        F: FnOnce(Ty<'tcx>) -> Expectation<'tcx>
     {
         match self.resolve(fcx) {
             NoExpectation => NoExpectation,
-            ExpectCastableToType(t) | ExpectHasType(t) => unpack(&t.sty),
+            ExpectCastableToType(ty) | ExpectHasType(ty) => unpack(ty),
         }
     }
 
     fn map_to_option<'a, O, F>(self, fcx: &FnCtxt<'a, 'tcx>, unpack: F) -> Option<O> where
-        F: FnOnce(&ty::sty<'tcx>) -> Option<O>,
+        F: FnOnce(Ty<'tcx>) -> Option<O>,
     {
         match self.resolve(fcx) {
             NoExpectation => None,
-            ExpectCastableToType(t) | ExpectHasType(t) => unpack(&t.sty),
+            ExpectCastableToType(ty) | ExpectHasType(ty) => unpack(ty),
         }
     }
 }
@@ -5320,12 +5321,6 @@ pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
     ty
 }
 
-// Returns the one-level-deep structure of the given type.
-pub fn structure_of<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span, typ: Ty<'tcx>)
-                        -> &'tcx ty::sty<'tcx> {
-    &structurally_resolved_type(fcx, sp, typ).sty
-}
-
 // Returns true if b contains a break that can exit from b
 pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &ast::Block) -> bool {
     // First: is there an unlabeled break immediately
index 33c015a9a081cba3cf9895cbc97f531cb14bd7d6..8e70b8ff0da50c84f4fae9932eb432131f901756 100644 (file)
 use syntax::visit::Visitor;
 
 use std::cell::{RefCell};
-use std::collections::hash_map::{Vacant, Occupied};
+use std::collections::hash_map::Entry::{Vacant, Occupied};
 
 use self::RepeatingScope::Repeating;
 use self::SubjectNode::Subject;
index c09ce3db6ddd21ed15b47c0f5c6b6be0c97e032a..24d7bf5031e46c8a6687c86dbf82cd6ac70ad446 100644 (file)
@@ -17,7 +17,7 @@
 use middle::traits;
 use middle::ty::{mod, Ty};
 use middle::ty::liberate_late_bound_regions;
-use middle::ty_fold::{TypeFolder, TypeFoldable};
+use middle::ty_fold::{TypeFolder, TypeFoldable, super_fold_ty};
 use util::ppaux::Repr;
 
 use std::collections::HashSet;
@@ -368,8 +368,8 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
 
                 self.binding_count -= 1;
             }
-            ref sty => {
-                self.fold_sty(sty);
+            _ => {
+                super_fold_ty(self, t);
             }
         }
 
index 4612acb04b2f021cfaae0e25bd85a75cf1eed8c8..3f59b50337faf144bee74bc8388c1ceb7d7d7304 100644 (file)
@@ -1364,8 +1364,7 @@ pub fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                 self_param_ty,
                                 bounds.as_slice(),
                                 unbound,
-                                it.span,
-                                &generics.where_clause);
+                                it.span);
 
     let substs = mk_item_substs(ccx, &ty_generics);
     let trait_def = Rc::new(ty::TraitDef {
@@ -1619,7 +1618,6 @@ fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                         subst::AssocSpace,
                         &associated_type.ty_param,
                         generics.types.len(subst::AssocSpace),
-                        &ast_generics.where_clause,
                         Some(local_def(trait_id)));
                 ccx.tcx.ty_param_defs.borrow_mut().insert(associated_type.ty_param.id,
                                                           def.clone());
@@ -1774,7 +1772,6 @@ fn ty_generics<'tcx,AC>(this: &AC,
                                                    space,
                                                    param,
                                                    i,
-                                                   where_clause,
                                                    None);
         debug!("ty_generics: def for type param: {}, {}",
                def.repr(this.tcx()),
@@ -1798,6 +1795,54 @@ fn ty_generics<'tcx,AC>(this: &AC,
     // into the predicates list. This is currently kind of non-DRY.
     create_predicates(this.tcx(), &mut result, space);
 
+    // Add the bounds not associated with a type parameter
+    for predicate in where_clause.predicates.iter() {
+        match predicate {
+            &ast::WherePredicate::BoundPredicate(ref bound_pred) => {
+                let ty = ast_ty_to_ty(this, &ExplicitRscope, &*bound_pred.bounded_ty);
+
+                for bound in bound_pred.bounds.iter() {
+                    match bound {
+                        &ast::TyParamBound::TraitTyParamBound(ref poly_trait_ref) => {
+                            let trait_ref = astconv::instantiate_poly_trait_ref(
+                                this,
+                                &ExplicitRscope,
+                                //@jroesch: for now trait_ref, poly_trait_ref?
+                                poly_trait_ref,
+                                Some(ty),
+                                AllowEqConstraints::Allow
+                            );
+
+                            result.predicates.push(space, ty::Predicate::Trait(trait_ref));
+                        }
+
+                        &ast::TyParamBound::RegionTyParamBound(ref lifetime) => {
+                            let region = ast_region_to_region(this.tcx(), lifetime);
+                            let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
+                            result.predicates.push(space, ty::Predicate::TypeOutlives(pred))
+                        }
+                    }
+                }
+            }
+
+            &ast::WherePredicate::RegionPredicate(ref region_pred) => {
+                let r1 = ast_region_to_region(this.tcx(), &region_pred.lifetime);
+                for bound in region_pred.bounds.iter() {
+                    let r2 = ast_region_to_region(this.tcx(), bound);
+                    let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
+                    result.predicates.push(space, ty::Predicate::RegionOutlives(pred))
+                }
+            }
+
+            &ast::WherePredicate::EqPredicate(ref eq_pred) => {
+                // FIXME(#20041)
+                this.tcx().sess.span_bug(eq_pred.span,
+                                         "Equality constraints are not yet \
+                                            implemented (#20041)")
+            }
+        }
+    }
+
     return result;
 
     fn create_type_parameters_for_associated_types<'tcx, AC>(
@@ -1915,7 +1960,6 @@ fn get_or_create_type_parameter_def<'tcx,AC>(this: &AC,
                                              space: subst::ParamSpace,
                                              param: &ast::TyParam,
                                              index: uint,
-                                             where_clause: &ast::WhereClause,
                                              associated_with: Option<ast::DefId>)
                                              -> ty::TypeParameterDef<'tcx>
     where AC: AstConv<'tcx>
@@ -1931,8 +1975,7 @@ fn get_or_create_type_parameter_def<'tcx,AC>(this: &AC,
                                 param_ty,
                                 param.bounds.as_slice(),
                                 &param.unbound,
-                                param.span,
-                                where_clause);
+                                param.span);
     let default = match param.default {
         None => None,
         Some(ref path) => {
@@ -1977,15 +2020,13 @@ fn compute_bounds<'tcx,AC>(this: &AC,
                            param_ty: ty::ParamTy,
                            ast_bounds: &[ast::TyParamBound],
                            unbound: &Option<ast::TraitRef>,
-                           span: Span,
-                           where_clause: &ast::WhereClause)
+                           span: Span)
                            -> ty::ParamBounds<'tcx>
                            where AC: AstConv<'tcx> {
     let mut param_bounds = conv_param_bounds(this,
                                              span,
                                              param_ty,
-                                             ast_bounds,
-                                             where_clause);
+                                             ast_bounds);
 
 
     add_unsized_bound(this,
@@ -2031,16 +2072,14 @@ fn check_bounds_compatible<'tcx>(tcx: &ty::ctxt<'tcx>,
 fn conv_param_bounds<'tcx,AC>(this: &AC,
                               span: Span,
                               param_ty: ty::ParamTy,
-                              ast_bounds: &[ast::TyParamBound],
-                              where_clause: &ast::WhereClause)
+                              ast_bounds: &[ast::TyParamBound])
                               -> ty::ParamBounds<'tcx>
-                              where AC: AstConv<'tcx> {
-    let all_bounds =
-        merge_param_bounds(this.tcx(), param_ty, ast_bounds, where_clause);
+                              where AC: AstConv<'tcx>
+{
     let astconv::PartitionedBounds { builtin_bounds,
                                      trait_bounds,
                                      region_bounds } =
-        astconv::partition_bounds(this.tcx(), span, all_bounds.as_slice());
+        astconv::partition_bounds(this.tcx(), span, ast_bounds.as_slice());
     let trait_bounds: Vec<Rc<ty::PolyTraitRef>> =
         trait_bounds.into_iter()
         .map(|bound| {
@@ -2062,43 +2101,6 @@ fn conv_param_bounds<'tcx,AC>(this: &AC,
     }
 }
 
-/// Merges the bounds declared on a type parameter with those found from where clauses into a
-/// single list.
-fn merge_param_bounds<'a>(tcx: &ty::ctxt,
-                          param_ty: ty::ParamTy,
-                          ast_bounds: &'a [ast::TyParamBound],
-                          where_clause: &'a ast::WhereClause)
-                          -> Vec<&'a ast::TyParamBound> {
-    let mut result = Vec::new();
-
-    for ast_bound in ast_bounds.iter() {
-        result.push(ast_bound);
-    }
-
-    for predicate in where_clause.predicates.iter() {
-        match predicate {
-            &ast::WherePredicate::BoundPredicate(ref bound_pred) => {
-                let predicate_param_id =
-                    tcx.def_map
-                       .borrow()
-                       .get(&bound_pred.id)
-                       .expect("merge_param_bounds(): resolve didn't resolve the \
-                                type parameter identifier in a `where` clause")
-                       .def_id();
-                if param_ty.def_id != predicate_param_id {
-                    continue
-                }
-                for bound in bound_pred.bounds.iter() {
-                    result.push(bound);
-                }
-            }
-            &ast::WherePredicate::EqPredicate(_) => panic!("not implemented")
-        }
-    }
-
-    result
-}
-
 pub fn ty_of_foreign_fn_decl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                        decl: &ast::FnDecl,
                                        def_id: ast::DefId,
index 5fc2466674ebe61dc9ba1bd5c51a7cf2364b1b6c..49c5f13fa73972a80393b046e4cdd93a55237ec1 100644 (file)
@@ -71,7 +71,7 @@
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/")]
 
-#![feature(default_type_params, globs, import_shadowing, macro_rules, phase, quote)]
+#![feature(default_type_params, globs, macro_rules, phase, quote)]
 #![feature(slicing_syntax, unsafe_destructor)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(unboxed_closures)]
@@ -90,7 +90,6 @@
 pub use rustc::util;
 
 use middle::def;
-use middle::resolve;
 use middle::infer;
 use middle::subst;
 use middle::subst::VecPerParamSpace;
@@ -121,7 +120,7 @@ struct TypeAndSubsts<'tcx> {
 
 struct CrateCtxt<'a, 'tcx: 'a> {
     // A mapping from method call sites to traits that have that method.
-    trait_map: resolve::TraitMap,
+    trait_map: ty::TraitMap,
     tcx: &'a ty::ctxt<'tcx>
 }
 
@@ -316,7 +315,7 @@ fn check_for_entry_fn(ccx: &CrateCtxt) {
     }
 }
 
-pub fn check_crate(tcx: &ty::ctxt, trait_map: resolve::TraitMap) {
+pub fn check_crate(tcx: &ty::ctxt, trait_map: ty::TraitMap) {
     let time_passes = tcx.sess.time_passes();
     let ccx = CrateCtxt {
         trait_map: trait_map,
index ed92320279591db599b9a3e67c807aca881100bb..ac688784f926cb3996b794a548818b36e9ea68a2 100644 (file)
@@ -163,33 +163,24 @@ fn clean(&self, cx: &DocContext) -> Crate {
             };
             let mut tmp = Vec::new();
             for child in m.items.iter_mut() {
-                let inner = match child.inner {
-                    ModuleItem(ref mut m) => m,
+                match child.inner {
+                    ModuleItem(..) => {}
                     _ => continue,
-                };
+                }
                 let prim = match PrimitiveType::find(child.attrs.as_slice()) {
                     Some(prim) => prim,
                     None => continue,
                 };
                 primitives.push(prim);
-                let mut i = Item {
+                tmp.push(Item {
                     source: Span::empty(),
                     name: Some(prim.to_url_str().to_string()),
-                    attrs: Vec::new(),
-                    visibility: None,
+                    attrs: child.attrs.clone(),
+                    visibility: Some(ast::Public),
                     stability: None,
                     def_id: ast_util::local_def(prim.to_node_id()),
                     inner: PrimitiveItem(prim),
-                };
-                // Push one copy to get indexed for the whole crate, and push a
-                // another copy in the proper location which will actually get
-                // documented. The first copy will also serve as a redirect to
-                // the other copy.
-                tmp.push(i.clone());
-                i.visibility = Some(ast::Public);
-                i.attrs = child.attrs.clone();
-                inner.items.push(i);
-
+                });
             }
             m.items.extend(tmp.into_iter());
         }
@@ -693,7 +684,7 @@ fn clean(&self, cx: &DocContext) -> Option<Lifetime> {
 
 #[deriving(Clone, Encodable, Decodable, PartialEq)]
 pub struct WherePredicate {
-    pub name: String,
+    pub ty: Type,
     pub bounds: Vec<TyParamBound>
 }
 
@@ -702,11 +693,12 @@ fn clean(&self, cx: &DocContext) -> WherePredicate {
         match *self {
             ast::WherePredicate::BoundPredicate(ref wbp) => {
                 WherePredicate {
-                    name: wbp.ident.clean(cx),
+                    ty: wbp.bounded_ty.clean(cx),
                     bounds: wbp.bounds.clean(cx)
                 }
             }
-            ast::WherePredicate::EqPredicate(_) => {
+            // FIXME(#20048)
+            _ => {
                 unimplemented!();
             }
         }
index 5572bcb6aa8f0053fe9bcac024c3225975928de2..e01cbbc812b8e1b15fb693be99df9092608f305f 100644 (file)
@@ -129,7 +129,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                 try!(f.write(", ".as_bytes()));
             }
             let bounds = pred.bounds.as_slice();
-            try!(write!(f, "{}: {}", pred.name, TyParamBounds(bounds)));
+            try!(write!(f, "{}: {}", pred.ty, TyParamBounds(bounds)));
         }
         Ok(())
     }
index 8831b5e7d96fe5db5675c3f3055bc1abb8a3fe9f..efec620bca758ee6e2e794fb62e28fad54d077b0 100644 (file)
@@ -35,7 +35,7 @@
 pub use self::ExternalLocation::*;
 
 use std::cell::RefCell;
-use std::collections::hash_map::{Occupied, Vacant};
+use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::collections::{HashMap, HashSet};
 use std::default::Default;
 use std::fmt;
index 9b99956937c24cc6f270818c3835b9319e7d580e..182c83d805c2dc2f946f6e4b7ee34fe0d1b06a31 100644 (file)
@@ -34,7 +34,7 @@
 
 use std::cell::RefCell;
 use std::collections::HashMap;
-use std::collections::hash_map::{Occupied, Vacant};
+use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::io::File;
 use std::io;
 use std::rc::Rc;
@@ -173,13 +173,8 @@ pub fn main_args(args: &[String]) -> int {
         usage(args[0].as_slice());
         return 0;
     } else if matches.opt_present("version") {
-        match rustc_driver::version("rustdoc", &matches) {
-            Some(err) => {
-                println!("{}", err);
-                return 1
-            },
-            None => return 0
-        }
+        rustc_driver::version("rustdoc", &matches);
+        return 0;
     }
 
     if matches.opt_strs("passes") == ["list"] {
index d3d1aa1d788791da44619bd8c2fd8fafab9423bb..3181e28a1211b11a2f0c605790cad81526748c33 100644 (file)
@@ -2012,7 +2012,6 @@ fn $name(&mut self) -> DecodeResult<$ty> {
 
 impl ::Decoder<DecoderError> for Decoder {
     fn read_nil(&mut self) -> DecodeResult<()> {
-        debug!("read_nil");
         expect!(self.pop(), Null)
     }
 
@@ -2030,7 +2029,6 @@ fn read_nil(&mut self) -> DecodeResult<()> {
     fn read_f32(&mut self) -> DecodeResult<f32> { self.read_f64().map(|x| x as f32) }
 
     fn read_f64(&mut self) -> DecodeResult<f64> {
-        debug!("read_f64");
         match self.pop() {
             Json::I64(f) => Ok(f as f64),
             Json::U64(f) => Ok(f as f64),
@@ -2049,7 +2047,6 @@ fn read_f64(&mut self) -> DecodeResult<f64> {
     }
 
     fn read_bool(&mut self) -> DecodeResult<bool> {
-        debug!("read_bool");
         expect!(self.pop(), Boolean)
     }
 
@@ -2067,14 +2064,12 @@ fn read_char(&mut self) -> DecodeResult<char> {
     }
 
     fn read_str(&mut self) -> DecodeResult<string::String> {
-        debug!("read_str");
         expect!(self.pop(), String)
     }
 
-    fn read_enum<T, F>(&mut self, name: &str, f: F) -> DecodeResult<T> where
+    fn read_enum<T, F>(&mut self, _name: &str, f: F) -> DecodeResult<T> where
         F: FnOnce(&mut Decoder) -> DecodeResult<T>,
     {
-        debug!("read_enum({})", name);
         f(self)
     }
 
@@ -2082,7 +2077,6 @@ fn read_enum_variant<T, F>(&mut self, names: &[&str],
                                mut f: F) -> DecodeResult<T>
         where F: FnMut(&mut Decoder, uint) -> DecodeResult<T>,
     {
-        debug!("read_enum_variant(names={})", names);
         let name = match self.pop() {
             Json::String(s) => s,
             Json::Object(mut o) => {
@@ -2122,36 +2116,32 @@ fn read_enum_variant<T, F>(&mut self, names: &[&str],
         f(self, idx)
     }
 
-    fn read_enum_variant_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
+    fn read_enum_variant_arg<T, F>(&mut self, _idx: uint, f: F) -> DecodeResult<T> where
         F: FnOnce(&mut Decoder) -> DecodeResult<T>,
     {
-        debug!("read_enum_variant_arg(idx={})", idx);
         f(self)
     }
 
     fn read_enum_struct_variant<T, F>(&mut self, names: &[&str], f: F) -> DecodeResult<T> where
         F: FnMut(&mut Decoder, uint) -> DecodeResult<T>,
     {
-        debug!("read_enum_struct_variant(names={})", names);
         self.read_enum_variant(names, f)
     }
 
 
     fn read_enum_struct_variant_field<T, F>(&mut self,
-                                         name: &str,
+                                         _name: &str,
                                          idx: uint,
                                          f: F)
                                          -> DecodeResult<T> where
         F: FnOnce(&mut Decoder) -> DecodeResult<T>,
     {
-        debug!("read_enum_struct_variant_field(name={}, idx={})", name, idx);
         self.read_enum_variant_arg(idx, f)
     }
 
-    fn read_struct<T, F>(&mut self, name: &str, len: uint, f: F) -> DecodeResult<T> where
+    fn read_struct<T, F>(&mut self, _name: &str, _len: uint, f: F) -> DecodeResult<T> where
         F: FnOnce(&mut Decoder) -> DecodeResult<T>,
     {
-        debug!("read_struct(name={}, len={})", name, len);
         let value = try!(f(self));
         self.pop();
         Ok(value)
@@ -2159,12 +2149,11 @@ fn read_struct<T, F>(&mut self, name: &str, len: uint, f: F) -> DecodeResult<T>
 
     fn read_struct_field<T, F>(&mut self,
                                name: &str,
-                               idx: uint,
+                               _idx: uint,
                                f: F)
                                -> DecodeResult<T> where
         F: FnOnce(&mut Decoder) -> DecodeResult<T>,
     {
-        debug!("read_struct_field(name={}, idx={})", name, idx);
         let mut obj = try!(expect!(self.pop(), Object));
 
         let value = match obj.remove(&name.to_string()) {
@@ -2189,7 +2178,6 @@ fn read_struct_field<T, F>(&mut self,
     fn read_tuple<T, F>(&mut self, tuple_len: uint, f: F) -> DecodeResult<T> where
         F: FnOnce(&mut Decoder) -> DecodeResult<T>,
     {
-        debug!("read_tuple()");
         self.read_seq(move |d, len| {
             if len == tuple_len {
                 f(d)
@@ -2202,18 +2190,16 @@ fn read_tuple<T, F>(&mut self, tuple_len: uint, f: F) -> DecodeResult<T> where
     fn read_tuple_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
         F: FnOnce(&mut Decoder) -> DecodeResult<T>,
     {
-        debug!("read_tuple_arg(idx={})", idx);
         self.read_seq_elt(idx, f)
     }
 
     fn read_tuple_struct<T, F>(&mut self,
-                               name: &str,
+                               _name: &str,
                                len: uint,
                                f: F)
                                -> DecodeResult<T> where
         F: FnOnce(&mut Decoder) -> DecodeResult<T>,
     {
-        debug!("read_tuple_struct(name={})", name);
         self.read_tuple(len, f)
     }
 
@@ -2223,14 +2209,12 @@ fn read_tuple_struct_arg<T, F>(&mut self,
                                    -> DecodeResult<T> where
         F: FnOnce(&mut Decoder) -> DecodeResult<T>,
     {
-        debug!("read_tuple_struct_arg(idx={})", idx);
         self.read_tuple_arg(idx, f)
     }
 
     fn read_option<T, F>(&mut self, mut f: F) -> DecodeResult<T> where
         F: FnMut(&mut Decoder, bool) -> DecodeResult<T>,
     {
-        debug!("read_option()");
         match self.pop() {
             Json::Null => f(self, false),
             value => { self.stack.push(value); f(self, true) }
@@ -2240,7 +2224,6 @@ fn read_option<T, F>(&mut self, mut f: F) -> DecodeResult<T> where
     fn read_seq<T, F>(&mut self, f: F) -> DecodeResult<T> where
         F: FnOnce(&mut Decoder, uint) -> DecodeResult<T>,
     {
-        debug!("read_seq()");
         let array = try!(expect!(self.pop(), Array));
         let len = array.len();
         for v in array.into_iter().rev() {
@@ -2249,17 +2232,15 @@ fn read_seq<T, F>(&mut self, f: F) -> DecodeResult<T> where
         f(self, len)
     }
 
-    fn read_seq_elt<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
+    fn read_seq_elt<T, F>(&mut self, _idx: uint, f: F) -> DecodeResult<T> where
         F: FnOnce(&mut Decoder) -> DecodeResult<T>,
     {
-        debug!("read_seq_elt(idx={})", idx);
         f(self)
     }
 
     fn read_map<T, F>(&mut self, f: F) -> DecodeResult<T> where
         F: FnOnce(&mut Decoder, uint) -> DecodeResult<T>,
     {
-        debug!("read_map()");
         let obj = try!(expect!(self.pop(), Object));
         let len = obj.len();
         for (key, value) in obj.into_iter() {
@@ -2269,17 +2250,15 @@ fn read_map<T, F>(&mut self, f: F) -> DecodeResult<T> where
         f(self, len)
     }
 
-    fn read_map_elt_key<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
+    fn read_map_elt_key<T, F>(&mut self, _idx: uint, f: F) -> DecodeResult<T> where
        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
     {
-        debug!("read_map_elt_key(idx={})", idx);
         f(self)
     }
 
-    fn read_map_elt_val<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
+    fn read_map_elt_val<T, F>(&mut self, _idx: uint, f: F) -> DecodeResult<T> where
        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
     {
-        debug!("read_map_elt_val(idx={})", idx);
         f(self)
     }
 
@@ -2441,9 +2420,7 @@ mod tests {
     use super::ParserError::*;
     use super::DecoderError::*;
     use super::JsonEvent::*;
-    use super::ParserState::*;
     use super::StackElement::*;
-    use super::InternalStackElement::*;
     use super::{PrettyEncoder, Json, from_str, DecodeResult, DecoderError, JsonEvent, Parser,
                 StackElement, Stack, Encoder, Decoder};
     use std::{i64, u64, f32, f64, io};
@@ -2678,8 +2655,6 @@ fn test_write_object() {
     }
 
     fn with_str_writer<F>(f: F) -> string::String where F: FnOnce(&mut io::Writer){
-        use std::str;
-
         let mut m = Vec::new();
         f(&mut m as &mut io::Writer);
         string::String::from_utf8(m).unwrap()
@@ -2756,9 +2731,9 @@ fn test_write_none() {
     fn test_write_char() {
         check_encoder_for_simple!('a', "\"a\"");
         check_encoder_for_simple!('\t', "\"\\t\"");
-        check_encoder_for_simple!('\u00a0', "\"\u00a0\"");
-        check_encoder_for_simple!('\uabcd', "\"\uabcd\"");
-        check_encoder_for_simple!('\U0010ffff', "\"\U0010ffff\"");
+        check_encoder_for_simple!('\u{00a0}', "\"\u{00a0}\"");
+        check_encoder_for_simple!('\u{abcd}', "\"\u{abcd}\"");
+        check_encoder_for_simple!('\u{10ffff}', "\"\u{10ffff}\"");
     }
 
     #[test]
index 2c4dc5313bbfa0af2569e54082ea4c468a56d162..08b17f25e29d97e4a231dfd27555942dd6ec8bb9 100644 (file)
@@ -633,7 +633,6 @@ mod tests {
     use prelude::*;
     use super::*;
     use char::from_u32;
-    use str::StrPrelude;
 
     macro_rules! v2ascii {
         ( [$($e:expr),*]) => (&[$(Ascii{chr:$e}),*]);
index f467b77dbf4cfdb9084171e07e9d5a16e5f9d369..d4ff05ce212c5dea2311c31a8bc6705ea4d2bf2e 100644 (file)
@@ -24,9 +24,9 @@
 /// ```{.rust}
 /// bitflags! {
 ///     flags Flags: u32 {
-///         const FLAG_A       = 0x00000001,
-///         const FLAG_B       = 0x00000010,
-///         const FLAG_C       = 0x00000100,
+///         const FLAG_A       = 0b00000001,
+///         const FLAG_B       = 0b00000010,
+///         const FLAG_C       = 0b00000100,
 ///         const FLAG_ABC     = FLAG_A.bits
 ///                            | FLAG_B.bits
 ///                            | FLAG_C.bits,
@@ -50,8 +50,8 @@
 ///
 /// bitflags! {
 ///     flags Flags: u32 {
-///         const FLAG_A   = 0x00000001,
-///         const FLAG_B   = 0x00000010,
+///         const FLAG_A   = 0b00000001,
+///         const FLAG_B   = 0b00000010,
 ///     }
 /// }
 ///
@@ -315,7 +315,6 @@ fn not(self) -> $BitFlags {
 #[cfg(test)]
 #[allow(non_upper_case_globals)]
 mod tests {
-    use kinds::Copy;
     use hash;
     use option::Option::{Some, None};
     use ops::{BitOr, BitAnd, BitXor, Sub, Not};
@@ -326,10 +325,10 @@ mod tests {
         #[doc = "> "]
         #[doc = "> - Richard Feynman"]
         flags Flags: u32 {
-            const FlagA       = 0x00000001,
+            const FlagA       = 0b00000001,
             #[doc = "<pcwalton> macros are way better at generating code than trans is"]
-            const FlagB       = 0x00000010,
-            const FlagC       = 0x00000100,
+            const FlagB       = 0b00000010,
+            const FlagC       = 0b00000100,
             #[doc = "* cmr bed"]
             #[doc = "* strcat table"]
             #[doc = "<strcat> wait what?"]
@@ -347,21 +346,21 @@ mod tests {
 
     #[test]
     fn test_bits(){
-        assert_eq!(Flags::empty().bits(), 0x00000000);
-        assert_eq!(FlagA.bits(), 0x00000001);
-        assert_eq!(FlagABC.bits(), 0x00000111);
+        assert_eq!(Flags::empty().bits(), 0b00000000);
+        assert_eq!(FlagA.bits(), 0b00000001);
+        assert_eq!(FlagABC.bits(), 0b00000111);
 
-        assert_eq!(AnotherSetOfFlags::empty().bits(), 0x00);
+        assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00);
         assert_eq!(AnotherFlag.bits(), !0_i8);
     }
 
     #[test]
     fn test_from_bits() {
         assert!(Flags::from_bits(0) == Some(Flags::empty()));
-        assert!(Flags::from_bits(0x1) == Some(FlagA));
-        assert!(Flags::from_bits(0x10) == Some(FlagB));
-        assert!(Flags::from_bits(0x11) == Some(FlagA | FlagB));
-        assert!(Flags::from_bits(0x1000) == None);
+        assert!(Flags::from_bits(0b1) == Some(FlagA));
+        assert!(Flags::from_bits(0b10) == Some(FlagB));
+        assert!(Flags::from_bits(0b11) == Some(FlagA | FlagB));
+        assert!(Flags::from_bits(0b1000) == None);
 
         assert!(AnotherSetOfFlags::from_bits(!0_i8) == Some(AnotherFlag));
     }
@@ -369,11 +368,11 @@ fn test_from_bits() {
     #[test]
     fn test_from_bits_truncate() {
         assert!(Flags::from_bits_truncate(0) == Flags::empty());
-        assert!(Flags::from_bits_truncate(0x1) == FlagA);
-        assert!(Flags::from_bits_truncate(0x10) == FlagB);
-        assert!(Flags::from_bits_truncate(0x11) == (FlagA | FlagB));
-        assert!(Flags::from_bits_truncate(0x1000) == Flags::empty());
-        assert!(Flags::from_bits_truncate(0x1001) == FlagA);
+        assert!(Flags::from_bits_truncate(0b1) == FlagA);
+        assert!(Flags::from_bits_truncate(0b10) == FlagB);
+        assert!(Flags::from_bits_truncate(0b11) == (FlagA | FlagB));
+        assert!(Flags::from_bits_truncate(0b1000) == Flags::empty());
+        assert!(Flags::from_bits_truncate(0b1001) == FlagA);
 
         assert!(AnotherSetOfFlags::from_bits_truncate(0_i8) == AnotherSetOfFlags::empty());
     }
diff --git a/src/libstd/bool.rs b/src/libstd/bool.rs
new file mode 100644 (file)
index 0000000..bbaab5e
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The boolean type
+
+#![doc(primitive = "bool")]
+#![stable]
+
index 8fe3642e702d44ce6d3f1a9e1cd9ea2db9d69f9b..f1c8e8950a22eed6915218d39004924fa008dcd6 100644 (file)
 //! }
 //! ```
 
-use string::String;
-use hash;
+use core::prelude::*;
+use libc;
+
 use fmt;
+use hash;
 use kinds::marker;
 use mem;
-use core::prelude::*;
-
 use ptr;
-use raw::Slice;
-use slice;
+use slice::{mod, ImmutableIntSlice};
 use str;
-use libc;
+use string::String;
+
 
 /// The representation of a C String.
 ///
@@ -210,7 +210,7 @@ pub fn owns_buffer(&self) -> bool {
     #[inline]
     pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
         unsafe {
-            mem::transmute(Slice { data: self.buf, len: self.len() + 1 })
+            slice::from_raw_buf(&self.buf, self.len() + 1).as_unsigned()
         }
     }
 
@@ -219,7 +219,7 @@ pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
     #[inline]
     pub fn as_bytes_no_nul<'a>(&'a self) -> &'a [u8] {
         unsafe {
-            mem::transmute(Slice { data: self.buf, len: self.len() })
+            slice::from_raw_buf(&self.buf, self.len()).as_unsigned()
         }
     }
 
index 6bfea7e3cb2a84b0b68a921dbe03a1d44c7e3c5c..c32fec67d66731f74a1eab99966c229664e6dcb5 100644 (file)
@@ -10,7 +10,7 @@
 //
 // ignore-lexer-test FIXME #15883
 
-pub use self::Entry::*;
+use self::Entry::*;
 use self::SearchResult::*;
 use self::VacantEntryState::*;
 
 use result::Result;
 use result::Result::{Ok, Err};
 
-use super::table;
 use super::table::{
+    mod,
     Bucket,
-    Empty,
     EmptyBucket,
-    Full,
     FullBucket,
     FullBucketImm,
     FullBucketMut,
     RawTable,
     SafeHash
 };
+use super::table::BucketState::{
+    Empty,
+    Full,
+};
 
 const INITIAL_LOG2_CAP: uint = 5;
 pub const INITIAL_CAPACITY: uint = 1 << INITIAL_LOG2_CAP; // 2^5
@@ -379,7 +381,7 @@ fn robin_hood<'a, K: 'a, V: 'a>(mut bucket: FullBucketMut<'a, K, V>,
             assert!(probe.index() != idx_end);
 
             let full_bucket = match probe.peek() {
-                table::Empty(bucket) => {
+                Empty(bucket) => {
                     // Found a hole!
                     let b = bucket.put(old_hash, old_key, old_val);
                     // Now that it's stolen, just read the value's pointer
@@ -390,7 +392,7 @@ fn robin_hood<'a, K: 'a, V: 'a>(mut bucket: FullBucketMut<'a, K, V>,
                                .into_mut_refs()
                                .1;
                 },
-                table::Full(bucket) => bucket
+                Full(bucket) => bucket
             };
 
             let probe_ib = full_bucket.index() - full_bucket.distance();
@@ -982,6 +984,35 @@ pub fn len(&self) -> uint { self.table.size() }
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn is_empty(&self) -> bool { self.len() == 0 }
 
+    /// Clears the map, returning all key-value pairs as an iterator. Keeps the
+    /// allocated memory for reuse.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut a = HashMap::new();
+    /// a.insert(1u, "a");
+    /// a.insert(2u, "b");
+    ///
+    /// for (k, v) in a.drain().take(1) {
+    ///     assert!(k == 1 || k == 2);
+    ///     assert!(v == "a" || v == "b");
+    /// }
+    ///
+    /// assert!(a.is_empty());
+    /// ```
+    #[inline]
+    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    pub fn drain(&mut self) -> Drain<K, V> {
+        fn last_two<A, B, C>((_, b, c): (A, B, C)) -> (B, C) { (b, c) }
+
+        Drain {
+            inner: self.table.drain().map(last_two),
+        }
+    }
+
     /// Clears the map, removing all key-value pairs. Keeps the allocated memory
     /// for reuse.
     ///
@@ -996,16 +1027,9 @@ pub fn is_empty(&self) -> bool { self.len() == 0 }
     /// assert!(a.is_empty());
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[inline]
     pub fn clear(&mut self) {
-        let cap = self.table.capacity();
-        let mut buckets = Bucket::first(&mut self.table);
-
-        while buckets.index() != cap {
-            buckets = match buckets.peek() {
-                Empty(b)   => b.next(),
-                Full(full) => full.take().0.next(),
-            };
-        }
+        self.drain();
     }
 
     /// Deprecated: Renamed to `get`.
@@ -1306,6 +1330,16 @@ pub struct Values<'a, K: 'a, V: 'a> {
     inner: Map<(&'a K, &'a V), &'a V, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>
 }
 
+/// HashMap drain iterator
+pub struct Drain<'a, K: 'a, V: 'a> {
+    inner: iter::Map<
+        (SafeHash, K, V),
+        (K, V),
+        table::Drain<'a, K, V>,
+        fn((SafeHash, K, V)) -> (K, V),
+    >
+}
+
 /// A view into a single occupied location in a HashMap
 pub struct OccupiedEntry<'a, K:'a, V:'a> {
     elem: FullBucket<K, V, &'a mut RawTable<K, V>>,
@@ -1360,6 +1394,17 @@ impl<'a, K, V> Iterator<&'a V> for Values<'a, K, V> {
     #[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
 }
 
+impl<'a, K: 'a, V: 'a> Iterator<(K, V)> for Drain<'a, K, V> {
+    #[inline]
+    fn next(&mut self) -> Option<(K, V)> {
+        self.inner.next()
+    }
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        self.inner.size_hint()
+    }
+}
+
 impl<'a, K, V> OccupiedEntry<'a, K, V> {
     /// Gets a reference to the value in the entry
     pub fn get(&self) -> &V {
@@ -1427,10 +1472,10 @@ mod test_map {
     use prelude::*;
 
     use super::HashMap;
-    use super::{Occupied, Vacant};
+    use super::Entry::{Occupied, Vacant};
     use cmp::Equiv;
     use hash;
-    use iter::{Iterator,range_inclusive,range_step_inclusive};
+    use iter::{range_inclusive, range_step_inclusive};
     use cell::RefCell;
     use rand::{weak_rng, Rng};
 
index 67c0f887832fa08d62e9296bb8fefbe9a8df92f8..f587669d3dacd5e967aa9d9e38e97a4b1ff4afa9 100644 (file)
 use fmt::Show;
 use fmt;
 use hash::{Hash, Hasher, RandomSipHasher};
-use iter::{Iterator, IteratorExt, FromIterator, Map, FilterMap, Chain, Repeat, Zip, Extend, repeat};
+use iter::{Iterator, IteratorExt, FromIterator, Map, Chain, Extend};
 use option::Option::{Some, None, mod};
 use result::Result::{Ok, Err};
 
-use super::map::{HashMap, MoveEntries, Keys, INITIAL_CAPACITY};
+use super::map::{mod, HashMap, MoveEntries, Keys, INITIAL_CAPACITY};
 
 // FIXME(conventions): implement BitOr, BitAnd, BitXor, and Sub
 
@@ -250,8 +250,8 @@ pub fn contains_equiv<Sized? Q: Hash<S> + Equiv<T>>(&self, value: &Q) -> bool {
     /// }
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
-    pub fn iter<'a>(&'a self) -> SetItems<'a, T> {
-        SetItems { iter: self.map.keys() }
+    pub fn iter<'a>(&'a self) -> Iter<'a, T> {
+        Iter { iter: self.map.keys() }
     }
 
     /// Creates a consuming iterator, that is, one that moves each value out
@@ -275,10 +275,10 @@ pub fn iter<'a>(&'a self) -> SetItems<'a, T> {
     /// }
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
-    pub fn into_iter(self) -> SetMoveItems<T> {
+    pub fn into_iter(self) -> IntoIter<T> {
         fn first<A, B>((a, _): (A, B)) -> A { a }
 
-        SetMoveItems { iter: self.map.into_iter().map(first) }
+        IntoIter { iter: self.map.into_iter().map(first) }
     }
 
     /// Visit the values representing the difference.
@@ -304,14 +304,11 @@ fn first<A, B>((a, _): (A, B)) -> A { a }
     /// assert_eq!(diff, [4i].iter().map(|&x| x).collect());
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
-    pub fn difference<'a>(&'a self, other: &'a HashSet<T, H>) -> SetAlgebraItems<'a, T, H> {
-        fn filter<'a, T, S, H>((other, elt): (&HashSet<T, H>, &'a T)) -> Option<&'a T> where
-            T: Eq + Hash<S>, H: Hasher<S>
-        {
-            if !other.contains(elt) { Some(elt) } else { None }
+    pub fn difference<'a>(&'a self, other: &'a HashSet<T, H>) -> Difference<'a, T, H> {
+        Difference {
+            iter: self.iter(),
+            other: other,
         }
-
-        SetAlgebraItems { iter: repeat(other).zip(self.iter()).filter_map(filter) }
     }
 
     /// Visit the values representing the symmetric difference.
@@ -336,8 +333,8 @@ fn filter<'a, T, S, H>((other, elt): (&HashSet<T, H>, &'a T)) -> Option<&'a T> w
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet<T, H>)
-        -> SymDifferenceItems<'a, T, H> {
-        SymDifferenceItems { iter: self.difference(other).chain(other.difference(self)) }
+        -> SymmetricDifference<'a, T, H> {
+        SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) }
     }
 
     /// Visit the values representing the intersection.
@@ -358,14 +355,11 @@ pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet<T, H>)
     /// assert_eq!(diff, [2i, 3].iter().map(|&x| x).collect());
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
-    pub fn intersection<'a>(&'a self, other: &'a HashSet<T, H>) -> SetAlgebraItems<'a, T, H> {
-        fn filter<'a, T, S, H>((other, elt): (&HashSet<T, H>, &'a T)) -> Option<&'a T> where
-            T: Eq + Hash<S>, H: Hasher<S>
-        {
-            if other.contains(elt) { Some(elt) } else { None }
+    pub fn intersection<'a>(&'a self, other: &'a HashSet<T, H>) -> Intersection<'a, T, H> {
+        Intersection {
+            iter: self.iter(),
+            other: other,
         }
-
-        SetAlgebraItems { iter: repeat(other).zip(self.iter()).filter_map(filter) }
     }
 
     /// Visit the values representing the union.
@@ -386,8 +380,8 @@ fn filter<'a, T, S, H>((other, elt): (&HashSet<T, H>, &'a T)) -> Option<&'a T> w
     /// assert_eq!(diff, [1i, 2, 3, 4].iter().map(|&x| x).collect());
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
-    pub fn union<'a>(&'a self, other: &'a HashSet<T, H>) -> UnionItems<'a, T, H> {
-        UnionItems { iter: self.iter().chain(other.difference(self)) }
+    pub fn union<'a>(&'a self, other: &'a HashSet<T, H>) -> Union<'a, T, H> {
+        Union { iter: self.iter().chain(other.difference(self)) }
     }
 
     /// Return the number of elements in the set
@@ -420,6 +414,14 @@ pub fn len(&self) -> uint { self.map.len() }
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn is_empty(&self) -> bool { self.map.len() == 0 }
 
+    /// Clears the set, returning all elements in an iterator.
+    #[inline]
+    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    pub fn drain(&mut self) -> Drain<T> {
+        fn first<A, B>((a, _): (A, B)) -> A { a }
+        Drain { iter: self.map.drain().map(first) }
+    }
+
     /// Clears the set, removing all values.
     ///
     /// # Example
@@ -617,58 +619,111 @@ fn default() -> HashSet<T, H> {
 }
 
 /// HashSet iterator
-pub struct SetItems<'a, K: 'a> {
+pub struct Iter<'a, K: 'a> {
     iter: Keys<'a, K, ()>
 }
 
 /// HashSet move iterator
-pub struct SetMoveItems<K> {
+pub struct IntoIter<K> {
     iter: Map<(K, ()), K, MoveEntries<K, ()>, fn((K, ())) -> K>
 }
 
-// `Repeat` is used to feed the filter closure an explicit capture
-// of a reference to the other set
-/// Set operations iterator, used directly for intersection and difference
-pub struct SetAlgebraItems<'a, T: 'a, H: 'a> {
-    iter: FilterMap<
-        (&'a HashSet<T, H>, &'a T),
-        &'a T,
-        Zip<Repeat<&'a HashSet<T, H>>, SetItems<'a, T>>,
-        for<'b> fn((&HashSet<T, H>, &'b T)) -> Option<&'b T>,
-    >
+/// HashSet drain iterator
+pub struct Drain<'a, K: 'a> {
+    iter: Map<(K, ()), K, map::Drain<'a, K, ()>, fn((K, ())) -> K>,
+}
+
+/// Intersection iterator
+pub struct Intersection<'a, T: 'a, H: 'a> {
+    // iterator of the first set
+    iter: Iter<'a, T>,
+    // the second set
+    other: &'a HashSet<T, H>,
+}
+
+/// Difference iterator
+pub struct Difference<'a, T: 'a, H: 'a> {
+    // iterator of the first set
+    iter: Iter<'a, T>,
+    // the second set
+    other: &'a HashSet<T, H>,
 }
 
 /// Symmetric difference iterator.
-pub struct SymDifferenceItems<'a, T: 'a, H: 'a> {
-    iter: Chain<SetAlgebraItems<'a, T, H>, SetAlgebraItems<'a, T, H>>
+pub struct SymmetricDifference<'a, T: 'a, H: 'a> {
+    iter: Chain<Difference<'a, T, H>, Difference<'a, T, H>>
 }
 
 /// Set union iterator.
-pub struct UnionItems<'a, T: 'a, H: 'a> {
-    iter: Chain<SetItems<'a, T>, SetAlgebraItems<'a, T, H>>
+pub struct Union<'a, T: 'a, H: 'a> {
+    iter: Chain<Iter<'a, T>, Difference<'a, T, H>>
 }
 
-impl<'a, K> Iterator<&'a K> for SetItems<'a, K> {
+impl<'a, K> Iterator<&'a K> for Iter<'a, K> {
     fn next(&mut self) -> Option<&'a K> { self.iter.next() }
     fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
 }
 
-impl<K> Iterator<K> for SetMoveItems<K> {
+impl<K> Iterator<K> for IntoIter<K> {
     fn next(&mut self) -> Option<K> { self.iter.next() }
     fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
 }
 
-impl<'a, T, H> Iterator<&'a T> for SetAlgebraItems<'a, T, H> {
-    fn next(&mut self) -> Option<&'a T> { self.iter.next() }
+impl<'a, K: 'a> Iterator<K> for Drain<'a, K> {
+    fn next(&mut self) -> Option<K> { self.iter.next() }
     fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
 }
 
-impl<'a, T, H> Iterator<&'a T> for SymDifferenceItems<'a, T, H> {
+impl<'a, T, S, H> Iterator<&'a T> for Intersection<'a, T, H>
+    where T: Eq + Hash<S>, H: Hasher<S>
+{
+    fn next(&mut self) -> Option<&'a T> {
+        loop {
+            match self.iter.next() {
+                None => return None,
+                Some(elt) => if self.other.contains(elt) {
+                    return Some(elt)
+                },
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        let (_, upper) = self.iter.size_hint();
+        (0, upper)
+    }
+}
+
+impl<'a, T, S, H> Iterator<&'a T> for Difference<'a, T, H>
+    where T: Eq + Hash<S>, H: Hasher<S>
+{
+    fn next(&mut self) -> Option<&'a T> {
+        loop {
+            match self.iter.next() {
+                None => return None,
+                Some(elt) => if !self.other.contains(elt) {
+                    return Some(elt)
+                },
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        let (_, upper) = self.iter.size_hint();
+        (0, upper)
+    }
+}
+
+impl<'a, T, S, H> Iterator<&'a T> for SymmetricDifference<'a, T, H>
+    where T: Eq + Hash<S>, H: Hasher<S>
+{
     fn next(&mut self) -> Option<&'a T> { self.iter.next() }
     fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
 }
 
-impl<'a, T, H> Iterator<&'a T> for UnionItems<'a, T, H> {
+impl<'a, T, S, H> Iterator<&'a T> for Union<'a, T, H>
+    where T: Eq + Hash<S>, H: Hasher<S>
+{
     fn next(&mut self) -> Option<&'a T> { self.iter.next() }
     fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
 }
@@ -678,7 +733,6 @@ mod test_set {
     use prelude::*;
 
     use super::HashSet;
-    use slice::PartialEqSliceExt;
 
     #[test]
     fn test_disjoint() {
@@ -914,4 +968,41 @@ fn test_show() {
         assert!(set_str == "{1, 2}" || set_str == "{2, 1}");
         assert_eq!(format!("{}", empty), "{}");
     }
+
+    #[test]
+    fn test_trivial_drain() {
+        let mut s = HashSet::<int>::new();
+        for _ in s.drain() {}
+        assert!(s.is_empty());
+        drop(s);
+
+        let mut s = HashSet::<int>::new();
+        drop(s.drain());
+        assert!(s.is_empty());
+    }
+
+    #[test]
+    fn test_drain() {
+        let mut s: HashSet<int> = range(1, 100).collect();
+
+        // try this a bunch of times to make sure we don't screw up internal state.
+        for _ in range(0i, 20) {
+            assert_eq!(s.len(), 99);
+
+            {
+                let mut last_i = 0;
+                let mut d = s.drain();
+                for (i, x) in d.by_ref().take(50).enumerate() {
+                    last_i = i;
+                    assert!(x != 0);
+                }
+                assert_eq!(last_i, 49);
+            }
+
+            for _ in s.iter() { panic!("s should be empty!"); }
+
+            // reset to try again.
+            s.extend(range(1, 100));
+        }
+    }
 }
index da06387e9a5eb7b940de5ce7b4759e778d362bec..ce7dbd8ea5ecb10b3c9250b3c374acba0fc06cce 100644 (file)
@@ -10,7 +10,7 @@
 //
 // ignore-lexer-test FIXME #15883
 
-pub use self::BucketState::*;
+use self::BucketState::*;
 
 use clone::Clone;
 use cmp;
@@ -684,6 +684,19 @@ pub fn into_iter(self) -> MoveEntries<K, V> {
         }
     }
 
+    pub fn drain(&mut self) -> Drain<K, V> {
+        let RawBuckets { raw, hashes_end, .. } = self.raw_buckets();
+        // Replace the marker regardless of lifetime bounds on parameters.
+        Drain {
+            iter: RawBuckets {
+                raw: raw,
+                hashes_end: hashes_end,
+                marker: marker::ContravariantLifetime::<'static>,
+            },
+            table: self,
+        }
+    }
+
     /// Returns an iterator that copies out each entry. Used while the table
     /// is being dropped.
     unsafe fn rev_move_buckets(&mut self) -> RevMoveBuckets<K, V> {
@@ -774,6 +787,12 @@ pub struct MoveEntries<K, V> {
     iter: RawBuckets<'static, K, V>
 }
 
+/// Iterator over the entries in a table, clearing the table.
+pub struct Drain<'a, K: 'a, V: 'a> {
+    table: &'a mut RawTable<K, V>,
+    iter: RawBuckets<'static, K, V>,
+}
+
 impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> {
     fn next(&mut self) -> Option<(&'a K, &'a V)> {
         self.iter.next().map(|bucket| {
@@ -828,6 +847,36 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
+impl<'a, K: 'a, V: 'a> Iterator<(SafeHash, K, V)> for Drain<'a, K, V> {
+    #[inline]
+    fn next(&mut self) -> Option<(SafeHash, K, V)> {
+        self.iter.next().map(|bucket| {
+            self.table.size -= 1;
+            unsafe {
+                (
+                    SafeHash {
+                        hash: ptr::replace(bucket.hash, EMPTY_BUCKET),
+                    },
+                    ptr::read(bucket.key as *const K),
+                    ptr::read(bucket.val as *const V)
+                )
+            }
+        })
+    }
+
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        let size = self.table.size();
+        (size, Some(size))
+    }
+}
+
+#[unsafe_destructor]
+impl<'a, K: 'a, V: 'a> Drop for Drain<'a, K, V> {
+    fn drop(&mut self) {
+        for _ in *self {}
+    }
+}
+
 impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
     fn clone(&self) -> RawTable<K, V> {
         unsafe {
index 9043cb8c7d6f5f6b40632d10e27b0716a81fe4e7..55f5662dbd897274b489c897fe19289342736643 100644 (file)
@@ -628,7 +628,7 @@ pub fn send_opt(&self, t: T) -> Result<(), T> {
     }
 }
 
-#[unstable]
+#[stable]
 impl<T: Send> Clone for Sender<T> {
     fn clone(&self) -> Sender<T> {
         let (packet, sleeper, guard) = match *unsafe { self.inner() } {
@@ -756,7 +756,7 @@ pub fn try_send(&self, t: T) -> Result<(), TrySendError<T>> {
     }
 }
 
-#[unstable]
+#[stable]
 impl<T: Send> Clone for SyncSender<T> {
     fn clone(&self) -> SyncSender<T> {
         unsafe { (*self.inner.get()).clone_chan(); }
index 291f384d619d9726adcc8bdf75eb4617959cc186..4d8c7d67b8c2ea15f36ac9b090c94595c123d5d5 100644 (file)
 #![experimental]
 #![allow(missing_docs)]
 
-use clone::Clone;
-use c_str::ToCStr;
-use iter::IteratorExt;
+use prelude::*;
 use mem;
-use ops::*;
-use option::*;
-use option::Option::{None, Some};
 use os;
-use path::{Path,GenericPath};
-use result::*;
-use result::Result::{Err, Ok};
-use slice::{AsSlice,SliceExt};
 use str;
-use string::String;
-use vec::Vec;
 
 #[allow(missing_copy_implementations)]
 pub struct DynamicLibrary {
@@ -211,15 +200,12 @@ fn test_errors_do_not_crash() {
           target_os = "freebsd",
           target_os = "dragonfly"))]
 pub mod dl {
-    pub use self::Rtld::*;
+    use self::Rtld::*;
 
-    use c_str::{CString, ToCStr};
+    use prelude::*;
+    use c_str::CString;
     use libc;
-    use ops::FnOnce;
     use ptr;
-    use result::*;
-    use result::Result::{Err, Ok};
-    use string::String;
 
     pub unsafe fn open_external<T: ToCStr>(filename: T) -> *mut u8 {
         filename.with_c_str(|raw_name| {
index 25f05940807c1ca613e60a0a716424b6800a9d37..9d9e882757147f33226f424035833ad32030148a 100644 (file)
@@ -409,7 +409,6 @@ mod test {
     use super::super::{IoResult, EndOfFile};
     use super::super::mem::MemReader;
     use self::test::Bencher;
-    use str::StrPrelude;
 
     /// A type, free to create, primarily intended for benchmarking creation of
     /// wrappers that, just for construction, don't need a Reader/Writer that
index e865bf42bd01d5239c6d912a05a6bba572d9526a..3a18b0dc1b525b495cb968a8b3dba01f2a13a7d4 100644 (file)
@@ -132,6 +132,7 @@ pub fn new(tx: Sender<Vec<u8>>) -> ChanWriter {
     }
 }
 
+#[stable]
 impl Clone for ChanWriter {
     fn clone(&self) -> ChanWriter {
         ChanWriter { tx: self.tx.clone() }
index fd3bae73cd3676d293f02e91d8d374eaa0a53224..4e736908c3720c15d443cc71b5da191affebba0f 100644 (file)
@@ -823,10 +823,6 @@ mod test {
     use io;
     use str;
     use io::fs::*;
-    use path::Path;
-    use io;
-    use ops::Drop;
-    use str::StrPrelude;
 
     macro_rules! check { ($e:expr) => (
         match $e {
index 71e8cb4b5ec1dee918843445be2843a06769bcbf..431e11cf9cacaf59b57ac8fd36235688d95d2434 100644 (file)
@@ -398,13 +398,12 @@ fn fill_buf(&mut self) -> IoResult<&[u8]> {
 
 #[cfg(test)]
 mod test {
-    extern crate test;
+    extern crate "test" as test_crate;
     use prelude::*;
     use super::*;
     use io::*;
     use io;
-    use self::test::Bencher;
-    use str::StrPrelude;
+    use self::test_crate::Bencher;
 
     #[test]
     fn test_vec_writer() {
index aa50597c816980d0e56fc64e6c321f310452edc3..36dd549235698e5c2f59c2c0e310b602837046fc 100644 (file)
@@ -104,7 +104,7 @@ pub struct StdinReader {
     inner: Arc<Mutex<BufferedReader<StdReader>>>,
 }
 
-/// A guard for exlusive access to `StdinReader`'s internal `BufferedReader`.
+/// A guard for exclusive access to `StdinReader`'s internal `BufferedReader`.
 pub struct StdinReaderGuard<'a> {
     inner: MutexGuard<'a, BufferedReader<StdReader>>,
 }
index f3a119399952d7c1ee02fc0a840eef26bb288d08..c2b4d5a1fa98241d776a68db3e15e279d242d404 100644 (file)
 
 /// A wrapper for a path to temporary directory implementing automatic
 /// scope-based deletion.
+///
+/// # Examples
+///
+/// ```no_run
+/// use std::io::TempDir;
+///
+/// {
+///     // create a temporary directory
+///     let tmpdir = match TempDir::new("mysuffix") {
+///         Ok(dir) => dir,
+///         Err(e) => panic!("couldn't create temporary directory: {}", e)
+///     };
+///
+///     // get the path of the temporary directory without affecting the wrapper
+///     let tmppath = tmpdir.path();
+///
+///     println!("The path of temporary directory is {}", tmppath.display());
+///
+///     // the temporary directory is automatically removed when tmpdir goes
+///     // out of scope at the end of the block
+/// }
+/// {
+///     // create a temporary directory, this time using a custom path
+///     let tmpdir = match TempDir::new_in(&Path::new("/tmp/best/custom/path"), "mysuffix") {
+///         Ok(dir) => dir,
+///         Err(e) => panic!("couldn't create temporary directory: {}", e)
+///     };
+///
+///     // get the path of the temporary directory and disable automatic deletion in the wrapper
+///     let tmppath = tmpdir.into_inner();
+///
+///     println!("The path of the not-so-temporary directory is {}", tmppath.display());
+///
+///     // the temporary directory is not removed here
+///     // because the directory is detached from the wrapper
+/// }
+/// {
+///     // create a temporary directory
+///     let tmpdir = match TempDir::new("mysuffix") {
+///         Ok(dir) => dir,
+///         Err(e) => panic!("couldn't create temporary directory: {}", e)
+///     };
+///
+///     // close the temporary directory manually and check the result
+///     match tmpdir.close() {
+///         Ok(_) => println!("success!"),
+///         Err(e) => panic!("couldn't remove temporary directory: {}", e)
+///     };
+/// }
+/// ```
 pub struct TempDir {
     path: Option<Path>,
     disarmed: bool
index 79048c37ab5bbb5bb22017ea965c0ce52149736b..953effe4345ceb18bac732b07d45b4fa7224f10d 100644 (file)
@@ -225,11 +225,11 @@ fn in_ms_u64(d: Duration) -> u64 {
 
 #[cfg(test)]
 mod test {
-    use super::*;
-    use time::Duration;
-    use task::spawn;
     use prelude::*;
 
+    use super::Timer;
+    use time::Duration;
+
     #[test]
     fn test_io_timer_sleep_simple() {
         let mut timer = Timer::new().unwrap();
index 78c194745a88838c9c3bc3a082b6146e34164ab1..8274baeacfad8378bb798da295f24f0982d4c7ee 100644 (file)
 #![allow(unknown_features)]
 #![feature(macro_rules, globs, linkage, thread_local, asm)]
 #![feature(default_type_params, phase, lang_items, unsafe_destructor)]
-#![feature(import_shadowing, slicing_syntax, tuple_indexing)]
-#![feature(unboxed_closures)]
+#![feature(slicing_syntax, unboxed_closures)]
 
 // Don't link to std. We are std.
 #![no_std]
 // NB: These reexports are in the order they should be listed in rustdoc
 
 pub use core::any;
-pub use core::bool;
 pub use core::borrow;
 pub use core::cell;
 pub use core::clone;
 pub use core::ptr;
 pub use core::raw;
 pub use core::simd;
-pub use core::tuple;
-// FIXME #15320: primitive documentation needs top-level modules, this
-// should be `std::tuple::unit`.
-pub use core::unit;
 pub use core::result;
 pub use core::option;
 
-pub use alloc::boxed;
+#[cfg(not(test))] pub use alloc::boxed;
 pub use alloc::rc;
 
 pub use core_collections::slice;
 pub mod rt;
 mod failure;
 
+// Documentation for primitive types
+
+mod bool;
+mod unit;
+mod tuple;
+
 // A curious inner-module that's not exported that contains the binding
 // 'std' so that macro-expanded references to std::error and such
 // can be resolved within libstd.
index 60b17de1718759dc5d97d8008ffda7bc24b6fe61..951627b26cad90b5ec8dd03ab53a59acc5bc1a28 100644 (file)
@@ -21,6 +21,9 @@
 use libc::c_int;
 use num::{Float, FloatMath};
 use num::strconv;
+use num::strconv::ExponentFormat::{ExpNone, ExpDec};
+use num::strconv::SignificantDigits::{DigAll, DigMax, DigExact};
+use num::strconv::SignFormat::SignNeg;
 
 pub use core::f32::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON, MIN_VALUE};
 pub use core::f32::{MIN_POS_VALUE, MAX_VALUE, MIN_EXP, MAX_EXP, MIN_10_EXP};
@@ -252,7 +255,7 @@ fn atanh(self) -> f32 {
 #[experimental = "may be removed or relocated"]
 pub fn to_string(num: f32) -> String {
     let (r, _) = strconv::float_to_str_common(
-        num, 10u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false);
+        num, 10u, true, SignNeg, DigAll, ExpNone, false);
     r
 }
 
@@ -265,7 +268,7 @@ pub fn to_string(num: f32) -> String {
 #[experimental = "may be removed or relocated"]
 pub fn to_str_hex(num: f32) -> String {
     let (r, _) = strconv::float_to_str_common(
-        num, 16u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false);
+        num, 16u, true, SignNeg, DigAll, ExpNone, false);
     r
 }
 
@@ -279,8 +282,7 @@ pub fn to_str_hex(num: f32) -> String {
 #[inline]
 #[experimental = "may be removed or relocated"]
 pub fn to_str_radix_special(num: f32, rdx: uint) -> (String, bool) {
-    strconv::float_to_str_common(num, rdx, true,
-                           strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false)
+    strconv::float_to_str_common(num, rdx, true, SignNeg, DigAll, ExpNone, false)
 }
 
 /// Converts a float to a string with exactly the number of
@@ -294,7 +296,7 @@ pub fn to_str_radix_special(num: f32, rdx: uint) -> (String, bool) {
 #[experimental = "may be removed or relocated"]
 pub fn to_str_exact(num: f32, dig: uint) -> String {
     let (r, _) = strconv::float_to_str_common(
-        num, 10u, true, strconv::SignNeg, strconv::DigExact(dig), strconv::ExpNone, false);
+        num, 10u, true, SignNeg, DigExact(dig), ExpNone, false);
     r
 }
 
@@ -309,7 +311,7 @@ pub fn to_str_exact(num: f32, dig: uint) -> String {
 #[experimental = "may be removed or relocated"]
 pub fn to_str_digits(num: f32, dig: uint) -> String {
     let (r, _) = strconv::float_to_str_common(
-        num, 10u, true, strconv::SignNeg, strconv::DigMax(dig), strconv::ExpNone, false);
+        num, 10u, true, SignNeg, DigMax(dig), ExpNone, false);
     r
 }
 
@@ -325,7 +327,7 @@ pub fn to_str_digits(num: f32, dig: uint) -> String {
 #[experimental = "may be removed or relocated"]
 pub fn to_str_exp_exact(num: f32, dig: uint, upper: bool) -> String {
     let (r, _) = strconv::float_to_str_common(
-        num, 10u, true, strconv::SignNeg, strconv::DigExact(dig), strconv::ExpDec, upper);
+        num, 10u, true, SignNeg, DigExact(dig), ExpDec, upper);
     r
 }
 
@@ -341,7 +343,7 @@ pub fn to_str_exp_exact(num: f32, dig: uint, upper: bool) -> String {
 #[experimental = "may be removed or relocated"]
 pub fn to_str_exp_digits(num: f32, dig: uint, upper: bool) -> String {
     let (r, _) = strconv::float_to_str_common(
-        num, 10u, true, strconv::SignNeg, strconv::DigMax(dig), strconv::ExpDec, upper);
+        num, 10u, true, SignNeg, DigMax(dig), ExpDec, upper);
     r
 }
 
@@ -349,7 +351,6 @@ pub fn to_str_exp_digits(num: f32, dig: uint, upper: bool) -> String {
 mod tests {
     use f32::*;
     use num::*;
-    use num;
 
     #[test]
     fn test_min_nan() {
@@ -364,8 +365,8 @@ fn test_max_nan() {
     }
 
     #[test]
-    fn test_num() {
-        num::test_num(10f32, 2f32);
+    fn test_num_f32() {
+        test_num(10f32, 2f32);
     }
 
     #[test]
index 4b31e33236d44305224eb3c2946e211d5c11582d..7cc94b9ebbbcb9b8b4f2937cd40e8e8a22843372 100644 (file)
@@ -20,6 +20,9 @@
 use libc::c_int;
 use num::{Float, FloatMath};
 use num::strconv;
+use num::strconv::ExponentFormat::{ExpNone, ExpDec};
+use num::strconv::SignificantDigits::{DigAll, DigMax, DigExact};
+use num::strconv::SignFormat::SignNeg;
 
 pub use core::f64::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON, MIN_VALUE};
 pub use core::f64::{MIN_POS_VALUE, MAX_VALUE, MIN_EXP, MAX_EXP, MIN_10_EXP};
@@ -260,7 +263,7 @@ fn atanh(self) -> f64 {
 #[experimental = "may be removed or relocated"]
 pub fn to_string(num: f64) -> String {
     let (r, _) = strconv::float_to_str_common(
-        num, 10u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false);
+        num, 10u, true, SignNeg, DigAll, ExpNone, false);
     r
 }
 
@@ -273,7 +276,7 @@ pub fn to_string(num: f64) -> String {
 #[experimental = "may be removed or relocated"]
 pub fn to_str_hex(num: f64) -> String {
     let (r, _) = strconv::float_to_str_common(
-        num, 16u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false);
+        num, 16u, true, SignNeg, DigAll, ExpNone, false);
     r
 }
 
@@ -287,8 +290,7 @@ pub fn to_str_hex(num: f64) -> String {
 #[inline]
 #[experimental = "may be removed or relocated"]
 pub fn to_str_radix_special(num: f64, rdx: uint) -> (String, bool) {
-    strconv::float_to_str_common(num, rdx, true,
-                           strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false)
+    strconv::float_to_str_common(num, rdx, true, SignNeg, DigAll, ExpNone, false)
 }
 
 /// Converts a float to a string with exactly the number of
@@ -302,7 +304,7 @@ pub fn to_str_radix_special(num: f64, rdx: uint) -> (String, bool) {
 #[experimental = "may be removed or relocated"]
 pub fn to_str_exact(num: f64, dig: uint) -> String {
     let (r, _) = strconv::float_to_str_common(
-        num, 10u, true, strconv::SignNeg, strconv::DigExact(dig), strconv::ExpNone, false);
+        num, 10u, true, SignNeg, DigExact(dig), ExpNone, false);
     r
 }
 
@@ -317,7 +319,7 @@ pub fn to_str_exact(num: f64, dig: uint) -> String {
 #[experimental = "may be removed or relocated"]
 pub fn to_str_digits(num: f64, dig: uint) -> String {
     let (r, _) = strconv::float_to_str_common(
-        num, 10u, true, strconv::SignNeg, strconv::DigMax(dig), strconv::ExpNone, false);
+        num, 10u, true, SignNeg, DigMax(dig), ExpNone, false);
     r
 }
 
@@ -333,7 +335,7 @@ pub fn to_str_digits(num: f64, dig: uint) -> String {
 #[experimental = "may be removed or relocated"]
 pub fn to_str_exp_exact(num: f64, dig: uint, upper: bool) -> String {
     let (r, _) = strconv::float_to_str_common(
-        num, 10u, true, strconv::SignNeg, strconv::DigExact(dig), strconv::ExpDec, upper);
+        num, 10u, true, SignNeg, DigExact(dig), ExpDec, upper);
     r
 }
 
@@ -349,7 +351,7 @@ pub fn to_str_exp_exact(num: f64, dig: uint, upper: bool) -> String {
 #[experimental = "may be removed or relocated"]
 pub fn to_str_exp_digits(num: f64, dig: uint, upper: bool) -> String {
     let (r, _) = strconv::float_to_str_common(
-        num, 10u, true, strconv::SignNeg, strconv::DigMax(dig), strconv::ExpDec, upper);
+        num, 10u, true, SignNeg, DigMax(dig), ExpDec, upper);
     r
 }
 
@@ -357,7 +359,6 @@ pub fn to_str_exp_digits(num: f64, dig: uint, upper: bool) -> String {
 mod tests {
     use f64::*;
     use num::*;
-    use num;
 
     #[test]
     fn test_min_nan() {
@@ -372,8 +373,8 @@ fn test_max_nan() {
     }
 
     #[test]
-    fn test_num() {
-        num::test_num(10f64, 2f64);
+    fn test_num_f64() {
+        test_num(10f64, 2f64);
     }
 
     #[test]
index f59dab4b20bde4c35419f59d43f258e1720a8e72..9ccb1544fdc6614d2c0a8f0a95ac6104baf7d45c 100644 (file)
@@ -10,7 +10,7 @@
 
 //! Operations and constants for architecture-sized signed integers (`int` type)
 
-#![unstable]
+#![stable]
 #![doc(primitive = "int")]
 
 pub use core::int::{BITS, BYTES, MIN, MAX};
index 016c4bd532a17e52c7dbf54796139a8b64e1bd43..b3e4dd52f89cb9d5ccc9e69297a6f368741e2c20 100644 (file)
@@ -12,9 +12,9 @@
 
 #![allow(missing_docs)]
 
-pub use self::ExponentFormat::*;
-pub use self::SignificantDigits::*;
-pub use self::SignFormat::*;
+use self::ExponentFormat::*;
+use self::SignificantDigits::*;
+use self::SignFormat::*;
 
 use char::{mod, Char};
 use num::{mod, Int, Float, FPNaN, FPInfinite, ToPrimitive};
index 7f8edee571fb8eafce0ef057c8a72320b6081759..cd000b3098bff4f6a7953a7d282299105144efc5 100644 (file)
@@ -10,7 +10,7 @@
 
 //! Operations and constants for architecture-sized unsigned integers (`uint` type)
 
-#![unstable]
+#![stable]
 #![doc(primitive = "uint")]
 
 pub use core::uint::{BITS, BYTES, MIN, MAX};
index dcc73f7844a4987b57d02f7523df7fe1558ddc44..258e8964a9fdfb57437bae146c9baef8a4d69813 100644 (file)
@@ -28,9 +28,9 @@
 #![allow(non_snake_case)]
 #![allow(unused_imports)]
 
-pub use self::MemoryMapKind::*;
-pub use self::MapOption::*;
-pub use self::MapError::*;
+use self::MemoryMapKind::*;
+use self::MapOption::*;
+use self::MapError::*;
 
 use clone::Clone;
 use error::{FromError, Error};
@@ -1425,7 +1425,6 @@ mod arch_consts {
 #[cfg(test)]
 mod tests {
     use prelude::*;
-    use c_str::ToCStr;
     use option;
     use os::{env, getcwd, getenv, make_absolute};
     use os::{split_paths, join_paths, setenv, unsetenv};
@@ -1618,8 +1617,8 @@ fn memory_map_rw() {
         use result::Result::{Ok, Err};
 
         let chunk = match os::MemoryMap::new(16, &[
-            os::MapReadable,
-            os::MapWritable
+            os::MapOption::MapReadable,
+            os::MapOption::MapWritable
         ]) {
             Ok(chunk) => chunk,
             Err(msg) => panic!("{}", msg)
@@ -1661,10 +1660,10 @@ fn get_fd(file: &File) -> libc::HANDLE {
         file.write_u8(0);
 
         let chunk = MemoryMap::new(size / 2, &[
-            MapReadable,
-            MapWritable,
-            MapFd(get_fd(&file)),
-            MapOffset(size / 2)
+            MapOption::MapReadable,
+            MapOption::MapWritable,
+            MapOption::MapFd(get_fd(&file)),
+            MapOption::MapOffset(size / 2)
         ]).unwrap();
         assert!(chunk.len > 0);
 
index 8f98329a4be720df6f06e0875eb4d5ab2fd9449c..ed4bb6ee08116ece668c1d80bf4d99c9055d440b 100644 (file)
@@ -931,8 +931,6 @@ fn contains_nul<T: BytesContainer>(v: &T) -> bool {
 #[cfg(test)]
 mod tests {
     use prelude::*;
-    use super::{GenericPath, PosixPath, WindowsPath};
-    use c_str::ToCStr;
 
     #[test]
     fn test_cstring() {
index 62f64159c047a0865b9e031abe2c3490044ba9b9..88907951673d1ce2f8b3a9b8e479952cfbc36e28 100644 (file)
@@ -445,7 +445,6 @@ mod tests {
     use prelude::*;
     use super::*;
     use str;
-    use str::StrPrelude;
 
     macro_rules! t {
         (s: $path:expr, $exp:expr) => (
index b498b3e8ad08350cc9970bda56077d7e766cc11e..c2c17103554ce608e1abba4cfa9d8c2ef0d99c2c 100644 (file)
@@ -12,7 +12,7 @@
 
 //! Windows file path handling
 
-pub use self::PathPrefix::*;
+use self::PathPrefix::*;
 
 use ascii::AsciiCast;
 use c_str::{CString, ToCStr};
@@ -1117,6 +1117,7 @@ fn prefix_len(p: Option<PathPrefix>) -> uint {
 mod tests {
     use prelude::*;
     use super::*;
+    use super::PathPrefix::*;
     use super::parse_prefix;
 
     macro_rules! t {
index 8b6575b6bc1cc8ae37ca0e6cd827f54138fd0774..f77627711a71f8a1793069c12f6abe4b57c5b301 100644 (file)
@@ -81,9 +81,9 @@
 #[doc(no_inline)] pub use io::{Buffer, Writer, Reader, Seek, BufferPrelude};
 #[doc(no_inline)] pub use str::{Str, StrVector, StrPrelude};
 #[doc(no_inline)] pub use str::{StrAllocating, UnicodeStrPrelude};
-#[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};
+#[doc(no_inline)] pub use core::prelude::{Tuple1, Tuple2, Tuple3, Tuple4};
+#[doc(no_inline)] pub use core::prelude::{Tuple5, Tuple6, Tuple7, Tuple8};
+#[doc(no_inline)] pub use core::prelude::{Tuple9, Tuple10, Tuple11, Tuple12};
 #[doc(no_inline)] pub use slice::AsSlice;
 #[doc(no_inline)] pub use slice::{VectorVector, PartialEqSliceExt};
 #[doc(no_inline)] pub use slice::{CloneSliceExt, OrdSliceExt, SliceExt};
index dbe5f9193298a7de0c4d3ad88c27bd7a1df492d0..68c99b12758556fae7a597a583032d696d2623e9 100644 (file)
@@ -170,7 +170,6 @@ mod imp {
     extern crate libc;
 
     use io::{IoResult};
-    use kinds::marker;
     use mem;
     use os;
     use rand::Rng;
index fa527a70f83958ee8fb3533a1f1ace2c6a60a6bb..77500ca74d092c628296e8f07557b241028adc73 100644 (file)
@@ -20,7 +20,6 @@
 
 use libc::{mod, uintptr_t};
 use os;
-use str::{FromStr, from_str, Str};
 use sync::atomic;
 
 /// Dynamically inquire about whether we're running under V.
@@ -66,7 +65,7 @@ pub fn min_stack() -> uint {
 pub fn default_sched_threads() -> uint {
     match os::getenv("RUST_THREADS") {
         Some(nstr) => {
-            let opt_n: Option<uint> = FromStr::from_str(nstr.as_slice());
+            let opt_n: Option<uint> = from_str(nstr.as_slice());
             match opt_n {
                 Some(n) if n > 0 => n,
                 _ => panic!("`RUST_THREADS` is `{}`, should be a positive integer", nstr)
index 5e9d234c6423df1de25631c2e6ed9a9797f86203..51899a87a325d72d05aff960e81f20817b041aec 100644 (file)
@@ -153,7 +153,6 @@ mod test {
     use prelude::*;
     use sync::Future;
     use task;
-    use comm::channel;
 
     #[test]
     fn test_from_value() {
index 793825f1b08f5c2b83807b8c7b90a371492f608b..366e4b7d35b01eb67acd50643dc9a0ed8e44395a 100644 (file)
@@ -131,10 +131,8 @@ fn spawn_in_pool(jobs: Arc<Mutex<Receiver<Thunk>>>) {
 
 #[cfg(test)]
 mod test {
-    use core::prelude::*;
+    use prelude::*;
     use super::*;
-    use comm::channel;
-    use iter::range;
 
     const TEST_TASKS: uint = 4u;
 
index 117d33db32896a7b57c8b6a6fd0de03af8a43deb..1a8a92a105a777d9e055be230611c31146d48b59 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub use sys::mutex::raw;
-
 use sys::mutex as imp;
 
 /// An OS-based mutual exclusion lock.
index 73da200e1623828eec709345afb7bd4b48dfce80..382f6875b281d01c3c788659978862f17608a381 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub use self::SocketStatus::*;
-pub use self::InAddr::*;
+use self::SocketStatus::*;
+use self::InAddr::*;
 
 use alloc::arc::Arc;
 use libc::{mod, c_char, c_int};
index df9dbad2ec787d81428de57046978eed4770bfaa..983d0e5fa1486b1de52656a47f3035015aee4c9d 100644 (file)
 #[cfg(all(target_os = "ios", target_arch = "arm"))]
 #[inline(never)]
 pub fn write(w: &mut Writer) -> IoResult<()> {
-    use iter::{Iterator, range};
+    use iter::{IteratorExt, range};
     use result;
     use slice::SliceExt;
 
@@ -117,7 +117,7 @@ fn backtrace(buf: *mut *mut libc::c_void,
     // while it doesn't requires lock for work as everything is
     // local, it still displays much nicer backtraces when a
     // couple of tasks panic simultaneously
-    static LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
+    static LOCK: StaticMutex = MUTEX_INIT;
     let _g = unsafe { LOCK.lock() };
 
     try!(writeln!(w, "stack backtrace:"));
index 66f7d85f20dfb4e15cc2cdc2ba3f939ed77effae..98d860f964649bed70b2ec478abd401e0b3c0f0c 100644 (file)
 use prelude::*;
 
 use io::{FilePermission, Write, UnstableFileStat, Open, FileAccess, FileMode};
-use io::{IoResult, FileStat, SeekStyle, Reader};
+use io::{IoResult, FileStat, SeekStyle};
 use io::{Read, Truncate, SeekCur, SeekSet, ReadWrite, SeekEnd, Append};
-use result::Result::{Ok, Err};
 use sys::retry;
 use sys_common::{keep_going, eof, mkerr_libc};
 
-pub use path::PosixPath as Path;
-
 pub type fd_t = libc::c_int;
 
 pub struct FileDesc {
index 0ed079df55b353f79e882346738db8ddc56dd350..6c909d7562d9aa213f1e50cb57bd468f69cfab74 100644 (file)
@@ -16,8 +16,8 @@
 use fmt;
 use io::{IoError, IoResult};
 use libc::{mod, c_int, c_char, c_void};
-use path::{Path, GenericPath, BytesContainer};
-use ptr::{mod, RawPtr};
+use path::BytesContainer;
+use ptr;
 use sync::atomic::{AtomicInt, INIT_ATOMIC_INT, SeqCst};
 use sys::fs::FileDesc;
 use os;
index 26fd410a7a9b61c19bb41426230d1e1bbbb12913..348b7cfad334ebf78aaca12cf65ff273662131be 100644 (file)
@@ -19,6 +19,7 @@
 use sys::{mod, timer, retry, c, set_nonblocking, wouldblock};
 use sys::fs::{fd_t, FileDesc};
 use sys_common::net::*;
+use sys_common::net::SocketStatus::*;
 use sys_common::{eof, mkerr_libc};
 
 fn unix_socket(ty: libc::c_int) -> IoResult<fd_t> {
index 00643ac0a79f259be77f10f9ca0bb66a04bdd985..5c99ad1e0ce223eeed6462ed42822a5f085e2f8f 100644 (file)
@@ -20,7 +20,8 @@
 use sys::{set_nonblocking, wouldblock};
 use sys;
 use sys_common;
-use sys_common::net::*;
+use sys_common::net;
+use sys_common::net::SocketStatus::Readable;
 
 pub use sys_common::net::TcpStream;
 
@@ -34,17 +35,19 @@ pub struct TcpListener {
 
 impl TcpListener {
     pub fn bind(addr: ip::SocketAddr) -> IoResult<TcpListener> {
-        let fd = try!(socket(addr, libc::SOCK_STREAM));
+        let fd = try!(net::socket(addr, libc::SOCK_STREAM));
         let ret = TcpListener { inner: FileDesc::new(fd, true) };
 
         let mut storage = unsafe { mem::zeroed() };
-        let len = addr_to_sockaddr(addr, &mut storage);
+        let len = net::addr_to_sockaddr(addr, &mut storage);
         let addrp = &storage as *const _ as *const libc::sockaddr;
 
         // On platforms with Berkeley-derived sockets, this allows
         // to quickly rebind a socket, without needing to wait for
         // the OS to clean up the previous one.
-        try!(setsockopt(fd, libc::SOL_SOCKET, libc::SO_REUSEADDR, 1 as libc::c_int));
+        try!(net::setsockopt(fd, libc::SOL_SOCKET,
+                             libc::SO_REUSEADDR,
+                             1 as libc::c_int));
 
 
         match unsafe { libc::bind(fd, addrp, len) } {
@@ -77,7 +80,7 @@ pub fn listen(self, backlog: int) -> IoResult<TcpAcceptor> {
     }
 
     pub fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
-        sockname(self.fd(), libc::getsockname)
+        net::sockname(self.fd(), libc::getsockname)
     }
 }
 
@@ -121,7 +124,7 @@ pub fn accept(&mut self) -> IoResult<TcpStream> {
                 -1 => return Err(last_net_error()),
                 fd => return Ok(TcpStream::new(fd as sock_t)),
             }
-            try!(await(&[self.fd(), self.inner.reader.fd()],
+            try!(net::await(&[self.fd(), self.inner.reader.fd()],
                        deadline, Readable));
         }
 
@@ -129,7 +132,7 @@ pub fn accept(&mut self) -> IoResult<TcpStream> {
     }
 
     pub fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
-        sockname(self.fd(), libc::getsockname)
+        net::sockname(self.fd(), libc::getsockname)
     }
 
     pub fn set_timeout(&mut self, timeout: Option<u64>) {
index 79a6a871f8dd41796779be5f66115b55c7fc8032..fe393b81e3d9a0a0f4194d3df54e1e28a08600c1 100644 (file)
@@ -46,7 +46,7 @@
 //!
 //! Note that all time units in this file are in *milliseconds*.
 
-pub use self::Req::*;
+use self::Req::*;
 
 use libc;
 use mem;
index 3cabf3a63194cceee3f107bf0e2c76150568ea8e..7f9d669c44748ec5cacb2649a040c67f634f92f2 100644 (file)
@@ -10,7 +10,6 @@
 
 use cell::UnsafeCell;
 use libc::{mod, DWORD};
-use libc;
 use os;
 use sys::mutex::{mod, Mutex};
 use sys::sync as ffi;
index 0fb52c758d5db08063a57ab7e575357d2b37f52a..d5bf8c5b62916e581388fad172799c21e8edfa44 100644 (file)
 use sys_common::{keep_going, eof, mkerr_libc};
 
 use io::{FilePermission, Write, UnstableFileStat, Open, FileAccess, FileMode};
-use io::{IoResult, IoError, FileStat, SeekStyle, Seek, Writer, Reader};
+use io::{IoResult, IoError, FileStat, SeekStyle};
 use io::{Read, Truncate, SeekCur, SeekSet, ReadWrite, SeekEnd, Append};
 
-pub use path::WindowsPath as Path;
 pub type fd_t = libc::c_int;
 
 pub struct FileDesc {
index 2fbb9494c710bdba8d1eb57f14ceb352a60e8df9..e2220b7b67bbd6e5dbb5f50c78901c27a731f454 100644 (file)
 use libc::{c_int, c_char, c_void};
 use libc;
 use os;
-use path::{Path, GenericPath, BytesContainer};
-use ptr::{mod, RawPtr};
+use path::BytesContainer;
+use ptr;
 use sync::atomic::{AtomicInt, INIT_ATOMIC_INT, SeqCst};
 use sys::fs::FileDesc;
-use option::Option;
-use option::Option::{Some, None};
 use slice;
 
 use os::TMPBUF_SZ;
index bbfd32ee76bfab72b273127eacc9b88b7af24f72..8945c155e66cedeb6816cb7c652a38d345195d6d 100644 (file)
@@ -29,7 +29,6 @@
 use sys_common::{AsInner, mkerr_libc, timeout};
 
 use io::fs::PathExtensions;
-use string::String;
 
 pub use sys_common::ProcessConfig;
 
index b577372d2fc591ed1d3ff693a2eb789a8896c620..505e6137bf9047162416ccaa277497642224b030 100644 (file)
@@ -18,8 +18,7 @@
 use sync::{Arc, atomic};
 use sys::fs::FileDesc;
 use sys::{mod, c, set_nonblocking, wouldblock, timer};
-use sys_common::{mod, timeout, eof};
-use sys_common::net::*;
+use sys_common::{mod, timeout, eof, net};
 
 pub use sys_common::net::TcpStream;
 
@@ -54,11 +53,11 @@ impl TcpListener {
     pub fn bind(addr: ip::SocketAddr) -> IoResult<TcpListener> {
         sys::init_net();
 
-        let sock = try!(socket(addr, libc::SOCK_STREAM));
+        let sock = try!(net::socket(addr, libc::SOCK_STREAM));
         let ret = TcpListener { sock: sock };
 
         let mut storage = unsafe { mem::zeroed() };
-        let len = addr_to_sockaddr(addr, &mut storage);
+        let len = net::addr_to_sockaddr(addr, &mut storage);
         let addrp = &storage as *const _ as *const libc::sockaddr;
 
         match unsafe { libc::bind(sock, addrp, len) } {
@@ -95,7 +94,7 @@ pub fn listen(self, backlog: int) -> IoResult<TcpAcceptor> {
     }
 
     pub fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
-        sockname(self.socket(), libc::getsockname)
+        net::sockname(self.socket(), libc::getsockname)
     }
 }
 
@@ -195,7 +194,7 @@ pub fn accept(&mut self) -> IoResult<TcpStream> {
     }
 
     pub fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
-        sockname(self.socket(), libc::getsockname)
+        net::sockname(self.socket(), libc::getsockname)
     }
 
     pub fn set_timeout(&mut self, timeout: Option<u64>) {
index e2f9e2a9201c3c260e7f55b4d3a19e2d5cff3098..7e4dd768aa975f8ef6f3a4bb8921037906acfb47 100644 (file)
@@ -20,7 +20,7 @@
 //! Other than that, the implementation is pretty straightforward in terms of
 //! the other two implementations of timers with nothing *that* new showing up.
 
-pub use self::Req::*;
+use self::Req::*;
 
 use libc;
 use ptr;
index 8ef53a22aeb04c765f2ae6ecd2165df40ae054eb..89773207347d548e0d8fafd7f7dbbd38066a2dae 100644 (file)
 //!
 //! * It can be implemented highly efficiently on many platforms.
 
-use core::prelude::*;
-
 use any::Any;
 use borrow::IntoCow;
 use boxed::Box;
 use cell::UnsafeCell;
+use clone::Clone;
+use kinds::Send;
+use ops::{Drop, FnOnce};
+use option::Option::{mod, Some, None};
+use result::Result::{Err, Ok};
 use sync::{Mutex, Condvar, Arc};
+use str::Str;
 use string::String;
 use rt::{mod, unwind};
 use io::{Writer, stdio};
@@ -424,13 +428,11 @@ fn drop(&mut self) {
 
 #[cfg(test)]
 mod test {
+    use prelude::*;
     use any::{Any, AnyRefExt};
     use boxed::BoxAny;
-    use prelude::*;
-    use result::Result::{Ok, Err};
     use result;
     use std::io::{ChanReader, ChanWriter};
-    use string::String;
     use thunk::Thunk;
     use super::{Thread, Builder};
 
diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs
new file mode 100644 (file)
index 0000000..5cd60d6
--- /dev/null
@@ -0,0 +1,66 @@
+// 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.
+
+//! Operations on tuples
+//!
+//! To access a single element of a tuple one can use the following
+//! methods:
+//!
+//! * `valN` - returns a value of _N_-th element
+//! * `refN` - returns a reference to _N_-th element
+//! * `mutN` - returns a mutable reference to _N_-th element
+//!
+//! Indexing starts from zero, so `val0` returns first value, `val1`
+//! returns second value, and so on. In general, a tuple with _S_
+//! elements provides aforementioned methods suffixed with numbers
+//! from `0` to `S-1`. Traits which contain these methods are
+//! implemented for tuples with up to 12 elements.
+//!
+//! If every type inside a tuple implements one of the following
+//! traits, then a tuple itself also implements it.
+//!
+//! * `Clone`
+//! * `PartialEq`
+//! * `Eq`
+//! * `PartialOrd`
+//! * `Ord`
+//! * `Default`
+//!
+//! # Examples
+//!
+//! Using methods:
+//!
+//! ```
+//! #[allow(deprecated)]
+//! # fn main() {
+//! let pair = ("pi", 3.14f64);
+//! assert_eq!(pair.val0(), "pi");
+//! assert_eq!(pair.val1(), 3.14f64);
+//! # }
+//! ```
+//!
+//! Using traits implemented for tuples:
+//!
+//! ```
+//! use std::default::Default;
+//!
+//! let a = (1i, 2i);
+//! let b = (3i, 4i);
+//! assert!(a != b);
+//!
+//! let c = b.clone();
+//! assert!(b == c);
+//!
+//! let d : (u32, f32) = Default::default();
+//! assert_eq!(d, (0u32, 0.0f32));
+//! ```
+
+#![doc(primitive = "tuple")]
+#![stable]
diff --git a/src/libstd/unit.rs b/src/libstd/unit.rs
new file mode 100644 (file)
index 0000000..012b175
--- /dev/null
@@ -0,0 +1,45 @@
+// 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.
+
+#![doc(primitive = "unit")]
+#![stable]
+
+//! The `()` type, sometimes called "unit" or "nil".
+//!
+//! The `()` type has exactly one value `()`, and is used when there
+//! is no other meaningful value that could be returned. `()` is most
+//! commonly seen implicitly: functions without a `-> ...` implicitly
+//! have return type `()`, that is, these are equivalent:
+//!
+//! ```rust
+//! fn long() -> () {}
+//!
+//! fn short() {}
+//! ```
+//!
+//! The semicolon `;` can be used to discard the result of an
+//! expression at the end of a block, making the expression (and thus
+//! the block) evaluate to `()`. For example,
+//!
+//! ```rust
+//! fn returns_i64() -> i64 {
+//!     1i64
+//! }
+//! fn returns_unit() {
+//!     1i64;
+//! }
+//!
+//! let is_i64 = {
+//!     returns_i64()
+//! };
+//! let is_unit = {
+//!     returns_i64();
+//! };
+//! ```
index be8f32bc4d5d8e58a640b0b461e817613391c8d0..a294706ef2c10ff67131e4cbb6b517367592b97a 100644 (file)
@@ -32,7 +32,6 @@
 pub use self::LocalSource::*;
 pub use self::Mac_::*;
 pub use self::MacStmtStyle::*;
-pub use self::MatchSource::*;
 pub use self::MetaItem_::*;
 pub use self::Method_::*;
 pub use self::Mutability::*;
@@ -415,17 +414,24 @@ pub struct WhereClause {
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum WherePredicate {
     BoundPredicate(WhereBoundPredicate),
+    RegionPredicate(WhereRegionPredicate),
     EqPredicate(WhereEqPredicate)
 }
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub struct WhereBoundPredicate {
-    pub id: NodeId,
     pub span: Span,
-    pub ident: Ident,
+    pub bounded_ty: P<Ty>,
     pub bounds: OwnedSlice<TyParamBound>,
 }
 
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
+pub struct WhereRegionPredicate {
+    pub span: Span,
+    pub lifetime: Lifetime,
+    pub bounds: Vec<Lifetime>,
+}
+
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub struct WhereEqPredicate {
     pub id: NodeId,
@@ -753,9 +759,9 @@ pub struct QPath {
 
 #[deriving(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum MatchSource {
-    MatchNormal,
-    MatchIfLetDesugar,
-    MatchWhileLetDesugar,
+    Normal,
+    IfLetDesugar { contains_else_clause: bool },
+    WhileLetDesugar,
 }
 
 #[deriving(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
index 3947a602809e69529e481ba6425a28c824d8c3fe..aefbb2a1feab365e0d0629a76fb24feecf7731fe 100644 (file)
@@ -490,7 +490,7 @@ pub fn expand_expr(&mut self, e: P<ast::Expr>) -> P<ast::Expr> {
 
     /// Returns a `Folder` for deeply expanding all macros in a AST node.
     pub fn expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> {
-        expand::MacroExpander { cx: self }
+        expand::MacroExpander::new(self)
     }
 
     pub fn new_parser_from_tts(&self, tts: &[ast::TokenTree])
index d35091f8ab0aaf11cd205cd4f3b13a94c95bbad6..9d4992f7453d0ab638982fa8756b6db6f6a43c23 100644 (file)
@@ -868,7 +868,7 @@ fn arm_unreachable(&self, span: Span) -> ast::Arm {
     }
 
     fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: Vec<ast::Arm>) -> P<Expr> {
-        self.expr(span, ast::ExprMatch(arg, arms, ast::MatchNormal))
+        self.expr(span, ast::ExprMatch(arg, arms, ast::MatchSource::Normal))
     }
 
     fn expr_if(&self, span: Span, cond: P<ast::Expr>,
index b31758e2d2a127cd5d81117fc6fa3f677ea0aabd..d8de3d2db9795c992cba98d3d8d68e7ffa0a65c8 100644 (file)
@@ -426,12 +426,18 @@ fn create_derived_impl(&self,
             match *clause {
                 ast::WherePredicate::BoundPredicate(ref wb) => {
                     ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
-                        id: ast::DUMMY_NODE_ID,
                         span: self.span,
-                        ident: wb.ident,
+                        bounded_ty: wb.bounded_ty.clone(),
                         bounds: OwnedSlice::from_vec(wb.bounds.iter().map(|b| b.clone()).collect())
                     })
                 }
+                ast::WherePredicate::RegionPredicate(ref rb) => {
+                    ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
+                        span: self.span,
+                        lifetime: rb.lifetime,
+                        bounds: rb.bounds.iter().map(|b| b.clone()).collect()
+                    })
+                }
                 ast::WherePredicate::EqPredicate(ref we) => {
                     ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
                         id: ast::DUMMY_NODE_ID,
index 20c8ff20b713b88bd3b62a690d8a27e242aa251e..b10ae7a09db17a7c518eeb557e2a6e37a8c412c7 100644 (file)
@@ -15,6 +15,7 @@
 use ast::{StmtExpr, StmtSemi};
 use ast::TokenTree;
 use ast;
+use ast_util::path_to_ident;
 use ext::mtwt;
 use ext::build::AstBuilder;
 use attr;
@@ -37,6 +38,30 @@ enum Either<L,R> {
     Right(R)
 }
 
+pub fn expand_type(t: P<ast::Ty>,
+                   fld: &mut MacroExpander,
+                   impl_ty: Option<P<ast::Ty>>)
+                   -> P<ast::Ty> {
+    debug!("expanding type {} with impl_ty {}", t, impl_ty);
+    let t = match (t.node.clone(), impl_ty) {
+        // Expand uses of `Self` in impls to the concrete type.
+        (ast::Ty_::TyPath(ref path, _), Some(ref impl_ty)) => {
+            let path_as_ident = path_to_ident(path);
+            // Note unhygenic comparison here. I think this is correct, since
+            // even though `Self` is almost just a type parameter, the treatment
+            // for this expansion is as if it were a keyword.
+            if path_as_ident.is_some() &&
+               path_as_ident.unwrap().name == token::special_idents::type_self.name {
+                impl_ty.clone()
+            } else {
+                t
+            }
+        }
+        _ => t
+    };
+    fold::noop_fold_ty(t, fld)
+}
+
 pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
     e.and_then(|ast::Expr {id, node, span}| match node {
         // expr_mac should really be expr_ext or something; it's the
@@ -97,7 +122,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
             // `match <expr> { ... }`
             let arms = vec![pat_arm, break_arm];
             let match_expr = fld.cx.expr(span,
-                                         ast::ExprMatch(expr, arms, ast::MatchWhileLetDesugar));
+                                    ast::ExprMatch(expr, arms, ast::MatchSource::WhileLetDesugar));
 
             // `[opt_ident]: loop { ... }`
             let loop_block = fld.cx.block_expr(match_expr);
@@ -158,6 +183,8 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
                 arms
             };
 
+            let contains_else_clause = elseopt.is_some();
+
             // `_ => [<elseopt> | ()]`
             let else_arm = {
                 let pat_under = fld.cx.pat_wild(span);
@@ -170,7 +197,11 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
             arms.extend(else_if_arms.into_iter());
             arms.push(else_arm);
 
-            let match_expr = fld.cx.expr(span, ast::ExprMatch(expr, arms, ast::MatchIfLetDesugar));
+            let match_expr = fld.cx.expr(span,
+                                         ast::ExprMatch(expr, arms,
+                                                ast::MatchSource::IfLetDesugar {
+                                                    contains_else_clause: contains_else_clause,
+                                                }));
             fld.fold_expr(match_expr)
         }
 
@@ -1059,6 +1090,14 @@ fn expand_and_rename_fn_decl_and_block(fn_decl: P<ast::FnDecl>, block: P<ast::Bl
 /// A tree-folder that performs macro expansion
 pub struct MacroExpander<'a, 'b:'a> {
     pub cx: &'a mut ExtCtxt<'b>,
+    // The type of the impl currently being expanded.
+    current_impl_type: Option<P<ast::Ty>>,
+}
+
+impl<'a, 'b> MacroExpander<'a, 'b> {
+    pub fn new(cx: &'a mut ExtCtxt<'b>) -> MacroExpander<'a, 'b> {
+        MacroExpander { cx: cx, current_impl_type: None }
+    }
 }
 
 impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
@@ -1071,7 +1110,14 @@ fn fold_pat(&mut self, pat: P<ast::Pat>) -> P<ast::Pat> {
     }
 
     fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
-        expand_item(item, self)
+        let prev_type = self.current_impl_type.clone();
+        if let ast::Item_::ItemImpl(_, _, _, ref ty, _) = item.node {
+            self.current_impl_type = Some(ty.clone());
+        }
+
+        let result = expand_item(item, self);
+        self.current_impl_type = prev_type;
+        result
     }
 
     fn fold_item_underscore(&mut self, item: ast::Item_) -> ast::Item_ {
@@ -1094,6 +1140,11 @@ fn fold_method(&mut self, method: P<ast::Method>) -> SmallVector<P<ast::Method>>
         expand_method(method, self)
     }
 
+    fn fold_ty(&mut self, t: P<ast::Ty>) -> P<ast::Ty> {
+        let impl_type = self.current_impl_type.clone();
+        expand_type(t, self, impl_type)
+    }
+
     fn new_span(&mut self, span: Span) -> Span {
         new_span(self.cx, span)
     }
@@ -1138,9 +1189,7 @@ pub fn expand_crate(parse_sess: &parse::ParseSess,
                     user_exts: Vec<NamedSyntaxExtension>,
                     c: Crate) -> Crate {
     let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg);
-    let mut expander = MacroExpander {
-        cx: &mut cx,
-    };
+    let mut expander = MacroExpander::new(&mut cx);
 
     for ExportedMacros { crate_name, macros } in imported_macros.into_iter() {
         let name = format!("<{} macros>", token::get_ident(crate_name))
index 5d595474e9c70e33c25f0fde134030ace1e98d55..95c7fcc564af8ad3465ff56c09668744985d70d8 100644 (file)
@@ -654,6 +654,7 @@ fn format_arg(ecx: &ExtCtxt, sp: Span,
             Known(ref tyname) => {
                 match tyname.as_slice() {
                     ""  => "Show",
+                    "?" => "Show",
                     "e" => "LowerExp",
                     "E" => "UpperExp",
                     "o" => "Octal",
index ae979020bc7e5351cb09d16258852970fbf217e5..f0392912878ff5c8f5aba57e64a62347361d0042 100644 (file)
@@ -21,7 +21,7 @@
 
 use std::cell::RefCell;
 use std::collections::HashMap;
-use std::collections::hash_map::{Occupied, Vacant};
+use std::collections::hash_map::Entry::{Occupied, Vacant};
 
 /// The SCTable contains a table of SyntaxContext_'s. It
 /// represents a flattened tree structure, to avoid having
index 4785fe37293c0bf3a9a365a5f53e8ba6d38fe4d8..bc639c32380f5eb040250122ed7663dc9e41dd86 100644 (file)
@@ -98,7 +98,7 @@
 use std::mem;
 use std::rc::Rc;
 use std::collections::HashMap;
-use std::collections::hash_map::{Vacant, Occupied};
+use std::collections::hash_map::Entry::{Vacant, Occupied};
 
 // To avoid costly uniqueness checks, we require that `MatchSeq` always has
 // a nonempty body.
index 10860ee5e01de99706a71f8e0d871af35440a41f..86df588386464d33bb270d34839a8a0291b99436 100644 (file)
@@ -814,17 +814,24 @@ pub fn noop_fold_where_predicate<T: Folder>(
                                  fld: &mut T)
                                  -> WherePredicate {
     match pred {
-        ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{id,
-                                                                     ident,
+        ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{bounded_ty,
                                                                      bounds,
                                                                      span}) => {
             ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
-                id: fld.new_id(id),
-                ident: fld.fold_ident(ident),
+                bounded_ty: fld.fold_ty(bounded_ty),
                 bounds: bounds.move_map(|x| fld.fold_ty_param_bound(x)),
                 span: fld.new_span(span)
             })
         }
+        ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{lifetime,
+                                                                       bounds,
+                                                                       span}) => {
+            ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
+                span: fld.new_span(span),
+                lifetime: fld.fold_lifetime(lifetime),
+                bounds: bounds.move_map(|bound| fld.fold_lifetime(bound))
+            })
+        }
         ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{id,
                                                                path,
                                                                ty,
index 5d5b56d444f8ec2deb3a054f34e3cdf7f82f908d..5f62c74ef0742814e524db0b63c3dd64fa006cbc 100644 (file)
@@ -24,7 +24,7 @@
 
 #![allow(unknown_features)]
 #![feature(macro_rules, globs, default_type_params, phase, slicing_syntax)]
-#![feature(quote, unsafe_destructor, import_shadowing)]
+#![feature(quote, unsafe_destructor)]
 #![feature(unboxed_closures)]
 
 extern crate arena;
index d6f5d0e248a86d206be640d88a82d988bec4ef60..3d0877dd4327311f4ee3505e07f65a9a30fd0818 100644 (file)
@@ -745,8 +745,7 @@ mod test {
     use owned_slice::OwnedSlice;
     use ast;
     use abi;
-    use attr;
-    use attr::AttrMetaMethods;
+    use attr::{first_attr_value_str_by_name, AttrMetaMethods};
     use parse::parser::Parser;
     use parse::token::{str_to_ident};
     use print::pprust::view_item_to_string;
@@ -1195,7 +1194,7 @@ fn wb() -> c_int { O_WRONLY as c_int }
         let name = "<source>".to_string();
         let source = "/// doc comment\r\nfn foo() {}".to_string();
         let item = parse_item_from_source_str(name.clone(), source, Vec::new(), &sess).unwrap();
-        let doc = attr::first_attr_value_str_by_name(item.attrs.as_slice(), "doc").unwrap();
+        let doc = first_attr_value_str_by_name(item.attrs.as_slice(), "doc").unwrap();
         assert_eq!(doc.get(), "/// doc comment");
 
         let source = "/// doc comment\r\n/// line 2\r\nfn foo() {}".to_string();
@@ -1207,7 +1206,7 @@ fn wb() -> c_int { O_WRONLY as c_int }
 
         let source = "/** doc comment\r\n *  with CRLF */\r\nfn foo() {}".to_string();
         let item = parse_item_from_source_str(name, source, Vec::new(), &sess).unwrap();
-        let doc = attr::first_attr_value_str_by_name(item.attrs.as_slice(), "doc").unwrap();
+        let doc = first_attr_value_str_by_name(item.attrs.as_slice(), "doc").unwrap();
         assert_eq!(doc.get(), "/** doc comment\n *  with CRLF */");
     }
 }
index 3ad224b93ce9625920b5638d9729890c7332515b..19af118b190517d57591b43021ea101c8400af05 100644 (file)
@@ -41,7 +41,7 @@
 use ast::{LitBool, LitChar, LitByte, LitBinary};
 use ast::{LitStr, LitInt, Local, LocalLet};
 use ast::{MacStmtWithBraces, MacStmtWithSemicolon, MacStmtWithoutBraces};
-use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, MatchNormal};
+use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, MatchSource};
 use ast::{Method, MutTy, BiMul, Mutability};
 use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, NodeId, UnNot};
 use ast::{Pat, PatEnum, PatIdent, PatLit, PatRange, PatRegion, PatStruct};
@@ -1497,9 +1497,6 @@ pub fn parse_ty_sum(&mut self) -> P<Ty> {
     }
 
     /// Parse a type.
-    ///
-    /// The second parameter specifies whether the `+` binary operator is
-    /// allowed in the type grammar.
     pub fn parse_ty(&mut self) -> P<Ty> {
         maybe_whole!(no_clone self, NtTy);
 
@@ -1548,7 +1545,7 @@ pub fn parse_ty(&mut self) -> P<Ty> {
             self.expect(&token::OpenDelim(token::Bracket));
             let t = self.parse_ty_sum();
 
-            // Parse the `, ..e` in `[ int, ..e ]`
+            // Parse the `; e` in `[ int; e ]`
             // where `e` is a const expression
             let t = match self.maybe_parse_fixed_vstore() {
                 None => TyVec(t),
@@ -1716,6 +1713,9 @@ pub fn maybe_parse_fixed_vstore(&mut self) -> Option<P<ast::Expr>> {
             self.bump();
             self.bump();
             Some(self.parse_expr())
+        } else if self.check(&token::Semi) {
+            self.bump();
+            Some(self.parse_expr())
         } else {
             None
         }
@@ -2262,6 +2262,12 @@ pub fn parse_bottom_expr(&mut self) -> P<Expr> {
                         let count = self.parse_expr();
                         self.expect(&token::CloseDelim(token::Bracket));
                         ex = ExprRepeat(first_expr, count);
+                    } else if self.check(&token::Semi) {
+                        // Repeating vector syntax: [ 0; 512 ]
+                        self.bump();
+                        let count = self.parse_expr();
+                        self.expect(&token::CloseDelim(token::Bracket));
+                        ex = ExprRepeat(first_expr, count);
                     } else if self.check(&token::Comma) {
                         // Vector with two or more elements.
                         self.bump();
@@ -3114,7 +3120,7 @@ fn parse_match_expr(&mut self) -> P<Expr> {
         }
         let hi = self.span.hi;
         self.bump();
-        return self.mk_expr(lo, hi, ExprMatch(discriminant, arms, MatchNormal));
+        return self.mk_expr(lo, hi, ExprMatch(discriminant, arms, MatchSource::Normal));
     }
 
     pub fn parse_arm(&mut self) -> Arm {
@@ -4179,6 +4185,10 @@ fn forbid_lifetime(&mut self) {
     }
 
     /// Parses an optional `where` clause and places it in `generics`.
+    ///
+    /// ```
+    /// where T : Trait<U, V> + 'b, 'a : 'b
+    /// ```
     fn parse_where_clause(&mut self, generics: &mut ast::Generics) {
         if !self.eat_keyword(keywords::Where) {
             return
@@ -4187,58 +4197,79 @@ fn parse_where_clause(&mut self, generics: &mut ast::Generics) {
         let mut parsed_something = false;
         loop {
             let lo = self.span.lo;
-            let path = match self.token {
-                token::Ident(..) => self.parse_path(NoTypesAllowed),
-                _ => break,
-            };
+            match self.token {
+                token::OpenDelim(token::Brace) => {
+                    break
+                }
 
-            if self.eat(&token::Colon) {
-                let bounds = self.parse_ty_param_bounds();
-                let hi = self.span.hi;
-                let span = mk_sp(lo, hi);
+                token::Lifetime(..) => {
+                    let bounded_lifetime =
+                        self.parse_lifetime();
 
-                if bounds.len() == 0 {
-                    self.span_err(span,
-                                  "each predicate in a `where` clause must have \
-                                   at least one bound in it");
+                    self.eat(&token::Colon);
+
+                    let bounds =
+                        self.parse_lifetimes(token::BinOp(token::Plus));
+
+                    let hi = self.span.hi;
+                    let span = mk_sp(lo, hi);
+
+                    generics.where_clause.predicates.push(ast::WherePredicate::RegionPredicate(
+                        ast::WhereRegionPredicate {
+                            span: span,
+                            lifetime: bounded_lifetime,
+                            bounds: bounds
+                        }
+                    ));
+
+                    parsed_something = true;
                 }
 
-                let ident = match ast_util::path_to_ident(&path) {
-                    Some(ident) => ident,
-                    None => {
-                        self.span_err(path.span, "expected a single identifier \
-                                                  in bound where clause");
-                        break;
-                    }
-                };
+                _ => {
+                    let bounded_ty = self.parse_ty();
 
-                generics.where_clause.predicates.push(
-                    ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
-                        id: ast::DUMMY_NODE_ID,
-                        span: span,
-                        ident: ident,
-                        bounds: bounds,
-                }));
-                parsed_something = true;
-            } else if self.eat(&token::Eq) {
-                let ty = self.parse_ty();
-                let hi = self.span.hi;
-                let span = mk_sp(lo, hi);
-                generics.where_clause.predicates.push(
-                    ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
-                        id: ast::DUMMY_NODE_ID,
-                        span: span,
-                        path: path,
-                        ty: ty,
-                }));
-                parsed_something = true;
-                // FIXME(#18433)
-                self.span_err(span, "equality constraints are not yet supported in where clauses");
-            } else {
-                let last_span = self.last_span;
-                self.span_err(last_span,
+                    if self.eat(&token::Colon) {
+                        let bounds = self.parse_ty_param_bounds();
+                        let hi = self.span.hi;
+                        let span = mk_sp(lo, hi);
+
+                        if bounds.len() == 0 {
+                            self.span_err(span,
+                                          "each predicate in a `where` clause must have \
+                                   at least one bound in it");
+                        }
+
+                        generics.where_clause.predicates.push(ast::WherePredicate::BoundPredicate(
+                                ast::WhereBoundPredicate {
+                                    span: span,
+                                    bounded_ty: bounded_ty,
+                                    bounds: bounds,
+                        }));
+
+                        parsed_something = true;
+                    } else if self.eat(&token::Eq) {
+                        // let ty = self.parse_ty();
+                        let hi = self.span.hi;
+                        let span = mk_sp(lo, hi);
+                        // generics.where_clause.predicates.push(
+                        //     ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
+                        //         id: ast::DUMMY_NODE_ID,
+                        //         span: span,
+                        //         path: panic!("NYI"), //bounded_ty,
+                        //         ty: ty,
+                        // }));
+                        // parsed_something = true;
+                        // // FIXME(#18433)
+                        self.span_err(span,
+                                     "equality constraints are not yet supported \
+                                     in where clauses (#20041)");
+                    } else {
+                        let last_span = self.last_span;
+                        self.span_err(last_span,
                               "unexpected token in `where` clause");
-            }
+                    }
+                }
+            };
 
             if !self.eat(&token::Comma) {
                 break
index d2cc0cba3173cf7b3011cfc6fb04a55f52f6418c..a9717a526ad9db6cb28327ec56cc97d5df7c0e25 100644 (file)
@@ -755,7 +755,7 @@ pub fn print_type(&mut self, ty: &ast::Ty) -> IoResult<()> {
             ast::TyFixedLengthVec(ref ty, ref v) => {
                 try!(word(&mut self.s, "["));
                 try!(self.print_type(&**ty));
-                try!(word(&mut self.s, ", .."));
+                try!(word(&mut self.s, ""));
                 try!(self.print_expr(&**v));
                 try!(word(&mut self.s, "]"));
             }
@@ -1531,8 +1531,7 @@ pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> {
                 try!(self.ibox(indent_unit));
                 try!(word(&mut self.s, "["));
                 try!(self.print_expr(&**element));
-                try!(word(&mut self.s, ","));
-                try!(word(&mut self.s, ".."));
+                try!(self.word_space(";"));
                 try!(self.print_expr(&**count));
                 try!(word(&mut self.s, "]"));
                 try!(self.end());
@@ -2437,12 +2436,26 @@ pub fn print_where_clause(&mut self, generics: &ast::Generics)
             }
 
             match predicate {
-                &ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ident,
+                &ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ref bounded_ty,
                                                                               ref bounds,
                                                                               ..}) => {
-                    try!(self.print_ident(ident));
+                    try!(self.print_type(&**bounded_ty));
                     try!(self.print_bounds(":", bounds.as_slice()));
                 }
+                &ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime,
+                                                                                ref bounds,
+                                                                                ..}) => {
+                    try!(self.print_lifetime(lifetime));
+                    try!(word(&mut self.s, ":"));
+
+                    for (i, bound) in bounds.iter().enumerate() {
+                        try!(self.print_lifetime(bound));
+
+                        if i != 0 {
+                            try!(word(&mut self.s, ":"));
+                        }
+                    }
+                }
                 &ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{ref path, ref ty, ..}) => {
                     try!(self.print_path(path, false));
                     try!(space(&mut self.s));
index b89e9a59349ce3e341ae7276e96eba8e612c1843..9938feb171eb0fc738509969e29cf5c7b6b6857a 100644 (file)
@@ -583,13 +583,21 @@ pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics
     walk_lifetime_decls_helper(visitor, &generics.lifetimes);
     for predicate in generics.where_clause.predicates.iter() {
         match predicate {
-            &ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{span,
-                                                                          ident,
+            &ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ref bounded_ty,
                                                                           ref bounds,
                                                                           ..}) => {
-                visitor.visit_ident(span, ident);
+                visitor.visit_ty(&**bounded_ty);
                 walk_ty_param_bounds_helper(visitor, bounds);
             }
+            &ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime,
+                                                                            ref bounds,
+                                                                            ..}) => {
+                visitor.visit_lifetime_ref(lifetime);
+
+                for bound in bounds.iter() {
+                    visitor.visit_lifetime_ref(bound);
+                }
+            }
             &ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{id,
                                                                     ref path,
                                                                     ref ty,
index 7441b39f35b23f5bdb70125af55ae2a21161c7e7..41146cded704c281779f9e925f66c0a76c6e7ddc 100644 (file)
@@ -11,7 +11,7 @@
 #![allow(missing_docs)]
 
 use std::collections::hash_map;
-use std::collections::hash_map::{Occupied, Vacant};
+use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::fmt::Show;
 use std::hash::Hash;
 use std::io;
index 96bae65639073de25c00b22890712223a740fd74..d97a2e3cda129d9da850ae0acf5507ff21b3c033 100644 (file)
@@ -28,7 +28,7 @@ pub fn foo(&self) {
 pub struct Parser<T>;
 impl<T: std::iter::Iterator<char>> Parser<T> {
     fn in_doctype(&mut self) {
-        static DOCTYPEPattern: [char, ..6] = ['O', 'C', 'T', 'Y', 'P', 'E'];
+        static DOCTYPEPattern: [char6] = ['O', 'C', 'T', 'Y', 'P', 'E'];
     }
 }
 
index 025f8467d206770d9dac925306b04d2e2e554a38..75cf864ce49612a00d48e336c4dd12ef8d03fd8e 100644 (file)
@@ -37,20 +37,20 @@ fn gradient(orig: Vec2, grad: Vec2, p: Vec2) -> f32 {
 }
 
 struct Noise2DContext {
-    rgradients: [Vec2, ..256],
-    permutations: [i32, ..256],
+    rgradients: [Vec2256],
+    permutations: [i32256],
 }
 
 impl Noise2DContext {
     fn new() -> Noise2DContext {
         let mut rng = StdRng::new().unwrap();
 
-        let mut rgradients = [Vec2 { x: 0.0, y: 0.0 }, ..256];
+        let mut rgradients = [Vec2 { x: 0.0, y: 0.0 }256];
         for x in rgradients.iter_mut() {
             *x = random_gradient(&mut rng);
         }
 
-        let mut permutations = [0i32, ..256];
+        let mut permutations = [0i32256];
         for (i, x) in permutations.iter_mut().enumerate() {
             *x = i as i32;
         }
@@ -65,7 +65,7 @@ fn get_gradient(&self, x: i32, y: i32) -> Vec2 {
         self.rgradients[(idx & 255) as uint]
     }
 
-    fn get_gradients(&self, x: f32, y: f32) -> ([Vec2, ..4], [Vec2, ..4]) {
+    fn get_gradients(&self, x: f32, y: f32) -> ([Vec2; 4], [Vec2; 4]) {
         let x0f = x.floor();
         let y0f = y.floor();
         let x1f = x0f + 1.0;
@@ -102,7 +102,7 @@ fn get(&self, x: f32, y: f32) -> f32 {
 
 fn main() {
     let symbols = [' ', 'â–‘', 'â–’', 'â–“', 'â–ˆ', 'â–ˆ'];
-    let mut pixels = [0f32, ..256*256];
+    let mut pixels = [0f32256*256];
     let n2d = Noise2DContext::new();
 
     for _ in range(0u, 100) {
index 4849421a3f01eceaebe07fdab4cbed2afadb1ef1..723b2b722d7e12258380e0594f9418367cf29975 100644 (file)
@@ -64,14 +64,14 @@ fn next_permutation(perm: &mut [i32], count: &mut [i32]) {
 }
 
 struct P {
-    p: [i32, .. 16],
+    p: [i32; 16],
 }
 
 impl Copy for P {}
 
 struct Perm {
-    cnt: [i32, .. 16],
-    fact: [u32, .. 16],
+    cnt: [i32; 16],
+    fact: [u32; 16],
     n: u32,
     permcount: u32,
     perm: P,
@@ -81,21 +81,21 @@ impl Copy for Perm {}
 
 impl Perm {
     fn new(n: u32) -> Perm {
-        let mut fact = [1, .. 16];
+        let mut fact = [1; 16];
         for i in range(1, n as uint + 1) {
             fact[i] = fact[i - 1] * i as u32;
         }
         Perm {
-            cnt: [0, .. 16],
+            cnt: [0; 16],
             fact: fact,
             n: n,
             permcount: 0,
-            perm: P { p: [0, .. 16 ] }
+            perm: P { p: [0; 16 ] }
         }
     }
 
     fn get(&mut self, mut idx: i32) -> P {
-        let mut pp = [0u8, .. 16];
+        let mut pp = [0u8; 16];
         self.permcount = idx as u32;
         for (i, place) in self.perm.p.iter_mut().enumerate() {
             *place = i as i32 + 1;
index afffbe5bed4e42dfff0f2c2eb0d7331c6ea3264c..eb18cfdaed3ad73bfc6b92ddab96c9880416a6ff 100644 (file)
@@ -64,7 +64,7 @@
 
 const NULL_AMINO_ACID: AminoAcid = AminoAcid { c: ' ' as u8, p: 0.0 };
 
-static IUB: [AminoAcid, ..15] = [
+static IUB: [AminoAcid;15] = [
     AminoAcid { c: 'a' as u8, p: 0.27 },
     AminoAcid { c: 'c' as u8, p: 0.12 },
     AminoAcid { c: 'g' as u8, p: 0.12 },
@@ -82,7 +82,7 @@
     AminoAcid { c: 'Y' as u8, p: 0.02 },
 ];
 
-static HOMO_SAPIENS: [AminoAcid, ..4] = [
+static HOMO_SAPIENS: [AminoAcid;4] = [
     AminoAcid { c: 'a' as u8, p: 0.3029549426680 },
     AminoAcid { c: 'c' as u8, p: 0.1979883004921 },
     AminoAcid { c: 'g' as u8, p: 0.1975473066391 },
@@ -148,8 +148,8 @@ fn make(&mut self, n: uint) -> IoResult<()> {
     }
 }
 
-fn make_lookup(a: &[AminoAcid]) -> [AminoAcid, ..LOOKUP_SIZE] {
-    let mut lookup = [ NULL_AMINO_ACID, ..LOOKUP_SIZE ];
+fn make_lookup(a: &[AminoAcid]) -> [AminoAcid;LOOKUP_SIZE] {
+    let mut lookup = [ NULL_AMINO_ACID;LOOKUP_SIZE ];
     let mut j = 0;
     for (i, slot) in lookup.iter_mut().enumerate() {
         while a[j].p < (i as f32) {
@@ -162,7 +162,7 @@ fn make_lookup(a: &[AminoAcid]) -> [AminoAcid, ..LOOKUP_SIZE] {
 
 struct RandomFasta<'a, W:'a> {
     seed: u32,
-    lookup: [AminoAcid, ..LOOKUP_SIZE],
+    lookup: [AminoAcid;LOOKUP_SIZE],
     out: &'a mut W,
 }
 
@@ -193,7 +193,7 @@ fn nextc(&mut self) -> u8 {
     fn make(&mut self, n: uint) -> IoResult<()> {
         let lines = n / LINE_LEN;
         let chars_left = n % LINE_LEN;
-        let mut buf = [0, ..LINE_LEN + 1];
+        let mut buf = [0;LINE_LEN + 1];
 
         for _ in range(0, lines) {
             for i in range(0u, LINE_LEN) {
index 1f0bed055211dc35778a3f8f1a2bc0f58db606ca..2de61cf3572c92c8cce0926f142df7ce48ff7e82 100644 (file)
@@ -89,7 +89,7 @@ fn make_fasta<W: Writer, I: Iterator<u8>>(
     -> std::io::IoResult<()>
 {
     try!(wr.write(header.as_bytes()));
-    let mut line = [0u8, .. LINE_LENGTH + 1];
+    let mut line = [0u8; LINE_LENGTH + 1];
     while n > 0 {
         let nb = min(LINE_LENGTH, n);
         for i in range(0, nb) {
index d112fe60674dadc4fec5d379cffbbe2cbd00c145..8521e2216e93f607f4bd24836f5a3ea5fd011f1b 100644 (file)
 use std::slice;
 use std::sync::{Arc, Future};
 
-static TABLE: [u8, ..4] = [ 'A' as u8, 'C' as u8, 'G' as u8, 'T' as u8 ];
+static TABLE: [u8;4] = [ 'A' as u8, 'C' as u8, 'G' as u8, 'T' as u8 ];
 static TABLE_SIZE: uint = 2 << 16;
 
-static OCCURRENCES: [&'static str, ..5] = [
+static OCCURRENCES: [&'static str;5] = [
     "GGT",
     "GGTA",
     "GGTATT",
index 3f36c16aff63fd9f58e82071e01c915bf5ebd5b3..dab67331120a9d6508477095c79c9891d30d2d13 100644 (file)
@@ -45,7 +45,7 @@
 const YEAR: f64 = 365.24;
 const N_BODIES: uint = 5;
 
-static BODIES: [Planet, ..N_BODIES] = [
+static BODIES: [Planet;N_BODIES] = [
     // Sun
     Planet {
         x: 0.0, y: 0.0, z: 0.0,
@@ -102,7 +102,7 @@ struct Planet {
 
 impl Copy for Planet {}
 
-fn advance(bodies: &mut [Planet, ..N_BODIES], dt: f64, steps: int) {
+fn advance(bodies: &mut [Planet;N_BODIES], dt: f64, steps: int) {
     for _ in range(0, steps) {
         let mut b_slice = bodies.as_mut_slice();
         loop {
@@ -135,7 +135,7 @@ fn advance(bodies: &mut [Planet, ..N_BODIES], dt: f64, steps: int) {
     }
 }
 
-fn energy(bodies: &[Planet, ..N_BODIES]) -> f64 {
+fn energy(bodies: &[Planet;N_BODIES]) -> f64 {
     let mut e = 0.0;
     let mut bodies = bodies.iter();
     loop {
@@ -155,7 +155,7 @@ fn energy(bodies: &[Planet, ..N_BODIES]) -> f64 {
     e
 }
 
-fn offset_momentum(bodies: &mut [Planet, ..N_BODIES]) {
+fn offset_momentum(bodies: &mut [Planet;N_BODIES]) {
     let mut px = 0.0;
     let mut py = 0.0;
     let mut pz = 0.0;
index 312ee2dd27e4d3c0306d5263ad15047beabb7ec7..d746ec1dbabd555ca940a4765dbb7def04526db0 100644 (file)
 use std::io::{IoResult, EndOfFile};
 
 struct Tables {
-    table8: [u8, ..1 << 8],
-    table16: [u16, ..1 << 16]
+    table8: [u8;1 << 8],
+    table16: [u16;1 << 16]
 }
 
 impl Tables {
     fn new() -> Tables {
-        let mut table8 = [0, ..1 << 8];
+        let mut table8 = [0;1 << 8];
         for (i, v) in table8.iter_mut().enumerate() {
             *v = Tables::computed_cpl8(i as u8);
         }
-        let mut table16 = [0, ..1 << 16];
+        let mut table16 = [0;1 << 16];
         for (i, v) in table16.iter_mut().enumerate() {
             *v = table8[i & 255] as u16 << 8 |
                  table8[i >> 8]  as u16;
index c55f85f40e8b628b180c101af342108698e8214c..5fb7e2c3a84989b9095fece1f3675c352a09dc51 100644 (file)
@@ -46,7 +46,7 @@ pub fn new(g: grid) -> Sudoku {
         return Sudoku { grid: g }
     }
 
-    pub fn from_vec(vec: &[[u8, ..9], ..9]) -> Sudoku {
+    pub fn from_vec(vec: &[[u8;9];9]) -> Sudoku {
         let g = Vec::from_fn(9u, |i| {
             Vec::from_fn(9u, |j| { vec[i][j] })
         });
@@ -198,7 +198,7 @@ fn remove(&mut self, color: u8) {
     }
 }
 
-static DEFAULT_SUDOKU: [[u8, ..9], ..9] = [
+static DEFAULT_SUDOKU: [[u8;9];9] = [
          /* 0    1    2    3    4    5    6    7    8    */
   /* 0 */  [0u8, 4u8, 0u8, 6u8, 0u8, 0u8, 0u8, 3u8, 2u8],
   /* 1 */  [0u8, 0u8, 8u8, 0u8, 2u8, 0u8, 0u8, 0u8, 0u8],
@@ -212,7 +212,7 @@ fn remove(&mut self, color: u8) {
 ];
 
 #[cfg(test)]
-static DEFAULT_SOLUTION: [[u8, ..9], ..9] = [
+static DEFAULT_SOLUTION: [[u8;9];9] = [
          /* 0    1    2    3    4    5    6    7    8    */
   /* 0 */  [1u8, 4u8, 9u8, 6u8, 7u8, 5u8, 8u8, 3u8, 2u8],
   /* 1 */  [5u8, 3u8, 8u8, 1u8, 2u8, 9u8, 7u8, 4u8, 6u8],
index 489f892726a3b4895ac8b03592dfb65a08b3b609..2e0f2a174c606575242e7b3fc4bad62cb40152b7 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 fn main() {
-    let x: [int ..3]; //~ ERROR expected one of `(`, `+`, `,`, `::`, or `]`, found `..`
+    let x: [int 3]; //~ ERROR expected one of `(`, `+`, `,`, `::`, `;`, or `]`, found `3`
 }
index 93a4383b4f59f5cf8dcc7e4c1d6d63a353ad115e..f0d42bb9ac115de19b410801e8a53c457cd399f3 100644 (file)
@@ -11,7 +11,7 @@
 // Issue #16205.
 
 struct Foo {
-    a: [Box<int>, ..3],
+    a: [Box<int>3],
 }
 
 fn main() {
index bb020688f58849ea08f7fda8b3b4e37f000c7f2e..b6b46fadb13dae444559ffddb0dea65141e5c3ff 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Tests that we forbid coercion from `[T, ..n]` to `&[T]`
+// Tests that we forbid coercion from `[Tn]` to `&[T]`
 
 fn main() {
-    let _: &[int] = [0i]; //~ERROR: mismatched types: expected `&[int]`, found `[int, ..1]`
+    let _: &[int] = [0i]; //~ERROR: mismatched types: expected `&[int]`, found `[int1]`
 }
index 223426dc7c6896c4f3f7621a346acc584a1013ce..b359744183418b3f0ceaee3e3961f5b8d0278d32 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static a: [u8, ..3] = ['h' as u8, 'i' as u8, 0 as u8];
+static a: [u83] = ['h' as u8, 'i' as u8, 0 as u8];
 static b: *const i8 = &a as *const i8; //~ ERROR mismatched types
 
 fn main() {
index 59499ac070d6d536b36d4a5a260c87eacaa0e096..c77ae25e0cf519db4ff4c5a8fa95d9dd8b054228 100644 (file)
@@ -20,9 +20,9 @@ trait Bar {}
 pub fn main() {
     // With a vec of ints.
     let f1 = Fat { ptr: [1, 2, 3] };
-    let f2: &Fat<[int, ..3]> = &f1;
+    let f2: &Fat<[int3]> = &f1;
     let f3: &Fat<[uint]> = f2;
-    //~^ ERROR mismatched types: expected `&Fat<[uint]>`, found `&Fat<[int, ..3]>`
+    //~^ ERROR mismatched types: expected `&Fat<[uint]>`, found `&Fat<[int3]>`
 
     // With a trait.
     let f1 = Fat { ptr: Foo };
index e1a754b633208bbdf8abc0db523e74b3397d851a..6eb650e97811786065d054b8e208b480126fbca5 100644 (file)
@@ -21,7 +21,7 @@ impl Bar for Foo {}
 pub fn main() {
     // With a vec of ints.
     let f1 = Fat { ptr: [1, 2, 3] };
-    let f2: &Fat<[int, ..3]> = &f1;
+    let f2: &Fat<[int3]> = &f1;
     let f3: &mut Fat<[int]> = f2; //~ ERROR mismatched types
 
     // With a trait.
index 7cf647a26d7a7ef89fb318449d7d3a7619aa0020..b0bd517637464891a47ab5826900c13b325b9057 100644 (file)
@@ -21,7 +21,7 @@ impl Bar for Foo {}
 fn baz<'a>() {
     // With a vec of ints.
     let f1 = Fat { ptr: [1, 2, 3] };
-    let f2: &Fat<[int, ..3]> = &f1; //~ ERROR `f1` does not live long enough
+    let f2: &Fat<[int3]> = &f1; //~ ERROR `f1` does not live long enough
     let f3: &'a Fat<[int]> = f2;
 
     // With a trait.
index 9010185f76b6ad2ddeb7e5b5149897814cbe7e8b..783a32d63028a9bb0492605e92b1938041c06c5c 100644 (file)
@@ -17,6 +17,6 @@ struct Fat<Sized? T> {
 pub fn main() {
     // With a vec of ints.
     let f1: &Fat<[int]> = &Fat { ptr: [1, 2, 3] };
-    let f2: &Fat<[int, ..3]> = f1;
-    //~^ ERROR mismatched types: expected `&Fat<[int, ..3]>`, found `&Fat<[int]>`
+    let f2: &Fat<[int3]> = f1;
+    //~^ ERROR mismatched types: expected `&Fat<[int3]>`, found `&Fat<[int]>`
 }
index 506322d41f531c975fc0ec82d8a3636eed758727..0833a74f1daf95f40033f642d8200e02b79ceefa 100644 (file)
@@ -18,7 +18,7 @@ struct Fat<Sized? T> {
 }
 
 pub fn main() {
-    let f: Fat<[int, ..3]> = Fat { ptr: [5i, 6, 7] };
+    let f: Fat<[int3]> = Fat { ptr: [5i, 6, 7] };
     let g: &Fat<[int]> = &f;
     let h: &Fat<Fat<[int]>> = &Fat { ptr: *g };
     //~^ ERROR the trait `core::kinds::Sized` is not implemented
index 17f85c7bd2b8d6ba0f6240a44e10aff59321f55b..a9dda771b7ff8b72cdf0c9d8f87985838961c30a 100644 (file)
@@ -11,5 +11,5 @@
 // error-pattern: too big for the current
 
 fn main() {
-   let fat : [u8, ..(1<<61)+(1<<31)] = [0, ..(1u64<<61) as uint +(1u64<<31) as uint];
+   let fat : [u8; (1<<61)+(1<<31)] = [0; (1u64<<61) as uint +(1u64<<31) as uint];
 }
index 4b91564154b6ae72958627f5d2d9030a763ee7a2..029e9651cb3cdd34c65ce848c94d59e930856608 100644 (file)
@@ -8,13 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern: ..1518599999
+// error-pattern:1518599999
 
 fn generic<T: Copy>(t: T) {
-    let s: [T, ..1518600000] = [t, ..1518600000];
+    let s: [T; 1518600000] = [t; 1518600000];
 }
 
 fn main() {
-    let x: [u8, ..1518599999] = [0, ..1518599999];
-    generic::<[u8, ..1518599999]>(x);
+    let x: [u8; 1518599999] = [0; 1518599999];
+    generic::<[u81518599999]>(x);
 }
index 4a85cb5753b7f64600a215d380260b135cbcd0b7..7c7a75abf3fc79705388cac0078d6b56df7afecd 100644 (file)
 
 #[cfg(target_word_size = "32")]
 fn main() {
-    let big: Option<[u32, ..(1<<29)-1]> = None;
+    let big: Option<[u32(1<<29)-1]> = None;
 }
 
 #[cfg(target_word_size = "64")]
 fn main() {
-    let big: Option<[u32, ..(1<<45)-1]> = None;
+    let big: Option<[u32(1<<45)-1]> = None;
 }
index 162324b7c59b25e1b2473c343f64803e7c910dca..a0a7660428d4106815906f0d7561c58802b01df7 100644 (file)
@@ -13,7 +13,7 @@
 
 // error-pattern: mismatched types
 
-static VEC: [u32, ..256] = vec!();
+static VEC: [u32256] = vec!();
 
 fn main() {}
 
index 4ec8c2b1b7ea580773294a6a374395b9321886a7..ef7d3d4d158d9fdcb202c4e0a0944acf10f7d13c 100644 (file)
@@ -14,7 +14,7 @@ fn main() {
     let x = [1,2];
     let y = match x {
         [] => None,
-        //~^ ERROR types: expected `[_#0i, ..2]`, found `[_#7t, ..0]`
+        //~^ ERROR types: expected `[_#0i; 2]`, found `[_#7t; 0]`
         //         (expected array of 2 elements, found array of 0 elements)
         [a,_] => Some(a)
     };
index 18070ed53b04ac8a791d27666bf753465a65d464..157280b1719ad2ca3a096f0c0692667b11421236 100644 (file)
@@ -12,7 +12,7 @@ fn main() {
   let x = [1,2];
   let y = match x {
     [] => None,
-//~^ ERROR types: expected `[_, ..2]`, found `[_, ..0]`
+//~^ ERROR types: expected `[_; 2]`, found `[_; 0]`
 //         (expected array of 2 elements, found array of 0 elements)
     [a,_] => Some(a)
   };
index bc606d8139f0144aa1a696b654bce35fc1bea9fe..5166d84a0254362f12a0503a282ad3f79440936a 100644 (file)
 
 
 struct X {
-    a: [u8, ..1]
+    a: [u81]
 }
 
 fn main() {
     let x = X { a: [0] };
     let _f = &x.a as *mut u8;
-    //~^ ERROR mismatched types: expected `*mut u8`, found `&[u8, ..1]`
+    //~^ ERROR mismatched types: expected `*mut u8`, found `&[u81]`
 
     let local = [0u8];
     let _v = &local as *mut u8;
-    //~^ ERROR mismatched types: expected `*mut u8`, found `&[u8, ..1]`
+    //~^ ERROR mismatched types: expected `*mut u8`, found `&[u81]`
 }
index 4a6b80d765b71e11e979273c7bf0ee00d3767d09..4adb3f041a3f4254b2d971fed405c6829b7c8da0 100644 (file)
 static FOO: uint = FOO; //~ ERROR recursive constant
 
 fn main() {
-    let _x: [u8, ..FOO]; // caused stack overflow prior to fix
+    let _x: [u8FOO]; // caused stack overflow prior to fix
     let _y: uint = 1 + {
         static BAR: uint = BAR; //~ ERROR recursive constant
-        let _z: [u8, ..BAR]; // caused stack overflow prior to fix
+        let _z: [u8BAR]; // caused stack overflow prior to fix
         1
     };
 }
index 11c815da1c7f51e677ea85629d45f1acb827cbe4..e5da5c5504ef3e1b728113a85abac6d621494bb7 100644 (file)
@@ -10,7 +10,7 @@
 
 fn main() {
     let _foo = &[1u, 2] as [uint];
-    //~^ ERROR cast to unsized type: `&[uint, ..2]` as `[uint]`
+    //~^ ERROR cast to unsized type: `&[uint2]` as `[uint]`
     //~^^ HELP consider using an implicit coercion to `&[uint]` instead
     let _bar = box 1u as std::fmt::Show;
     //~^ ERROR cast to unsized type: `Box<uint>` as `core::fmt::Show`
@@ -19,6 +19,6 @@ fn main() {
     //~^ ERROR cast to unsized type: `uint` as `core::fmt::Show`
     //~^^ HELP consider using a box or reference as appropriate
     let _quux = [1u, 2] as [uint];
-    //~^ ERROR cast to unsized type: `[uint, ..2]` as `[uint]`
+    //~^ ERROR cast to unsized type: `[uint2]` as `[uint]`
     //~^^ HELP consider using a box or reference as appropriate
 }
index 1f763dbdc9fa642001f8e79a7eef83259e2408fe..8aa5fdf1c4d21fb3256996dbf5e92ea5b10942d6 100644 (file)
@@ -15,7 +15,7 @@ struct S { a: uint }
 static C: &'static uint = &(A.a);
 //~^ ERROR: cannot refer to the interior of another static
 
-static D: [uint, ..1] = [1];
+static D: [uint1] = [1];
 static E: uint = D[0];
 //~^ ERROR: cannot refer to other statics by value
 static F: &'static uint = &D[0];
index 7ca83f21305f15842f9cb4a2e831fd3e4b35c946..fafe6377397a39343a3367d3dc465a984395a77d 100644 (file)
@@ -11,6 +11,6 @@
 const TUP: (uint,) = (42,);
 
 fn main() {
-    let a: [int, ..TUP.1];
+    let a: [intTUP.1];
     //~^ ERROR expected constant expr for array length: tuple index out of bounds
 }
index d9aeecc02222ca7d291be6fdbf11ad29895663ee..95965ca35f944ed593fc3abe3f4fbef788855a8b 100644 (file)
@@ -12,6 +12,6 @@ struct MyStruct { field: uint }
 const STRUCT: MyStruct = MyStruct { field: 42 };
 
 fn main() {
-    let a: [int, ..STRUCT.nonexistent_field];
+    let a: [intSTRUCT.nonexistent_field];
     //~^ ERROR expected constant expr for array length: nonexistent struct field
 }
diff --git a/src/test/compile-fail/issue-19991.rs b/src/test/compile-fail/issue-19991.rs
new file mode 100644 (file)
index 0000000..0f1dbfa
--- /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.
+
+// Test if the sugared if-let construct correctly prints "missing an else clause" when an else
+// clause does not exist, instead of the unsympathetic "match arms have incompatible types"
+
+fn main() {
+    if let Some(homura) = Some("madoka") { //~ ERROR missing an else clause: expected `()`
+        765i32
+    };
+}
index 1150f40db762f7849622dc7b6f1b6d3fb62efa27..3343e92252f8e4926e5de54b196221115bef095c 100644 (file)
@@ -22,5 +22,5 @@ fn bind<B>(&self, f: |A| -> Vec<B> ) {
 }
 fn main() {
     ["hi"].bind(|x| [x] );
-    //~^ ERROR type `[&str, ..1]` does not implement any method in scope named `bind`
+    //~^ ERROR type `[&str1]` does not implement any method in scope named `bind`
 }
index f61ed35fca3595cc0d8054726181a6355848b17c..1c5fd9be1bd4d24d1d3c26804aff580f60199f6c 100644 (file)
@@ -11,8 +11,8 @@
 fn bar(int_param: int) {}
 
 fn main() {
-    let foo: [u8, ..4] = [1u8, ..4u];
+    let foo: [u8; 4] = [1u8; 4u];
     bar(foo);
-    //~^ ERROR mismatched types: expected `int`, found `[u8, ..4]`
+    //~^ ERROR mismatched types: expected `int`, found `[u84]`
     //         (expected int, found vector)
 }
index a90a1ac1a75f0ed66403f2e1b5c4a0cab1d87816..573d847cbe3b88cbce5ee7fcd1ec5785343b4a65 100644 (file)
@@ -11,5 +11,5 @@
 pub extern crate core; //~ ERROR: `pub` visibility is not allowed
 
 fn main() {
-    pub use std::bool; //~ ERROR: imports in functions are never reachable
+    pub use std::uint; //~ ERROR: imports in functions are never reachable
 }
index eb5c475e7ef4fdca3aff442ad5b272be419d0a99..19373c806f14d4da979f7c787e3c19d7292f13c1 100644 (file)
@@ -29,7 +29,7 @@ fn main() {
     println!("{}", Test);
 
     let mut f = File::open(&Path::new("something.txt"));
-    let mut buff = [0u8, ..16];
+    let mut buff = [0u816];
     match f.read(&mut buff) {
         Ok(cnt) => println!("read this many bytes: {}", cnt),
         Err(IoError{ kind: EndOfFile, .. }) => println!("Got end of file: {}", EndOfFile.to_string()),
index ce05087f6597948ba9669df7a48263905f62acdc..0b095ff6f820dbc5b68863a89730bf13734cd699 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Test moving array structures, e.g. `[T, ..3]` as well as moving
+// Test moving array structures, e.g. `[T3]` as well as moving
 // elements in and out of such arrays.
 //
 // Note also that the `test_move_array_then_overwrite` tests represent
@@ -18,14 +18,14 @@ pub struct D { d: int }
 impl Drop for D { fn drop(&mut self) { } }
 
 #[rustc_move_fragments]
-pub fn test_move_array_via_return(a: [D, ..3]) -> [D, ..3] {
+pub fn test_move_array_via_return(a: [D; 3]) -> [D; 3] {
     //~^ ERROR                  assigned_leaf_path: `$(local a)`
     //~| ERROR                     moved_leaf_path: `$(local a)`
     return a;
 }
 
 #[rustc_move_fragments]
-pub fn test_move_array_into_recv(a: [D, ..3], recv: &mut [D, ..3]) {
+pub fn test_move_array_into_recv(a: [D; 3], recv: &mut [D; 3]) {
     //~^ ERROR                 parent_of_fragments: `$(local recv)`
     //~| ERROR                  assigned_leaf_path: `$(local a)`
     //~| ERROR                     moved_leaf_path: `$(local a)`
@@ -34,7 +34,7 @@ pub fn test_move_array_into_recv(a: [D, ..3], recv: &mut [D, ..3]) {
 }
 
 #[rustc_move_fragments]
-pub fn test_extract_array_elem(a: [D, ..3], i: uint) -> D {
+pub fn test_extract_array_elem(a: [D3], i: uint) -> D {
     //~^ ERROR                 parent_of_fragments: `$(local a)`
     //~| ERROR                  assigned_leaf_path: `$(local i)`
     //~| ERROR                     moved_leaf_path: `$(local a).[]`
@@ -43,7 +43,7 @@ pub fn test_extract_array_elem(a: [D, ..3], i: uint) -> D {
 }
 
 #[rustc_move_fragments]
-pub fn test_overwrite_array_elem(mut a: [D, ..3], i: uint, d: D) {
+pub fn test_overwrite_array_elem(mut a: [D3], i: uint, d: D) {
     //~^ ERROR                 parent_of_fragments: `$(local mut a)`
     //~| ERROR                  assigned_leaf_path: `$(local i)`
     //~| ERROR                  assigned_leaf_path: `$(local d)`
@@ -59,7 +59,7 @@ pub fn test_overwrite_array_elem(mut a: [D, ..3], i: uint, d: D) {
 // See RFC PR 320 for more discussion.
 
 #[rustc_move_fragments]
-pub fn test_move_array_then_overwrite_elem1(mut a: [D, ..3], i: uint, recv: &mut [D, ..3], d: D) {
+pub fn test_move_array_then_overwrite_elem1(mut a: [D; 3], i: uint, recv: &mut [D; 3], d: D) {
     //~^ ERROR                 parent_of_fragments: `$(local mut a)`
     //~| ERROR                 parent_of_fragments: `$(local recv)`
     //~| ERROR                  assigned_leaf_path: `$(local recv).*`
@@ -76,8 +76,8 @@ pub fn test_move_array_then_overwrite_elem1(mut a: [D, ..3], i: uint, recv: &mut
 }
 
 #[rustc_move_fragments]
-pub fn test_move_array_then_overwrite_elem2(mut a: [D, ..3], i: uint, j: uint,
-                                            recv: &mut [D, ..3], d1: D, d2: D) {
+pub fn test_move_array_then_overwrite_elem2(mut a: [D3], i: uint, j: uint,
+                                            recv: &mut [D3], d1: D, d2: D) {
     //~^^ ERROR                parent_of_fragments: `$(local mut a)`
     //~| ERROR                 parent_of_fragments: `$(local recv)`
     //~| ERROR                  assigned_leaf_path: `$(local recv).*`
index 678808f166cde90c7f094e97b7e14241aea31357..d8d84e558a947ff734d4afa1b1b8283766eda956 100644 (file)
@@ -89,7 +89,7 @@ fn f100() {
 
 fn f110() {
     let x = vec!("hi".to_string());
-    let _y = [x.into_iter().next().unwrap(), ..1];
+    let _y = [x.into_iter().next().unwrap()1];
     touch(&x); //~ ERROR use of moved value: `x`
 }
 
index 3ccce591ee7288747e13aee6ae530a6c9414151d..a1dc2ab2041a5ea0e6199746b0fd47da449d43e3 100644 (file)
@@ -11,6 +11,6 @@
 enum State { ST_NULL, ST_WHITESPACE }
 
 fn main() {
-    [State::ST_NULL, ..(State::ST_WHITESPACE as uint)];
+    [State::ST_NULL(State::ST_WHITESPACE as uint)];
     //~^ ERROR expected constant integer for repeat count, found non-constant expression
 }
index 91551941c0656012a6f4b616d21216c068fe65f0..85d734ddaf2b9fab308f3616a8a8e2a9faecea0f 100644 (file)
@@ -12,7 +12,7 @@
 
 fn main() {
     fn bar(n: int) {
-        let _x: [int, ..n];
+        let _x: [intn];
         //~^ ERROR expected constant expr for array length: non-constant path in constant expr
     }
 }
index 299e9d3dced3c0fb963153aa6f0cad0f70c7c50a..2e063e5237c44a4ad67c30a3ae96d639f5d06efe 100644 (file)
@@ -12,6 +12,6 @@
 
 fn main() {
     fn bar(n: uint) {
-        let _x = [0, ..n]; //~ ERROR expected constant integer for repeat count, found variable
+        let _x = [0n]; //~ ERROR expected constant integer for repeat count, found variable
     }
 }
index 6e1c3db10140f26b2afe0971ec3e3287bb031ec8..d35e3ad3c55b02769e6cdf2d932bbcc5edf177bf 100644 (file)
@@ -12,7 +12,7 @@
 
 struct Foo {
     first: bool,
-    second: Option<[uint, ..4]>
+    second: Option<[uint4]>
 }
 
 enum Color {
index d699f69864e38474df7ca2373f5a03e976536f4a..5c0aba42b9683221374078f66c47d8a707eae9ae 100644 (file)
@@ -33,7 +33,7 @@ struct Oof<T, S> {
 fn main() {
     let foo = Foo { bar: [1u8, 2, 3, 4, 5], baz: 10i32 };
     unsafe {
-        let oof: Oof<[u8, .. 5], i32> = mem::transmute(foo);
+        let oof: Oof<[u8; 5], i32> = mem::transmute(foo);
         println!("{} {}", oof.rab[], oof.zab);
     }
 }
diff --git a/src/test/compile-fail/region-lifetime-bounds-on-fns-where-clause.rs b/src/test/compile-fail/region-lifetime-bounds-on-fns-where-clause.rs
new file mode 100644 (file)
index 0000000..381144f
--- /dev/null
@@ -0,0 +1,39 @@
+// 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 a<'a, 'b>(x: &mut &'a int, y: &mut &'b int) where 'b: 'a {
+    // Note: this is legal because of the `'b:'a` declaration.
+    *x = *y;
+}
+
+fn b<'a, 'b>(x: &mut &'a int, y: &mut &'b int) {
+    // Illegal now because there is no `'b:'a` declaration.
+    *x = *y; //~ ERROR mismatched types
+}
+
+fn c<'a,'b>(x: &mut &'a int, y: &mut &'b int) {
+    // Here we try to call `foo` but do not know that `'a` and `'b` are
+    // related as required.
+    a(x, y); //~ ERROR cannot infer
+}
+
+fn d() {
+    // 'a and 'b are early bound in the function `a` because they appear
+    // inconstraints:
+    let _: fn(&mut &int, &mut &int) = a; //~ ERROR mismatched types
+}
+
+fn e() {
+    // 'a and 'b are late bound in the function `b` because there are
+    // no constraints:
+    let _: fn(&mut &int, &mut &int) = b;
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/region-multiple-lifetime-bounds-on-fns-where-clause.rs b/src/test/compile-fail/region-multiple-lifetime-bounds-on-fns-where-clause.rs
new file mode 100644 (file)
index 0000000..a03911e
--- /dev/null
@@ -0,0 +1,41 @@
+// 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 a<'a, 'b, 'c>(x: &mut &'a int, y: &mut &'b int, z: &mut &'c int) where 'b: 'a + 'c {
+    // Note: this is legal because of the `'b:'a` declaration.
+    *x = *y;
+    *z = *y;
+}
+
+fn b<'a, 'b, 'c>(x: &mut &'a int, y: &mut &'b int, z: &mut &'c int) {
+    // Illegal now because there is no `'b:'a` declaration.
+    *x = *y; //~ ERROR mismatched types
+    *z = *y; //~ ERROR mismatched types
+}
+
+fn c<'a,'b, 'c>(x: &mut &'a int, y: &mut &'b int, z: &mut &'c int) {
+    // Here we try to call `foo` but do not know that `'a` and `'b` are
+    // related as required.
+    a(x, y, z); //~ ERROR cannot infer
+}
+
+fn d() {
+    // 'a and 'b are early bound in the function `a` because they appear
+    // inconstraints:
+    let _: fn(&mut &int, &mut &int, &mut &int) = a; //~ ERROR mismatched types
+}
+
+fn e() {
+    // 'a and 'b are late bound in the function `b` because there are
+    // no constraints:
+    let _: fn(&mut &int, &mut &int, &mut &int) = b;
+}
+
+fn main() { }
index fe49d1f4a8d853187911b8ba6d1eddf409dc32c2..0a8420c19c33f2cbc0b3199d610ac5482e8c8476 100644 (file)
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-type v = [int * 3]; //~ ERROR expected one of `(`, `+`, `,`, `::`, or `]`, found `*`
+type v = [int * 3]; //~ ERROR expected one of `(`, `+`, `,`, `::`, `;`, or `]`, found `*`
index 437f871f8eabdde0023ed63f61522e76aa6fc7c7..30302bbd16ef8e0387083285bba38b5c39f43647 100644 (file)
@@ -11,5 +11,5 @@
 fn f() {
     let v = [mut 1, 2, 3, 4];
     //~^  ERROR expected identifier, found keyword `mut`
-    //~^^ ERROR expected one of `!`, `,`, `.`, `::`, `]`, `{`, or an operator, found `1`
+    //~^^ ERROR expected one of `!`, `,`, `.`, `::`, `;`, `]`, `{`, or an operator, found `1`
 }
index af469fadf986d34b828006a85a17b90a73837b46..9c6056bd72a1c1c8f4c04119b5b966618c2c9b5a 100644 (file)
@@ -10,4 +10,4 @@
 
 type v = [mut int];
     //~^  ERROR expected identifier, found keyword `mut`
-    //~^^ ERROR expected one of `(`, `+`, `,`, `::`, or `]`, found `int`
+    //~^^ ERROR expected one of `(`, `+`, `,`, `::`, `;`, or `]`, found `int`
index 8fdf586b3d1de4ec3a88cefcc140ce102c79ec08..d3126cf44d1b152fcd01e39cfcd1f1bc09283832 100644 (file)
@@ -24,6 +24,6 @@ fn drop(&mut self) {
 
 fn main() {
     let a = Foo { x: 3 };
-    let _ = [ a, ..5 ];
+    let _ = [ a5 ];
     //~^ ERROR the trait `core::kinds::Copy` is not implemented for the type `Foo`
 }
index 38fbb426fb19885259fc9f90e69d4af3e1b8d30f..3b0ef0c293af75c260e724a1195c3d2e3913862b 100644 (file)
 
 fn main() {
     let n = 1;
-    let a = [0, ..n]; //~ ERROR expected constant integer for repeat count, found variable
-    let b = [0, ..()];
+    let a = [0n]; //~ ERROR expected constant integer for repeat count, found variable
+    let b = [0()];
 //~^ ERROR expected constant integer for repeat count, found non-constant expression
 //~^^ ERROR: expected `uint`, found `()`
-    let c = [0, ..true]; //~ ERROR expected positive integer for repeat count, found boolean
+    let c = [0true]; //~ ERROR expected positive integer for repeat count, found boolean
     //~^ ERROR: expected `uint`, found `bool`
-    let d = [0, ..0.5]; //~ ERROR expected positive integer for repeat count, found float
+    let d = [00.5]; //~ ERROR expected positive integer for repeat count, found float
     //~^ ERROR: expected `uint`, found `_`
-    let e = [0, .."foo"]; //~ ERROR expected positive integer for repeat count, found string
+    let e = [0"foo"]; //~ ERROR expected positive integer for repeat count, found string
     //~^ ERROR: expected `uint`, found `&'static str`
-    let f = [0, ..-4];
+    let f = [0-4];
     //~^ ERROR expected positive integer for repeat count, found negative integer
-    let f = [0u, ..-1];
+    let f = [0u-1];
     //~^ ERROR expected positive integer for repeat count, found negative integer
 }
index 03be2cc8f0f02741a85cb0fa3492a56bb8f91ff6..ff84ed5bf0cd499d72000663407b3c3d0c994faa 100644 (file)
@@ -10,7 +10,7 @@
 
 fn foo() -> int { 23 }
 
-static a: [int, ..2] = [foo(), ..2];
+static a: [int; 2] = [foo(); 2];
 //~^ ERROR: function calls in constants are limited to struct and enum constructors
 
 fn main() {}
diff --git a/src/test/compile-fail/trailing-comma-array-repeat.rs b/src/test/compile-fail/trailing-comma-array-repeat.rs
deleted file mode 100644 (file)
index dadd657..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    let [_, ..,] = [(), ()]; //~ ERROR unexpected token: `]`
-}
index 53391a0e8947b9088b3d9398d88019a130279ed3..2286c0e75bd9dcc22393e9fea52f5db052188c81 100644 (file)
@@ -20,7 +20,7 @@ unsafe fn g<T>(x: (T, int)) {
     let _: int = transmute(x);  //~ ERROR cannot transmute
 }
 
-unsafe fn h<T>(x: [T, ..10]) {
+unsafe fn h<T>(x: [T10]) {
     let _: int = transmute(x);  //~ ERROR cannot transmute
 }
 
index e096e5eb436298556ab7a0ceb2bf6c7958b2f799..c5109ce473e9efebbcd5e191792769ca976758ce 100644 (file)
 // presence of the `_` type shorthand notation.
 
 struct X {
-    y: [u8, ..2],
+    y: [u82],
 }
 
 fn main() {
     let x1 = X { y: [0, 0] };
 
     let p1: *const u8 = &x1.y as *const _;  //~ ERROR mismatched types
-    let t1: *const [u8, ..2] = &x1.y as *const _;
-    let h1: *const [u8, ..2] = &x1.y as *const [u8, ..2];
+    let t1: *const [u82] = &x1.y as *const _;
+    let h1: *const [u8; 2] = &x1.y as *const [u8; 2];
 
     let mut x1 = X { y: [0, 0] };
 
     let p1: *mut u8 = &mut x1.y as *mut _;  //~ ERROR mismatched types
-    let t1: *mut [u8, ..2] = &mut x1.y as *mut _;
-    let h1: *mut [u8, ..2] = &mut x1.y as *mut [u8, ..2];
+    let t1: *mut [u82] = &mut x1.y as *mut _;
+    let h1: *mut [u8; 2] = &mut x1.y as *mut [u8; 2];
 }
 
index 740848e93cbeaba799d176b7493dfc9a13b5ffee..7ff18f8e0886c1d5826a5142228b9b872e610db2 100644 (file)
 
 trait Foo {}
 
-pub fn f<T:Foo>() {}    //~ ERROR private type in exported type
+pub fn f<
+    T
+    : Foo //~ ERROR private trait in exported type parameter bound
+>() {}
 
-pub fn g<T>() where T: Foo {}   //~ ERROR private type in exported type
+pub fn g<T>() where
+    T
+    : Foo //~ ERROR private trait in exported type parameter bound
+{}
 
-pub struct H<T:Foo> {   //~ ERROR private type in exported type
-    x: T,
+pub struct S;
+
+impl S {
+    pub fn f<
+        T
+        : Foo //~ ERROR private trait in exported type parameter bound
+    >() {}
+
+    pub fn g<T>() where
+        T
+        : Foo //~ ERROR private trait in exported type parameter bound
+    {}
 }
 
-pub struct I<T> where T: Foo {  //~ ERROR private type in exported type
-    x: T,
+pub struct S1<
+    T
+    : Foo //~ ERROR private trait in exported type parameter bound
+> {
+    x: T
 }
 
-fn main() {}
+pub struct S2<T> where
+    T
+    : Foo //~ ERROR private trait in exported type parameter bound
+{
+    x: T
+}
 
+pub enum E1<
+    T
+    : Foo //~ ERROR private trait in exported type parameter bound
+> {
+    V1(T)
+}
+
+pub enum E2<T> where
+    T
+    : Foo //~ ERROR private trait in exported type parameter bound
+{
+    V2(T)
+}
+
+fn main() {}
index c4457aaf1e1f3da15341afe7c3670c7f03810382..dc6d446154ac75b4045c7006e98b7a6f07134495 100644 (file)
@@ -10,7 +10,6 @@
 
 trait Foo {}
 
-pub trait Bar : Foo {}  //~ ERROR private type in exported type
+pub trait Bar : Foo {} //~ ERROR private trait in exported type
 
 fn main() {}
-
diff --git a/src/test/compile-fail/where-clause-constraints-are-local-for-inherent-impl.rs b/src/test/compile-fail/where-clause-constraints-are-local-for-inherent-impl.rs
new file mode 100644 (file)
index 0000000..8d72e26
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn require_copy<T: Copy>(x: T) {}
+
+struct Foo<T> { x: T }
+
+// Ensure constraints are only attached to methods locally
+impl<T> Foo<T> {
+    fn needs_copy(self) where T: Copy {
+        require_copy(self.x);
+
+    }
+
+    fn fails_copy(self) {
+        require_copy(self.x);
+        //~^ ERROR the trait `core::kinds::Copy` is not implemented for the type `T`
+    }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/where-clause-constraints-are-local-for-trait-impl.rs b/src/test/compile-fail/where-clause-constraints-are-local-for-trait-impl.rs
new file mode 100644 (file)
index 0000000..096b53a
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn require_copy<T: Copy>(x: T) {}
+
+struct Bar<T> { x: T }
+
+trait Foo<T> {
+    fn needs_copy(self) where T: Copy;
+    fn fails_copy(self);
+}
+
+// Ensure constraints are only attached to methods locally
+impl<T> Foo<T> for Bar<T> {
+    fn needs_copy(self) where T: Copy {
+        require_copy(self.x);
+
+    }
+
+    fn fails_copy(self) {
+        require_copy(self.x);
+        //~^ ERROR the trait `core::kinds::Copy` is not implemented for the type `T`
+    }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/where-clause-method-substituion.rs b/src/test/compile-fail/where-clause-method-substituion.rs
new file mode 100644 (file)
index 0000000..40d2df4
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait Foo<T> {}
+
+trait Bar<A> {
+    fn method<B>(&self) where A: Foo<B>;
+}
+
+struct S;
+struct X;
+
+// Remove this impl causing the below resolution to fail // impl Foo<S> for X {}
+
+impl Bar<X> for int {
+    fn method<U>(&self) where X: Foo<U> {
+    }
+}
+
+fn main() {
+    1.method::<X>();
+    //~^ ERROR the trait `Foo<X>` is not implemented for the type `X`
+}
diff --git a/src/test/compile-fail/where-clauses-method-unsatisfied.rs b/src/test/compile-fail/where-clauses-method-unsatisfied.rs
new file mode 100644 (file)
index 0000000..e5b5458
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that a where clause attached to a method allows us to add
+// additional constraints to a parameter out of scope.
+
+struct Foo<T> {
+    value: T
+}
+
+struct Bar; // does not implement Eq
+
+impl<T> Foo<T> {
+    fn equals(&self, u: &Foo<T>) -> bool where T : Eq {
+        self.value == u.value
+    }
+}
+
+fn main() {
+    let x = Foo { value: Bar };
+    x.equals(&x);
+    //~^ ERROR the trait `core::cmp::Eq` is not implemented for the type `Bar`
+}
index 2817aa16e8e5ecb29dce23a3ebb4e6a507b6b3e1..9e81703787f3e0f011c5b7c298c187797bf80832 100644 (file)
@@ -8,10 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn equal<T>(_: &T, _: &T) -> bool where int : Eq {
-    //~^ ERROR undeclared type parameter
+struct A;
+
+trait U {}
+
+// impl U for A {}
+
+fn equal<T>(_: &T, _: &T) -> bool where A : U {
+    true
 }
 
 fn main() {
+    equal(&0i, &0i);
+    //~^ ERROR the trait `U` is not implemented for the type `A`
 }
-
diff --git a/src/test/debuginfo/destructured-for-loop-variable.rs b/src/test/debuginfo/destructured-for-loop-variable.rs
new file mode 100644 (file)
index 0000000..19a82ee
--- /dev/null
@@ -0,0 +1,178 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-android: FIXME(#10381)
+// min-lldb-version: 310
+
+// compile-flags:-g
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command:run
+
+// DESTRUCTURED STRUCT
+// gdb-command:print x
+// gdb-check:$1 = 400
+// gdb-command:print y
+// gdb-check:$2 = 401.5
+// gdb-command:print z
+// gdb-check:$3 = true
+// gdb-command:continue
+
+// DESTRUCTURED TUPLE
+// gdb-command:print/x _i8
+// gdb-check:$4 = 0x6f
+// gdb-command:print/x _u8
+// gdb-check:$5 = 0x70
+// gdb-command:print _i16
+// gdb-check:$6 = -113
+// gdb-command:print _u16
+// gdb-check:$7 = 114
+// gdb-command:print _i32
+// gdb-check:$8 = -115
+// gdb-command:print _u32
+// gdb-check:$9 = 116
+// gdb-command:print _i64
+// gdb-check:$10 = -117
+// gdb-command:print _u64
+// gdb-check:$11 = 118
+// gdb-command:print _f32
+// gdb-check:$12 = 119.5
+// gdb-command:print _f64
+// gdb-check:$13 = 120.5
+// gdb-command:continue
+
+// MORE COMPLEX CASE
+// gdb-command:print v1
+// gdb-check:$14 = 80000
+// gdb-command:print x1
+// gdb-check:$15 = 8000
+// gdb-command:print *y1
+// gdb-check:$16 = 80001.5
+// gdb-command:print z1
+// gdb-check:$17 = false
+// gdb-command:print *x2
+// gdb-check:$18 = -30000
+// gdb-command:print y2
+// gdb-check:$19 = -300001.5
+// gdb-command:print *z2
+// gdb-check:$20 = true
+// gdb-command:print v2
+// gdb-check:$21 = 854237.5
+// gdb-command:continue
+
+
+// === LLDB TESTS ==================================================================================
+
+// lldb-command:type format add --format hex char
+// lldb-command:type format add --format hex 'unsigned char'
+
+// lldb-command:run
+
+// DESTRUCTURED STRUCT
+// lldb-command:print x
+// lldb-check:[...]$0 = 400
+// lldb-command:print y
+// lldb-check:[...]$1 = 401.5
+// lldb-command:print z
+// lldb-check:[...]$2 = true
+// lldb-command:continue
+
+// DESTRUCTURED TUPLE
+// lldb-command:print _i8
+// lldb-check:[...]$3 = 0x6f
+// lldb-command:print _u8
+// lldb-check:[...]$4 = 0x70
+// lldb-command:print _i16
+// lldb-check:[...]$5 = -113
+// lldb-command:print _u16
+// lldb-check:[...]$6 = 114
+// lldb-command:print _i32
+// lldb-check:[...]$7 = -115
+// lldb-command:print _u32
+// lldb-check:[...]$8 = 116
+// lldb-command:print _i64
+// lldb-check:[...]$9 = -117
+// lldb-command:print _u64
+// lldb-check:[...]$10 = 118
+// lldb-command:print _f32
+// lldb-check:[...]$11 = 119.5
+// lldb-command:print _f64
+// lldb-check:[...]$12 = 120.5
+// lldb-command:continue
+
+// MORE COMPLEX CASE
+// lldb-command:print v1
+// lldb-check:[...]$13 = 80000
+// lldb-command:print x1
+// lldb-check:[...]$14 = 8000
+// lldb-command:print *y1
+// lldb-check:[...]$15 = 80001.5
+// lldb-command:print z1
+// lldb-check:[...]$16 = false
+// lldb-command:print *x2
+// lldb-check:[...]$17 = -30000
+// lldb-command:print y2
+// lldb-check:[...]$18 = -300001.5
+// lldb-command:print *z2
+// lldb-check:[...]$19 = true
+// lldb-command:print v2
+// lldb-check:[...]$20 = 854237.5
+// lldb-command:continue
+
+
+struct Struct {
+    x: i16,
+    y: f32,
+    z: bool
+}
+
+fn main() {
+
+    let s = Struct {
+        x: 400,
+        y: 401.5,
+        z: true
+    };
+
+    for &Struct { x, y, z } in [s].iter() {
+        zzz(); // #break
+    }
+
+    let tuple: (i8, u8, i16, u16, i32, u32, i64, u64, f32, f64) =
+        (0x6f, 0x70, -113, 114, -115, 116, -117, 118, 119.5, 120.5);
+
+    for &(_i8, _u8, _i16, _u16, _i32, _u32, _i64, _u64, _f32, _f64) in [tuple].iter() {
+        zzz(); // #break
+    }
+
+    let more_complex: (i32, &Struct, Struct, Box<f64>) =
+        (80000,
+         &Struct {
+            x: 8000,
+            y: 80001.5,
+            z: false
+         },
+         Struct {
+            x: -30000,
+            y: -300001.5,
+            z: true
+         },
+         box 854237.5);
+
+    for &(v1,
+          &Struct { x: x1, y: ref y1, z: z1 },
+          Struct { x: ref x2, y: y2, z: ref z2 },
+          box v2) in [more_complex].iter() {
+        zzz(); // #break
+    }
+}
+
+fn zzz() {()}
index aab9c446a9e2d2080c91006f86ae31261c1ab10a..786868f6b89ddab084dbce06cb0117fd821d42f9 100644 (file)
 #![allow(unused_variables)]
 
 struct NoPadding1 {
-    x: [u32, ..3],
+    x: [u323],
     y: i32,
-    z: [f32, ..2]
+    z: [f322]
 }
 
 struct NoPadding2 {
-    x: [u32, ..3],
-    y: [[u32, ..2], ..2]
+    x: [u323],
+    y: [[u32; 2]; 2]
 }
 
 struct StructInternalPadding {
-    x: [i16, ..2],
-    y: [i64, ..2]
+    x: [i162],
+    y: [i642]
 }
 
 struct SingleVec {
-    x: [i16, ..5]
+    x: [i165]
 }
 
 struct StructPaddedAtEnd {
-    x: [i64, ..2],
-    y: [i16, ..2]
+    x: [i642],
+    y: [i162]
 }
 
 fn main() {
index bcaebb5c153f5d411f685243110d9aec4b4c25ac..7636ffdb07dcd6a02a54e656d3db53d5a5a9bd75 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // ignore-android: FIXME(#10381)
-// ignore-test: Not sure what is going on here --pcwalton
 // min-lldb-version: 310
 
 // compile-flags:-g
index a1f34aea0f21f02ee58d9d78f7f5e47439bb73da..41dee642feacd9c4886d83e8e073a4523ac49e6a 100644 (file)
@@ -450,7 +450,7 @@ fn main() {
         sentinel();
 
         val
-    }, ..10];
+    }10];
 
     zzz(); // #break
     sentinel();
@@ -491,7 +491,7 @@ fn main() {
     sentinel();
 
     // index expression
-    let a_vector = [10i, ..20];
+    let a_vector = [10i20];
     let _ = a_vector[{
         zzz(); // #break
         sentinel();
index 032b8b1fa262fdaba624fb83eb5278e04e3efc7b..8cc0fdabfc2e7b73cb7465dcaaf0b73597edd198 100644 (file)
@@ -143,7 +143,7 @@ fn main() {
         value: 2,
     };
 
-    let vec_unique: [UniqueNode<f32>, ..1] = [UniqueNode {
+    let vec_unique: [UniqueNode<f32>1] = [UniqueNode {
         next: Val {
             val: box UniqueNode {
                 next: Empty,
index d72b080409e1d43fa4dc942b99ab30a8de397bf1..286c44667c5b46cdbfcf2ac4a246ceb4d2dcfaa9 100644 (file)
 
 // VECTORS
 // gdb-command:whatis fixed_size_vec1
-// gdb-check:type = struct ([type-names::Struct1, ..3], i16)
+// gdb-check:type = struct ([type-names::Struct13], i16)
 
 // gdb-command:whatis fixed_size_vec2
-// gdb-check:type = struct ([uint, ..3], i16)
+// gdb-check:type = struct ([uint3], i16)
 
 // gdb-command:whatis slice1
 // gdb-check:type = struct &[uint]
index fd422a90e632fd3315138a42642fd0268d1db6d5..00c93653cf411892b4c4e7e7526ae36d4f5dbbc5 100644 (file)
@@ -30,7 +30,7 @@
 
 #![allow(unused_variables)]
 
-static mut VECT: [i32, ..3] = [1, 2, 3];
+static mut VECT: [i323] = [1, 2, 3];
 
 fn main() {
     let a = [1i, 2, 3];
index 24eb5337d25f70d25d05f6340d529fba0642d71a..1774edd3f76e2bc88bf0e71796d79bded267cdd6 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // pp-exact
-fn f() -> [int, ..3] {
+fn f() -> [int3] {
     let picard = 0;
 
     let data = 1;
index b5ea9bd4b89c6a9ae3af71d9849cd398a848d4d3..974af1e6f3e108992f2a04178062ea9a46be60dd 100644 (file)
@@ -21,26 +21,26 @@ use std::prelude::*;
 
 // #4264 fixed-length vector types
 
-pub fn foo(_: [int, ..(3 as uint)]) { }
+pub fn foo(_: [int(3 as uint)]) { }
 
 pub fn bar() {
     const FOO: uint = ((5u as uint) - (4u as uint) as uint);
-    let _: [(), ..(FOO as uint)] = ([(() as ())] as [(), ..1]);
+    let _: [(); (FOO as uint)] = ([(() as ())] as [(); 1]);
 
-    let _: [(), ..(1u as uint)] = ([(() as ())] as [(), ..1]);
+    let _: [(); (1u as uint)] = ([(() as ())] as [(); 1]);
 
     let _ =
-        (((&((([(1i as int), (2 as int), (3 as int)] as [int, ..3])) as
-                [int, ..3]) as &[int, ..3]) as *const _ as *const [int, ..3])
-            as *const [int, ..(3u as uint)] as *const [int, ..3]);
+        (((&((([(1i as int), (2 as int), (3 as int)] as [int3])) as
+                [int; 3]) as &[int; 3]) as *const _ as *const [int; 3]) as
+            *const [int; (3u as uint)] as *const [int; 3]);
 
     (match (() as ()) {
          () => {
              #[inline]
              #[allow(dead_code)]
              static __STATIC_FMTSTR: &'static [&'static str] =
-                 (&([("test" as &'static str)] as [&'static str, ..1]) as
-                     &'static [&'static str, ..1]);
+                 (&([("test" as &'static str)] as [&'static str1]) as
+                     &'static [&'static str1]);
 
 
 
@@ -57,9 +57,9 @@ pub fn bar() {
                                                                                                                                                                 &'static [&'static str]),
                                                                                                                                                             (&([]
                                                                                                                                                                   as
-                                                                                                                                                                  [core::fmt::Argument<'_>, ..0])
+                                                                                                                                                                  [core::fmt::Argument<'_>0])
                                                                                                                                                                 as
-                                                                                                                                                                &[core::fmt::Argument<'_>, ..0]))
+                                                                                                                                                                &[core::fmt::Argument<'_>0]))
                                                                                       as
                                                                                       core::fmt::Arguments<'_>)
                                                                                     as
@@ -68,18 +68,17 @@ pub fn bar() {
          }
      } as collections::string::String);
 }
-pub type Foo = [int, ..(3u as uint)];
+pub type Foo = [int(3u as uint)];
 pub struct Bar {
-    pub x: [int, ..(3u as uint)],
+    pub x: [int(3u as uint)],
 }
-pub struct TupleBar([int, ..(4u as uint)]);
-pub enum Baz { BazVariant([int, ..(5u as uint)]), }
+pub struct TupleBar([int(4u as uint)]);
+pub enum Baz { BazVariant([int(5u as uint)]), }
 pub fn id<T>(x: T) -> T { (x as T) }
 pub fn use_id() {
     let _ =
-        ((id::<[int, ..(3u as uint)]> as
-             fn([int, ..3]) -> [int, ..3])(([(1 as int), (2 as int),
-                                             (3 as int)] as [int, ..3])) as
-            [int, ..3]);
+        ((id::<[int; (3u as uint)]> as
+             fn([int; 3]) -> [int; 3])(([(1 as int), (2 as int), (3 as int)]
+                                           as [int; 3])) as [int; 3]);
 }
 fn main() { }
diff --git a/src/test/pretty/where-clauses.rs b/src/test/pretty/where-clauses.rs
new file mode 100644 (file)
index 0000000..0f3b914
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// pp-exact
+
+fn f<'a, 'b, T>(t: T) -> int where T: 'a, 'a:'b, T: Eq { 0 }
+
+fn main() { }
+
index 302bb84908b66caf9ade6c81429ace97b4341803..88be7630e83914dd325f0ec45171213132507ac3 100644 (file)
@@ -1,4 +1,4 @@
-LIB := $(shell $(RUSTC) --crate-file-name --crate-type=lib lib.rs)
+LIB := $(shell $(RUSTC) --print file-names --crate-type=lib lib.rs)
 
 $(TMPDIR)/$(LIB):
        $(RUSTC) --dep-info $(TMPDIR)/custom-deps-file.d --crate-type=lib lib.rs
index 2b43dd0ec7095fbde0af1a498e01a0619628d8bf..e5df31f88c1e155a452f0baa34733870d8e7fdc1 100644 (file)
@@ -1,7 +1,7 @@
-LIB := $(shell $(RUSTC) --crate-file-name --crate-type=lib lib.rs)
+LIB := $(shell $(RUSTC) --print file-names --crate-type=lib lib.rs)
 
 $(TMPDIR)/$(LIB):
-       $(RUSTC) --dep-info --crate-type=lib lib.rs
+       $(RUSTC) --emit dep-info,link --crate-type=lib lib.rs
        touch $(TMPDIR)/done
 
 -include $(TMPDIR)/foo.d
index 7f715a475beadf1321a7921ed5ca7049c8827cba..f24933cac011788045e3a4b61735be0848ccce15 100644 (file)
@@ -6,6 +6,6 @@
 # used in the inner functions should each appear only once in the generated IR.
 
 all:
-       $(RUSTC) foo.rs --emit=ir
+       $(RUSTC) foo.rs --emit=llvm-ir
        [ "$$(grep -c 8675309 "$(TMPDIR)/foo.ll")" -eq "1" ]
        [ "$$(grep -c 11235813 "$(TMPDIR)/foo.ll")" -eq "1" ]
index d19e8f22c05479a648f3fdc4802a4336fccaa621..f097d8fabd1a8541ae95d814abc4a29eef5dc9fd 100644 (file)
@@ -4,7 +4,7 @@ ifdef IS_WINDOWS
 all:
 else
 
-NAME := $(shell $(RUSTC) --crate-file-name foo.rs)
+NAME := $(shell $(RUSTC) --print file-names foo.rs)
 
 all:
        mkdir -p $(TMPDIR)/outdir
index ef2db932b418d625eb4374479f142f1a6c2e7efe..7d0fc2d7fe503e618f2e300873d10bd4b86d753d 100644 (file)
@@ -20,6 +20,6 @@
 #[no_stack_check]
 pub unsafe fn foo() {
     // Make sure we use the stack
-    let x: [u8, ..50] = [0, ..50];
+    let x: [u8; 50] = [0; 50];
     black_box(x.as_ptr());
 }
index ee0364001e19a8258d8c677302d18c9fca6593be..2b6e7240d6fa857edf8a0e2a26dfb6e7d258124e 100644 (file)
@@ -19,6 +19,6 @@
 
 pub unsafe fn foo() {
     // Make sure we use the stack
-    let x: [u8, ..50] = [0, ..50];
+    let x: [u8; 50] = [0; 50];
     black_box(x.as_ptr());
 }
index fed071d1a43c28a27435a5169d058609cc829291..4efbd9ee48df21f3bae75e5710b3b29b82bf8167 100644 (file)
@@ -12,7 +12,7 @@ all:
        rm $(TMPDIR)/$(call BIN,bar)
        [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
 
-       $(RUSTC) foo.rs --emit=asm,ir,bc,obj,link
+       $(RUSTC) foo.rs --emit=asm,llvm-ir,llvm-bc,obj,link
        rm $(TMPDIR)/bar.ll
        rm $(TMPDIR)/bar.bc
        rm $(TMPDIR)/bar.s
@@ -24,11 +24,11 @@ all:
        rm $(TMPDIR)/foo
        [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
 
-       $(RUSTC) foo.rs --emit=bc -o $(TMPDIR)/foo
+       $(RUSTC) foo.rs --emit=llvm-bc -o $(TMPDIR)/foo
        rm $(TMPDIR)/foo
        [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
 
-       $(RUSTC) foo.rs --emit=ir -o $(TMPDIR)/foo
+       $(RUSTC) foo.rs --emit=llvm-ir -o $(TMPDIR)/foo
        rm $(TMPDIR)/foo
        [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
 
@@ -56,7 +56,7 @@ all:
        rm $(TMPDIR)/$(call BIN,foo)
        [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
 
-       $(RUSTC) foo.rs --emit=asm,ir,bc,obj,link --crate-type=staticlib
+       $(RUSTC) foo.rs --emit=asm,llvm-ir,llvm-bc,obj,link --crate-type=staticlib
        rm $(TMPDIR)/bar.ll
        rm $(TMPDIR)/bar.s
        rm $(TMPDIR)/bar.o
@@ -65,7 +65,7 @@ all:
        # Don't check that the $(TMPDIR) is empty - we left `foo.bc` for later
        # comparison.
 
-       $(RUSTC) foo.rs --emit=bc,link --crate-type=rlib
+       $(RUSTC) foo.rs --emit=llvm-bc,link --crate-type=rlib
        cmp $(TMPDIR)/foo.bc $(TMPDIR)/bar.bc
        rm $(TMPDIR)/bar.bc
        rm $(TMPDIR)/foo.bc
index 65db841b0c0edb5bbbddd57af531fa12f11772b6..189088219d5b3ae3417cd8906d46fd87bb395e86 100644 (file)
@@ -5,5 +5,5 @@
 
 all:
        $(RUSTC) cci_lib.rs
-       $(RUSTC) foo.rs --emit=ir -C codegen-units=3
+       $(RUSTC) foo.rs --emit=llvm-ir -C codegen-units=3
        [ "$$(cat "$(TMPDIR)"/foo.?.ll | grep -c define\ .*cci_fn)" -eq "2" ]
index 6cb9f9a3f31bc0fc510f143d26412f7da24e0554..bc299de0c2d3fc1f10318c4eeb2a1835eee35ecd 100644 (file)
@@ -6,7 +6,7 @@
 # function should be defined in only one compilation unit.
 
 all:
-       $(RUSTC) foo.rs --emit=ir -C codegen-units=3
+       $(RUSTC) foo.rs --emit=llvm-ir -C codegen-units=3
        [ "$$(cat "$(TMPDIR)"/foo.?.ll | grep -c define\ i32\ .*inlined)" -eq "1" ]
        [ "$$(cat "$(TMPDIR)"/foo.?.ll | grep -c define\ available_externally\ i32\ .*inlined)" -eq "2" ]
        [ "$$(cat "$(TMPDIR)"/foo.?.ll | grep -c define\ i32\ .*normal)" -eq "1" ]
index 265bd68bd2e8216ed722e7561f0635879b21585d..a475bdfd74a24f5795625f8898820dfd9970390d 100644 (file)
@@ -5,5 +5,5 @@
 # wind up in three different compilation units.
 
 all:
-       $(RUSTC) foo.rs --emit=ir -C codegen-units=3
+       $(RUSTC) foo.rs --emit=llvm-ir -C codegen-units=3
        [ "$$(cat "$(TMPDIR)"/foo.?.ll | grep -c define\ .*magic_fn)" -eq "3" ]
index cab98204b17d76ddeb02de086840b877a39f8f70..fd112034f40c50d3f53be37539e919fde84369d1 100644 (file)
@@ -21,7 +21,7 @@ trait Sized { }
 fn start(_main: *const u8, _argc: int, _argv: *const *const u8) -> int { 0 }
 
 extern {
-    fn _foo() -> [u8, ..16];
+    fn _foo() -> [u816];
 }
 
 fn _main() {
index 4950fe7572a3d694df8b75aec3b46b2e5935f616..23e14a9cb93de11b9e2b361fc63fea64e9b5259f 100644 (file)
@@ -1,8 +1,6 @@
 -include ../tools.mk
 
 all:
-       $(RUSTC) -v
-       $(RUSTC) -v verbose
-       $(RUSTC) -v bad_arg && exit 1 || exit 0
-       $(RUSTC) --version verbose
-       $(RUSTC) --version bad_arg && exit 1 || exit 0
+       $(RUSTC) -V
+       $(RUSTC) -vV
+       $(RUSTC) --version --verbose
index bf79ca68c9461ac8d6fe57a456a7d8ad1f39038c..34fa56efee6fa20c8fcdf3a4408f3057752d233f 100644 (file)
@@ -5,6 +5,6 @@ all:
        $(RUSTC) main.rs
        $(call RUN,main)
        # ... and the loads/stores must not be optimized out.
-       $(RUSTC) main.rs --emit=ir
+       $(RUSTC) main.rs --emit=llvm-ir
        grep "load volatile"  $(TMPDIR)/main.ll
        grep "store volatile" $(TMPDIR)/main.ll
index aaffb013ad8c75c93307d28e22fe34c4e0d1aaf2..717ca3ff9feccb24bd9d289a2e7dfa4e9af20eb1 100644 (file)
@@ -13,8 +13,8 @@
 const SIZE: int = 25;
 
 fn main() {
-    let _a: [bool, ..1 as uint];
-    let _b: [int, ..SIZE as uint] = [1, ..SIZE as uint];
-    let _c: [bool, ..'\n' as uint] = [true, ..'\n' as uint];
-    let _d: [bool, ..true as uint] = [true, ..true as uint];
+    let _a: [bool1 as uint];
+    let _b: [int; SIZE as uint] = [1; SIZE as uint];
+    let _c: [bool; '\n' as uint] = [true; '\n' as uint];
+    let _d: [bool; true as uint] = [true; true as uint];
 }
index 60daedec4c79fe5199ad7b2237a2e958936d82b3..6e2cfedf9ec3ebed8eabf9d6a166043bf8ec3a17 100644 (file)
 // Check that the various ways of getting to a reference to a vec (both sized
 // and unsized) work properly.
 
-const aa: [int, ..3] = [1, 2, 3];
-const ab: &'static [int, ..3] = &aa;
+const aa: [int3] = [1, 2, 3];
+const ab: &'static [int3] = &aa;
 const ac: &'static [int] = ab;
 const ad: &'static [int] = &aa;
-const ae: &'static [int, ..3] = &[1, 2, 3];
+const ae: &'static [int3] = &[1, 2, 3];
 const af: &'static [int] = &[1, 2, 3];
 
 static ca: int = aa[0];
index e80ed7c984b4a4da33b5f607fcec9ace7513aa1d..71312fb387845b54f5bf18f5cb129fc2c4420f86 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static A: [u8, ..1] = ['h' as u8];
+static A: [u81] = ['h' as u8];
 static B: u8 = (&A)[0];
-static C: &'static &'static &'static &'static [u8, ..1] = & & & &A;
+static C: &'static &'static &'static &'static [u81] = & & & &A;
 static D: u8 = (&C)[0];
 
 pub fn main() {
index fef6c8624cf71140547dae1e787adb48b23c5e7e..4c8124d28a24157c02dbe6669849294674cce707 100644 (file)
@@ -12,7 +12,7 @@ enum E { V1(int), V0 }
 const C: &'static [E] = &[E::V0, E::V1(0xDEADBEE)];
 static C0: E = C[0];
 static C1: E = C[1];
-const D: &'static [E, ..2] = &[E::V0, E::V1(0xDEADBEE)];
+const D: &'static [E2] = &[E::V0, E::V1(0xDEADBEE)];
 static D0: E = C[0];
 static D1: E = C[1];
 
index 83687f8775b346e4220327734af1963373cca57e..6eb5c2dab38ba17fa680da8e14ccc31705d16292 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 enum E { V1(int), V0 }
-static C: [E, ..3] = [E::V0, E::V1(0xDEADBEE), E::V0];
+static C: [E3] = [E::V0, E::V1(0xDEADBEE), E::V0];
 
 pub fn main() {
     match C[1] {
index 317a54e927f31fb40ebbabc75f7f9a0fad49f240..6317c2eec1801b34bf2a678a2c797fb43cc8108e 100644 (file)
@@ -14,6 +14,6 @@
 pub fn main() {
 
     const FOO: uint = 2;
-    let _v: [int, ..FOO*3];
+    let _v: [intFOO*3];
 
 }
index 54386b33dd9dad8b9c89f622da1ef8eac0a2a2f5..d692f3a87e457b385f956ccb62d0aae6e599803e 100644 (file)
@@ -13,6 +13,6 @@
 pub fn main() {
 
     const FOO: uint = 2;
-    let _v = [0i, ..FOO*3*2/2];
+    let _v = [0iFOO*3*2/2];
 
 }
index 49b244a162b0c28bee40c28a77ba2c57939a1bf3..0819e0becbf9564cb1ac9738cc04147a65167182 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-const x : [int, ..4] = [1,2,3,4];
+const x : [int4] = [1,2,3,4];
 static p : int = x[2];
 const y : &'static [int] = &[1,2,3,4];
 static q : int = y[2];
index 5e417efb4b5838ef2f1ca0ab37ae82e936dc3226..e8081005d4a8ff4695ddc124e364ea86305fc53a 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-type Big = [u64, ..8];
+type Big = [u648];
 struct Pair<'a> { a: int, b: &'a Big }
 const x: &'static Big = &([13, 14, 10, 13, 11, 14, 14, 15]);
 const y: &'static Pair<'static> = &Pair {a: 15, b: x};
index 47d59eca26316c07b16a2b6f4e1df929c776e0e4..d6f0296619ab4e7ff62ab4ff97af53964390d71a 100644 (file)
@@ -10,8 +10,8 @@
 
 use std::{str, string};
 
-const A: [u8, ..2] = ['h' as u8, 'i' as u8];
-const B: &'static [u8, ..2] = &A;
+const A: [u82] = ['h' as u8, 'i' as u8];
+const B: &'static [u82] = &A;
 const C: *const u8 = B as *const u8;
 
 pub fn main() {
index 1a2a3e36e874672cdc7cfd34fa91b0bcbc6c3a79..26874b9f9d52dfc1744b9db85931e1f30216241c 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static x : [int, ..4] = [1,2,3,4];
+static x : [int4] = [1,2,3,4];
 static y : &'static [int] = &[1,2,3,4];
-static z : &'static [int, ..4] = &[1,2,3,4];
+static z : &'static [int4] = &[1,2,3,4];
 static zz : &'static [int] = &[1,2,3,4];
 
 pub fn main() {
index bf5b300f7cf0aa72be0b5337fc8ff5de6187bb3b..3644ca81d5659f784a13c28718cf9c1b10e07774 100644 (file)
@@ -120,7 +120,7 @@ pub fn main() {
     assert!((*f2)[1] == 2);
 
     // Nested Box.
-    let f1 : Box<Fat<[int, ..3]>> = box Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] };
+    let f1 : Box<Fat<[int3]>> = box Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] };
     foo(&*f1);
     let f2 : Box<Fat<[int]>> = f1;
     foo(&*f2);
index 0256420ac4c3dc0e4c6d429273b265cf8c143329..d436916c279673c30fed5d2f18a05483acf8a69b 100644 (file)
@@ -16,9 +16,9 @@ enum Flopsy {
 const BAR2:uint = BAR;
 
 pub fn main() {
-    let _v = [0i, .. Flopsy::Bunny as uint];
-    let _v = [0i, .. BAR];
-    let _v = [0i, .. BAR2];
+    let _v = [0i Flopsy::Bunny as uint];
+    let _v = [0i BAR];
+    let _v = [0i BAR2];
     const BAR3:uint = BAR2;
-    let _v = [0i, .. BAR3];
+    let _v = [0i BAR3];
 }
index 36b5f86aedab48727709be3864cefa42454c9d39..28b5f781b5cfd7d962cd5d6b434e8adf35ac58f9 100644 (file)
 // Doesn't work; needs a design decision.
 
 pub fn main() {
-    let x : [int, ..5] = [1,2,3,4,5];
-    let _y : [int, ..5] = [1,2,3,4,5];
+    let x : [int5] = [1,2,3,4,5];
+    let _y : [int5] = [1,2,3,4,5];
     let mut z = [1,2,3,4,5];
     z = x;
     assert_eq!(z[0], 1);
     assert_eq!(z[4], 5);
 
-    let a : [int, ..5] = [1,1,1,1,1];
-    let b : [int, ..5] = [2,2,2,2,2];
-    let c : [int, ..5] = [2,2,2,2,3];
+    let a : [int5] = [1,1,1,1,1];
+    let b : [int5] = [2,2,2,2,2];
+    let c : [int5] = [2,2,2,2,3];
 
     log(debug, a);
 
index f63ab7fb7c9a5ca5e6b1bc155ebf8b5a76d17cba..38d1093762432652df59625ee5e8fddebe155a7d 100644 (file)
 
 #![feature(macro_rules)]
 
-use std::num::strconv as s;
+use std::num::strconv::ExponentFormat::{ExpBin, ExpDec};
+use std::num::strconv::SignificantDigits::DigMax;
+use std::num::strconv::SignFormat::{SignAll, SignNeg};
 use std::num::strconv::float_to_str_common as to_string;
 
 macro_rules! t(($a:expr, $b:expr) => { { let (r, _) = $a; assert_eq!(r, $b.to_string()); } });
 
 pub fn main() {
     // Basic usage
-    t!(to_string(1.2345678e-5f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpDec, false),
+    t!(to_string(1.2345678e-5f64, 10u, true, SignNeg, DigMax(6), ExpDec, false),
              "1.234568e-5");
 
     // Hexadecimal output
-    t!(to_string(7.281738281250e+01f64, 16u, true, s::SignAll, s::DigMax(6), s::ExpBin, false),
+    t!(to_string(7.281738281250e+01f64, 16u, true, SignAll, DigMax(6), ExpBin, false),
               "+1.2345p+6");
-    t!(to_string(-1.777768135071e-02f64, 16u, true, s::SignAll, s::DigMax(6), s::ExpBin, false),
+    t!(to_string(-1.777768135071e-02f64, 16u, true, SignAll, DigMax(6), ExpBin, false),
              "-1.2345p-6");
 
     // Some denormals
-    t!(to_string(4.9406564584124654e-324f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpBin, false),
+    t!(to_string(4.9406564584124654e-324f64, 10u, true, SignNeg, DigMax(6), ExpBin, false),
              "1p-1074");
-    t!(to_string(2.2250738585072009e-308f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpBin, false),
+    t!(to_string(2.2250738585072009e-308f64, 10u, true, SignNeg, DigMax(6), ExpBin, false),
              "1p-1022");
 }
index d494e0bf40dea8a28712b1251379e0328c39eaaa..e24731546edfe3cc035a3e2fe8c2e38424fd82a3 100644 (file)
 
 #[cfg(target_word_size = "32")]
 pub fn main() {
-    assert_eq!(size_of::<[u8, ..(1 << 31) - 1]>(), (1 << 31) - 1);
+    assert_eq!(size_of::<[u8(1 << 31) - 1]>(), (1 << 31) - 1);
 }
 
 #[cfg(target_word_size = "64")]
 pub fn main() {
-    assert_eq!(size_of::<[u8, ..(1 << 47) - 1]>(), (1 << 47) - 1);
+    assert_eq!(size_of::<[u8(1 << 47) - 1]>(), (1 << 47) - 1);
 }
index 9eac9c30dc8f7ee27d2a9a4061e73c05b03dd425..f3e15562b6dc99a92d1f46173518f3aa861ebacf 100644 (file)
@@ -60,6 +60,7 @@ pub fn main() {
     t!(format!("{}", 10i), "10");
     t!(format!("{}", 10i), "10");
     t!(format!("{}", 10u), "10");
+    t!(format!("{:?}", true), "true");
     t!(format!("{:o}", 10u), "12");
     t!(format!("{:x}", 10u), "a");
     t!(format!("{:X}", 10u), "A");
index ea138311f19b3bb25a4696a8844dc97d51bbfe41..549a70f19e334fb166149f2cee556d6b55523ec5 100644 (file)
 
 trait Foo {}
 impl Foo for int {}
-fn foo(_: [&Foo, ..2]) {}
+fn foo(_: [&Foo2]) {}
 fn foos(_: &[&Foo]) {}
 fn foog<T>(_: &[T], _: &[T]) {}
 
-fn bar(_: [Box<Foo>, ..2]) {}
+fn bar(_: [Box<Foo>2]) {}
 fn bars(_: &[Box<Foo>]) {}
 
 fn main() {
-    let x: [&Foo, ..2] = [&1i, &2i];
+    let x: [&Foo2] = [&1i, &2i];
     foo(x);
     foo([&1i, &2i]);
 
     let r = &1i;
-    let x: [&Foo, ..2] = [r, ..2];
+    let x: [&Foo; 2] = [r; 2];
     foo(x);
-    foo([&1i, ..2]);
+    foo([&1i2]);
 
     let x: &[&Foo] = &[&1i, &2i];
     foos(x);
@@ -37,7 +37,7 @@ fn main() {
     let r = &1i;
     foog(x, &[r]);
 
-    let x: [Box<Foo>, ..2] = [box 1i, box 2i];
+    let x: [Box<Foo>2] = [box 1i, box 2i];
     bar(x);
     bar([box 1i, box 2i]);
 
@@ -49,16 +49,16 @@ fn main() {
     foog(x, &[box 1i]);
 
     struct T<'a> {
-        t: [&'a (Foo+'a), ..2]
+        t: [&'a (Foo+'a)2]
     }
     let _n = T {
         t: [&1i, &2i]
     };
     let r = &1i;
     let _n = T {
-        t: [r, ..2]
+        t: [r2]
     };
-    let x: [&Foo, ..2] = [&1i, &2i];
+    let x: [&Foo2] = [&1i, &2i];
     let _n = T {
         t: x
     };
@@ -70,11 +70,11 @@ struct F<'b> {
         t: &[&1i, &2i]
     };
     let r = &1i;
-    let r: [&Foo, ..2] = [r, ..2];
+    let r: [&Foo; 2] = [r; 2];
     let _n = F {
         t: &r
     };
-    let x: [&Foo, ..2] = [&1i, &2i];
+    let x: [&Foo2] = [&1i, &2i];
     let _n = F {
         t: &x
     };
@@ -85,7 +85,7 @@ struct M<'a> {
     let _n = M {
         t: &[box 1i, box 2i]
     };
-    let x: [Box<Foo>, ..2] = [box 1i, box 2i];
+    let x: [Box<Foo>2] = [box 1i, box 2i];
     let _n = M {
         t: &x
     };
index 0e42bdbd6add7c9b44e42b10d9d789837866cc6c..329ab7c921dda3ebe476af0fb67d00ba0e6d6e3f 100644 (file)
@@ -27,7 +27,7 @@ fn FormatMessageW(flags: DWORD,
     }
 
     pub fn test() {
-        let mut buf: [u16, ..50] = [0, ..50];
+        let mut buf: [u16; 50] = [0; 50];
         let ret = unsafe {
             FormatMessageW(0x1000, 0 as *mut c_void, 1, 0x400,
                            buf.as_mut_ptr(), buf.len() as u32, 0 as *const c_void)
index 8b2b732415ee0b9f6e2d9c7b09eec2f39da1ea3f..81b6892b0f97ac4f97922a6125b02c11c82a6f44 100644 (file)
@@ -12,9 +12,9 @@
 
 const NUM: uint = u8::BITS as uint;
 
-struct MyStruct { nums: [uint, ..8] }
+struct MyStruct { nums: [uint8] }
 
 
 fn main() {
-    let _s = MyStruct { nums: [0, ..NUM] };
+    let _s = MyStruct { nums: [0NUM] };
 }
index 221115a0869a58047b2f187911333fd5d4000bd4..f62a45277b22a29c1b7c0923dd9edc96f94d3402 100644 (file)
@@ -8,6 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static TEST_VALUE : *const [int, ..2] = 0x1234 as *const [int, ..2];
+static TEST_VALUE : *const [int; 2] = 0x1234 as *const [int; 2];
 
 fn main() {}
index 160828d42fc54a768bc8c0ad4c3bffedc86b0517..ad4ed03e6e2c82386f09c1add758975a89ce71d5 100644 (file)
@@ -24,7 +24,7 @@ fn a() {}
     fn b(&self) {}
 }
 
-// If these fail, it's necessary to update middle::resolve and the cfail tests.
+// If these fail, it's necessary to update rustc_resolve and the cfail tests.
 impl Foo for *const BarTy {
     fn bar(&self) {
         self.baz();
@@ -33,7 +33,7 @@ fn bar(&self) {
     }
 }
 
-// If these fail, it's necessary to update middle::resolve and the cfail tests.
+// If these fail, it's necessary to update rustc_resolve and the cfail tests.
 impl<'a> Foo for &'a BarTy {
     fn bar(&self) {
         self.baz();
@@ -45,7 +45,7 @@ fn bar(&self) {
     }
 }
 
-// If these fail, it's necessary to update middle::resolve and the cfail tests.
+// If these fail, it's necessary to update rustc_resolve and the cfail tests.
 impl<'a> Foo for &'a mut BarTy {
     fn bar(&self) {
         self.baz();
@@ -57,7 +57,7 @@ fn bar(&self) {
     }
 }
 
-// If these fail, it's necessary to update middle::resolve and the cfail tests.
+// If these fail, it's necessary to update rustc_resolve and the cfail tests.
 impl Foo for Box<BarTy> {
     fn bar(&self) {
         self.baz();
@@ -65,7 +65,7 @@ fn bar(&self) {
     }
 }
 
-// If these fail, it's necessary to update middle::resolve and the cfail tests.
+// If these fail, it's necessary to update rustc_resolve and the cfail tests.
 impl Foo for *const int {
     fn bar(&self) {
         self.baz();
@@ -73,7 +73,7 @@ fn bar(&self) {
     }
 }
 
-// If these fail, it's necessary to update middle::resolve and the cfail tests.
+// If these fail, it's necessary to update rustc_resolve and the cfail tests.
 impl<'a> Foo for &'a int {
     fn bar(&self) {
         self.baz();
@@ -81,7 +81,7 @@ fn bar(&self) {
     }
 }
 
-// If these fail, it's necessary to update middle::resolve and the cfail tests.
+// If these fail, it's necessary to update rustc_resolve and the cfail tests.
 impl<'a> Foo for &'a mut int {
     fn bar(&self) {
         self.baz();
@@ -89,7 +89,7 @@ fn bar(&self) {
     }
 }
 
-// If these fail, it's necessary to update middle::resolve and the cfail tests.
+// If these fail, it's necessary to update rustc_resolve and the cfail tests.
 impl Foo for Box<int> {
     fn bar(&self) {
         self.baz();
index cef09af1fcff2ff4db304255ac274c0bbafe756e..d815620c9694d7f4fede8925019fd7f671e467c9 100644 (file)
@@ -15,7 +15,7 @@ fn main() {
     let args = os::args();
     if args.len() > 1 {
         let mut out = stdio::stdout();
-        out.write(&['a' as u8, ..128 * 1024]).unwrap();
+        out.write(&['a' as u8128 * 1024]).unwrap();
     } else {
         let out = Command::new(args[0].as_slice()).arg("child").output();
         let out = out.unwrap();
index 051d98aa1d89b93381c5dae415e3b92d3e3c1ff7..e66788a2c003779d020a725b2c6f51725bf17c5e 100644 (file)
@@ -10,6 +10,6 @@
 
 use std::iter::AdditiveIterator;
 fn main() {
-    let x: [u64, ..3] = [1, 2, 3];
+    let x: [u643] = [1, 2, 3];
     assert_eq!(6, range(0, 3).map(|i| x[i]).sum());
 }
index 50583c7d127d884ae9e75e8dbaf290f7f9c554d2..b2abf2d2b1a9c60238af56ad651827f953f8092a 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static mut DROPPED: [bool, ..2] = [false, false];
+static mut DROPPED: [bool2] = [false, false];
 
 struct A(uint);
 struct Foo { _a: A, _b: int }
index 51db2f0595997f0841e73ee7b82d42a904f83002..827e6a10abdfd12fcc064c1adb26f963cd44237b 100644 (file)
@@ -9,11 +9,11 @@
 // except according to those terms.
 
 fn main() {
-    assert_eq!(match [0u8, ..1024] {
+    assert_eq!(match [0u81024] {
         _ => 42u,
     }, 42u);
 
-    assert_eq!(match [0u8, ..1024] {
+    assert_eq!(match [0u81024] {
         [1, _..] => 0u,
         [0, _..] => 1u,
         _ => 2u
index 6bb244bf88f424d24958e95e37995338ec57c777..f61530c741851e1c0d33180c1bae5523082832ff 100644 (file)
@@ -12,5 +12,5 @@
 // expression with a count of 1 and a non-Copy element type.
 
 fn main() {
-    let _ = [box 1u, ..1];
+    let _ = [box 1u1];
 }
index d42bda6cd5d420139953d59c0eaa09853859eaf0..3ee5ce9bff93a089ffeb34a59e3cd50cf16939a0 100644 (file)
@@ -13,8 +13,8 @@ struct MyStruct { field: uint }
 const TUP: (uint,) = (43,);
 
 fn main() {
-    let a = [0i, ..STRUCT.field];
-    let b = [0i, ..TUP.0];
+    let a = [0iSTRUCT.field];
+    let b = [0iTUP.0];
 
     assert!(a.len() == 42);
     assert!(b.len() == 43);
diff --git a/src/test/run-pass/issue-19811-escape-unicode.rs b/src/test/run-pass/issue-19811-escape-unicode.rs
new file mode 100644 (file)
index 0000000..2340085
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let mut escaped = String::from_str("");
+    for c in '\u{10401}'.escape_unicode() {
+        escaped.push(c);
+    }
+    assert_eq!("\\u{10401}", escaped);
+}
index 1dc1587ff2fd69bf80d79a54c570a583ad76372b..f87eb46d553b77446686cbafb353285a0a40fcda 100644 (file)
@@ -63,7 +63,7 @@ fn read_board_grid<rdr:'static + io::Reader>(mut input: rdr)
                    -> Vec<Vec<square>> {
     let mut input: &mut io::Reader = &mut input;
     let mut grid = Vec::new();
-    let mut line = [0, ..10];
+    let mut line = [010];
     input.read(&mut line);
     let mut row = Vec::new();
     for c in line.iter() {
index 53157ce7546ffd367fa908ea862e2b558b09cb9f..8a39676ca17ac44a40e7266c1523e41800e53872 100644 (file)
@@ -16,7 +16,7 @@
 use libc::{c_uint, uint32_t, c_void};
 
 pub struct KEYGEN {
-    hash_algorithm: [c_uint, ..2],
+    hash_algorithm: [c_uint2],
     count: uint32_t,
     salt: *const c_void,
     salt_size: uint32_t,
index 447bf3b4b267e8f11d1fe16eb5f5497eb2423faa..43948ef4a45c52d7834ba37760862b0f589978ab 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 pub fn main() {
-    let _foo = [0i, ..2*4];
+    let _foo = [0i2*4];
 }
index 0a13e001fabf5895f91d217e21d2f487913a11ea..7c8940aafbfbe82831d82363cc2a8f2ea8a8b315 100644 (file)
@@ -13,7 +13,7 @@
 
 ...should print &[1, 2, 3] but instead prints something like
 &[4492532864, 24]. It is pretty evident that the compiler messed up
-with the representation of [int, ..n] and [int] somehow, or at least
+with the representation of [intn] and [int] somehow, or at least
 failed to typecheck correctly.
 */
 
index 666847517efdeda568d337a45d628f586e46fb20..b936eb322fc5ffc17506cde105d74a5e6dcf449a 100644 (file)
 
 #![feature(advanced_slice_patterns)]
 
-fn foo<T: Add<T, T> + Clone>([x, y, z]: [T, ..3]) -> (T, T, T) {
+fn foo<T: Add<T, T> + Clone>([x, y, z]: [T3]) -> (T, T, T) {
     (x.clone(), x.clone() + y.clone(), x + y + z)
 }
-fn bar(a: &'static str, b: &'static str) -> [&'static str, ..4] {
+fn bar(a: &'static str, b: &'static str) -> [&'static str4] {
     [a, b, b, a]
 }
 
index b9410ffdb43ec7f63724a71307b7d6a4814ed47c..321e22cd19c9268c0dd5dfc0ef44541cfbb4ee78 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 pub fn main() {
-    const S: uint = 23 as uint; [0i, ..S]; ()
+    const S: uint = 23 as uint; [0iS]; ()
 }
index 4c124d85eee3acbc84c3acbb6023bdfecb494776..ecd7c0458f701a391157fa7203b7ac80b5d8b631 100644 (file)
@@ -15,5 +15,5 @@ macro_rules! four (
 );
 
 fn main() {
-    let _x: [u16, ..four!()];
+    let _x: [u16four!()];
 }
index 400aab64b4cdb4460a5f8e68a1650f1ab66ca8f8..db512adc011646db661cbfa3bd41660648c0d112 100644 (file)
@@ -64,7 +64,7 @@ fn action_to_str(state: glfw::InputState) -> &'static str {
 }
 
 fn issue_13626() {
-    const VAL: [u8, ..1] = [0];
+    const VAL: [u81] = [0];
     match [1] {
         VAL => unreachable!(),
         _ => ()
index 00319d57f8da64e5cb16cc6c1ce30e559876066e..9ae7f49c75a154f22d97e2a237032b2df6810cb8 100644 (file)
@@ -38,7 +38,7 @@ fn my_write(&mut self, buf: &[u8]) -> IoResult<()> {
 }
 
 fn main() {
-    let mut buf = [0_u8, .. 6];
+    let mut buf = [0_u8; 6];
 
     {
         let mut writer = buf.as_mut_slice();
index 986236fb6f9fdc201f458462d17fd60c566bdea3..fbecb6851b68758dd44ad067850761c22dafde8b 100644 (file)
@@ -28,7 +28,7 @@ fn foo(self) {}
 }
 
 fn main() {
-    let x: [int, ..4] = [1,2,3,4];
+    let x: [int4] = [1,2,3,4];
     let xptr = x.as_slice() as *const _;
     xptr.foo();
 }
index ef0bc75c32661551ccf1b3235d29860c825d72fd..bf926a6c48ace0fcf29841d4c89b69e4f47cf49f 100644 (file)
@@ -9,13 +9,13 @@
 // except according to those terms.
 
 fn test1() {
-    let mut ints = [0i, ..32];
+    let mut ints = [0i32];
     ints[0] += 1;
     assert_eq!(ints[0], 1);
 }
 
 fn test2() {
-    let mut ints = [0i, ..32];
+    let mut ints = [0i32];
     for i in ints.iter_mut() { *i += 22; }
     for i in ints.iter() { assert!(*i == 22); }
 }
index a689fb0cf7c2b24f75c814ea4566c15012222bf2..e06461daed0c93c9afea708e96e195bf276283cc 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: [int, ..3] = [1, 2, 3];
+static FOO: [int3] = [1, 2, 3];
 
 pub fn main() {
     println!("{} {} {}", FOO[0], FOO[1], FOO[2]);
index da1ad094df6a035effb8e693b581bd3d393bc310..2660de619e9c775f709159ac750df76c67845c96 100644 (file)
@@ -20,7 +20,7 @@
 // trying to get assert failure messages that at least identify which case
 // failed.
 
-enum E<T> { Thing(int, T), Nothing((), ((), ()), [i8, ..0]) }
+enum E<T> { Thing(int, T), Nothing((), ((), ()), [i80]) }
 impl<T> E<T> {
     fn is_none(&self) -> bool {
         match *self {
@@ -54,7 +54,7 @@ macro_rules! check_fancy {
         check_fancy!($e: $T, |ptr| assert!(*ptr == $e));
     }};
     ($e:expr: $T:ty, |$v:ident| $chk:expr) => {{
-        assert!(E::Nothing::<$T>((), ((), ()), [23i8, ..0]).is_none());
+        assert!(E::Nothing::<$T>((), ((), ()), [23i80]).is_none());
         let e = $e;
         let t_ = E::Thing::<$T>(23, e);
         match t_.get_ref() {
index 5708310abadbfe88e0740d981feed67b5ff0edca..afc22be38b8a48b16b542a642f46a8418cea235e 100644 (file)
@@ -12,7 +12,7 @@
 
 use std::mem;
 
-enum E<T> { Thing(int, T), Nothing((), ((), ()), [i8, ..0]) }
+enum E<T> { Thing(int, T), Nothing((), ((), ()), [i80]) }
 struct S<T>(int, T);
 
 // These are macros so we get useful assert messages.
index 9a76beac9e5f75c49c160750bae829f82cc5e70a..a866be43a051473b5b8fcc9fe0921a10b8307414 100644 (file)
@@ -14,7 +14,7 @@
 // in ORDER matching up to when it ran.
 // Correct order is: matched, inner, outer
 
-static mut ORDER: [uint, ..3] = [0, 0, 0];
+static mut ORDER: [uint3] = [0, 0, 0];
 static mut INDEX: uint = 0;
 
 struct A;
index 419d9b5d824b14ad7406684b56afd988a2cba948..674d0dc86da1cd35900a7e6ba06c0c6548a5551d 100644 (file)
@@ -27,7 +27,7 @@ pub fn black_box<T>(dummy: T) { unsafe { asm!("" : : "r"(&dummy)) } }
 
 #[no_stack_check]
 fn recurse() {
-    let buf = [0i, ..10];
+    let buf = [0i10];
     black_box(buf);
     recurse();
 }
index ecb93cc6f8c7ef152e11c3a8499bcc4b244df77e..79926776abf4c0284470a080158bf793c993290d 100644 (file)
@@ -28,7 +28,7 @@ pub fn black_box<T>(dummy: T) { unsafe { asm!("" : : "r"(&dummy)) } }
 
 #[no_stack_check]
 fn recurse() {
-    let buf = [0i, ..10];
+    let buf = [0i10];
     black_box(buf);
     recurse();
 }
index 81e75ba2cd53dc4ede60399ef9f5d960cbf8b5ab..1594cca89e55b8ada6f50b385afd3922c1f72964 100644 (file)
@@ -22,7 +22,7 @@
 pub fn black_box<T>(dummy: T) { unsafe { asm!("" : : "r"(&dummy)) } }
 
 fn silent_recurse() {
-    let buf = [0i, ..1000];
+    let buf = [0i1000];
     black_box(buf);
     silent_recurse();
 }
index 999e4aeeb5977ebacedd0d5195f56da419496a0d..004a30220183ed101a9b5b28010625286121a397 100644 (file)
@@ -20,7 +20,7 @@ struct S<T, S> {
 pub fn main() {
     unsafe {
         let s = S { a: 0xff_ff_ff_ffu32, b: 1, c: 0xaa_aa_aa_aa as i32 };
-        let transd : [u8, .. 9] = mem::transmute(s);
+        let transd : [u8; 9] = mem::transmute(s);
         // Don't worry about endianness, the numbers are palindromic.
         assert!(transd ==
                    [0xff, 0xff, 0xff, 0xff,
@@ -29,7 +29,7 @@ pub fn main() {
 
 
         let s = S { a: 1u8, b: 2u8, c: 0b10000001_10000001 as i16};
-        let transd : [u8, .. 4] = mem::transmute(s);
+        let transd : [u8; 4] = mem::transmute(s);
         // Again, no endianness problems.
         assert!(transd ==
                    [1, 2, 0b10000001, 0b10000001]);
index b4fbf0820cd46b0badead839ab53af6d727bc7e1..9e94502a92a6384199380bd85bc708ed62d80cea 100644 (file)
@@ -13,7 +13,7 @@
 #[repr(packed)]
 struct S4 {
     a: u8,
-    b: [u8, .. 3],
+    b: [u8; 3],
 }
 
 #[repr(packed)]
@@ -25,11 +25,11 @@ struct S5 {
 pub fn main() {
     unsafe {
         let s4 = S4 { a: 1, b: [2,3,4] };
-        let transd : [u8, .. 4] = mem::transmute(s4);
+        let transd : [u8; 4] = mem::transmute(s4);
         assert!(transd == [1, 2, 3, 4]);
 
         let s5 = S5 { a: 1, b: 0xff_00_00_ff };
-        let transd : [u8, .. 5] = mem::transmute(s5);
+        let transd : [u8; 5] = mem::transmute(s5);
         // Don't worry about endianness, the u32 is palindromic.
         assert!(transd == [1, 0xff, 0, 0, 0xff]);
     }
index 9472fd4ce38ed33318ca87e502b165cf15b56d7b..846d51e2e7ecc916e29e1fad89a53541ab5bc610 100644 (file)
@@ -14,7 +14,7 @@
 #[repr(packed)]
 struct S4 {
     a: u8,
-    b: [u8, .. 3],
+    b: [u8 3],
 }
 
 #[repr(packed)]
index 59bb5678b6936e5a490a2a0b48a027c78f4bd29f..d2121aa775216d221b34ee7776744d263fb06b36 100644 (file)
@@ -22,9 +22,9 @@ struct Foo {
 impl Copy for Foo {}
 
 pub fn main() {
-    let foos = [Foo { bar: 1, baz: 2 }, .. 10];
+    let foos = [Foo { bar: 1, baz: 2 }; 10];
 
-    assert_eq!(mem::size_of::<[Foo, .. 10]>(), 90);
+    assert_eq!(mem::size_of::<[Foo; 10]>(), 90);
 
     for i in range(0u, 10) {
         assert_eq!(foos[i], Foo { bar: 1, baz: 2});
index 5fb43503ccb26b0ccfff993b6959783ea9a5064d..c41d678b0f5b702826f1b7e098112bc9a5b37f5d 100644 (file)
@@ -11,7 +11,7 @@
 use std::mem;
 
 #[repr(packed)]
-struct S4(u8,[u8, .. 3]);
+struct S4(u8,[u8; 3]);
 
 #[repr(packed)]
 struct S5(u8,u32);
 pub fn main() {
     unsafe {
         let s4 = S4(1, [2,3,4]);
-        let transd : [u8, .. 4] = mem::transmute(s4);
+        let transd : [u8; 4] = mem::transmute(s4);
         assert!(transd == [1, 2, 3, 4]);
 
         let s5 = S5(1, 0xff_00_00_ff);
-        let transd : [u8, .. 5] = mem::transmute(s5);
+        let transd : [u8; 5] = mem::transmute(s5);
         // Don't worry about endianness, the u32 is palindromic.
         assert!(transd == [1, 0xff, 0, 0, 0xff]);
     }
index 8967b07ca8823757b788c07edf1e52c79a515f88..a0b88ea53c5a4f3d60d54de588ffbeba0e8cd883 100644 (file)
@@ -12,7 +12,7 @@
 use std::mem;
 
 #[repr(packed)]
-struct S4(u8,[u8, .. 3]);
+struct S4(u8,[u8 3]);
 
 #[repr(packed)]
 struct S5(u8, u32);
index 79f8ca48882cfb4a8881b75ed9b64e69023461c4..41396ef01bee8def070e284a246f9f2822bd2069 100644 (file)
@@ -18,7 +18,7 @@ struct A {
 
 struct B {
     v1: int,
-    v2: [int, ..3],
+    v2: [int3],
     v3: Vec<int> ,
     v4: C,
     v5: Box<C>,
index 9955673bb0b12aa1755ae03d795b78a270bbfebb..a53f1da4ce605ee7a1bdc3bbb8bd115c2ba10732 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: [int, ..4] = [32, ..4];
-static BAR: [int, ..4] = [32, 32, 32, 32];
+static FOO: [int; 4] = [32; 4];
+static BAR: [int4] = [32, 32, 32, 32];
 
 pub fn main() {
     assert!(FOO == BAR);
index 9c369c0d770c6a5a3142db4d6ee43f1ae9feebcc..0781822cb748203ac502305255d04a561904d0cd 100644 (file)
@@ -11,8 +11,8 @@
 #![feature(slicing_syntax)]
 
 pub fn main() {
-    let x = [ [true], ..512 ];
-    let y = [ 0i, ..1 ];
+    let x = [ [true]512 ];
+    let y = [ 0i1 ];
 
     print!("[");
     for xi in x.iter() {
diff --git a/src/test/run-pass/self-impl.rs b/src/test/run-pass/self-impl.rs
new file mode 100644 (file)
index 0000000..3ece042
--- /dev/null
@@ -0,0 +1,42 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that we can use `Self` types in impls in the expected way.
+
+struct Foo;
+
+// Test uses on inherant impl.
+impl Foo {
+    fn foo(_x: Self, _y: &Self, _z: Box<Self>) -> Self {
+        Foo
+    }
+}
+
+// Test uses when implementing a trait and with a type parameter.
+pub struct Baz<X> {
+    pub f: X,
+}
+
+trait Bar<X> {
+    fn bar(x: Self, y: &Self, z: Box<Self>) -> Self;
+}
+
+impl Bar<int> for Box<Baz<int>> {
+    fn bar(_x: Self, _y: &Self, _z: Box<Self>) -> Self {
+        box Baz { f: 42 }
+    }
+}
+
+fn main() {
+    let _: Foo = Foo::foo(Foo, &Foo, box Foo);
+    let _: Box<Baz<int>> = Bar::bar(box Baz { f: 42 },
+                                    &box Baz { f: 42 },
+                                    box box Baz { f: 42 });
+}
index 005205353fce6a4d15a02de5a086f073f5b8f21d..c2bd738b8a46bad1371ec7cb34342f03d69b57bb 100644 (file)
@@ -18,6 +18,6 @@
 pub fn main() {
     unsafe {
         let _x: Foo = mem::uninitialized();
-        let _x: [Foo, ..2] = mem::uninitialized();
+        let _x: [Foo2] = mem::uninitialized();
     }
 }
index e5e6ce6e76bb6dc3391a1010ae6c01852ad68944..271f5817c9e79fd0a3c90012fe8bf9f804ae2524 100644 (file)
@@ -60,7 +60,7 @@ pub fn main() {
 
     unsafe {
         struct Foo_<T> {
-            f: [T, ..3]
+            f: [T3]
         }
 
         let data = box Foo_{f: [1i32, 2, 3] };
@@ -72,7 +72,7 @@ struct Foo_<T> {
 
         struct Baz_ {
             f1: uint,
-            f2: [u8, ..5],
+            f2: [u85],
         }
 
         let data = box Baz_{ f1: 42, f2: ['a' as u8, 'b' as u8, 'c' as u8, 'd' as u8, 'e' as u8] };
index aa71de2123c7d596c9ef32d629350ed6e06903ae..f8eef98856114a9e1703ba5a044ac2a9b5971377 100644 (file)
@@ -19,7 +19,7 @@
 }
 
 unsafe fn check<T>(expected: &str, f: |*mut c_char| -> T) {
-    let mut x = [0 as c_char, ..50];
+    let mut x = [0 as c_char50];
     f(&mut x[0] as *mut c_char);
     let res = CString::new(&x[0], false);
     assert_eq!(expected, res.as_str().unwrap());
index d8bf0a5c627f68f29fd3358512fe7263fd862a64..4a36231e72b0af44aead25b0212a3a96ccdcd056 100644 (file)
@@ -9,9 +9,9 @@
 // except according to those terms.
 
 pub fn main() {
-    // Tests for indexing into box/& [T, ..n]
-    let x: [int, ..3] = [1, 2, 3];
-    let mut x: Box<[int, ..3]> = box x;
+    // Tests for indexing into box/& [Tn]
+    let x: [int3] = [1, 2, 3];
+    let mut x: Box<[int3]> = box x;
     assert!(x[0] == 1);
     assert!(x[1] == 2);
     assert!(x[2] == 3);
@@ -20,8 +20,8 @@ pub fn main() {
     assert!(x[1] == 45);
     assert!(x[2] == 3);
 
-    let mut x: [int, ..3] = [1, 2, 3];
-    let x: &mut [int, ..3] = &mut x;
+    let mut x: [int3] = [1, 2, 3];
+    let x: &mut [int3] = &mut x;
     assert!(x[0] == 1);
     assert!(x[1] == 2);
     assert!(x[2] == 3);
index 05a7388b5e2c401136a88adaa3d2442fd937d237..20e1becd008a52d2215b7068f658b2ad97c40cbb 100644 (file)
 use std::mem::size_of;
 
 pub fn main() {
-    let x: [int, ..4] = [1, 2, 3, 4];
+    let x: [int4] = [1, 2, 3, 4];
     assert_eq!(x[0], 1);
     assert_eq!(x[1], 2);
     assert_eq!(x[2], 3);
     assert_eq!(x[3], 4);
 
-    assert_eq!(size_of::<[u8, ..4]>(), 4u);
+    assert_eq!(size_of::<[u84]>(), 4u);
 
     // FIXME #10183
     // FIXME #18069
     //if cfg!(target_word_size = "64") {
-    //    assert_eq!(size_of::<[u8, ..(1 << 32)]>(), (1u << 32));
+    //    assert_eq!(size_of::<[u8(1 << 32)]>(), (1u << 32));
     //}
 }
index 18ccd8c96ab6c95316474933dfeba64fd2362838..97a443cb3b8e0fc0c6c55a7165e11b1b7eda03e7 100644 (file)
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub fn main() { let _a = [0i, ..1 as uint]; }
+pub fn main() { let _a = [0i1 as uint]; }
index c969e66957ccb752d4aa4f2a1c39b2aaa8bfe991..fe89c7532eebcc0ad429e6a9af5f2fd17a7e045c 100644 (file)
@@ -14,7 +14,7 @@
 
 const REPEATS: uint = 5;
 const MAX_LEN: uint = 32;
-static drop_counts: [AtomicUint, .. MAX_LEN] =
+static drop_counts: [AtomicUint MAX_LEN] =
     // FIXME #5244: AtomicUint is not Copy.
     [
         INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT,
diff --git a/src/test/run-pass/where-clause-early-bound-lifetimes.rs b/src/test/run-pass/where-clause-early-bound-lifetimes.rs
new file mode 100644 (file)
index 0000000..cade99b
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait TheTrait { }
+
+impl TheTrait for &'static int { }
+
+fn foo<'a,T>(_: &'a T) where &'a T : TheTrait { }
+
+fn bar<T>(_: &'static T) where &'static T : TheTrait { }
+
+fn main() {
+    static x: int = 1;
+    foo(&x);
+    bar(&x);
+}
diff --git a/src/test/run-pass/where-clause-method-substituion.rs b/src/test/run-pass/where-clause-method-substituion.rs
new file mode 100644 (file)
index 0000000..b391df8
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait Foo<T> {}
+
+trait Bar<A> {
+    fn method<B>(&self) where A: Foo<B>;
+}
+
+struct S;
+struct X;
+
+impl Foo<S> for X {}
+
+impl Bar<X> for int {
+    fn method<U>(&self) where X: Foo<U> {
+    }
+}
+
+fn main() {
+    1.method::<S>();
+}
+
diff --git a/src/test/run-pass/where-clause-region-outlives.rs b/src/test/run-pass/where-clause-region-outlives.rs
new file mode 100644 (file)
index 0000000..1ecb4b6
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct A<'a, 'b> where 'a : 'b { x: &'a int, y: &'b int }
+
+fn main() {
+    let x = 1i;
+    let y = 1i;
+    let a = A { x: &x, y: &y };
+}
diff --git a/src/test/run-pass/where-clauses-method.rs b/src/test/run-pass/where-clauses-method.rs
new file mode 100644 (file)
index 0000000..2b87bcd
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that a where clause attached to a method allows us to add
+// additional constraints to a parameter out of scope.
+
+struct Foo<T> {
+    value: T
+}
+
+impl<T> Foo<T> {
+    fn equals(&self, u: &Foo<T>) -> bool where T : Eq {
+        self.value == u.value
+    }
+}
+
+fn main() {
+    let x = Foo { value: 1i };
+    let y = Foo { value: 2i };
+    println!("{}", x.equals(&x));
+    println!("{}", x.equals(&y));
+}
diff --git a/src/test/run-pass/where-clauses-not-parameter.rs b/src/test/run-pass/where-clauses-not-parameter.rs
new file mode 100644 (file)
index 0000000..bc5fc38
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn equal<T>(_: &T, _: &T) -> bool where int : Eq {
+    true
+}
+
+fn main() {
+    equal(&0i, &0i);
+}