]> git.lizzy.rs Git - rust.git/commitdiff
rollup merge of #20350: fhahn/issue-20340-rustdoc-version
authorAlex Crichton <alex@alexcrichton.com>
Wed, 31 Dec 2014 00:26:24 +0000 (16:26 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Wed, 31 Dec 2014 00:26:24 +0000 (16:26 -0800)
Patch for #20340. `rustdoc --version` panics because it uses `rustc_driver::version`, which in turn checks the `verbose` flag, which was not defined for rustdoc.  In this patch I have added a verbose flag to rustdoc, because I think it should be useful for other things besides --version.

Another possible fix would be to check if a verbose option was defined in `rustc_driver` or add an extra `version` function for rustdoc.

187 files changed:
mk/clean.mk
mk/debuggers.mk
mk/dist.mk
mk/main.mk
mk/prepare.mk
src/compiletest/runtest.rs
src/doc/guide.md
src/etc/gdb_load_rust_pretty_printers.py [new file with mode: 0644]
src/etc/rust-gdb [new file with mode: 0755]
src/grammar/README.md
src/grammar/RustLexer.g4
src/grammar/check.sh
src/liballoc/arc.rs
src/liballoc/boxed.rs
src/liballoc/rc.rs
src/libcollections/binary_heap.rs
src/libcollections/bit.rs
src/libcollections/btree/map.rs
src/libcollections/btree/node.rs
src/libcollections/dlist.rs
src/libcollections/enum_set.rs
src/libcollections/ring_buf.rs
src/libcollections/slice.rs
src/libcollections/string.rs
src/libcollections/vec.rs
src/libcollections/vec_map.rs
src/libcore/array.rs
src/libcore/atomic.rs
src/libcore/borrow.rs
src/libcore/cell.rs
src/libcore/char.rs
src/libcore/cmp.rs
src/libcore/ptr.rs
src/libcore/slice.rs
src/libcore/str/mod.rs
src/libcore/tuple.rs
src/liblog/lib.rs
src/libregex/re.rs
src/librustc/lint/builtin.rs
src/librustc_llvm/lib.rs
src/librustc_resolve/build_reduced_graph.rs [new file with mode: 0644]
src/librustc_resolve/lib.rs
src/librustc_resolve/record_exports.rs
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/closure.rs
src/librustc_trans/trans/debuginfo.rs
src/librustc_typeck/check/vtable.rs
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/io/fs.rs
src/libstd/io/net/addrinfo.rs
src/libstd/io/stdio.rs
src/libstd/io/util.rs
src/libstd/lib.rs
src/libstd/rand/os.rs
src/libstd/rt/at_exit_imp.rs
src/libstd/rt/mod.rs
src/libstd/rt/unwind.rs
src/libstd/sync/atomic.rs
src/libstd/sys/common/helper_thread.rs
src/libstd/sys/common/mod.rs
src/libstd/sys/common/mutex.rs
src/libstd/sys/common/net.rs
src/libstd/sys/common/rwlock.rs
src/libstd/sys/common/stack.rs
src/libstd/sys/common/thread_info.rs
src/libstd/sys/common/thread_local.rs
src/libstd/sys/unix/backtrace.rs
src/libstd/sys/unix/c.rs
src/libstd/sys/unix/mod.rs
src/libstd/sys/unix/mutex.rs
src/libstd/sys/unix/os.rs
src/libstd/sys/unix/pipe.rs
src/libstd/sys/unix/process.rs
src/libstd/sys/unix/rwlock.rs
src/libstd/sys/unix/stack_overflow.rs
src/libstd/sys/unix/tcp.rs
src/libstd/sys/unix/timer.rs
src/libstd/sys/unix/tty.rs
src/libstd/sys/windows/backtrace.rs
src/libstd/sys/windows/c.rs
src/libstd/sys/windows/fs.rs
src/libstd/sys/windows/mod.rs
src/libstd/sys/windows/os.rs
src/libstd/sys/windows/pipe.rs
src/libstd/sys/windows/process.rs
src/libstd/sys/windows/stack_overflow.rs
src/libstd/sys/windows/tcp.rs
src/libstd/sys/windows/thread.rs
src/libstd/sys/windows/thread_local.rs
src/libstd/sys/windows/timer.rs
src/libstd/sys/windows/tty.rs
src/libstd/thread.rs
src/rustllvm/RustWrapper.cpp
src/test/compile-fail/trait-object-safety.rs [new file with mode: 0644]
src/test/debuginfo/basic-types-globals-metadata.rs
src/test/debuginfo/basic-types-globals.rs
src/test/debuginfo/basic-types-metadata.rs
src/test/debuginfo/basic-types-mut-globals.rs
src/test/debuginfo/basic-types.rs
src/test/debuginfo/borrowed-basic.rs
src/test/debuginfo/borrowed-c-style-enum.rs
src/test/debuginfo/borrowed-enum.rs
src/test/debuginfo/borrowed-struct.rs
src/test/debuginfo/borrowed-tuple.rs
src/test/debuginfo/borrowed-unique-basic.rs
src/test/debuginfo/box.rs
src/test/debuginfo/boxed-struct.rs
src/test/debuginfo/by-value-non-immediate-argument.rs
src/test/debuginfo/by-value-self-argument-in-trait-impl.rs
src/test/debuginfo/c-style-enum-in-composite.rs
src/test/debuginfo/c-style-enum.rs
src/test/debuginfo/closure-in-generic-function.rs
src/test/debuginfo/destructured-fn-argument.rs
src/test/debuginfo/destructured-for-loop-variable.rs
src/test/debuginfo/destructured-local.rs
src/test/debuginfo/evec-in-struct.rs
src/test/debuginfo/function-arg-initialization.rs
src/test/debuginfo/function-arguments.rs
src/test/debuginfo/function-prologue-stepping-no-stack-check.rs
src/test/debuginfo/function-prologue-stepping-regular.rs
src/test/debuginfo/gdb-pretty-struct-and-enums-pre-gdb-7-7.rs
src/test/debuginfo/gdb-pretty-struct-and-enums.rs
src/test/debuginfo/generic-function.rs
src/test/debuginfo/generic-functions-nested.rs
src/test/debuginfo/generic-method-on-generic-struct.rs
src/test/debuginfo/generic-static-method-on-struct-and-enum.rs
src/test/debuginfo/generic-struct-style-enum.rs
src/test/debuginfo/generic-struct.rs
src/test/debuginfo/generic-trait-generic-static-default-method.rs
src/test/debuginfo/generic-tuple-style-enum.rs
src/test/debuginfo/include_string.rs
src/test/debuginfo/issue12886.rs
src/test/debuginfo/lexical-scope-in-for-loop.rs
src/test/debuginfo/lexical-scope-in-if.rs
src/test/debuginfo/lexical-scope-in-match.rs
src/test/debuginfo/lexical-scope-in-stack-closure.rs
src/test/debuginfo/lexical-scope-in-unconditional-loop.rs
src/test/debuginfo/lexical-scope-in-unique-closure.rs
src/test/debuginfo/lexical-scope-in-while.rs
src/test/debuginfo/lexical-scope-with-macro.rs
src/test/debuginfo/lexical-scopes-in-block-expression.rs
src/test/debuginfo/limited-debuginfo.rs
src/test/debuginfo/method-on-enum.rs
src/test/debuginfo/method-on-generic-struct.rs
src/test/debuginfo/method-on-struct.rs
src/test/debuginfo/method-on-trait.rs
src/test/debuginfo/method-on-tuple-struct.rs
src/test/debuginfo/multiple-functions-equal-var-names.rs
src/test/debuginfo/multiple-functions.rs
src/test/debuginfo/name-shadowing-and-scope-nesting.rs
src/test/debuginfo/nil-enum.rs
src/test/debuginfo/no-debug-attribute.rs
src/test/debuginfo/option-like-enum.rs
src/test/debuginfo/packed-struct-with-destructor.rs
src/test/debuginfo/packed-struct.rs
src/test/debuginfo/recursive-enum.rs
src/test/debuginfo/recursive-struct.rs
src/test/debuginfo/self-in-default-method.rs
src/test/debuginfo/self-in-generic-default-method.rs
src/test/debuginfo/shadowed-argument.rs
src/test/debuginfo/shadowed-variable.rs
src/test/debuginfo/simd.rs
src/test/debuginfo/simple-lexical-scope.rs
src/test/debuginfo/simple-struct.rs
src/test/debuginfo/simple-tuple.rs
src/test/debuginfo/static-method-on-struct-and-enum.rs
src/test/debuginfo/struct-in-enum.rs
src/test/debuginfo/struct-in-struct.rs
src/test/debuginfo/struct-style-enum.rs
src/test/debuginfo/struct-with-destructor.rs
src/test/debuginfo/trait-generic-static-default-method.rs
src/test/debuginfo/trait-pointers.rs
src/test/debuginfo/tuple-in-struct.rs
src/test/debuginfo/tuple-in-tuple.rs
src/test/debuginfo/tuple-struct.rs
src/test/debuginfo/tuple-style-enum.rs
src/test/debuginfo/type-names.rs
src/test/debuginfo/unique-enum.rs
src/test/debuginfo/var-captured-in-nested-closure.rs
src/test/debuginfo/var-captured-in-sendable-closure.rs
src/test/debuginfo/var-captured-in-stack-closure.rs
src/test/debuginfo/vec-slices.rs
src/test/debuginfo/vec.rs
src/test/run-pass/trait-object-safety.rs

index aadc55ba6c4977dda86d5e5567c1ea6a8681b108..5b90d41ceeceb85c5e1ed457f054032149d39bc1 100644 (file)
@@ -64,6 +64,7 @@ clean-generic-$(2)-$(1):
          -name '*.dll' -o \
          -name '*.def' -o \
          -name '*.py' -o \
+         -name '*.pyc' -o \
          -name '*.bc' \
          \) \
          | xargs rm -f
@@ -79,7 +80,7 @@ define CLEAN_HOST_STAGE_N
 
 clean$(1)_H_$(2): \
            $$(foreach crate,$$(CRATES),clean$(1)_H_$(2)-lib-$$(crate)) \
-           $$(foreach tool,$$(TOOLS) $$(DEBUGGER_BIN_SCRIPTS),clean$(1)_H_$(2)-tool-$$(tool))
+           $$(foreach tool,$$(TOOLS) $$(DEBUGGER_BIN_SCRIPTS_ALL),clean$(1)_H_$(2)-tool-$$(tool))
        $$(Q)rm -fr $(2)/rt/libbacktrace
 
 clean$(1)_H_$(2)-tool-%:
@@ -99,7 +100,7 @@ define CLEAN_TARGET_STAGE_N
 
 clean$(1)_T_$(2)_H_$(3): \
            $$(foreach crate,$$(CRATES),clean$(1)_T_$(2)_H_$(3)-lib-$$(crate)) \
-           $$(foreach tool,$$(TOOLS) $$(DEBUGGER_BIN_SCRIPTS),clean$(1)_T_$(2)_H_$(3)-tool-$$(tool))
+           $$(foreach tool,$$(TOOLS) $$(DEBUGGER_BIN_SCRIPTS_ALL),clean$(1)_T_$(2)_H_$(3)-tool-$$(tool))
        $$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a
        $$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/libcompiler-rt.a
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/librun_pass_stage* # For unix
index 54955f06295fc168eb069bb170601d02ed96a54b..899cc42d066e4a2032a37a5646925fecb7e913d2 100644 (file)
 # Copy debugger related scripts
 ######################################################################
 
-DEBUGGER_RUSTLIB_ETC_SCRIPTS=lldb_rust_formatters.py
-DEBUGGER_BIN_SCRIPTS=rust-lldb
 
-DEBUGGER_RUSTLIB_ETC_SCRIPTS_ABS=$(foreach script,$(DEBUGGER_RUSTLIB_ETC_SCRIPTS), \
-                                     $(CFG_SRC_DIR)src/etc/$(script))
-DEBUGGER_BIN_SCRIPTS_ABS=$(foreach script,$(DEBUGGER_BIN_SCRIPTS), \
-                             $(CFG_SRC_DIR)src/etc/$(script))
+## GDB ##
+DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB=gdb_load_rust_pretty_printers.py \
+                                 gdb_rust_pretty_printing.py
+DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS=\
+    $(foreach script,$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB), \
+        $(CFG_SRC_DIR)src/etc/$(script))
+
+DEBUGGER_BIN_SCRIPTS_GDB=rust-gdb
+DEBUGGER_BIN_SCRIPTS_GDB_ABS=\
+    $(foreach script,$(DEBUGGER_BIN_SCRIPTS_GDB), \
+        $(CFG_SRC_DIR)src/etc/$(script))
+
+
+## LLDB ##
+DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB=lldb_rust_formatters.py
+DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS=\
+    $(foreach script,$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB), \
+        $(CFG_SRC_DIR)src/etc/$(script))
+
+DEBUGGER_BIN_SCRIPTS_LLDB=rust-lldb
+DEBUGGER_BIN_SCRIPTS_LLDB_ABS=\
+    $(foreach script,$(DEBUGGER_BIN_SCRIPTS_LLDB), \
+        $(CFG_SRC_DIR)src/etc/$(script))
+
+
+## ALL ##
+DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL=$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB) \
+                                 $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB)
+DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS=$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) \
+                                     $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS)
+DEBUGGER_BIN_SCRIPTS_ALL=$(DEBUGGER_BIN_SCRIPTS_GDB) \
+                         $(DEBUGGER_BIN_SCRIPTS_LLDB)
+DEBUGGER_BIN_SCRIPTS_ALL_ABS=$(DEBUGGER_BIN_SCRIPTS_GDB_ABS) \
+                             $(DEBUGGER_BIN_SCRIPTS_LLDB_ABS)
 
-DEBUGGER_SCRIPTS_ALL=$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ABS) $(DEBUGGER_BIN_SCRIPTS_ABS)
 
 # $(1) - the stage to copy to
 # $(2) - the host triple
 define DEF_INSTALL_DEBUGGER_SCRIPTS_HOST
 
-tmp/install-debugger-scripts$(1)_H_$(2).done: $$(DEBUGGER_SCRIPTS_ALL)
+tmp/install-debugger-scripts$(1)_H_$(2)-gdb.done: \
+  $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) \
+  $$(DEBUGGER_BIN_SCRIPTS_GDB_ABS)
+       $(Q)mkdir -p $$(HBIN$(1)_H_$(2))
+       $(Q)mkdir -p $$(HLIB$(1)_H_$(2))/rustlib/etc
+       $(Q)install $$(DEBUGGER_BIN_SCRIPTS_GDB_ABS) $$(HBIN$(1)_H_$(2))
+       $(Q)install $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) $$(HLIB$(1)_H_$(2))/rustlib/etc
+       $(Q)touch $$@
+
+tmp/install-debugger-scripts$(1)_H_$(2)-lldb.done: \
+  $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) \
+  $$(DEBUGGER_BIN_SCRIPTS_LLDB_ABS)
+       $(Q)mkdir -p $$(HBIN$(1)_H_$(2))
+       $(Q)mkdir -p $$(HLIB$(1)_H_$(2))/rustlib/etc
+       $(Q)install $$(DEBUGGER_BIN_SCRIPTS_LLDB_ABS) $$(HBIN$(1)_H_$(2))
+       $(Q)install $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) $$(HLIB$(1)_H_$(2))/rustlib/etc
+       $(Q)touch $$@
+
+tmp/install-debugger-scripts$(1)_H_$(2)-all.done: \
+  $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) \
+  $$(DEBUGGER_BIN_SCRIPTS_ALL_ABS)
        $(Q)mkdir -p $$(HBIN$(1)_H_$(2))
        $(Q)mkdir -p $$(HLIB$(1)_H_$(2))/rustlib/etc
-       $(Q)install $(DEBUGGER_BIN_SCRIPTS_ABS) $$(HBIN$(1)_H_$(2))
-       $(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ABS) $$(HLIB$(1)_H_$(2))/rustlib/etc
+       $(Q)install $$(DEBUGGER_BIN_SCRIPTS_ALL_ABS) $$(HBIN$(1)_H_$(2))
+       $(Q)install $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) $$(HLIB$(1)_H_$(2))/rustlib/etc
        $(Q)touch $$@
+
+tmp/install-debugger-scripts$(1)_H_$(2)-none.done:
+       $(Q)touch $$@
+
 endef
 
 # Expand host make-targets for all stages
@@ -44,12 +95,36 @@ $(foreach stage,$(STAGES), \
 # $(3) is the host triple
 define DEF_INSTALL_DEBUGGER_SCRIPTS_TARGET
 
-tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3).done: $$(DEBUGGER_SCRIPTS_ALL)
+tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-gdb.done: \
+  $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) \
+  $$(DEBUGGER_BIN_SCRIPTS_GDB_ABS)
+       $(Q)mkdir -p $$(TBIN$(1)_T_$(2)_H_$(3))
+       $(Q)mkdir -p $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
+       $(Q)install $(DEBUGGER_BIN_SCRIPTS_GDB_ABS) $$(TBIN$(1)_T_$(2)_H_$(3))
+       $(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
+       $(Q)touch $$@
+
+tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-lldb.done: \
+  $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) \
+  $$(DEBUGGER_BIN_SCRIPTS_LLDB_ABS)
        $(Q)mkdir -p $$(TBIN$(1)_T_$(2)_H_$(3))
        $(Q)mkdir -p $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
-       $(Q)install $(DEBUGGER_BIN_SCRIPTS_ABS) $$(TBIN$(1)_T_$(2)_H_$(3))
-       $(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ABS) $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
+       $(Q)install $(DEBUGGER_BIN_SCRIPTS_LLDB_ABS) $$(TBIN$(1)_T_$(2)_H_$(3))
+       $(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
        $(Q)touch $$@
+
+tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-all.done: \
+  $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) \
+  $$(DEBUGGER_BIN_SCRIPTS_ALL_ABS)
+       $(Q)mkdir -p $$(TBIN$(1)_T_$(2)_H_$(3))
+       $(Q)mkdir -p $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
+       $(Q)install $(DEBUGGER_BIN_SCRIPTS_ALL_ABS) $$(TBIN$(1)_T_$(2)_H_$(3))
+       $(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
+       $(Q)touch $$@
+
+tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-none.done:
+       $(Q)touch $$@
+
 endef
 
 # Expand target make-targets for all stages
index 963627dbe099723f16c3cf12512f33d2d6815154..833750665e4fb4a73a15f8b962a157e9eeb1446c 100644 (file)
@@ -35,7 +35,7 @@ LICENSE.txt: $(S)COPYRIGHT $(S)LICENSE-APACHE $(S)LICENSE-MIT
 # Source tarball
 ######################################################################
 
-PKG_TAR = dist/$(PKG_NAME).tar.gz
+PKG_TAR = dist/$(PKG_NAME)-src.tar.gz
 
 PKG_GITMODULES := $(S)src/llvm $(S)src/compiler-rt \
                  $(S)src/rt/hoedown $(S)src/jemalloc
index 4aed1cea9ca0987dd637ffbdd1a5fdac70e2307c..32167dfd8999019c5b5ee13bd23611ce8e0b6587 100644 (file)
@@ -15,6 +15,9 @@
 # The version number
 CFG_RELEASE_NUM=0.13.0
 
+# An optional number to put after the label, e.g. '2' -> '-beta2'
+CFG_BETA_CYCLE=
+
 CFG_FILENAME_EXTRA=4e7c5e5c
 
 ifeq ($(CFG_RELEASE_CHANNEL),stable)
@@ -24,12 +27,13 @@ CFG_RELEASE=$(CFG_RELEASE_NUM)
 CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)
 endif
 ifeq ($(CFG_RELEASE_CHANNEL),beta)
-CFG_RELEASE=$(CFG_RELEASE_NUM)-beta
+# The beta channel is temporarily called 'alpha'
+CFG_RELEASE=$(CFG_RELEASE_NUM)-alpha$(CFG_BETA_CYCLE)
 # When building beta/nightly distributables just reuse the same "beta"
 # name so when we upload we'll always override the previous
 # nighly. This doesn't actually impact the version reported by rustc -
 # it's just for file naming.
-CFG_PACKAGE_VERS=beta
+CFG_PACKAGE_VERS=alpha
 endif
 ifeq ($(CFG_RELEASE_CHANNEL),nightly)
 CFG_RELEASE=$(CFG_RELEASE_NUM)-nightly
@@ -325,6 +329,12 @@ export CFG_DISABLE_INJECT_STD_VERSION
 # Per-stage targets and runner
 ######################################################################
 
+# Valid setting-strings are 'all', 'none', 'gdb', 'lldb'
+# This 'function' will determine which debugger scripts to copy based on a
+# target triple. See debuggers.mk for more information.
+TRIPLE_TO_DEBUGGER_SCRIPT_SETTING=\
+ $(if $(findstring windows,$(1)),none,$(if $(findstring darwin,$(1)),lldb,gdb))
+
 STAGES = 0 1 2 3
 
 define SREQ
@@ -357,7 +367,7 @@ else
 HSREQ$(1)_H_$(3) = \
        $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
        $$(MKFILE_DEPS) \
-       tmp/install-debugger-scripts$(1)_H_$(3).done
+       tmp/install-debugger-scripts$(1)_H_$(3)-$$(call TRIPLE_TO_DEBUGGER_SCRIPT_SETTING,$(3)).done
 endif
 
 # Prerequisites for using the stageN compiler to build target artifacts
@@ -372,7 +382,7 @@ SREQ$(1)_T_$(2)_H_$(3) = \
        $$(TSREQ$(1)_T_$(2)_H_$(3)) \
        $$(foreach dep,$$(TARGET_CRATES), \
            $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(dep)) \
-       tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3).done
+       tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-$$(call TRIPLE_TO_DEBUGGER_SCRIPT_SETTING,$(2)).done
 
 # Prerequisites for a working stageN compiler and complete set of target
 # libraries
index d404d3d2950e04a931740f3e926975ad4f97efd2..52fbbef81bd78e4098fd9ecafd1b3981f1ea70c6 100644 (file)
@@ -144,6 +144,27 @@ prepare-target-$(2)-host-$(3)-$(1)-$(4): prepare-maybe-clean-$(4) \
           $$(call PREPARE_LIB,libcompiler-rt.a),),),)
 endef
 
+define INSTALL_GDB_DEBUGGER_SCRIPTS_COMMANDS
+       $(Q)$(PREPARE_BIN_CMD) $(DEBUGGER_BIN_SCRIPTS_GDB_ABS) $(PREPARE_DEST_BIN_DIR)
+       $(Q)$(PREPARE_LIB_CMD) $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) $(PREPARE_DEST_LIB_DIR)/rustlib/etc
+endef
+
+define INSTALL_LLDB_DEBUGGER_SCRIPTS_COMMANDS
+       $(Q)$(PREPARE_BIN_CMD) $(DEBUGGER_BIN_SCRIPTS_LLDB_ABS) $(PREPARE_DEST_BIN_DIR)
+       $(Q)$(PREPARE_LIB_CMD) $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) $(PREPARE_DEST_LIB_DIR)/rustlib/etc
+endef
+
+define INSTALL_NO_DEBUGGER_SCRIPTS_COMMANDS
+       $(Q)echo "No debugger scripts will be installed for host $(PREPARE_HOST)"
+endef
+
+# $(1) is PREPARE_HOST
+INSTALL_DEBUGGER_SCRIPT_COMMANDS=$(if $(findstring windows,$(1)),\
+                                   $(INSTALL_NO_DEBUGGER_SCRIPTS_COMMANDS),\
+                                   $(if $(findstring darwin,$(1)),\
+                                     $(INSTALL_LLDB_DEBUGGER_SCRIPTS_COMMANDS),\
+                                     $(INSTALL_GDB_DEBUGGER_SCRIPTS_COMMANDS)))
+
 define DEF_PREPARE
 
 prepare-base-$(1): PREPARE_SOURCE_DIR=$$(PREPARE_HOST)/stage$$(PREPARE_STAGE)
@@ -170,9 +191,10 @@ prepare-host-dirs-$(1): prepare-maybe-clean-$(1)
        $$(call PREPARE_DIR,$$(PREPARE_DEST_LIB_DIR)/rustlib/etc)
        $$(call PREPARE_DIR,$$(PREPARE_DEST_MAN_DIR))
 
-prepare-debugger-scripts-$(1): prepare-host-dirs-$(1) $(DEBUGGER_SCRIPTS_ALL)
-       $$(Q)$$(PREPARE_BIN_CMD) $(DEBUGGER_BIN_SCRIPTS_ABS) $$(PREPARE_DEST_BIN_DIR)
-       $$(Q)$$(PREPARE_LIB_CMD) $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ABS) $$(PREPARE_DEST_LIB_DIR)/rustlib/etc
+prepare-debugger-scripts-$(1): prepare-host-dirs-$(1) \
+                               $$(DEBUGGER_BIN_SCRIPTS_ALL_ABS) \
+                               $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS)
+       $$(call INSTALL_DEBUGGER_SCRIPT_COMMANDS,$$(PREPARE_HOST))
 
 $$(foreach tool,$$(PREPARE_TOOLS), \
   $$(foreach host,$$(CFG_HOST), \
index 1abcd8bd214075ecd264622abeea789b207264ab..6bc34f1eb2c60da030ecc0e51bb8b64afd280dfe 100644 (file)
@@ -367,7 +367,6 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
     let DebuggerCommands {
         commands,
         check_lines,
-        use_gdb_pretty_printer,
         breakpoint_lines
     } = parse_debugger_commands(testfile, "gdb");
     let mut cmds = commands.connect("\n");
@@ -521,16 +520,11 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
                     if header::gdb_version_to_int(version.as_slice()) >
                         header::gdb_version_to_int("7.4") {
                         // Add the directory containing the pretty printers to
-                        // GDB's script auto loading safe path ...
+                        // GDB's script auto loading safe path
                         script_str.push_str(
                             format!("add-auto-load-safe-path {}\n",
                                     rust_pp_module_abs_path.replace("\\", "\\\\").as_slice())
                                 .as_slice());
-                        // ... and also the test directory
-                        script_str.push_str(
-                            format!("add-auto-load-safe-path {}\n",
-                                    config.build_base.as_str().unwrap().replace("\\", "\\\\"))
-                                .as_slice());
                     }
                 }
                 _ => {
@@ -543,6 +537,9 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
             // pretty printing, it just tells GDB to print values on one line:
             script_str.push_str("set print pretty off\n");
 
+            // Add the pretty printer directory to GDB's source-file search path
+            script_str.push_str(format!("directory {}\n", rust_pp_module_abs_path)[]);
+
             // Load the target executable
             script_str.push_str(format!("file {}\n",
                                         exe_file.as_str().unwrap().replace("\\", "\\\\"))
@@ -564,12 +561,6 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
                              script_str.as_slice(),
                              "debugger.script");
 
-            if use_gdb_pretty_printer {
-                // Only emit the gdb auto-loading script if pretty printers
-                // should actually be loaded
-                dump_gdb_autoload_script(config, testfile);
-            }
-
             // run debugger script with gdb
             #[cfg(windows)]
             fn debugger() -> String {
@@ -611,19 +602,6 @@ fn debugger() -> String {
     }
 
     check_debugger_output(&debugger_run_result, check_lines.as_slice());
-
-    fn dump_gdb_autoload_script(config: &Config, testfile: &Path) {
-        let mut script_path = output_base_name(config, testfile);
-        let mut script_file_name = script_path.filename().unwrap().to_vec();
-        script_file_name.push_all("-gdb.py".as_bytes());
-        script_path.set_filename(script_file_name.as_slice());
-
-        let script_content = "import gdb_rust_pretty_printing\n\
-                              gdb_rust_pretty_printing.register_printers(gdb.current_objfile())\n"
-                             .as_bytes();
-
-        File::create(&script_path).write(script_content).unwrap();
-    }
 }
 
 fn find_rust_src_root(config: &Config) -> Option<Path> {
@@ -781,7 +759,6 @@ struct DebuggerCommands {
     commands: Vec<String>,
     check_lines: Vec<String>,
     breakpoint_lines: Vec<uint>,
-    use_gdb_pretty_printer: bool
 }
 
 fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str)
@@ -794,7 +771,6 @@ fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str)
     let mut breakpoint_lines = vec!();
     let mut commands = vec!();
     let mut check_lines = vec!();
-    let mut use_gdb_pretty_printer = false;
     let mut counter = 1;
     let mut reader = BufferedReader::new(File::open(file_path).unwrap());
     for line in reader.lines() {
@@ -804,10 +780,6 @@ fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str)
                     breakpoint_lines.push(counter);
                 }
 
-                if line.as_slice().contains("gdb-use-pretty-printer") {
-                    use_gdb_pretty_printer = true;
-                }
-
                 header::parse_name_value_directive(
                         line.as_slice(),
                         command_directive.as_slice()).map(|cmd| {
@@ -832,7 +804,6 @@ fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str)
         commands: commands,
         check_lines: check_lines,
         breakpoint_lines: breakpoint_lines,
-        use_gdb_pretty_printer: use_gdb_pretty_printer,
     }
 }
 
index d094c47da93bb3f1386e61ae2dd9d210cdf23e0a..fe65f4bd7f53d1277223187511e06ff1ac2d6860 100644 (file)
@@ -460,7 +460,7 @@ x = 10i;
 There is no single reason that bindings are immutable by default, but we can
 think about it through one of Rust's primary focuses: safety. If you forget to
 say `mut`, the compiler will catch it, and let you know that you have mutated
-something you may not have cared to mutate. If bindings were mutable by
+something you may not have intended to mutate. If bindings were mutable by
 default, the compiler would not be able to tell you this. If you _did_ intend
 mutation, then the solution is quite easy: add `mut`.
 
@@ -889,9 +889,8 @@ fn hello(name: &str) {
 When writing doc comments, adding sections for any arguments, return values,
 and providing some examples of usage is very, very helpful.
 
-You can use the `rustdoc` tool to generate HTML documentation from these doc
-comments. We will talk more about `rustdoc` when we get to modules, as
-generally, you want to export documentation for a full module.
+You can use the [`rustdoc`](rustdoc.html) tool to generate HTML documentation
+from these doc comments.
 
 # Compound Data Types
 
diff --git a/src/etc/gdb_load_rust_pretty_printers.py b/src/etc/gdb_load_rust_pretty_printers.py
new file mode 100644 (file)
index 0000000..755cac1
--- /dev/null
@@ -0,0 +1,12 @@
+# 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.
+
+import gdb_rust_pretty_printing
+gdb_rust_pretty_printing.register_printers(gdb.current_objfile())
diff --git a/src/etc/rust-gdb b/src/etc/rust-gdb
new file mode 100755 (executable)
index 0000000..520a108
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/sh
+# 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.
+
+# Exit if anything fails
+set -e
+
+# Find out where the pretty printer Python module is
+RUSTC_SYSROOT=`rustc --print=sysroot`
+GDB_PYTHON_MODULE_DIRECTORY="$RUSTC_SYSROOT/lib/rustlib/etc"
+
+# Run GDB with the additional arguments that load the pretty printers
+PYTHONPATH="$PYTHONPATH:$GDB_PYTHON_MODULE_DIRECTORY" gdb \
+  -d "$GDB_PYTHON_MODULE_DIRECTORY" \
+  -iex "add-auto-load-safe-path $GDB_PYTHON_MODULE_DIRECTORY" \
+  "$@"
index f5b872cdc7f679511b8acafda9b3620e49e5c02f..1f7923e1caff2b81fa9e0fb9af3be99bc52249a9 100644 (file)
@@ -1,7 +1,7 @@
 Reference grammar.
 
 Uses [antlr4](http://www.antlr.org/) and a custom Rust tool to compare
-ASTs/token streams generated. You can use the `check-syntax` make target to
+ASTs/token streams generated. You can use the `check-lexer` make target to
 run all of the available tests.
 
 To use manually:
@@ -12,7 +12,7 @@ javac *.java
 rustc -O verify.rs
 for file in ../*/**.rs; do
     echo $file;
-    grun RustLexer tokens -tokens < $file | ./verify $file || break
+    grun RustLexer tokens -tokens < $file | ./verify $file RustLexer.tokens || break
 done
 ```
 
index 00af6d358e5eb3d3643592bb929db3c7adf2b275..88de5db41fe7b555369e2ff6e595e8bda6e8c650 100644 (file)
@@ -112,8 +112,64 @@ LIT_INTEGER
   ;
 
 LIT_FLOAT
-  : [0-9][0-9_]* ( '.' {_input.LA(1) != '.'}?
-                 | ('.' [0-9][0-9_]*)? ([eE] [-+]? [0-9][0-9_]*)? SUFFIX?)
+  : [0-9][0-9_]* ('.' {
+        /* dot followed by another dot is a range, no float */
+        _input.LA(1) != '.' &&
+        /* dot followed by an identifier is an integer with a function call, no float */
+        _input.LA(1) != '_' &&
+        _input.LA(1) != 'a' &&
+        _input.LA(1) != 'b' &&
+        _input.LA(1) != 'c' &&
+        _input.LA(1) != 'd' &&
+        _input.LA(1) != 'e' &&
+        _input.LA(1) != 'f' &&
+        _input.LA(1) != 'g' &&
+        _input.LA(1) != 'h' &&
+        _input.LA(1) != 'i' &&
+        _input.LA(1) != 'j' &&
+        _input.LA(1) != 'k' &&
+        _input.LA(1) != 'l' &&
+        _input.LA(1) != 'm' &&
+        _input.LA(1) != 'n' &&
+        _input.LA(1) != 'o' &&
+        _input.LA(1) != 'p' &&
+        _input.LA(1) != 'q' &&
+        _input.LA(1) != 'r' &&
+        _input.LA(1) != 's' &&
+        _input.LA(1) != 't' &&
+        _input.LA(1) != 'u' &&
+        _input.LA(1) != 'v' &&
+        _input.LA(1) != 'w' &&
+        _input.LA(1) != 'x' &&
+        _input.LA(1) != 'y' &&
+        _input.LA(1) != 'z' &&
+        _input.LA(1) != 'A' &&
+        _input.LA(1) != 'B' &&
+        _input.LA(1) != 'C' &&
+        _input.LA(1) != 'D' &&
+        _input.LA(1) != 'E' &&
+        _input.LA(1) != 'F' &&
+        _input.LA(1) != 'G' &&
+        _input.LA(1) != 'H' &&
+        _input.LA(1) != 'I' &&
+        _input.LA(1) != 'J' &&
+        _input.LA(1) != 'K' &&
+        _input.LA(1) != 'L' &&
+        _input.LA(1) != 'M' &&
+        _input.LA(1) != 'N' &&
+        _input.LA(1) != 'O' &&
+        _input.LA(1) != 'P' &&
+        _input.LA(1) != 'Q' &&
+        _input.LA(1) != 'R' &&
+        _input.LA(1) != 'S' &&
+        _input.LA(1) != 'T' &&
+        _input.LA(1) != 'U' &&
+        _input.LA(1) != 'V' &&
+        _input.LA(1) != 'W' &&
+        _input.LA(1) != 'X' &&
+        _input.LA(1) != 'Y' &&
+        _input.LA(1) != 'Z'
+  }? | ('.' [0-9][0-9_]*)? ([eE] [-+]? [0-9][0-9_]*)? SUFFIX?)
   ;
 
 LIT_STR
index f2836312437c9af80e9f3750561f2fa5c5b2f1d2..cb269bbdb0ade0dc343bc3513bc9ce82698a0119 100755 (executable)
@@ -11,6 +11,10 @@ if [ "${VERBOSE}" == "1" ]; then
     set -x
 fi
 
+passed=0
+failed=0
+skipped=0
+
 check() {
     grep --silent "// ignore-lexer-test" $1;
 
@@ -21,14 +25,27 @@ check() {
         # seem to have anny effect.
         if $3 RustLexer tokens -tokens < $1 | $4 $1 $5; then
             echo "pass: $1"
+            passed=`expr $passed + 1`
         else
             echo "fail: $1"
+            failed=`expr $failed + 1`
         fi
     else
         echo "skip: $1"
+        skipped=`expr $skipped + 1`
     fi
 }
 
 for file in $(find $1 -iname '*.rs' ! -path '*/test/compile-fail*'); do
     check $file $2 $3 $4 $5
 done
+
+printf "\ntest result: "
+
+if [ $failed -eq 0 ]; then
+    printf "ok. $passed passed; $failed failed; $skipped skipped\n\n"
+else
+    printf "failed. $passed passed; $failed failed; $skipped skipped\n\n"
+    exit 1
+fi
+
index 21c47cdf3d752129153e6d983120417650eb3410..04128f837ec12e310630a8998b65017e751deba8 100644 (file)
@@ -68,6 +68,7 @@
 //! ```
 
 use core::atomic;
+use core::atomic::Ordering::{Relaxed, Release, Acquire, SeqCst};
 use core::borrow::BorrowFrom;
 use core::clone::Clone;
 use core::fmt::{mod, Show};
@@ -182,7 +183,7 @@ pub fn new(data: T) -> Arc<T> {
     #[experimental = "Weak pointers may not belong in this module."]
     pub fn downgrade(&self) -> Weak<T> {
         // See the clone() impl for why this is relaxed
-        self.inner().weak.fetch_add(1, atomic::Relaxed);
+        self.inner().weak.fetch_add(1, Relaxed);
         Weak { _ptr: self._ptr }
     }
 }
@@ -201,12 +202,12 @@ fn inner(&self) -> &ArcInner<T> {
 /// Get the number of weak references to this value.
 #[inline]
 #[experimental]
-pub fn weak_count<T>(this: &Arc<T>) -> uint { this.inner().weak.load(atomic::SeqCst) - 1 }
+pub fn weak_count<T>(this: &Arc<T>) -> uint { this.inner().weak.load(SeqCst) - 1 }
 
 /// Get the number of strong references to this value.
 #[inline]
 #[experimental]
-pub fn strong_count<T>(this: &Arc<T>) -> uint { this.inner().strong.load(atomic::SeqCst) }
+pub fn strong_count<T>(this: &Arc<T>) -> uint { this.inner().strong.load(SeqCst) }
 
 #[stable]
 impl<T> Clone for Arc<T> {
@@ -234,7 +235,7 @@ fn clone(&self) -> Arc<T> {
         // 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);
+        self.inner().strong.fetch_add(1, Relaxed);
         Arc { _ptr: self._ptr }
     }
 }
@@ -273,8 +274,8 @@ impl<T: Send + Sync + Clone> Arc<T> {
     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.
-        if self.inner().strong.load(atomic::SeqCst) != 1 ||
-           self.inner().weak.load(atomic::SeqCst) != 1 {
+        if self.inner().strong.load(SeqCst) != 1 ||
+           self.inner().weak.load(SeqCst) != 1 {
             *self = Arc::new((**self).clone())
         }
         // This unsafety is ok because we're guaranteed that the pointer returned is the *only*
@@ -322,7 +323,7 @@ fn drop(&mut self) {
         // 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 }
+        if self.inner().strong.fetch_sub(1, 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
@@ -339,14 +340,14 @@ fn drop(&mut self) {
         // > operation before deleting the object.
         //
         // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
-        atomic::fence(atomic::Acquire);
+        atomic::fence(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).
         unsafe { drop(ptr::read(&self.inner().data)); }
 
-        if self.inner().weak.fetch_sub(1, atomic::Release) == 1 {
-            atomic::fence(atomic::Acquire);
+        if self.inner().weak.fetch_sub(1, Release) == 1 {
+            atomic::fence(Acquire);
             unsafe { deallocate(ptr as *mut u8, size_of::<ArcInner<T>>(),
                                 min_align_of::<ArcInner<T>>()) }
         }
@@ -377,9 +378,9 @@ pub fn upgrade(&self) -> Option<Arc<T>> {
         // count hits 0 is must never be above 0.
         let inner = self.inner();
         loop {
-            let n = inner.strong.load(atomic::SeqCst);
+            let n = inner.strong.load(SeqCst);
             if n == 0 { return None }
-            let old = inner.strong.compare_and_swap(n, n + 1, atomic::SeqCst);
+            let old = inner.strong.compare_and_swap(n, n + 1, SeqCst);
             if old == n { return Some(Arc { _ptr: self._ptr }) }
         }
     }
@@ -409,7 +410,7 @@ impl<T: Sync + Send> Clone for Weak<T> {
     #[inline]
     fn clone(&self) -> Weak<T> {
         // See comments in Arc::clone() for why this is relaxed
-        self.inner().weak.fetch_add(1, atomic::Relaxed);
+        self.inner().weak.fetch_add(1, Relaxed);
         Weak { _ptr: self._ptr }
     }
 }
@@ -450,15 +451,15 @@ fn drop(&mut self) {
 
         // 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);
+        if self.inner().weak.fetch_sub(1, Release) == 1 {
+            atomic::fence(Acquire);
             unsafe { deallocate(ptr as *mut u8, size_of::<ArcInner<T>>(),
                                 min_align_of::<ArcInner<T>>()) }
         }
     }
 }
 
-#[unstable = "waiting on PartialEq"]
+#[stable]
 impl<T: PartialEq> PartialEq for Arc<T> {
     /// Equality for two `Arc<T>`s.
     ///
@@ -490,7 +491,7 @@ fn eq(&self, other: &Arc<T>) -> bool { *(*self) == *(*other) }
     /// ```
     fn ne(&self, other: &Arc<T>) -> bool { *(*self) != *(*other) }
 }
-#[unstable = "waiting on PartialOrd"]
+#[stable]
 impl<T: PartialOrd> PartialOrd for Arc<T> {
     /// Partial comparison for two `Arc<T>`s.
     ///
@@ -569,11 +570,11 @@ fn gt(&self, other: &Arc<T>) -> bool { *(*self) > *(*other) }
     /// ```
     fn ge(&self, other: &Arc<T>) -> bool { *(*self) >= *(*other) }
 }
-#[unstable = "waiting on Ord"]
+#[stable]
 impl<T: Ord> Ord for Arc<T> {
     fn cmp(&self, other: &Arc<T>) -> Ordering { (**self).cmp(&**other) }
 }
-#[unstable = "waiting on Eq"]
+#[stable]
 impl<T: Eq> Eq for Arc<T> {}
 
 impl<T: fmt::Show> fmt::Show for Arc<T> {
@@ -613,7 +614,7 @@ fn drop(&mut self) {
             unsafe {
                 match *self {
                     Canary(c) => {
-                        (*c).fetch_add(1, atomic::SeqCst);
+                        (*c).fetch_add(1, SeqCst);
                     }
                 }
             }
@@ -732,7 +733,7 @@ fn drop_arc() {
         let mut canary = atomic::AtomicUint::new(0);
         let x = Arc::new(Canary(&mut canary as *mut atomic::AtomicUint));
         drop(x);
-        assert!(canary.load(atomic::Acquire) == 1);
+        assert!(canary.load(Acquire) == 1);
     }
 
     #[test]
@@ -740,9 +741,9 @@ fn drop_arc_weak() {
         let mut canary = atomic::AtomicUint::new(0);
         let arc = Arc::new(Canary(&mut canary as *mut atomic::AtomicUint));
         let arc_weak = arc.downgrade();
-        assert!(canary.load(atomic::Acquire) == 0);
+        assert!(canary.load(Acquire) == 0);
         drop(arc);
-        assert!(canary.load(atomic::Acquire) == 1);
+        assert!(canary.load(Acquire) == 1);
         drop(arc_weak);
     }
 
index 3c6b2d2cbc068904bc2f87e6aa7b844eafb9f49b..74f0599e486e1da696f2619ceaa6a0248db948e1 100644 (file)
@@ -72,12 +72,14 @@ fn clone_from(&mut self, source: &Box<T>) {
     }
 }
 
+#[stable]
 impl<Sized? T: PartialEq> PartialEq for Box<T> {
     #[inline]
     fn eq(&self, other: &Box<T>) -> bool { PartialEq::eq(&**self, &**other) }
     #[inline]
     fn ne(&self, other: &Box<T>) -> bool { PartialEq::ne(&**self, &**other) }
 }
+#[stable]
 impl<Sized? T: PartialOrd> PartialOrd for Box<T> {
     #[inline]
     fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
@@ -92,12 +94,14 @@ fn ge(&self, other: &Box<T>) -> bool { PartialOrd::ge(&**self, &**other) }
     #[inline]
     fn gt(&self, other: &Box<T>) -> bool { PartialOrd::gt(&**self, &**other) }
 }
+#[stable]
 impl<Sized? T: Ord> Ord for Box<T> {
     #[inline]
     fn cmp(&self, other: &Box<T>) -> Ordering {
         Ord::cmp(&**self, &**other)
     }
-}
+
+#[stable]}
 impl<Sized? T: Eq> Eq for Box<T> {}
 
 impl<S: hash::Writer, Sized? T: Hash<S>> Hash<S> for Box<T> {
index 214fae02ce27210e3010f41ec6cdda38c2c65fea..75d4342083b983f06505480ecf5dff78040f9dc7 100644 (file)
@@ -452,7 +452,7 @@ fn default() -> Rc<T> {
     }
 }
 
-#[unstable = "PartialEq is unstable."]
+#[stable]
 impl<T: PartialEq> PartialEq for Rc<T> {
     /// Equality for two `Rc<T>`s.
     ///
@@ -487,10 +487,10 @@ fn eq(&self, other: &Rc<T>) -> bool { **self == **other }
     fn ne(&self, other: &Rc<T>) -> bool { **self != **other }
 }
 
-#[unstable = "Eq is unstable."]
+#[stable]
 impl<T: Eq> Eq for Rc<T> {}
 
-#[unstable = "PartialOrd is unstable."]
+#[stable]
 impl<T: PartialOrd> PartialOrd for Rc<T> {
     /// Partial comparison for two `Rc<T>`s.
     ///
@@ -575,7 +575,7 @@ fn gt(&self, other: &Rc<T>) -> bool { **self > **other }
     fn ge(&self, other: &Rc<T>) -> bool { **self >= **other }
 }
 
-#[unstable = "Ord is unstable."]
+#[stable]
 impl<T: Ord> Ord for Rc<T> {
     /// Comparison for two `Rc<T>`s.
     ///
index a2f38bb667447bf01bc69748fd00614eafbe7d4a..b2dba59c977a3525bcf9836fb28b86db8c6040ff 100644 (file)
@@ -563,6 +563,13 @@ pub struct Iter <'a, T: 'a> {
     iter: slice::Iter<'a, T>,
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<'a, T> Clone for Iter<'a, T> {
+    fn clone(&self) -> Iter<'a, T> {
+        Iter { iter: self.iter.clone() }
+    }
+}
+
 impl<'a, T> Iterator<&'a T> for Iter<'a, T> {
     #[inline]
     fn next(&mut self) -> Option<&'a T> { self.iter.next() }
index 430d7210bf69b105be1a6ef4032974562548213b..74ff6d90da7a044cdc30519b5ae6dd7c11d0b57c 100644 (file)
@@ -965,6 +965,7 @@ fn clone_from(&mut self, source: &Bitv) {
     }
 }
 
+#[stable]
 impl PartialOrd for Bitv {
     #[inline]
     fn partial_cmp(&self, other: &Bitv) -> Option<Ordering> {
@@ -972,6 +973,7 @@ fn partial_cmp(&self, other: &Bitv) -> Option<Ordering> {
     }
 }
 
+#[stable]
 impl Ord for Bitv {
     #[inline]
     fn cmp(&self, other: &Bitv) -> Ordering {
@@ -997,6 +999,7 @@ fn hash(&self, state: &mut S) {
     }
 }
 
+#[stable]
 impl cmp::PartialEq for Bitv {
     #[inline]
     fn eq(&self, other: &Bitv) -> bool {
@@ -1007,9 +1010,11 @@ fn eq(&self, other: &Bitv) -> bool {
     }
 }
 
+#[stable]
 impl cmp::Eq for Bitv {}
 
 /// An iterator for `Bitv`.
+#[deriving(Clone)]
 pub struct Bits<'a> {
     bitv: &'a Bitv,
     next_idx: uint,
@@ -1129,6 +1134,7 @@ fn extend<I: Iterator<uint>>(&mut self, mut iterator: I) {
     }
 }
 
+#[stable]
 impl PartialOrd for BitvSet {
     #[inline]
     fn partial_cmp(&self, other: &BitvSet) -> Option<Ordering> {
@@ -1137,6 +1143,7 @@ fn partial_cmp(&self, other: &BitvSet) -> Option<Ordering> {
     }
 }
 
+#[stable]
 impl Ord for BitvSet {
     #[inline]
     fn cmp(&self, other: &BitvSet) -> Ordering {
@@ -1145,6 +1152,7 @@ fn cmp(&self, other: &BitvSet) -> Ordering {
     }
 }
 
+#[stable]
 impl cmp::PartialEq for BitvSet {
     #[inline]
     fn eq(&self, other: &BitvSet) -> bool {
@@ -1153,6 +1161,7 @@ fn eq(&self, other: &BitvSet) -> bool {
     }
 }
 
+#[stable]
 impl cmp::Eq for BitvSet {}
 
 impl BitvSet {
@@ -1739,12 +1748,14 @@ fn hash(&self, state: &mut S) {
 }
 
 /// An iterator for `BitvSet`.
+#[deriving(Clone)]
 pub struct BitPositions<'a> {
     set: &'a BitvSet,
     next_idx: uint
 }
 
 /// An iterator combining two `BitvSet` iterators.
+#[deriving(Clone)]
 pub struct TwoBitPositions<'a> {
     set: &'a BitvSet,
     other: &'a BitvSet,
index 65c644da3d8926dee83b3556c87237424f45ecce..a3dff3e870658d54dfbc6c5add62e59f03e666e5 100644 (file)
@@ -843,6 +843,7 @@ fn default() -> BTreeMap<K, V> {
     }
 }
 
+#[stable]
 impl<K: PartialEq, V: PartialEq> PartialEq for BTreeMap<K, V> {
     fn eq(&self, other: &BTreeMap<K, V>) -> bool {
         self.len() == other.len() &&
@@ -850,8 +851,10 @@ fn eq(&self, other: &BTreeMap<K, V>) -> bool {
     }
 }
 
+#[stable]
 impl<K: Eq, V: Eq> Eq for BTreeMap<K, V> {}
 
+#[stable]
 impl<K: PartialOrd, V: PartialOrd> PartialOrd for BTreeMap<K, V> {
     #[inline]
     fn partial_cmp(&self, other: &BTreeMap<K, V>) -> Option<Ordering> {
@@ -859,6 +862,7 @@ fn partial_cmp(&self, other: &BTreeMap<K, V>) -> Option<Ordering> {
     }
 }
 
+#[stable]
 impl<K: Ord, V: Ord> Ord for BTreeMap<K, V> {
     #[inline]
     fn cmp(&self, other: &BTreeMap<K, V>) -> Ordering {
index 2c3c546fdb7ff9c924984e491c4e625e6b17443b..1e4d3237501fe79ea990c4e26588cc50b6235c34 100644 (file)
@@ -21,6 +21,7 @@
 use core::{slice, mem, ptr, cmp, num, raw};
 use core::iter::Zip;
 use core::borrow::BorrowFrom;
+use core::ptr::Unique;
 use alloc::heap;
 
 /// Represents the result of an Insertion: either the item fit, or the node had to split
@@ -51,11 +52,11 @@ pub struct Node<K, V> {
     // These will never be null during normal usage of a `Node`. However, to avoid the need for a
     // drop flag, `Node::drop` zeroes `keys`, signaling that the `Node` has already been cleaned
     // up.
-    keys: *mut K,
-    vals: *mut V,
+    keys: Unique<K>,
+    vals: Unique<V>,
 
     // In leaf nodes, this will be null, and no space will be allocated for edges.
-    edges: *mut Node<K, V>,
+    edges: Unique<Node<K, V>>,
 
     // At any given time, there will be `_len` keys, `_len` values, and (in an internal node)
     // `_len + 1` edges. In a leaf node, there will never be any edges.
@@ -255,7 +256,7 @@ fn drop(&mut self) {
 #[unsafe_destructor]
 impl<K, V> Drop for Node<K, V> {
     fn drop(&mut self) {
-        if self.keys.is_null() {
+        if self.keys.0.is_null() {
             // We have already cleaned up this node.
             return;
         }
@@ -269,7 +270,7 @@ fn drop(&mut self) {
             self.destroy();
         }
 
-        self.keys = ptr::null_mut();
+        self.keys.0 = ptr::null_mut();
     }
 }
 
@@ -285,9 +286,9 @@ unsafe fn new_internal(capacity: uint) -> Node<K, V> {
         let (vals_offset, edges_offset) = calculate_offsets_generic::<K, V>(capacity, false);
 
         Node {
-            keys: buffer as *mut K,
-            vals: buffer.offset(vals_offset as int) as *mut V,
-            edges: buffer.offset(edges_offset as int) as *mut Node<K, V>,
+            keys: Unique(buffer as *mut K),
+            vals: Unique(buffer.offset(vals_offset as int) as *mut V),
+            edges: Unique(buffer.offset(edges_offset as int) as *mut Node<K, V>),
             _len: 0,
             _capacity: capacity,
         }
@@ -303,9 +304,9 @@ fn new_leaf(capacity: uint) -> Node<K, V> {
         let (vals_offset, _) = calculate_offsets_generic::<K, V>(capacity, true);
 
         Node {
-            keys: buffer as *mut K,
-            vals: unsafe { buffer.offset(vals_offset as int) as *mut V },
-            edges: ptr::null_mut(),
+            keys: Unique(buffer as *mut K).
+            vals: Unique(unsafe { buffer.offset(vals_offset as int) as *mut V }),
+            edges: Unique(ptr::null_mut::<u8>()),
             _len: 0,
             _capacity: capacity,
         }
@@ -314,18 +315,18 @@ fn new_leaf(capacity: uint) -> Node<K, V> {
     unsafe fn destroy(&mut self) {
         let (alignment, size) =
                 calculate_allocation_generic::<K, V>(self.capacity(), self.is_leaf());
-        heap::deallocate(self.keys as *mut u8, size, alignment);
+        heap::deallocate(self.keys.0 as *mut u8, size, alignment);
     }
 
     #[inline]
     pub fn as_slices<'a>(&'a self) -> (&'a [K], &'a [V]) {
         unsafe {(
             mem::transmute(raw::Slice {
-                data: self.keys as *const K,
+                data: self.keys.0 as *const K,
                 len: self.len()
             }),
             mem::transmute(raw::Slice {
-                data: self.vals as *const V,
+                data: self.vals.0 as *const V,
                 len: self.len()
             })
         )}
@@ -344,7 +345,7 @@ pub fn as_slices_internal<'a>(&'a self) -> (&'a [K], &'a [V], &'a [Node<K, V>])
         } else {
             unsafe {
                 mem::transmute(raw::Slice {
-                    data: self.edges as *const Node<K, V>,
+                    data: self.edges.0 as *const Node<K, V>,
                     len: self.len() + 1
                 })
             }
index d8ce79f4fe90d29c3e9f28e80cf46848cf7f3a94..9f2dcda92c02524c1ab1a420e5ce1bd02f0f1893 100644 (file)
@@ -770,6 +770,7 @@ fn extend<T: Iterator<A>>(&mut self, mut iterator: T) {
     }
 }
 
+#[stable]
 impl<A: PartialEq> PartialEq for DList<A> {
     fn eq(&self, other: &DList<A>) -> bool {
         self.len() == other.len() &&
@@ -782,14 +783,17 @@ fn ne(&self, other: &DList<A>) -> bool {
     }
 }
 
+#[stable]
 impl<A: Eq> Eq for DList<A> {}
 
+#[stable]
 impl<A: PartialOrd> PartialOrd for DList<A> {
     fn partial_cmp(&self, other: &DList<A>) -> Option<Ordering> {
         iter::order::partial_cmp(self.iter(), other.iter())
     }
 }
 
+#[stable]
 impl<A: Ord> Ord for DList<A> {
     #[inline]
     fn cmp(&self, other: &DList<A>) -> Ordering {
index fd04ce94247b7f2a352556dc0c6d519a4b4f3fae..b484fc41ff6e5bed9e43cbdc8783749e66a949de 100644 (file)
@@ -213,6 +213,16 @@ pub struct Iter<E> {
     bits: uint,
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<E> Clone for Iter<E> {
+    fn clone(&self) -> Iter<E> {
+        Iter {
+            index: self.index,
+            bits: self.bits,
+        }
+    }
+}
+
 impl<E:CLike> Iter<E> {
     fn new(bits: uint) -> Iter<E> {
         Iter { index: 0, bits: bits }
index df8e08f07a32150f4390a8fb914a01dd029629b3..7f43f8f2e0d181141466101669818f9c30f864e5 100644 (file)
@@ -48,6 +48,12 @@ pub struct RingBuf<T> {
     ptr: *mut T
 }
 
+#[stable]
+unsafe impl<T: Send> Send for RingBuf<T> {}
+
+#[stable]
+unsafe impl<T: Sync> Sync for RingBuf<T> {}
+
 #[stable]
 impl<T: Clone> Clone for RingBuf<T> {
     fn clone(&self) -> RingBuf<T> {
@@ -1129,6 +1135,17 @@ pub struct Iter<'a, T:'a> {
     head: uint
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<'a, T> Clone for Iter<'a, T> {
+    fn clone(&self) -> Iter<'a, T> {
+        Iter {
+            ring: self.ring,
+            tail: self.tail,
+            head: self.head
+        }
+    }
+}
+
 impl<'a, T> Iterator<&'a T> for Iter<'a, T> {
     #[inline]
     fn next(&mut self) -> Option<&'a T> {
@@ -1290,6 +1307,7 @@ fn next_back(&mut self) -> Option<T> {
 
 impl<'a, T: 'a> ExactSizeIterator<T> for Drain<'a, T> {}
 
+#[stable]
 impl<A: PartialEq> PartialEq for RingBuf<A> {
     fn eq(&self, other: &RingBuf<A>) -> bool {
         self.len() == other.len() &&
@@ -1297,14 +1315,17 @@ fn eq(&self, other: &RingBuf<A>) -> bool {
     }
 }
 
+#[stable]
 impl<A: Eq> Eq for RingBuf<A> {}
 
+#[stable]
 impl<A: PartialOrd> PartialOrd for RingBuf<A> {
     fn partial_cmp(&self, other: &RingBuf<A>) -> Option<Ordering> {
         iter::order::partial_cmp(self.iter(), other.iter())
     }
 }
 
+#[stable]
 impl<A: Ord> Ord for RingBuf<A> {
     #[inline]
     fn cmp(&self, other: &RingBuf<A>) -> Ordering {
index c55a8ba104ebefc86c31fd17cc2053a02f82378d..0c894d3cc46cd8701199d53717e750ec3c720fac 100644 (file)
@@ -155,6 +155,7 @@ fn connect_vec(&self, sep: &T) -> Vec<T> {
 ///
 /// The last generated swap is always (0, 1), and it returns the
 /// sequence to its initial order.
+#[deriving(Clone)]
 pub struct ElementSwaps {
     sdir: Vec<SizeDirection>,
     /// If `true`, emit the last swap that returns the sequence to initial
@@ -177,11 +178,11 @@ pub fn new(length: uint) -> ElementSwaps {
     }
 }
 
-#[deriving(Copy)]
+#[deriving(Copy, Clone)]
 enum Direction { Pos, Neg }
 
 /// An `Index` and `Direction` together.
-#[deriving(Copy)]
+#[deriving(Copy, Clone)]
 struct SizeDirection {
     size: uint,
     dir: Direction,
@@ -247,6 +248,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
 /// swap applied.
 ///
 /// Generates even and odd permutations alternately.
+#[deriving(Clone)]
 pub struct Permutations<T> {
     swaps: ElementSwaps,
     v: Vec<T>,
index c6c19cae75f1efc1b55a005d0f6a8eeb6cf307d6..0969f0fcfcc474c24d4006de9d244a5693de4a90 100644 (file)
@@ -815,6 +815,7 @@ fn extend<I: Iterator<&'a str>>(&mut self, mut iterator: I) {
     }
 }
 
+#[stable]
 impl PartialEq for String {
     #[inline]
     fn eq(&self, other: &String) -> bool { PartialEq::eq(&**self, &**other) }
@@ -824,6 +825,7 @@ fn ne(&self, other: &String) -> bool { PartialEq::ne(&**self, &**other) }
 
 macro_rules! impl_eq {
     ($lhs:ty, $rhs: ty) => {
+        #[stable]
         impl<'a> PartialEq<$rhs> for $lhs {
             #[inline]
             fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
@@ -831,6 +833,7 @@ fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
             fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
         }
 
+        #[stable]
         impl<'a> PartialEq<$lhs> for $rhs {
             #[inline]
             fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&**self, &**other) }
@@ -844,6 +847,7 @@ fn ne(&self, other: &$lhs) -> bool { PartialEq::ne(&**self, &**other) }
 impl_eq! { String, &'a str }
 impl_eq! { CowString<'a>, String }
 
+#[stable]
 impl<'a, 'b> PartialEq<&'b str> for CowString<'a> {
     #[inline]
     fn eq(&self, other: &&'b str) -> bool { PartialEq::eq(&**self, &**other) }
@@ -851,6 +855,7 @@ fn eq(&self, other: &&'b str) -> bool { PartialEq::eq(&**self, &**other) }
     fn ne(&self, other: &&'b str) -> bool { PartialEq::ne(&**self, &**other) }
 }
 
+#[stable]
 impl<'a, 'b> PartialEq<CowString<'a>> for &'b str {
     #[inline]
     fn eq(&self, other: &CowString<'a>) -> bool { PartialEq::eq(&**self, &**other) }
index bf69980b49c8f75a90fe0009454dd3ee4749a635..e2a9d2f8f63c6a16293305fc3b5afce84c65f861 100644 (file)
@@ -588,6 +588,7 @@ fn extend<I: Iterator<T>>(&mut self, mut iterator: I) {
     }
 }
 
+#[stable]
 impl<A, B> PartialEq<Vec<B>> for Vec<A> where A: PartialEq<B> {
     #[inline]
     fn eq(&self, other: &Vec<B>) -> bool { PartialEq::eq(&**self, &**other) }
@@ -597,6 +598,7 @@ fn ne(&self, other: &Vec<B>) -> bool { PartialEq::ne(&**self, &**other) }
 
 macro_rules! impl_eq {
     ($lhs:ty, $rhs:ty) => {
+        #[stable]
         impl<'b, A, B> PartialEq<$rhs> for $lhs where A: PartialEq<B> {
             #[inline]
             fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
@@ -604,6 +606,7 @@ fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
             fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
         }
 
+        #[stable]
         impl<'b, A, B> PartialEq<$lhs> for $rhs where B: PartialEq<A> {
             #[inline]
             fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&**self, &**other) }
@@ -616,6 +619,7 @@ fn ne(&self, other: &$lhs) -> bool { PartialEq::ne(&**self, &**other) }
 impl_eq! { Vec<A>, &'b [B] }
 impl_eq! { Vec<A>, &'b mut [B] }
 
+#[stable]
 impl<'a, A, B> PartialEq<Vec<B>> for CowVec<'a, A> where A: PartialEq<B> + Clone {
     #[inline]
     fn eq(&self, other: &Vec<B>) -> bool { PartialEq::eq(&**self, &**other) }
@@ -623,6 +627,7 @@ fn eq(&self, other: &Vec<B>) -> bool { PartialEq::eq(&**self, &**other) }
     fn ne(&self, other: &Vec<B>) -> bool { PartialEq::ne(&**self, &**other) }
 }
 
+#[stable]
 impl<'a, A, B> PartialEq<CowVec<'a, A>> for Vec<B> where A: Clone, B: PartialEq<A> {
     #[inline]
     fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) }
@@ -632,6 +637,7 @@ fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) }
 
 macro_rules! impl_eq_for_cowvec {
     ($rhs:ty) => {
+        #[stable]
         impl<'a, 'b, A, B> PartialEq<$rhs> for CowVec<'a, A> where A: PartialEq<B> + Clone {
             #[inline]
             fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
@@ -639,6 +645,7 @@ fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
             fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
         }
 
+        #[stable]
         impl<'a, 'b, A, B> PartialEq<CowVec<'a, A>> for $rhs where A: Clone, B: PartialEq<A> {
             #[inline]
             fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) }
@@ -651,7 +658,7 @@ fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) }
 impl_eq_for_cowvec! { &'b [B] }
 impl_eq_for_cowvec! { &'b mut [B] }
 
-#[unstable = "waiting on PartialOrd stability"]
+#[stable]
 impl<T: PartialOrd> PartialOrd for Vec<T> {
     #[inline]
     fn partial_cmp(&self, other: &Vec<T>) -> Option<Ordering> {
@@ -659,7 +666,7 @@ fn partial_cmp(&self, other: &Vec<T>) -> Option<Ordering> {
     }
 }
 
-#[unstable = "waiting on Eq stability"]
+#[stable]
 impl<T: Eq> Eq for Vec<T> {}
 
 #[allow(deprecated)]
@@ -669,7 +676,7 @@ impl<T: PartialEq, Sized? V: AsSlice<T>> Equiv<V> for Vec<T> {
     fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
 }
 
-#[unstable = "waiting on Ord stability"]
+#[stable]
 impl<T: Ord> Ord for Vec<T> {
     #[inline]
     fn cmp(&self, other: &Vec<T>) -> Ordering {
index 5ebcc736624f6f95a7a6c3c158a5dfbb8a28e845..99d4e18fb87669283196d682772fe8c63236b6da 100644 (file)
@@ -537,14 +537,18 @@ pub fn update_with_key<F>(&mut self, key: uint, val: V, ff: F) -> bool where
     }
 }
 
+
+#[stable]
 impl<V: PartialEq> PartialEq for VecMap<V> {
     fn eq(&self, other: &VecMap<V>) -> bool {
         iter::order::eq(self.iter(), other.iter())
     }
 }
 
+#[stable]
 impl<V: Eq> Eq for VecMap<V> {}
 
+#[stable]
 impl<V: PartialOrd> PartialOrd for VecMap<V> {
     #[inline]
     fn partial_cmp(&self, other: &VecMap<V>) -> Option<Ordering> {
@@ -552,6 +556,7 @@ fn partial_cmp(&self, other: &VecMap<V>) -> Option<Ordering> {
     }
 }
 
+#[stable]
 impl<V: Ord> Ord for VecMap<V> {
     #[inline]
     fn cmp(&self, other: &VecMap<V>) -> Ordering {
@@ -667,6 +672,17 @@ pub struct Iter<'a, V:'a> {
     iter: slice::Iter<'a, Option<V>>
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<'a, V> Clone for Iter<'a, V> {
+    fn clone(&self) -> Iter<'a, V> {
+        Iter {
+            front: self.front,
+            back: self.back,
+            iter: self.iter.clone()
+        }
+    }
+}
+
 iterator! { impl Iter -> (uint, &'a V), as_ref }
 double_ended_iterator! { impl Iter -> (uint, &'a V), as_ref }
 
@@ -686,11 +702,29 @@ pub struct Keys<'a, V: 'a> {
     iter: Map<(uint, &'a V), uint, Iter<'a, V>, fn((uint, &'a V)) -> uint>
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<'a, V> Clone for Keys<'a, V> {
+    fn clone(&self) -> Keys<'a, V> {
+        Keys {
+            iter: self.iter.clone()
+        }
+    }
+}
+
 /// An iterator over the values of a map.
 pub struct Values<'a, V: 'a> {
     iter: Map<(uint, &'a V), &'a V, Iter<'a, V>, fn((uint, &'a V)) -> &'a V>
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<'a, V> Clone for Values<'a, V> {
+    fn clone(&self) -> Values<'a, V> {
+        Values {
+            iter: self.iter.clone()
+        }
+    }
+}
+
 /// A consuming iterator over the key-value pairs of a map.
 pub struct IntoIter<V> {
     iter: FilterMap<
index e85a132ed363f5a2e6c85dceef701117913118ef..88e23377046f12419cfd1c93c52f4f7600fc4ad4 100644 (file)
@@ -39,7 +39,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                 }
             }
 
-            #[unstable = "waiting for PartialEq to stabilize"]
+            #[stable]
             impl<A, B> PartialEq<[B, ..$N]> for [A, ..$N] where A: PartialEq<B> {
                 #[inline]
                 fn eq(&self, other: &[B, ..$N]) -> bool {
@@ -51,6 +51,7 @@ fn ne(&self, other: &[B, ..$N]) -> bool {
                 }
             }
 
+            #[stable]
             impl<'a, A, B, Rhs> PartialEq<Rhs> for [A, ..$N] where
                 A: PartialEq<B>,
                 Rhs: Deref<[B]>,
@@ -61,6 +62,7 @@ fn eq(&self, other: &Rhs) -> bool { PartialEq::eq(self[], &**other) }
                 fn ne(&self, other: &Rhs) -> bool { PartialEq::ne(self[], &**other) }
             }
 
+            #[stable]
             impl<'a, A, B, Lhs> PartialEq<[B, ..$N]> for Lhs where
                 A: PartialEq<B>,
                 Lhs: Deref<[A]>
@@ -71,10 +73,10 @@ fn eq(&self, other: &[B, ..$N]) -> bool { PartialEq::eq(&**self, other[]) }
                 fn ne(&self, other: &[B, ..$N]) -> bool { PartialEq::ne(&**self, other[]) }
             }
 
-            #[unstable = "waiting for Eq to stabilize"]
+            #[stable]
             impl<T:Eq> Eq for [T, ..$N] { }
 
-            #[unstable = "waiting for PartialOrd to stabilize"]
+            #[stable]
             impl<T:PartialOrd> PartialOrd for [T, ..$N] {
                 #[inline]
                 fn partial_cmp(&self, other: &[T, ..$N]) -> Option<Ordering> {
@@ -98,7 +100,7 @@ fn gt(&self, other: &[T, ..$N]) -> bool {
                 }
             }
 
-            #[unstable = "waiting for Ord to stabilize"]
+            #[stable]
             impl<T:Ord> Ord for [T, ..$N] {
                 #[inline]
                 fn cmp(&self, other: &[T, ..$N]) -> Ordering {
index 9452d0a64bf63e914333fa299728bc9656f5b739..6a40915f4dd829970102bf1a557827c5a9ff0957 100644 (file)
@@ -12,7 +12,7 @@
 
 #![stable]
 
-pub use self::Ordering::*;
+use self::Ordering::*;
 
 use kinds::Sync;
 
index 9bbcf67773ebbc966bc9081ea1bde77e0dbf34de..3a2cb8ea7d9848e0f1bdb5cafa51b7f84b4287c1 100644 (file)
@@ -200,8 +200,10 @@ fn deref(&self) -> &B {
     }
 }
 
+#[stable]
 impl<'a, T, Sized? B> Eq for Cow<'a, T, B> where B: Eq + ToOwned<T> {}
 
+#[stable]
 impl<'a, T, Sized? B> Ord for Cow<'a, T, B> where B: Ord + ToOwned<T> {
     #[inline]
     fn cmp(&self, other: &Cow<'a, T, B>) -> Ordering {
@@ -209,6 +211,7 @@ fn cmp(&self, other: &Cow<'a, T, B>) -> Ordering {
     }
 }
 
+#[stable]
 impl<'a, 'b, T, U, Sized? B, Sized? C> PartialEq<Cow<'b, U, C>> for Cow<'a, T, B> where
     B: PartialEq<C> + ToOwned<T>,
     C: ToOwned<U>,
@@ -219,6 +222,7 @@ fn eq(&self, other: &Cow<'b, U, C>) -> bool {
     }
 }
 
+#[stable]
 impl<'a, T, Sized? B> PartialOrd for Cow<'a, T, B> where B: PartialOrd + ToOwned<T> {
     #[inline]
     fn partial_cmp(&self, other: &Cow<'a, T, B>) -> Option<Ordering> {
index 01a1e7f97110a93668dfa1a641e82459b4a23834..6249f7600cd22ac34d733272caacde357dfa3728 100644 (file)
@@ -224,7 +224,7 @@ fn default() -> Cell<T> {
     }
 }
 
-#[unstable = "waiting for `PartialEq` trait to become stable"]
+#[stable]
 impl<T:PartialEq + Copy> PartialEq for Cell<T> {
     fn eq(&self, other: &Cell<T>) -> bool {
         self.get() == other.get()
@@ -358,7 +358,7 @@ fn default() -> RefCell<T> {
     }
 }
 
-#[unstable = "waiting for `PartialEq` to become stable"]
+#[stable]
 impl<T: PartialEq> PartialEq for RefCell<T> {
     fn eq(&self, other: &RefCell<T>) -> bool {
         *self.borrow() == *other.borrow()
index 9c12b3f68d3de71603f732bdb14a3448d88c554c..f0151dda8d71e57c12700a27c22a6d53efeee573 100644 (file)
@@ -430,11 +430,13 @@ fn encode_utf16(&self, dst: &mut [u16]) -> Option<uint> {
 
 /// An iterator over the characters that represent a `char`, as escaped by
 /// Rust's unicode escaping rules.
+#[deriving(Clone)]
 pub struct EscapeUnicode {
     c: char,
     state: EscapeUnicodeState
 }
 
+#[deriving(Clone)]
 enum EscapeUnicodeState {
     Backslash,
     Type,
@@ -486,10 +488,12 @@ fn next(&mut self) -> Option<char> {
 
 /// An iterator over the characters that represent a `char`, escaped
 /// for maximum portability.
+#[deriving(Clone)]
 pub struct EscapeDefault {
     state: EscapeDefaultState
 }
 
+#[deriving(Clone)]
 enum EscapeDefaultState {
     Backslash(char),
     Char(char),
@@ -513,4 +517,3 @@ fn next(&mut self) -> Option<char> {
         }
     }
 }
-
index ca523db214b0c50b444b8abad74e90a422a41ba5..367c794e84bb647b9687c05bbc41b339c9f73561 100644 (file)
 use kinds::Sized;
 use option::Option::{mod, Some, None};
 
-/// Trait for values that can be compared for equality and inequality.
+/// Trait for equality comparisons which are [partial equivalence relations](
+/// http://en.wikipedia.org/wiki/Partial_equivalence_relation).
 ///
-/// This trait allows for partial equality, for types that do not have an
+/// This trait allows for partial equality, for types that do not have a full
 /// equivalence relation. For example, in floating point numbers `NaN != NaN`,
 /// so floating point types implement `PartialEq` but not `Eq`.
 ///
+/// Formally, the equality must be (for all `a`, `b` and `c`):
+///
+/// - symmetric: `a == b` implies `b == a`; and
+/// - transitive: `a == b` and `b == c` implies `a == c`.
+///
+/// Note that these requirements mean that the trait itself must be
+/// implemented symmetrically and transitively: if `T: PartialEq<U>`
+/// and `U: PartialEq<V>` then `U: PartialEq<T>` and `T:
+/// PartialEq<V>`.
+///
 /// PartialEq only requires the `eq` method to be implemented; `ne` is defined
 /// in terms of it by default. Any manual implementation of `ne` *must* respect
 /// the rule that `eq` is a strict inverse of `ne`; that is, `!(a == b)` if and
 /// only if `a != b`.
-///
-/// Eventually, this will be implemented by default for types that implement
-/// `Eq`.
 #[lang="eq"]
-#[unstable = "Definition may change slightly after trait reform"]
+#[stable]
 pub trait PartialEq<Sized? Rhs = Self> for Sized? {
     /// This method tests for `self` and `other` values to be equal, and is used by `==`.
+    #[stable]
     fn eq(&self, other: &Rhs) -> bool;
 
     /// This method tests for `!=`.
     #[inline]
+    #[stable]
     fn ne(&self, other: &Rhs) -> bool { !self.eq(other) }
 }
 
@@ -79,8 +89,8 @@ fn ne(&self, other: &Rhs) -> bool { !self.eq(other) }
 /// - reflexive: `a == a`;
 /// - symmetric: `a == b` implies `b == a`; and
 /// - transitive: `a == b` and `b == c` implies `a == c`.
-#[unstable = "Definition may change slightly after trait reform"]
-pub trait Eq<Sized? Rhs = Self> for Sized?: PartialEq<Rhs> {
+#[stable]
+pub trait Eq for Sized?: PartialEq<Self> {
     // FIXME #13101: this method is used solely by #[deriving] to
     // assert that every component of a type implements #[deriving]
     // itself, the current deriving infrastructure means doing this
@@ -97,12 +107,15 @@ fn assert_receiver_is_total_eq(&self) {}
 #[deriving(Clone, Copy, PartialEq, Show)]
 #[stable]
 pub enum Ordering {
-   /// An ordering where a compared value is less [than another].
-   Less = -1i,
-   /// An ordering where a compared value is equal [to another].
-   Equal = 0i,
-   /// An ordering where a compared value is greater [than another].
-   Greater = 1i,
+    /// An ordering where a compared value is less [than another].
+    #[stable]
+    Less = -1i,
+    /// An ordering where a compared value is equal [to another].
+    #[stable]
+    Equal = 0i,
+    /// An ordering where a compared value is greater [than another].
+    #[stable]
+    Greater = 1i,
 }
 
 impl Ordering {
@@ -126,7 +139,7 @@ impl Ordering {
     /// assert!(data == b);
     /// ```
     #[inline]
-    #[experimental]
+    #[stable]
     pub fn reverse(self) -> Ordering {
         unsafe {
             // this compiles really nicely (to a single instruction);
@@ -149,8 +162,8 @@ pub fn reverse(self) -> Ordering {
 ///   true; and
 /// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for
 ///   both `==` and `>`.
-#[unstable = "Definition may change slightly after trait reform"]
-pub trait Ord<Sized? Rhs = Self> for Sized?: Eq<Rhs> + PartialOrd<Rhs> {
+#[stable]
+pub trait Ord for Sized?: Eq + PartialOrd<Self> {
     /// This method returns an ordering between `self` and `other` values.
     ///
     /// By convention, `self.cmp(&other)` returns the ordering matching
@@ -161,23 +174,26 @@ pub trait Ord<Sized? Rhs = Self> for Sized?: Eq<Rhs> + PartialOrd<Rhs> {
     /// assert_eq!(10u.cmp(&5),  Greater);  // because 10 > 5
     /// assert_eq!( 5u.cmp(&5),  Equal);    // because 5 == 5
     /// ```
-    fn cmp(&self, other: &Rhs) -> Ordering;
+    #[stable]
+    fn cmp(&self, other: &Self) -> Ordering;
 }
 
-#[unstable = "Trait is unstable."]
+#[stable]
 impl Eq for Ordering {}
 
-#[unstable = "Trait is unstable."]
+#[stable]
 impl Ord for Ordering {
     #[inline]
+    #[stable]
     fn cmp(&self, other: &Ordering) -> Ordering {
         (*self as int).cmp(&(*other as int))
     }
 }
 
-#[unstable = "Trait is unstable."]
+#[stable]
 impl PartialOrd for Ordering {
     #[inline]
+    #[stable]
     fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
         (*self as int).partial_cmp(&(*other as int))
     }
@@ -185,6 +201,17 @@ fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
 
 /// Trait for values that can be compared for a sort-order.
 ///
+/// The comparison must satisfy, for all `a`, `b` and `c`:
+///
+/// - antisymmetry: if `a < b` then `!(a > b)` and vice versa; and
+/// - transitivity: `a < b` and `b < c` implies `a < c`. The same must hold for
+///   both `==` and `>`.
+///
+/// Note that these requirements mean that the trait itself must be
+/// implemented symmetrically and transitively: if `T: PartialOrd<U>`
+/// and `U: PartialOrd<V>` then `U: PartialOrd<T>` and `T:
+/// PartialOrd<V>`.
+///
 /// PartialOrd only requires implementation of the `partial_cmp` method,
 /// with the others generated from default implementations.
 ///
@@ -193,14 +220,16 @@ fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
 /// `NaN < 0 == false` and `NaN >= 0 == false` (cf. IEEE 754-2008 section
 /// 5.11).
 #[lang="ord"]
-#[unstable = "Definition may change slightly after trait reform"]
+#[stable]
 pub trait PartialOrd<Sized? Rhs = Self> for Sized?: PartialEq<Rhs> {
     /// This method returns an ordering between `self` and `other` values
     /// if one exists.
+    #[stable]
     fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
 
     /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
     #[inline]
+    #[stable]
     fn lt(&self, other: &Rhs) -> bool {
         match self.partial_cmp(other) {
             Some(Less) => true,
@@ -210,6 +239,7 @@ fn lt(&self, other: &Rhs) -> bool {
 
     /// This method tests less than or equal to (`<=`).
     #[inline]
+    #[stable]
     fn le(&self, other: &Rhs) -> bool {
         match self.partial_cmp(other) {
             Some(Less) | Some(Equal) => true,
@@ -219,6 +249,7 @@ fn le(&self, other: &Rhs) -> bool {
 
     /// This method tests greater than (`>`).
     #[inline]
+    #[stable]
     fn gt(&self, other: &Rhs) -> bool {
         match self.partial_cmp(other) {
             Some(Greater) => true,
@@ -228,6 +259,7 @@ fn gt(&self, other: &Rhs) -> bool {
 
     /// This method tests greater than or equal to (`>=`).
     #[inline]
+    #[stable]
     fn ge(&self, other: &Rhs) -> bool {
         match self.partial_cmp(other) {
             Some(Greater) | Some(Equal) => true,
@@ -296,7 +328,7 @@ mod impls {
 
     macro_rules! partial_eq_impl {
         ($($t:ty)*) => ($(
-            #[unstable = "Trait is unstable."]
+            #[stable]
             impl PartialEq for $t {
                 #[inline]
                 fn eq(&self, other: &$t) -> bool { (*self) == (*other) }
@@ -306,7 +338,7 @@ fn ne(&self, other: &$t) -> bool { (*self) != (*other) }
         )*)
     }
 
-    #[unstable = "Trait is unstable."]
+    #[stable]
     impl PartialEq for () {
         #[inline]
         fn eq(&self, _other: &()) -> bool { true }
@@ -320,7 +352,7 @@ fn ne(&self, _other: &()) -> bool { false }
 
     macro_rules! eq_impl {
         ($($t:ty)*) => ($(
-            #[unstable = "Trait is unstable."]
+            #[stable]
             impl Eq for $t {}
         )*)
     }
@@ -329,7 +361,7 @@ impl Eq for $t {}
 
     macro_rules! partial_ord_impl {
         ($($t:ty)*) => ($(
-            #[unstable = "Trait is unstable."]
+            #[stable]
             impl PartialOrd for $t {
                 #[inline]
                 fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
@@ -352,7 +384,7 @@ fn gt(&self, other: &$t) -> bool { (*self) > (*other) }
         )*)
     }
 
-    #[unstable = "Trait is unstable."]
+    #[stable]
     impl PartialOrd for () {
         #[inline]
         fn partial_cmp(&self, _: &()) -> Option<Ordering> {
@@ -360,7 +392,7 @@ fn partial_cmp(&self, _: &()) -> Option<Ordering> {
         }
     }
 
-    #[unstable = "Trait is unstable."]
+    #[stable]
     impl PartialOrd for bool {
         #[inline]
         fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
@@ -372,7 +404,7 @@ fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
 
     macro_rules! ord_impl {
         ($($t:ty)*) => ($(
-            #[unstable = "Trait is unstable."]
+            #[stable]
             impl Ord for $t {
                 #[inline]
                 fn cmp(&self, other: &$t) -> Ordering {
@@ -384,13 +416,13 @@ fn cmp(&self, other: &$t) -> Ordering {
         )*)
     }
 
-    #[unstable = "Trait is unstable."]
+    #[stable]
     impl Ord for () {
         #[inline]
         fn cmp(&self, _other: &()) -> Ordering { Equal }
     }
 
-    #[unstable = "Trait is unstable."]
+    #[stable]
     impl Ord for bool {
         #[inline]
         fn cmp(&self, other: &bool) -> Ordering {
@@ -402,68 +434,69 @@ fn cmp(&self, other: &bool) -> Ordering {
 
     // & pointers
 
-    #[unstable = "Trait is unstable."]
+    #[stable]
     impl<'a, 'b, Sized? A, Sized? B> PartialEq<&'b B> for &'a A where A: PartialEq<B> {
         #[inline]
         fn eq(&self, other: & &'b B) -> bool { PartialEq::eq(*self, *other) }
         #[inline]
         fn ne(&self, other: & &'b B) -> bool { PartialEq::ne(*self, *other) }
     }
-    #[unstable = "Trait is unstable."]
-    impl<'a, Sized? T: PartialOrd> PartialOrd for &'a T {
+    #[stable]
+    impl<'a, 'b, Sized? A, Sized? B> PartialOrd<&'b B> for &'a A where A: PartialOrd<B> {
         #[inline]
-        fn partial_cmp(&self, other: &&'a T) -> Option<Ordering> {
+        fn partial_cmp(&self, other: &&'b B) -> Option<Ordering> {
             PartialOrd::partial_cmp(*self, *other)
         }
         #[inline]
-        fn lt(&self, other: & &'a T) -> bool { PartialOrd::lt(*self, *other) }
+        fn lt(&self, other: & &'b B) -> bool { PartialOrd::lt(*self, *other) }
         #[inline]
-        fn le(&self, other: & &'a T) -> bool { PartialOrd::le(*self, *other) }
+        fn le(&self, other: & &'b B) -> bool { PartialOrd::le(*self, *other) }
         #[inline]
-        fn ge(&self, other: & &'a T) -> bool { PartialOrd::ge(*self, *other) }
+        fn ge(&self, other: & &'b B) -> bool { PartialOrd::ge(*self, *other) }
         #[inline]
-        fn gt(&self, other: & &'a T) -> bool { PartialOrd::gt(*self, *other) }
+        fn gt(&self, other: & &'b B) -> bool { PartialOrd::gt(*self, *other) }
     }
-    #[unstable = "Trait is unstable."]
-    impl<'a, Sized? T: Ord> Ord for &'a T {
+    #[stable]
+    impl<'a, Sized? A> Ord for &'a A where A: Ord {
         #[inline]
-        fn cmp(&self, other: & &'a T) -> Ordering { Ord::cmp(*self, *other) }
+        fn cmp(&self, other: & &'a A) -> Ordering { Ord::cmp(*self, *other) }
     }
-    #[unstable = "Trait is unstable."]
-    impl<'a, Sized? T: Eq> Eq for &'a T {}
+    #[stable]
+    impl<'a, Sized? A> Eq for &'a A where A: Eq {}
 
     // &mut pointers
 
-    #[unstable = "Trait is unstable."]
+    #[stable]
     impl<'a, 'b, Sized? A, Sized? B> PartialEq<&'b mut B> for &'a mut A where A: PartialEq<B> {
         #[inline]
         fn eq(&self, other: &&'b mut B) -> bool { PartialEq::eq(*self, *other) }
         #[inline]
         fn ne(&self, other: &&'b mut B) -> bool { PartialEq::ne(*self, *other) }
     }
-    #[unstable = "Trait is unstable."]
-    impl<'a, Sized? T: PartialOrd> PartialOrd for &'a mut T {
+    #[stable]
+    impl<'a, 'b, Sized? A, Sized? B> PartialOrd<&'b mut B> for &'a mut A where A: PartialOrd<B> {
         #[inline]
-        fn partial_cmp(&self, other: &&'a mut T) -> Option<Ordering> {
+        fn partial_cmp(&self, other: &&'b mut B) -> Option<Ordering> {
             PartialOrd::partial_cmp(*self, *other)
         }
         #[inline]
-        fn lt(&self, other: &&'a mut T) -> bool { PartialOrd::lt(*self, *other) }
+        fn lt(&self, other: &&'b mut B) -> bool { PartialOrd::lt(*self, *other) }
         #[inline]
-        fn le(&self, other: &&'a mut T) -> bool { PartialOrd::le(*self, *other) }
+        fn le(&self, other: &&'b mut B) -> bool { PartialOrd::le(*self, *other) }
         #[inline]
-        fn ge(&self, other: &&'a mut T) -> bool { PartialOrd::ge(*self, *other) }
+        fn ge(&self, other: &&'b mut B) -> bool { PartialOrd::ge(*self, *other) }
         #[inline]
-        fn gt(&self, other: &&'a mut T) -> bool { PartialOrd::gt(*self, *other) }
+        fn gt(&self, other: &&'b mut B) -> bool { PartialOrd::gt(*self, *other) }
     }
-    #[unstable = "Trait is unstable."]
-    impl<'a, Sized? T: Ord> Ord for &'a mut T {
+    #[stable]
+    impl<'a, Sized? A> Ord for &'a mut A where A: Ord {
         #[inline]
-        fn cmp(&self, other: &&'a mut T) -> Ordering { Ord::cmp(*self, *other) }
+        fn cmp(&self, other: &&'a mut A) -> Ordering { Ord::cmp(*self, *other) }
     }
-    #[unstable = "Trait is unstable."]
-    impl<'a, Sized? T: Eq> Eq for &'a mut T {}
+    #[stable]
+    impl<'a, Sized? A> Eq for &'a mut A where A: Eq {}
 
+    #[stable]
     impl<'a, 'b, Sized? A, Sized? B> PartialEq<&'b mut B> for &'a A where A: PartialEq<B> {
         #[inline]
         fn eq(&self, other: &&'b mut B) -> bool { PartialEq::eq(*self, *other) }
@@ -471,6 +504,7 @@ fn eq(&self, other: &&'b mut B) -> bool { PartialEq::eq(*self, *other) }
         fn ne(&self, other: &&'b mut B) -> bool { PartialEq::ne(*self, *other) }
     }
 
+    #[stable]
     impl<'a, 'b, Sized? A, Sized? B> PartialEq<&'b B> for &'a mut A where A: PartialEq<B> {
         #[inline]
         fn eq(&self, other: &&'b B) -> bool { PartialEq::eq(*self, *other) }
index 75bb8d33ea85f514419190b2d52be05d579d8f51..faf1d781465c76457b4d08ef731a0cd58fcec2c3 100644 (file)
@@ -379,6 +379,7 @@ unsafe fn as_mut<'a>(&self) -> Option<&'a mut T> {
 }
 
 // Equality for pointers
+#[stable]
 impl<T> PartialEq for *const T {
     #[inline]
     fn eq(&self, other: &*const T) -> bool {
@@ -388,8 +389,10 @@ fn eq(&self, other: &*const T) -> bool {
     fn ne(&self, other: &*const T) -> bool { !self.eq(other) }
 }
 
+#[stable]
 impl<T> Eq for *const T {}
 
+#[stable]
 impl<T> PartialEq for *mut T {
     #[inline]
     fn eq(&self, other: &*mut T) -> bool {
@@ -399,6 +402,7 @@ fn eq(&self, other: &*mut T) -> bool {
     fn ne(&self, other: &*mut T) -> bool { !self.eq(other) }
 }
 
+#[stable]
 impl<T> Eq for *mut T {}
 
 // Equivalence for pointers
@@ -439,6 +443,7 @@ mod externfnpointers {
     use mem;
     use cmp::PartialEq;
 
+    #[stable]
     impl<_R> PartialEq for extern "C" fn() -> _R {
         #[inline]
         fn eq(&self, other: &extern "C" fn() -> _R) -> bool {
@@ -449,6 +454,7 @@ fn eq(&self, other: &extern "C" fn() -> _R) -> bool {
     }
     macro_rules! fnptreq {
         ($($p:ident),*) => {
+            #[stable]
             impl<_R,$($p),*> PartialEq for extern "C" fn($($p),*) -> _R {
                 #[inline]
                 fn eq(&self, other: &extern "C" fn($($p),*) -> _R) -> bool {
@@ -468,6 +474,7 @@ fn eq(&self, other: &extern "C" fn($($p),*) -> _R) -> bool {
 }
 
 // Comparison for pointers
+#[stable]
 impl<T> Ord for *const T {
     #[inline]
     fn cmp(&self, other: &*const T) -> Ordering {
@@ -481,6 +488,7 @@ fn cmp(&self, other: &*const T) -> Ordering {
     }
 }
 
+#[stable]
 impl<T> PartialOrd for *const T {
     #[inline]
     fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
@@ -500,6 +508,7 @@ fn gt(&self, other: &*const T) -> bool { *self > *other }
     fn ge(&self, other: &*const T) -> bool { *self >= *other }
 }
 
+#[stable]
 impl<T> Ord for *mut T {
     #[inline]
     fn cmp(&self, other: &*mut T) -> Ordering {
@@ -513,6 +522,7 @@ fn cmp(&self, other: &*mut T) -> Ordering {
     }
 }
 
+#[stable]
 impl<T> PartialOrd for *mut T {
     #[inline]
     fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> {
index f356a0867d2529b57397d944790dbca42cff5ccb..77bb5cc2499c881e696a81775c629f74fbac151f 100644 (file)
@@ -1437,7 +1437,7 @@ pub fn copy_memory(dst: &mut [u8], src: &[u8]) {
 // Boilerplate traits
 //
 
-#[unstable = "waiting for DST"]
+#[stable]
 impl<A, B> PartialEq<[B]> for [A] where A: PartialEq<B> {
     fn eq(&self, other: &[B]) -> bool {
         self.len() == other.len() &&
@@ -1449,7 +1449,7 @@ fn ne(&self, other: &[B]) -> bool {
     }
 }
 
-#[unstable = "waiting for DST"]
+#[stable]
 impl<T: Eq> Eq for [T] {}
 
 #[allow(deprecated)]
@@ -1466,14 +1466,14 @@ impl<'a,T:PartialEq, Sized? V: AsSlice<T>> Equiv<V> for &'a mut [T] {
     fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
 }
 
-#[unstable = "waiting for DST"]
+#[stable]
 impl<T: Ord> Ord for [T] {
     fn cmp(&self, other: &[T]) -> Ordering {
         order::cmp(self.iter(), other.iter())
     }
 }
 
-#[unstable = "waiting for DST"]
+#[stable]
 impl<T: PartialOrd> PartialOrd for [T] {
     #[inline]
     fn partial_cmp(&self, other: &[T]) -> Option<Ordering> {
index 8db672b26537532fa44ad720c5cc91e7558e5c9b..59cf79408b100acb837ee39cae95012a366d0250 100644 (file)
@@ -1143,6 +1143,7 @@ pub mod traits {
     use ops;
     use str::{Str, StrExt, eq_slice};
 
+    #[stable]
     impl Ord for str {
         #[inline]
         fn cmp(&self, other: &str) -> Ordering {
@@ -1158,6 +1159,7 @@ fn cmp(&self, other: &str) -> Ordering {
         }
     }
 
+    #[stable]
     impl PartialEq for str {
         #[inline]
         fn eq(&self, other: &str) -> bool {
@@ -1167,8 +1169,10 @@ fn eq(&self, other: &str) -> bool {
         fn ne(&self, other: &str) -> bool { !(*self).eq(other) }
     }
 
+    #[stable]
     impl Eq for str {}
 
+    #[stable]
     impl PartialOrd for str {
         #[inline]
         fn partial_cmp(&self, other: &str) -> Option<Ordering> {
index a92914c99e35b7b5a83af0619864b772eccb976d..576989fabe77c92a573e6d348b5ff411c3ee6e31 100644 (file)
@@ -132,7 +132,7 @@ fn clone(&self) -> ($($T,)+) {
                 }
             }
 
-            #[unstable = "waiting for PartialEq to stabilize"]
+            #[stable]
             impl<$($T:PartialEq),+> PartialEq for ($($T,)+) {
                 #[inline]
                 fn eq(&self, other: &($($T,)+)) -> bool {
@@ -144,10 +144,10 @@ fn ne(&self, other: &($($T,)+)) -> bool {
                 }
             }
 
-            #[unstable = "waiting for Eq to stabilize"]
+            #[stable]
             impl<$($T:Eq),+> Eq for ($($T,)+) {}
 
-            #[unstable = "waiting for PartialOrd to stabilize"]
+            #[stable]
             impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+) {
                 #[inline]
                 fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
@@ -171,7 +171,7 @@ fn gt(&self, other: &($($T,)+)) -> bool {
                 }
             }
 
-            #[unstable = "waiting for Ord to stabilize"]
+            #[stable]
             impl<$($T:Ord),+> Ord for ($($T,)+) {
                 #[inline]
                 fn cmp(&self, other: &($($T,)+)) -> Ordering {
index 1d865868f18834f75196366becf74a4a9bdbdec1..6ee8ae25f1bdd39e78be4c29aee2d2d4baa8467c 100644 (file)
 use std::os;
 use std::rt;
 use std::slice;
-use std::sync::{Once, ONCE_INIT};
+use std::sync::{Once, ONCE_INIT, StaticMutex, MUTEX_INIT};
 
 use regex::Regex;
 
 /// The default logging level of a crate if no other is specified.
 const DEFAULT_LOG_LEVEL: u32 = 1;
 
+static LOCK: StaticMutex = MUTEX_INIT;
+
 /// An unsafe constant that is the maximum logging level of any module
 /// specified. This is the first line of defense to determining whether a
 /// logging statement should be run.
@@ -281,9 +283,18 @@ fn drop(&mut self) {
 pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) {
     // Test the literal string from args against the current filter, if there
     // is one.
-    match unsafe { FILTER.as_ref() } {
-        Some(filter) if !filter.is_match(args.to_string()[]) => return,
-        _ => {}
+    unsafe {
+        let _g = LOCK.lock();
+        match FILTER as uint {
+            0 => {}
+            1 => panic!("cannot log after main thread has exited"),
+            n => {
+                let filter = mem::transmute::<_, &Regex>(n);
+                if !filter.is_match(args.to_string().as_slice()) {
+                    return
+                }
+            }
+        }
     }
 
     // Completely remove the local logger from TLS in case anyone attempts to
@@ -401,9 +412,15 @@ pub fn mod_enabled(level: u32, module: &str) -> bool {
 
     // This assertion should never get tripped unless we're in an at_exit
     // handler after logging has been torn down and a logging attempt was made.
-    assert!(unsafe { !DIRECTIVES.is_null() });
 
-    enabled(level, module, unsafe { (*DIRECTIVES).iter() })
+    let _g = LOCK.lock();
+    unsafe {
+        assert!(DIRECTIVES as uint != 0);
+        assert!(DIRECTIVES as uint != 1,
+                "cannot log after the main thread has exited");
+
+        enabled(level, module, (*DIRECTIVES).iter())
+    }
 }
 
 fn enabled(level: u32,
@@ -459,14 +476,15 @@ fn init() {
 
         // Schedule the cleanup for the globals for when the runtime exits.
         rt::at_exit(move |:| {
+            let _g = LOCK.lock();
             assert!(!DIRECTIVES.is_null());
             let _directives: Box<Vec<directive::LogDirective>> =
                 mem::transmute(DIRECTIVES);
-            DIRECTIVES = 0 as *const Vec<directive::LogDirective>;
+            DIRECTIVES = 1 as *const Vec<directive::LogDirective>;
 
             if !FILTER.is_null() {
                 let _filter: Box<Regex> = mem::transmute(FILTER);
-                FILTER = 0 as *const _;
+                FILTER = 1 as *const _;
             }
         });
     }
index 4383192edafb05485f4984190b8ee7c6c17edaf9..51c234631550cf9c1e57c78398421614dff5cb70 100644 (file)
@@ -539,6 +539,7 @@ fn names_len(&self) -> uint {
 
 }
 
+#[deriving(Clone)]
 pub enum NamesIter<'a> {
     NamesIterNative(::std::slice::Iter<'a, Option<&'static str>>),
     NamesIterDynamic(::std::slice::Iter<'a, Option<String>>)
@@ -595,6 +596,7 @@ fn reg_replace<'a>(&'a mut self, caps: &Captures) -> CowString<'a> {
 ///
 /// `'r` is the lifetime of the compiled expression and `'t` is the lifetime
 /// of the string being split.
+#[deriving(Clone)]
 pub struct RegexSplits<'r, 't> {
     finder: FindMatches<'r, 't>,
     last: uint,
@@ -628,6 +630,7 @@ fn next(&mut self) -> Option<&'t str> {
 ///
 /// `'r` is the lifetime of the compiled expression and `'t` is the lifetime
 /// of the string being split.
+#[deriving(Clone)]
 pub struct RegexSplitsN<'r, 't> {
     splits: RegexSplits<'r, 't>,
     cur: uint,
@@ -791,6 +794,7 @@ pub fn is_empty(&self) -> bool { self.len() == 0 }
 /// expression.
 ///
 /// `'t` is the lifetime of the matched text.
+#[deriving(Clone)]
 pub struct SubCaptures<'t> {
     idx: uint,
     caps: &'t Captures<'t>,
@@ -813,6 +817,7 @@ fn next(&mut self) -> Option<&'t str> {
 /// Positions are byte indices in terms of the original string matched.
 ///
 /// `'t` is the lifetime of the matched text.
+#[deriving(Clone)]
 pub struct SubCapturesPos<'t> {
     idx: uint,
     caps: &'t Captures<'t>,
@@ -836,6 +841,7 @@ fn next(&mut self) -> Option<Option<(uint, uint)>> {
 ///
 /// `'r` is the lifetime of the compiled expression and `'t` is the lifetime
 /// of the matched string.
+#[deriving(Clone)]
 pub struct FindCaptures<'r, 't> {
     re: &'r Regex,
     search: &'t str,
@@ -878,6 +884,7 @@ fn next(&mut self) -> Option<Captures<'t>> {
 ///
 /// `'r` is the lifetime of the compiled expression and `'t` is the lifetime
 /// of the matched string.
+#[deriving(Clone)]
 pub struct FindMatches<'r, 't> {
     re: &'r Regex,
     search: &'t str,
index 35c29f646e4a01b1917cff23aa3c3214b298b6b6..7c496623d62d2da9236db4117d33f32155f9241d 100644 (file)
@@ -654,6 +654,7 @@ fn check_attribute(&mut self, cx: &Context, attr: &ast::Attribute) {
             "static_assert",
             "thread_local",
             "no_debug",
+            "omit_gdb_pretty_printer_section",
             "unsafe_no_drop_flag",
 
             // used in resolve
index 3528b510ea1bbf6ae4b8c89bc8958baae2fe9b66..296ebcf9cfd8f7b946bef5d6e0bf2700654f2d57 100644 (file)
@@ -1743,7 +1743,8 @@ pub fn LLVMDIBuilderCreateCompileUnit(Builder: DIBuilderRef,
                                           isOptimized: bool,
                                           Flags: *const c_char,
                                           RuntimeVer: c_uint,
-                                          SplitName: *const c_char);
+                                          SplitName: *const c_char)
+                                          -> DIDescriptor;
 
     pub fn LLVMDIBuilderCreateFile(Builder: DIBuilderRef,
                                    Filename: *const c_char,
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
new file mode 100644 (file)
index 0000000..7dbcc81
--- /dev/null
@@ -0,0 +1,1282 @@
+// 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.
+
+//! Reduced graph building
+//!
+//! Here we build the "reduced graph": the graph of the module tree without
+//! any imports resolved.
+
+use {DefModifiers, PUBLIC, IMPORTABLE};
+use ImportDirective;
+use ImportDirectiveSubclass::{mod, SingleImport, GlobImport};
+use ImportResolution;
+use Module;
+use ModuleKind::*;
+use Namespace::{TypeNS, ValueNS};
+use NameBindings;
+use ParentLink::{mod, ModuleParentLink, BlockParentLink};
+use Resolver;
+use RibKind::*;
+use Shadowable;
+use TypeNsDef;
+use TypeParameters::HasTypeParameters;
+
+use self::DuplicateCheckingMode::*;
+use self::NamespaceError::*;
+
+use rustc::metadata::csearch;
+use rustc::metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
+use rustc::middle::def::*;
+use rustc::middle::subst::FnSpace;
+
+use syntax::ast::{Block, Crate};
+use syntax::ast::{DeclItem, DefId};
+use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic};
+use syntax::ast::{Item, ItemConst, ItemEnum, ItemFn};
+use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
+use syntax::ast::{ItemStruct, ItemTrait, ItemTy};
+use syntax::ast::{MethodImplItem, Name, NamedField, NodeId};
+use syntax::ast::{PathListIdent, PathListMod};
+use syntax::ast::{Public, SelfStatic};
+use syntax::ast::StmtDecl;
+use syntax::ast::StructVariantKind;
+use syntax::ast::TupleVariantKind;
+use syntax::ast::TyObjectSum;
+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::TyPath;
+use syntax::ast;
+use syntax::ast_util::{mod, PostExpansionMethod, local_def};
+use syntax::attr::AttrMetaMethods;
+use syntax::parse::token::{mod, special_idents};
+use syntax::codemap::{Span, DUMMY_SP};
+use syntax::visit::{mod, Visitor};
+
+use std::rc::Rc;
+use std::mem::replace;
+
+// 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
+}
+
+#[deriving(Copy, PartialEq)]
+enum NamespaceError {
+    NoError,
+    ModuleError,
+    TypeError,
+    ValueError
+}
+
+fn namespace_error_to_string(ns: NamespaceError) -> &'static str {
+    match ns {
+        NoError                 => "",
+        ModuleError | TypeError => "type or module",
+        ValueError              => "value",
+    }
+}
+
+struct GraphBuilder<'a, 'b:'a, 'tcx:'b> {
+    resolver: &'a mut Resolver<'b, 'tcx>
+}
+
+impl<'a, 'b:'a, 'tcx:'b> Deref<Resolver<'b, 'tcx>> for GraphBuilder<'a, 'b, 'tcx> {
+    fn deref(&self) -> &Resolver<'b, 'tcx> {
+        &*self.resolver
+    }
+}
+
+impl<'a, 'b:'a, 'tcx:'b> DerefMut<Resolver<'b, 'tcx>> for GraphBuilder<'a, 'b, 'tcx> {
+    fn deref_mut(&mut self) -> &mut Resolver<'b, 'tcx> {
+        &mut *self.resolver
+    }
+}
+
+impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
+    /// Constructs the reduced graph for the entire crate.
+    fn build_reduced_graph(self, krate: &ast::Crate) {
+        let parent = self.graph_root.get_module();
+        let mut visitor = BuildReducedGraphVisitor {
+            builder: 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,
+                 parent: &Rc<Module>,
+                 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.
+
+        self.check_for_conflicts_between_external_crates_and_items(&**parent,
+                                                                   name,
+                                                                   sp);
+
+        // Add or reuse the child.
+        let child = parent.children.borrow().get(&name).cloned();
+        match child {
+            None => {
+                let child = Rc::new(NameBindings::new());
+                parent.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))[]);
+                    {
+                        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))[]);
+                        }
+                    }
+                }
+                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: &Rc<Module>, name: Name) -> ParentLink {
+        ModuleParentLink(parent.downgrade(), name)
+    }
+
+    /// Constructs the reduced graph for one item.
+    fn build_reduced_graph_for_item(&mut self, item: &Item, parent: &Rc<Module>) -> Rc<Module> {
+        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, 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);
+
+                name_bindings.get_module()
+            }
+
+            ItemForeignMod(..) => parent.clone(),
+
+            // These items live in the value namespace.
+            ItemStatic(_, m, _) => {
+                let name_bindings = self.add_child(name, parent, ForbidDuplicateValues, sp);
+                let mutbl = m == ast::MutMutable;
+
+                name_bindings.define_value(DefStatic(local_def(item.id), mutbl), sp, modifiers);
+                parent.clone()
+            }
+            ItemConst(_, _) => {
+                self.add_child(name, parent, ForbidDuplicateValues, sp)
+                    .define_value(DefConst(local_def(item.id)), sp, modifiers);
+                parent.clone()
+            }
+            ItemFn(_, _, _, _, _) => {
+                let name_bindings = self.add_child(name, parent, ForbidDuplicateValues, sp);
+
+                let def = DefFn(local_def(item.id), false);
+                name_bindings.define_value(def, sp, modifiers);
+                parent.clone()
+            }
+
+            // These items live in the type namespace.
+            ItemTy(..) => {
+                let name_bindings =
+                    self.add_child(name, parent, ForbidDuplicateTypesAndModules, sp);
+
+                name_bindings.define_type(DefTy(local_def(item.id), false), sp, modifiers);
+                parent.clone()
+            }
+
+            ItemEnum(ref enum_definition, _) => {
+                let name_bindings =
+                    self.add_child(name, parent, ForbidDuplicateTypesAndModules, sp);
+
+                name_bindings.define_type(DefTy(local_def(item.id), true), sp, modifiers);
+
+                let parent_link = self.get_parent_link(parent, 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);
+
+                let module = name_bindings.get_module();
+
+                for variant in (*enum_definition).variants.iter() {
+                    self.build_reduced_graph_for_variant(
+                        &**variant,
+                        local_def(item.id),
+                        &module);
+                }
+                parent.clone()
+            }
+
+            // 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, 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
+                if let Some(cid) = ctor_id {
+                    name_bindings.define_value(DefStruct(local_def(cid)), sp, modifiers);
+                }
+
+                // 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.clone()
+            }
+
+            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.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) => {
+                                    child.get_module()
+                                }
+                            Some(ref child) if child.get_module_if_available()
+                                .is_some() &&
+                                child.get_module().kind.get() ==
+                                EnumModuleKind => child.get_module(),
+                            // Create the module
+                            _ => {
+                                let name_bindings =
+                                    self.add_child(mod_name, parent, ForbidDuplicateModules, sp);
+
+                                let parent_link = self.get_parent_link(parent, 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);
+
+                                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,
+                                                       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,
+                                            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.clone()
+            }
+
+            ItemImpl(_, _, Some(_), _, _) => parent.clone(),
+
+            ItemTrait(_, _, _, ref items) => {
+                let name_bindings =
+                    self.add_child(name, parent, ForbidDuplicateTypesAndModules, sp);
+
+                // Add all the items within to a new module.
+                let parent_link = self.get_parent_link(parent, name);
+                name_bindings.define_module(parent_link,
+                                            Some(local_def(item.id)),
+                                            TraitModuleKind,
+                                            false,
+                                            item.vis == ast::Public,
+                                            sp);
+                let module_parent = 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,
+                                               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,
+                                               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.clone()
+            }
+            ItemMac(..) => parent.clone()
+        }
+    }
+
+    // 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: &Rc<Module>) {
+        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: &Rc<Module>) {
+        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 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)
+                             });
+                let shadowable = if shadowable {
+                    Shadowable::Always
+                } else {
+                    Shadowable::Never
+                };
+
+                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(&**parent,
+                                                    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(
+                                &**parent,
+                                module_path,
+                                SingleImport(name, name),
+                                source_item.span,
+                                source_item.node.id(),
+                                is_public,
+                                shadowable);
+                        }
+                    }
+                    ViewPathGlob(_, id) => {
+                        self.build_import_directive(&**parent,
+                                                    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.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,
+                        name.name,
+                        view_item.span);
+                    parent.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: &Rc<Module>,
+                                               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.resolver)
+            }
+        }
+    }
+
+    fn build_reduced_graph_for_block(&mut self, block: &Block, parent: &Rc<Module>) -> Rc<Module> {
+        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 new_module = Rc::new(Module::new(
+                BlockParentLink(parent.downgrade(), block_id),
+                None,
+                AnonymousModuleKind,
+                false,
+                false));
+            parent.anonymous_children.borrow_mut().insert(block_id, new_module.clone());
+            new_module
+        } else {
+            parent.clone()
+        }
+    }
+
+    fn handle_external_def(&mut self,
+                           def: Def,
+                           vis: Visibility,
+                           child_name_bindings: &NameBindings,
+                           final_ident: &str,
+                           name: Name,
+                           new_parent: &Rc<Module>) {
+        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.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, 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.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,
+                                def_like,
+                                child_name,
+                                vis)
+                        });
+                    }
+                    _ => {
+                        let child_name_bindings =
+                            self.add_child(name,
+                                           root,
+                                           OverwriteDuplicates,
+                                           DUMMY_SP);
+
+                        self.handle_external_def(def,
+                                                 visibility,
+                                                 &*child_name_bindings,
+                                                 token::get_name(name).get(),
+                                                 name,
+                                                 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,
+                                        root,
+                                        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(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 = 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,
+                                                       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,
+                                                            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)
+        }
+        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, 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: Shadowable) {
+        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[]),
+                       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);
+            }
+        }
+    }
+}
+
+struct BuildReducedGraphVisitor<'a, 'b:'a, 'tcx:'b> {
+    builder: GraphBuilder<'a, 'b, 'tcx>,
+    parent: Rc<Module>
+}
+
+impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
+    fn visit_item(&mut self, item: &Item) {
+        let p = self.builder.build_reduced_graph_for_item(item, &self.parent);
+        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;
+        self.builder.build_reduced_graph_for_foreign_item(foreign_item,
+                                                          parent,
+                                                          |r| {
+            let mut v = BuildReducedGraphVisitor {
+                builder: GraphBuilder { resolver: r },
+                parent: parent.clone()
+            };
+            visit::walk_foreign_item(&mut v, foreign_item);
+        })
+    }
+
+    fn visit_view_item(&mut self, view_item: &ViewItem) {
+        self.builder.build_reduced_graph_for_view_item(view_item, &self.parent);
+    }
+
+    fn visit_block(&mut self, block: &Block) {
+        let np = self.builder.build_reduced_graph_for_block(block, &self.parent);
+        let old_parent = replace(&mut self.parent, np);
+        visit::walk_block(self, block);
+        self.parent = old_parent;
+    }
+}
+
+pub fn build_reduced_graph(resolver: &mut Resolver, krate: &ast::Crate) {
+    GraphBuilder {
+        resolver: resolver
+    }.build_reduced_graph(krate);
+}
+
+pub fn populate_module_if_necessary(resolver: &mut Resolver, module: &Rc<Module>) {
+    GraphBuilder {
+        resolver: resolver
+    }.populate_module_if_necessary(module);
+}
index 52bd096eb83dea2f5b45f0675d02a0ddae1ff6f2..6b504d6d16e98cbcaedbe8210b72c4fbd8618a90 100644 (file)
 
 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::*;
@@ -40,7 +38,6 @@
 use self::ModulePrefixResult::*;
 use self::NameSearchType::*;
 use self::BareIdentifierPatternResolution::*;
-use self::DuplicateCheckingMode::*;
 use self::ParentLink::*;
 use self::ModuleKind::*;
 use self::TraitReferenceType::*;
 use rustc::util::lev_distance::lev_distance;
 
 use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
-use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField};
+use syntax::ast::{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::{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, LOCAL_CRATE};
-use syntax::ast::{MethodImplItem, Mod, Name, NamedField, NodeId};
+use syntax::ast::{MethodImplItem, Mod, Name, 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::{PatRange, PatStruct, Path};
+use syntax::ast::{PolyTraitRef, PrimTy, SelfExplicit};
+use syntax::ast::{RegionTyParamBound, StructField};
+use syntax::ast::{TraitRef, TraitTyParamBound};
+use syntax::ast::{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::{TypeImplItem};
 use syntax::ast;
 use syntax::ast_map;
-use syntax::ast_util::{mod, PostExpansionMethod, local_def, walk_pat};
+use syntax::ast_util::{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::codemap::{Span, Pos};
 use syntax::owned_slice::OwnedSlice;
 use syntax::visit::{mod, Visitor};
 
 
 mod check_unused;
 mod record_exports;
+mod build_reduced_graph;
 
 #[deriving(Copy)]
 struct BindingInfo {
@@ -123,14 +118,6 @@ enum Namespace {
     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.
@@ -197,22 +184,6 @@ enum ImportDirectiveSubclass {
     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> {
@@ -314,17 +285,6 @@ enum BareIdentifierPatternResolution {
     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 {
@@ -865,15 +825,6 @@ fn intern(&mut self, string: &str, primitive_type: PrimTy) {
     }
 }
 
-
-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, 'tcx:'a> {
     session: &'a Session,
@@ -939,46 +890,6 @@ struct Resolver<'a, 'tcx:'a> {
     used_crates: HashSet<CrateNum>,
 }
 
-struct BuildReducedGraphVisitor<'a, 'b:'a, 'tcx:'b> {
-    resolver: &'a mut Resolver<'b, 'tcx>,
-    parent: ReducedGraphParent
-}
-
-impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
-
-    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,
@@ -1047,1191 +958,6 @@ fn new(session: &'a Session,
         }
     }
 
-    //
-    // 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))[]);
-                    {
-                        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))[]);
-                        }
-                    }
-                }
-                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)
-                             });
-                let shadowable = if shadowable {
-                    Shadowable::Always
-                } else {
-                    Shadowable::Never
-                };
-
-                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: Shadowable) {
-        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[]),
-                       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
@@ -2276,7 +1002,7 @@ fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
         self.resolve_imports_for_module(module_.clone());
         self.current_module = orig_module;
 
-        self.populate_module_if_necessary(&module_);
+        build_reduced_graph::populate_module_if_necessary(self, &module_);
         for (_, child_node) in module_.children.borrow().iter() {
             match child_node.get_module_if_available() {
                 None => {
@@ -2542,7 +1268,7 @@ fn resolve_single_import(&mut self,
         let mut type_result = UnknownResult;
 
         // Search for direct children of the containing module.
-        self.populate_module_if_necessary(&containing_module);
+        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
 
         match containing_module.children.borrow().get(&source) {
             None => {
@@ -2902,7 +1628,7 @@ fn resolve_glob_import(&mut self,
         }
 
         // Add all children from the containing module.
-        self.populate_module_if_necessary(&containing_module);
+        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
 
         for (&name, name_bindings) in containing_module.children.borrow().iter() {
             self.merge_import_resolution(module_,
@@ -3422,7 +2148,7 @@ fn resolve_item_in_lexical_scope(&mut self,
 
         // The current module node is handled specially. First, check for
         // its immediate children.
-        self.populate_module_if_necessary(&module_);
+        build_reduced_graph::populate_module_if_necessary(self, &module_);
 
         match module_.children.borrow().get(&name) {
             Some(name_bindings)
@@ -3687,7 +2413,7 @@ fn resolve_name_in_module(&mut self,
                self.module_to_string(&*module_));
 
         // First, check the direct children of the module.
-        self.populate_module_if_necessary(&module_);
+        build_reduced_graph::populate_module_if_necessary(self, &module_);
 
         match module_.children.borrow().get(&name) {
             Some(name_bindings)
@@ -3783,7 +2509,7 @@ fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
         }
 
         // Descend into children and anonymous children.
-        self.populate_module_if_necessary(&module_);
+        build_reduced_graph::populate_module_if_necessary(self, &module_);
 
         for (_, child_node) in module_.children.borrow().iter() {
             match child_node.get_module_if_available() {
@@ -3830,7 +2556,7 @@ fn with_scope<F>(&mut self, name: Option<Name>, f: F) where
                 // Nothing to do.
             }
             Some(name) => {
-                self.populate_module_if_necessary(&orig_module);
+                build_reduced_graph::populate_module_if_necessary(self, &orig_module);
 
                 match orig_module.children.borrow().get(&name) {
                     None => {
@@ -5243,7 +3969,7 @@ fn resolve_definition_of_name_in_module(&mut self,
                                             namespace: Namespace)
                                             -> NameDefinition {
         // First, search children.
-        self.populate_module_if_necessary(&containing_module);
+        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
 
         match containing_module.children.borrow().get(&name) {
             Some(child_name_bindings) => {
@@ -5931,7 +4657,7 @@ fn add_trait_info(found_traits: &mut Vec<DefId>,
             }
 
             // Look for trait children.
-            self.populate_module_if_necessary(&search_module);
+            build_reduced_graph::populate_module_if_necessary(self, &search_module);
 
             {
                 for (_, child_names) in search_module.children.borrow().iter() {
@@ -6059,7 +4785,7 @@ 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_);
+        build_reduced_graph::populate_module_if_necessary(self, &module_);
         for (&name, _) in module_.children.borrow().iter() {
             debug!("* {}", token::get_name(name));
         }
@@ -6116,7 +4842,7 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
                                -> CrateMap {
     let mut resolver = Resolver::new(session, ast_map, krate.span, make_glob_map);
 
-    resolver.build_reduced_graph(krate);
+    build_reduced_graph::build_reduced_graph(&mut resolver, krate);
     session.abort_if_errors();
 
     resolver.resolve_imports();
index 80659152f9fc77450dafbae2a5cb26cb4f74b307..9c2437c376ddd20592d3c8ab1e83ab7297900487 100644 (file)
@@ -21,6 +21,8 @@
 use {Module, NameBindings, Resolver};
 use Namespace::{mod, TypeNS, ValueNS};
 
+use build_reduced_graph;
+
 use rustc::middle::def::Export;
 use syntax::ast;
 use syntax::parse::token;
@@ -73,7 +75,7 @@ fn record_exports_for_module_subtree(&mut self,
         }
 
         self.record_exports_for_module(&*module_);
-        self.populate_module_if_necessary(&module_);
+        build_reduced_graph::populate_module_if_necessary(self.resolver, &module_);
 
         for (_, child_name_bindings) in module_.children.borrow().iter() {
             match child_name_bindings.get_module_if_available() {
index c5d3ad805d93428d013b93507efcc379de8c655c..fb4ae21478bc271258717a5811bc1cc2b4065d6f 100644 (file)
@@ -55,7 +55,7 @@
 use trans::cleanup;
 use trans::closure;
 use trans::common::{Block, C_bool, C_bytes_in_context, C_i32, C_integral};
-use trans::common::{C_null, C_struct_in_context, C_u64, C_u8, C_uint, C_undef};
+use trans::common::{C_null, C_struct_in_context, C_u64, C_u8, C_undef};
 use trans::common::{CrateContext, ExternMap, FunctionContext};
 use trans::common::{NodeInfo, Result};
 use trans::common::{node_id_type, return_type_is_void};
@@ -73,7 +73,7 @@
 use trans::inline;
 use trans::intrinsic;
 use trans::machine;
-use trans::machine::{llsize_of, llsize_of_real, llalign_of_min};
+use trans::machine::{llsize_of, llsize_of_real};
 use trans::meth;
 use trans::monomorphize;
 use trans::tvec;
@@ -396,30 +396,6 @@ pub fn malloc_raw_dyn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     Result::new(r.bcx, PointerCast(r.bcx, r.val, llty_ptr))
 }
 
-pub fn malloc_raw_dyn_proc<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>)
-                                       -> Result<'blk, 'tcx> {
-    let _icx = push_ctxt("malloc_raw_dyn_proc");
-    let ccx = bcx.ccx();
-
-    // Grab the TypeRef type of ptr_ty.
-    let ptr_ty = ty::mk_uniq(bcx.tcx(), t);
-    let ptr_llty = type_of(ccx, ptr_ty);
-
-    let llty = type_of(bcx.ccx(), t);
-    let size = llsize_of(bcx.ccx(), llty);
-    let llalign = C_uint(ccx, llalign_of_min(bcx.ccx(), llty));
-
-    // Allocate space and store the destructor pointer:
-    let Result {bcx, val: llbox} = malloc_raw_dyn(bcx, ptr_llty, t, size, llalign);
-    let dtor_ptr = GEPi(bcx, llbox, &[0u, abi::BOX_FIELD_DROP_GLUE]);
-    let drop_glue_field_ty = type_of(ccx, ty::mk_nil_ptr(bcx.tcx()));
-    let drop_glue = PointerCast(bcx, glue::get_drop_glue(ccx, ty::mk_uniq(bcx.tcx(), t)),
-                                drop_glue_field_ty);
-    Store(bcx, drop_glue, dtor_ptr);
-
-    Result::new(bcx, llbox)
-}
-
 // Type descriptor and type glue stuff
 
 pub fn get_tydesc<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
@@ -2676,6 +2652,8 @@ fn create_entry_fn(ccx: &CrateContext,
         unsafe {
             llvm::LLVMPositionBuilderAtEnd(bld, llbb);
 
+            debuginfo::insert_reference_to_gdb_debug_scripts_section_global(ccx);
+
             let (start_fn, args) = if use_start_lang_item {
                 let start_def_id = match ccx.tcx().lang_items.require(StartFnLangItem) {
                     Ok(id) => id,
index ed3c820f2faf4e999d10ba3417dce30cc6f05522..3723ad07a36ec89d3288285f17a44bcd12fd2d60 100644 (file)
@@ -137,26 +137,6 @@ fn tuplify_box_ty<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> Ty<'tcx> {
     ty::mk_tup(tcx, vec!(tcx.types.uint, ty::mk_nil_ptr(tcx), ptr, ptr, t))
 }
 
-fn allocate_cbox<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                             store: ty::TraitStore,
-                             cdata_ty: Ty<'tcx>)
-                             -> Result<'blk, 'tcx> {
-    let _icx = push_ctxt("closure::allocate_cbox");
-    let tcx = bcx.tcx();
-
-    // Allocate and initialize the box:
-    let cbox_ty = tuplify_box_ty(tcx, cdata_ty);
-    match store {
-        ty::UniqTraitStore => {
-            malloc_raw_dyn_proc(bcx, cbox_ty)
-        }
-        ty::RegionTraitStore(..) => {
-            let llbox = alloc_ty(bcx, cbox_ty, "__closure");
-            Result::new(bcx, llbox)
-        }
-    }
-}
-
 pub struct ClosureResult<'blk, 'tcx: 'blk> {
     llbox: ValueRef,        // llvalue of ptr to closure
     cdata_ty: Ty<'tcx>,     // type of the closure data
@@ -168,8 +148,7 @@ pub struct ClosureResult<'blk, 'tcx: 'blk> {
 // heap allocated closure that copies the upvars into environment.
 // Otherwise, it is stack allocated and copies pointers to the upvars.
 pub fn store_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                                     bound_values: Vec<EnvValue<'tcx>> ,
-                                     store: ty::TraitStore)
+                                     bound_values: Vec<EnvValue<'tcx>>)
                                      -> ClosureResult<'blk, 'tcx> {
     let _icx = push_ctxt("closure::store_environment");
     let ccx = bcx.ccx();
@@ -193,7 +172,7 @@ pub fn store_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     }
 
     // allocate closure in the heap
-    let Result {bcx, val: llbox} = allocate_cbox(bcx, store, cdata_ty);
+    let llbox = alloc_ty(bcx, cbox_ty, "__closure");
 
     let llbox = PointerCast(bcx, llbox, llboxptr_ty);
     debug!("tuplify_box_ty = {}", ty_to_string(tcx, cbox_ty));
@@ -227,8 +206,7 @@ pub fn store_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 // collects the upvars and packages them up for store_environment.
 fn build_closure<'blk, 'tcx>(bcx0: Block<'blk, 'tcx>,
                              freevar_mode: ast::CaptureClause,
-                             freevars: &Vec<ty::Freevar>,
-                             store: ty::TraitStore)
+                             freevars: &Vec<ty::Freevar>)
                              -> ClosureResult<'blk, 'tcx> {
     let _icx = push_ctxt("closure::build_closure");
 
@@ -242,7 +220,7 @@ fn build_closure<'blk, 'tcx>(bcx0: Block<'blk, 'tcx>,
         env_vals.push(EnvValue {action: freevar_mode, datum: datum});
     }
 
-    store_environment(bcx, env_vals, store)
+    store_environment(bcx, env_vals)
 }
 
 // Given an enclosing block context, a new function context, a closure type,
@@ -456,7 +434,7 @@ pub fn trans_expr_fn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         llbox,
         cdata_ty,
         bcx
-    } = build_closure(bcx, freevar_mode, &freevars, store);
+    } = build_closure(bcx, freevar_mode, &freevars);
 
     trans_closure(ccx,
                   decl,
index b5b1c6ff86479a1b1544ca7e540239162a7fb0f5..91989b5f7c08cc2ede3d9ab9f23ecbef3b96a52d 100644 (file)
 use std::rc::{Rc, Weak};
 use syntax::util::interner::Interner;
 use syntax::codemap::{Span, Pos};
-use syntax::{ast, codemap, ast_util, ast_map};
+use syntax::{ast, codemap, ast_util, ast_map, attr};
 use syntax::ast_util::PostExpansionMethod;
 use syntax::parse::token::{mod, special_idents};
 
@@ -741,7 +741,16 @@ pub fn finalize(cx: &CrateContext) {
     }
 
     debug!("finalize");
-    compile_unit_metadata(cx);
+    let _ = compile_unit_metadata(cx);
+
+    if needs_gdb_debug_scripts_section(cx) {
+        // Add a .debug_gdb_scripts section to this compile-unit. This will
+        // cause GDB to try and load the gdb_load_rust_pretty_printers.py file,
+        // which activates the Rust pretty printers for binary this section is
+        // contained in.
+        get_or_insert_gdb_debug_scripts_section_global(cx);
+    }
+
     unsafe {
         llvm::LLVMDIBuilderFinalize(DIB(cx));
         llvm::LLVMDIBuilderDispose(DIB(cx));
@@ -1586,7 +1595,7 @@ fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray {
     };
 }
 
-fn compile_unit_metadata(cx: &CrateContext) {
+fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor {
     let work_dir = &cx.sess().working_dir;
     let compile_unit_name = match cx.sess().local_crate_source_file {
         None => fallback_path(cx),
@@ -1621,7 +1630,7 @@ fn compile_unit_metadata(cx: &CrateContext) {
                            (option_env!("CFG_VERSION")).expect("CFG_VERSION"));
 
     let compile_unit_name = compile_unit_name.as_ptr();
-    work_dir.as_vec().with_c_str(|work_dir| {
+    return work_dir.as_vec().with_c_str(|work_dir| {
         producer.with_c_str(|producer| {
             "".with_c_str(|flags| {
                 "".with_c_str(|split_name| {
@@ -1635,7 +1644,7 @@ fn compile_unit_metadata(cx: &CrateContext) {
                             cx.sess().opts.optimize != config::No,
                             flags,
                             0,
-                            split_name);
+                            split_name)
                     }
                 })
             })
@@ -4112,3 +4121,76 @@ fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTree
         }
     })
 }
+
+
+//=-----------------------------------------------------------------------------
+// .debug_gdb_scripts binary section
+//=-----------------------------------------------------------------------------
+
+/// Inserts a side-effect free instruction sequence that makes sure that the
+/// .debug_gdb_scripts global is referenced, so it isn't removed by the linker.
+pub fn insert_reference_to_gdb_debug_scripts_section_global(ccx: &CrateContext) {
+    if needs_gdb_debug_scripts_section(ccx) {
+        let empty = b"".to_c_str();
+        let gdb_debug_scripts_section_global =
+            get_or_insert_gdb_debug_scripts_section_global(ccx);
+        unsafe {
+            let volative_load_instruction =
+                llvm::LLVMBuildLoad(ccx.raw_builder(),
+                                    gdb_debug_scripts_section_global,
+                                    empty.as_ptr());
+            llvm::LLVMSetVolatile(volative_load_instruction, llvm::True);
+        }
+    }
+}
+
+/// Allocates the global variable responsible for the .debug_gdb_scripts binary
+/// section.
+fn get_or_insert_gdb_debug_scripts_section_global(ccx: &CrateContext)
+                                                  -> llvm::ValueRef {
+    let section_var_name = b"__rustc_debug_gdb_scripts_section__".to_c_str();
+
+    let section_var = unsafe {
+        llvm::LLVMGetNamedGlobal(ccx.llmod(), section_var_name.as_ptr())
+    };
+
+    if section_var == ptr::null_mut() {
+        let section_name = b".debug_gdb_scripts".to_c_str();
+        let section_contents = b"\x01gdb_load_rust_pretty_printers.py\0";
+
+        unsafe {
+            let llvm_type = Type::array(&Type::i8(ccx),
+                                        section_contents.len() as u64);
+            let section_var = llvm::LLVMAddGlobal(ccx.llmod(),
+                                                  llvm_type.to_ref(),
+                                                  section_var_name.as_ptr());
+            llvm::LLVMSetSection(section_var, section_name.as_ptr());
+            llvm::LLVMSetInitializer(section_var, C_bytes(ccx, section_contents));
+            llvm::LLVMSetGlobalConstant(section_var, llvm::True);
+            llvm::LLVMSetUnnamedAddr(section_var, llvm::True);
+            llvm::SetLinkage(section_var, llvm::Linkage::LinkOnceODRLinkage);
+            // This should make sure that the whole section is not larger than
+            // the string it contains. Otherwise we get a warning from GDB.
+            llvm::LLVMSetAlignment(section_var, 1);
+            section_var
+        }
+    } else {
+        section_var
+    }
+}
+
+fn needs_gdb_debug_scripts_section(ccx: &CrateContext) -> bool {
+    let omit_gdb_pretty_printer_section =
+        attr::contains_name(ccx.tcx()
+                               .map
+                               .krate()
+                               .attrs
+                               .as_slice(),
+                            "omit_gdb_pretty_printer_section");
+
+    !omit_gdb_pretty_printer_section &&
+    !ccx.sess().target.target.options.is_like_osx &&
+    !ccx.sess().target.target.options.is_like_windows &&
+    ccx.sess().opts.debuginfo != NoDebugInfo
+}
+
index 23a8643aadcf535da46ce16952766268bba05628..f153b51c5df7798f175bb3eec8b0f4725696dae0 100644 (file)
@@ -190,11 +190,13 @@ fn check_object_safety_inner<'tcx>(tcx: &ty::ctxt<'tcx>,
         }
     }
 
-    /// Returns a vec of error messages. If hte vec is empty - no errors!
+    /// Returns a vec of error messages. If the vec is empty - no errors!
     ///
     /// There are some limitations to calling functions through an object, because (a) the self
     /// type is not known (that's the whole point of a trait instance, after all, to obscure the
-    /// self type) and (b) the call must go through a vtable and hence cannot be monomorphized.
+    /// self type), (b) the call must go through a vtable and hence cannot be monomorphized and
+    /// (c) the trait contains static methods which can't be called because we don't know the
+    /// concrete type.
     fn check_object_safety_of_method<'tcx>(tcx: &ty::ctxt<'tcx>,
                                            object_trait: &ty::PolyTraitRef<'tcx>,
                                            method: &ty::Method<'tcx>)
@@ -210,9 +212,11 @@ fn check_object_safety_of_method<'tcx>(tcx: &ty::ctxt<'tcx>,
             }
 
             ty::StaticExplicitSelfCategory => {
-                // Static methods are always object-safe since they
-                // can't be called through a trait object
-                return msgs
+                // Static methods are never object safe (reason (c)).
+                msgs.push(format!("cannot call a static method (`{}`) \
+                                   through a trait object",
+                                  method_name));
+                return msgs;
             }
             ty::ByReferenceExplicitSelfCategory(..) |
             ty::ByBoxExplicitSelfCategory => {}
index f28abcc10cfd8dcf0d651005566e08a61a67834c..8dbaab564ba2bfcaf5a633151bcaba5798224ee3 100644 (file)
@@ -486,6 +486,8 @@ fn check_for_null(v: &[u8], buf: *mut libc::c_char) {
 /// External iterator for a CString's bytes.
 ///
 /// Use with the `std::iter` module.
+#[allow(raw_pointer_deriving)]
+#[deriving(Clone)]
 pub struct CChars<'a> {
     ptr: *const libc::c_char,
     marker: marker::ContravariantLifetime<'a>,
index 7b7473b2c993c27d3cd13d6e9cd86034f3eed7ab..8181ea5253f9395faf18bca54b050dbdec1b61c7 100644 (file)
@@ -1261,6 +1261,7 @@ pub fn get_copy(&self, k: &K) -> V {
     }
 }
 
+#[stable]
 impl<K: Eq + Hash<S>, V: PartialEq, S, H: Hasher<S>> PartialEq for HashMap<K, V, H> {
     fn eq(&self, other: &HashMap<K, V, H>) -> bool {
         if self.len() != other.len() { return false; }
@@ -1271,6 +1272,7 @@ fn eq(&self, other: &HashMap<K, V, H>) -> bool {
     }
 }
 
+#[stable]
 impl<K: Eq + Hash<S>, V: Eq, S, H: Hasher<S>> Eq for HashMap<K, V, H> {}
 
 impl<K: Eq + Hash<S> + Show, V: Show, S, H: Hasher<S>> Show for HashMap<K, V, H> {
@@ -1317,6 +1319,15 @@ pub struct Iter<'a, K: 'a, V: 'a> {
     inner: table::Iter<'a, K, V>
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<'a, K, V> Clone for Entries<'a, K, V> {
+    fn clone(&self) -> Entries<'a, K, V> {
+        Entries {
+            inner: self.inner.clone()
+        }
+    }
+}
+
 /// HashMap mutable values iterator
 pub struct IterMut<'a, K: 'a, V: 'a> {
     inner: table::IterMut<'a, K, V>
@@ -1337,11 +1348,29 @@ pub struct Keys<'a, K: 'a, V: 'a> {
     inner: Map<(&'a K, &'a V), &'a K, Iter<'a, K, V>, fn((&'a K, &'a V)) -> &'a K>
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<'a, K, V> Clone for Keys<'a, K, V> {
+    fn clone(&self) -> Keys<'a, K, V> {
+        Keys {
+            inner: self.inner.clone()
+        }
+    }
+}
+
 /// HashMap values iterator
 pub struct Values<'a, K: 'a, V: 'a> {
     inner: Map<(&'a K, &'a V), &'a V, Iter<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<'a, K, V> Clone for Values<'a, K, V> {
+    fn clone(&self) -> Values<'a, K, V> {
+        Values {
+            inner: self.inner.clone()
+        }
+    }
+}
+
 /// HashMap drain iterator
 pub struct Drain<'a, K: 'a, V: 'a> {
     inner: iter::Map<
index 6d83d5510b35735603d535dd01974c68bca04cfa..93f6895f6885b519dc8311076cd6c986e9f7cf23 100644 (file)
@@ -572,6 +572,7 @@ pub fn remove<Sized? Q>(&mut self, value: &Q) -> bool
     }
 }
 
+#[stable]
 impl<T: Eq + Hash<S>, S, H: Hasher<S>> PartialEq for HashSet<T, H> {
     fn eq(&self, other: &HashSet<T, H>) -> bool {
         if self.len() != other.len() { return false; }
@@ -580,6 +581,7 @@ fn eq(&self, other: &HashSet<T, H>) -> bool {
     }
 }
 
+#[stable]
 impl<T: Eq + Hash<S>, S, H: Hasher<S>> Eq for HashSet<T, H> {}
 
 impl<T: Eq + Hash<S> + fmt::Show, S, H: Hasher<S>> fmt::Show for HashSet<T, H> {
index f76b8ac3326f5bec2d5d5ddb743d199bc74a221d..f5fbfcabcfb71d7232044f846da6c4c036fe2290 100644 (file)
@@ -718,6 +718,18 @@ struct RawBuckets<'a, K, V> {
     marker: marker::ContravariantLifetime<'a>,
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<'a, K, V> Clone for RawBuckets<'a, K, V> {
+    fn clone(&self) -> RawBuckets<'a, K, V> {
+        RawBuckets {
+            raw: self.raw,
+            hashes_end: self.hashes_end,
+            marker: marker::ContravariantLifetime,
+        }
+    }
+}
+
+
 impl<'a, K, V> Iterator<RawBucket<K, V>> for RawBuckets<'a, K, V> {
     fn next(&mut self) -> Option<RawBucket<K, V>> {
         while self.raw.hash != self.hashes_end {
@@ -775,6 +787,17 @@ pub struct Iter<'a, K: 'a, V: 'a> {
     elems_left: uint,
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<'a, K, V> Clone for Entries<'a, K, V> {
+    fn clone(&self) -> Entries<'a, K, V> {
+        Entries {
+            iter: self.iter.clone(),
+            elems_left: self.elems_left
+        }
+    }
+}
+
+
 /// Iterator over mutable references to entries in a table.
 pub struct IterMut<'a, K: 'a, V: 'a> {
     iter: RawBuckets<'a, K, V>,
index caa6590bb28212bd7cb8dc192d1c4bed0bbc0c56..e4c31ff8dd321a5f1c515721547667bb6dbf978f 100644 (file)
@@ -558,6 +558,7 @@ pub fn walk_dir(path: &Path) -> IoResult<Directories> {
 }
 
 /// An iterator that walks over a directory
+#[deriving(Clone)]
 pub struct Directories {
     stack: Vec<Path>,
 }
index 69ba64d856e7f325b2781f98dfef299ea7b4c485..e8fbb12118199f9912c291ea409c6dd2dcaa1dc7 100644 (file)
@@ -10,8 +10,8 @@
 
 //! Synchronous DNS Resolution
 //!
-//! Contains the functionality to perform DNS resolution in a style related to
-//! `getaddrinfo()`
+//! Contains the functionality to perform DNS resolution or reverse lookup,
+//! in a style related to `getaddrinfo()` and `getnameinfo()`, respectively.
 
 #![allow(missing_docs)]
 
@@ -24,6 +24,7 @@
 use io::net::ip::{SocketAddr, IpAddr};
 use option::Option;
 use option::Option::{Some, None};
+use string::String;
 use sys;
 use vec::Vec;
 
@@ -83,6 +84,12 @@ pub fn get_host_addresses(host: &str) -> IoResult<Vec<IpAddr>> {
     lookup(Some(host), None, None).map(|a| a.into_iter().map(|i| i.address.ip).collect())
 }
 
+/// Reverse name resolution. Given an address, returns the corresponding
+/// hostname.
+pub fn get_address_name(addr: IpAddr) -> IoResult<String> {
+    sys::addrinfo::get_address_name(addr)
+}
+
 /// Full-fledged resolution. This function will perform a synchronous call to
 /// getaddrinfo, controlled by the parameters
 ///
index 6c8e4eea40fdc442b5f799b2ceb140e83eedd500..fa04efce86edeaffdc65392238cfe926e932e42b 100644 (file)
 //! ```
 
 use self::StdSource::*;
+use prelude::*;
 
-use boxed::Box;
 use cell::RefCell;
-use clone::Clone;
 use failure::LOCAL_STDERR;
 use fmt;
-use io::{Reader, Writer, IoResult, IoError, OtherIoError, Buffer,
-         standard_error, EndOfFile, LineBufferedWriter, BufferedReader};
-use kinds::{Sync, Send};
+use io::{IoResult, IoError, OtherIoError};
+use io::{standard_error, EndOfFile, LineBufferedWriter, BufferedReader};
 use libc;
 use mem;
-use option::Option;
-use option::Option::{Some, None};
-use ops::{Deref, DerefMut, FnOnce};
-use result::Result::{Ok, Err};
 use rt;
-use slice::SliceExt;
-use str::StrExt;
-use string::String;
 use sys::{fs, tty};
-use sync::{Arc, Mutex, MutexGuard, Once, ONCE_INIT};
+use sync::{Arc, Mutex, MutexGuard, StaticMutex, MUTEX_INIT};
 use uint;
-use vec::Vec;
 
 // And so begins the tale of acquiring a uv handle to a stdio stream on all
 // platforms in all situations. Our story begins by splitting the world into two
@@ -215,14 +205,15 @@ fn read_be_uint_n(&mut self, nbytes: uint) -> IoResult<u64> {
 pub fn stdin() -> StdinReader {
     // We're following the same strategy as kimundi's lazy_static library
     static mut STDIN: *const StdinReader = 0 as *const StdinReader;
-    static ONCE: Once = ONCE_INIT;
+    static LOCK: StaticMutex = MUTEX_INIT;
 
     unsafe {
-        ONCE.doit(|| {
-            // The default buffer capacity is 64k, but apparently windows doesn't like
-            // 64k reads on stdin. See #13304 for details, but the idea is that on
-            // windows we use a slightly smaller buffer that's been seen to be
-            // acceptable.
+        let _g = LOCK.lock();
+        if STDIN as uint == 0 {
+            // The default buffer capacity is 64k, but apparently windows
+            // doesn't like 64k reads on stdin. See #13304 for details, but the
+            // idea is that on windows we use a slightly smaller buffer that's
+            // been seen to be acceptable.
             let stdin = if cfg!(windows) {
                 BufferedReader::with_capacity(8 * 1024, stdin_raw())
             } else {
@@ -235,11 +226,15 @@ pub fn stdin() -> StdinReader {
 
             // Make sure to free it at exit
             rt::at_exit(|| {
-                mem::transmute::<_, Box<StdinReader>>(STDIN);
-                STDIN = 0 as *const _;
+                let g = LOCK.lock();
+                let stdin = STDIN;
+                STDIN = 1 as *const _;
+                drop(g);
+                mem::transmute::<_, Box<StdinReader>>(stdin);
             });
-        });
-
+        } else if STDIN as uint == 1 {
+            panic!("accessing stdin after the main thread has exited")
+        }
         (*STDIN).clone()
     }
 }
index 90d7c1388a196e56800786c23fa3d20627b8dede..2a98067c970804ad265491a94bb29cfd55967999 100644 (file)
@@ -163,6 +163,7 @@ fn flush(&mut self) -> io::IoResult<()> {
 
 /// A `Reader` which chains input from multiple `Reader`s, reading each to
 /// completion before moving onto the next.
+#[deriving(Clone)]
 pub struct ChainedReader<I, R> {
     readers: I,
     cur_reader: Option<R>,
@@ -246,6 +247,7 @@ pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) -> io::IoResult<()> {
 }
 
 /// An adaptor converting an `Iterator<u8>` to a `Reader`.
+#[deriving(Clone)]
 pub struct IterReader<T> {
     iter: T,
 }
index 8274baeacfad8378bb798da295f24f0982d4c7ee..5c70340fe102e7963f7388b3862b127fbc5a29a6 100644 (file)
 pub mod sync;
 pub mod comm;
 
+#[path = "sys/common/mod.rs"] mod sys_common;
+
 #[cfg(unix)]
 #[path = "sys/unix/mod.rs"] mod sys;
 #[cfg(windows)]
 #[path = "sys/windows/mod.rs"] mod sys;
 
-#[path = "sys/common/mod.rs"] mod sys_common;
-
 pub mod rt;
 mod failure;
 
index 46c3a4f622a5448defd13e981288eede71929b52..91b6a1f0ce0ce8a8e176634c642693e8cafbf1ab 100644 (file)
@@ -170,6 +170,7 @@ mod imp {
     extern crate libc;
 
     use io::{IoResult};
+    use kinds::Sync;
     use mem;
     use os;
     use rand::Rng;
@@ -196,6 +197,8 @@ pub struct OsRng {
     #[repr(C)]
     struct SecRandom;
 
+    unsafe impl Sync for *const SecRandom {}
+
     #[allow(non_upper_case_globals)]
     static kSecRandomDefault: *const SecRandom = 0 as *const SecRandom;
 
index 5823f8453d84a3ffc8f87d7f2efe137db6786932..08dabd3b0b6038c86c9ad1bbe0a665ea7c733add 100644 (file)
@@ -29,6 +29,8 @@
 static LOCK: Mutex = MUTEX_INIT;
 static mut QUEUE: *mut Queue = 0 as *mut Queue;
 
+const DTOR_RUN_ITERS: uint = 10;
+
 unsafe fn init() {
     if QUEUE.is_null() {
         let state: Box<Queue> = box Vec::new();
@@ -49,7 +51,7 @@ pub fn cleanup() {
     unsafe {
         LOCK.lock();
         let queue = QUEUE;
-        QUEUE = 1 as *mut _;
+        QUEUE = 1u as *mut _;
         LOCK.unlock();
 
         // make sure we're not recursively cleaning up
index e877dd5c6aab813ba5689070940299b667d5df1a..a4421f23c50b606a79e9b6acb41971221c42a4ea 100644 (file)
@@ -92,9 +92,7 @@ fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
         // but we just do this to name the main thread and to give it correct
         // info about the stack bounds.
         let thread: Thread = NewThread::new(Some("<main>".to_string()));
-        thread_info::set((my_stack_bottom, my_stack_top),
-                         sys::thread::guard::main(),
-                         thread);
+        thread_info::set(sys::thread::guard::main(), thread);
 
         // By default, some platforms will send a *signal* when a EPIPE error
         // would otherwise be delivered. This runtime doesn't install a SIGPIPE
@@ -133,20 +131,14 @@ fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
     }
 }
 
-/// Enqueues a procedure to run when the runtime is cleaned up
-///
-/// The procedure passed to this function will be executed as part of the
-/// runtime cleanup phase. For normal rust programs, this means that it will run
-/// after all other threads have exited.
-///
-/// The procedure is *not* executed with a local `Thread` available to it, so
-/// primitives like logging, I/O, channels, spawning, etc, are *not* available.
-/// This is meant for "bare bones" usage to clean up runtime details, this is
-/// not meant as a general-purpose "let's clean everything up" function.
+/// Enqueues a procedure to run when the main thread exits.
 ///
 /// It is forbidden for procedures to register more `at_exit` handlers when they
 /// are running, and doing so will lead to a process abort.
-pub fn at_exit<F:FnOnce()+Send>(f: F) {
+///
+/// Note that other threads may still be running when `at_exit` routines start
+/// running.
+pub fn at_exit<F: FnOnce() + Send>(f: F) {
     at_exit_imp::push(Thunk::new(f));
 }
 
@@ -162,8 +154,5 @@ pub fn at_exit<F:FnOnce()+Send>(f: F) {
 pub unsafe fn cleanup() {
     args::cleanup();
     sys::stack_overflow::cleanup();
-    // FIXME: (#20012): the resources being cleaned up by at_exit
-    // currently are not prepared for cleanup to happen asynchronously
-    // with detached threads using the resources; for now, we leak.
-    // at_exit_imp::cleanup();
+    at_exit_imp::cleanup();
 }
index 9b57dcc9e18bfc941cb4657cf198738ff620097d..32fa126ded4b5d2d84a98663d817a5caf21052dc 100644 (file)
@@ -68,7 +68,7 @@
 use libc::c_void;
 use mem;
 use sync::atomic;
-use sync::{Once, ONCE_INIT};
+use sys_common::mutex::{Mutex, MUTEX_INIT};
 
 use rt::libunwind as uw;
 
@@ -587,11 +587,20 @@ pub fn begin_unwind<M: Any + Send>(msg: M, file_line: &(&'static str, uint)) ->
 /// Doing this split took the LLVM IR line counts of `fn main() { panic!()
 /// }` from ~1900/3700 (-O/no opts) to 180/590.
 #[inline(never)] #[cold] // this is the slow path, please never inline this
-fn begin_unwind_inner(msg: Box<Any + Send>, file_line: &(&'static str, uint)) -> ! {
+fn begin_unwind_inner(msg: Box<Any + Send>,
+                      file_line: &(&'static str, uint)) -> ! {
     // Make sure the default failure handler is registered before we look at the
     // callbacks.
-    static INIT: Once = ONCE_INIT;
-    INIT.doit(|| unsafe { register(failure::on_fail); });
+    unsafe {
+        static LOCK: Mutex = MUTEX_INIT;
+        static mut INIT: bool = false;
+        LOCK.lock();
+        if !INIT {
+            register(failure::on_fail);
+            INIT = true;
+        }
+        LOCK.unlock();
+    }
 
     // First, invoke call the user-defined callbacks triggered on thread panic.
     //
index bdf947438f36bd617093a36cf57868eab2a9e488..18c917aca8a4aba2102adb4f7785fadee4f3786d 100644 (file)
 use core::prelude::{Send, Drop, None, Option, Some};
 
 pub use core::atomic::{AtomicBool, AtomicInt, AtomicUint, AtomicPtr};
-pub use core::atomic::{Ordering, Relaxed, Release, Acquire, AcqRel, SeqCst};
 pub use core::atomic::{INIT_ATOMIC_BOOL, INIT_ATOMIC_INT, INIT_ATOMIC_UINT};
 pub use core::atomic::fence;
+pub use core::atomic::Ordering::{mod, Relaxed, Release, Acquire, AcqRel, SeqCst};
 
 /// An atomic, nullable unique pointer
 ///
index 9ef1c33312fc8b4ac6c5a6e354ce0caa12bcc0b2..7093c417b1140540d961c3c9701364a7af520bf6 100644 (file)
@@ -20,6 +20,8 @@
 //! can be created in the future and there must be no active timers at that
 //! time.
 
+#![macro_escape]
+
 use prelude::*;
 
 use cell::UnsafeCell;
@@ -68,6 +70,17 @@ unsafe impl<M:Send> Sync for Helper<M> { }
 unsafe impl Send for RaceBox {}
 unsafe impl Sync for RaceBox {}
 
+macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => (
+    static $name: Helper<$m> = Helper {
+        lock: ::sync::MUTEX_INIT,
+        cond: ::sync::CONDVAR_INIT,
+        chan: ::cell::UnsafeCell { value: 0 as *mut Sender<$m> },
+        signal: ::cell::UnsafeCell { value: 0 },
+        initialized: ::cell::UnsafeCell { value: false },
+        shutdown: ::cell::UnsafeCell { value: false },
+    };
+) }
+
 impl<M: Send> Helper<M> {
     /// Lazily boots a helper thread, becoming a no-op if the helper has already
     /// been spawned.
@@ -84,7 +97,7 @@ pub fn boot<T, F>(&'static self, f: F, helper: fn(helper_signal::signal, Receive
     {
         unsafe {
             let _guard = self.lock.lock().unwrap();
-            if !*self.initialized.get() {
+            if *self.chan.get() as uint == 0 {
                 let (tx, rx) = channel();
                 *self.chan.get() = mem::transmute(box tx);
                 let (receive, send) = helper_signal::new();
@@ -93,15 +106,17 @@ pub fn boot<T, F>(&'static self, f: F, helper: fn(helper_signal::signal, Receive
                 let receive = RaceBox(receive);
 
                 let t = f();
-                Thread::spawn(move |:| {
+                Thread::spawn(move || {
                     helper(receive.0, rx, t);
                     let _g = self.lock.lock().unwrap();
                     *self.shutdown.get() = true;
                     self.cond.notify_one()
                 }).detach();
 
-                rt::at_exit(move|:| { self.shutdown() });
+                rt::at_exit(move || { self.shutdown() });
                 *self.initialized.get() = true;
+            } else if *self.chan.get() as uint == 1 {
+                panic!("cannot continue usage after shutdown");
             }
         }
     }
@@ -116,7 +131,9 @@ pub fn send(&'static self, msg: M) {
             // Must send and *then* signal to ensure that the child receives the
             // message. Otherwise it could wake up and go to sleep before we
             // send the message.
-            assert!(!self.chan.get().is_null());
+            assert!(*self.chan.get() as uint != 0);
+            assert!(*self.chan.get() as uint != 1,
+                    "cannot continue usage after shutdown");
             (**self.chan.get()).send(msg);
             helper_signal::signal(*self.signal.get() as helper_signal::signal);
         }
@@ -129,9 +146,13 @@ fn shutdown(&'static self) {
             // returns.
             let mut guard = self.lock.lock().unwrap();
 
+            let ptr = *self.chan.get();
+            if ptr as uint == 1 {
+                panic!("cannot continue usage after shutdown");
+            }
             // Close the channel by destroying it
             let chan: Box<Sender<M>> = mem::transmute(*self.chan.get());
-            *self.chan.get() = 0 as *mut Sender<M>;
+            *self.chan.get() = 1 as *mut Sender<M>;
             drop(chan);
             helper_signal::signal(*self.signal.get() as helper_signal::signal);
 
index dc0ad08cdbef637100a7f8477897af5643ddcedf..6b2b325e638d798fc88fd50cdf85605688655361 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #![allow(missing_docs)]
-#![allow(dead_code)]
+#![macro_escape]
 
 use io::{mod, IoError, IoResult};
 use prelude::*;
index 567c26956efe94f6c3a1e62d440b7e75b9d46035..322d2f202f7728436a2f3dd509cb5f16394e6d97 100644 (file)
@@ -29,6 +29,7 @@ impl Mutex {
     /// Behavior is undefined if the mutex is moved after the first method is
     /// called on the mutex.
     #[inline]
+    #[allow(dead_code)] // sys is not exported yet
     pub unsafe fn new() -> Mutex { Mutex(imp::Mutex::new()) }
 
     /// Lock the mutex blocking the current thread until it is available.
index 7a09137a225dca5e21dc6d68994a9c71ee947e63..552d1c201da548b27fb087eb7d6d2e2864f46c80 100644 (file)
@@ -13,6 +13,7 @@
 
 use alloc::arc::Arc;
 use libc::{mod, c_char, c_int};
+use c_str::CString;
 use mem;
 use num::Int;
 use ptr::{mod, null, null_mut};
@@ -22,7 +23,9 @@
 use sys::{mod, retry, c, sock_t, last_error, last_net_error, last_gai_error, close_sock,
           wrlen, msglen_t, os, wouldblock, set_nonblocking, timer, ms_to_timeval,
           decode_error_detailed};
-use sync::{Mutex, MutexGuard};
+use sync::Mutex;
+#[cfg(not(target_os = "linux"))]
+use sync::MutexGuard;
 use sys_common::{mod, keep_going, short_write, timeout};
 use prelude::*;
 use cmp;
@@ -290,6 +293,43 @@ pub fn get_host_addresses(host: Option<&str>, servname: Option<&str>,
     Ok(addrs)
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// get_address_name
+////////////////////////////////////////////////////////////////////////////////
+
+extern "system" {
+    fn getnameinfo(sa: *const libc::sockaddr, salen: libc::socklen_t,
+        host: *mut c_char, hostlen: libc::size_t,
+        serv: *mut c_char, servlen: libc::size_t,
+        flags: c_int) -> c_int;
+}
+
+const NI_MAXHOST: uint = 1025;
+
+pub fn get_address_name(addr: IpAddr) -> Result<String, IoError> {
+    let addr = SocketAddr{ip: addr, port: 0};
+
+    let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
+    let len = addr_to_sockaddr(addr, &mut storage);
+
+    let mut hostbuf = [0 as c_char, ..NI_MAXHOST];
+
+    let res = unsafe {
+        getnameinfo(&storage as *const _ as *const libc::sockaddr, len,
+            hostbuf.as_mut_ptr(), NI_MAXHOST as libc::size_t,
+            ptr::null_mut(), 0,
+            0)
+    };
+
+    if res != 0 {
+        return Err(last_gai_error(res));
+    }
+
+    unsafe {
+        Ok(CString::new(hostbuf.as_ptr(), false).as_str().unwrap().to_string())
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Timeout helpers
 //
@@ -573,11 +613,13 @@ impl Drop for Inner {
     fn drop(&mut self) { unsafe { close_sock(self.fd); } }
 }
 
+#[cfg(not(target_os = "linux"))]
 pub struct Guard<'a> {
     pub fd: sock_t,
     pub guard: MutexGuard<'a, ()>,
 }
 
+#[cfg(not(target_os = "linux"))]
 #[unsafe_destructor]
 impl<'a> Drop for Guard<'a> {
     fn drop(&mut self) {
index df016b9e293b7fb44e20aecd4ccdca1acd94429f..b7c4cfcd0f5fef8e758715ead568e4ac32fad3ec 100644 (file)
@@ -26,6 +26,7 @@ impl RWLock {
     /// Usage of an RWLock is undefined if it is moved after its first use (any
     /// function calls below).
     #[inline]
+    #[allow(dead_code)] // sys is not exported yet
     pub unsafe fn new() -> RWLock { RWLock(imp::RWLock::new()) }
 
     /// Acquire shared access to the underlying lock, blocking the current
index 2a88e20c8fa1f1e727cdc1546812e48fa30fde81..1966a9544e1a5205dcdcbd1cec78a0c99b05e44c 100644 (file)
@@ -121,37 +121,6 @@ pub unsafe fn record_os_managed_stack_bounds(stack_lo: uint, _stack_hi: uint) {
     record_sp_limit(stack_lo + RED_ZONE);
 }
 
-#[inline(always)]
-pub unsafe fn record_rust_managed_stack_bounds(stack_lo: uint, stack_hi: uint) {
-    // When the old runtime had segmented stacks, it used a calculation that was
-    // "limit + RED_ZONE + FUDGE". The red zone was for things like dynamic
-    // symbol resolution, llvm function calls, etc. In theory this red zone
-    // value is 0, but it matters far less when we have gigantic stacks because
-    // we don't need to be so exact about our stack budget. The "fudge factor"
-    // was because LLVM doesn't emit a stack check for functions < 256 bytes in
-    // size. Again though, we have giant stacks, so we round all these
-    // calculations up to the nice round number of 20k.
-    record_sp_limit(stack_lo + RED_ZONE);
-
-    return target_record_stack_bounds(stack_lo, stack_hi);
-
-    #[cfg(not(windows))] #[inline(always)]
-    unsafe fn target_record_stack_bounds(_stack_lo: uint, _stack_hi: uint) {}
-
-    #[cfg(all(windows, target_arch = "x86"))] #[inline(always)]
-    unsafe fn target_record_stack_bounds(stack_lo: uint, stack_hi: uint) {
-        // stack range is at TIB: %fs:0x04 (top) and %fs:0x08 (bottom)
-        asm!("mov $0, %fs:0x04" :: "r"(stack_hi) :: "volatile");
-        asm!("mov $0, %fs:0x08" :: "r"(stack_lo) :: "volatile");
-    }
-    #[cfg(all(windows, target_arch = "x86_64"))] #[inline(always)]
-    unsafe fn target_record_stack_bounds(stack_lo: uint, stack_hi: uint) {
-        // stack range is at TIB: %gs:0x08 (top) and %gs:0x10 (bottom)
-        asm!("mov $0, %gs:0x08" :: "r"(stack_hi) :: "volatile");
-        asm!("mov $0, %gs:0x10" :: "r"(stack_lo) :: "volatile");
-    }
-}
-
 /// Records the current limit of the stack as specified by `end`.
 ///
 /// This is stored in an OS-dependent location, likely inside of the thread
index dc21feb17a8e83c660788c6d720399debf17cb8c..f32c1ea3658bfcb9bfda78f6b59baa06e8750de4 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(dead_code)] // stack_guard isn't used right now on all platforms
+
 use core::prelude::*;
 
 use thread::Thread;
 use string::String;
 
 struct ThreadInfo {
-    // This field holds the known bounds of the stack in (lo, hi)
-    // form. Not all threads necessarily know their precise bounds,
-    // hence this is optional.
-    stack_bounds: (uint, uint),
     stack_guard: uint,
     thread: Thread,
 }
@@ -35,7 +33,6 @@ fn with<R>(f: |&mut ThreadInfo| -> R) -> R {
         THREAD_INFO.with(|c| {
             if c.borrow().is_none() {
                 *c.borrow_mut() = Some(ThreadInfo {
-                    stack_bounds: (0, 0),
                     stack_guard: 0,
                     thread: NewThread::new(None),
                 })
@@ -53,10 +50,9 @@ pub fn stack_guard() -> uint {
     ThreadInfo::with(|info| info.stack_guard)
 }
 
-pub fn set(stack_bounds: (uint, uint), stack_guard: uint, thread: Thread) {
+pub fn set(stack_guard: uint, thread: Thread) {
     THREAD_INFO.with(|c| assert!(c.borrow().is_none()));
     THREAD_INFO.with(move |c| *c.borrow_mut() = Some(ThreadInfo{
-        stack_bounds: stack_bounds,
         stack_guard: stack_guard,
         thread: thread,
     }));
index fe7a7d8d0371688540bd19b327340f7a5b268afe..cc69fbceacb335908986bad39ea286b3d723b27c 100644 (file)
 //! ```
 
 #![allow(non_camel_case_types)]
+#![allow(dead_code)] // sys isn't exported yet
 
 use prelude::*;
 
 use sync::atomic::{mod, AtomicUint};
-use sync::{Mutex, Once, ONCE_INIT};
 
 use sys::thread_local as imp;
 
@@ -140,9 +140,6 @@ pub struct Key {
     key: atomic::INIT_ATOMIC_UINT,
 };
 
-static INIT_KEYS: Once = ONCE_INIT;
-static mut KEYS: *mut Mutex<Vec<imp::Key>> = 0 as *mut _;
-
 impl StaticKey {
     /// Gets the value associated with this TLS key
     ///
index ddae9a132c31483a88b79286e6d3c1c747a872df..0ec34fb1318210fbe8e05c0443db348d1be42e82 100644 (file)
 /// to symbols. This is a bit of a hokey implementation as-is, but it works for
 /// all unix platforms we support right now, so it at least gets the job done.
 
+use prelude::*;
+
 use c_str::CString;
-use io::{IoResult, Writer};
+use io::IoResult;
 use libc;
 use mem;
-use option::Option::{mod, Some, None};
-use result::Result::{Ok, Err};
 use sync::{StaticMutex, MUTEX_INIT};
 
 use sys_common::backtrace::*;
@@ -151,7 +151,7 @@ struct Context<'a> {
     // I/O done here is blocking I/O, not green I/O, so we don't have to
     // worry about this being a native vs green mutex.
     static LOCK: StaticMutex = MUTEX_INIT;
-    let _g = unsafe { LOCK.lock() };
+    let _g = LOCK.lock();
 
     try!(writeln!(w, "stack backtrace:"));
 
@@ -241,12 +241,8 @@ fn dladdr(addr: *const libc::c_void,
 
 #[cfg(not(any(target_os = "macos", target_os = "ios")))]
 fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
-    use iter::{Iterator, IteratorExt};
     use os;
-    use path::GenericPath;
-    use ptr::PtrExt;
     use ptr;
-    use slice::SliceExt;
 
     ////////////////////////////////////////////////////////////////////////
     // libbacktrace.h API
index a4ebcbd25d00efc345345c66b8562ff551104cd4..208dc60e405dcb87d109b7c82f6273dd55c83069 100644 (file)
@@ -214,8 +214,8 @@ pub struct sigaction {
         sa_resv: [libc::c_int, ..1],
     }
 
-    impl ::kinds::Send for sigaction { }
-    impl ::kinds::Sync for sigaction { }
+    unsafe impl ::kinds::Send for sigaction { }
+    unsafe impl ::kinds::Sync for sigaction { }
 
     #[repr(C)]
     pub struct sigset_t {
index 4b7ac8ff4d3a962e3f3c33dce1e784f0cd1e93d6..dd4141de998a962322312ed500177c1d8d57a326 100644 (file)
 
 #![allow(missing_docs)]
 #![allow(non_camel_case_types)]
-#![allow(unused_imports)]
-#![allow(dead_code)]
-#![allow(unused_unsafe)]
-#![allow(unused_mut)]
 
 extern crate libc;
 
-use num;
 use num::{Int, SignedInt};
 use prelude::*;
 use io::{mod, IoResult, IoError};
 use sys_common::mkerr_libc;
 
-macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => (
-    static $name: Helper<$m> = Helper {
-        lock: ::sync::MUTEX_INIT,
-        cond: ::sync::CONDVAR_INIT,
-        chan: ::cell::UnsafeCell { value: 0 as *mut Sender<$m> },
-        signal: ::cell::UnsafeCell { value: 0 },
-        initialized: ::cell::UnsafeCell { value: false },
-        shutdown: ::cell::UnsafeCell { value: false },
-    };
-) }
-
 pub mod backtrace;
 pub mod c;
 pub mod ext;
@@ -56,6 +40,7 @@ macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => (
 
 pub mod addrinfo {
     pub use sys_common::net::get_host_addresses;
+    pub use sys_common::net::get_address_name;
 }
 
 // FIXME: move these to c module
index 81f8659d6ae08b87c79c247655ab1c68a668a1ba..c9cb46b0289f12893f894e9261770e7b84afc46d 100644 (file)
@@ -11,7 +11,6 @@
 use cell::UnsafeCell;
 use kinds::Sync;
 use sys::sync as ffi;
-use sys_common::mutex;
 
 pub struct Mutex { inner: UnsafeCell<ffi::pthread_mutex_t> }
 
@@ -26,6 +25,7 @@ pub unsafe fn raw(m: &Mutex) -> *mut ffi::pthread_mutex_t {
 
 unsafe impl Sync for Mutex {}
 
+#[allow(dead_code)] // sys isn't exported yet
 impl Mutex {
     #[inline]
     pub unsafe fn new() -> Mutex {
index cafe52f8403b6d312c1d6c66f079d49b7c76a92b..446960ab92f4b9da1677126bd1879934e14fcc6e 100644 (file)
 
 //! Implementation of `std::os` functionality for unix systems
 
+#![allow(unused_imports)] // lots of cfg code here
+
 use prelude::*;
 
-use error::{FromError, Error};
-use fmt;
 use io::{IoError, IoResult};
-use libc::{mod, c_int, c_char, c_void};
+use libc::{mod, c_int, c_char};
+use os;
 use path::BytesContainer;
 use ptr;
-use sync::atomic::{AtomicInt, INIT_ATOMIC_INT, SeqCst};
 use sys::fs::FileDesc;
-use os;
 
 use os::TMPBUF_SZ;
 
index 868b460aa5ed3897e807bc667aaf05babd764949..3b868065f8f1cfe6f4a867976e6612179327659c 100644 (file)
@@ -145,7 +145,7 @@ fn lock_nonblocking(&self) {}
     fn lock_nonblocking<'a>(&'a self) -> Guard<'a> {
         let ret = Guard {
             fd: self.fd(),
-            guard: unsafe { self.inner.lock.lock().unwrap() },
+            guard: self.inner.lock.lock().unwrap(),
         };
         assert!(set_nonblocking(self.fd(), true).is_ok());
         ret
index 835f4279d9bc69d3055eaf7431edc130e7c08f20..48df8c4eced9d3f33b6be67c11da5bfb161eaa99 100644 (file)
@@ -11,7 +11,7 @@
 
 use libc::{mod, pid_t, c_void, c_int};
 use c_str::CString;
-use io::{mod, IoResult, IoError, EndOfFile};
+use io::{IoResult, EndOfFile};
 use mem;
 use os;
 use ptr;
@@ -327,7 +327,7 @@ pub fn wait(&self, deadline: u64) -> IoResult<ProcessExit> {
         // The actual communication between the helper thread and this thread is
         // quite simple, just a channel moving data around.
 
-        unsafe { HELPER.boot(register_sigchld, waitpid_helper) }
+        HELPER.boot(register_sigchld, waitpid_helper);
 
         match self.try_wait() {
             Some(ret) => return Ok(ret),
@@ -335,7 +335,7 @@ pub fn wait(&self, deadline: u64) -> IoResult<ProcessExit> {
         }
 
         let (tx, rx) = channel();
-        unsafe { HELPER.send(NewChild(self.pid, tx, deadline)); }
+        HELPER.send(NewChild(self.pid, tx, deadline));
         return match rx.recv_opt() {
             Ok(e) => Ok(e),
             Err(()) => Err(timeout("wait timed out")),
@@ -419,8 +419,15 @@ fn waitpid_helper(input: libc::c_int,
                             Ok(NewChild(pid, tx, deadline)) => {
                                 active.push((pid, tx, deadline));
                             }
+                            // Once we've been disconnected it means the main
+                            // thread is exiting (at_exit has run). We could
+                            // still have active waiter for other threads, so
+                            // we're just going to drop them all on the floor.
+                            // This means that they won't receive a "you're
+                            // done" message in which case they'll be considered
+                            // as timed out, but more generally errors will
+                            // start propagating.
                             Err(comm::Disconnected) => {
-                                assert!(active.len() == 0);
                                 break 'outer;
                             }
                             Err(comm::Empty) => break,
index 0d63ff14ff26b892a3e0f346598dd60f2cd81b61..4f9b06685ec0c5269106966ab536ca84dd621c29 100644 (file)
@@ -17,6 +17,7 @@ pub struct RWLock { inner: UnsafeCell<ffi::pthread_rwlock_t> }
     inner: UnsafeCell { value: ffi::PTHREAD_RWLOCK_INITIALIZER },
 };
 
+#[allow(dead_code)] // sys isn't exported yet
 impl RWLock {
     #[inline]
     pub unsafe fn new() -> RWLock {
index bcbbb8766b7f47038534f8b574e19be6c9773989..f1d7f1784d098834a0445ba5f3f6ddd5db3f16cb 100644 (file)
@@ -34,7 +34,6 @@ fn drop(&mut self) {
 
 #[cfg(any(target_os = "linux", target_os = "macos"))]
 mod imp {
-    use core::prelude::*;
     use sys_common::stack;
 
     use super::Handler;
index e2a78947e167ab015c9ea3950b3d5a0b1fda65d3..696d3fb676df38f91cc3148a4f13ddd03c5e4f6d 100644 (file)
@@ -135,10 +135,6 @@ pub fn accept(&mut self) -> IoResult<TcpStream> {
         Err(sys_common::eof())
     }
 
-    pub fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
-        net::sockname(self.fd(), libc::getsockname)
-    }
-
     pub fn set_timeout(&mut self, timeout: Option<u64>) {
         self.deadline = timeout.map(|a| sys::timer::now() + a).unwrap_or(0);
     }
index fe393b81e3d9a0a0f4194d3df54e1e28a08600c1..1ababbc0d855a99e1997079e8bc23748179778f1 100644 (file)
@@ -100,7 +100,7 @@ pub fn now() -> u64 {
 fn helper(input: libc::c_int, messages: Receiver<Req>, _: ()) {
     let mut set: c::fd_set = unsafe { mem::zeroed() };
 
-    let mut fd = FileDesc::new(input, true);
+    let fd = FileDesc::new(input, true);
     let mut timeout: libc::timeval = unsafe { mem::zeroed() };
 
     // active timers are those which are able to be selected upon (and it's a
@@ -168,8 +168,15 @@ fn signal(active: &mut Vec<Box<Inner>>,
             1 => {
                 loop {
                     match messages.try_recv() {
+                        // Once we've been disconnected it means the main thread
+                        // is exiting (at_exit has run). We could still have
+                        // active timers for other threads, so we're just going
+                        // to drop them all on the floor. This is all we can
+                        // really do, however, to prevent resource leakage. The
+                        // remaining timers will likely start panicking quickly
+                        // as they attempt to re-use this thread but are
+                        // disallowed to do so.
                         Err(comm::Disconnected) => {
-                            assert!(active.len() == 0);
                             break 'outer;
                         }
 
index 28c17fd4966c09468fe1df7f9570e67cd911ab6e..d05047a220fcdf50205286c9b67611ce327bded2 100644 (file)
@@ -43,5 +43,4 @@ pub fn set_raw(&mut self, _raw: bool) -> IoResult<()> {
     pub fn get_winsize(&mut self) -> IoResult<(int, int)> {
         Err(sys_common::unimpl())
     }
-    pub fn isatty(&self) -> bool { false }
 }
index 42c8f7705e1fcdf2fbcdce5c43ad091486d2ece2..e5a37e5651b25905a774c2a4390437cbceff7813 100644 (file)
@@ -7,19 +7,22 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-/// As always, windows has something very different than unix, we mainly want
-/// to avoid having to depend too much on libunwind for windows.
-///
-/// If you google around, you'll find a fair bit of references to built-in
-/// functions to get backtraces on windows. It turns out that most of these are
-/// in an external library called dbghelp. I was unable to find this library
-/// via `-ldbghelp`, but it is apparently normal to do the `dlopen` equivalent
-/// of it.
-///
-/// You'll also find that there's a function called CaptureStackBackTrace
-/// mentioned frequently (which is also easy to use), but sadly I didn't have a
-/// copy of that function in my mingw install (maybe it was broken?). Instead,
-/// this takes the route of using StackWalk64 in order to walk the stack.
+
+//! As always, windows has something very different than unix, we mainly want
+//! to avoid having to depend too much on libunwind for windows.
+//!
+//! If you google around, you'll find a fair bit of references to built-in
+//! functions to get backtraces on windows. It turns out that most of these are
+//! in an external library called dbghelp. I was unable to find this library
+//! via `-ldbghelp`, but it is apparently normal to do the `dlopen` equivalent
+//! of it.
+//!
+//! You'll also find that there's a function called CaptureStackBackTrace
+//! mentioned frequently (which is also easy to use), but sadly I didn't have a
+//! copy of that function in my mingw install (maybe it was broken?). Instead,
+//! this takes the route of using StackWalk64 in order to walk the stack.
+
+#![allow(dead_code)] // constants/fields aren't always used on all platforms
 
 use c_str::CString;
 use intrinsics;
@@ -294,7 +297,7 @@ pub fn write(w: &mut Writer) -> IoResult<()> {
     // According to windows documentation, all dbghelp functions are
     // single-threaded.
     static LOCK: StaticMutex = MUTEX_INIT;
-    let _g = unsafe { LOCK.lock() };
+    let _g = LOCK.lock();
 
     // Open up dbghelp.dll, we don't link to it explicitly because it can't
     // always be found. Additionally, it's nice having fewer dependencies.
index 06259d61fcb8413bfa24b78e6cd36ed7352b7a87..0aa7e539d781f10c6da5b255863b8009e6f96e1f 100644 (file)
@@ -15,7 +15,6 @@
 #![allow(non_camel_case_types)]
 
 use libc;
-use prelude::*;
 
 pub const WSADESCRIPTION_LEN: uint = 256;
 pub const WSASYS_STATUS_LEN: uint = 128;
index 3ad439078b9a146767660b3469ca6d93586add35..523d9e9a3c24ce96d1385ffa9c0b46f4f12e720b 100644 (file)
 
 //! Blocking Windows-based file I/O
 
-use alloc::arc::Arc;
 use libc::{mod, c_int};
 
-use c_str::CString;
+use io;
 use mem;
-use sys::os::fill_utf16_buf_and_decode;
-use path;
 use ptr;
-use str;
-use io;
+use sys::os::fill_utf16_buf_and_decode;
 
 use prelude::*;
 use sys;
 use sys::os;
-use sys_common::{keep_going, eof, mkerr_libc};
+use sys_common::{unimpl, mkerr_libc};
 
 use io::{FilePermission, Write, UnstableFileStat, Open, FileAccess, FileMode};
 use io::{IoResult, IoError, FileStat, SeekStyle};
@@ -445,7 +441,7 @@ pub fn stat(p: &Path) -> IoResult<FileStat> {
 // FIXME: move this to platform-specific modules (for now)?
 pub fn lstat(_p: &Path) -> IoResult<FileStat> {
     // FIXME: implementation is missing
-    Err(super::unimpl())
+    Err(unimpl())
 }
 
 pub fn utime(p: &Path, atime: u64, mtime: u64) -> IoResult<()> {
index aee98e22836be89280114a9260ebb6376e8955c3..3fae03146f3134ae429910cb44dfc0cc5751ada1 100644 (file)
 #![allow(missing_docs)]
 #![allow(non_camel_case_types)]
 #![allow(non_snake_case)]
-#![allow(unused_imports)]
-#![allow(dead_code)]
-#![allow(unused_unsafe)]
-#![allow(unused_mut)]
 
 extern crate libc;
 
-use num;
 use mem;
 use prelude::*;
 use io::{mod, IoResult, IoError};
 use sync::{Once, ONCE_INIT};
 
-macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => (
-    static $name: Helper<$m> = Helper {
-        lock: ::sync::MUTEX_INIT,
-        cond: ::sync::CONDVAR_INIT,
-        chan: ::cell::UnsafeCell { value: 0 as *mut Sender<$m> },
-        signal: ::cell::UnsafeCell { value: 0 },
-        initialized: ::cell::UnsafeCell { value: false },
-        shutdown: ::cell::UnsafeCell { value: false },
-    };
-) }
-
 pub mod backtrace;
 pub mod c;
 pub mod ext;
@@ -57,6 +41,7 @@ macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => (
 
 pub mod addrinfo {
     pub use sys_common::net::get_host_addresses;
+    pub use sys_common::net::get_address_name;
 }
 
 // FIXME: move these to c module
@@ -179,14 +164,6 @@ pub fn init_net() {
     }
 }
 
-pub fn unimpl() -> IoError {
-    IoError {
-        kind: io::IoUnavailable,
-        desc: "operation is not implemented",
-        detail: None,
-    }
-}
-
 pub fn to_utf16(s: Option<&str>) -> IoResult<Vec<u16>> {
     match s {
         Some(s) => Ok({
index fa08290a888e9f3a2f86d1dcc303eec09aae1e2e..5a7be63e39f175097e8464a16b839b28207e550a 100644 (file)
 
 use prelude::*;
 
-use fmt;
 use io::{IoResult, IoError};
-use libc::{c_int, c_char, c_void};
+use libc::{c_int, c_void};
 use libc;
 use os;
 use path::BytesContainer;
 use ptr;
-use sync::atomic::{AtomicInt, INIT_ATOMIC_INT, SeqCst};
 use sys::fs::FileDesc;
 use slice;
 
index fc3640f260437b8d1f72a1eb1f5ccb6cbbe2add7..8b2fc3d9fb57ff9569e5f6c4f73687958a7e7f4c 100644 (file)
@@ -365,7 +365,7 @@ pub fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
         // acquire the lock.
         //
         // See comments in close_read() about why this lock is necessary.
-        let guard = unsafe { self.inner.lock.lock() };
+        let guard = self.inner.lock.lock();
         if self.read_closed() {
             return Err(eof())
         }
@@ -441,7 +441,7 @@ pub fn write(&mut self, buf: &[u8]) -> IoResult<()> {
             // going after we woke up.
             //
             // See comments in close_read() about why this lock is necessary.
-            let guard = unsafe { self.inner.lock.lock() };
+            let guard = self.inner.lock.lock();
             if self.write_closed() {
                 return Err(epipe())
             }
@@ -516,14 +516,14 @@ pub fn close_read(&mut self) -> IoResult<()> {
         // close_read() between steps 1 and 2. By atomically executing steps 1
         // and 2 with a lock with respect to close_read(), we're guaranteed that
         // no thread will erroneously sit in a read forever.
-        let _guard = unsafe { self.inner.lock.lock() };
+        let _guard = self.inner.lock.lock();
         self.inner.read_closed.store(true, atomic::SeqCst);
         self.cancel_io()
     }
 
     pub fn close_write(&mut self) -> IoResult<()> {
         // see comments in close_read() for why this lock is necessary
-        let _guard = unsafe { self.inner.lock.lock() };
+        let _guard = self.inner.lock.lock();
         self.inner.write_closed.store(true, atomic::SeqCst);
         self.cancel_io()
     }
index 0c2c76077dd5458595987f6b4c7736307110919e..0c5a0eb6bb9cf15c1a5255aee6f1552c22f7f290 100644 (file)
@@ -8,25 +8,24 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use libc::{pid_t, c_void, c_int};
+use prelude::*;
+
+use libc::{pid_t, c_void};
 use libc;
 use c_str::CString;
 use io;
 use mem;
 use os;
 use ptr;
-use prelude::*;
-use io::process::{ProcessExit, ExitStatus, ExitSignal};
+use io::process::{ProcessExit, ExitStatus};
 use collections;
 use path::BytesContainer;
 use hash::Hash;
 use io::{IoResult, IoError};
 
-use sys::fs;
-use sys::{mod, retry, c, wouldblock, set_nonblocking, ms_to_timeval, timer};
+use sys::timer;
 use sys::fs::FileDesc;
-use sys_common::helper_thread::Helper;
-use sys_common::{AsInner, mkerr_libc, timeout};
+use sys_common::{AsInner, timeout};
 
 use io::fs::PathExtensions;
 
@@ -121,8 +120,6 @@ pub fn spawn<K, V, C, P>(cfg: &C, in_fd: Option<P>,
         use libc::funcs::extra::msvcrt::get_osfhandle;
 
         use mem;
-        use iter::{Iterator, IteratorExt};
-        use str::StrExt;
 
         if cfg.gid().is_some() || cfg.uid().is_some() {
             return Err(IoError {
index bdf2e0bccb1a07695e27b6ccb86d601854a20d96..ab092f5a243279bb16623ba0fbd609c504c1c556 100644 (file)
@@ -14,7 +14,7 @@
 use mem;
 use libc;
 use libc::types::os::arch::extra::{LPVOID, DWORD, LONG, BOOL};
-use sys_common::{stack, thread_info};
+use sys_common::stack;
 
 pub struct Handler {
     _data: *mut libc::c_void
@@ -30,14 +30,6 @@ impl Drop for Handler {
     fn drop(&mut self) {}
 }
 
-// get_task_info is called from an exception / signal handler.
-// It returns the guard page of the current task or 0 if that
-// guard page doesn't exist. None is returned if there's currently
-// no local task.
-unsafe fn get_task_guard_page() -> uint {
-    thread_info::stack_guard()
-}
-
 // This is initialized in init() and only read from after
 static mut PAGE_SIZE: uint = 0;
 
index 513c1d38e363492bf5b4111675fafe2453780637..339c724d9a9a1bfc4c11410f60f1cd83eb1ec02b 100644 (file)
 use mem;
 use ptr;
 use prelude::*;
-use super::{last_error, last_net_error, retry, sock_t};
+use super::{last_error, last_net_error, sock_t};
 use sync::{Arc, atomic};
-use sys::fs::FileDesc;
 use sys::{mod, c, set_nonblocking, wouldblock, timer};
-use sys_common::{mod, timeout, eof, net};
+use sys_common::{timeout, eof, net};
 
 pub use sys_common::net::TcpStream;
 
@@ -205,10 +204,6 @@ pub fn accept(&mut self) -> IoResult<TcpStream> {
         Err(eof())
     }
 
-    pub fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
-        net::sockname(self.socket(), libc::getsockname)
-    }
-
     pub fn set_timeout(&mut self, timeout: Option<u64>) {
         self.deadline = timeout.map(|a| timer::now() + a).unwrap_or(0);
     }
index 4498f56c00a1e4adcefdc3e1b21885e1bc4587dd..59ab5f5c4d990b776f2741ae6af69e134aff1dfd 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use core::prelude::*;
-
 use boxed::Box;
 use cmp;
 use mem;
index 60b0d584db3a7a6936fa8c1f160c19109739d331..4ac57e37117877139bbe1a00ad8aae53ca9c084e 100644 (file)
@@ -137,9 +137,9 @@ unsafe fn init_dtors() {
     rt::at_exit(move|| {
         DTOR_LOCK.lock();
         let dtors = DTORS;
-        DTORS = 0 as *mut _;
+        DTORS = 1 as *mut _;
         mem::transmute::<_, Box<Vec<(Key, Dtor)>>>(dtors);
-        assert!(DTORS.is_null()); // can't re-init after destructing
+        assert!(DTORS as uint == 1); // can't re-init after destructing
         DTOR_LOCK.unlock();
     });
 }
@@ -147,6 +147,9 @@ unsafe fn init_dtors() {
 unsafe fn register_dtor(key: Key, dtor: Dtor) {
     DTOR_LOCK.lock();
     init_dtors();
+    assert!(DTORS as uint != 0);
+    assert!(DTORS as uint != 1,
+            "cannot create new TLS keys after the main thread has exited");
     (*DTORS).push((key, dtor));
     DTOR_LOCK.unlock();
 }
@@ -154,6 +157,9 @@ unsafe fn register_dtor(key: Key, dtor: Dtor) {
 unsafe fn unregister_dtor(key: Key) -> bool {
     DTOR_LOCK.lock();
     init_dtors();
+    assert!(DTORS as uint != 0);
+    assert!(DTORS as uint != 1,
+            "cannot unregister destructors after the main thread has exited");
     let ret = {
         let dtors = &mut *DTORS;
         let before = dtors.len();
@@ -232,6 +238,7 @@ unsafe fn unregister_dtor(key: Key) -> bool {
     }
 }
 
+#[allow(dead_code)] // not actually dead
 unsafe fn run_dtors() {
     let mut any_run = true;
     for _ in range(0, 5i) {
index 874838950cd12bfcd59f0751d74d64b40de9cbfc..c0e67642a6466b6a1ad1b74244ecfa668c03f3a7 100644 (file)
@@ -26,8 +26,6 @@
 use ptr;
 use comm;
 
-use sys::c;
-use sys::fs::FileDesc;
 use sys_common::helper_thread::Helper;
 use prelude::*;
 use io::IoResult;
@@ -80,9 +78,10 @@ fn helper(input: libc::HANDLE, messages: Receiver<Req>, _: ()) {
                             None => {}
                         }
                     }
+                    // See the comment in unix::timer for why we don't have any
+                    // asserts here and why we're likely just leaving timers on
+                    // the floor as we exit.
                     Err(comm::Disconnected) => {
-                        assert_eq!(objs.len(), 1);
-                        assert_eq!(chans.len(), 0);
                         break 'outer;
                     }
                     Err(..) => break
index 99292b3b44bd1749b3b84ca51e3d1c4d06fdd97c..607bb05f54fd421a93d162df2801736cee992245 100644 (file)
@@ -26,7 +26,6 @@
 //! to working in raw UTF-16, with such a wrapper around it.
 
 use super::c::{ReadConsoleW, WriteConsoleW, GetConsoleMode, SetConsoleMode};
-use super::c::{ERROR_ILLEGAL_CHARACTER};
 use super::c::{ENABLE_ECHO_INPUT, ENABLE_EXTENDED_FLAGS};
 use super::c::{ENABLE_INSERT_MODE, ENABLE_LINE_INPUT};
 use super::c::{ENABLE_PROCESSED_INPUT, ENABLE_QUICK_EDIT_MODE};
@@ -38,6 +37,8 @@
 use ptr;
 use str::from_utf8;
 
+use sys_common::unimpl;
+
 fn invalid_encoding() -> IoError {
     IoError {
         kind: io::InvalidInput,
@@ -149,11 +150,8 @@ pub fn get_winsize(&mut self) -> IoResult<(int, int)> {
         // Make a CONSOLE_SCREEN_BUFFER_INFO
         // Call GetConsoleScreenBufferInfo
         // Maybe call GetLargestConsoleWindowSize instead?
-        Err(super::unimpl())
+        Err(unimpl())
     }
-
-    // Let us magically declare this as a TTY
-    pub fn isatty(&self) -> bool { true }
 }
 
 impl Drop for TTY {
index a7b3ee996a34dc428bf77bb827feceb2ba5742ef..cfdb5c2ec26cb59a00cc41eac2c4951e85bf1199 100644 (file)
@@ -232,13 +232,10 @@ fn spawn_inner<T: Send>(self, f: Thunk<(), T>) -> JoinGuard<T> {
             let my_stack_top = addr as uint;
             let my_stack_bottom = my_stack_top - stack_size + 1024;
             unsafe {
-                stack::record_os_managed_stack_bounds(my_stack_bottom, my_stack_top);
+                stack::record_os_managed_stack_bounds(my_stack_bottom,
+                                                      my_stack_top);
+                thread_info::set(imp::guard::current(), their_thread);
             }
-            thread_info::set(
-                (my_stack_bottom, my_stack_top),
-                unsafe { imp::guard::current() },
-                their_thread
-            );
 
             let mut output = None;
             let f: Thunk<(), T> = if stdout.is_some() || stderr.is_some() {
index 9fda05431db49639cf742bda554bf2c3d63d5f47..bce73a27699363db24e5f4339c7b6bbff6216396 100644 (file)
@@ -257,7 +257,7 @@ extern "C" void LLVMDIBuilderFinalize(DIBuilderRef Builder) {
     Builder->finalize();
 }
 
-extern "C" void LLVMDIBuilderCreateCompileUnit(
+extern "C" LLVMValueRef LLVMDIBuilderCreateCompileUnit(
     DIBuilderRef Builder,
     unsigned Lang,
     const char* File,
@@ -267,8 +267,14 @@ extern "C" void LLVMDIBuilderCreateCompileUnit(
     const char* Flags,
     unsigned RuntimeVer,
     const char* SplitName) {
-    Builder->createCompileUnit(Lang, File, Dir, Producer, isOptimized,
-        Flags, RuntimeVer, SplitName);
+    return wrap(Builder->createCompileUnit(Lang,
+                                           File,
+                                           Dir,
+                                           Producer,
+                                           isOptimized,
+                                           Flags,
+                                           RuntimeVer,
+                                           SplitName));
 }
 
 extern "C" LLVMValueRef LLVMDIBuilderCreateFile(
diff --git a/src/test/compile-fail/trait-object-safety.rs b/src/test/compile-fail/trait-object-safety.rs
new file mode 100644 (file)
index 0000000..d594e3e
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Check that static methods are not object-safe.
+
+trait Tr {
+    fn foo();
+}
+
+struct St;
+
+impl Tr for St {
+    fn foo() {}
+}
+
+fn main() {
+    let _: &Tr = &St; //~ ERROR cannot convert to a trait object because trait `Tr` is not
+    //~^ NOTE cannot call a static method (`foo`) through a trait object
+}
index 54d34d1840ca033aa6e9cbd989d007a34f11585b..4251f22b291470cef15d41a0ecf391a4f5dfad59 100644 (file)
@@ -45,6 +45,7 @@
 
 #![allow(unused_variables)]
 #![allow(dead_code)]
+#![omit_gdb_pretty_printer_section]
 
 
 static B: bool = false;
index bbb8c2423c375ed5da4f896aa3830dfff2e1c101..a4d4ddfea531db9303ff0ab0a8748e73e07c3845 100644 (file)
@@ -50,6 +50,7 @@
 // gdb-command:continue
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 static B: bool = false;
 static I: int = -1;
index b998f096a07389b0de8581184b08126e0b3b4c79..6aa228ec51bfce93cae3939bffa7ed31c6bfbb8f 100644 (file)
@@ -48,6 +48,7 @@
 // gdb-command:continue
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 fn main() {
     let unit: () = ();
index 435bfd98989b3cb9fa875309f30f0415f48234ae..bc8cdaf8eacc9eb41e6a9c14e9aff8f426ab48c1 100644 (file)
@@ -83,6 +83,7 @@
 // gdb-check:$28 = 9.25
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 static mut B: bool = false;
 static mut I: int = -1;
index 8be91e3ee76b3bd1a510c85292b1e8eb30d52544..f61f49228cdebf508223b82aaaba685f8dc6f9b2 100644 (file)
@@ -88,6 +88,7 @@
 // lldb-check:[...]$12 = 3.5
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 fn main() {
     let b: bool = false;
index 00bee44d264cff20c7640a71558326b1ad01ca69..f4c31278cf63be5c83722eee42a9e8ecc004eeee 100644 (file)
 // lldb-check:[...]$12 = 3.5
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 fn main() {
     let bool_val: bool = true;
index bbda6c93ebaf9344ad319899f054654190f6fb2c..c2da58f1583c0b38c239865ce51b30a43d9607f5 100644 (file)
@@ -41,6 +41,7 @@
 // lldb-check:[...]$2 = TheC
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 enum ABC { TheA, TheB, TheC }
 
index 9cda56a774380e2295f8a342db0d56d6850f2abc..d54869888f182d590c235949d73ac9b4a4ea3f6d 100644 (file)
@@ -40,6 +40,7 @@
 // lldb-check:[...]$2 = TheOnlyCase(4820353753753434)
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 // The first element is to ensure proper alignment, irrespective of the machines word size. Since
 // the size of the discriminant value is machine dependent, this has be taken into account when
index 7e6cf41162c38f9b767007653db9ee63c8a8e525..e3cf438be439c81dd56aa33163679e41c7d0b8fb 100644 (file)
@@ -64,6 +64,7 @@
 // lldb-check:[...]$6 = 26.5
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 struct SomeStruct {
     x: int,
index 57c14450467497d71f54274546cb7000b7155f26..ce0930f2fbf38f71de67f153a28c1b6836ec987c 100644 (file)
@@ -42,6 +42,7 @@
 
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 fn main() {
     let stack_val: (i16, f32) = (-14, -19f32);
index 30787716c72a803fd83b3dc77ec81a248254230b..d152775a8ed6a9514626589208f25474dfe9e4db 100644 (file)
 // lldb-check:[...]$12 = 3.5
 
 #![allow(unused_variables)]
-
+#![omit_gdb_pretty_printer_section]
 
 fn main() {
     let bool_box: Box<bool> = box true;
index 59f0c8f2d657ca60d17a1adee5e6b6881d7d6d96..5a70eb190412832f3a0266993297a8241e5d8ab9 100644 (file)
@@ -32,6 +32,7 @@
 // lldb-check:[...]$1 = (2, 3.5)
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 fn main() {
     let a = box 1i;
index 8f77de7e6d3ced64a317bfa8f1824228bcb5baf5..f9d762bf99d28a1b43c16fe5742c5f891d726b76 100644 (file)
@@ -35,6 +35,7 @@
 // lldb-check:[...]$1 = StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 }
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 struct StructWithSomePadding {
     x: i16,
index 258c49afcc42c84f4422f7b170cc808b6f5066fc..b0c5b2f21b95cf675b96e96ef95c3ded614cb853 100644 (file)
@@ -71,6 +71,8 @@
 // lldb-check:[...]$6 = Case1 { x: 0, y: 8970181431921507452 }
 // lldb-command:continue
 
+#![omit_gdb_pretty_printer_section]
+
 #[deriving(Clone)]
 struct Struct {
     a: int,
index 57a3e503d0aa9a14c8997158e94db34add854fc8..6907313370e1a5edf57f26e6ec3bc158dc9bea1d 100644 (file)
@@ -46,6 +46,8 @@
 // lldb-check:[...]$2 = (4444.5, 5555, 6666, 7777.5)
 // lldb-command:continue
 
+#![omit_gdb_pretty_printer_section]
+
 trait Trait {
     fn method(self) -> Self;
 }
index 17e4110c2f1d3868aaea9dba48e0e1e225a0d110..f2dfc63d52253edfe7f0211741c0927e4807765c 100644 (file)
@@ -65,6 +65,7 @@
 // lldb-check:[...]$6 = (StructWithDrop { a: OneHundred, b: Vienna }, 9)
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 use self::AnEnum::{OneHundred, OneThousand, OneMillion};
 use self::AnotherEnum::{MountainView, Toronto, Vienna};
index b0a0142f6dd556eb2de16434a6e3d02501e20c79..b62a8167eaf07f30e40a54f083888b6a29018b27 100644 (file)
@@ -99,6 +99,7 @@
 
 #![allow(unused_variables)]
 #![allow(dead_code)]
+#![omit_gdb_pretty_printer_section]
 
 use self::AutoDiscriminant::{One, Two, Three};
 use self::ManualDiscriminant::{OneHundred, OneThousand, OneMillion};
index 673b4676a9552aaa2ce6fd20d9fe2feca6bb4d18..84366ae71146501ee1e25e61d44c4d67fc009f78 100644 (file)
@@ -46,6 +46,8 @@
 // lldb-check:[...]$3 = 110
 // lldb-command:continue
 
+#![omit_gdb_pretty_printer_section]
+
 fn some_generic_fun<T1, T2>(a: T1, b: T2) -> (T2, T1) {
 
     let closure = |x, y| {
index 17e1651f9f6eda68487e1d3d0ba09e2885207f6e..b4688e4928a6bfa65644a532068c821cdd9b58e8 100644 (file)
 // lldb-command:continue
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 use self::Univariant::Unit;
 
index 9935bb60364862da137b08ffd5618a2d42d71f62..364720d0e4fb34d0316d8630bd29142438967371 100644 (file)
 // lldb-check:[...]$23 = (34903493, 232323)
 // lldb-command:continue
 
+#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
+
 struct Struct {
     x: i16,
     y: f32,
index 58db37888e6d7aa7b0a66552c4d6c281d010a631..d5a6b36f1fcf90329f69cf7d16726be3f1db3f34 100644 (file)
 
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 use self::Univariant::Unit;
 
index 786868f6b89ddab084dbce06cb0117fd821d42f9..f623a321922b8d7695cd4f7665cab48414a17059 100644 (file)
@@ -51,6 +51,7 @@
 // lldb-check:[...]$4 = StructPaddedAtEnd { x: [22, 23], y: [24, 25] }
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 struct NoPadding1 {
     x: [u32; 3],
index 53b3044b0f7f7c9c2fb5a4fe397b94c49f8707fa..55c5c50406416aa807d43b576cc593f075587ef6 100644 (file)
 // lldb-command:continue
 
 
-
 #![allow(unused_variables)]
-
-
+#![omit_gdb_pretty_printer_section]
 
 fn immediate_args(a: int, b: bool, c: f64) {
     ::std::io::print("") // #break
index 304745e39453d2a1691486f4a52da2fd945b901c..01136c11014a343f8764c5ae340f10bcd7f0d1d1 100644 (file)
@@ -45,6 +45,9 @@
 // lldb-check:[...]$3 = 3000
 // lldb-command:continue
 
+
+#![omit_gdb_pretty_printer_section]
+
 fn main() {
 
     fun(111102, true);
index 3288fa4c0cbd1746c63fe2a9bb378f2764d5bda5..e437e35db3a991117d4c61332a295422ba3040e9 100644 (file)
 // lldb-command:continue
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 #[no_stack_check]
 fn immediate_args(a: int, b: bool, c: f64) {
index dbeb87fd44afe1662b80e4f646161e12b3789e02..05ea357389bc61004678a88beb9835f47ea61329 100644 (file)
 // lldb-command:continue
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 fn immediate_args(a: int, b: bool, c: f64) {
     ()
index 8abb2cd5c26f984b91f68bc4128cc7b20bc40bb9..092cd9edc70658e21d3a008c9048270a9aaaf6f9 100644 (file)
@@ -17,7 +17,6 @@
 // ignore-lldb
 // ignore-android: FIXME(#10381)
 // compile-flags:-g
-// gdb-use-pretty-printer
 
 // gdb-command: run
 
index 76cf3c1149dd552e8665965cabeb1d2b0e3f921b..64c120e1ab3a9a6566f59f9830afadbf708a9969 100644 (file)
@@ -13,7 +13,6 @@
 // ignore-lldb
 // ignore-android: FIXME(#10381)
 // compile-flags:-g
-// gdb-use-pretty-printer
 
 // This test uses some GDB Python API features (e.g. accessing anonymous fields)
 // which are only available in newer GDB version. The following directive will
index abfe95db51ba2d9ff5e00b99a49878d0ee18ff5b..cefe67970e959494f291d56b4f487e64db26c4c4 100644 (file)
@@ -70,6 +70,7 @@
 // lldb-check:[...]$8 = ((5, Struct { a: 6, b: 7.5 }), (Struct { a: 6, b: 7.5 }, 5))
 // lldb-command:continue
 
+#![omit_gdb_pretty_printer_section]
 
 #[deriving(Clone)]
 struct Struct {
index 069906b14fd08dd3ec7fed41f36f588271e0686c..0f3fd556f189a6c64f67d52cfb8f994575261537 100644 (file)
@@ -70,6 +70,9 @@
 // lldb-check:[...]$7 = 2.5
 // lldb-command:continue
 
+
+#![omit_gdb_pretty_printer_section]
+
 fn outer<TA: Clone>(a: TA) {
     inner(a.clone(), 1i);
     inner(a.clone(), 2.5f64);
index 4c0c82efea35d33873f78142ac1c2aaccc2e2e37..0e358499a3d025d0ae0e5ac4816250f241cc041c 100644 (file)
 // lldb-check:[...]$14 = -10.5
 // lldb-command:continue
 
+#![omit_gdb_pretty_printer_section]
 
 struct Struct<T> {
     x: T
index d69d432fcb30f64815e13ec6be10c1aaeb7b78de..bf755d379a6237ffd7cc26e4c341dd65d1e97389 100644 (file)
@@ -31,6 +31,9 @@
 // gdb-check:$5 = 5
 // gdb-command:continue
 
+
+#![omit_gdb_pretty_printer_section]
+
 struct Struct {
     x: int
 }
index 5e967266421722ed7bae849775a2e17851d05801..992e74179137bad54a4c4b7ef50fcc2f78eb6462 100644 (file)
@@ -29,6 +29,9 @@
 // gdb-command:print univariant
 // gdb-check:$4 = {{a = -1}}
 
+
+#![omit_gdb_pretty_printer_section]
+
 use self::Regular::{Case1, Case2, Case3};
 use self::Univariant::TheOnlyCase;
 
index 7d485a6f5d5a025fe70166a88f1515a5447c715f..908968fd6b32acbd97265b9c2bd24c37195e1d0c 100644 (file)
@@ -41,6 +41,9 @@
 // lldb-command:print float_int_float
 // lldb-check:[...]$3 = AGenericStruct<f64, generic-struct::AGenericStruct<int, f64>> { key: 6.5, value: AGenericStruct<int, f64> { key: 7, value: 8.5 } }
 
+
+#![omit_gdb_pretty_printer_section]
+
 struct AGenericStruct<TKey, TValue> {
     key: TKey,
     value: TValue
index 0984f8c9fa2cfde6f74e50972081cbddb95925dd..4382861fd20991af0d3e2f248fc4978e5528449c 100644 (file)
@@ -25,6 +25,7 @@
 // gdb-check:$4 = {3.5, {4, 5, 6}}
 // gdb-command:continue
 
+#![omit_gdb_pretty_printer_section]
 
 struct Struct {
     x: int
index 74d5dd2adc800365eab7331877edc4a8bff230b7..f9dc9d1f055c82c205a3ae57ab29d2fdde507601 100644 (file)
@@ -48,6 +48,8 @@
 // lldb-command:print univariant
 // lldb-check:[...]$3 = TheOnlyCase(-1)
 
+#![omit_gdb_pretty_printer_section]
+
 use self::Regular::{Case1, Case2, Case3};
 use self::Univariant::TheOnlyCase;
 
index f196938437a3975c8210e51c071cece57a6efadb..25719a802863d78898283b61a2e2dfa3a0fde9dc 100644 (file)
@@ -36,6 +36,7 @@
 // lldb-command:continue
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 // This test case makes sure that debug info does not ICE when include_str is
 // used multiple times (see issue #11322).
index e2dae2dc3f05992c86367c0cb37d8b81babec6b8..c6acc9a31fe3c68a0c70d13ac41f48144241b818 100644 (file)
 
 // gdb-command:run
 // gdb-command:next
-// gdb-check:[...]32[...]s
+// gdb-check:[...]34[...]s
 // gdb-command:continue
 
+#![omit_gdb_pretty_printer_section]
+
 // IF YOU MODIFY THIS FILE, BE CAREFUL TO ADAPT THE LINE NUMBERS IN THE DEBUGGER COMMANDS
 
 // This test makes sure that gdb does not set unwanted breakpoints in inlined functions. If a
index 7636ffdb07dcd6a02a54e656d3db53d5a5a9bd75..3309ae13c9dcbc2430c9368f89517ca4cc3f0311 100644 (file)
@@ -86,6 +86,8 @@
 // lldb-check:[...]$6 = 1000000
 // lldb-command:continue
 
+#![omit_gdb_pretty_printer_section]
+
 fn main() {
 
     let range = [1i, 2, 3];
index 5bfe8371209c4ea7903e1c978215da249c6c2a5f..bc3a69452432550aaecd01eefabade4acc1dca05 100644 (file)
 // lldb-check:[...]$15 = -1
 // lldb-command:continue
 
+#![omit_gdb_pretty_printer_section]
 
 fn main() {
 
index 6a956e06f245bf06110f6ccc38ab81ce5205fb13..37976ab3996ae22e18a9156dadd155f7937c4f99 100644 (file)
 // lldb-check:[...]$17 = 232
 // lldb-command:continue
 
+#![omit_gdb_pretty_printer_section]
 
 struct Struct {
     x: int,
index 6666ddfbc829c26086ea42925db3b7456b875c36..d6e3a43eea0a6383f478ebf0a23243515bfcff8c 100644 (file)
@@ -70,6 +70,8 @@
 // lldb-check:[...]$5 = false
 // lldb-command:continue
 
+#![omit_gdb_pretty_printer_section]
+
 fn main() {
 
     let x = false;
index 51ddc83a8d863c9dcde38ae6c5bab3c7ea122291..b295c6f37a7a16d3d5567a9c32881c1f7451894b 100644 (file)
 // lldb-check:[...]$12 = 2
 // lldb-command:continue
 
+#![omit_gdb_pretty_printer_section]
+
 fn main() {
 
     let mut x = 0i;
index fa7822495d5f15ede8117880cc1b546583fbd752..be4085b63abe51dcacd0261647af347d9aa1632b 100644 (file)
@@ -70,6 +70,9 @@
 // lldb-check:[...]$5 = false
 // lldb-command:continue
 
+
+#![omit_gdb_pretty_printer_section]
+
 fn main() {
 
     let x = false;
index bafff552cd394cc140997712afdaecc7889dfc72..c7a36ef9b82bd07f0e69ba72d32380c11899d519 100644 (file)
 // lldb-check:[...]$12 = 2
 // lldb-command:continue
 
+#![omit_gdb_pretty_printer_section]
 
 fn main() {
 
index 2c76f2ca7dfa87385843104ab479f02dc5660cbb..be52ffff1b45e9aaba2df6274ea5240cfe740b80 100644 (file)
 
 
 #![feature(macro_rules)]
+#![omit_gdb_pretty_printer_section]
 
 macro_rules! trivial {
     ($e1:expr) => ($e1)
index 41dee642feacd9c4886d83e8e073a4523ac49e6a..2f8b11ac283b63b884cf719c856d5075100f0441 100644 (file)
 
 #![allow(unused_variables)]
 #![allow(unused_assignments)]
+#![omit_gdb_pretty_printer_section]
 
 static mut MUT_INT: int = 0;
 
index 3a633fc5eeccf42f5ddcdbf041dbba5257177ba1..35889ff81335c04b9789447e487988d583d27a66 100644 (file)
@@ -30,6 +30,7 @@
 
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 struct Struct {
     a: i64,
index 8cb8fae75cf062bbd9819228ee838ece8bf95c1e..b1ebb124d4e76a53a4e877590f0e33864dc9fb46 100644 (file)
 // lldb-check:[...]$14 = -10
 // lldb-command:continue
 
+#![omit_gdb_pretty_printer_section]
+
 enum Enum {
     Variant1 { x: u16, y: u16 },
     Variant2 (u32)
index d4244ee27d4c20b696d5d09c4d22be690ef2bbcd..68a6ac8c1f31e9c00f8f635942981ad2f0c89bf0 100644 (file)
 // lldb-command:continue
 
 
+#![omit_gdb_pretty_printer_section]
+
 struct Struct<T> {
     x: T
 }
index ca00587ba445d81ca4e797b2532f06f79eca204c..84e74d4364cfaa2cea68cdf833acda89c87a82cb 100644 (file)
 // lldb-check:[...]$14 = -10
 // lldb-command:continue
 
+
+#![omit_gdb_pretty_printer_section]
+
 struct Struct {
     x: int
 }
index e70f86a53679ea555b34b6110a0204fe7102eee4..f53bb11eac442555e4f9786df0b8b6a626248011 100644 (file)
 // lldb-check:[...]$14 = -10
 // lldb-command:continue
 
+
+#![omit_gdb_pretty_printer_section]
+
 struct Struct {
     x: int
 }
index 31bdd20e409db8eb2d8e6027142b9bb32d922934..6994c38818c1b906733db0945d942ab33ed29779 100644 (file)
 // lldb-check:[...]$14 = -10
 // lldb-command:continue
 
+
+#![omit_gdb_pretty_printer_section]
+
 struct TupleStruct(int, f64);
 
 impl TupleStruct {
index d5d085bfe50a63e5998f9754ad3f6b6d0f71407b..cb21c13426a7b63cd3977f7d86cbb8cd1cef3be4 100644 (file)
@@ -45,6 +45,7 @@
 // lldb-check:[...]$2 = 30303
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 fn function_one() {
     let abc = 10101i;
index a94785b892dc02912664b23fd07c834f2ff7a134..ef7c4ce2045c7fe02d9e6e593dadc3292ad6089a 100644 (file)
@@ -45,6 +45,7 @@
 // lldb-check:[...]$2 = 30303
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 fn function_one() {
     let a = 10101i;
index 5d6dfb90794fdab905ffe998970823364b0ceea7..d248c7e98198c71b9c1264fb149ad8b5414e3da7 100644 (file)
@@ -94,6 +94,8 @@
 // lldb-check:[...]$11 = 20
 // lldb-command:continue
 
+#![omit_gdb_pretty_printer_section]
+
 fn main() {
     let x = false;
     let y = true;
index 306dfed9895e8cb63a621f5ea4916caaff3f88d1..f0eaf6acb6138f86ea4f7fec1fb906a0fba6bc9d 100644 (file)
@@ -23,6 +23,7 @@
 // gdb-check:$2 = {<No data fields>}
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 enum ANilEnum {}
 enum AnotherNilEnum {}
index 826ac381c82098b977ba0650385cadfced366cc6..dcc1928ae50c91e7ddcf86d312be5c26e816da55 100644 (file)
@@ -24,6 +24,7 @@
 // gdb-command:continue
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 fn function_with_debuginfo() {
     let abc = 10u;
index 333a430e3511130c47567d22939ec712869f2aa4..333ad602cf1301a55c21082689f79007a42f15b3 100644 (file)
@@ -68,6 +68,8 @@
 // lldb-check:[...]$7 = None
 
 
+#![omit_gdb_pretty_printer_section]
+
 // If a struct has exactly two variants, one of them is empty, and the other one
 // contains a non-nullable pointer, then this value is used as the discriminator.
 // The test cases in this file make sure that something readable is generated for
index 1140c2cdb44d1a34a9d8f5057f5fd6d5b4ffe3fa..84c0b8da02c0610bdfc7d008c48399d48ce87237 100644 (file)
@@ -74,6 +74,7 @@
 
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 #[repr(packed)]
 struct Packed {
index 93941823fbc3a845a114ed2f631755ff77109545..97e6ee79952e8078c0480e6673833f3f3762c594 100644 (file)
@@ -60,6 +60,7 @@
 // lldb-check:[...]$5 = 40
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 #[repr(packed)]
 struct Packed {
index f43caed0810144ccd524a2a59d8c949c171724bc..93348e7b53e559b9732726850bae5c61fb1898ed 100644 (file)
@@ -18,6 +18,7 @@
 // is taken from issue #11083.
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 pub struct Window<'a> {
     callbacks: WindowCallbacks<'a>
index 8cc0fdabfc2e7b73cb7465dcaaf0b73597edd198..90c32ad8da11ffad27354715c5f94d53063cea2b 100644 (file)
@@ -69,6 +69,7 @@
 // gdb-command:continue
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 use self::Opt::{Empty, Val};
 
index 87fdb2c42c8f86956905346f0946c1b1af4170a7..f8ef5b3d2fcf9411cfe493eaccd8c5172cf40c19 100644 (file)
 // lldb-check:[...]$14 = -10
 // lldb-command:continue
 
+#![omit_gdb_pretty_printer_section]
 
 struct Struct {
     x: int
index 6f488230521eb066d4e423b0c0a9ff7ac33f81e4..c2594df7d351c1da129e3e56bccad819dbbd2819 100644 (file)
 // lldb-check:[...]$14 = -10.5
 // lldb-command:continue
 
+#![omit_gdb_pretty_printer_section]
 
 struct Struct {
     x: int
index ead960c36df99361c2a715461efb744e6c2d3309..c5c3664b07a7c307f355236ef695369129345ac2 100644 (file)
@@ -58,6 +58,9 @@
 // lldb-check:[...]$5 = 20
 // lldb-command:continue
 
+
+#![omit_gdb_pretty_printer_section]
+
 fn a_function(x: bool, y: bool) {
     zzz(); // #break
     sentinel();
index fa56c1d1fb756d24f316d249c75771f2d0d645bd..f384b756da67813c9941a6562c534b157b5d2f3c 100644 (file)
@@ -58,6 +58,8 @@
 // lldb-check:[...]$5 = 20
 // lldb-command:continue
 
+#![omit_gdb_pretty_printer_section]
+
 fn main() {
     let x = false;
     let y = true;
index 2c2eedf416775299a0d6ec12e5765209b008a75f..288e7461dd5a0c226d5a507000dfac7fc52b97ae 100644 (file)
@@ -43,6 +43,7 @@
 
 #![allow(experimental)]
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 use std::simd::{i8x16, i16x8,i32x4,i64x2,u8x16,u16x8,u32x4,u64x2,f32x4,f64x2};
 
index 4330a27325837c07b3a9f4f8e2c96ba7b687121a..5981c18494d40c8b4ffe6079f0fc3437934f9917 100644 (file)
@@ -78,6 +78,9 @@
 // lldb-check:[...]$6 = false
 // lldb-command:continue
 
+
+#![omit_gdb_pretty_printer_section]
+
 fn main() {
     let x = false;
 
index 51241be921ca2acca866cbedbb316b8e4bf16dfa..3015b16a0aa99ea4ccdda9103f64f83c5aafc3b7 100644 (file)
@@ -95,8 +95,9 @@
 // lldb-command:print padding_at_end
 // lldb-check:[...]$5 = PaddingAtEnd { x: -10014, y: 10015 }
 
-#![allow(unused_variables)];
-#![allow(dead_code)];
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![omit_gdb_pretty_printer_section]
 
 struct NoPadding16 {
     x: u16,
index bbc9941e013c10e9ff1a05d2b14b14311cd3b06c..78184fab7d3904971a6c4e620f75f2e81885b03a 100644 (file)
@@ -92,6 +92,7 @@
 
 #![allow(unused_variables)]
 #![allow(dead_code)]
+#![omit_gdb_pretty_printer_section]
 
 static mut NO_PADDING_8: (i8, u8) = (-50, 50);
 static mut NO_PADDING_16: (i16, i16, u16) = (-1, 2, 3);
index f808e7f8a90ff578710da5008c23ca1bbab381fd..59ee300b3e3b52644a2fa1dc36ebf0c796ba6d84 100644 (file)
@@ -54,6 +54,8 @@
 // lldb-check:[...]$4 = 5
 // lldb-command:continue
 
+#![omit_gdb_pretty_printer_section]
+
 struct Struct {
     x: int
 }
index 68281cb2230281bd8e5104eb3cd98147f1a3fe84..6f801a7d587d378a9b4b2b5c11d121217c34cbfa 100644 (file)
@@ -42,6 +42,7 @@
 // lldb-check:[...]$2 = TheOnlyCase(Struct { x: 123, y: 456, z: 789 })
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 use self::Regular::{Case1, Case2};
 use self::Univariant::TheOnlyCase;
index 4a7588b0bec592b207c1e2e164e2822d0a62856b..3f819c92e1017de50d762f9295522dec5e654e72 100644 (file)
@@ -57,6 +57,7 @@
 // lldb-check:[...]$7 = Tree { x: Simple { x: 25 }, y: InternalPaddingParent { x: InternalPadding { x: 26, y: 27 }, y: InternalPadding { x: 28, y: 29 }, z: InternalPadding { x: 30, y: 31 } }, z: BagInBag { x: Bag { x: Simple { x: 32 } } } }
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 struct Simple {
     x: i32
index 48c6c2d79fb43afb30103c8f571721a5d7d475d4..f6d4627082f0e2d37b8b6b009d19be2e936e2e12 100644 (file)
@@ -49,6 +49,7 @@
 // lldb-check:[...]$3 = TheOnlyCase { a: -1 }
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 use self::Regular::{Case1, Case2, Case3};
 use self::Univariant::TheOnlyCase;
index 854ba2171eb4285071d2e9cf73838607841f9124..743f5ac5ff452c82023504d02ec1e7114ffd0ac3 100644 (file)
@@ -45,6 +45,7 @@
 // lldb-check:[...]$3 = NestedOuter { a: NestedInner { a: WithDestructor { x: 7890, y: 9870 } } }
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 struct NoDestructor {
     x: i32,
index 8d565a323acd3e652cdf92ea37661f761f5e69ce..2ecafb02ae52d4e8ac4f1d1355e98d962f1162de 100644 (file)
@@ -45,6 +45,8 @@
 // lldb-check:[...]$3 = (1, 2, 3)
 // lldb-command:continue
 
+#![omit_gdb_pretty_printer_section]
+
 struct Struct {
     x: int
 }
index d73c3cf0f7789bebfbc16519942f84d6e1dffcf2..9f8c0aa06e67692f2fd118498707a31b4772f2fa 100644 (file)
@@ -16,6 +16,7 @@
 // lldb-command:run
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 trait Trait {
     fn method(&self) -> int { 0 }
index 02492bf1aa2cf58239792786c37b38587e4f9c59..3d28490c0cfd76f3f38eb38b0148d11ff44de2a7 100644 (file)
@@ -41,6 +41,7 @@
 // gdb-check:$10 = {x = {{40, 41, 42}, {43, 44}}, y = {45, 46, 47, 48}}
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 struct NoPadding1 {
     x: (i32, i32),
index 30fdd8c5530ade2b832f736ff8dce68fa25f03fe..b1228f7a8846ada1726d3a1b6156e2e3e9c10334 100644 (file)
@@ -57,6 +57,7 @@
 // lldb-check:[...]$6 = ((21, 22), 23)
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 fn main() {
     let no_padding1: ((u32, u32), u32, u32) = ((0, 1), 2, 3);
index 62c150878cfb99b722470a08cc4059a484c94ef8..0960ab5834dd6693b08d8aeec56e3f202c9723e0 100644 (file)
@@ -62,6 +62,9 @@
 // to all fields having the name "<unnamed_field>"). Otherwise they are handled the same a normal
 // structs.
 
+
+#![omit_gdb_pretty_printer_section]
+
 struct NoPadding16(u16, i16);
 struct NoPadding32(i32, f32, u32);
 struct NoPadding64(f64, i64, u64);
index 07a0f1696061134dba93e6008942ed0c4aae8d49..f205f484f25fb5ba1cd617560af0f293bc702799 100644 (file)
@@ -49,6 +49,7 @@
 // lldb-check:[...]$3 = TheOnlyCase(-1)
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 use self::Regular::{Case1, Case2, Case3};
 use self::Univariant::TheOnlyCase;
index 286c44667c5b46cdbfcf2ac4a246ceb4d2dcfaa9..ddcbfdcceee01c2c8bbb36d54055a53990cd3d62 100644 (file)
 // gdb-command:whatis stack_closure2
 // gdb-check:type = struct (&mut|i8, f32| -> f32, uint)
 
+#![omit_gdb_pretty_printer_section]
+
 use self::Enum1::{Variant1_1, Variant1_2};
 use std::ptr;
 
index 3c0a4a21b4fceb92125e897c1c60e9d72a084c6b..3d028eb1077bc70f431ae9f686f19ae7cec478fb 100644 (file)
@@ -42,6 +42,7 @@
 // lldb-check:[...]$2 = TheOnlyCase(123234)
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 // The first element is to ensure proper alignment, irrespective of the machines word size. Since
 // the size of the discriminant value is machine dependent, this has be taken into account when
index f3ee711e8fdc7530afde199b448c1c817a8480e6..99d67c60516b5a6fe1e8652c6efcf6e6952b7c4a 100644 (file)
@@ -79,6 +79,7 @@
 // lldb-command:continue
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 struct Struct {
     a: int,
index fca47ed47bd7a1adeeee3503369fc362301a006e..b34749260f30c16816b0d04dc798998f783a47d0 100644 (file)
@@ -42,6 +42,7 @@
 
 #![allow(unused_variables)]
 #![feature(unboxed_closures)]
+#![omit_gdb_pretty_printer_section]
 
 struct Struct {
     a: int,
index 761d0f0be8f583309d5a682b6ddfdbb264693438..f474e8d1317993feb8647e2d2626a4fb32ab9b9f 100644 (file)
@@ -72,6 +72,7 @@
 
 #![feature(unboxed_closures)]
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 struct Struct {
     a: int,
index dfe16452d85890ddb5d178f945000b0005143cfa..70211d74d885d9534bd600a8bc80b70fb7324774 100644 (file)
@@ -78,6 +78,7 @@
 
 #![allow(unused_variables)]
 #![feature(slicing_syntax)]
+#![omit_gdb_pretty_printer_section]
 
 struct AStruct {
     x: i16,
index 00c93653cf411892b4c4e7e7526ae36d4f5dbbc5..92a490206b6243afc7855c6484b6a20d15cf9cbe 100644 (file)
@@ -29,6 +29,7 @@
 // lldb-check:[...]$0 = [1, 2, 3]
 
 #![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
 
 static mut VECT: [i32; 3] = [1, 2, 3];
 
index 929cb9e7f17594631f5df6f52ea18d62cc1e256c..ed7284a8353651d26c1bf2fc09bbe3ae662e73b7 100644 (file)
@@ -8,20 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Check that object-safe methods are identified as such.  Also
-// acts as a regression test for #18490
+// Check that object-safe methods are identified as such.
 
 trait Tr {
-    // Static methods are always safe regardless of other rules
-    fn new() -> Self;
+    fn foo(&self);
 }
 
 struct St;
 
 impl Tr for St {
-    fn new() -> St { St }
+    fn foo(&self) {}
 }
 
 fn main() {
-    &St as &Tr;
+    let s: &Tr = &St;
+    s.foo();
 }