]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #35989 - 0xmohit:pr/error-code-E0453, r=jonathandturner
authorJonathan Turner <jonathandturner@users.noreply.github.com>
Sat, 27 Aug 2016 19:43:31 +0000 (12:43 -0700)
committerGitHub <noreply@github.com>
Sat, 27 Aug 2016 19:43:31 +0000 (12:43 -0700)
Update E0453 to new error format

Fixes #35929.
Part of #35233.

r? @jonathandturner

373 files changed:
mk/docs.mk
src/bootstrap/lib.rs
src/bootstrap/step.rs
src/doc/style/README.md [deleted file]
src/doc/style/SUMMARY.md [deleted file]
src/doc/style/errors/README.md [deleted file]
src/doc/style/errors/ergonomics.md [deleted file]
src/doc/style/errors/handling.md [deleted file]
src/doc/style/errors/propagation.md [deleted file]
src/doc/style/errors/signaling.md [deleted file]
src/doc/style/features/README.md [deleted file]
src/doc/style/features/crates.md [deleted file]
src/doc/style/features/functions-and-methods/README.md [deleted file]
src/doc/style/features/functions-and-methods/convenience.md [deleted file]
src/doc/style/features/functions-and-methods/input.md [deleted file]
src/doc/style/features/functions-and-methods/output.md [deleted file]
src/doc/style/features/let.md [deleted file]
src/doc/style/features/loops.md [deleted file]
src/doc/style/features/match.md [deleted file]
src/doc/style/features/modules.md [deleted file]
src/doc/style/features/traits/README.md [deleted file]
src/doc/style/features/traits/common.md [deleted file]
src/doc/style/features/traits/extensions.md [deleted file]
src/doc/style/features/traits/generics.md [deleted file]
src/doc/style/features/traits/objects.md [deleted file]
src/doc/style/features/traits/overloading.md [deleted file]
src/doc/style/features/traits/reuse.md [deleted file]
src/doc/style/features/types/README.md [deleted file]
src/doc/style/features/types/conversions.md [deleted file]
src/doc/style/features/types/newtype.md [deleted file]
src/doc/style/ownership/README.md [deleted file]
src/doc/style/ownership/builders.md [deleted file]
src/doc/style/ownership/cell-smart.md [deleted file]
src/doc/style/ownership/constructors.md [deleted file]
src/doc/style/ownership/destructors.md [deleted file]
src/doc/style/ownership/raii.md [deleted file]
src/doc/style/platform.md [deleted file]
src/doc/style/safety/README.md [deleted file]
src/doc/style/safety/lib-guarantees.md [deleted file]
src/doc/style/safety/unsafe.md [deleted file]
src/doc/style/style/README.md [deleted file]
src/doc/style/style/braces.md [deleted file]
src/doc/style/style/comments.md [deleted file]
src/doc/style/style/features.md [deleted file]
src/doc/style/style/imports.md [deleted file]
src/doc/style/style/naming/README.md [deleted file]
src/doc/style/style/naming/containers.md [deleted file]
src/doc/style/style/naming/conversions.md [deleted file]
src/doc/style/style/naming/iterators.md [deleted file]
src/doc/style/style/naming/ownership.md [deleted file]
src/doc/style/style/optional.md [deleted file]
src/doc/style/style/organization.md [deleted file]
src/doc/style/style/whitespace.md [deleted file]
src/doc/style/testing/README.md [deleted file]
src/doc/style/testing/unit.md [deleted file]
src/doc/style/todo.md [deleted file]
src/liballoc/boxed.rs
src/liballoc/lib.rs
src/libcollections/binary_heap.rs
src/libcollections/borrow.rs
src/libcollections/linked_list.rs
src/libcollections/range.rs
src/libcollections/vec_deque.rs
src/libcore/any.rs
src/libcore/array.rs
src/libcore/borrow.rs
src/libcore/cell.rs
src/libcore/char.rs
src/libcore/char_private.rs
src/libcore/clone.rs
src/libcore/cmp.rs
src/libcore/convert.rs
src/libcore/default.rs
src/libcore/fmt/builders.rs
src/libcore/fmt/mod.rs
src/libcore/fmt/num.rs
src/libcore/hash/mod.rs
src/libcore/hash/sip.rs
src/libcore/intrinsics.rs
src/libcore/iter/iterator.rs
src/libcore/iter/mod.rs
src/libcore/iter/range.rs
src/libcore/iter/sources.rs
src/libcore/iter/traits.rs
src/libcore/iter_private.rs
src/libcore/lib.rs
src/libcore/marker.rs
src/libcore/mem.rs
src/libcore/nonzero.rs
src/libcore/num/bignum.rs
src/libcore/num/dec2flt/algorithm.rs
src/libcore/num/dec2flt/mod.rs
src/libcore/num/dec2flt/num.rs
src/libcore/num/dec2flt/parse.rs
src/libcore/num/dec2flt/rawfp.rs
src/libcore/num/flt2dec/decoder.rs
src/libcore/num/flt2dec/mod.rs
src/libcore/num/flt2dec/strategy/dragon.rs
src/libcore/num/flt2dec/strategy/grisu.rs
src/libcore/num/mod.rs
src/libcore/ops.rs
src/libcore/option.rs
src/libcore/ptr.rs
src/libcore/result.rs
src/libcore/slice.rs
src/libcore/str/mod.rs
src/libcore/str/pattern.rs
src/libcore/sync/atomic.rs
src/libcore/tuple.rs
src/libcoretest/char.rs
src/librbml/lib.rs
src/librustc/infer/bivariate.rs
src/librustc/infer/combine.rs
src/librustc/infer/equate.rs
src/librustc/infer/error_reporting.rs
src/librustc/infer/freshen.rs
src/librustc/infer/glb.rs
src/librustc/infer/higher_ranked/mod.rs
src/librustc/infer/lub.rs
src/librustc/infer/mod.rs
src/librustc/infer/region_inference/graphviz.rs
src/librustc/infer/region_inference/mod.rs
src/librustc/infer/resolve.rs
src/librustc/infer/sub.rs
src/librustc/lib.rs
src/librustc/lint/builtin.rs
src/librustc/lint/context.rs
src/librustc/lint/mod.rs
src/librustc/middle/cstore.rs
src/librustc/middle/dead.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/free_region.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/region.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/mir/repr.rs
src/librustc/mir/tcx.rs
src/librustc/mir/visit.rs
src/librustc/session/config.rs
src/librustc/traits/error_reporting.rs
src/librustc/traits/fulfill.rs
src/librustc/traits/object_safety.rs
src/librustc/traits/select.rs
src/librustc/traits/util.rs
src/librustc/ty/_match.rs
src/librustc/ty/context.rs
src/librustc/ty/error.rs
src/librustc/ty/flags.rs
src/librustc/ty/fold.rs
src/librustc/ty/item_path.rs
src/librustc/ty/maps.rs
src/librustc/ty/mod.rs
src/librustc/ty/outlives.rs
src/librustc/ty/relate.rs
src/librustc/ty/structural_impls.rs
src/librustc/ty/sty.rs
src/librustc/ty/subst.rs
src/librustc/ty/util.rs
src/librustc/ty/walk.rs
src/librustc/ty/wf.rs
src/librustc/util/ppaux.rs
src/librustc_borrowck/borrowck/check_loans.rs
src/librustc_borrowck/borrowck/gather_loans/lifetime.rs
src/librustc_borrowck/borrowck/gather_loans/mod.rs
src/librustc_borrowck/borrowck/gather_loans/restrictions.rs
src/librustc_borrowck/borrowck/mir/dataflow/impls.rs
src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
src/librustc_borrowck/borrowck/mir/gather_moves.rs
src/librustc_borrowck/borrowck/mir/mod.rs
src/librustc_borrowck/borrowck/mir/patch.rs
src/librustc_borrowck/borrowck/mod.rs
src/librustc_const_eval/check_match.rs
src/librustc_driver/lib.rs
src/librustc_driver/test.rs
src/librustc_errors/emitter.rs
src/librustc_errors/lib.rs
src/librustc_errors/lock.rs [new file with mode: 0644]
src/librustc_llvm/ffi.rs
src/librustc_metadata/astencode.rs
src/librustc_metadata/csearch.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/tydecode.rs
src/librustc_metadata/tyencode.rs
src/librustc_mir/build/cfg.rs
src/librustc_mir/build/matches/mod.rs
src/librustc_mir/build/matches/test.rs
src/librustc_mir/build/mod.rs
src/librustc_mir/build/scope.rs
src/librustc_mir/hair/cx/expr.rs
src/librustc_mir/hair/cx/mod.rs
src/librustc_mir/hair/cx/pattern.rs
src/librustc_mir/hair/mod.rs
src/librustc_mir/pretty.rs
src/librustc_mir/transform/no_landing_pads.rs
src/librustc_mir/transform/promote_consts.rs
src/librustc_mir/transform/qualify_consts.rs
src/librustc_mir/transform/type_check.rs
src/librustc_passes/consts.rs
src/librustc_passes/rvalues.rs
src/librustc_trans/back/symbol_names.rs
src/librustc_trans/base.rs
src/librustc_trans/callee.rs
src/librustc_trans/collector.rs
src/librustc_trans/common.rs
src/librustc_trans/context.rs
src/librustc_trans/debuginfo/create_scope_map.rs
src/librustc_trans/debuginfo/metadata.rs
src/librustc_trans/debuginfo/mod.rs
src/librustc_trans/debuginfo/type_names.rs
src/librustc_trans/glue.rs
src/librustc_trans/intrinsic.rs
src/librustc_trans/meth.rs
src/librustc_trans/mir/analyze.rs
src/librustc_trans/mir/mod.rs
src/librustc_trans/monomorphize.rs
src/librustc_trans/partitioning.rs
src/librustc_trans/trans_item.rs
src/librustc_trans/type_of.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/autoderef.rs
src/librustc_typeck/check/closure.rs
src/librustc_typeck/check/coercion.rs
src/librustc_typeck/check/compare_method.rs
src/librustc_typeck/check/dropck.rs
src/librustc_typeck/check/intrinsic.rs
src/librustc_typeck/check/method/confirm.rs
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/method/suggest.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/check/upvar.rs
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/check/writeback.rs
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/constrained_type_params.rs
src/librustc_typeck/lib.rs
src/librustc_typeck/rscope.rs
src/librustc_typeck/variance/constraints.rs
src/librustc_typeck/variance/solve.rs
src/librustc_typeck/variance/terms.rs
src/librustdoc/clean/mod.rs
src/librustdoc/html/format.rs
src/librustdoc/html/item_type.rs
src/librustdoc/html/render.rs
src/libstd/ascii.rs
src/libstd/collections/hash/map.rs
src/libstd/collections/hash/set.rs
src/libstd/env.rs
src/libstd/error.rs
src/libstd/ffi/c_str.rs
src/libstd/ffi/os_str.rs
src/libstd/fs.rs
src/libstd/io/buffered.rs
src/libstd/io/cursor.rs
src/libstd/io/error.rs
src/libstd/io/impls.rs
src/libstd/io/lazy.rs
src/libstd/io/mod.rs
src/libstd/io/stdio.rs
src/libstd/io/util.rs
src/libstd/lib.rs
src/libstd/memchr.rs
src/libstd/net/addr.rs
src/libstd/net/ip.rs
src/libstd/net/mod.rs
src/libstd/net/parser.rs
src/libstd/net/tcp.rs
src/libstd/net/test.rs
src/libstd/net/udp.rs
src/libstd/num/mod.rs
src/libstd/panic.rs
src/libstd/panicking.rs
src/libstd/path.rs
src/libstd/process.rs
src/libstd/rt.rs
src/libstd/sync/barrier.rs
src/libstd/sync/condvar.rs
src/libstd/sync/mpsc/blocking.rs
src/libstd/sync/mpsc/mod.rs
src/libstd/sync/mpsc/mpsc_queue.rs
src/libstd/sync/mpsc/select.rs
src/libstd/sync/mpsc/spsc_queue.rs
src/libstd/sync/mpsc/sync.rs
src/libstd/sync/mutex.rs
src/libstd/sync/once.rs
src/libstd/sync/rwlock.rs
src/libstd/sys/common/args.rs
src/libstd/sys/common/at_exit_imp.rs
src/libstd/sys/common/backtrace.rs
src/libstd/sys/common/io.rs
src/libstd/sys/common/mod.rs
src/libstd/sys/common/mutex.rs
src/libstd/sys/common/net.rs
src/libstd/sys/common/remutex.rs
src/libstd/sys/common/thread.rs
src/libstd/sys/common/thread_info.rs
src/libstd/sys/common/thread_local.rs
src/libstd/sys/common/wtf8.rs
src/libstd/sys/unix/ext/ffi.rs
src/libstd/sys/unix/ext/net.rs
src/libstd/sys/unix/ext/process.rs
src/libstd/sys/unix/fd.rs
src/libstd/sys/unix/fs.rs
src/libstd/sys/unix/net.rs
src/libstd/sys/unix/os.rs
src/libstd/sys/unix/os_str.rs
src/libstd/sys/unix/pipe.rs
src/libstd/sys/unix/process.rs
src/libstd/sys/unix/rand.rs
src/libstd/sys/unix/stdio.rs
src/libstd/sys/unix/thread.rs
src/libstd/sys/windows/compat.rs
src/libstd/sys/windows/dynamic_lib.rs
src/libstd/sys/windows/fs.rs
src/libstd/sys/windows/handle.rs
src/libstd/sys/windows/mod.rs
src/libstd/sys/windows/mutex.rs
src/libstd/sys/windows/net.rs
src/libstd/sys/windows/os.rs
src/libstd/sys/windows/os_str.rs
src/libstd/sys/windows/pipe.rs
src/libstd/sys/windows/process.rs
src/libstd/sys/windows/stdio.rs
src/libstd/sys/windows/thread.rs
src/libstd/sys/windows/thread_local.rs
src/libstd/thread/local.rs
src/libstd/thread/mod.rs
src/libsyntax/ext/expand.rs
src/libsyntax/feature_gate.rs
src/libsyntax/parse/parser.rs
src/rustllvm/RustWrapper.cpp
src/test/compile-fail/E0277.rs
src/test/compile-fail/E0389.rs
src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs
src/test/compile-fail/cast-rfc0401.rs
src/test/compile-fail/const-unsized.rs
src/test/compile-fail/impl-trait/auto-trait-leak.rs
src/test/compile-fail/issue-30007.rs
src/test/compile-fail/issue-32950.rs
src/test/compile-fail/issue-35869.rs [new file with mode: 0644]
src/test/compile-fail/macro-context.rs
src/test/compile-fail/macro-error.rs
src/test/compile-fail/missing-block-hint.rs [new file with mode: 0644]
src/test/compile-fail/on-unimplemented/multiple-impls.rs
src/test/compile-fail/on-unimplemented/on-impl.rs
src/test/compile-fail/on-unimplemented/on-trait.rs
src/test/compile-fail/on-unimplemented/slice-index.rs
src/test/compile-fail/privacy/restricted/tuple-struct-fields/test.rs
src/test/compile-fail/privacy/restricted/tuple-struct-fields/test2.rs
src/test/compile-fail/privacy/restricted/tuple-struct-fields/test3.rs
src/test/compile-fail/syntax-extension-minor.rs
src/test/compile-fail/trait-suggest-where-clause.rs
src/test/compile-fail/type-macros-fail.rs [deleted file]
src/test/compile-fail/variance-associated-types.rs
src/test/compile-fail/variance-object-types.rs
src/test/compile-fail/variance-region-bounds.rs
src/test/compile-fail/variance-regions-direct.rs
src/test/compile-fail/variance-regions-indirect.rs
src/test/compile-fail/variance-trait-bounds.rs
src/test/compile-fail/variance-trait-object-bound.rs
src/test/compile-fail/variance-types-bounds.rs
src/test/compile-fail/variance-types.rs
src/test/debuginfo/auxiliary/macro-stepping.rs [new file with mode: 0644]
src/test/debuginfo/lexical-scope-with-macro.rs
src/test/debuginfo/macro-stepping.rs [new file with mode: 0644]
src/test/run-pass-fulldeps/auxiliary/dummy_mir_pass.rs
src/test/run-pass/fds-are-cloexec.rs
src/test/run-pass/mir_heavy_promoted.rs [new file with mode: 0644]
src/test/run-pass/simd-intrinsic-generic-cast.rs
src/test/run-pass/type-macros-hlist.rs
src/test/run-pass/type-macros-simple.rs

index f202c75360bf8f8c99c9f7cc35eb2cc32654546d..6c0be654e1f5d74a8e39b6f18f26896742fda9d1 100644 (file)
@@ -66,7 +66,7 @@ ERR_IDX_GEN_MD = $(RPATH_VAR2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) $(ERR_IDX_GEN_EXE)
 
 D := $(S)src/doc
 
-DOC_TARGETS := book nomicon style error-index
+DOC_TARGETS := book nomicon error-index
 COMPILER_DOC_TARGETS :=
 DOC_L10N_TARGETS :=
 
@@ -209,13 +209,6 @@ doc/nomicon/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/nomicon/*.md) |
        $(Q)rm -rf doc/nomicon
        $(Q)$(RUSTBOOK) build $(S)src/doc/nomicon doc/nomicon
 
-style: doc/style/index.html
-
-doc/style/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/style/*.md) | doc/
-       @$(call E, rustbook: $@)
-       $(Q)rm -rf doc/style
-       $(Q)$(RUSTBOOK) build $(S)src/doc/style doc/style
-
 error-index: doc/error-index.html
 
 # Metadata used to generate the index is created as a side effect of
index b40dbfde4a4a5af0cd25554091f1079abf5e17ab..9eacb5e3924fa25a62059081803b41830bd11343 100644 (file)
@@ -308,10 +308,6 @@ pub fn build(&mut self) {
                     doc::rustbook(self, stage, target.target, "nomicon",
                                   &doc_out);
                 }
-                DocStyle { stage } => {
-                    doc::rustbook(self, stage, target.target, "style",
-                                  &doc_out);
-                }
                 DocStandalone { stage } => {
                     doc::standalone(self, stage, target.target, &doc_out);
                 }
index 8d3cb36166b70ffb5e0ab2b5850734aa222f96d1..12929664886c4964f2096f0f530ec1946b3cd924 100644 (file)
@@ -92,7 +92,6 @@ macro_rules! targets {
             (doc, Doc { stage: u32 }),
             (doc_book, DocBook { stage: u32 }),
             (doc_nomicon, DocNomicon { stage: u32 }),
-            (doc_style, DocStyle { stage: u32 }),
             (doc_standalone, DocStandalone { stage: u32 }),
             (doc_std, DocStd { stage: u32 }),
             (doc_test, DocTest { stage: u32 }),
@@ -366,8 +365,7 @@ pub fn deps(&self, build: &'a Build) -> Vec<Step<'a>> {
                 vec![self.libtest(compiler)]
             }
             Source::DocBook { stage } |
-            Source::DocNomicon { stage } |
-            Source::DocStyle { stage } => {
+            Source::DocNomicon { stage } => {
                 vec![self.target(&build.config.build).tool_rustbook(stage)]
             }
             Source::DocErrorIndex { stage } => {
@@ -382,8 +380,7 @@ pub fn deps(&self, build: &'a Build) -> Vec<Step<'a>> {
             Source::Doc { stage } => {
                 let mut deps = vec![
                     self.doc_book(stage), self.doc_nomicon(stage),
-                    self.doc_style(stage), self.doc_standalone(stage),
-                    self.doc_std(stage),
+                    self.doc_standalone(stage), self.doc_std(stage),
                     self.doc_error_index(stage),
                 ];
 
diff --git a/src/doc/style/README.md b/src/doc/style/README.md
deleted file mode 100644 (file)
index 8d837d1..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-% Style Guidelines
-
-This document collects the emerging principles, conventions, abstractions, and
-best practices for writing Rust code.
-
-Since Rust is evolving at a rapid pace, these guidelines are
-preliminary. The hope is that writing them down explicitly will help
-drive discussion, consensus and adoption.
-
-Whenever feasible, guidelines provide specific examples from Rust's standard
-libraries.
-
-### Guideline statuses
-
-Every guideline has a status:
-
-* **[FIXME]**: Marks places where there is more work to be done. In
-  some cases, that just means going through the RFC process.
-
-* **[FIXME #NNNNN]**: Like **[FIXME]**, but links to the issue tracker.
-
-* **[RFC #NNNN]**: Marks accepted guidelines, linking to the rust-lang
-  RFC establishing them.
-
-### Guideline stabilization
-
-One purpose of these guidelines is to reach decisions on a number of
-cross-cutting API and stylistic choices. Discussion and development of
-the guidelines will happen primarily on https://internals.rust-lang.org/,
-using the Guidelines category. Discussion can also occur on the
-[guidelines issue tracker](https://github.com/rust-lang/rust-guidelines).
-
-Guidelines that are under development or discussion will be marked with the
-status **[FIXME]**, with a link to the issue tracker when appropriate.
-
-Once a concrete guideline is ready to be proposed, it should be filed
-as an [FIXME: needs RFC](https://github.com/rust-lang/rfcs). If the RFC is
-accepted, the official guidelines will be updated to match, and will
-include the tag **[RFC #NNNN]** linking to the RFC document.
-
-### What's in this document
-
-This document is broken into four parts:
-
-* **[Style](style/README.md)** provides a set of rules governing naming conventions,
-  whitespace, and other stylistic issues.
-
-* **[Guidelines by Rust feature](features/README.md)** places the focus on each of
-  Rust's features, starting from expressions and working the way out toward
-  crates, dispensing guidelines relevant to each.
-
-* **Topical guidelines and patterns**. The rest of the document proceeds by
-  cross-cutting topic, starting with
-  [Ownership and resources](ownership/README.md).
-
-* **APIs for a changing Rust**
-  discusses the forward-compatibility hazards, especially those that interact
-  with the pre-1.0 library stabilization process.
-
-> **[FIXME]** Add cross-references throughout this document to the tutorial,
-> reference manual, and other guides.
-
-> **[FIXME]** What are some _non_-goals, _non_-principles, or _anti_-patterns that
-> we should document?
diff --git a/src/doc/style/SUMMARY.md b/src/doc/style/SUMMARY.md
deleted file mode 100644 (file)
index 508ede6..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-# Summary
-
-* [Style](style/README.md)
-    * [Whitespace](style/whitespace.md)
-    * [Comments](style/comments.md)
-    * [Braces, semicolons, commas](style/braces.md)
-    * [Naming](style/naming/README.md)
-        * [Ownership variants](style/naming/ownership.md)
-        * [Containers/wrappers](style/naming/containers.md)
-        * [Conversions](style/naming/conversions.md)
-        * [Iterators](style/naming/iterators.md)
-    * [Imports](style/imports.md)
-    * [Organization](style/organization.md)
-* [Guidelines by Rust feature](features/README.md)
-    * [Let binding](features/let.md)
-    * [Pattern matching](features/match.md)
-    * [Loops](features/loops.md)
-    * [Functions and methods](features/functions-and-methods/README.md)
-        * [Input](features/functions-and-methods/input.md)
-        * [Output](features/functions-and-methods/output.md)
-        * [For convenience](features/functions-and-methods/convenience.md)
-    * [Types](features/types/README.md)
-        * [Conversions](features/types/conversions.md)
-        * [The newtype pattern](features/types/newtype.md)
-    * [Traits](features/traits/README.md)
-        * [For generics](features/traits/generics.md)
-        * [For objects](features/traits/objects.md)
-        * [For overloading](features/traits/overloading.md)
-        * [For extensions](features/traits/extensions.md)
-        * [For reuse](features/traits/reuse.md)
-        * [Common traits](features/traits/common.md)
-    * [Modules](features/modules.md)
-    * [Crates](features/crates.md)
-* [Ownership and resources](ownership/README.md)
-    * [Constructors](ownership/constructors.md)
-    * [Builders](ownership/builders.md)
-    * [Destructors](ownership/destructors.md)
-    * [RAII](ownership/raii.md)
-    * [Cells and smart pointers](ownership/cell-smart.md)
-* [Errors](errors/README.md)
-    * [Signaling](errors/signaling.md)
-    * [Handling](errors/handling.md)
-    * [Propagation](errors/propagation.md)
-    * [Ergonomics](errors/ergonomics.md)
-* [Safety and guarantees](safety/README.md)
-    * [Using unsafe](safety/unsafe.md)
-    * [Library guarantees](safety/lib-guarantees.md)
-* [Testing](testing/README.md)
-    * [Unit testing](testing/unit.md)
-* [FFI, platform-specific code](platform.md)
diff --git a/src/doc/style/errors/README.md b/src/doc/style/errors/README.md
deleted file mode 100644 (file)
index 444da26..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-% Errors
-
-> **[FIXME]** Add some general text here.
diff --git a/src/doc/style/errors/ergonomics.md b/src/doc/style/errors/ergonomics.md
deleted file mode 100644 (file)
index 269f2a2..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-% Ergonomic error handling
-
-Error propagation with raw `Result`s can require tedious matching and
-repackaging. This tedium is largely alleviated by the `try!` macro,
-and can be completely removed (in some cases) by the "`Result`-`impl`"
-pattern.
-
-### The `try!` macro
-
-Prefer
-
-```rust,ignore
-use std::io::{File, Open, Write, IoError};
-
-struct Info {
-    name: String,
-    age: i32,
-    rating: i32
-}
-
-fn write_info(info: &Info) -> Result<(), IoError> {
-    let mut file = File::open_mode(&Path::new("my_best_friends.txt"),
-                                   Open, Write);
-    // Early return on error
-    try!(file.write_line(&format!("name: {}", info.name)));
-    try!(file.write_line(&format!("age: {}", info.age)));
-    try!(file.write_line(&format!("rating: {}", info.rating)));
-    return Ok(());
-}
-```
-
-over
-
-```rust,ignore
-use std::io::{File, Open, Write, IoError};
-
-struct Info {
-    name: String,
-    age: i32,
-    rating: i32
-}
-
-fn write_info(info: &Info) -> Result<(), IoError> {
-    let mut file = File::open_mode(&Path::new("my_best_friends.txt"),
-                                   Open, Write);
-    // Early return on error
-    match file.write_line(&format!("name: {}", info.name)) {
-        Ok(_) => (),
-        Err(e) => return Err(e)
-    }
-    match file.write_line(&format!("age: {}", info.age)) {
-        Ok(_) => (),
-        Err(e) => return Err(e)
-    }
-    return file.write_line(&format!("rating: {}", info.rating));
-}
-```
-
-See
-[the `result` module documentation](https://doc.rust-lang.org/stable/std/result/index.html#the-try-macro)
-for more details.
-
-### The `Result`-`impl` pattern [FIXME]
-
-> **[FIXME]** Document the way that the `io` module uses trait impls
-> on `std::io::Result` to painlessly propagate errors.
diff --git a/src/doc/style/errors/handling.md b/src/doc/style/errors/handling.md
deleted file mode 100644 (file)
index 9b8a00d..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-% Handling errors
-
-### Use thread isolation to cope with failure. [FIXME]
-
-> **[FIXME]** Explain how to isolate threads and detect thread failure for recovery.
-
-### Consuming `Result` [FIXME]
diff --git a/src/doc/style/errors/propagation.md b/src/doc/style/errors/propagation.md
deleted file mode 100644 (file)
index 0a347cd..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-% Propagation
-
-> **[FIXME]** We need guidelines on how to layer error information up a stack of
-> abstractions.
-
-### Error interoperation [FIXME]
-
-> **[FIXME]** Document the `FromError` infrastructure.
diff --git a/src/doc/style/errors/signaling.md b/src/doc/style/errors/signaling.md
deleted file mode 100644 (file)
index 4038ec1..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-% Signaling errors [RFC #236]
-
-> The guidelines below were approved by [RFC #236](https://github.com/rust-lang/rfcs/pull/236).
-
-Errors fall into one of three categories:
-
-* Catastrophic errors, e.g. out-of-memory.
-* Contract violations, e.g. wrong input encoding, index out of bounds.
-* Obstructions, e.g. file not found, parse error.
-
-The basic principle of the convention is that:
-
-* Catastrophic errors and programming errors (bugs) can and should only be
-recovered at a *coarse grain*, i.e. a thread boundary.
-* Obstructions preventing an operation should be reported at a maximally *fine
-grain* -- to the immediate invoker of the operation.
-
-## Catastrophic errors
-
-An error is _catastrophic_ if there is no meaningful way for the current thread to
-continue after the error occurs.
-
-Catastrophic errors are _extremely_ rare, especially outside of `libstd`.
-
-**Canonical examples**: out of memory, stack overflow.
-
-### For catastrophic errors, panic
-
-For errors like stack overflow, Rust currently aborts the process, but
-could in principle panic, which (in the best case) would allow
-reporting and recovery from a supervisory thread.
-
-## Contract violations
-
-An API may define a contract that goes beyond the type checking enforced by the
-compiler. For example, slices support an indexing operation, with the contract
-that the supplied index must be in bounds.
-
-Contracts can be complex and involve more than a single function invocation. For
-example, the `RefCell` type requires that `borrow_mut` not be called until all
-existing borrows have been relinquished.
-
-### For contract violations, panic
-
-A contract violation is always a bug, and for bugs we follow the Erlang
-philosophy of "let it crash": we assume that software *will* have bugs, and we
-design coarse-grained thread boundaries to report, and perhaps recover, from these
-bugs.
-
-### Contract design
-
-One subtle aspect of these guidelines is that the contract for a function is
-chosen by an API designer -- and so the designer also determines what counts as
-a violation.
-
-This RFC does not attempt to give hard-and-fast rules for designing
-contracts. However, here are some rough guidelines:
-
-* Prefer expressing contracts through static types whenever possible.
-
-* It *must* be possible to write code that uses the API without violating the
-  contract.
-
-* Contracts are most justified when violations are *inarguably* bugs -- but this
-  is surprisingly rare.
-
-* Consider whether the API client could benefit from the contract-checking
-  logic.  The checks may be expensive. Or there may be useful programming
-  patterns where the client does not want to check inputs before hand, but would
-  rather attempt the operation and then find out whether the inputs were invalid.
-
-* When a contract violation is the *only* kind of error a function may encounter
-  -- i.e., there are no obstructions to its success other than "bad" inputs --
-  using `Result` or `Option` instead is especially warranted. Clients can then use
-  `unwrap` to assert that they have passed valid input, or re-use the error
-  checking done by the API for their own purposes.
-
-* When in doubt, use loose contracts and instead return a `Result` or `Option`.
-
-## Obstructions
-
-An operation is *obstructed* if it cannot be completed for some reason, even
-though the operation's contract has been satisfied. Obstructed operations may
-have (documented!) side effects -- they are not required to roll back after
-encountering an obstruction.  However, they should leave the data structures in
-a "coherent" state (satisfying their invariants, continuing to guarantee safety,
-etc.).
-
-Obstructions may involve external conditions (e.g., I/O), or they may involve
-aspects of the input that are not covered by the contract.
-
-**Canonical examples**: file not found, parse error.
-
-### For obstructions, use `Result`
-
-The
-[`Result<T,E>` type](https://doc.rust-lang.org/stable/std/result/index.html)
-represents either a success (yielding `T`) or failure (yielding `E`). By
-returning a `Result`, a function allows its clients to discover and react to
-obstructions in a fine-grained way.
-
-#### What about `Option`?
-
-The `Option` type should not be used for "obstructed" operations; it
-should only be used when a `None` return value could be considered a
-"successful" execution of the operation.
-
-This is of course a somewhat subjective question, but a good litmus
-test is: would a reasonable client ever ignore the result? The
-`Result` type provides a lint that ensures the result is actually
-inspected, while `Option` does not, and this difference of behavior
-can help when deciding between the two types.
-
-Another litmus test: can the operation be understood as asking a
-question (possibly with sideeffects)? Operations like `pop` on a
-vector can be viewed as asking for the contents of the first element,
-with the side effect of removing it if it exists -- with an `Option`
-return value.
-
-## Do not provide both `Result` and `panic!` variants.
-
-An API should not provide both `Result`-producing and `panic`king versions of an
-operation. It should provide just the `Result` version, allowing clients to use
-`try!` or `unwrap` instead as needed. This is part of the general pattern of
-cutting down on redundant variants by instead using method chaining.
diff --git a/src/doc/style/features/README.md b/src/doc/style/features/README.md
deleted file mode 100644 (file)
index 0965750..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-% Guidelines by language feature
-
-Rust provides a unique combination of language features, some new and some
-old. This section gives guidance on when and how to use Rust's features, and
-brings attention to some of the tradeoffs between different features.
-
-Notably missing from this section is an in-depth discussion of Rust's pointer
-types (both built-in and in the library). The topic of pointers is discussed at
-length in a [separate section on ownership](../ownership/README.md).
diff --git a/src/doc/style/features/crates.md b/src/doc/style/features/crates.md
deleted file mode 100644 (file)
index 4748b05..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-% Crates
-
-> **[FIXME]** What general guidelines should we provide for crate design?
-
-> Possible topics: facades; per-crate preludes (to be imported as globs);
-> "lib.rs"
diff --git a/src/doc/style/features/functions-and-methods/README.md b/src/doc/style/features/functions-and-methods/README.md
deleted file mode 100644 (file)
index a3559ca..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-% Functions and methods
-
-### Prefer methods to functions if there is a clear receiver. **[FIXME: needs RFC]**
-
-Prefer
-
-```rust,ignore
-impl Foo {
-    pub fn frob(&self, w: widget) { ... }
-}
-```
-
-over
-
-```rust,ignore
-pub fn frob(foo: &Foo, w: widget) { ... }
-```
-
-for any operation that is clearly associated with a particular
-type.
-
-Methods have numerous advantages over functions:
-
-* They do not need to be imported or qualified to be used: all you
-  need is a value of the appropriate type.
-* Their invocation performs autoborrowing (including mutable borrows).
-* They make it easy to answer the question "what can I do with a value
-  of type `T`" (especially when using rustdoc).
-* They provide `self` notation, which is more concise and often more
-  clearly conveys ownership distinctions.
-
-> **[FIXME]** Revisit these guidelines with
-> [UFCS](https://github.com/nick29581/rfcs/blob/ufcs/0000-ufcs.md) and
-> conventions developing around it.
-
-
-
-### Guidelines for inherent methods. **[FIXME]**
-
-> **[FIXME]** We need guidelines for when to provide inherent methods on a type,
-> versus methods through a trait or functions.
-
-> **NOTE**: Rules for method resolution around inherent methods are in flux,
-> which may impact the guidelines.
diff --git a/src/doc/style/features/functions-and-methods/convenience.md b/src/doc/style/features/functions-and-methods/convenience.md
deleted file mode 100644 (file)
index 69fd377..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-% Convenience methods
-
-### Provide small, coherent sets of convenience methods. **[FIXME: needs RFC]**
-
-_Convenience methods_ wrap up existing functionality in a more convenient
-way. The work done by a convenience method varies widely:
-
-* _Re-providing functions as methods_. For example, the `std::path::Path` type
-  provides methods like `stat` on `Path`s that simply invoke the corresponding
-  function in `std::io::fs`.
-* _Skipping through conversions_. For example, the `str` type provides a
-  `.len()` convenience method which is also expressible as `.as_bytes().len()`.
-  Sometimes the conversion is more complex: the `str` module also provides
-  `from_chars`, which encapsulates a simple use of iterators.
-* _Encapsulating common arguments_. For example, vectors of `&str`s
-  provide a `connect` as well as a special case, `concat`, that is expressible
-  using `connect` with a fixed separator of `""`.
-* _Providing more efficient special cases_. The `connect` and `concat` example
-  also applies here: singling out `concat` as a special case allows for a more
-  efficient implementation.
-
-  Note, however, that the `connect` method actually detects the special case
-  internally and invokes `concat`. Usually, it is not necessary to add a public
-  convenience method just for efficiency gains; there should also be a
-  _conceptual_ reason to add it, e.g. because it is such a common special case.
-
-It is tempting to add convenience methods in a one-off, haphazard way as
-common use patterns emerge. Avoid this temptation, and instead _design_ small,
-coherent sets of convenience methods that are easy to remember:
-
-* _Small_: Avoid combinatorial explosions of convenience methods. For example,
-  instead of adding `_str` variants of methods that provide a `str` output,
-  instead ensure that the normal output type of methods is easily convertible to
-  `str`.
-* _Coherent_: Look for small groups of convenience methods that make sense to
-  include together. For example, the `Path` API mentioned above includes a small
-  selection of the most common filesystem operations that take a `Path`
-  argument.  If one convenience method strongly suggests the existence of others,
-  consider adding the whole group.
-* _Memorable_: It is not worth saving a few characters of typing if you have to
-  look up the name of a convenience method every time you use it. Add
-  convenience methods with names that are obvious and easy to remember, and add
-  them for the most common or painful use cases.
diff --git a/src/doc/style/features/functions-and-methods/input.md b/src/doc/style/features/functions-and-methods/input.md
deleted file mode 100644 (file)
index 5b63a45..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-% Input to functions and methods
-
-### Let the client decide when to copy and where to place data. [FIXME: needs RFC]
-
-#### Copying:
-
-Prefer
-
-```rust,ignore
-fn foo(b: Bar) {
-   // use b as owned, directly
-}
-```
-
-over
-
-```rust,ignore
-fn foo(b: &Bar) {
-    let b = b.clone();
-    // use b as owned after cloning
-}
-```
-
-If a function requires ownership of a value of unknown type `T`, but does not
-otherwise need to make copies, the function should take ownership of the
-argument (pass by value `T`) rather than using `.clone()`. That way, the caller
-can decide whether to relinquish ownership or to `clone`.
-
-Similarly, the `Copy` trait bound should only be demanded it when absolutely
-needed, not as a way of signaling that copies should be cheap to make.
-
-#### Placement:
-
-Prefer
-
-```rust,ignore
-fn foo(b: Bar) -> Bar { ... }
-```
-
-over
-
-```rust,ignore
-fn foo(b: Box<Bar>) -> Box<Bar> { ... }
-```
-
-for concrete types `Bar` (as opposed to trait objects). This way, the caller can
-decide whether to place data on the stack or heap. No overhead is imposed by
-letting the caller determine the placement.
-
-### Minimize assumptions about parameters. [FIXME: needs RFC]
-
-The fewer assumptions a function makes about its inputs, the more widely usable
-it becomes.
-
-#### Minimizing assumptions through generics:
-
-Prefer
-
-```rust,ignore
-fn foo<T: Iterator<i32>>(c: T) { ... }
-```
-
-over any of
-
-```rust,ignore
-fn foo(c: &[i32]) { ... }
-fn foo(c: &Vec<i32>) { ... }
-fn foo(c: &SomeOtherCollection<i32>) { ... }
-```
-
-if the function only needs to iterate over the data.
-
-More generally, consider using generics to pinpoint the assumptions a function
-needs to make about its arguments.
-
-On the other hand, generics can make it more difficult to read and understand a
-function's signature. Aim for "natural" parameter types that a neither overly
-concrete nor overly abstract. See the discussion on
-[traits](../traits/README.md) for more guidance.
-
-
-#### Minimizing ownership assumptions:
-
-Prefer either of
-
-```rust,ignore
-fn foo(b: &Bar) { ... }
-fn foo(b: &mut Bar) { ... }
-```
-
-over
-
-```rust,ignore
-fn foo(b: Bar) { ... }
-```
-
-That is, prefer borrowing arguments rather than transferring ownership, unless
-ownership is actually needed.
-
-### Prefer compound return types to out-parameters. [FIXME: needs RFC]
-
-Prefer
-
-```rust,ignore
-fn foo() -> (Bar, Bar)
-```
-
-over
-
-```rust,ignore
-fn foo(output: &mut Bar) -> Bar
-```
-
-for returning multiple `Bar` values.
-
-Compound return types like tuples and structs are efficiently compiled
-and do not require heap allocation. If a function needs to return
-multiple values, it should do so via one of these types.
-
-The primary exception: sometimes a function is meant to modify data
-that the caller already owns, for example to re-use a buffer:
-
-```rust,ignore
-fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize>
-```
-
-(From the [Read trait](https://doc.rust-lang.org/stable/std/io/trait.Read.html#tymethod.read).)
-
-### Consider validating arguments, statically or dynamically. [FIXME: needs RFC]
-
-_Note: this material is closely related to
-  [library-level guarantees](../../safety/lib-guarantees.md)._
-
-Rust APIs do _not_ generally follow the
-[robustness principle](https://en.wikipedia.org/wiki/Robustness_principle): "be
-conservative in what you send; be liberal in what you accept".
-
-Instead, Rust code should _enforce_ the validity of input whenever practical.
-
-Enforcement can be achieved through the following mechanisms (listed
-in order of preference).
-
-#### Static enforcement:
-
-Choose an argument type that rules out bad inputs.
-
-For example, prefer
-
-```rust,ignore
-enum FooMode {
-    Mode1,
-    Mode2,
-    Mode3,
-}
-fn foo(mode: FooMode) { ... }
-```
-
-over
-
-```rust,ignore
-fn foo(mode2: bool, mode3: bool) {
-    assert!(!mode2 || !mode3);
-    ...
-}
-```
-
-Static enforcement usually comes at little run-time cost: it pushes the
-costs to the boundaries. It also catches bugs early, during compilation,
-rather than through run-time failures.
-
-On the other hand, some properties are difficult or impossible to
-express using types.
-
-#### Dynamic enforcement:
-
-Validate the input as it is processed (or ahead of time, if necessary).  Dynamic
-checking is often easier to implement than static checking, but has several
-downsides:
-
-1. Runtime overhead (unless checking can be done as part of processing the input).
-2. Delayed detection of bugs.
-3. Introduces failure cases, either via `panic!` or `Result`/`Option` types (see
-   the [error handling guidelines](../../errors/README.md)), which must then be
-   dealt with by client code.
-
-#### Dynamic enforcement with `debug_assert!`:
-
-Same as dynamic enforcement, but with the possibility of easily turning off
-expensive checks for production builds.
-
-#### Dynamic enforcement with opt-out:
-
-Same as dynamic enforcement, but adds sibling functions that opt out of the
-checking.
-
-The convention is to mark these opt-out functions with a suffix like
-`_unchecked` or by placing them in a `raw` submodule.
-
-The unchecked functions can be used judiciously in cases where (1) performance
-dictates avoiding checks and (2) the client is otherwise confident that the
-inputs are valid.
-
-> **[FIXME]** Should opt-out functions be marked `unsafe`?
diff --git a/src/doc/style/features/functions-and-methods/output.md b/src/doc/style/features/functions-and-methods/output.md
deleted file mode 100644 (file)
index e26eee5..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-% Output from functions and methods
-
-### Don't overpromise. [FIXME]
-
-> **[FIXME]** Add discussion of overly-specific return types,
-> e.g. returning a compound iterator type rather than hiding it behind
-> a use of newtype.
-
-### Let clients choose what to throw away. [FIXME: needs RFC]
-
-#### Return useful intermediate results:
-
-Many functions that answer a question also compute interesting related data.  If
-this data is potentially of interest to the client, consider exposing it in the
-API.
-
-Prefer
-
-```rust,ignore
-struct SearchResult {
-    found: bool,          // item in container?
-    expected_index: usize // what would the item's index be?
-}
-
-fn binary_search(&self, k: Key) -> SearchResult
-```
-or
-
-```rust,ignore
-fn binary_search(&self, k: Key) -> (bool, usize)
-```
-
-over
-
-```rust,ignore
-fn binary_search(&self, k: Key) -> bool
-```
-
-#### Yield back ownership:
-
-Prefer
-
-```rust,ignore
-fn from_utf8_owned(vv: Vec<u8>) -> Result<String, Vec<u8>>
-```
-
-over
-
-```rust,ignore
-fn from_utf8_owned(vv: Vec<u8>) -> Option<String>
-```
-
-The `from_utf8_owned` function gains ownership of a vector.  In the successful
-case, the function consumes its input, returning an owned string without
-allocating or copying. In the unsuccessful case, however, the function returns
-back ownership of the original slice.
diff --git a/src/doc/style/features/let.md b/src/doc/style/features/let.md
deleted file mode 100644 (file)
index ba9787b..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-% Let binding
-
-### Always separately bind RAII guards. [FIXME: needs RFC]
-
-Prefer
-
-```rust,ignore
-fn use_mutex(m: sync::mutex::Mutex<i32>) {
-    let guard = m.lock();
-    do_work(guard);
-    drop(guard); // unlock the lock
-    // do other work
-}
-```
-
-over
-
-```rust,ignore
-fn use_mutex(m: sync::mutex::Mutex<i32>) {
-    do_work(m.lock());
-    // do other work
-}
-```
-
-As explained in the [RAII guide](../ownership/raii.md), RAII guards are values
-that represent ownership of some resource and whose destructor releases the
-resource. Because the lifetime of guards are significant, they should always be
-explicitly `let`-bound to make the lifetime clear. Consider using an explicit
-`drop` to release the resource early.
-
-### Prefer conditional expressions to deferred initialization. [FIXME: needs RFC]
-
-Prefer
-
-```rust,ignore
-let foo = match bar {
-    Baz => 0,
-    Quux => 1
-};
-```
-
-over
-
-```rust,ignore
-let foo;
-match bar {
-    Baz => {
-        foo = 0;
-    }
-    Quux => {
-        foo = 1;
-    }
-}
-```
-
-unless the conditions for initialization are too complex to fit into a simple
-conditional expression.
-
-### Use type annotations for clarification; prefer explicit generics when inference fails. [FIXME: needs RFC]
-
-Prefer
-
-```rust,ignore
-let v = s.iter().map(|x| x * 2)
-                .collect::<Vec<_>>();
-```
-
-over
-
-```rust,ignore
-let v: Vec<_> = s.iter().map(|x| x * 2)
-                        .collect();
-```
-
-When the type of a value might be unclear to the _reader_ of the code, consider
-explicitly annotating it in a `let`.
-
-On the other hand, when the type is unclear to the _compiler_, prefer to specify
-the type by explicit generics instantiation, which is usually more clear.
-
-### Shadowing [FIXME]
-
-> **[FIXME]** Repeatedly shadowing a binding is somewhat common in Rust code. We
-> need to articulate a guideline on when it is appropriate/useful and when not.
-
-### Prefer immutable bindings. [FIXME: needs RFC]
-
-Use `mut` bindings to signal the span during which a value is mutated:
-
-```rust,ignore
-let mut v = Vec::new();
-// push things onto v
-let v = v;
-// use v immutably henceforth
-```
-
-### Prefer to bind all `struct` or tuple fields. [FIXME: needs RFC]
-
-When consuming a `struct` or tuple via a `let`, bind all of the fields rather
-than using `..` to elide the ones you don't need. The benefit is that when
-fields are added, the compiler will pinpoint all of the places where that type
-of value was consumed, which will often need to be adjusted to take the new
-field properly into account.
diff --git a/src/doc/style/features/loops.md b/src/doc/style/features/loops.md
deleted file mode 100644 (file)
index b144825..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-% Loops
-
-### Prefer `for` to `while`. [FIXME: needs RFC]
-
-A `for` loop is preferable to a `while` loop, unless the loop counts in a
-non-uniform way (making it difficult to express using `for`).
-
-### Guidelines for `loop`. [FIXME]
-
-> **[FIXME]** When is `loop` recommended? Some possibilities:
-> * For optimistic retry algorithms
-> * For servers
-> * To avoid mutating local variables sometimes needed to fit `while`
diff --git a/src/doc/style/features/match.md b/src/doc/style/features/match.md
deleted file mode 100644 (file)
index 0d5a118..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-% Pattern matching
-
-### Dereference `match` targets when possible. [FIXME: needs RFC]
-
-Prefer
-
-~~~~ignore
-match *foo {
-    X(...) => ...
-    Y(...) => ...
-}
-~~~~
-
-over
-
-~~~~ignore
-match foo {
-    box X(...) => ...
-    box Y(...) => ...
-}
-~~~~
-
-<!-- ### Clearly indicate important scopes. **[FIXME: needs RFC]** -->
-
-<!-- If it is important that the destructor for a value be executed at a specific -->
-<!-- time, clearly bind that value using a standalone `let` -->
diff --git a/src/doc/style/features/modules.md b/src/doc/style/features/modules.md
deleted file mode 100644 (file)
index 995c5fd..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-% Modules
-
-> **[FIXME]** What general guidelines should we provide for module design?
-
-> We should discuss visibility, nesting, `mod.rs`, and any interesting patterns
-> around modules.
-
-### Headers [FIXME: needs RFC]
-
-Organize module headers as follows:
-  1. [Imports](../style/imports.md).
-  1. `mod` declarations.
-  1. `pub mod` declarations.
-
-### Avoid `path` directives. [FIXME: needs RFC]
-
-Avoid using `#[path="..."]` directives; make the file system and
-module hierarchy match, instead.
-
-### Use the module hierarchy to organize APIs into coherent sections. [FIXME]
-
-> **[FIXME]** Flesh this out with examples; explain what a "coherent
-> section" is with examples.
->
-> The module hierarchy defines both the public and internal API of your module.
-> Breaking related functionality into submodules makes it understandable to both
-> users and contributors to the module.
-
-### Place modules in their own file. [FIXME: needs RFC]
-
-> **[FIXME]**
-> - "<100 lines" is arbitrary, but it's a clearer recommendation
->   than "~1 page" or similar suggestions that vary by screen size, etc.
-
-For all except very short modules (<100 lines) and [tests](../testing/README.md),
-place the module `foo` in a separate file, as in:
-
-```rust,ignore
-pub mod foo;
-
-// in foo.rs or foo/mod.rs
-pub fn bar() { println!("..."); }
-/* ... */
-```
-
-rather than declaring it inline:
-
-```rust,ignore
-pub mod foo {
-    pub fn bar() { println!("..."); }
-    /* ... */
-}
-```
-
-#### Use subdirectories for modules with children. [FIXME: needs RFC]
-
-For modules that themselves have submodules, place the module in a separate
-directory (e.g., `bar/mod.rs` for a module `bar`) rather than the same directory.
-
-Note the structure of
-[`std::io`](https://doc.rust-lang.org/std/io/). Many of the submodules lack
-children, like
-[`io::fs`](https://doc.rust-lang.org/std/io/fs/)
-and
-[`io::stdio`](https://doc.rust-lang.org/std/io/stdio/).
-On the other hand,
-[`io::net`](https://doc.rust-lang.org/std/io/net/)
-contains submodules, so it lives in a separate directory:
-
-```text
-io/mod.rs
-   io/extensions.rs
-   io/fs.rs
-   io/net/mod.rs
-          io/net/addrinfo.rs
-          io/net/ip.rs
-          io/net/tcp.rs
-          io/net/udp.rs
-          io/net/unix.rs
-   io/pipe.rs
-   ...
-```
-
-While it is possible to define all of `io` within a single directory,
-mirroring the module hierarchy in the directory structure makes
-submodules of `io::net` easier to find.
-
-### Consider top-level definitions or reexports. [FIXME: needs RFC]
-
-For modules with submodules,
-define or [reexport](https://doc.rust-lang.org/std/io/#reexports) commonly used
-definitions at the top level:
-
-* Functionality relevant to the module itself or to many of its
-  children should be defined in `mod.rs`.
-* Functionality specific to a submodule should live in that
-  submodule. Reexport at the top level for the most important or
-  common definitions.
-
-For example,
-[`IoError`](https://doc.rust-lang.org/std/io/struct.IoError.html)
-is defined in `io/mod.rs`, since it pertains to the entirety of `io`,
-while
-[`TcpStream`](https://doc.rust-lang.org/std/io/net/tcp/struct.TcpStream.html)
-is defined in `io/net/tcp.rs` and reexported in the `io` module.
-
-### Use internal module hierarchies for organization. [FIXME: needs RFC]
-
-> **[FIXME]**
-> - Referencing internal modules from the standard library is subject to
->   becoming outdated.
-
-Internal module hierarchies (i.e., private submodules) may be used to
-hide implementation details that are not part of the module's API.
-
-For example, in [`std::io`](https://doc.rust-lang.org/std/io/), `mod mem`
-provides implementations for
-[`BufReader`](https://doc.rust-lang.org/std/io/struct.BufReader.html)
-and
-[`BufWriter`](https://doc.rust-lang.org/std/io/struct.BufWriter.html),
-but these are re-exported in `io/mod.rs` at the top level of the module:
-
-```rust,ignore
-// libstd/io/mod.rs
-
-pub use self::mem::{MemReader, BufReader, MemWriter, BufWriter};
-/* ... */
-mod mem;
-```
-
-This hides the detail that there even exists a `mod mem` in `io`, and
-helps keep code organized while offering freedom to change the
-implementation.
diff --git a/src/doc/style/features/traits/README.md b/src/doc/style/features/traits/README.md
deleted file mode 100644 (file)
index 1893db2..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-% Traits
-
-Traits are probably Rust's most complex feature, supporting a wide range of use
-cases and design tradeoffs. Patterns of trait usage are still emerging.
-
-### Know whether a trait will be used as an object. [FIXME: needs RFC]
-
-Trait objects have some [significant limitations](objects.md): methods
-invoked through a trait object cannot use generics, and cannot use
-`Self` except in receiver position.
-
-When designing a trait, decide early on whether the trait will be used
-as an [object](objects.md) or as a [bound on generics](generics.md);
-the tradeoffs are discussed in each of the linked sections.
-
-If a trait is meant to be used as an object, its methods should take
-and return trait objects rather than use generics.
-
-
-### Default methods [FIXME]
-
-> **[FIXME]** Guidelines for default methods.
diff --git a/src/doc/style/features/traits/common.md b/src/doc/style/features/traits/common.md
deleted file mode 100644 (file)
index e8699c7..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-% Common traits
-
-### Eagerly implement common traits. [FIXME: needs RFC]
-
-Rust's trait system does not allow _orphans_: roughly, every `impl` must live
-either in the crate that defines the trait or the implementing
-type. Consequently, crates that define new types should eagerly implement all
-applicable, common traits.
-
-To see why, consider the following situation:
-
-* Crate `std` defines trait `Debug`.
-* Crate `url` defines type `Url`, without implementing `Debug`.
-* Crate `webapp` imports from both `std` and `url`,
-
-There is no way for `webapp` to add `Debug` to `url`, since it defines neither.
-(Note: the newtype pattern can provide an efficient, but inconvenient
-workaround; see [newtype for views](../types/newtype.md))
-
-The most important common traits to implement from `std` are:
-
-```text
-Clone, Debug, Hash, Eq
-```
-
-#### When safe, derive or otherwise implement `Send` and `Share`. [FIXME]
-
-> **[FIXME]**. This guideline is in flux while the "opt-in" nature of
-> built-in traits is being decided. See https://github.com/rust-lang/rfcs/pull/127
-
-### Prefer to derive, rather than implement. [FIXME: needs RFC]
-
-Deriving saves implementation effort, makes correctness trivial, and
-automatically adapts to upstream changes.
-
-### Do not overload operators in surprising ways. [FIXME: needs RFC]
-
-Operators with built in syntax (`*`, `|`, and so on) can be provided for a type
-by implementing the traits in `core::ops`. These operators come with strong
-expectations: implement `Mul` only for an operation that bears some resemblance
-to multiplication (and shares the expected properties, e.g. associativity), and
-so on for the other traits.
-
-### The `Drop` trait
-
-The `Drop` trait is treated specially by the compiler as a way of
-associating destructors with types. See
-[the section on destructors](../../ownership/destructors.md) for
-guidance.
-
-### The `Deref`/`DerefMut` traits
-
-#### Use `Deref`/`DerefMut` only for smart pointers. [FIXME: needs RFC]
-
-The `Deref` traits are used implicitly by the compiler in many circumstances,
-and interact with method resolution. The relevant rules are designed
-specifically to accommodate smart pointers, and so the traits should be used
-only for that purpose.
-
-#### Do not fail within a `Deref`/`DerefMut` implementation. [FIXME: needs RFC]
-
-Because the `Deref` traits are invoked implicitly by the compiler in sometimes
-subtle ways, failure during dereferencing can be extremely confusing. If a
-dereference might not succeed, target the `Deref` trait as a `Result` or
-`Option` type instead.
-
-#### Avoid inherent methods when implementing `Deref`/`DerefMut` [FIXME: needs RFC]
-
-The rules around method resolution and `Deref` are in flux, but inherent methods
-on a type implementing `Deref` are likely to shadow any methods of the referent
-with the same name.
diff --git a/src/doc/style/features/traits/extensions.md b/src/doc/style/features/traits/extensions.md
deleted file mode 100644 (file)
index fc3a03c..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-% Using traits to add extension methods
-
-> **[FIXME]** Elaborate.
-
-### Consider using default methods rather than extension traits **[FIXME]**
-
-> **[FIXME]** Elaborate.
diff --git a/src/doc/style/features/traits/generics.md b/src/doc/style/features/traits/generics.md
deleted file mode 100644 (file)
index f9dac12..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-% Using traits for bounds on generics
-
-The most widespread use of traits is for writing generic functions or types. For
-example, the following signature describes a function for consuming any iterator
-yielding items of type `A` to produce a collection of `A`:
-
-```rust,ignore
-fn from_iter<T: Iterator<A>>(iterator: T) -> SomeCollection<A>
-```
-
-Here, the `Iterator` trait specifies an interface that a type `T` must
-explicitly implement to be used by this generic function.
-
-**Pros**:
-
-* _Reusability_. Generic functions can be applied to an open-ended collection of
-  types, while giving a clear contract for the functionality those types must
-  provide.
-* _Static dispatch and optimization_. Each use of a generic function is
-  specialized ("monomorphized") to the particular types implementing the trait
-  bounds, which means that (1) invocations of trait methods are static, direct
-  calls to the implementation and (2) the compiler can inline and otherwise
-  optimize these calls.
-* _Inline layout_. If a `struct` and `enum` type is generic over some type
-  parameter `T`, values of type `T` will be laid out _inline_ in the
-  `struct`/`enum`, without any indirection.
-* _Inference_. Since the type parameters to generic functions can usually be
-  inferred, generic functions can help cut down on verbosity in code where
-  explicit conversions or other method calls would usually be necessary. See the
-  overloading/implicits use case below.
-* _Precise types_. Because generics give a _name_ to the specific type
-  implementing a trait, it is possible to be precise about places where that
-  exact type is required or produced. For example, a function
-
-  ```rust,ignore
-  fn binary<T: Trait>(x: T, y: T) -> T
-  ```
-
-  is guaranteed to consume and produce elements of exactly the same type `T`; it
-  cannot be invoked with parameters of different types that both implement
-  `Trait`.
-
-**Cons**:
-
-* _Code size_. Specializing generic functions means that the function body is
-  duplicated. The increase in code size must be weighed against the performance
-  benefits of static dispatch.
-* _Homogeneous types_. This is the other side of the "precise types" coin: if
-  `T` is a type parameter, it stands for a _single_ actual type. So for example
-  a `Vec<T>` contains elements of a single concrete type (and, indeed, the
-  vector representation is specialized to lay these out in line). Sometimes
-  heterogeneous collections are useful; see
-  trait objects below.
-* _Signature verbosity_. Heavy use of generics can bloat function signatures.
-  **[Ed. note]** This problem may be mitigated by some language improvements; stay tuned.
-
-### Favor widespread traits. **[FIXME: needs RFC]**
-
-Generic types are a form of abstraction, which entails a mental indirection: if
-a function takes an argument of type `T` bounded by `Trait`, clients must first
-think about the concrete types that implement `Trait` to understand how and when
-the function is callable.
-
-To keep the cost of abstraction low, favor widely-known traits. Whenever
-possible, implement and use traits provided as part of the standard library.  Do
-not introduce new traits for generics lightly; wait until there are a wide range
-of types that can implement the type.
diff --git a/src/doc/style/features/traits/objects.md b/src/doc/style/features/traits/objects.md
deleted file mode 100644 (file)
index 34712ed..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-% Using trait objects
-
-> **[FIXME]** What are uses of trait objects other than heterogeneous collections?
-
-Trait objects are useful primarily when _heterogeneous_ collections of objects
-need to be treated uniformly; it is the closest that Rust comes to
-object-oriented programming.
-
-```rust,ignore
-struct Frame  { ... }
-struct Button { ... }
-struct Label  { ... }
-
-trait Widget  { ... }
-
-impl Widget for Frame  { ... }
-impl Widget for Button { ... }
-impl Widget for Label  { ... }
-
-impl Frame {
-    fn new(contents: &[Box<Widget>]) -> Frame {
-        ...
-    }
-}
-
-fn make_gui() -> Box<Widget> {
-    let b: Box<Widget> = box Button::new(...);
-    let l: Box<Widget> = box Label::new(...);
-
-    box Frame::new([b, l]) as Box<Widget>
-}
-```
-
-By using trait objects, we can set up a GUI framework with a `Frame` widget that
-contains a heterogeneous collection of children widgets.
-
-**Pros**:
-
-* _Heterogeneity_. When you need it, you really need it.
-* _Code size_. Unlike generics, trait objects do not generate specialized
-  (monomorphized) versions of code, which can greatly reduce code size.
-
-**Cons**:
-
-* _No generic methods_. Trait objects cannot currently provide generic methods.
-* _Dynamic dispatch and fat pointers_. Trait objects inherently involve
-  indirection and vtable dispatch, which can carry a performance penalty.
-* _No Self_. Except for the method receiver argument, methods on trait objects
-  cannot use the `Self` type.
diff --git a/src/doc/style/features/traits/overloading.md b/src/doc/style/features/traits/overloading.md
deleted file mode 100644 (file)
index d7482c9..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-% Using traits for overloading
-
-> **[FIXME]** Elaborate.
-
-> **[FIXME]** We need to decide on guidelines for this use case. There are a few
-> patterns emerging in current Rust code, but it's not clear how widespread they
-> should be.
diff --git a/src/doc/style/features/traits/reuse.md b/src/doc/style/features/traits/reuse.md
deleted file mode 100644 (file)
index feedd39..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-% Using traits to share implementations
-
-> **[FIXME]** Elaborate.
-
-> **[FIXME]** We probably want to discourage this, at least when used in a way
-> that is publicly exposed.
-
-Traits that provide default implementations for function can provide code reuse
-across types. For example, a `print` method can be defined across multiple
-types as follows:
-
-``` Rust
-trait Printable {
-    // Default method implementation
-    fn print(&self) { println!("{:?}", *self) }
-}
-
-impl Printable for i32 {}
-
-impl Printable for String {
-    fn print(&self) { println!("{}", *self) }
-}
-
-impl Printable for bool {}
-
-impl Printable for f32 {}
-```
-
-This allows the implementation of `print` to be shared across types, yet
-overridden where needed, as seen in the `impl` for `String`.
diff --git a/src/doc/style/features/types/README.md b/src/doc/style/features/types/README.md
deleted file mode 100644 (file)
index d3b95d8..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-% Data types
-
-### Use custom types to imbue meaning; do not abuse `bool`, `Option` or other core types. **[FIXME: needs RFC]**
-
-Prefer
-
-```rust,ignore
-let w = Widget::new(Small, Round)
-```
-
-over
-
-```rust,ignore
-let w = Widget::new(true, false)
-```
-
-Core types like `bool`, `u8` and `Option` have many possible interpretations.
-
-Use custom types (whether `enum`s, `struct`, or tuples) to convey
-interpretation and invariants. In the above example,
-it is not immediately clear what `true` and `false` are conveying without
-looking up the argument names, but `Small` and `Round` are more suggestive.
-
-Using custom types makes it easier to expand the
-options later on, for example by adding an `ExtraLarge` variant.
-
-See [the newtype pattern](newtype.md) for a no-cost way to wrap
-existing types with a distinguished name.
-
-### Prefer private fields, except for passive data. **[FIXME: needs RFC]**
-
-Making a field public is a strong commitment: it pins down a representation
-choice, _and_ prevents the type from providing any validation or maintaining any
-invariants on the contents of the field, since clients can mutate it arbitrarily.
-
-Public fields are most appropriate for `struct` types in the C spirit: compound,
-passive data structures. Otherwise, consider providing getter/setter methods
-and hiding fields instead.
-
-> **[FIXME]** Cross-reference validation for function arguments.
-
-### Use custom `enum`s for alternatives, `bitflags` for C-style flags. **[FIXME: needs RFC]**
-
-Rust supports `enum` types with "custom discriminants":
-
-~~~~
-enum Color {
-  Red = 0xff0000,
-  Green = 0x00ff00,
-  Blue = 0x0000ff
-}
-~~~~
-
-Custom discriminants are useful when an `enum` type needs to be serialized to an
-integer value compatibly with some other system/language. They support
-"typesafe" APIs: by taking a `Color`, rather than an integer, a function is
-guaranteed to get well-formed inputs, even if it later views those inputs as
-integers.
-
-An `enum` allows an API to request exactly one choice from among many. Sometimes
-an API's input is instead the presence or absence of a set of flags. In C code,
-this is often done by having each flag correspond to a particular bit, allowing
-a single integer to represent, say, 32 or 64 flags. Rust's `std::bitflags`
-module provides a typesafe way for doing so.
-
-### Phantom types. [FIXME]
-
-> **[FIXME]** Add some material on phantom types (https://blog.mozilla.org/research/2014/06/23/static-checking-of-units-in-servo/)
diff --git a/src/doc/style/features/types/conversions.md b/src/doc/style/features/types/conversions.md
deleted file mode 100644 (file)
index f0f230f..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-% Conversions between types
-
-### Associate conversions with the most specific type involved. **[FIXME: needs RFC]**
-
-When in doubt, prefer `to_`/`as_`/`into_` to `from_`, because they are
-more ergonomic to use (and can be chained with other methods).
-
-For many conversions between two types, one of the types is clearly more
-"specific": it provides some additional invariant or interpretation that is not
-present in the other type. For example, `str` is more specific than `&[u8]`,
-since it is a utf-8 encoded sequence of bytes.
-
-Conversions should live with the more specific of the involved types. Thus,
-`str` provides both the `as_bytes` method and the `from_utf8` constructor for
-converting to and from `&[u8]` values. Besides being intuitive, this convention
-avoids polluting concrete types like `&[u8]` with endless conversion methods.
-
-### Explicitly mark lossy conversions, or do not label them as conversions. **[FIXME: needs RFC]**
-
-If a function's name implies that it is a conversion (prefix `from_`, `as_`,
-`to_` or `into_`), but the function loses information, add a suffix `_lossy` or
-otherwise indicate the lossyness. Consider avoiding the conversion name prefix.
diff --git a/src/doc/style/features/types/newtype.md b/src/doc/style/features/types/newtype.md
deleted file mode 100644 (file)
index 9646e3e..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-% The newtype pattern
-
-A "newtype" is a tuple or `struct` with a single field. The terminology is borrowed from Haskell.
-
-Newtypes are a zero-cost abstraction: they introduce a new, distinct name for an
-existing type, with no runtime overhead when converting between the two types.
-
-### Use newtypes to provide static distinctions. [FIXME: needs RFC]
-
-Newtypes can statically distinguish between different interpretations of an
-underlying type.
-
-For example, a `f64` value might be used to represent a quantity in miles or in
-kilometers. Using newtypes, we can keep track of the intended interpretation:
-
-```rust,ignore
-struct Miles(pub f64);
-struct Kilometers(pub f64);
-
-impl Miles {
-    fn as_kilometers(&self) -> Kilometers { ... }
-}
-impl Kilometers {
-    fn as_miles(&self) -> Miles { ... }
-}
-```
-
-Once we have separated these two types, we can statically ensure that we do not
-confuse them. For example, the function
-
-```rust,ignore
-fn are_we_there_yet(distance_travelled: Miles) -> bool { ... }
-```
-
-cannot accidentally be called with a `Kilometers` value. The compiler will
-remind us to perform the conversion, thus averting certain
-[catastrophic bugs](http://en.wikipedia.org/wiki/Mars_Climate_Orbiter).
-
-### Use newtypes with private fields for hiding. [FIXME: needs RFC]
-
-A newtype can be used to hide representation details while making precise
-promises to the client.
-
-For example, consider a function `my_transform` that returns a compound iterator
-type `Enumerate<Skip<vec::MoveItems<T>>>`. We wish to hide this type from the
-client, so that the client's view of the return type is roughly `Iterator<(usize,
-T)>`. We can do so using the newtype pattern:
-
-```rust,ignore
-struct MyTransformResult<T>(Enumerate<Skip<vec::MoveItems<T>>>);
-impl<T> Iterator<(usize, T)> for MyTransformResult<T> { ... }
-
-fn my_transform<T, Iter: Iterator<T>>(iter: Iter) -> MyTransformResult<T> {
-    ...
-}
-```
-
-Aside from simplifying the signature, this use of newtypes allows us to make a
-expose and promise less to the client. The client does not know _how_ the result
-iterator is constructed or represented, which means the representation can
-change in the future without breaking client code.
-
-> **[FIXME]** Interaction with auto-deref.
-
-### Use newtypes to provide cost-free _views_ of another type. **[FIXME]**
-
-> **[FIXME]** Describe the pattern of using newtypes to provide a new set of
-> inherent or trait methods, providing a different perspective on the underlying
-> type.
diff --git a/src/doc/style/ownership/README.md b/src/doc/style/ownership/README.md
deleted file mode 100644 (file)
index 11bdb03..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-% Ownership and resource management
-
-> **[FIXME]** Add general remarks about ownership/resources here.
diff --git a/src/doc/style/ownership/builders.md b/src/doc/style/ownership/builders.md
deleted file mode 100644 (file)
index 3422591..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-% The builder pattern
-
-Some data structures are complicated to construct, due to their construction needing:
-
-* a large number of inputs
-* compound data (e.g. slices)
-* optional configuration data
-* choice between several flavors
-
-which can easily lead to a large number of distinct constructors with
-many arguments each.
-
-If `T` is such a data structure, consider introducing a `T` _builder_:
-
-1. Introduce a separate data type `TBuilder` for incrementally configuring a `T`
-   value. When possible, choose a better name: e.g. `Command` is the builder for
-   `Process`.
-2. The builder constructor should take as parameters only the data _required_ to
-   make a `T`.
-3. The builder should offer a suite of convenient methods for configuration,
-   including setting up compound inputs (like slices) incrementally.
-   These methods should return `self` to allow chaining.
-4. The builder should provide one or more "_terminal_" methods for actually building a `T`.
-
-The builder pattern is especially appropriate when building a `T` involves side
-effects, such as spawning a thread or launching a process.
-
-In Rust, there are two variants of the builder pattern, differing in the
-treatment of ownership, as described below.
-
-### Non-consuming builders (preferred):
-
-In some cases, constructing the final `T` does not require the builder itself to
-be consumed. The follow variant on
-[`std::process::Command`](https://doc.rust-lang.org/stable/std/process/struct.Command.html)
-is one example:
-
-```rust,ignore
-// NOTE: the actual Command API does not use owned Strings;
-// this is a simplified version.
-
-pub struct Command {
-    program: String,
-    args: Vec<String>,
-    cwd: Option<String>,
-    // etc
-}
-
-impl Command {
-    pub fn new(program: String) -> Command {
-        Command {
-            program: program,
-            args: Vec::new(),
-            cwd: None,
-        }
-    }
-
-    /// Add an argument to pass to the program.
-    pub fn arg<'a>(&'a mut self, arg: String) -> &'a mut Command {
-        self.args.push(arg);
-        self
-    }
-
-    /// Add multiple arguments to pass to the program.
-    pub fn args<'a>(&'a mut self, args: &[String])
-                    -> &'a mut Command {
-        self.args.push_all(args);
-        self
-    }
-
-    /// Set the working directory for the child process.
-    pub fn cwd<'a>(&'a mut self, dir: String) -> &'a mut Command {
-        self.cwd = Some(dir);
-        self
-    }
-
-    /// Executes the command as a child process, which is returned.
-    pub fn spawn(&self) -> std::io::Result<Process> {
-        ...
-    }
-}
-```
-
-Note that the `spawn` method, which actually uses the builder configuration to
-spawn a process, takes the builder by immutable reference. This is possible
-because spawning the process does not require ownership of the configuration
-data.
-
-Because the terminal `spawn` method only needs a reference, the configuration
-methods take and return a mutable borrow of `self`.
-
-#### The benefit
-
-By using borrows throughout, `Command` can be used conveniently for both
-one-liner and more complex constructions:
-
-```rust,ignore
-// One-liners
-Command::new("/bin/cat").arg("file.txt").spawn();
-
-// Complex configuration
-let mut cmd = Command::new("/bin/ls");
-cmd.arg(".");
-
-if size_sorted {
-    cmd.arg("-S");
-}
-
-cmd.spawn();
-```
-
-### Consuming builders:
-
-Sometimes builders must transfer ownership when constructing the final type
-`T`, meaning that the terminal methods must take `self` rather than `&self`:
-
-```rust,ignore
-// A simplified excerpt from std::thread::Builder
-
-impl ThreadBuilder {
-    /// Name the thread-to-be. Currently the name is used for identification
-    /// only in failure messages.
-    pub fn named(mut self, name: String) -> ThreadBuilder {
-        self.name = Some(name);
-        self
-    }
-
-    /// Redirect thread-local stdout.
-    pub fn stdout(mut self, stdout: Box<Writer + Send>) -> ThreadBuilder {
-        self.stdout = Some(stdout);
-        //   ^~~~~~ this is owned and cannot be cloned/re-used
-        self
-    }
-
-    /// Creates and executes a new child thread.
-    pub fn spawn(self, f: proc():Send) {
-        // consume self
-        ...
-    }
-}
-```
-
-Here, the `stdout` configuration involves passing ownership of a `Writer`,
-which must be transferred to the thread upon construction (in `spawn`).
-
-When the terminal methods of the builder require ownership, there is a basic tradeoff:
-
-* If the other builder methods take/return a mutable borrow, the complex
-  configuration case will work well, but one-liner configuration becomes
-  _impossible_.
-
-* If the other builder methods take/return an owned `self`, one-liners
-  continue to work well but complex configuration is less convenient.
-
-Under the rubric of making easy things easy and hard things possible, _all_
-builder methods for a consuming builder should take and returned an owned
-`self`. Then client code works as follows:
-
-```rust,ignore
-// One-liners
-ThreadBuilder::new().named("my_thread").spawn(proc() { ... });
-
-// Complex configuration
-let mut thread = ThreadBuilder::new();
-thread = thread.named("my_thread_2"); // must re-assign to retain ownership
-
-if reroute {
-    thread = thread.stdout(mywriter);
-}
-
-thread.spawn(proc() { ... });
-```
-
-One-liners work as before, because ownership is threaded through each of the
-builder methods until being consumed by `spawn`. Complex configuration,
-however, is more verbose: it requires re-assigning the builder at each step.
diff --git a/src/doc/style/ownership/cell-smart.md b/src/doc/style/ownership/cell-smart.md
deleted file mode 100644 (file)
index cd027cc..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-% Cells and smart pointers
-
-> **[FIXME]** Add guidelines about when to use Cell, RefCell, Rc and
-> Arc (and how to use them together).
diff --git a/src/doc/style/ownership/constructors.md b/src/doc/style/ownership/constructors.md
deleted file mode 100644 (file)
index 51fc74a..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-% Constructors
-
-### Define constructors as static, inherent methods. [FIXME: needs RFC]
-
-In Rust, "constructors" are just a convention:
-
-```rust,ignore
-impl<T> Vec<T> {
-    pub fn new() -> Vec<T> { ... }
-}
-```
-
-Constructors are static (no `self`) inherent methods for the type that they
-construct. Combined with the practice of
-[fully importing type names](../style/imports.md), this convention leads to
-informative but concise construction:
-
-```rust,ignore
-use vec::Vec;
-
-// construct a new vector
-let mut v = Vec::new();
-```
-
-This convention also applied to conversion constructors (prefix `from` rather
-than `new`).
-
-### Provide constructors for passive `struct`s with defaults. [FIXME: needs RFC]
-
-Given the `struct`
-
-```rust,ignore
-pub struct Config {
-    pub color: Color,
-    pub size:  Size,
-    pub shape: Shape,
-}
-```
-
-provide a constructor if there are sensible defaults:
-
-```rust,ignore
-impl Config {
-    pub fn new() -> Config {
-        Config {
-            color: Brown,
-            size: Medium,
-            shape: Square,
-        }
-    }
-}
-```
-
-which then allows clients to concisely override using `struct` update syntax:
-
-```rust,ignore
-Config { color: Red, .. Config::new() };
-```
-
-See the [guideline for field privacy](../features/types/README.md) for
-discussion on when to create such "passive" `struct`s with public
-fields.
diff --git a/src/doc/style/ownership/destructors.md b/src/doc/style/ownership/destructors.md
deleted file mode 100644 (file)
index 1cfcd78..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-% Destructors
-
-Unlike constructors, destructors in Rust have a special status: they are added
-by implementing `Drop` for a type, and they are automatically invoked as values
-go out of scope.
-
-> **[FIXME]** This section needs to be expanded.
-
-### Destructors should not fail. [FIXME: needs RFC]
-
-Destructors are executed on thread failure, and in that context a failing
-destructor causes the program to abort.
-
-Instead of failing in a destructor, provide a separate method for checking for
-clean teardown, e.g. a `close` method, that returns a `Result` to signal
-problems.
-
-### Destructors should not block. [FIXME: needs RFC]
-
-Similarly, destructors should not invoke blocking operations, which can make
-debugging much more difficult. Again, consider providing a separate method for
-preparing for an infallible, nonblocking teardown.
diff --git a/src/doc/style/ownership/raii.md b/src/doc/style/ownership/raii.md
deleted file mode 100644 (file)
index 244e809..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-% RAII
-
-Resource Acquisition is Initialization
-
-> **[FIXME]** Explain the RAII pattern and give best practices.
-
-### Whenever possible, tie resource access to guard scopes [FIXME]
-
-> **[FIXME]** Example: Mutex guards guarantee that access to the
-> protected resource only happens when the guard is in scope.
-
-`must_use`
diff --git a/src/doc/style/platform.md b/src/doc/style/platform.md
deleted file mode 100644 (file)
index d29d060..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-% FFI and platform-specific code **[FIXME]**
-
-> **[FIXME]** Not sure where this should live.
-
-When writing cross-platform code, group platform-specific code into a
-module called `platform`. Avoid `#[cfg]` directives outside this
-`platform` module.
diff --git a/src/doc/style/safety/README.md b/src/doc/style/safety/README.md
deleted file mode 100644 (file)
index 1ac6e70..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-% Safety and guarantees
-
-> **[FIXME]** Is there a better phrase than "strong guarantees" that encompasses
-> both e.g. memory safety and e.g. data structure invariants?
-
-A _guarantee_ is a property that holds no matter what client code does, unless
-the client explicitly opts out:
-
-* Rust guarantees memory safety and data-race freedom, with `unsafe`
-  blocks as an opt-out mechanism.
-
-* APIs in Rust often provide their own guarantees. For example, `std::str`
-guarantees that its underlying buffer is valid utf-8. The `std::path::Path` type
-guarantees no interior nulls. Both strings and paths provide `unsafe` mechanisms
-for opting out of these guarantees (and thereby avoiding runtime checks).
-
-Thinking about guarantees is an essential part of writing good Rust code.  The
-rest of this subsection outlines some cross-cutting principles around
-guarantees.
diff --git a/src/doc/style/safety/lib-guarantees.md b/src/doc/style/safety/lib-guarantees.md
deleted file mode 100644 (file)
index 8ee64f1..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-% Library-level guarantees
-
-Most libraries rely on internal invariants, e.g. about their data, resource
-ownership, or protocol states. In Rust, broken invariants cannot produce
-segfaults, but they can still lead to wrong answers.
-
-### Provide library-level guarantees whenever practical. **[FIXME: needs RFC]**
-
-Library-level invariants should be turned into guarantees whenever
-practical. They should hold no matter what the client does, modulo
-explicit opt-outs. Depending on the kind of invariant, this can be
-achieved through a combination of static and dynamic enforcement, as
-described below.
-
-#### Static enforcement:
-
-Guaranteeing invariants almost always requires _hiding_,
-i.e. preventing the client from directly accessing or modifying
-internal data.
-
-For example, the representation of the `str` type is hidden,
-which means that any value of type `str` must have been produced
-through an API under the control of the `str` module, and these
-APIs in turn ensure valid utf-8 encoding.
-
-Rust's type system makes it possible to provide guarantees even while
-revealing more of the representation than usual. For example, the
-`as_bytes()` method on `&str` gives a _read-only_ view into the
-underlying buffer, which cannot be used to violate the utf-8 property.
-
-#### Dynamic enforcement:
-
-Malformed inputs from the client are hazards to library-level
-guarantees, so library APIs should validate their input.
-
-For example, `std::str::from_utf8_owned` attempts to convert a `u8`
-slice into an owned string, but dynamically checks that the slice is
-valid utf-8 and returns `Err` if not.
-
-See
-[the discussion on input validation](../features/functions-and-methods/input.md)
-for more detail.
-
-
-### Prefer static enforcement of guarantees. **[FIXME: needs RFC]**
-
-Static enforcement provides two strong benefits over dynamic enforcement:
-
-* Bugs are caught at compile time.
-* There is no runtime cost.
-
-Sometimes purely static enforcement is impossible or impractical. In these
-cases, a library should check as much as possible statically, but defer to
-dynamic checks where needed.
-
-For example, the `std::string` module exports a `String` type with the guarantee
-that all instances are valid utf-8:
-
-* Any _consumer_ of a `String` is statically guaranteed utf-8 contents. For example,
-  the `append` method can push a `&str` onto the end of a `String` without
-  checking anything dynamically, since the existing `String` and `&str` are
-  statically guaranteed to be in utf-8.
-
-* Some _producers_ of a `String` must perform dynamic checks. For example, the
-  `from_utf8` function attempts to convert a `Vec<u8>` into a `String`, but
-  dynamically checks that the contents are utf-8.
-
-### Provide opt-outs with caution; make them explicit. **[FIXME: needs RFC]**
-
-Providing library-level guarantees sometimes entails inconvenience (for static
-checks) or overhead (for dynamic checks). So it is sometimes desirable to allow
-clients to sidestep this checking, while promising to use the API in a way that
-still provides the guarantee. Such escape hatches should only be introduced when
-there is a demonstrated need for them.
-
-It should be trivial for clients to audit their use of the library for
-escape hatches.
-
-See
-[the discussion on input validation](../features/functions-and-methods/input.md)
-for conventions on marking opt-out functions.
diff --git a/src/doc/style/safety/unsafe.md b/src/doc/style/safety/unsafe.md
deleted file mode 100644 (file)
index a8a50af..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-% Using `unsafe`
-
-### Unconditionally guarantee safety, or mark API as `unsafe`. **[FIXME: needs RFC]**
-
-Memory safety, type safety, and data race freedom are basic assumptions for all
-Rust code.
-
-APIs that use `unsafe` blocks internally thus have two choices:
-
-* They can guarantee safety _unconditionally_ (i.e., regardless of client
-  behavior or inputs) and be exported as safe code. Any safety violation is then
-  the library's fault, not the client's fault.
-
-* They can export potentially unsafe functions with the `unsafe` qualifier. In
-  this case, the documentation should make very clear the conditions under which
-  safety is guaranteed.
-
-The result is that a client program can never violate safety merely by having a
-bug; it must have explicitly opted out by using an `unsafe` block.
-
-Of the two options for using `unsafe`, creating such safe abstractions (the
-first option above) is strongly preferred.
diff --git a/src/doc/style/style/README.md b/src/doc/style/style/README.md
deleted file mode 100644 (file)
index 8744971..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-% Style
-
-This section gives a set of strict rules for styling Rust code.
-
-> **[FIXME]** General remarks about the style guidelines
diff --git a/src/doc/style/style/braces.md b/src/doc/style/style/braces.md
deleted file mode 100644 (file)
index 80323db..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-% Braces, semicolons, and commas [FIXME: needs RFC]
-
-### Opening braces always go on the same line.
-
-```rust,ignore
-fn foo() {
-    ...
-}
-
-fn frobnicate(a: Bar, b: Bar,
-              c: Bar, d: Bar)
-              -> Bar {
-    ...
-}
-
-trait Bar {
-    fn baz(&self);
-}
-
-impl Bar for Baz {
-    fn baz(&self) {
-        ...
-    }
-}
-
-frob(|x| {
-    x.transpose()
-})
-```
-
-### `match` arms get braces, except for single-line expressions.
-
-```rust,ignore
-match foo {
-    bar => baz,
-    quux => {
-        do_something();
-        do_something_else()
-    }
-}
-```
-
-### `return` statements get semicolons.
-
-```rust,ignore
-fn foo() {
-    do_something();
-
-    if condition() {
-        return;
-    }
-
-    do_something_else();
-}
-```
-
-### Trailing commas
-
-> **[FIXME]** We should have a guideline for when to include trailing
-> commas in `struct`s, `match`es, function calls, etc.
->
-> One possible rule: a trailing comma should be included whenever the
-> closing delimiter appears on a separate line:
-
-```rust,ignore
-Foo { bar: 0, baz: 1 }
-
-Foo {
-    bar: 0,
-    baz: 1,
-}
-
-match a_thing {
-    None => 0,
-    Some(x) => 1,
-}
-```
diff --git a/src/doc/style/style/comments.md b/src/doc/style/style/comments.md
deleted file mode 100644 (file)
index af02d87..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-% Comments [RFC #505]
-
-### Avoid block comments.
-
-Use line comments:
-
-```rust
-// Wait for the main thread to return, and set the process error code
-// appropriately.
-```
-
-Instead of:
-
-``` rust
-/*
- * Wait for the main thread to return, and set the process error code
- * appropriately.
- */
-```
-
-## Doc comments
-
-Doc comments are prefixed by three slashes (`///`) and indicate
-documentation that you would like to be included in Rustdoc's output.
-They support
-[Markdown syntax](https://en.wikipedia.org/wiki/Markdown)
-and are the main way of documenting your public APIs.
-
-The supported markdown syntax includes all of the extensions listed in the
-[GitHub Flavored Markdown]
-(https://help.github.com/articles/github-flavored-markdown) documentation,
-plus superscripts.
-
-### Summary line
-
-The first line in any doc comment should be a single-line short sentence
-providing a summary of the code. This line is used as a short summary
-description throughout Rustdoc's output, so it's a good idea to keep it
-short.
-
-### Sentence structure
-
-All doc comments, including the summary line, should begin with a
-capital letter and end with a period, question mark, or exclamation
-point. Prefer full sentences to fragments.
-
-The summary line should be written in
-[third person singular present indicative form]
-(http://en.wikipedia.org/wiki/English_verbs#Third_person_singular_present).
-Basically, this means write "Returns" instead of "Return".
-
-For example:
-
-```rust,ignore
-/// Sets up a default runtime configuration, given compiler-supplied arguments.
-///
-/// This function will block until the entire pool of M:N schedulers has
-/// exited. This function also requires a local thread to be available.
-///
-/// # Arguments
-///
-/// * `argc` & `argv` - The argument vector. On Unix this information is used
-///                     by `os::args`.
-/// * `main` - The initial procedure to run inside of the M:N scheduling pool.
-///            Once this procedure exits, the scheduling pool will begin to shut
-///            down. The entire pool (and this function) will only return once
-///            all child threads have finished executing.
-///
-/// # Return value
-///
-/// The return value is used as the process return code. 0 on success, 101 on
-/// error.
-```
-
-### Code snippets
-
-Only use inner doc comments `//!` to write crate and module-level documentation,
-nothing else. When using `mod` blocks, prefer `///` outside of the block:
-
-```rust
-/// This module contains tests
-mod test {
-    // ...
-}
-```
-
-over
-
-```rust
-mod test {
-    //! This module contains tests
-
-    // ...
-}
-```
-
-### Avoid inner doc comments.
-
-Use inner doc comments _only_ to document crates and file-level modules:
-
-```rust,ignore
-//! The core library.
-//!
-//! The core library is a something something...
-```
-
-### Explain context.
-
-Rust doesn't have special constructors, only functions that return new
-instances.  These aren't visible in the automatically generated documentation
-for a type, so you should specifically link to them:
-
-```rust,ignore
-/// An iterator that yields `None` forever after the underlying iterator
-/// yields `None` once.
-///
-/// These can be created through
-/// [`iter.fuse()`](trait.Iterator.html#method.fuse).
-pub struct Fuse<I> {
-    // ...
-}
-```
diff --git a/src/doc/style/style/features.md b/src/doc/style/style/features.md
deleted file mode 100644 (file)
index 13cc37f..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-## `return` [RFC #968]
-
-Terminate `return` statements with semicolons:
-
-``` rust,ignore
-fn foo(bar: i32) -> Option<i32> {
-    if some_condition() {
-        return None;
-    }
-
-    ...
-}
-```
diff --git a/src/doc/style/style/imports.md b/src/doc/style/style/imports.md
deleted file mode 100644 (file)
index c958875..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-% Imports [FIXME: needs RFC]
-
-The imports of a crate/module should consist of the following
-sections, in order, with a blank space between each:
-
-* `extern crate` directives
-* external `use` imports
-* local `use` imports
-* `pub use` imports
-
-For example:
-
-```rust,ignore
-// Crates.
-extern crate getopts;
-extern crate mylib;
-
-// Standard library imports.
-use getopts::{optopt, getopts};
-use std::os;
-
-// Import from a library that we wrote.
-use mylib::webserver;
-
-// Will be reexported when we import this module.
-pub use self::types::Webdata;
-```
-
-### Avoid `use *`, except in tests.
-
-Glob imports have several downsides:
-* They make it harder to tell where names are bound.
-* They are forwards-incompatible, since new upstream exports can clash
-  with existing names.
-
-When writing a [`test` submodule](../testing/README.md), importing `super::*` is appropriate
-as a convenience.
-
-### Prefer fully importing types/traits while module-qualifying functions.
-
-For example:
-
-```rust,ignore
-use option::Option;
-use mem;
-
-let i: isize = mem::transmute(Option(0));
-```
-
-> **[FIXME]** Add rationale.
diff --git a/src/doc/style/style/naming/README.md b/src/doc/style/style/naming/README.md
deleted file mode 100644 (file)
index 6d88a83..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-% Naming conventions
-
-### General conventions [RFC #430]
-
-> The guidelines below were approved by [RFC #430](https://github.com/rust-lang/rfcs/pull/430).
-
-In general, Rust tends to use `CamelCase` for "type-level" constructs
-(types and traits) and `snake_case` for "value-level" constructs. More
-precisely:
-
-| Item | Convention |
-| ---- | ---------- |
-| Crates | `snake_case` (but prefer single word) |
-| Modules | `snake_case` |
-| Types | `CamelCase` |
-| Traits | `CamelCase` |
-| Enum variants | `CamelCase` |
-| Functions | `snake_case` |
-| Methods | `snake_case` |
-| General constructors | `new` or `with_more_details` |
-| Conversion constructors | `from_some_other_type` |
-| Local variables | `snake_case` |
-| Static variables | `SCREAMING_SNAKE_CASE` |
-| Constant variables | `SCREAMING_SNAKE_CASE` |
-| Type parameters | concise `CamelCase`, usually single uppercase letter: `T` |
-| Lifetimes | short, lowercase: `'a` |
-
-<p>
-In `CamelCase`, acronyms count as one word: use `Uuid` rather than
-`UUID`.  In `snake_case`, acronyms are lower-cased: `is_xid_start`.
-
-In `snake_case` or `SCREAMING_SNAKE_CASE`, a "word" should never
-consist of a single letter unless it is the last "word". So, we have
-`btree_map` rather than `b_tree_map`, but `PI_2` rather than `PI2`.
-
-### Referring to types in function/method names [RFC 344]
-
-> The guidelines below were approved by [RFC #344](https://github.com/rust-lang/rfcs/pull/344).
-
-Function names often involve type names, the most common example being conversions
-like `as_slice`. If the type has a purely textual name (ignoring parameters), it
-is straightforward to convert between type conventions and function conventions:
-
-Type name | Text in methods
---------- | ---------------
-`String`  | `string`
-`Vec<T>`  | `vec`
-`YourType`| `your_type`
-
-Types that involve notation follow the convention below. There is some
-overlap on these rules; apply the most specific applicable rule:
-
-Type name | Text in methods
---------- | ---------------
-`&str`    | `str`
-`&[T]`    | `slice`
-`&mut [T]`| `mut_slice`
-`&[u8]`   | `bytes`
-`&T`      | `ref`
-`&mut T`  | `mut`
-`*const T`| `ptr`
-`*mut T`  | `mut_ptr`
-
-### Avoid redundant prefixes [RFC 356]
-
-> The guidelines below were approved by [RFC #356](https://github.com/rust-lang/rfcs/pull/356).
-
-Names of items within a module should not be prefixed with that module's name:
-
-Prefer
-
-```rust,ignore
-mod foo {
-    pub struct Error { ... }
-}
-```
-
-over
-
-```rust,ignore
-mod foo {
-    pub struct FooError { ... }
-}
-```
-
-This convention avoids stuttering (like `io::IoError`). Library clients can
-rename on import to avoid clashes.
-
-### Getter/setter methods [RFC 344]
-
-> The guidelines below were approved by [RFC #344](https://github.com/rust-lang/rfcs/pull/344).
-
-Some data structures do not wish to provide direct access to their fields, but
-instead offer "getter" and "setter" methods for manipulating the field state
-(often providing checking or other functionality).
-
-The convention for a field `foo: T` is:
-
-* A method `foo(&self) -> &T` for getting the current value of the field.
-* A method `set_foo(&self, val: T)` for setting the field. (The `val` argument
-  here may take `&T` or some other type, depending on the context.)
-
-Note that this convention is about getters/setters on ordinary data types, *not*
-on [builder objects](../../ownership/builders.html).
-
-### Escape hatches [FIXME]
-
-> **[FIXME]** Should we standardize a convention for functions that may break API
-> guarantees? e.g. `ToCStr::to_c_str_unchecked`
-
-### Predicates
-
-* Simple boolean predicates should be prefixed with `is_` or another
-  short question word, e.g., `is_empty`.
-* Common exceptions: `lt`, `gt`, and other established predicate names.
diff --git a/src/doc/style/style/naming/containers.md b/src/doc/style/style/naming/containers.md
deleted file mode 100644 (file)
index c352a5b..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-% Common container/wrapper methods [FIXME: needs RFC]
-
-Containers, wrappers, and cells all provide ways to access the data
-they enclose.  Accessor methods often have variants to access the data
-by value, by reference, and by mutable reference.
-
-In general, the `get` family of methods is used to access contained
-data without any risk of thread failure; they return `Option` as
-appropriate. This name is chosen rather than names like `find` or
-`lookup` because it is appropriate for a wider range of container types.
-
-#### Containers
-
-For a container with keys/indexes of type `K` and elements of type `V`:
-
-```rust,ignore
-// Look up element without failing
-fn get(&self, key: K) -> Option<&V>
-fn get_mut(&mut self, key: K) -> Option<&mut V>
-
-// Convenience for .get(key).map(|elt| elt.clone())
-fn get_clone(&self, key: K) -> Option<V>
-
-// Lookup element, failing if it is not found:
-impl Index<K, V> for Container { ... }
-impl IndexMut<K, V> for Container { ... }
-```
-
-#### Wrappers/Cells
-
-Prefer specific conversion functions like `as_bytes` or `into_vec` whenever
-possible. Otherwise, use:
-
-```rust,ignore
-// Extract contents without failing
-fn get(&self) -> &V
-fn get_mut(&mut self) -> &mut V
-fn unwrap(self) -> V
-```
-
-#### Wrappers/Cells around `Copy` data
-
-```rust,ignore
-// Extract contents without failing
-fn get(&self) -> V
-```
-
-#### `Option`-like types
-
-Finally, we have the cases of types like `Option` and `Result`, which
-play a special role for failure.
-
-For `Option<V>`:
-
-```rust,ignore
-// Extract contents or fail if not available
-fn assert(self) -> V
-fn expect(self, &str) -> V
-```
-
-For `Result<V, E>`:
-
-```rust,ignore
-// Extract the contents of Ok variant; fail if Err
-fn assert(self) -> V
-
-// Extract the contents of Err variant; fail if Ok
-fn assert_err(self) -> E
-```
diff --git a/src/doc/style/style/naming/conversions.md b/src/doc/style/style/naming/conversions.md
deleted file mode 100644 (file)
index 0287919..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-% Conversions [Rust issue #7087]
-
-> The guidelines below were approved by [rust issue #7087](https://github.com/rust-lang/rust/issues/7087).
-
-> **[FIXME]** Should we provide standard traits for conversions? Doing
-> so nicely will require
-> [trait reform](https://github.com/rust-lang/rfcs/pull/48) to land.
-
-Conversions should be provided as methods, with names prefixed as follows:
-
-| Prefix | Cost | Consumes convertee |
-| ------ | ---- | ------------------ |
-| `as_` | Free | No |
-| `to_` | Expensive | No |
-| `into_` | Variable | Yes |
-
-<p>
-For example:
-
-* `as_bytes()` gives a `&[u8]` view into a `&str`, which is a no-op.
-* `to_owned()` copies a `&str` to a new `String`.
-* `into_bytes()` consumes a `String` and yields the underlying
-  `Vec<u8>`, which is a no-op.
-
-Conversions prefixed `as_` and `into_` typically _decrease abstraction_, either
-exposing a view into the underlying representation (`as`) or deconstructing data
-into its underlying representation (`into`). Conversions prefixed `to_`, on the
-other hand, typically stay at the same level of abstraction but do some work to
-change one representation into another.
-
-> **[FIXME]** The distinctions between conversion methods does not work
-> so well for `from_` conversion constructors. Is that a problem?
diff --git a/src/doc/style/style/naming/iterators.md b/src/doc/style/style/naming/iterators.md
deleted file mode 100644 (file)
index 945cbe4..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-% Iterators
-
-#### Method names [RFC #199]
-
-> The guidelines below were approved by [RFC #199](https://github.com/rust-lang/rfcs/pull/199).
-
-For a container with elements of type `U`, iterator methods should be named:
-
-```rust,ignore
-fn iter(&self) -> T           // where T implements Iterator<&U>
-fn iter_mut(&mut self) -> T   // where T implements Iterator<&mut U>
-fn into_iter(self) -> T       // where T implements Iterator<U>
-```
-
-The default iterator variant yields shared references `&U`.
-
-#### Type names [RFC #344]
-
-> The guidelines below were approved by [RFC #344](https://github.com/rust-lang/rfcs/pull/344).
-
-The name of an iterator type should be the same as the method that
-produces the iterator.
-
-For example:
-
-* `iter` should yield an `Iter`
-* `iter_mut` should yield an `IterMut`
-* `into_iter` should yield an `IntoIter`
-* `keys` should yield `Keys`
-
-These type names make the most sense when prefixed with their owning module,
-e.g. `vec::IntoIter`.
diff --git a/src/doc/style/style/naming/ownership.md b/src/doc/style/style/naming/ownership.md
deleted file mode 100644 (file)
index 32cd8a1..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-% Ownership variants [RFC #199]
-
-> The guidelines below were approved by [RFC #199](https://github.com/rust-lang/rfcs/pull/199).
-
-Functions often come in multiple variants: immutably borrowed, mutably
-borrowed, and owned.
-
-The right default depends on the function in question. Variants should
-be marked through suffixes.
-
-#### Immutably borrowed by default
-
-If `foo` uses/produces an immutable borrow by default, use:
-
-* The `_mut` suffix (e.g. `foo_mut`) for the mutably borrowed variant.
-* The `_move` suffix (e.g. `foo_move`) for the owned variant.
-
-#### Owned by default
-
-If `foo` uses/produces owned data by default, use:
-
-* The `_ref` suffix (e.g. `foo_ref`) for the immutably borrowed variant.
-* The `_mut` suffix (e.g. `foo_mut`) for the mutably borrowed variant.
-
-#### Exceptions
-
-In the case of iterators, the moving variant can also be understood as
-an `into` conversion, `into_iter`, and `for x in v.into_iter()` reads
-arguably better than `for x in v.iter_move()`, so the convention is
-`into_iter`.
-
-For mutably borrowed variants, if the `mut` qualifier is part of a
-type name (e.g. `as_mut_slice`), it should appear as it would appear
-in the type.
diff --git a/src/doc/style/style/optional.md b/src/doc/style/style/optional.md
deleted file mode 100644 (file)
index d3c2178..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-*
-
-*
diff --git a/src/doc/style/style/organization.md b/src/doc/style/style/organization.md
deleted file mode 100644 (file)
index 8506540..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-% Organization [FIXME: needs RFC]
-
-> **[FIXME]** What else?
-
-### Reexport the most important types at the crate level.
-
-Crates `pub use` the most common types for convenience, so that clients do not
-have to remember or write the crate's module hierarchy to use these types.
-
-### Define types and operations together.
-
-Type definitions and the functions/methods that operate on them should be
-defined together in a single module, with the type appearing above the
-functions/methods.
diff --git a/src/doc/style/style/whitespace.md b/src/doc/style/style/whitespace.md
deleted file mode 100644 (file)
index c33c17c..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-% Whitespace [FIXME: needs RFC]
-
-* Lines must not exceed 99 characters.
-* Use 4 spaces for indentation, _not_ tabs.
-* No trailing whitespace at the end of lines or files.
-
-### Spaces
-
-* Use spaces around binary operators, including the equals sign in attributes:
-
-```rust,ignore
-#[deprecated = "Use `bar` instead."]
-fn foo(a: usize, b: usize) -> usize {
-    a + b
-}
-```
-
-* Use a space after colons and commas:
-
-```rust,ignore
-fn foo(a: Bar);
-
-MyStruct { foo: 3, bar: 4 }
-
-foo(bar, baz);
-```
-
-* Use a space after the opening and before the closing brace for
-  single line blocks or `struct` expressions:
-
-```rust,ignore
-spawn(proc() { do_something(); })
-
-Point { x: 0.1, y: 0.3 }
-```
-
-### Line wrapping
-
-* For multiline function signatures, each new line should align with the
-  first parameter. Multiple parameters per line are permitted:
-
-```rust,ignore
-fn frobnicate(a: Bar, b: Bar,
-              c: Bar, d: Bar)
-              -> Bar {
-    ...
-}
-
-fn foo<T: This,
-       U: That>(
-       a: Bar,
-       b: Bar)
-       -> Baz {
-    ...
-}
-```
-
-* Multiline function invocations generally follow the same rule as for
-  signatures. However, if the final argument begins a new block, the
-  contents of the block may begin on a new line, indented one level:
-
-```rust,ignore
-fn foo_bar(a: Bar, b: Bar,
-           c: |Bar|) -> Bar {
-    ...
-}
-
-// Same line is fine:
-foo_bar(x, y, |z| { z.transpose(y) });
-
-// Indented body on new line is also fine:
-foo_bar(x, y, |z| {
-    z.quux();
-    z.rotate(x)
-})
-```
-
-> **[FIXME]** Do we also want to allow the following?
->
-> ```rust,ignore
-> frobnicate(
->     arg1,
->     arg2,
->     arg3)
-> ```
->
-> This style could ease the conflict between line length and functions
-> with many parameters (or long method chains).
-
-### Matches
-
-> * **[Deprecated]** If you have multiple patterns in a single `match`
->   arm, write each pattern on a separate line:
->
->     ```rust,ignore
->     match foo {
->         bar(_)
->         | baz => quux,
->         x
->         | y
->         | z => {
->             quuux
->         }
->     }
->     ```
-
-### Alignment
-
-Idiomatic code should not use extra whitespace in the middle of a line
-to provide alignment.
-
-
-```rust,ignore
-// Good
-struct Foo {
-    short: f64,
-    really_long: f64,
-}
-
-// Bad
-struct Bar {
-    short:       f64,
-    really_long: f64,
-}
-
-// Good
-let a = 0;
-let radius = 7;
-
-// Bad
-let b        = 0;
-let diameter = 7;
-```
diff --git a/src/doc/style/testing/README.md b/src/doc/style/testing/README.md
deleted file mode 100644 (file)
index a21f694..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-% Testing
-
-> **[FIXME]** Add some general remarks about when and how to unit
-> test, versus other kinds of testing. What are our expectations for
-> Rust's core libraries?
diff --git a/src/doc/style/testing/unit.md b/src/doc/style/testing/unit.md
deleted file mode 100644 (file)
index dbbe9fc..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-% Unit testing
-
-Unit tests should live in a `tests` submodule at the bottom of the module they
-test. Mark the `tests` submodule with `#[cfg(test)]` so it is only compiled when
-testing.
-
-The `tests` module should contain:
-
-* Imports needed only for testing.
-* Functions marked with `#[test]` striving for full coverage of the parent module's
-  definitions.
-* Auxiliary functions needed for writing the tests.
-
-For example:
-
-``` rust
-// Excerpt from std::str
-
-#[cfg(test)]
-mod tests {
-    #[test]
-    fn test_eq() {
-        assert!((eq(&"".to_owned(), &"".to_owned())));
-        assert!((eq(&"foo".to_owned(), &"foo".to_owned())));
-        assert!((!eq(&"foo".to_owned(), &"bar".to_owned())));
-    }
-}
-```
-
-> **[FIXME]** add details about useful macros for testing, e.g. `assert!`
diff --git a/src/doc/style/todo.md b/src/doc/style/todo.md
deleted file mode 100644 (file)
index 28ef2a1..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-* [Containers and iteration]()
-* [The visitor pattern]()
-* [Concurrency]()
-* [Documentation]()
-* [Macros]()
index dae12f6e8bdf7c48558c22880fc473e35d27be6a..c8a78f84f185768fde245c014c5d9bf29559833a 100644 (file)
@@ -67,7 +67,6 @@
 use core::ops::{CoerceUnsized, Deref, DerefMut};
 use core::ops::{BoxPlace, Boxed, InPlace, Place, Placer};
 use core::ptr::{self, Unique};
-use core::raw::TraitObject;
 use core::convert::From;
 
 /// A value that represents the heap. This is the default place that the `box`
@@ -428,12 +427,8 @@ impl Box<Any> {
     pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any>> {
         if self.is::<T>() {
             unsafe {
-                // Get the raw representation of the trait object
-                let raw = Box::into_raw(self);
-                let to: TraitObject = mem::transmute::<*mut Any, TraitObject>(raw);
-
-                // Extract the data pointer
-                Ok(Box::from_raw(to.data as *mut T))
+                let raw: *mut Any = Box::into_raw(self);
+                Ok(Box::from_raw(raw as *mut T))
             }
         } else {
             Err(self)
index d9fd2d92710dc5c75b873e4577a62c28b11c2755..c6453da3f4697d5f660634cf59a088a4197059ea 100644 (file)
@@ -91,7 +91,7 @@
 #![cfg_attr(stage0, feature(unsafe_no_drop_flag))]
 #![feature(unsize)]
 
-#![cfg_attr(not(test), feature(fused, raw, fn_traits, placement_new_protocol))]
+#![cfg_attr(not(test), feature(fused, fn_traits, placement_new_protocol))]
 #![cfg_attr(test, feature(test, box_heap))]
 
 // Allow testing this library
index c062ae62b00496c4de8fa03e6327bf81e605bf2c..5ece27372e13034f2cc0400e3ce2f37e98903d20 100644 (file)
 #![allow(missing_docs)]
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use core::ops::{Drop, Deref, DerefMut};
+use core::ops::{Deref, DerefMut};
 use core::iter::{FromIterator, FusedIterator};
 use core::mem::swap;
 use core::mem::size_of;
index 37dbeb4eae17d6d61f7dad0929e8ae3c9830c72d..3ad1d08298581c81785cf6259754a24eab774033 100644 (file)
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use core::clone::Clone;
-use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
-use core::convert::AsRef;
-use core::default::Default;
+use core::cmp::Ordering;
 use core::hash::{Hash, Hasher};
-use core::marker::Sized;
 use core::ops::Deref;
-use core::option::Option;
 
 use fmt;
 
index 8b8bea0ca45a14ef60fc8ad07ade2740efcfb60c..769c5162a456057a3d22a027b277f5345bbf8c2c 100644 (file)
@@ -1159,9 +1159,6 @@ unsafe impl<'a, T: Sync> Sync for IterMut<'a, T> {}
 
 #[cfg(test)]
 mod tests {
-    use std::clone::Clone;
-    use std::iter::{Iterator, IntoIterator, Extend};
-    use std::option::Option::{self, Some, None};
     use std::__rand::{thread_rng, Rng};
     use std::thread;
     use std::vec::Vec;
@@ -1319,7 +1316,6 @@ fn test_fuzz() {
 
     #[test]
     fn test_26021() {
-        use std::iter::ExactSizeIterator;
         // There was a bug in split_off that failed to null out the RHS's head's prev ptr.
         // This caused the RHS's dtor to walk up into the LHS at drop and delete all of
         // its nodes.
index 1badc72aed07c1a9d21eab781c59fd6ef5fed9f9..d331ead2c5ee685173d8ab82210a99c3f297fe03 100644 (file)
@@ -14,7 +14,6 @@
 
 //! Range syntax.
 
-use core::option::Option::{self, None, Some};
 use core::ops::{RangeFull, Range, RangeTo, RangeFrom};
 
 /// **RangeArgument** is implemented by Rust's built-in range types, produced
index 6f220c1d472a61acfdf38a162e4e082618efa1bc..96624f121b2afbe5ffa81433606b4c3ba84046cc 100644 (file)
@@ -2332,9 +2332,6 @@ fn from(other: VecDeque<T>) -> Self {
 
 #[cfg(test)]
 mod tests {
-    use core::iter::Iterator;
-    use core::option::Option::Some;
-
     use test;
 
     use super::VecDeque;
index a452be2565b655e14597eed0116d65386bc53210..a3018a46eea22063545331e6937609597a98654d 100644 (file)
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use fmt;
-use marker::Send;
-use mem::transmute;
-use option::Option::{self, Some, None};
-use raw::TraitObject;
 use intrinsics;
-use marker::{Reflect, Sized};
+use marker::Reflect;
 
 ///////////////////////////////////////////////////////////////////////////////
 // Any trait
@@ -201,11 +197,7 @@ pub fn is<T: Any>(&self) -> bool {
     pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
         if self.is::<T>() {
             unsafe {
-                // Get the raw representation of the trait object
-                let to: TraitObject = transmute(self);
-
-                // Extract the data pointer
-                Some(&*(to.data as *const T))
+                Some(&*(self as *const Any as *const T))
             }
         } else {
             None
@@ -242,11 +234,7 @@ pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
     pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
         if self.is::<T>() {
             unsafe {
-                // Get the raw representation of the trait object
-                let to: TraitObject = transmute(self);
-
-                // Extract the data pointer
-                Some(&mut *(to.data as *const T as *mut T))
+                Some(&mut *(self as *mut Any as *mut T))
             }
         } else {
             None
index 45fc5ff80093a99176599d4f760e2a4e1ce45610..9866a39619a82ecfdc3265be60e7e4e4adde7006 100644 (file)
             issue = "27778")]
 
 use borrow::{Borrow, BorrowMut};
-use clone::Clone;
-use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
-use convert::{AsRef, AsMut};
-use default::Default;
+use cmp::Ordering;
 use fmt;
 use hash::{Hash, self};
-use iter::IntoIterator;
-use marker::{Copy, Sized, Unsize};
-use option::Option;
-use slice::{Iter, IterMut, SliceExt};
+use marker::Unsize;
+use slice::{Iter, IterMut};
 
 /// Utility trait implemented only on arrays of fixed size
 ///
index 79330d3a61ea7dcfedeb9f6da18513bf1f4b5f91..3d223465c88a03b44dc01bb913d210b50e14d575 100644 (file)
@@ -12,8 +12,6 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use marker::Sized;
-
 /// A trait for borrowing data.
 ///
 /// In general, there may be several ways to "borrow" a piece of data.  The
index 2af48ef2fabe3b42d04cfa53bb4bd565259f538b..ec35198b68517ae5988fb6bdf864288eb02931cc 100644 (file)
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use clone::Clone;
-use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
-use convert::From;
-use default::Default;
+use cmp::Ordering;
 use fmt::{self, Debug, Display};
-use marker::{Copy, PhantomData, Send, Sync, Sized, Unsize};
-use ops::{Deref, DerefMut, Drop, FnOnce, CoerceUnsized};
-use option::Option;
-use option::Option::{None, Some};
-use result::Result;
-use result::Result::{Ok, Err};
+use marker::{PhantomData, Unsize};
+use ops::{Deref, DerefMut, CoerceUnsized};
 
 /// A mutable memory location that admits only `Copy` data.
 ///
index 98b7632a220dd1cc014eefabbca332d5cf56f6e2..4677f0b523f425c6365d78bf8b764f90826605aa 100644 (file)
@@ -15,8 +15,6 @@
 #![allow(non_snake_case)]
 #![stable(feature = "core_char", since = "1.2.0")]
 
-use prelude::v1::*;
-
 use char_private::is_printable;
 use iter::FusedIterator;
 use mem::transmute;
@@ -752,25 +750,81 @@ pub fn decode_utf8<I: IntoIterator<Item = u8>>(i: I) -> DecodeUtf8<I::IntoIter>
 impl<I: Iterator<Item = u8>> Iterator for DecodeUtf8<I> {
     type Item = Result<char, InvalidSequence>;
     #[inline]
+
     fn next(&mut self) -> Option<Result<char, InvalidSequence>> {
-        self.0.next().map(|b| {
-            if b & 0x80 == 0 { Ok(b as char) } else {
-                let l = (!b).leading_zeros() as usize; // number of bytes in UTF-8 representation
-                if l < 2 || l > 6 { return Err(InvalidSequence(())) };
-                let mut x = (b as u32) & (0x7F >> l);
-                for _ in 0..l-1 {
+        self.0.next().map(|first_byte| {
+            // Emit InvalidSequence according to
+            // Unicode Â§5.22 Best Practice for U+FFFD Substitution
+            // http://www.unicode.org/versions/Unicode9.0.0/ch05.pdf#G40630
+
+            // Roughly: consume at least one byte,
+            // then validate one byte at a time and stop before the first unexpected byte
+            // (which might be the valid start of the next byte sequence).
+
+            let mut code_point;
+            macro_rules! first_byte {
+                ($mask: expr) => {
+                    code_point = u32::from(first_byte & $mask)
+                }
+            }
+            macro_rules! continuation_byte {
+                () => { continuation_byte!(0x80...0xBF) };
+                ($range: pat) => {
                     match self.0.peek() {
-                        Some(&b) if b & 0xC0 == 0x80 => {
+                        Some(&byte @ $range) => {
+                            code_point = (code_point << 6) | u32::from(byte & 0b0011_1111);
                             self.0.next();
-                            x = (x << 6) | (b as u32) & 0x3F;
-                        },
-                        _ => return Err(InvalidSequence(())),
+                        }
+                        _ => return Err(InvalidSequence(()))
                     }
                 }
-                match from_u32(x) {
-                    Some(x) if l == x.len_utf8() => Ok(x),
-                    _ => Err(InvalidSequence(())),
+            }
+
+            match first_byte {
+                0x00...0x7F => {
+                    first_byte!(0b1111_1111);
+                }
+                0xC2...0xDF => {
+                    first_byte!(0b0001_1111);
+                    continuation_byte!();
                 }
+                0xE0 => {
+                    first_byte!(0b0000_1111);
+                    continuation_byte!(0xA0...0xBF);  // 0x80...0x9F here are overlong
+                    continuation_byte!();
+                }
+                0xE1...0xEC | 0xEE...0xEF => {
+                    first_byte!(0b0000_1111);
+                    continuation_byte!();
+                    continuation_byte!();
+                }
+                0xED => {
+                    first_byte!(0b0000_1111);
+                    continuation_byte!(0x80...0x9F);  // 0xA0..0xBF here are surrogates
+                    continuation_byte!();
+                }
+                0xF0 => {
+                    first_byte!(0b0000_0111);
+                    continuation_byte!(0x90...0xBF);  // 0x80..0x8F here are overlong
+                    continuation_byte!();
+                    continuation_byte!();
+                }
+                0xF1...0xF3 => {
+                    first_byte!(0b0000_0111);
+                    continuation_byte!();
+                    continuation_byte!();
+                    continuation_byte!();
+                }
+                0xF4 => {
+                    first_byte!(0b0000_0111);
+                    continuation_byte!(0x80...0x8F);  // 0x90..0xBF here are beyond char::MAX
+                    continuation_byte!();
+                    continuation_byte!();
+                }
+                _ => return Err(InvalidSequence(()))  // Illegal first byte, overlong, or beyond MAX
+            }
+            unsafe {
+                Ok(from_u32_unchecked(code_point))
             }
         })
     }
index 1d8f95cd4b81cd800aa3320a4510193496caf3f1..708e7cc15e7c97f97f89f9f4c326bc02bf2acd97 100644 (file)
@@ -11,8 +11,6 @@
 // NOTE: The following code was generated by "src/etc/char_private.py",
 //       do not edit directly!
 
-use slice::SliceExt;
-
 fn check(x: u16, singletons: &[u16], normal: &[u16]) -> bool {
     for &s in singletons {
         if x == s {
index e8cd36f3cd70bf13d751790bcbefdb2e9a16a937..748bb62a1f3eb51794c40f8611ca7f4d1d1e4f29 100644 (file)
@@ -44,8 +44,6 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use marker::Sized;
-
 /// A common trait for the ability to explicitly duplicate an object.
 ///
 /// Differs from `Copy` in that `Copy` is implicit and extremely inexpensive, while
index 9bba6cd38e5567d9611d4f84affb00e4049f653b..907dd1508d8bee9b7c1012629b974da85473a6e5 100644 (file)
@@ -34,9 +34,6 @@
 
 use self::Ordering::*;
 
-use marker::Sized;
-use option::Option::{self, Some};
-
 /// Trait for equality comparisons which are [partial equivalence
 /// relations](http://en.wikipedia.org/wiki/Partial_equivalence_relation).
 ///
@@ -571,11 +568,7 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
 
 // Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
 mod impls {
-    use cmp::{PartialOrd, Ord, PartialEq, Eq, Ordering};
-    use cmp::Ordering::{Less, Greater, Equal};
-    use marker::Sized;
-    use option::Option;
-    use option::Option::{Some, None};
+    use cmp::Ordering::{self, Less, Greater, Equal};
 
     macro_rules! partial_eq_impl {
         ($($t:ty)*) => ($(
index e68f973d8d940e44460f2b4404c25be57e561ac6..8e7e2abfc1e174c6dc73267c87218f6b623eb8eb 100644 (file)
@@ -40,9 +40,6 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use marker::Sized;
-use result::Result;
-
 /// A cheap, reference-to-reference conversion.
 ///
 /// `AsRef` is very similar to, but different than, `Borrow`. See
index a0dd38c983b89fd826d1f9585d36eb35fcb2f0f0..85e4b2a0067698b385963e3fce5c586909673056 100644 (file)
@@ -12,8 +12,6 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use marker::Sized;
-
 /// A trait for giving a type a useful default value.
 ///
 /// Sometimes, you want to fall back to some kind of default value, and
index 6cac80ab6245f8bf421ce5be8c7c2c514042aed6..102e3c0bd7b95f04841117ef16b8cb3c4a4e65a4 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
 use fmt::{self, FlagV1};
 
 struct PadAdapter<'a, 'b: 'a> {
index 7688da971eb1dde87c2bb8409d13a2f2030535a9..66ef92928eb06c590dcda324ed897e454c2935ac 100644 (file)
@@ -12,8 +12,6 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use prelude::v1::*;
-
 use cell::{UnsafeCell, Cell, RefCell, Ref, RefMut, BorrowState};
 use marker::PhantomData;
 use mem;
@@ -905,8 +903,6 @@ pub fn pad_integral(&mut self,
                         prefix: &str,
                         buf: &str)
                         -> Result {
-        use char::CharExt;
-
         let mut width = buf.len();
 
         let mut sign = None;
@@ -1020,7 +1016,6 @@ fn with_padding<F>(&mut self, padding: usize, default: rt::v1::Alignment,
                        f: F) -> Result
         where F: FnOnce(&mut Formatter) -> Result,
     {
-        use char::CharExt;
         let align = match self.align {
             rt::v1::Alignment::Unknown => default,
             _ => self.align
index d55e0317a949218af2cca35aebd36da2997d1dc3..0145897d8f6909568cdba4b3e066ddf6a7242520 100644 (file)
@@ -14,8 +14,6 @@
 
 // FIXME: #6220 Implement floating point formatting
 
-use prelude::v1::*;
-
 use fmt;
 use num::Zero;
 use ops::{Div, Rem, Sub};
index 27fdbd383017f08ea3e38350b47e0a6b9c9a84aa..081f0c14ec30c978e44611e66c1650d45a3df8b3 100644 (file)
@@ -71,8 +71,6 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use prelude::v1::*;
-
 use fmt;
 use marker;
 use mem;
@@ -288,8 +286,6 @@ fn default() -> BuildHasherDefault<H> {
 //////////////////////////////////////////////////////////////////////////////
 
 mod impls {
-    use prelude::v1::*;
-
     use mem;
     use slice;
     use super::*;
index 4a806a3c98602aa224b963e8a862526d3b1b48ef..bd6cae92b050c6bdb80ffde8b5aa537aacae184b 100644 (file)
@@ -10,8 +10,6 @@
 
 //! An implementation of SipHash.
 
-use prelude::v1::*;
-
 use marker::PhantomData;
 use ptr;
 
index 3c2c5abcb2821ce7ccb81be4838e6a43facb869b..8271b85b01a3b93553403fb45f6c096256a1cf79 100644 (file)
@@ -46,8 +46,6 @@
             issue = "0")]
 #![allow(missing_docs)]
 
-use marker::Sized;
-
 extern "rust-intrinsic" {
 
     // NB: These intrinsics take raw pointers because they mutate aliased
index 6b01ccaceea2f31c3726597244a23ccefdda2fc1..ea97c87efbb410fad9c24a4aed79cf75f5eba764 100644 (file)
@@ -8,19 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use clone::Clone;
-use cmp::{Ord, PartialOrd, PartialEq, Ordering};
-use default::Default;
-use ops::FnMut;
-use option::Option::{self, Some, None};
-use marker::Sized;
+use cmp::Ordering;
 
 use super::{Chain, Cycle, Cloned, Enumerate, Filter, FilterMap, FlatMap, Fuse};
 use super::{Inspect, Map, Peekable, Scan, Skip, SkipWhile, Take, TakeWhile, Rev};
 use super::{Zip, Sum, Product};
-use super::ChainState;
-use super::{DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator};
-use super::{IntoIterator, ZipImpl};
+use super::{ChainState, FromIterator, ZipImpl};
 
 fn _assert_is_object_safe(_: &Iterator<Item=()>) {}
 
index cfe117c0b1d695713c8801cbd1a4f054d9952558..b1d3ab1d1febcd18cb81bd4f4a566aad692342c0 100644 (file)
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use clone::Clone;
 use cmp;
-use default::Default;
 use fmt;
 use iter_private::TrustedRandomAccess;
-use ops::FnMut;
-use option::Option::{self, Some, None};
 use usize;
 
 #[stable(feature = "rust1", since = "1.0.0")]
index 48816bf66bbb79d8b09fc2263492fd7eab76d73f..8408e5d88b4cbec4b37d1ddcf492a93b0d9fccc7 100644 (file)
@@ -8,15 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use clone::Clone;
-use cmp::PartialOrd;
 use mem;
 use ops::{self, Add, Sub};
-use option::Option::{self, Some, None};
-use marker::Sized;
 use usize;
 
-use super::{DoubleEndedIterator, ExactSizeIterator, Iterator, FusedIterator};
+use super::FusedIterator;
 
 /// Objects that can be stepped over in both directions.
 ///
index a2a019a07dcf1b2b942890f3f86db119db8182de..da346eaf1db96d24ee991be0bfe431e201217b52 100644 (file)
@@ -8,14 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use clone::Clone;
-use default::Default;
 use fmt;
 use marker;
-use option::Option::{self, Some, None};
 use usize;
 
-use super::{DoubleEndedIterator, IntoIterator, Iterator, ExactSizeIterator, FusedIterator};
+use super::FusedIterator;
 
 /// An iterator that repeats an element endlessly.
 ///
index 6f80a0246817478b90eb9eb67673ec7c8da32d56..59e23c4d960567d6af82c729eada07b6becd1c14 100644 (file)
@@ -8,11 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use option::Option::{self, Some};
-use marker::Sized;
-
-use super::Iterator;
-
 /// Conversion from an `Iterator`.
 ///
 /// By implementing `FromIterator` for a type, you define how it will be
index effe43cc67cea8912573c96abd40afb00612b99f..83eeef31ab054cd074c3fa515a78f6ead1401594 100644 (file)
@@ -9,8 +9,6 @@
 // except according to those terms.
 
 
-use iter::ExactSizeIterator;
-
 /// An iterator whose items are random accessible efficiently
 ///
 /// # Safety
index fbeddf26b939a4014dddf8e527d6d5f365bf5f5b..1ae4cf8e5ef5f05b37c920206786768eba05d41c 100644 (file)
 #![feature(unboxed_closures)]
 #![feature(question_mark)]
 #![feature(never_type)]
+#![feature(prelude_import)]
+
+#[prelude_import]
+#[allow(unused)]
+use prelude::v1::*;
 
 #[macro_use]
 mod macros;
index 894982abaa939879f58e410e03c595ddf17cb684..0a46813df7eb82774e94d5e081598a2321963e24 100644 (file)
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use clone::Clone;
 use cmp;
-use default::Default;
-use option::Option;
 use hash::Hash;
 use hash::Hasher;
 
@@ -414,8 +411,6 @@ fn default() -> $t<T> {
 impls! { PhantomData }
 
 mod impls {
-    use super::{Send, Sync, Sized};
-
     #[stable(feature = "rust1", since = "1.0.0")]
     unsafe impl<'a, T: Sync + ?Sized> Send for &'a T {}
     #[stable(feature = "rust1", since = "1.0.0")]
index 6ebbe97d064a2c23521f247dc4e4e31bdea0af52..9c61f76ac8895b9e8817447030606e8b5d1da6e3 100644 (file)
@@ -15,7 +15,6 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use marker::Sized;
 use intrinsics;
 use ptr;
 
index 92bbc4efb7cc1d78ab45fe0d0828401d544608d3..47afaf77353ee42803a246a61d1bc98a64bb9ef1 100644 (file)
@@ -13,7 +13,6 @@
             reason = "needs an RFC to flesh out the design",
             issue = "27730")]
 
-use marker::Sized;
 use ops::{CoerceUnsized, Deref};
 
 /// Unsafe trait to indicate what types are usable with the NonZero struct
index a881b539cedebf0ba5dbb4b2c6342f458c6c89ba..bc503ba3e46aedc0ccb983818e970680268b5c93 100644 (file)
@@ -27,8 +27,6 @@
             issue = "0")]
 #![macro_use]
 
-use prelude::v1::*;
-
 use mem;
 use intrinsics;
 
@@ -494,6 +492,5 @@ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
 // this one is used for testing only.
 #[doc(hidden)]
 pub mod tests {
-    use prelude::v1::*;
     define_bignum!(Big8x3: type=u8, n=3);
 }
index 4761727cec03ff93594b2fb4d706c960ba99479a..604bc7c10dea0aedaa886e976f1c63e392314fce 100644 (file)
@@ -10,7 +10,6 @@
 
 //! The various algorithms from the paper.
 
-use prelude::v1::*;
 use cmp::min;
 use cmp::Ordering::{Less, Equal, Greater};
 use num::diy_float::Fp;
@@ -47,7 +46,6 @@ pub fn set_precision<T>() { }
 #[cfg(all(target_arch="x86", not(target_feature="sse2")))]
 mod fpu_precision {
     use mem::size_of;
-    use ops::Drop;
 
     /// A structure used to preserve the original value of the FPU control word, so that it can be
     /// restored when the structure is dropped.
index ff2d85307b1060ef6cb2c5a2bcc619a80fe2b7f5..cd40e399ab95e6639ebb579e0e89776db8179b96 100644 (file)
@@ -92,7 +92,6 @@
             reason = "internal routines only exposed for testing",
             issue = "0")]
 
-use prelude::v1::*;
 use fmt;
 use str::FromStr;
 
index 81e7856633b2571f9f0a33c2295671deefc1bda9..34b41fa9decd295703f903bb48aad4f4d4c5b0cc 100644 (file)
@@ -12,7 +12,6 @@
 
 // FIXME This module's name is a bit unfortunate, since other modules also import `core::num`.
 
-use prelude::v1::*;
 use cmp::Ordering::{self, Less, Equal, Greater};
 
 pub use num::bignum::Big32x40 as Big;
index fce1c250a022e0f44075f52f940d09ffb5b893e6..d20986faa0fc24b1dfde7fcfc65db70ab6c82e6a 100644 (file)
@@ -20,7 +20,6 @@
 //! modules rely on to not panic (or overflow) in turn.
 //! To make matters worse, all that happens in a single pass over the input.
 //! So, be careful when modifying anything, and double-check with the other modules.
-use prelude::v1::*;
 use super::num;
 use self::ParseResult::{Valid, ShortcutToInf, ShortcutToZero, Invalid};
 
index 68e4dc4b359efa73fb3ee5373004d569f756fcd9..e3b58b6cc7ce94407980d2c351e71b2a982f2565 100644 (file)
@@ -27,7 +27,6 @@
 //! Many functions in this module only handle normal numbers. The dec2flt routines conservatively
 //! take the universally-correct slow path (Algorithm M) for very small and very large numbers.
 //! That algorithm needs only next_float() which does handle subnormals and zeros.
-use prelude::v1::*;
 use u32;
 use cmp::Ordering::{Less, Equal, Greater};
 use ops::{Mul, Div, Neg};
index 5420e7bdd2a5a064092b398387c89ec884c97c6b..276667e44aae1a42c65a91e14d2225d805fff8db 100644 (file)
@@ -10,8 +10,6 @@
 
 //! Decodes a floating-point value into individual parts and error ranges.
 
-use prelude::v1::*;
-
 use {f32, f64};
 use num::FpCategory;
 use num::dec2flt::rawfp::RawFloat;
index b549f33424264d3ddcf741b19cc8408486aabd74..f6c03a59f81e4ed7750a3cda89fc5841e64a3505 100644 (file)
             reason = "internal routines only exposed for testing",
             issue = "0")]
 
-use prelude::v1::*;
 use i16;
 pub use self::decoder::{decode, DecodableFloat, FullDecoded, Decoded};
 
index 2d68c3a6d026ec397cd7fdd55ec849e961cf8d72..6aa4f297e75ba7f79fe6164867c36dd01ee860b5 100644 (file)
@@ -15,8 +15,6 @@
     quickly and accurately. SIGPLAN Not. 31, 5 (May. 1996), 108-116.
 */
 
-use prelude::v1::*;
-
 use cmp::Ordering;
 
 use num::flt2dec::{Decoded, MAX_SIG_DIGITS, round_up};
index 13e01d9a7f7ab548918288fbbe693da00c980cf1..cf70a1978f5e6d53aa3de3fdf7b02fecfd459806 100644 (file)
@@ -16,8 +16,6 @@
     accurately with integers. SIGPLAN Not. 45, 6 (June 2010), 233-243.
 */
 
-use prelude::v1::*;
-
 use num::diy_float::Fp;
 use num::flt2dec::{Decoded, MAX_SIG_DIGITS, round_up};
 
index 4636811aa46da2c95f96d6c87bf9cdd3a06a09b6..29ee29eb3eb7f61584dbbf0f8b0a1a6708679e81 100644 (file)
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use char::CharExt;
-use cmp::PartialOrd;
-use convert::{From, TryFrom};
+use convert::TryFrom;
 use fmt;
 use intrinsics;
-use marker::{Copy, Sized};
 use mem::size_of;
-use option::Option::{self, Some, None};
-use result::Result::{self, Ok, Err};
-use str::{FromStr, StrExt};
-use slice::SliceExt;
+use str::FromStr;
 
 /// Provides intentionally-wrapped arithmetic on `T`.
 ///
index 5d431230e9744cfeaaed9aaed96e7ee0cf1db62c..b9adaf0206d948048b9ed1501b2216416c99656a 100644 (file)
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use cmp::PartialOrd;
 use fmt;
-use marker::{Sized, Unsize};
-use result::Result::{self, Ok, Err};
+use marker::Unsize;
 
 /// The `Drop` trait is used to run some code when a value goes out of scope.
 /// This is sometimes called a 'destructor'.
@@ -2208,9 +2206,6 @@ pub trait FnOnce<Args> {
 }
 
 mod impls {
-    use marker::Sized;
-    use super::{Fn, FnMut, FnOnce};
-
     #[stable(feature = "rust1", since = "1.0.0")]
     impl<'a,A,F:?Sized> Fn<A> for &'a F
         where F : Fn<A>
index 51bbad085fba4fc244f48c4fd3568a016b20af35..cf52849e019722a71797d4a300983f06f9eab291 100644 (file)
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use self::Option::*;
-
-use clone::Clone;
-use convert::From;
-use default::Default;
-use iter::{Iterator, FromIterator, IntoIterator, ExactSizeIterator, DoubleEndedIterator};
-use iter::FusedIterator;
+use iter::{FromIterator, FusedIterator};
 use mem;
-use ops::FnOnce;
-use result::Result::{Ok, Err};
-use result::Result;
 
 // Note that this is not a lang item per se, but it has a hidden dependency on
 // `Iterator`, which is one. The compiler assumes that the `next` method of
index dd76843793332f407514e850087cffde7494a039..8c8925251e5cf4ef9d4c1a75aa6f0d8966fa8d4b 100644 (file)
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use clone::Clone;
 use intrinsics;
 use ops::{CoerceUnsized, Deref};
 use fmt;
 use hash;
-use option::Option::{self, Some, None};
-use marker::{Copy, PhantomData, Send, Sized, Sync, Unsize};
+use marker::{PhantomData, Unsize};
 use mem;
 use nonzero::NonZero;
 
-use cmp::{PartialEq, Eq, Ord, PartialOrd};
 use cmp::Ordering::{self, Less, Equal, Greater};
 
 // FIXME #19649: intrinsic docs don't render, so these have no docs :(
index 718fdf865a9703a4410df95b09b8386da45e377e..49eb5619bc6baafa72ea7b32a6e9259656e67a24 100644 (file)
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use self::Result::{Ok, Err};
-
-use clone::Clone;
 use fmt;
-use iter::{Iterator, DoubleEndedIterator, FromIterator, ExactSizeIterator, IntoIterator};
-use iter::FusedIterator;
-use ops::FnOnce;
-use option::Option::{self, None, Some};
+use iter::{FromIterator, FusedIterator};
 
 /// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
 ///
index 603f55a6e108e4e09db1c780ae7b805703791f45..baa41aa7af5b274298181abc13424fe93d949a35 100644 (file)
 // * The `raw` and `bytes` submodules.
 // * Boilerplate trait implementations.
 
-use clone::Clone;
-use cmp::{Ordering, PartialEq, PartialOrd, Eq, Ord};
-use cmp::Ordering::{Less, Equal, Greater};
+use cmp::Ordering::{self, Less, Equal, Greater};
 use cmp;
-use convert::AsRef;
-use default::Default;
 use fmt;
 use intrinsics::assume;
 use iter::*;
-use ops::{FnMut, self};
-use ops::RangeFull;
-use option::Option;
-use option::Option::{None, Some};
-use result::Result;
-use result::Result::{Ok, Err};
+use ops::{self, RangeFull};
 use ptr;
 use mem;
-use marker::{Copy, Send, Sync, self};
+use marker;
 use iter_private::TrustedRandomAccess;
 
 #[repr(C)]
index 5dc5880e310d038115dd234e965de44f96097200..18e43c02c648fb7973fd5eb9b46722fc08e9d7dd 100644 (file)
 use self::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
 
 use char;
-use clone::Clone;
-use convert::AsRef;
-use default::Default;
 use fmt;
-use iter::ExactSizeIterator;
-use iter::{Map, Cloned, Iterator, DoubleEndedIterator, FusedIterator};
-use marker::Sized;
+use iter::{Map, Cloned, FusedIterator};
 use mem;
-use ops::{Fn, FnMut, FnOnce};
-use option::Option::{self, None, Some};
-use result::Result::{self, Ok, Err};
-use slice::{self, SliceExt};
+use slice;
 
 pub mod pattern;
 
@@ -1338,11 +1330,9 @@ macro_rules! next { () => {{
 */
 
 mod traits {
-    use cmp::{Ord, Ordering, PartialEq, PartialOrd, Eq};
-    use option::Option;
-    use option::Option::Some;
+    use cmp::Ordering;
     use ops;
-    use str::{StrExt, eq_slice};
+    use str::eq_slice;
 
     #[stable(feature = "rust1", since = "1.0.0")]
     impl Ord for str {
index 53804c611e66ed52dc196b01e68eee88cce6820b..7dced2ba7514c2ac492167f882adcede4e7970bb 100644 (file)
@@ -17,8 +17,6 @@
             reason = "API not fully fleshed out and ready to be stabilized",
             issue = "27721")]
 
-use prelude::v1::*;
-
 use cmp;
 use fmt;
 use usize;
index bd62879c1a57229b3ee85a10b6a805892b6e3a73..75ddd2021a8f7fa74f9afa82b162f3820b4d6142 100644 (file)
 
 use self::Ordering::*;
 
-use marker::{Send, Sync};
-
 use intrinsics;
 use cell::UnsafeCell;
-
-use result::Result::{self, Ok, Err};
-
-use default::Default;
 use fmt;
 
 /// A boolean type which can be safely shared between threads.
index abaabfd129b383d31584a10657dc0a71232f7a3c..c3608b60a31a7ad9d9d422681aee947e0f8add51 100644 (file)
 
 // See src/libstd/primitive_docs.rs for documentation.
 
-use clone::Clone;
 use cmp::*;
 use cmp::Ordering::*;
-use default::Default;
-use option::Option;
-use option::Option::Some;
 
 // FIXME(#19630) Remove this work-around
 macro_rules! e {
index 4632419336d7f5f047e0057d02a3ce48d45a44b2..333503d738943b10cd74584cfb34c1119eed4579 100644 (file)
@@ -358,29 +358,50 @@ fn check(c: char) {
 
 #[test]
 fn test_decode_utf8() {
-    use core::char::*;
-    use core::iter::FromIterator;
-
-    for &(str, bs) in [("", &[] as &[u8]),
-                       ("A", &[0x41u8] as &[u8]),
-                       ("�", &[0xC1u8, 0x81u8] as &[u8]),
-                       ("♥", &[0xE2u8, 0x99u8, 0xA5u8]),
-                       ("♥A", &[0xE2u8, 0x99u8, 0xA5u8, 0x41u8] as &[u8]),
-                       ("�", &[0xE2u8, 0x99u8] as &[u8]),
-                       ("�A", &[0xE2u8, 0x99u8, 0x41u8] as &[u8]),
-                       ("�", &[0xC0u8] as &[u8]),
-                       ("�A", &[0xC0u8, 0x41u8] as &[u8]),
-                       ("�", &[0x80u8] as &[u8]),
-                       ("�A", &[0x80u8, 0x41u8] as &[u8]),
-                       ("�", &[0xFEu8] as &[u8]),
-                       ("�A", &[0xFEu8, 0x41u8] as &[u8]),
-                       ("�", &[0xFFu8] as &[u8]),
-                       ("�A", &[0xFFu8, 0x41u8] as &[u8])].into_iter() {
-        assert!(Iterator::eq(str.chars(),
-                             decode_utf8(bs.into_iter().map(|&b|b))
-                                 .map(|r_b| r_b.unwrap_or('\u{FFFD}'))),
-                "chars = {}, bytes = {:?}, decoded = {:?}", str, bs,
-                Vec::from_iter(decode_utf8(bs.into_iter().map(|&b|b))
-                                   .map(|r_b| r_b.unwrap_or('\u{FFFD}'))));
+    macro_rules! assert_decode_utf8 {
+        ($input_bytes: expr, $expected_str: expr) => {
+            let input_bytes: &[u8] = &$input_bytes;
+            let s = char::decode_utf8(input_bytes.iter().cloned())
+                .map(|r_b| r_b.unwrap_or('\u{FFFD}'))
+                .collect::<String>();
+            assert_eq!(s, $expected_str,
+                       "input bytes: {:?}, expected str: {:?}, result: {:?}",
+                       input_bytes, $expected_str, s);
+            assert_eq!(String::from_utf8_lossy(&$input_bytes), $expected_str);
+        }
     }
+
+    assert_decode_utf8!([], "");
+    assert_decode_utf8!([0x41], "A");
+    assert_decode_utf8!([0xC1, 0x81], "��");
+    assert_decode_utf8!([0xE2, 0x99, 0xA5], "♥");
+    assert_decode_utf8!([0xE2, 0x99, 0xA5, 0x41], "♥A");
+    assert_decode_utf8!([0xE2, 0x99], "�");
+    assert_decode_utf8!([0xE2, 0x99, 0x41], "�A");
+    assert_decode_utf8!([0xC0], "�");
+    assert_decode_utf8!([0xC0, 0x41], "�A");
+    assert_decode_utf8!([0x80], "�");
+    assert_decode_utf8!([0x80, 0x41], "�A");
+    assert_decode_utf8!([0xFE], "�");
+    assert_decode_utf8!([0xFE, 0x41], "�A");
+    assert_decode_utf8!([0xFF], "�");
+    assert_decode_utf8!([0xFF, 0x41], "�A");
+    assert_decode_utf8!([0xC0, 0x80], "��");
+
+    // Surrogates
+    assert_decode_utf8!([0xED, 0x9F, 0xBF], "\u{D7FF}");
+    assert_decode_utf8!([0xED, 0xA0, 0x80], "���");
+    assert_decode_utf8!([0xED, 0xBF, 0x80], "���");
+    assert_decode_utf8!([0xEE, 0x80, 0x80], "\u{E000}");
+
+    // char::MAX
+    assert_decode_utf8!([0xF4, 0x8F, 0xBF, 0xBF], "\u{10FFFF}");
+    assert_decode_utf8!([0xF4, 0x8F, 0xBF, 0x41], "�A");
+    assert_decode_utf8!([0xF4, 0x90, 0x80, 0x80], "����");
+
+    // 5 and 6 bytes sequence
+    // Part of the original design of UTF-8,
+    // but invalid now that UTF-8 is artificially restricted to match the range of UTF-16.
+    assert_decode_utf8!([0xF8, 0x80, 0x80, 0x80, 0x80], "�����");
+    assert_decode_utf8!([0xFC, 0x80, 0x80, 0x80, 0x80, 0x80], "������");
 }
index 4edbeab5dfb11049cbedf1255d30608c16abcc6f..1825a892cf55415d0832167c03310faa0a921541 100644 (file)
@@ -173,12 +173,12 @@ pub fn is_empty(&self) -> bool {
         self.start == self.end
     }
 
-    pub fn as_str_slice(&self) -> &'doc str {
+    pub fn as_str(&self) -> &'doc str {
         str::from_utf8(&self.data[self.start..self.end]).unwrap()
     }
 
-    pub fn as_str(&self) -> String {
-        self.as_str_slice().to_string()
+    pub fn to_string(&self) -> String {
+        self.as_str().to_string()
     }
 }
 
@@ -773,7 +773,7 @@ fn read_char(&mut self) -> DecodeResult<char> {
             Ok(char::from_u32(doc_as_u32(self.next_doc(EsChar)?)).unwrap())
         }
         fn read_str(&mut self) -> DecodeResult<String> {
-            Ok(self.next_doc(EsStr)?.as_str())
+            Ok(self.next_doc(EsStr)?.to_string())
         }
 
         // Compound types:
index 125f815feda6fa6d902bea13a91be128cb1a603c..4acb8b807d594efcc0f6b8be67ec1165a93c9a9f 100644 (file)
@@ -106,7 +106,8 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
         }
     }
 
-    fn regions(&mut self, a: ty::Region, _: ty::Region) -> RelateResult<'tcx, ty::Region> {
+    fn regions(&mut self, a: &'tcx ty::Region, _: &'tcx ty::Region)
+               -> RelateResult<'tcx, &'tcx ty::Region> {
         Ok(a)
     }
 
index b4818f963b3ba76e4b6ae71f2ad4f381dbbd1616..5ce30484ede0027aab5c595d58a5ef906067ea86 100644 (file)
@@ -329,8 +329,8 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
         }
     }
 
-    fn fold_region(&mut self, r: ty::Region) -> ty::Region {
-        match r {
+    fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
+        match *r {
             // Never make variables for regions bound within the type itself,
             // nor for erased regions.
             ty::ReLateBound(..) |
index e06f7303acb2927ac99950a43b087c39f9c6c7ac..bf247acec5a2d31112c5a787ac2b7772ab029318 100644 (file)
@@ -79,7 +79,8 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
         }
     }
 
-    fn regions(&mut self, a: ty::Region, b: ty::Region) -> RelateResult<'tcx, ty::Region> {
+    fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region)
+               -> RelateResult<'tcx, &'tcx ty::Region> {
         debug!("{}.regions({:?}, {:?})",
                self.tag(),
                a,
index 1e053d6bfdab22b3f57d2c47c3a9135db7407692..9169d299e040b815876b8f75511b3a5981f06868 100644 (file)
@@ -99,7 +99,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     pub fn note_and_explain_region(self,
                                    err: &mut DiagnosticBuilder,
                                    prefix: &str,
-                                   region: ty::Region,
+                                   region: &'tcx ty::Region,
                                    suffix: &str) {
         fn item_scope_tag(item: &hir::Item) -> &'static str {
             match item.node {
@@ -120,7 +120,7 @@ fn explain_span<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
              Some(span))
         }
 
-        let (description, span) = match region {
+        let (description, span) = match *region {
             ty::ReScope(scope) => {
                 let new_string;
                 let unknown_scope = || {
@@ -405,12 +405,12 @@ fn new(sub_fr: ty::FreeRegion,
         }
 
         fn free_regions_from_same_fn<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                                                     sub: Region,
-                                                     sup: Region)
+                                                     sub: &'tcx Region,
+                                                     sup: &'tcx Region)
                                                      -> Option<FreeRegionsFromSameFn> {
             debug!("free_regions_from_same_fn(sub={:?}, sup={:?})", sub, sup);
             let (scope_id, fr1, fr2) = match (sub, sup) {
-                (ReFree(fr1), ReFree(fr2)) => {
+                (&ReFree(fr1), &ReFree(fr2)) => {
                     if fr1.scope != fr2.scope {
                         return None
                     }
@@ -602,7 +602,7 @@ fn expected_found_str<T: fmt::Display + TypeFoldable<'tcx>>(
     fn report_generic_bound_failure(&self,
                                     origin: SubregionOrigin<'tcx>,
                                     bound_kind: GenericKind<'tcx>,
-                                    sub: Region)
+                                    sub: &'tcx Region)
     {
         // FIXME: it would be better to report the first error message
         // with the span of the parameter itself, rather than the span
@@ -616,7 +616,7 @@ fn report_generic_bound_failure(&self,
                 format!("the associated type `{}`", p),
         };
 
-        let mut err = match sub {
+        let mut err = match *sub {
             ty::ReFree(ty::FreeRegion {bound_region: ty::BrNamed(..), ..}) => {
                 // Does the required lifetime have a nice name we can print?
                 let mut err = struct_span_err!(self.tcx.sess,
@@ -667,8 +667,8 @@ fn report_generic_bound_failure(&self,
 
     fn report_concrete_failure(&self,
                                origin: SubregionOrigin<'tcx>,
-                               sub: Region,
-                               sup: Region)
+                               sub: &'tcx Region,
+                               sup: &'tcx Region)
                                 -> DiagnosticBuilder<'tcx> {
         match origin {
             infer::Subtype(trace) => {
@@ -939,9 +939,9 @@ fn report_concrete_failure(&self,
     fn report_sub_sup_conflict(&self,
                                var_origin: RegionVariableOrigin,
                                sub_origin: SubregionOrigin<'tcx>,
-                               sub_region: Region,
+                               sub_region: &'tcx Region,
                                sup_origin: SubregionOrigin<'tcx>,
-                               sup_region: Region) {
+                               sup_region: &'tcx Region) {
         let mut err = self.report_inference_failure(var_origin);
 
         self.tcx.note_and_explain_region(&mut err,
index ecd9759c721b2f11062386e08b259c9249737f4c..beda734ee0d567b3baf332d1f5a3af7919c052c3 100644 (file)
@@ -83,8 +83,8 @@ fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> {
         self.infcx.tcx
     }
 
-    fn fold_region(&mut self, r: ty::Region) -> ty::Region {
-        match r {
+    fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
+        match *r {
             ty::ReEarlyBound(..) |
             ty::ReLateBound(..) => {
                 // leave bound regions alone
@@ -99,7 +99,7 @@ fn fold_region(&mut self, r: ty::Region) -> ty::Region {
             ty::ReEmpty |
             ty::ReErased => {
                 // replace all free regions with 'erased
-                ty::ReErased
+                self.tcx().mk_region(ty::ReErased)
             }
         }
     }
index 5dd85a31a9a2087effd0487c3e1393c0b058107c..a5709e1880801d8942d87f909a1de2d46e301308 100644 (file)
@@ -57,7 +57,8 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
         lattice::super_lattice_tys(self, a, b)
     }
 
-    fn regions(&mut self, a: ty::Region, b: ty::Region) -> RelateResult<'tcx, ty::Region> {
+    fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region)
+               -> RelateResult<'tcx, &'tcx ty::Region> {
         debug!("{}.regions({:?}, {:?})",
                self.tag(),
                a,
index 743d6135fbb5b555a9c61b151a023626a2325dd1..90be5e935baf16a2733ec7e28f4a447d00135599 100644 (file)
@@ -164,7 +164,7 @@ pub fn higher_ranked_match<T, U>(&mut self,
                 .map(|(&skol, &(br, ref regions))| {
                     let representative =
                         regions.iter()
-                               .filter(|r| !skol_resolution_map.contains_key(r))
+                               .filter(|&&r| !skol_resolution_map.contains_key(r))
                                .cloned()
                                .next()
                                .unwrap_or_else(|| { // [1]
@@ -268,9 +268,9 @@ fn generalize_region<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
                                              snapshot: &CombinedSnapshot,
                                              debruijn: ty::DebruijnIndex,
                                              new_vars: &[ty::RegionVid],
-                                             a_map: &FnvHashMap<ty::BoundRegion, ty::Region>,
-                                             r0: ty::Region)
-                                             -> ty::Region {
+                                             a_map: &FnvHashMap<ty::BoundRegion, &'tcx ty::Region>,
+                                             r0: &'tcx ty::Region)
+                                             -> &'tcx ty::Region {
             // Regions that pre-dated the LUB computation stay as they are.
             if !is_var_in_set(new_vars, r0) {
                 assert!(!r0.is_bound());
@@ -301,7 +301,7 @@ fn generalize_region<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
                     debug!("generalize_region(r0={:?}): \
                             replacing with {:?}, tainted={:?}",
                            r0, *a_br, tainted);
-                    return ty::ReLateBound(debruijn, *a_br);
+                    return infcx.tcx.mk_region(ty::ReLateBound(debruijn, *a_br));
                 }
             }
 
@@ -364,10 +364,12 @@ fn generalize_region<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
                                              snapshot: &CombinedSnapshot,
                                              debruijn: ty::DebruijnIndex,
                                              new_vars: &[ty::RegionVid],
-                                             a_map: &FnvHashMap<ty::BoundRegion, ty::Region>,
+                                             a_map: &FnvHashMap<ty::BoundRegion,
+                                                                &'tcx ty::Region>,
                                              a_vars: &[ty::RegionVid],
                                              b_vars: &[ty::RegionVid],
-                                             r0: ty::Region) -> ty::Region {
+                                             r0: &'tcx ty::Region)
+                                             -> &'tcx ty::Region {
             if !is_var_in_set(new_vars, r0) {
                 assert!(!r0.is_bound());
                 return r0;
@@ -419,7 +421,7 @@ fn generalize_region<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
 
             if a_r.is_some() && b_r.is_some() && only_new_vars {
                 // Related to exactly one bound variable from each fn:
-                return rev_lookup(span, a_map, a_r.unwrap());
+                return rev_lookup(infcx, span, a_map, a_r.unwrap());
             } else if a_r.is_none() && b_r.is_none() {
                 // Not related to bound variables from either fn:
                 assert!(!r0.is_bound());
@@ -430,13 +432,14 @@ fn generalize_region<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
             }
         }
 
-        fn rev_lookup(span: Span,
-                      a_map: &FnvHashMap<ty::BoundRegion, ty::Region>,
-                      r: ty::Region) -> ty::Region
+        fn rev_lookup<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+                                      span: Span,
+                                      a_map: &FnvHashMap<ty::BoundRegion, &'tcx ty::Region>,
+                                      r: &'tcx ty::Region) -> &'tcx ty::Region
         {
             for (a_br, a_r) in a_map {
                 if *a_r == r {
-                    return ty::ReLateBound(ty::DebruijnIndex::new(1), *a_br);
+                    return infcx.tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), *a_br));
                 }
             }
             span_bug!(
@@ -445,19 +448,21 @@ fn rev_lookup(span: Span,
                 r);
         }
 
-        fn fresh_bound_variable(infcx: &InferCtxt, debruijn: ty::DebruijnIndex) -> ty::Region {
+        fn fresh_bound_variable<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+                                                debruijn: ty::DebruijnIndex)
+                                                -> &'tcx ty::Region {
             infcx.region_vars.new_bound(debruijn)
         }
     }
 }
 
 fn var_ids<'a, 'gcx, 'tcx>(fields: &CombineFields<'a, 'gcx, 'tcx>,
-                           map: &FnvHashMap<ty::BoundRegion, ty::Region>)
+                           map: &FnvHashMap<ty::BoundRegion, &'tcx ty::Region>)
                            -> Vec<ty::RegionVid> {
     map.iter()
-       .map(|(_, r)| match *r {
+       .map(|(_, &r)| match *r {
            ty::ReVar(r) => { r }
-           r => {
+           _ => {
                span_bug!(
                    fields.trace.origin.span(),
                    "found non-region-vid: {:?}",
@@ -467,8 +472,8 @@ fn var_ids<'a, 'gcx, 'tcx>(fields: &CombineFields<'a, 'gcx, 'tcx>,
        .collect()
 }
 
-fn is_var_in_set(new_vars: &[ty::RegionVid], r: ty::Region) -> bool {
-    match r {
+fn is_var_in_set(new_vars: &[ty::RegionVid], r: &ty::Region) -> bool {
+    match *r {
         ty::ReVar(ref v) => new_vars.iter().any(|x| x == v),
         _ => false
     }
@@ -479,13 +484,13 @@ fn fold_regions_in<'a, 'gcx, 'tcx, T, F>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                                          mut fldr: F)
                                          -> T
     where T: TypeFoldable<'tcx>,
-          F: FnMut(ty::Region, ty::DebruijnIndex) -> ty::Region,
+          F: FnMut(&'tcx ty::Region, ty::DebruijnIndex) -> &'tcx ty::Region,
 {
     tcx.fold_regions(unbound_value, &mut false, |region, current_depth| {
         // we should only be encountering "escaping" late-bound regions here,
         // because the ones at the current level should have been replaced
         // with fresh variables
-        assert!(match region {
+        assert!(match *region {
             ty::ReLateBound(..) => false,
             _ => true
         });
@@ -497,9 +502,9 @@ fn fold_regions_in<'a, 'gcx, 'tcx, T, F>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     fn tainted_regions(&self,
                        snapshot: &CombinedSnapshot,
-                       r: ty::Region,
+                       r: &'tcx ty::Region,
                        directions: TaintDirections)
-                       -> FnvHashSet<ty::Region> {
+                       -> FnvHashSet<&'tcx ty::Region> {
         self.region_vars.tainted(&snapshot.region_vars_snapshot, r, directions)
     }
 
@@ -596,7 +601,7 @@ fn region_vars_confined_to_snapshot(&self,
     pub fn skolemize_late_bound_regions<T>(&self,
                                            binder: &ty::Binder<T>,
                                            snapshot: &CombinedSnapshot)
-                                           -> (T, SkolemizationMap)
+                                           -> (T, SkolemizationMap<'tcx>)
         where T : TypeFoldable<'tcx>
     {
         let (result, map) = self.tcx.replace_late_bound_regions(binder, |br| {
@@ -619,7 +624,7 @@ pub fn skolemize_late_bound_regions<T>(&self,
     pub fn leak_check(&self,
                       overly_polymorphic: bool,
                       span: Span,
-                      skol_map: &SkolemizationMap,
+                      skol_map: &SkolemizationMap<'tcx>,
                       snapshot: &CombinedSnapshot)
                       -> RelateResult<'tcx, ()>
     {
@@ -673,7 +678,7 @@ pub fn leak_check(&self,
             for &tainted_region in &incoming_taints {
                 // Each skolemized should only be relatable to itself
                 // or new variables:
-                match tainted_region {
+                match *tainted_region {
                     ty::ReVar(vid) => {
                         if new_vars.contains(&vid) {
                             warnings.extend(
@@ -742,7 +747,7 @@ pub fn leak_check(&self,
     /// to the depth of the predicate, in this case 1, so that the final
     /// predicate is `for<'a> &'a int : Clone`.
     pub fn plug_leaks<T>(&self,
-                         skol_map: SkolemizationMap,
+                         skol_map: SkolemizationMap<'tcx>,
                          snapshot: &CombinedSnapshot,
                          value: &T) -> T
         where T : TypeFoldable<'tcx>
@@ -755,7 +760,7 @@ pub fn plug_leaks<T>(&self,
         // region back to the `ty::BoundRegion` that it originally
         // represented. Because `leak_check` passed, we know that
         // these taint sets are mutually disjoint.
-        let inv_skol_map: FnvHashMap<ty::Region, ty::BoundRegion> =
+        let inv_skol_map: FnvHashMap<&'tcx ty::Region, ty::BoundRegion> =
             skol_map
             .iter()
             .flat_map(|(&skol_br, &skol)| {
@@ -794,7 +799,7 @@ pub fn plug_leaks<T>(&self,
                     // (which ought not to escape the snapshot, but we
                     // don't check that) or itself
                     assert!(
-                        match r {
+                        match *r {
                             ty::ReVar(_) => true,
                             ty::ReSkolemized(_, ref br1) => br == br1,
                             _ => false,
@@ -802,7 +807,8 @@ pub fn plug_leaks<T>(&self,
                         "leak-check would have us replace {:?} with {:?}",
                         r, br);
 
-                    ty::ReLateBound(ty::DebruijnIndex::new(current_depth - 1), br.clone())
+                    self.tcx.mk_region(ty::ReLateBound(
+                        ty::DebruijnIndex::new(current_depth - 1), br.clone()))
                 }
             }
         });
@@ -826,7 +832,7 @@ pub fn plug_leaks<T>(&self,
     ///
     /// Note: popping also occurs implicitly as part of `leak_check`.
     pub fn pop_skolemized(&self,
-                          skol_map: SkolemizationMap,
+                          skol_map: SkolemizationMap<'tcx>,
                           snapshot: &CombinedSnapshot)
     {
         debug!("pop_skolemized({:?})", skol_map);
index ad1b32ffaeb320ac18159277ee07d34df3a016c7..7d352be67d32b9c2a1dd716df90b74cbbaaec689 100644 (file)
@@ -57,7 +57,8 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
         lattice::super_lattice_tys(self, a, b)
     }
 
-    fn regions(&mut self, a: ty::Region, b: ty::Region) -> RelateResult<'tcx, ty::Region> {
+    fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region)
+               -> RelateResult<'tcx, &'tcx ty::Region> {
         debug!("{}.regions({:?}, {:?})",
                self.tag(),
                a,
index 1b65b5dae074850ad2d74951d9102f73849f4921..9854cd95397b79179bb300abb77078d016a34502 100644 (file)
@@ -177,7 +177,7 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
 
 /// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
 /// region that each late-bound region was replaced with.
-pub type SkolemizationMap = FnvHashMap<ty::BoundRegion, ty::Region>;
+pub type SkolemizationMap<'tcx> = FnvHashMap<ty::BoundRegion, &'tcx ty::Region>;
 
 /// Why did we require that the two types be related?
 ///
@@ -1123,8 +1123,8 @@ pub fn sub_poly_trait_refs(&self,
 
     pub fn sub_regions(&self,
                        origin: SubregionOrigin<'tcx>,
-                       a: ty::Region,
-                       b: ty::Region) {
+                       a: &'tcx ty::Region,
+                       b: &'tcx ty::Region) {
         debug!("sub_regions({:?} <: {:?})", a, b);
         self.region_vars.make_subregion(origin, a, b);
     }
@@ -1147,7 +1147,7 @@ pub fn equality_predicate(&self,
 
     pub fn region_outlives_predicate(&self,
                                      span: Span,
-                                     predicate: &ty::PolyRegionOutlivesPredicate)
+                                     predicate: &ty::PolyRegionOutlivesPredicate<'tcx>)
         -> UnitResult<'tcx>
     {
         self.commit_if_ok(|snapshot| {
@@ -1190,8 +1190,9 @@ pub fn next_float_var_id(&self) -> FloatVid {
             .new_key(None)
     }
 
-    pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region {
-        ty::ReVar(self.region_vars.new_region_var(origin))
+    pub fn next_region_var(&self, origin: RegionVariableOrigin)
+                           -> &'tcx ty::Region {
+        self.tcx.mk_region(ty::ReVar(self.region_vars.new_region_var(origin)))
     }
 
     /// Create a region inference variable for the given
@@ -1199,7 +1200,7 @@ pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region {
     pub fn region_var_for_def(&self,
                               span: Span,
                               def: &ty::RegionParameterDef)
-                              -> ty::Region {
+                              -> &'tcx ty::Region {
         self.next_region_var(EarlyBoundRegion(span, def.name))
     }
 
@@ -1245,7 +1246,7 @@ pub fn fresh_substs_for_item(&self,
         })
     }
 
-    pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> ty::Region {
+    pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> &'tcx ty::Region {
         self.region_vars.new_bound(debruijn)
     }
 
@@ -1530,7 +1531,7 @@ pub fn replace_late_bound_regions_with_fresh_var<T>(
         span: Span,
         lbrct: LateBoundRegionConversionTime,
         value: &ty::Binder<T>)
-        -> (T, FnvHashMap<ty::BoundRegion,ty::Region>)
+        -> (T, FnvHashMap<ty::BoundRegion, &'tcx ty::Region>)
         where T : TypeFoldable<'tcx>
     {
         self.tcx.replace_late_bound_regions(
@@ -1576,8 +1577,8 @@ pub fn match_poly_projection_predicate(&self,
     pub fn verify_generic_bound(&self,
                                 origin: SubregionOrigin<'tcx>,
                                 kind: GenericKind<'tcx>,
-                                a: ty::Region,
-                                bound: VerifyBound) {
+                                a: &'tcx ty::Region,
+                                bound: VerifyBound<'tcx>) {
         debug!("verify_generic_bound({:?}, {:?} <: {:?})",
                kind,
                a,
@@ -1666,7 +1667,7 @@ pub fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<CodeExtent> {
         self.tcx.region_maps.temporary_scope(rvalue_id)
     }
 
-    pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
+    pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture<'tcx>> {
         self.tables.borrow().upvar_capture_map.get(&upvar_id).cloned()
     }
 
index 905ad7c0faa236c45e18c6eb5d03cc64e3663441..1c64ebc0537ae7455f774eb2a0245042199f208d 100644 (file)
@@ -123,7 +123,7 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
 struct ConstraintGraph<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
     graph_name: String,
-    map: &'a FnvHashMap<Constraint, SubregionOrigin<'tcx>>,
+    map: &'a FnvHashMap<Constraint<'tcx>, SubregionOrigin<'tcx>>,
     node_ids: FnvHashMap<Node, usize>,
 }
 
@@ -135,8 +135,8 @@ enum Node {
 
 // type Edge = Constraint;
 #[derive(Clone, PartialEq, Eq, Debug, Copy)]
-enum Edge {
-    Constraint(Constraint),
+enum Edge<'tcx> {
+    Constraint(Constraint<'tcx>),
     EnclScope(CodeExtent, CodeExtent),
 }
 
@@ -177,7 +177,7 @@ fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
 
 impl<'a, 'gcx, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
     type Node = Node;
-    type Edge = Edge;
+    type Edge = Edge<'tcx>;
     fn graph_id(&self) -> dot::Id {
         dot::Id::new(&*self.graph_name).unwrap()
     }
@@ -214,11 +214,11 @@ fn constraint_to_nodes(c: &Constraint) -> (Node, Node) {
         Constraint::ConstrainVarSubVar(rv_1, rv_2) =>
             (Node::RegionVid(rv_1), Node::RegionVid(rv_2)),
         Constraint::ConstrainRegSubVar(r_1, rv_2) =>
-            (Node::Region(r_1), Node::RegionVid(rv_2)),
+            (Node::Region(*r_1), Node::RegionVid(rv_2)),
         Constraint::ConstrainVarSubReg(rv_1, r_2) =>
-            (Node::RegionVid(rv_1), Node::Region(r_2)),
+            (Node::RegionVid(rv_1), Node::Region(*r_2)),
         Constraint::ConstrainRegSubReg(r_1, r_2) =>
-            (Node::Region(r_1), Node::Region(r_2)),
+            (Node::Region(*r_1), Node::Region(*r_2)),
     }
 }
 
@@ -234,7 +234,7 @@ fn edge_to_nodes(e: &Edge) -> (Node, Node) {
 
 impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
     type Node = Node;
-    type Edge = Edge;
+    type Edge = Edge<'tcx>;
     fn nodes(&self) -> dot::Nodes<Node> {
         let mut set = FnvHashSet();
         for node in self.node_ids.keys() {
@@ -243,26 +243,26 @@ fn nodes(&self) -> dot::Nodes<Node> {
         debug!("constraint graph has {} nodes", set.len());
         set.into_iter().collect()
     }
-    fn edges(&self) -> dot::Edges<Edge> {
+    fn edges(&self) -> dot::Edges<Edge<'tcx>> {
         debug!("constraint graph has {} edges", self.map.len());
         let mut v: Vec<_> = self.map.keys().map(|e| Edge::Constraint(*e)).collect();
         self.tcx.region_maps.each_encl_scope(|sub, sup| v.push(Edge::EnclScope(*sub, *sup)));
         debug!("region graph has {} edges", v.len());
         Cow::Owned(v)
     }
-    fn source(&self, edge: &Edge) -> Node {
+    fn source(&self, edge: &Edge<'tcx>) -> Node {
         let (n1, _) = edge_to_nodes(edge);
         debug!("edge {:?} has source {:?}", edge, n1);
         n1
     }
-    fn target(&self, edge: &Edge) -> Node {
+    fn target(&self, edge: &Edge<'tcx>) -> Node {
         let (_, n2) = edge_to_nodes(edge);
         debug!("edge {:?} has target {:?}", edge, n2);
         n2
     }
 }
 
-pub type ConstraintMap<'tcx> = FnvHashMap<Constraint, SubregionOrigin<'tcx>>;
+pub type ConstraintMap<'tcx> = FnvHashMap<Constraint<'tcx>, SubregionOrigin<'tcx>>;
 
 fn dump_region_constraints_to<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                                               map: &ConstraintMap<'tcx>,
index d3b4afa2cee7915caa98b010a4b792d8713ea5df..b3693ae1e21ad86378859fa9fc92ce428de236f6 100644 (file)
 
 // A constraint that influences the inference process.
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
-pub enum Constraint {
+pub enum Constraint<'tcx> {
     // One region variable is subregion of another
     ConstrainVarSubVar(RegionVid, RegionVid),
 
     // Concrete region is subregion of region variable
-    ConstrainRegSubVar(Region, RegionVid),
+    ConstrainRegSubVar(&'tcx Region, RegionVid),
 
     // Region variable is subregion of concrete region. This does not
     // directly affect inference, but instead is checked after
     // inference is complete.
-    ConstrainVarSubReg(RegionVid, Region),
+    ConstrainVarSubReg(RegionVid, &'tcx Region),
 
     // A constraint where neither side is a variable. This does not
     // directly affect inference, but instead is checked after
     // inference is complete.
-    ConstrainRegSubReg(Region, Region),
+    ConstrainRegSubReg(&'tcx Region, &'tcx Region),
 }
 
 // VerifyGenericBound(T, _, R, RS): The parameter type `T` (or
@@ -66,8 +66,8 @@ pub enum Constraint {
 pub struct Verify<'tcx> {
     kind: GenericKind<'tcx>,
     origin: SubregionOrigin<'tcx>,
-    region: Region,
-    bound: VerifyBound,
+    region: &'tcx Region,
+    bound: VerifyBound<'tcx>,
 }
 
 #[derive(Copy, Clone, PartialEq, Eq)]
@@ -80,36 +80,36 @@ pub enum GenericKind<'tcx> {
 // particular region (let's call it `'min`) meets some bound.
 // The bound is described the by the following grammar:
 #[derive(Debug)]
-pub enum VerifyBound {
+pub enum VerifyBound<'tcx> {
     // B = exists {R} --> some 'r in {R} must outlive 'min
     //
     // Put another way, the subject value is known to outlive all
     // regions in {R}, so if any of those outlives 'min, then the
     // bound is met.
-    AnyRegion(Vec<Region>),
+    AnyRegion(Vec<&'tcx Region>),
 
     // B = forall {R} --> all 'r in {R} must outlive 'min
     //
     // Put another way, the subject value is known to outlive some
     // region in {R}, so if all of those outlives 'min, then the bound
     // is met.
-    AllRegions(Vec<Region>),
+    AllRegions(Vec<&'tcx Region>),
 
     // B = exists {B} --> 'min must meet some bound b in {B}
-    AnyBound(Vec<VerifyBound>),
+    AnyBound(Vec<VerifyBound<'tcx>>),
 
     // B = forall {B} --> 'min must meet all bounds b in {B}
-    AllBounds(Vec<VerifyBound>),
+    AllBounds(Vec<VerifyBound<'tcx>>),
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
-pub struct TwoRegions {
-    a: Region,
-    b: Region,
+pub struct TwoRegions<'tcx> {
+    a: &'tcx Region,
+    b: &'tcx Region,
 }
 
 #[derive(Copy, Clone, PartialEq)]
-pub enum UndoLogEntry {
+pub enum UndoLogEntry<'tcx> {
     /// Pushed when we start a snapshot.
     OpenSnapshot,
 
@@ -122,7 +122,7 @@ pub enum UndoLogEntry {
     AddVar(RegionVid),
 
     /// We added the given `constraint`
-    AddConstraint(Constraint),
+    AddConstraint(Constraint<'tcx>),
 
     /// We added the given `verify`
     AddVerify(usize),
@@ -131,7 +131,7 @@ pub enum UndoLogEntry {
     AddGiven(ty::FreeRegion, ty::RegionVid),
 
     /// We added a GLB/LUB "combinaton variable"
-    AddCombination(CombineMapType, TwoRegions),
+    AddCombination(CombineMapType, TwoRegions<'tcx>),
 
     /// During skolemization, we sometimes purge entries from the undo
     /// log in a kind of minisnapshot (unlike other snapshots, this
@@ -153,13 +153,13 @@ pub enum RegionResolutionError<'tcx> {
     /// `ConcreteFailure(o, a, b)`:
     ///
     /// `o` requires that `a <= b`, but this does not hold
-    ConcreteFailure(SubregionOrigin<'tcx>, Region, Region),
+    ConcreteFailure(SubregionOrigin<'tcx>, &'tcx Region, &'tcx Region),
 
     /// `GenericBoundFailure(p, s, a)
     ///
     /// The parameter/associated-type `p` must be known to outlive the lifetime
     /// `a` (but none of the known bounds are sufficient).
-    GenericBoundFailure(SubregionOrigin<'tcx>, GenericKind<'tcx>, Region),
+    GenericBoundFailure(SubregionOrigin<'tcx>, GenericKind<'tcx>, &'tcx Region),
 
     /// `SubSupConflict(v, sub_origin, sub_r, sup_origin, sup_r)`:
     ///
@@ -168,9 +168,9 @@ pub enum RegionResolutionError<'tcx> {
     /// `sub_r <= sup_r` does not hold.
     SubSupConflict(RegionVariableOrigin,
                    SubregionOrigin<'tcx>,
-                   Region,
+                   &'tcx Region,
                    SubregionOrigin<'tcx>,
-                   Region),
+                   &'tcx Region),
 
     /// For subsets of `ConcreteFailure` and `SubSupConflict`, we can derive
     /// more specific errors message by suggesting to the user where they
@@ -182,7 +182,7 @@ pub enum RegionResolutionError<'tcx> {
 
 #[derive(Clone, Debug)]
 pub enum ProcessedErrorOrigin<'tcx> {
-    ConcreteFailure(SubregionOrigin<'tcx>, Region, Region),
+    ConcreteFailure(SubregionOrigin<'tcx>, &'tcx Region, &'tcx Region),
     VariableFailure(RegionVariableOrigin),
 }
 
@@ -213,7 +213,7 @@ pub fn push(&mut self, other: BoundRegion) {
     }
 }
 
-pub type CombineMap = FnvHashMap<TwoRegions, RegionVid>;
+pub type CombineMap<'tcx> = FnvHashMap<TwoRegions<'tcx>, RegionVid>;
 
 pub struct RegionVarBindings<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
@@ -222,7 +222,7 @@ pub struct RegionVarBindings<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     // Constraints of the form `A <= B` introduced by the region
     // checker.  Here at least one of `A` and `B` must be a region
     // variable.
-    constraints: RefCell<FnvHashMap<Constraint, SubregionOrigin<'tcx>>>,
+    constraints: RefCell<FnvHashMap<Constraint<'tcx>, SubregionOrigin<'tcx>>>,
 
     // A "verify" is something that we need to verify after inference is
     // done, but which does not directly affect inference in any way.
@@ -250,8 +250,8 @@ pub struct RegionVarBindings<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     // a bit of a hack but seems to work.
     givens: RefCell<FnvHashSet<(ty::FreeRegion, ty::RegionVid)>>,
 
-    lubs: RefCell<CombineMap>,
-    glbs: RefCell<CombineMap>,
+    lubs: RefCell<CombineMap<'tcx>>,
+    glbs: RefCell<CombineMap<'tcx>>,
     skolemization_count: Cell<u32>,
     bound_count: Cell<u32>,
 
@@ -264,12 +264,12 @@ pub struct RegionVarBindings<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     // otherwise we end up adding entries for things like the lower
     // bound on a variable and so forth, which can never be rolled
     // back.
-    undo_log: RefCell<Vec<UndoLogEntry>>,
+    undo_log: RefCell<Vec<UndoLogEntry<'tcx>>>,
     unification_table: RefCell<UnificationTable<ty::RegionVid>>,
 
     // This contains the results of inference.  It begins as an empty
     // option and only acquires a value after inference is complete.
-    values: RefCell<Option<Vec<VarValue>>>,
+    values: RefCell<Option<Vec<VarValue<'tcx>>>>,
 }
 
 pub struct RegionSnapshot {
@@ -303,14 +303,14 @@ pub fn both() -> Self {
     }
 }
 
-struct TaintSet {
+struct TaintSet<'tcx> {
     directions: TaintDirections,
-    regions: FnvHashSet<ty::Region>
+    regions: FnvHashSet<&'tcx ty::Region>
 }
 
-impl TaintSet {
+impl<'a, 'gcx, 'tcx> TaintSet<'tcx> {
     fn new(directions: TaintDirections,
-           initial_region: ty::Region)
+           initial_region: &'tcx ty::Region)
            -> Self {
         let mut regions = FnvHashSet();
         regions.insert(initial_region);
@@ -318,8 +318,9 @@ fn new(directions: TaintDirections,
     }
 
     fn fixed_point(&mut self,
-                   undo_log: &[UndoLogEntry],
-                   verifys: &[Verify]) {
+                   tcx: TyCtxt<'a, 'gcx, 'tcx>,
+                   undo_log: &[UndoLogEntry<'tcx>],
+                   verifys: &[Verify<'tcx>]) {
         let mut prev_len = 0;
         while prev_len < self.len() {
             debug!("tainted: prev_len = {:?} new_len = {:?}",
@@ -330,19 +331,21 @@ fn fixed_point(&mut self,
             for undo_entry in undo_log {
                 match undo_entry {
                     &AddConstraint(ConstrainVarSubVar(a, b)) => {
-                        self.add_edge(ReVar(a), ReVar(b));
+                        self.add_edge(tcx.mk_region(ReVar(a)),
+                                      tcx.mk_region(ReVar(b)));
                     }
                     &AddConstraint(ConstrainRegSubVar(a, b)) => {
-                        self.add_edge(a, ReVar(b));
+                        self.add_edge(a, tcx.mk_region(ReVar(b)));
                     }
                     &AddConstraint(ConstrainVarSubReg(a, b)) => {
-                        self.add_edge(ReVar(a), b);
+                        self.add_edge(tcx.mk_region(ReVar(a)), b);
                     }
                     &AddConstraint(ConstrainRegSubReg(a, b)) => {
                         self.add_edge(a, b);
                     }
                     &AddGiven(a, b) => {
-                        self.add_edge(ReFree(a), ReVar(b));
+                        self.add_edge(tcx.mk_region(ReFree(a)),
+                                      tcx.mk_region(ReVar(b)));
                     }
                     &AddVerify(i) => {
                         verifys[i].bound.for_each_region(&mut |b| {
@@ -359,7 +362,7 @@ fn fixed_point(&mut self,
         }
     }
 
-    fn into_set(self) -> FnvHashSet<ty::Region> {
+    fn into_set(self) -> FnvHashSet<&'tcx ty::Region> {
         self.regions
     }
 
@@ -368,8 +371,8 @@ fn len(&self) -> usize {
     }
 
     fn add_edge(&mut self,
-                source: ty::Region,
-                target: ty::Region) {
+                source: &'tcx ty::Region,
+                target: &'tcx ty::Region) {
         if self.directions.incoming {
             if self.regions.contains(&target) {
                 self.regions.insert(source);
@@ -450,7 +453,7 @@ pub fn rollback_to(&self, snapshot: RegionSnapshot) {
             .rollback_to(snapshot.region_snapshot);
     }
 
-    pub fn rollback_undo_entry(&self, undo_entry: UndoLogEntry) {
+    pub fn rollback_undo_entry(&self, undo_entry: UndoLogEntry<'tcx>) {
         match undo_entry {
             OpenSnapshot => {
                 panic!("Failure to observe stack discipline");
@@ -529,13 +532,14 @@ pub fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin {
     /// The `snapshot` argument to this function is not really used;
     /// it's just there to make it explicit which snapshot bounds the
     /// skolemized region that results. It should always be the top-most snapshot.
-    pub fn push_skolemized(&self, br: ty::BoundRegion, snapshot: &RegionSnapshot) -> Region {
+    pub fn push_skolemized(&self, br: ty::BoundRegion, snapshot: &RegionSnapshot)
+                           -> &'tcx Region {
         assert!(self.in_snapshot());
         assert!(self.undo_log.borrow()[snapshot.length] == OpenSnapshot);
 
         let sc = self.skolemization_count.get();
         self.skolemization_count.set(sc + 1);
-        ReSkolemized(ty::SkolemizedRegionVid { index: sc }, br)
+        self.tcx.mk_region(ReSkolemized(ty::SkolemizedRegionVid { index: sc }, br))
     }
 
     /// Removes all the edges to/from the skolemized regions that are
@@ -543,7 +547,7 @@ pub fn push_skolemized(&self, br: ty::BoundRegion, snapshot: &RegionSnapshot) ->
     /// completes to remove all trace of the skolemized regions
     /// created in that time.
     pub fn pop_skolemized(&self,
-                          skols: &FnvHashSet<ty::Region>,
+                          skols: &FnvHashSet<&'tcx ty::Region>,
                           snapshot: &RegionSnapshot) {
         debug!("pop_skolemized_regions(skols={:?})", skols);
 
@@ -566,7 +570,7 @@ pub fn pop_skolemized(&self,
                 skols.len());
         debug_assert! {
             skols.iter()
-                 .all(|k| match *k {
+                 .all(|&k| match *k {
                      ty::ReSkolemized(index, _) =>
                          index.index >= first_to_pop &&
                          index.index < last_to_pop,
@@ -597,9 +601,9 @@ pub fn pop_skolemized(&self,
         self.skolemization_count.set(snapshot.skolemization_count);
         return;
 
-        fn kill_constraint(skols: &FnvHashSet<ty::Region>,
-                           undo_entry: &UndoLogEntry)
-                           -> bool {
+        fn kill_constraint<'tcx>(skols: &FnvHashSet<&'tcx ty::Region>,
+                                 undo_entry: &UndoLogEntry<'tcx>)
+                                 -> bool {
             match undo_entry {
                 &AddConstraint(ConstrainVarSubVar(_, _)) =>
                     false,
@@ -626,7 +630,7 @@ fn kill_constraint(skols: &FnvHashSet<ty::Region>,
 
     }
 
-    pub fn new_bound(&self, debruijn: ty::DebruijnIndex) -> Region {
+    pub fn new_bound(&self, debruijn: ty::DebruijnIndex) -> &'tcx Region {
         // Creates a fresh bound variable for use in GLB computations.
         // See discussion of GLB computation in the large comment at
         // the top of this file for more details.
@@ -652,14 +656,14 @@ pub fn new_bound(&self, debruijn: ty::DebruijnIndex) -> Region {
             bug!("rollover in RegionInference new_bound()");
         }
 
-        ReLateBound(debruijn, BrFresh(sc))
+        self.tcx.mk_region(ReLateBound(debruijn, BrFresh(sc)))
     }
 
     fn values_are_none(&self) -> bool {
         self.values.borrow().is_none()
     }
 
-    fn add_constraint(&self, constraint: Constraint, origin: SubregionOrigin<'tcx>) {
+    fn add_constraint(&self, constraint: Constraint<'tcx>, origin: SubregionOrigin<'tcx>) {
         // cannot add constraints once regions are resolved
         assert!(self.values_are_none());
 
@@ -704,20 +708,26 @@ pub fn add_given(&self, sub: ty::FreeRegion, sup: ty::RegionVid) {
         }
     }
 
-    pub fn make_eqregion(&self, origin: SubregionOrigin<'tcx>, sub: Region, sup: Region) {
+    pub fn make_eqregion(&self,
+                         origin: SubregionOrigin<'tcx>,
+                         sub: &'tcx Region,
+                         sup: &'tcx Region) {
         if sub != sup {
             // Eventually, it would be nice to add direct support for
             // equating regions.
             self.make_subregion(origin.clone(), sub, sup);
             self.make_subregion(origin, sup, sub);
 
-            if let (ty::ReVar(sub), ty::ReVar(sup)) = (sub, sup) {
+            if let (ty::ReVar(sub), ty::ReVar(sup)) = (*sub, *sup) {
                 self.unification_table.borrow_mut().union(sub, sup);
             }
         }
     }
 
-    pub fn make_subregion(&self, origin: SubregionOrigin<'tcx>, sub: Region, sup: Region) {
+    pub fn make_subregion(&self,
+                          origin: SubregionOrigin<'tcx>,
+                          sub: &'tcx Region,
+                          sup: &'tcx Region) {
         // cannot add constraints once regions are resolved
         assert!(self.values_are_none());
 
@@ -727,26 +737,26 @@ pub fn make_subregion(&self, origin: SubregionOrigin<'tcx>, sub: Region, sup: Re
                origin);
 
         match (sub, sup) {
-            (ReEarlyBound(..), _) |
-            (ReLateBound(..), _) |
-            (_, ReEarlyBound(..)) |
-            (_, ReLateBound(..)) => {
+            (&ReEarlyBound(..), _) |
+            (&ReLateBound(..), _) |
+            (_, &ReEarlyBound(..)) |
+            (_, &ReLateBound(..)) => {
                 span_bug!(origin.span(),
                           "cannot relate bound region: {:?} <= {:?}",
                           sub,
                           sup);
             }
-            (_, ReStatic) => {
+            (_, &ReStatic) => {
                 // all regions are subregions of static, so we can ignore this
             }
-            (ReVar(sub_id), ReVar(sup_id)) => {
+            (&ReVar(sub_id), &ReVar(sup_id)) => {
                 self.add_constraint(ConstrainVarSubVar(sub_id, sup_id), origin);
             }
-            (r, ReVar(sup_id)) => {
-                self.add_constraint(ConstrainRegSubVar(r, sup_id), origin);
+            (_, &ReVar(sup_id)) => {
+                self.add_constraint(ConstrainRegSubVar(sub, sup_id), origin);
             }
-            (ReVar(sub_id), r) => {
-                self.add_constraint(ConstrainVarSubReg(sub_id, r), origin);
+            (&ReVar(sub_id), _) => {
+                self.add_constraint(ConstrainVarSubReg(sub_id, sup), origin);
             }
             _ => {
                 self.add_constraint(ConstrainRegSubReg(sub, sup), origin);
@@ -758,8 +768,8 @@ pub fn make_subregion(&self, origin: SubregionOrigin<'tcx>, sub: Region, sup: Re
     pub fn verify_generic_bound(&self,
                                 origin: SubregionOrigin<'tcx>,
                                 kind: GenericKind<'tcx>,
-                                sub: Region,
-                                bound: VerifyBound) {
+                                sub: &'tcx Region,
+                                bound: VerifyBound<'tcx>) {
         self.add_verify(Verify {
             kind: kind,
             origin: origin,
@@ -768,29 +778,43 @@ pub fn verify_generic_bound(&self,
         });
     }
 
-    pub fn lub_regions(&self, origin: SubregionOrigin<'tcx>, a: Region, b: Region) -> Region {
+    pub fn lub_regions(&self,
+                       origin: SubregionOrigin<'tcx>,
+                       a: &'tcx Region,
+                       b: &'tcx Region)
+                       -> &'tcx Region {
         // cannot add constraints once regions are resolved
         assert!(self.values_are_none());
 
         debug!("RegionVarBindings: lub_regions({:?}, {:?})", a, b);
-        if a == ty::ReStatic || b == ty::ReStatic {
-            ReStatic // nothing lives longer than static
-        } else if a == b {
-            a // LUB(a,a) = a
-        } else {
-            self.combine_vars(Lub, a, b, origin.clone(), |this, old_r, new_r| {
-                this.make_subregion(origin.clone(), old_r, new_r)
-            })
+        match (a, b) {
+            (r @ &ReStatic, _) | (_, r @ &ReStatic) => {
+                r // nothing lives longer than static
+            }
+
+            _ if a == b => {
+                a // LUB(a,a) = a
+            }
+
+            _ => {
+                self.combine_vars(Lub, a, b, origin.clone(), |this, old_r, new_r| {
+                    this.make_subregion(origin.clone(), old_r, new_r)
+                })
+            }
         }
     }
 
-    pub fn glb_regions(&self, origin: SubregionOrigin<'tcx>, a: Region, b: Region) -> Region {
+    pub fn glb_regions(&self,
+                       origin: SubregionOrigin<'tcx>,
+                       a: &'tcx Region,
+                       b: &'tcx Region)
+                       -> &'tcx Region {
         // cannot add constraints once regions are resolved
         assert!(self.values_are_none());
 
         debug!("RegionVarBindings: glb_regions({:?}, {:?})", a, b);
         match (a, b) {
-            (ReStatic, r) | (r, ReStatic) => {
+            (&ReStatic, r) | (r, &ReStatic) => {
                 r // static lives longer than everything else
             }
 
@@ -806,7 +830,7 @@ pub fn glb_regions(&self, origin: SubregionOrigin<'tcx>, a: Region, b: Region) -
         }
     }
 
-    pub fn resolve_var(&self, rid: RegionVid) -> ty::Region {
+    pub fn resolve_var(&self, rid: RegionVid) -> &'tcx ty::Region {
         match *self.values.borrow() {
             None => {
                 span_bug!((*self.var_origins.borrow())[rid.index as usize].span(),
@@ -814,18 +838,19 @@ pub fn resolve_var(&self, rid: RegionVid) -> ty::Region {
                            been computed!")
             }
             Some(ref values) => {
-                let r = lookup(values, rid);
+                let r = lookup(self.tcx, values, rid);
                 debug!("resolve_var({:?}) = {:?}", rid, r);
                 r
             }
         }
     }
 
-    pub fn opportunistic_resolve_var(&self, rid: RegionVid) -> ty::Region {
-        ty::ReVar(self.unification_table.borrow_mut().find_value(rid).min_vid)
+    pub fn opportunistic_resolve_var(&self, rid: RegionVid) -> &'tcx ty::Region {
+        let vid = self.unification_table.borrow_mut().find_value(rid).min_vid;
+        self.tcx.mk_region(ty::ReVar(vid))
     }
 
-    fn combine_map(&self, t: CombineMapType) -> &RefCell<CombineMap> {
+    fn combine_map(&self, t: CombineMapType) -> &RefCell<CombineMap<'tcx>> {
         match t {
             Glb => &self.glbs,
             Lub => &self.lubs,
@@ -834,26 +859,26 @@ fn combine_map(&self, t: CombineMapType) -> &RefCell<CombineMap> {
 
     pub fn combine_vars<F>(&self,
                            t: CombineMapType,
-                           a: Region,
-                           b: Region,
+                           a: &'tcx Region,
+                           b: &'tcx Region,
                            origin: SubregionOrigin<'tcx>,
                            mut relate: F)
-                           -> Region
-        where F: FnMut(&RegionVarBindings<'a, 'gcx, 'tcx>, Region, Region)
+                           -> &'tcx Region
+        where F: FnMut(&RegionVarBindings<'a, 'gcx, 'tcx>, &'tcx Region, &'tcx Region)
     {
         let vars = TwoRegions { a: a, b: b };
         if let Some(&c) = self.combine_map(t).borrow().get(&vars) {
-            return ReVar(c);
+            return self.tcx.mk_region(ReVar(c));
         }
         let c = self.new_region_var(MiscVariable(origin.span()));
         self.combine_map(t).borrow_mut().insert(vars, c);
         if self.in_snapshot() {
             self.undo_log.borrow_mut().push(AddCombination(t, vars));
         }
-        relate(self, a, ReVar(c));
-        relate(self, b, ReVar(c));
+        relate(self, a, self.tcx.mk_region(ReVar(c)));
+        relate(self, b, self.tcx.mk_region(ReVar(c)));
         debug!("combine_vars() c={:?}", c);
-        ReVar(c)
+        self.tcx.mk_region(ReVar(c))
     }
 
     pub fn vars_created_since_snapshot(&self, mark: &RegionSnapshot) -> Vec<RegionVid> {
@@ -878,9 +903,9 @@ pub fn vars_created_since_snapshot(&self, mark: &RegionSnapshot) -> Vec<RegionVi
     /// related to other regions.
     pub fn tainted(&self,
                    mark: &RegionSnapshot,
-                   r0: Region,
+                   r0: &'tcx Region,
                    directions: TaintDirections)
-                   -> FnvHashSet<ty::Region> {
+                   -> FnvHashSet<&'tcx ty::Region> {
         debug!("tainted(mark={:?}, r0={:?}, directions={:?})",
                mark, r0, directions);
 
@@ -888,7 +913,8 @@ pub fn tainted(&self,
         // edges and add any new regions we find to result_set.  This
         // is not a terribly efficient implementation.
         let mut taint_set = TaintSet::new(directions, r0);
-        taint_set.fixed_point(&self.undo_log.borrow()[mark.length..],
+        taint_set.fixed_point(self.tcx,
+                              &self.undo_log.borrow()[mark.length..],
                               &self.verifys.borrow());
         debug!("tainted: result={:?}", taint_set.regions);
         return taint_set.into_set();
@@ -910,26 +936,30 @@ pub fn resolve_regions(&self,
         errors
     }
 
-    fn lub_concrete_regions(&self, free_regions: &FreeRegionMap, a: Region, b: Region) -> Region {
+    fn lub_concrete_regions(&self,
+                            free_regions: &FreeRegionMap,
+                            a: &'tcx Region,
+                            b: &'tcx Region)
+                            -> &'tcx Region {
         match (a, b) {
-            (ReLateBound(..), _) |
-            (_, ReLateBound(..)) |
-            (ReEarlyBound(..), _) |
-            (_, ReEarlyBound(..)) |
-            (ReErased, _) |
-            (_, ReErased) => {
+            (&ReLateBound(..), _) |
+            (_, &ReLateBound(..)) |
+            (&ReEarlyBound(..), _) |
+            (_, &ReEarlyBound(..)) |
+            (&ReErased, _) |
+            (_, &ReErased) => {
                 bug!("cannot relate region: LUB({:?}, {:?})", a, b);
             }
 
-            (ReStatic, _) | (_, ReStatic) => {
-                ReStatic // nothing lives longer than static
+            (r @ &ReStatic, _) | (_, r @ &ReStatic) => {
+                r // nothing lives longer than static
             }
 
-            (ReEmpty, r) | (r, ReEmpty) => {
+            (&ReEmpty, r) | (r, &ReEmpty) => {
                 r // everything lives longer than empty
             }
 
-            (ReVar(v_id), _) | (_, ReVar(v_id)) => {
+            (&ReVar(v_id), _) | (_, &ReVar(v_id)) => {
                 span_bug!((*self.var_origins.borrow())[v_id.index as usize].span(),
                           "lub_concrete_regions invoked with non-concrete \
                            regions: {:?}, {:?}",
@@ -937,9 +967,8 @@ fn lub_concrete_regions(&self, free_regions: &FreeRegionMap, a: Region, b: Regio
                           b);
             }
 
-            (ReFree(ref fr), ReScope(s_id)) |
-            (ReScope(s_id), ReFree(ref fr)) => {
-                let f = ReFree(*fr);
+            (&ReFree(fr), &ReScope(s_id)) |
+            (&ReScope(s_id), &ReFree(fr)) => {
                 // A "free" region can be interpreted as "some region
                 // at least as big as the block fr.scope_id".  So, we can
                 // reasonably compare free regions and scopes:
@@ -949,33 +978,34 @@ fn lub_concrete_regions(&self, free_regions: &FreeRegionMap, a: Region, b: Regio
                     // if the free region's scope `fr.scope_id` is bigger than
                     // the scope region `s_id`, then the LUB is the free
                     // region itself:
-                    f
+                    self.tcx.mk_region(ReFree(fr))
                 } else {
                     // otherwise, we don't know what the free region is,
                     // so we must conservatively say the LUB is static:
-                    ReStatic
+                    self.tcx.mk_region(ReStatic)
                 }
             }
 
-            (ReScope(a_id), ReScope(b_id)) => {
+            (&ReScope(a_id), &ReScope(b_id)) => {
                 // The region corresponding to an outer block is a
                 // subtype of the region corresponding to an inner
                 // block.
-                ReScope(self.tcx.region_maps.nearest_common_ancestor(a_id, b_id))
+                self.tcx.mk_region(ReScope(
+                    self.tcx.region_maps.nearest_common_ancestor(a_id, b_id)))
             }
 
-            (ReFree(a_fr), ReFree(b_fr)) => {
-                free_regions.lub_free_regions(a_fr, b_fr)
+            (&ReFree(a_fr), &ReFree(b_fr)) => {
+                self.tcx.mk_region(free_regions.lub_free_regions(a_fr, b_fr))
             }
 
             // For these types, we cannot define any additional
             // relationship:
-            (ReSkolemized(..), _) |
-            (_, ReSkolemized(..)) => {
+            (&ReSkolemized(..), _) |
+            (_, &ReSkolemized(..)) => {
                 if a == b {
                     a
                 } else {
-                    ReStatic
+                    self.tcx.mk_region(ReStatic)
                 }
             }
         }
@@ -985,24 +1015,24 @@ fn lub_concrete_regions(&self, free_regions: &FreeRegionMap, a: Region, b: Regio
 // ______________________________________________________________________
 
 #[derive(Copy, Clone, Debug)]
-pub enum VarValue {
-    Value(Region),
+pub enum VarValue<'tcx> {
+    Value(&'tcx Region),
     ErrorValue,
 }
 
 struct RegionAndOrigin<'tcx> {
-    region: Region,
+    region: &'tcx Region,
     origin: SubregionOrigin<'tcx>,
 }
 
-type RegionGraph = graph::Graph<(), Constraint>;
+type RegionGraph<'tcx> = graph::Graph<(), Constraint<'tcx>>;
 
 impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
     fn infer_variable_values(&self,
                              free_regions: &FreeRegionMap,
                              errors: &mut Vec<RegionResolutionError<'tcx>>,
                              subject: ast::NodeId)
-                             -> Vec<VarValue> {
+                             -> Vec<VarValue<'tcx>> {
         let mut var_data = self.construct_var_data();
 
         // Dorky hack to cause `dump_constraints` to only get called
@@ -1020,9 +1050,9 @@ fn infer_variable_values(&self,
         var_data
     }
 
-    fn construct_var_data(&self) -> Vec<VarValue> {
+    fn construct_var_data(&self) -> Vec<VarValue<'tcx>> {
         (0..self.num_vars() as usize)
-            .map(|_| Value(ty::ReEmpty))
+            .map(|_| Value(self.tcx.mk_region(ty::ReEmpty)))
             .collect()
     }
 
@@ -1059,7 +1089,7 @@ fn expand_givens(&self, graph: &RegionGraph) {
         }
     }
 
-    fn expansion(&self, free_regions: &FreeRegionMap, var_values: &mut [VarValue]) {
+    fn expansion(&self, free_regions: &FreeRegionMap, var_values: &mut [VarValue<'tcx>]) {
         self.iterate_until_fixed_point("Expansion", |constraint, origin| {
             debug!("expansion: constraint={:?} origin={:?}",
                    constraint, origin);
@@ -1089,9 +1119,9 @@ fn expansion(&self, free_regions: &FreeRegionMap, var_values: &mut [VarValue]) {
 
     fn expand_node(&self,
                    free_regions: &FreeRegionMap,
-                   a_region: Region,
+                   a_region: &'tcx Region,
                    b_vid: RegionVid,
-                   b_data: &mut VarValue)
+                   b_data: &mut VarValue<'tcx>)
                    -> bool {
         debug!("expand_node({:?}, {:?} == {:?})",
                a_region,
@@ -1099,7 +1129,7 @@ fn expand_node(&self,
                b_data);
 
         // Check if this relationship is implied by a given.
-        match a_region {
+        match *a_region {
             ty::ReFree(fr) => {
                 if self.givens.borrow().contains(&(fr, b_vid)) {
                     debug!("given");
@@ -1136,7 +1166,7 @@ fn expand_node(&self,
     /// and check that they are satisfied.
     fn collect_errors(&self,
                       free_regions: &FreeRegionMap,
-                      var_data: &mut Vec<VarValue>,
+                      var_data: &mut Vec<VarValue<'tcx>>,
                       errors: &mut Vec<RegionResolutionError<'tcx>>) {
         let constraints = self.constraints.borrow();
         for (constraint, origin) in constraints.iter() {
@@ -1192,7 +1222,7 @@ fn collect_errors(&self,
 
         for verify in self.verifys.borrow().iter() {
             debug!("collect_errors: verify={:?}", verify);
-            let sub = normalize(var_data, verify.region);
+            let sub = normalize(self.tcx, var_data, verify.region);
             if verify.bound.is_met(self.tcx, free_regions, var_data, sub) {
                 continue;
             }
@@ -1213,8 +1243,8 @@ fn collect_errors(&self,
     /// and create a `RegionResolutionError` for each of them.
     fn collect_var_errors(&self,
                           free_regions: &FreeRegionMap,
-                          var_data: &[VarValue],
-                          graph: &RegionGraph,
+                          var_data: &[VarValue<'tcx>],
+                          graph: &RegionGraph<'tcx>,
                           errors: &mut Vec<RegionResolutionError<'tcx>>) {
         debug!("collect_var_errors");
 
@@ -1271,7 +1301,7 @@ fn collect_var_errors(&self,
         }
     }
 
-    fn construct_graph(&self) -> RegionGraph {
+    fn construct_graph(&self) -> RegionGraph<'tcx> {
         let num_vars = self.num_vars();
 
         let constraints = self.constraints.borrow();
@@ -1315,7 +1345,7 @@ fn construct_graph(&self) -> RegionGraph {
 
     fn collect_error_for_expanding_node(&self,
                                         free_regions: &FreeRegionMap,
-                                        graph: &RegionGraph,
+                                        graph: &RegionGraph<'tcx>,
                                         dup_vec: &mut [u32],
                                         node_idx: RegionVid,
                                         errors: &mut Vec<RegionResolutionError<'tcx>>) {
@@ -1339,9 +1369,9 @@ fn collect_error_for_expanding_node(&self,
         // the user will more likely get a specific suggestion.
         fn free_regions_first(a: &RegionAndOrigin, b: &RegionAndOrigin) -> Ordering {
             match (a.region, b.region) {
-                (ReFree(..), ReFree(..)) => Equal,
-                (ReFree(..), _) => Less,
-                (_, ReFree(..)) => Greater,
+                (&ReFree(..), &ReFree(..)) => Equal,
+                (&ReFree(..), _) => Less,
+                (_, &ReFree(..)) => Greater,
                 (_, _) => Equal,
             }
         }
@@ -1378,7 +1408,7 @@ fn free_regions_first(a: &RegionAndOrigin, b: &RegionAndOrigin) -> Ordering {
     }
 
     fn collect_concrete_regions(&self,
-                                graph: &RegionGraph,
+                                graph: &RegionGraph<'tcx>,
                                 orig_node_idx: RegionVid,
                                 dir: Direction,
                                 dup_vec: &mut [u32])
@@ -1423,7 +1453,7 @@ struct WalkState<'tcx> {
 
         fn process_edges<'a, 'gcx, 'tcx>(this: &RegionVarBindings<'a, 'gcx, 'tcx>,
                                          state: &mut WalkState<'tcx>,
-                                         graph: &RegionGraph,
+                                         graph: &RegionGraph<'tcx>,
                                          source_vid: RegionVid,
                                          dir: Direction) {
             debug!("process_edges(source_vid={:?}, dir={:?})", source_vid, dir);
@@ -1460,7 +1490,7 @@ fn process_edges<'a, 'gcx, 'tcx>(this: &RegionVarBindings<'a, 'gcx, 'tcx>,
     }
 
     fn iterate_until_fixed_point<F>(&self, tag: &str, mut body: F)
-        where F: FnMut(&Constraint, &SubregionOrigin<'tcx>) -> bool
+        where F: FnMut(&Constraint<'tcx>, &SubregionOrigin<'tcx>) -> bool
     {
         let mut iteration = 0;
         let mut changed = true;
@@ -1481,17 +1511,23 @@ fn iterate_until_fixed_point<F>(&self, tag: &str, mut body: F)
 
 }
 
-fn normalize(values: &Vec<VarValue>, r: ty::Region) -> ty::Region {
-    match r {
-        ty::ReVar(rid) => lookup(values, rid),
+fn normalize<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
+                             values: &Vec<VarValue<'tcx>>,
+                             r: &'tcx ty::Region)
+                             -> &'tcx ty::Region {
+    match *r {
+        ty::ReVar(rid) => lookup(tcx, values, rid),
         _ => r,
     }
 }
 
-fn lookup(values: &Vec<VarValue>, rid: ty::RegionVid) -> ty::Region {
+fn lookup<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
+                          values: &Vec<VarValue<'tcx>>,
+                          rid: ty::RegionVid)
+                          -> &'tcx ty::Region {
     match values[rid.index as usize] {
         Value(r) => r,
-        ErrorValue => ReStatic, // Previously reported error.
+        ErrorValue => tcx.mk_region(ReStatic), // Previously reported error.
     }
 }
 
@@ -1535,8 +1571,8 @@ pub fn to_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> VerifyBound {
-    fn for_each_region(&self, f: &mut FnMut(ty::Region)) {
+impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> {
+    fn for_each_region(&self, f: &mut FnMut(&'tcx ty::Region)) {
         match self {
             &VerifyBound::AnyRegion(ref rs) |
             &VerifyBound::AllRegions(ref rs) => for &r in rs {
@@ -1552,7 +1588,7 @@ fn for_each_region(&self, f: &mut FnMut(ty::Region)) {
 
     pub fn must_hold(&self) -> bool {
         match self {
-            &VerifyBound::AnyRegion(ref bs) => bs.contains(&ty::ReStatic),
+            &VerifyBound::AnyRegion(ref bs) => bs.contains(&&ty::ReStatic),
             &VerifyBound::AllRegions(ref bs) => bs.is_empty(),
             &VerifyBound::AnyBound(ref bs) => bs.iter().any(|b| b.must_hold()),
             &VerifyBound::AllBounds(ref bs) => bs.iter().all(|b| b.must_hold()),
@@ -1562,13 +1598,13 @@ pub fn must_hold(&self) -> bool {
     pub fn cannot_hold(&self) -> bool {
         match self {
             &VerifyBound::AnyRegion(ref bs) => bs.is_empty(),
-            &VerifyBound::AllRegions(ref bs) => bs.contains(&ty::ReEmpty),
+            &VerifyBound::AllRegions(ref bs) => bs.contains(&&ty::ReEmpty),
             &VerifyBound::AnyBound(ref bs) => bs.iter().all(|b| b.cannot_hold()),
             &VerifyBound::AllBounds(ref bs) => bs.iter().any(|b| b.cannot_hold()),
         }
     }
 
-    pub fn or(self, vb: VerifyBound) -> VerifyBound {
+    pub fn or(self, vb: VerifyBound<'tcx>) -> VerifyBound<'tcx> {
         if self.must_hold() || vb.cannot_hold() {
             self
         } else if self.cannot_hold() || vb.must_hold() {
@@ -1578,7 +1614,7 @@ pub fn or(self, vb: VerifyBound) -> VerifyBound {
         }
     }
 
-    pub fn and(self, vb: VerifyBound) -> VerifyBound {
+    pub fn and(self, vb: VerifyBound<'tcx>) -> VerifyBound<'tcx> {
         if self.must_hold() && vb.must_hold() {
             self
         } else if self.cannot_hold() && vb.cannot_hold() {
@@ -1590,18 +1626,18 @@ pub fn and(self, vb: VerifyBound) -> VerifyBound {
 
     fn is_met(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
               free_regions: &FreeRegionMap,
-              var_values: &Vec<VarValue>,
-              min: ty::Region)
+              var_values: &Vec<VarValue<'tcx>>,
+              min: &'tcx ty::Region)
               -> bool {
         match self {
             &VerifyBound::AnyRegion(ref rs) =>
                 rs.iter()
-                  .map(|&r| normalize(var_values, r))
+                  .map(|&r| normalize(tcx, var_values, r))
                   .any(|r| free_regions.is_subregion_of(tcx, min, r)),
 
             &VerifyBound::AllRegions(ref rs) =>
                 rs.iter()
-                  .map(|&r| normalize(var_values, r))
+                  .map(|&r| normalize(tcx, var_values, r))
                   .all(|r| free_regions.is_subregion_of(tcx, min, r)),
 
             &VerifyBound::AnyBound(ref bs) =>
index 5f550b427e21aed275e47d59357bbfdb9de613d8..357a03a2ffd7c214d4919169e76a363620fd2f46 100644 (file)
@@ -72,10 +72,10 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
         }
     }
 
-    fn fold_region(&mut self, r: ty::Region) -> ty::Region {
-        match r {
-          ty::ReVar(rid) => self.infcx.region_vars.opportunistic_resolve_var(rid),
-          _ => r,
+    fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
+        match *r {
+            ty::ReVar(rid) => self.infcx.region_vars.opportunistic_resolve_var(rid),
+            _ => r,
         }
     }
 }
@@ -138,10 +138,10 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
         }
     }
 
-    fn fold_region(&mut self, r: ty::Region) -> ty::Region {
-        match r {
-          ty::ReVar(rid) => self.infcx.region_vars.resolve_var(rid),
-          _ => r,
+    fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
+        match *r {
+            ty::ReVar(rid) => self.infcx.region_vars.resolve_var(rid),
+            _ => r,
         }
     }
 }
index 2f7f5254727db15d1f245be227498b046bc307fc..159de2faced574e5fb9817f6e03223768fc1233d 100644 (file)
@@ -107,7 +107,8 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
         }
     }
 
-    fn regions(&mut self, a: ty::Region, b: ty::Region) -> RelateResult<'tcx, ty::Region> {
+    fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region)
+               -> RelateResult<'tcx, &'tcx ty::Region> {
         debug!("{}.regions({:?}, {:?}) self.cause={:?}",
                self.tag(), a, b, self.fields.cause);
         // FIXME -- we have more fine-grained information available
index 48ea953cc1e8b05a137d32659ab11caa20bde3a8..1e4b2e9116fd27f67e5b344e947e683e9700c568 100644 (file)
@@ -27,6 +27,7 @@
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(collections)]
+#![feature(conservative_impl_trait)]
 #![feature(const_fn)]
 #![feature(core_intrinsics)]
 #![feature(enumset)]
index f0ddcdc07e1206beb5746685b0f7897d833cbb83..b2ee38741fcabc1927d01c0107a9a9317c4ef0ad 100644 (file)
 
 declare_lint! {
     pub TRANSMUTE_FROM_FN_ITEM_TYPES,
-    Warn,
+    Deny,
     "transmute from function item type to pointer-sized type erroneously allowed"
 }
 
index 9c06f0cca15666203a026c64a32393555c87a7de..0bab919a9ae3e4e384d219581321d41f4a522032 100644 (file)
@@ -601,7 +601,7 @@ fn with_lint_attrs<F>(&mut self,
             for (lint_id, level, span) in v {
                 let (now, now_source) = self.lints().get_level_source(lint_id);
                 if now == Forbid && level != Forbid {
-                    let lint_name = lint_id.as_str();
+                    let lint_name = lint_id.to_string();
                     let mut diag_builder = struct_span_err!(self.sess(), span, E0453,
                                                             "{}({}) overruled by outer forbid({})",
                                                             level.as_str(), lint_name,
@@ -1217,7 +1217,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         for &(lint, span, ref msg) in v {
             span_bug!(span,
                       "unprocessed lint {} at {}: {}",
-                      lint.as_str(), tcx.map.node_to_string(*id), *msg)
+                      lint.to_string(), tcx.map.node_to_string(*id), *msg)
         }
     }
 
@@ -1253,7 +1253,7 @@ pub fn check_ast_crate(sess: &Session, krate: &ast::Crate) {
     // in the iteration code.
     for (_, v) in sess.lints.borrow().iter() {
         for &(lint, span, ref msg) in v {
-            span_bug!(span, "unprocessed lint {}: {}", lint.as_str(), *msg)
+            span_bug!(span, "unprocessed lint {}: {}", lint.to_string(), *msg)
         }
     }
 }
index f34b14224f7797f0ad798cd4e045e294fdb5104c..0938086b000c037b1c22ac592ceb12deb8390c37 100644 (file)
@@ -263,7 +263,7 @@ pub fn of(lint: &'static Lint) -> LintId {
     }
 
     /// Get the name of the lint.
-    pub fn as_str(&self) -> String {
+    pub fn to_string(&self) -> String {
         self.lint.name_lower()
     }
 }
index 92e1b0681cc7e24eef7edfa61322e777e7481f83..b33bc520fe21622407561beccea2dab9e662dc30 100644 (file)
@@ -149,7 +149,7 @@ pub trait CrateStore<'tcx> {
     fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind;
     fn closure_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
                       -> ty::ClosureTy<'tcx>;
-    fn item_variances(&self, def: DefId) -> ty::ItemVariances;
+    fn item_variances(&self, def: DefId) -> Vec<ty::Variance>;
     fn repr_attrs(&self, def: DefId) -> Vec<attr::ReprAttr>;
     fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
                      -> Ty<'tcx>;
@@ -198,7 +198,6 @@ fn impl_or_trait_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
     fn is_default_impl(&self, impl_did: DefId) -> bool;
     fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool;
     fn is_foreign_item(&self, did: DefId) -> bool;
-    fn is_static_method(&self, did: DefId) -> bool;
     fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool;
     fn is_typedef(&self, did: DefId) -> bool;
 
@@ -329,7 +328,7 @@ fn visibility(&self, def: DefId) -> ty::Visibility { bug!("visibility") }
     fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind  { bug!("closure_kind") }
     fn closure_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
                       -> ty::ClosureTy<'tcx>  { bug!("closure_ty") }
-    fn item_variances(&self, def: DefId) -> ty::ItemVariances { bug!("item_variances") }
+    fn item_variances(&self, def: DefId) -> Vec<ty::Variance> { bug!("item_variances") }
     fn repr_attrs(&self, def: DefId) -> Vec<attr::ReprAttr> { bug!("repr_attrs") }
     fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
                      -> Ty<'tcx> { bug!("item_type") }
@@ -391,7 +390,6 @@ fn is_default_impl(&self, impl_did: DefId) -> bool { bug!("is_default_impl") }
     fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool
         { bug!("is_extern_item") }
     fn is_foreign_item(&self, did: DefId) -> bool { bug!("is_foreign_item") }
-    fn is_static_method(&self, did: DefId) -> bool { bug!("is_static_method") }
     fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { false }
     fn is_typedef(&self, did: DefId) -> bool { bug!("is_typedef") }
 
index 2a8594c59a83764c727862b7f3ff38684154d7e4..37366f38974a4bbc8c77a2e7bf93bacadd09468b 100644 (file)
@@ -95,7 +95,7 @@ fn lookup_and_handle_definition(&mut self, id: ast::NodeId) {
             Def::AssociatedTy(..) | Def::Method(_) | Def::AssociatedConst(_)
             if self.tcx.trait_of_item(def.def_id()).is_some() => {
                 if let Some(substs) = self.tcx.tables.borrow().item_substs.get(&id) {
-                    match substs.substs.types[0].sty {
+                    match substs.substs.type_at(0).sty {
                         TyEnum(tyid, _) | TyStruct(tyid, _) => {
                             self.check_def_id(tyid.did)
                         }
index 87463055a276a76748f939b8d59e2aaa51c6f50f..798702e6fd6571b5f70269576e641c335dbc4e1c 100644 (file)
@@ -76,7 +76,7 @@ fn borrow(&mut self,
               borrow_id: ast::NodeId,
               borrow_span: Span,
               cmt: mc::cmt<'tcx>,
-              loan_region: ty::Region,
+              loan_region: &'tcx ty::Region,
               bk: ty::BorrowKind,
               loan_cause: LoanCause);
 
@@ -301,11 +301,11 @@ fn walk_arg_patterns(&mut self,
         for arg in &decl.inputs {
             let arg_ty = return_if_err!(self.mc.infcx.node_ty(arg.pat.id));
 
-            let fn_body_scope = self.tcx().region_maps.node_extent(body.id);
+            let fn_body_scope_r = self.tcx().node_scope_region(body.id);
             let arg_cmt = self.mc.cat_rvalue(
                 arg.id,
                 arg.pat.span,
-                ty::ReScope(fn_body_scope), // Args live only as long as the fn body.
+                fn_body_scope_r, // Args live only as long as the fn body.
                 arg_ty);
 
             self.walk_irrefutable_pat(arg_cmt, &arg.pat);
@@ -352,7 +352,7 @@ fn mutate_expr(&mut self,
 
     fn borrow_expr(&mut self,
                    expr: &hir::Expr,
-                   r: ty::Region,
+                   r: &'tcx ty::Region,
                    bk: ty::BorrowKind,
                    cause: LoanCause) {
         debug!("borrow_expr(expr={:?}, r={:?}, bk={:?})",
@@ -431,7 +431,8 @@ pub fn walk_expr(&mut self, expr: &hir::Expr) {
 
             hir::ExprMatch(ref discr, ref arms, _) => {
                 let discr_cmt = return_if_err!(self.mc.cat_expr(&discr));
-                self.borrow_expr(&discr, ty::ReEmpty, ty::ImmBorrow, MatchDiscriminant);
+                let r = self.tcx().mk_region(ty::ReEmpty);
+                self.borrow_expr(&discr, r, ty::ImmBorrow, MatchDiscriminant);
 
                 // treatment of the discriminant is handled while walking the arms.
                 for arm in arms {
@@ -449,7 +450,7 @@ pub fn walk_expr(&mut self, expr: &hir::Expr) {
                 // make sure that the thing we are pointing out stays valid
                 // for the lifetime `scope_r` of the resulting ptr:
                 let expr_ty = return_if_err!(self.mc.infcx.node_ty(expr.id));
-                if let ty::TyRef(&r, _) = expr_ty.sty {
+                if let ty::TyRef(r, _) = expr_ty.sty {
                     let bk = ty::BorrowKind::from_mutbl(m);
                     self.borrow_expr(&base, r, bk, AddrOf);
                 }
@@ -557,7 +558,6 @@ fn walk_callee(&mut self, call: &hir::Expr, callee: &hir::Expr) {
         let callee_ty = return_if_err!(self.mc.infcx.expr_ty_adjusted(callee));
         debug!("walk_callee: callee={:?} callee_ty={:?}",
                callee, callee_ty);
-        let call_scope = self.tcx().region_maps.node_extent(call.id);
         match callee_ty.sty {
             ty::TyFnDef(..) | ty::TyFnPtr(_) => {
                 self.consume_expr(callee);
@@ -578,14 +578,16 @@ fn walk_callee(&mut self, call: &hir::Expr, callee: &hir::Expr) {
                     };
                 match overloaded_call_type {
                     FnMutOverloadedCall => {
+                        let call_scope_r = self.tcx().node_scope_region(call.id);
                         self.borrow_expr(callee,
-                                         ty::ReScope(call_scope),
+                                         call_scope_r,
                                          ty::MutBorrow,
                                          ClosureInvocation);
                     }
                     FnOverloadedCall => {
+                        let call_scope_r = self.tcx().node_scope_region(call.id);
                         self.borrow_expr(callee,
-                                         ty::ReScope(call_scope),
+                                         call_scope_r,
                                          ty::ImmBorrow,
                                          ClosureInvocation);
                     }
@@ -761,7 +763,7 @@ fn walk_autoderefs(&mut self,
                 };
                 let bk = ty::BorrowKind::from_mutbl(m);
                 self.delegate.borrow(expr.id, expr.span, cmt,
-                                     *r, bk, AutoRef);
+                                     r, bk, AutoRef);
             }
         }
     }
@@ -822,7 +824,7 @@ fn walk_autoref(&mut self,
                 self.delegate.borrow(expr.id,
                                      expr.span,
                                      cmt_base,
-                                     *r,
+                                     r,
                                      ty::BorrowKind::from_mutbl(m),
                                      AutoRef);
             }
@@ -835,7 +837,7 @@ fn walk_autoref(&mut self,
                 // Converting from a &T to *T (or &mut T to *mut T) is
                 // treated as borrowing it for the enclosing temporary
                 // scope.
-                let r = ty::ReScope(self.tcx().region_maps.node_extent(expr.id));
+                let r = self.tcx().node_scope_region(expr.id);
 
                 self.delegate.borrow(expr.id,
                                      expr.span,
@@ -890,7 +892,7 @@ fn walk_overloaded_operator(&mut self,
         // methods are implicitly autoref'd which sadly does not use
         // adjustments, so we must hardcode the borrow here.
 
-        let r = ty::ReScope(self.tcx().region_maps.node_extent(expr.id));
+        let r = self.tcx().node_scope_region(expr.id);
         let bk = ty::ImmBorrow;
 
         for &arg in &rhs {
@@ -979,7 +981,7 @@ fn walk_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &hir::Pat, match_mode: Mat
                 // It is also a borrow or copy/move of the value being matched.
                 match bmode {
                     hir::BindByRef(m) => {
-                        if let ty::TyRef(&r, _) = pat_ty.sty {
+                        if let ty::TyRef(r, _) = pat_ty.sty {
                             let bk = ty::BorrowKind::from_mutbl(m);
                             delegate.borrow(pat.id, pat.span, cmt_pat, r, bk, RefBinding);
                         }
index e4ce89767139a23157a2f29543d288f4ae0dd724..8193d062631c1f4be6309ffae1ad1813ef91f8df 100644 (file)
@@ -37,7 +37,7 @@ pub fn relate_free_regions_from_implied_bounds<'tcx>(&mut self,
         for implied_bound in implied_bounds {
             debug!("implied bound: {:?}", implied_bound);
             match *implied_bound {
-                ImpliedBound::RegionSubRegion(ty::ReFree(free_a), ty::ReFree(free_b)) => {
+                ImpliedBound::RegionSubRegion(&ty::ReFree(free_a), &ty::ReFree(free_b)) => {
                     self.relate_free_regions(free_a, free_b);
                 }
                 ImpliedBound::RegionSubRegion(..) |
@@ -65,9 +65,9 @@ pub fn relate_free_regions_from_predicates(&mut self,
                 }
                 ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r_a, r_b))) => {
                     match (r_a, r_b) {
-                        (ty::ReStatic, ty::ReFree(_)) => {},
-                        (ty::ReFree(fr_a), ty::ReStatic) => self.relate_to_static(fr_a),
-                        (ty::ReFree(fr_a), ty::ReFree(fr_b)) => {
+                        (&ty::ReStatic, &ty::ReFree(_)) => {},
+                        (&ty::ReFree(fr_a), &ty::ReStatic) => self.relate_to_static(fr_a),
+                        (&ty::ReFree(fr_a), &ty::ReFree(fr_b)) => {
                             // Record that `'a:'b`. Or, put another way, `'b <= 'a`.
                             self.relate_free_regions(fr_b, fr_a);
                         }
@@ -122,26 +122,26 @@ pub fn lub_free_regions(&self, fr_a: FreeRegion, fr_b: FreeRegion) -> Region {
     /// inference* and sadly the logic is somewhat duplicated with the code in infer.rs.
     pub fn is_subregion_of(&self,
                            tcx: TyCtxt,
-                           sub_region: ty::Region,
-                           super_region: ty::Region)
+                           sub_region: &ty::Region,
+                           super_region: &ty::Region)
                            -> bool {
         let result = sub_region == super_region || {
             match (sub_region, super_region) {
-                (ty::ReEmpty, _) |
-                (_, ty::ReStatic) =>
+                (&ty::ReEmpty, _) |
+                (_, &ty::ReStatic) =>
                     true,
 
-                (ty::ReScope(sub_scope), ty::ReScope(super_scope)) =>
+                (&ty::ReScope(sub_scope), &ty::ReScope(super_scope)) =>
                     tcx.region_maps.is_subscope_of(sub_scope, super_scope),
 
-                (ty::ReScope(sub_scope), ty::ReFree(fr)) =>
+                (&ty::ReScope(sub_scope), &ty::ReFree(fr)) =>
                     tcx.region_maps.is_subscope_of(sub_scope, fr.scope) ||
                     self.is_static(fr),
 
-                (ty::ReFree(sub_fr), ty::ReFree(super_fr)) =>
+                (&ty::ReFree(sub_fr), &ty::ReFree(super_fr)) =>
                     self.sub_free_region(sub_fr, super_fr),
 
-                (ty::ReStatic, ty::ReFree(sup_fr)) =>
+                (&ty::ReStatic, &ty::ReFree(sup_fr)) =>
                     self.is_static(sup_fr),
 
                 _ =>
index 676e456dcea94e2ecaf96fe984b50d1dec27dd47..a74bdb02044dee92127b18420480469de2b241d6 100644 (file)
 
 #[derive(Clone, PartialEq)]
 pub enum Categorization<'tcx> {
-    Rvalue(ty::Region),                    // temporary val, argument is its scope
+    Rvalue(&'tcx ty::Region),                    // temporary val, argument is its scope
     StaticItem,
     Upvar(Upvar),                          // upvar referenced by closure env
     Local(ast::NodeId),                    // local variable
-    Deref(cmt<'tcx>, usize, PointerKind),  // deref of a ptr
+    Deref(cmt<'tcx>, usize, PointerKind<'tcx>),  // deref of a ptr
     Interior(cmt<'tcx>, InteriorKind),     // something interior: field, tuple, etc
     Downcast(cmt<'tcx>, DefId),            // selects a particular enum variant (*1)
 
@@ -110,18 +110,18 @@ pub struct Upvar {
 
 // different kinds of pointers:
 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
-pub enum PointerKind {
+pub enum PointerKind<'tcx> {
     /// `Box<T>`
     Unique,
 
     /// `&T`
-    BorrowedPtr(ty::BorrowKind, ty::Region),
+    BorrowedPtr(ty::BorrowKind, &'tcx ty::Region),
 
     /// `*T`
     UnsafePtr(hir::Mutability),
 
     /// Implicit deref of the `&T` that results from an overloaded index `[]`.
-    Implicit(ty::BorrowKind, ty::Region),
+    Implicit(ty::BorrowKind, &'tcx ty::Region),
 }
 
 // We use the term "interior" to mean "something reachable from the
@@ -198,8 +198,8 @@ pub struct cmt_<'tcx> {
 // We pun on *T to mean both actual deref of a ptr as well
 // as accessing of components:
 #[derive(Copy, Clone)]
-pub enum deref_kind {
-    deref_ptr(PointerKind),
+pub enum deref_kind<'tcx> {
+    deref_ptr(PointerKind<'tcx>),
     deref_interior(InteriorKind),
 }
 
@@ -216,7 +216,7 @@ fn deref_kind(t: Ty, context: DerefKindContext) -> McResult<deref_kind> {
 
         ty::TyRef(r, mt) => {
             let kind = ty::BorrowKind::from_mutbl(mt.mutbl);
-            Ok(deref_ptr(BorrowedPtr(kind, *r)))
+            Ok(deref_ptr(BorrowedPtr(kind, r)))
         }
 
         ty::TyRawPtr(ref mt) => {
@@ -767,13 +767,13 @@ fn env_deref(&self,
         };
 
         // Region of environment pointer
-        let env_region = ty::ReFree(ty::FreeRegion {
+        let env_region = self.tcx().mk_region(ty::ReFree(ty::FreeRegion {
             // The environment of a closure is guaranteed to
             // outlive any bindings introduced in the body of the
             // closure itself.
             scope: self.tcx().region_maps.item_extent(fn_body_id),
             bound_region: ty::BrEnv
-        });
+        }));
 
         let env_ptr = BorrowedPtr(env_borrow_kind, env_region);
 
@@ -817,11 +817,11 @@ fn env_deref(&self,
 
     /// Returns the lifetime of a temporary created by expr with id `id`.
     /// This could be `'static` if `id` is part of a constant expression.
-    pub fn temporary_scope(&self, id: ast::NodeId) -> ty::Region {
-        match self.infcx.temporary_scope(id) {
+    pub fn temporary_scope(&self, id: ast::NodeId) -> &'tcx ty::Region {
+        self.tcx().mk_region(match self.infcx.temporary_scope(id) {
             Some(scope) => ty::ReScope(scope),
             None => ty::ReStatic
-        }
+        })
     }
 
     pub fn cat_rvalue_node(&self,
@@ -845,7 +845,7 @@ pub fn cat_rvalue_node(&self,
         let re = if qualif.intersects(ConstQualif::NON_STATIC_BORROWS) {
             self.temporary_scope(id)
         } else {
-            ty::ReStatic
+            self.tcx().mk_region(ty::ReStatic)
         };
         let ret = self.cat_rvalue(id, span, re, expr_ty);
         debug!("cat_rvalue_node ret {:?}", ret);
@@ -855,7 +855,7 @@ pub fn cat_rvalue_node(&self,
     pub fn cat_rvalue(&self,
                       cmt_id: ast::NodeId,
                       span: Span,
-                      temp_scope: ty::Region,
+                      temp_scope: &'tcx ty::Region,
                       expr_ty: Ty<'tcx>) -> cmt<'tcx> {
         let ret = Rc::new(cmt_ {
             id:cmt_id,
@@ -1480,7 +1480,7 @@ pub fn ptr_sigil(ptr: PointerKind) -> &'static str {
     }
 }
 
-impl fmt::Debug for PointerKind {
+impl<'tcx> fmt::Debug for PointerKind<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             Unique => write!(f, "Box"),
index 6f0ad087dc5898ad72b259f267274654ac5c467a..faf2f7dae08c5a9793eb8ba303e02e8f88e146ee 100644 (file)
@@ -237,7 +237,7 @@ pub fn span(&self, region_maps: &RegionMaps, ast_map: &ast_map::Map) -> Option<S
                         // (This is the special case aluded to in the
                         // doc-comment for this method)
                         let stmt_span = blk.stmts[r.first_statement_index as usize].span;
-                        Some(Span { lo: stmt_span.hi, ..blk.span })
+                        Some(Span { lo: stmt_span.hi, hi: blk.span.hi, expn_id: stmt_span.expn_id })
                     }
                 }
             }
index 8369a6c39d54d658a825aaa2eb4842e5c9aa06f2..ebe4050022153bee2cb2db306778f25eee1bd967 100644 (file)
@@ -89,9 +89,12 @@ struct LifetimeContext<'a, 'tcx: 'a> {
 
 #[derive(PartialEq, Debug)]
 enum ScopeChain<'a> {
-    /// EarlyScope(['a, 'b, ...], s) extends s with early-bound
-    /// lifetimes.
-    EarlyScope(&'a [hir::LifetimeDef], Scope<'a>),
+    /// EarlyScope(['a, 'b, ...], start, s) extends s with early-bound
+    /// lifetimes, with consecutive parameter indices from `start`.
+    /// That is, 'a has index `start`, 'b has index `start + 1`, etc.
+    /// Indices before `start` correspond to other generic parameters
+    /// of a parent item (trait/impl of a method), or `Self` in traits.
+    EarlyScope(&'a [hir::LifetimeDef], u32, Scope<'a>),
     /// LateScope(['a, 'b, ...], s) extends s with late-bound
     /// lifetimes introduced by the declaration binder_id.
     LateScope(&'a [hir::LifetimeDef], Scope<'a>),
@@ -157,7 +160,12 @@ fn visit_item(&mut self, item: &hir::Item) {
                 hir::ItemImpl(_, _, ref generics, _, _, _) => {
                     // These kinds of items have only early bound lifetime parameters.
                     let lifetimes = &generics.lifetimes;
-                    this.with(EarlyScope(lifetimes, &ROOT_SCOPE), |old_scope, this| {
+                    let start = if let hir::ItemTrait(..) = item.node {
+                        1 // Self comes before lifetimes
+                    } else {
+                        0
+                    };
+                    this.with(EarlyScope(lifetimes, start, &ROOT_SCOPE), |old_scope, this| {
                         this.check_lifetime_defs(old_scope, lifetimes);
                         intravisit::walk_item(this, item);
                     });
@@ -461,7 +469,7 @@ fn check_if_label_shadows_lifetime<'a>(sess: &'a Session,
                 FnScope { s, .. } => { scope = s; }
                 RootScope => { return; }
 
-                EarlyScope(lifetimes, s) |
+                EarlyScope(lifetimes, _, s) |
                 LateScope(lifetimes, s) => {
                     for lifetime_def in lifetimes {
                         // FIXME (#24278): non-hygienic comparison
@@ -566,8 +574,24 @@ fn visit_early_late<F>(&mut self,
                     .cloned()
                     .partition(|l| self.map.late_bound.contains_key(&l.lifetime.id));
 
+        // Find the start of nested early scopes, e.g. in methods.
+        let mut start = 0;
+        if let EarlyScope(..) = *self.scope {
+            let parent = self.hir_map.expect_item(self.hir_map.get_parent(fn_id));
+            if let hir::ItemTrait(..) = parent.node {
+                start += 1; // Self comes first.
+            }
+            match parent.node {
+                hir::ItemTrait(_, ref generics, _, _) |
+                hir::ItemImpl(_, _, ref generics, _, _, _) => {
+                    start += generics.lifetimes.len() + generics.ty_params.len();
+                }
+                _ => {}
+            }
+        }
+
         let this = self;
-        this.with(EarlyScope(&early, this.scope), move |old_scope, this| {
+        this.with(EarlyScope(&early, start as u32, this.scope), move |old_scope, this| {
             this.with(LateScope(&late, this.scope), move |_, this| {
                 this.check_lifetime_defs(old_scope, &generics.lifetimes);
                 walk(this);
@@ -597,19 +621,11 @@ fn resolve_lifetime_ref(&mut self, lifetime_ref: &hir::Lifetime) {
                     break;
                 }
 
-                EarlyScope(lifetimes, s) => {
+                EarlyScope(lifetimes, start, s) => {
                     match search_lifetimes(lifetimes, lifetime_ref) {
-                        Some((mut index, lifetime_def)) => {
-                            // Adjust for nested early scopes, e.g. in methods.
-                            let mut parent = s;
-                            while let EarlyScope(lifetimes, s) = *parent {
-                                index += lifetimes.len() as u32;
-                                parent = s;
-                            }
-                            assert_eq!(*parent, RootScope);
-
+                        Some((index, lifetime_def)) => {
                             let decl_id = lifetime_def.id;
-                            let def = DefEarlyBoundRegion(index, decl_id);
+                            let def = DefEarlyBoundRegion(start + index, decl_id);
                             self.insert_lifetime(lifetime_ref, def);
                             return;
                         }
@@ -671,7 +687,7 @@ fn resolve_free_lifetime_ref(&mut self,
                     break;
                 }
 
-                EarlyScope(lifetimes, s) |
+                EarlyScope(lifetimes, _, s) |
                 LateScope(lifetimes, s) => {
                     search_result = search_lifetimes(lifetimes, lifetime_ref);
                     if search_result.is_some() {
@@ -767,7 +783,7 @@ fn check_lifetime_def_for_shadowing(&self,
                     return;
                 }
 
-                EarlyScope(lifetimes, s) |
+                EarlyScope(lifetimes, _, s) |
                 LateScope(lifetimes, s) => {
                     if let Some((_, lifetime_def)) = search_lifetimes(lifetimes, lifetime) {
                         signal_shadowing_problem(
index f511d820fac5878f5f05ee51e79b4b0efb491d36..8145c0aae3f74cb344303a5084468f455897943c 100644 (file)
@@ -911,7 +911,7 @@ pub enum Rvalue<'tcx> {
     Repeat(Operand<'tcx>, TypedConstVal<'tcx>),
 
     /// &x or &mut x
-    Ref(Region, BorrowKind, Lvalue<'tcx>),
+    Ref(&'tcx Region, BorrowKind, Lvalue<'tcx>),
 
     /// length of a [X] or [X;n] value
     Len(Lvalue<'tcx>),
@@ -1239,3 +1239,14 @@ impl<'a, 'b>  GraphSuccessors<'b> for Mir<'a> {
     type Item = BasicBlock;
     type Iter = IntoIter<BasicBlock>;
 }
+
+#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Ord, PartialOrd)]
+pub struct Location {
+    /// the location is within this block
+    pub block: BasicBlock,
+
+    /// the location is the start of the this statement; or, if `statement_index`
+    /// == num-statements, then the start of the terminator.
+    pub statement_index: usize,
+}
+
index cf91229f1c713afa07c4baf714e51d161baa4df7..76e5f8598c1c549c6da3843e7275d293aa9a1eae 100644 (file)
@@ -145,8 +145,7 @@ pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Opti
             }
             &Rvalue::Ref(reg, bk, ref lv) => {
                 let lv_ty = lv.ty(mir, tcx).to_ty(tcx);
-                Some(tcx.mk_ref(
-                    tcx.mk_region(reg),
+                Some(tcx.mk_ref(reg,
                     ty::TypeAndMut {
                         ty: lv_ty,
                         mutbl: bk.to_mutbl_lossy()
index ead8de86dbae4094f555d09068fde43057d6a0cf..2771880735c27a71866ba304563c910d99fef0c0 100644 (file)
@@ -103,60 +103,70 @@ fn visit_visibility_scope_data(&mut self,
 
             fn visit_statement(&mut self,
                                block: BasicBlock,
-                               statement: & $($mutability)* Statement<'tcx>) {
-                self.super_statement(block, statement);
+                               statement: & $($mutability)* Statement<'tcx>,
+                               location: Location) {
+                self.super_statement(block, statement, location);
             }
 
             fn visit_assign(&mut self,
                             block: BasicBlock,
                             lvalue: & $($mutability)* Lvalue<'tcx>,
-                            rvalue: & $($mutability)* Rvalue<'tcx>) {
-                self.super_assign(block, lvalue, rvalue);
+                            rvalue: & $($mutability)* Rvalue<'tcx>,
+                            location: Location) {
+                self.super_assign(block, lvalue, rvalue, location);
             }
 
             fn visit_terminator(&mut self,
                                 block: BasicBlock,
-                                terminator: & $($mutability)* Terminator<'tcx>) {
-                self.super_terminator(block, terminator);
+                                terminator: & $($mutability)* Terminator<'tcx>,
+                                location: Location) {
+                self.super_terminator(block, terminator, location);
             }
 
             fn visit_terminator_kind(&mut self,
                                      block: BasicBlock,
-                                     kind: & $($mutability)* TerminatorKind<'tcx>) {
-                self.super_terminator_kind(block, kind);
+                                     kind: & $($mutability)* TerminatorKind<'tcx>,
+                                     location: Location) {
+                self.super_terminator_kind(block, kind, location);
             }
 
             fn visit_assert_message(&mut self,
-                                    msg: & $($mutability)* AssertMessage<'tcx>) {
-                self.super_assert_message(msg);
+                                    msg: & $($mutability)* AssertMessage<'tcx>,
+                                    location: Location) {
+                self.super_assert_message(msg, location);
             }
 
             fn visit_rvalue(&mut self,
-                            rvalue: & $($mutability)* Rvalue<'tcx>) {
-                self.super_rvalue(rvalue);
+                            rvalue: & $($mutability)* Rvalue<'tcx>,
+                            location: Location) {
+                self.super_rvalue(rvalue, location);
             }
 
             fn visit_operand(&mut self,
-                             operand: & $($mutability)* Operand<'tcx>) {
-                self.super_operand(operand);
+                             operand: & $($mutability)* Operand<'tcx>,
+                             location: Location) {
+                self.super_operand(operand, location);
             }
 
             fn visit_lvalue(&mut self,
                             lvalue: & $($mutability)* Lvalue<'tcx>,
-                            context: LvalueContext) {
-                self.super_lvalue(lvalue, context);
+                            context: LvalueContext,
+                            location: Location) {
+                self.super_lvalue(lvalue, context, location);
             }
 
             fn visit_projection(&mut self,
                                 lvalue: & $($mutability)* LvalueProjection<'tcx>,
-                                context: LvalueContext) {
-                self.super_projection(lvalue, context);
+                                context: LvalueContext,
+                                location: Location) {
+                self.super_projection(lvalue, context, location);
             }
 
             fn visit_projection_elem(&mut self,
                                      lvalue: & $($mutability)* LvalueElem<'tcx>,
-                                     context: LvalueContext) {
-                self.super_projection_elem(lvalue, context);
+                                     context: LvalueContext,
+                                     location: Location) {
+                self.super_projection_elem(lvalue, context, location);
             }
 
             fn visit_branch(&mut self,
@@ -166,17 +176,20 @@ fn visit_branch(&mut self,
             }
 
             fn visit_constant(&mut self,
-                              constant: & $($mutability)* Constant<'tcx>) {
-                self.super_constant(constant);
+                              constant: & $($mutability)* Constant<'tcx>,
+                              location: Location) {
+                self.super_constant(constant, location);
             }
 
             fn visit_literal(&mut self,
-                             literal: & $($mutability)* Literal<'tcx>) {
-                self.super_literal(literal);
+                             literal: & $($mutability)* Literal<'tcx>,
+                             location: Location) {
+                self.super_literal(literal, location);
             }
 
             fn visit_def_id(&mut self,
-                            def_id: & $($mutability)* DefId) {
+                            def_id: & $($mutability)* DefId,
+                            _: Location) {
                 self.super_def_id(def_id);
             }
 
@@ -206,18 +219,21 @@ fn visit_closure_substs(&mut self,
             }
 
             fn visit_const_val(&mut self,
-                               const_val: & $($mutability)* ConstVal) {
+                               const_val: & $($mutability)* ConstVal,
+                               _: Location) {
                 self.super_const_val(const_val);
             }
 
             fn visit_const_usize(&mut self,
-                                 const_usize: & $($mutability)* ConstUsize) {
+                                 const_usize: & $($mutability)* ConstUsize,
+                                 _: Location) {
                 self.super_const_usize(const_usize);
             }
 
             fn visit_typed_const_val(&mut self,
-                                     val: & $($mutability)* TypedConstVal<'tcx>) {
-                self.super_typed_const_val(val);
+                                     val: & $($mutability)* TypedConstVal<'tcx>,
+                                     location: Location) {
+                self.super_typed_const_val(val, location);
             }
 
             fn visit_var_decl(&mut self,
@@ -280,12 +296,16 @@ fn super_basic_block_data(&mut self,
                     is_cleanup: _
                 } = *data;
 
+                let mut index = 0;
                 for statement in statements {
-                    self.visit_statement(block, statement);
+                    let location = Location { block: block, statement_index: index };
+                    self.visit_statement(block, statement, location);
+                    index += 1;
                 }
 
                 if let Some(ref $($mutability)* terminator) = *terminator {
-                    self.visit_terminator(block, terminator);
+                    let location = Location { block: block, statement_index: index };
+                    self.visit_terminator(block, terminator, location);
                 }
             }
 
@@ -304,7 +324,8 @@ fn super_visibility_scope_data(&mut self,
 
             fn super_statement(&mut self,
                                block: BasicBlock,
-                               statement: & $($mutability)* Statement<'tcx>) {
+                               statement: & $($mutability)* Statement<'tcx>,
+                               location: Location) {
                 let Statement {
                     ref $($mutability)* source_info,
                     ref $($mutability)* kind,
@@ -314,16 +335,16 @@ fn super_statement(&mut self,
                 match *kind {
                     StatementKind::Assign(ref $($mutability)* lvalue,
                                           ref $($mutability)* rvalue) => {
-                        self.visit_assign(block, lvalue, rvalue);
+                        self.visit_assign(block, lvalue, rvalue, location);
                     }
                     StatementKind::SetDiscriminant{ ref $($mutability)* lvalue, .. } => {
-                        self.visit_lvalue(lvalue, LvalueContext::Store);
+                        self.visit_lvalue(lvalue, LvalueContext::Store, location);
                     }
                     StatementKind::StorageLive(ref $($mutability)* lvalue) => {
-                        self.visit_lvalue(lvalue, LvalueContext::StorageLive);
+                        self.visit_lvalue(lvalue, LvalueContext::StorageLive, location);
                     }
                     StatementKind::StorageDead(ref $($mutability)* lvalue) => {
-                        self.visit_lvalue(lvalue, LvalueContext::StorageDead);
+                        self.visit_lvalue(lvalue, LvalueContext::StorageDead, location);
                     }
                 }
             }
@@ -331,26 +352,29 @@ fn super_statement(&mut self,
             fn super_assign(&mut self,
                             _block: BasicBlock,
                             lvalue: &$($mutability)* Lvalue<'tcx>,
-                            rvalue: &$($mutability)* Rvalue<'tcx>) {
-                self.visit_lvalue(lvalue, LvalueContext::Store);
-                self.visit_rvalue(rvalue);
+                            rvalue: &$($mutability)* Rvalue<'tcx>,
+                            location: Location) {
+                self.visit_lvalue(lvalue, LvalueContext::Store, location);
+                self.visit_rvalue(rvalue, location);
             }
 
             fn super_terminator(&mut self,
                                 block: BasicBlock,
-                                terminator: &$($mutability)* Terminator<'tcx>) {
+                                terminator: &$($mutability)* Terminator<'tcx>,
+                                location: Location) {
                 let Terminator {
                     ref $($mutability)* source_info,
                     ref $($mutability)* kind,
                 } = *terminator;
 
                 self.visit_source_info(source_info);
-                self.visit_terminator_kind(block, kind);
+                self.visit_terminator_kind(block, kind, location);
             }
 
             fn super_terminator_kind(&mut self,
                                      block: BasicBlock,
-                                     kind: & $($mutability)* TerminatorKind<'tcx>) {
+                                     kind: & $($mutability)* TerminatorKind<'tcx>,
+                                     source_location: Location) {
                 match *kind {
                     TerminatorKind::Goto { target } => {
                         self.visit_branch(block, target);
@@ -358,7 +382,7 @@ fn super_terminator_kind(&mut self,
 
                     TerminatorKind::If { ref $($mutability)* cond,
                                          ref $($mutability)* targets } => {
-                        self.visit_operand(cond);
+                        self.visit_operand(cond, source_location);
                         for &target in targets.as_slice() {
                             self.visit_branch(block, target);
                         }
@@ -367,7 +391,7 @@ fn super_terminator_kind(&mut self,
                     TerminatorKind::Switch { ref $($mutability)* discr,
                                              adt_def: _,
                                              ref targets } => {
-                        self.visit_lvalue(discr, LvalueContext::Inspect);
+                        self.visit_lvalue(discr, LvalueContext::Inspect, source_location);
                         for &target in targets {
                             self.visit_branch(block, target);
                         }
@@ -377,10 +401,10 @@ fn super_terminator_kind(&mut self,
                                                 ref $($mutability)* switch_ty,
                                                 ref $($mutability)* values,
                                                 ref targets } => {
-                        self.visit_lvalue(discr, LvalueContext::Inspect);
+                        self.visit_lvalue(discr, LvalueContext::Inspect, source_location);
                         self.visit_ty(switch_ty);
                         for value in values {
-                            self.visit_const_val(value);
+                            self.visit_const_val(value, source_location);
                         }
                         for &target in targets {
                             self.visit_branch(block, target);
@@ -395,7 +419,7 @@ fn super_terminator_kind(&mut self,
                     TerminatorKind::Drop { ref $($mutability)* location,
                                            target,
                                            unwind } => {
-                        self.visit_lvalue(location, LvalueContext::Drop);
+                        self.visit_lvalue(location, LvalueContext::Drop, source_location);
                         self.visit_branch(block, target);
                         unwind.map(|t| self.visit_branch(block, t));
                     }
@@ -404,8 +428,8 @@ fn super_terminator_kind(&mut self,
                                                      ref $($mutability)* value,
                                                      target,
                                                      unwind } => {
-                        self.visit_lvalue(location, LvalueContext::Drop);
-                        self.visit_operand(value);
+                        self.visit_lvalue(location, LvalueContext::Drop, source_location);
+                        self.visit_operand(value, source_location);
                         self.visit_branch(block, target);
                         unwind.map(|t| self.visit_branch(block, t));
                     }
@@ -414,12 +438,12 @@ fn super_terminator_kind(&mut self,
                                            ref $($mutability)* args,
                                            ref $($mutability)* destination,
                                            cleanup } => {
-                        self.visit_operand(func);
+                        self.visit_operand(func, source_location);
                         for arg in args {
-                            self.visit_operand(arg);
+                            self.visit_operand(arg, source_location);
                         }
                         if let Some((ref $($mutability)* destination, target)) = *destination {
-                            self.visit_lvalue(destination, LvalueContext::Call);
+                            self.visit_lvalue(destination, LvalueContext::Call, source_location);
                             self.visit_branch(block, target);
                         }
                         cleanup.map(|t| self.visit_branch(block, t));
@@ -430,8 +454,8 @@ fn super_terminator_kind(&mut self,
                                              ref $($mutability)* msg,
                                              target,
                                              cleanup } => {
-                        self.visit_operand(cond);
-                        self.visit_assert_message(msg);
+                        self.visit_operand(cond, source_location);
+                        self.visit_assert_message(msg, source_location);
                         self.visit_branch(block, target);
                         cleanup.map(|t| self.visit_branch(block, t));
                     }
@@ -439,47 +463,49 @@ fn super_terminator_kind(&mut self,
             }
 
             fn super_assert_message(&mut self,
-                                    msg: & $($mutability)* AssertMessage<'tcx>) {
+                                    msg: & $($mutability)* AssertMessage<'tcx>,
+                                    location: Location) {
                 match *msg {
                     AssertMessage::BoundsCheck {
                         ref $($mutability)* len,
                         ref $($mutability)* index
                     } => {
-                        self.visit_operand(len);
-                        self.visit_operand(index);
+                        self.visit_operand(len, location);
+                        self.visit_operand(index, location);
                     }
                     AssertMessage::Math(_) => {}
                 }
             }
 
             fn super_rvalue(&mut self,
-                            rvalue: & $($mutability)* Rvalue<'tcx>) {
+                            rvalue: & $($mutability)* Rvalue<'tcx>,
+                            location: Location) {
                 match *rvalue {
                     Rvalue::Use(ref $($mutability)* operand) => {
-                        self.visit_operand(operand);
+                        self.visit_operand(operand, location);
                     }
 
                     Rvalue::Repeat(ref $($mutability)* value,
                                    ref $($mutability)* typed_const_val) => {
-                        self.visit_operand(value);
-                        self.visit_typed_const_val(typed_const_val);
+                        self.visit_operand(value, location);
+                        self.visit_typed_const_val(typed_const_val, location);
                     }
 
                     Rvalue::Ref(r, bk, ref $($mutability)* path) => {
                         self.visit_lvalue(path, LvalueContext::Borrow {
                             region: r,
                             kind: bk
-                        });
+                        }, location);
                     }
 
                     Rvalue::Len(ref $($mutability)* path) => {
-                        self.visit_lvalue(path, LvalueContext::Inspect);
+                        self.visit_lvalue(path, LvalueContext::Inspect, location);
                     }
 
                     Rvalue::Cast(_cast_kind,
                                  ref $($mutability)* operand,
                                  ref $($mutability)* ty) => {
-                        self.visit_operand(operand);
+                        self.visit_operand(operand, location);
                         self.visit_ty(ty);
                     }
 
@@ -489,12 +515,12 @@ fn super_rvalue(&mut self,
                     Rvalue::CheckedBinaryOp(_bin_op,
                                      ref $($mutability)* lhs,
                                      ref $($mutability)* rhs) => {
-                        self.visit_operand(lhs);
-                        self.visit_operand(rhs);
+                        self.visit_operand(lhs, location);
+                        self.visit_operand(rhs, location);
                     }
 
                     Rvalue::UnaryOp(_un_op, ref $($mutability)* op) => {
-                        self.visit_operand(op);
+                        self.visit_operand(op, location);
                     }
 
                     Rvalue::Box(ref $($mutability)* ty) => {
@@ -515,13 +541,13 @@ fn super_rvalue(&mut self,
                             }
                             AggregateKind::Closure(ref $($mutability)* def_id,
                                                    ref $($mutability)* closure_substs) => {
-                                self.visit_def_id(def_id);
+                                self.visit_def_id(def_id, location);
                                 self.visit_closure_substs(closure_substs);
                             }
                         }
 
                         for operand in operands {
-                            self.visit_operand(operand);
+                            self.visit_operand(operand, location);
                         }
                     }
 
@@ -529,30 +555,32 @@ fn super_rvalue(&mut self,
                                         ref $($mutability)* inputs,
                                         asm: _ } => {
                         for output in & $($mutability)* outputs[..] {
-                            self.visit_lvalue(output, LvalueContext::Store);
+                            self.visit_lvalue(output, LvalueContext::Store, location);
                         }
                         for input in & $($mutability)* inputs[..] {
-                            self.visit_operand(input);
+                            self.visit_operand(input, location);
                         }
                     }
                 }
             }
 
             fn super_operand(&mut self,
-                             operand: & $($mutability)* Operand<'tcx>) {
+                             operand: & $($mutability)* Operand<'tcx>,
+                             location: Location) {
                 match *operand {
                     Operand::Consume(ref $($mutability)* lvalue) => {
-                        self.visit_lvalue(lvalue, LvalueContext::Consume);
+                        self.visit_lvalue(lvalue, LvalueContext::Consume, location);
                     }
                     Operand::Constant(ref $($mutability)* constant) => {
-                        self.visit_constant(constant);
+                        self.visit_constant(constant, location);
                     }
                 }
             }
 
             fn super_lvalue(&mut self,
                             lvalue: & $($mutability)* Lvalue<'tcx>,
-                            context: LvalueContext) {
+                            context: LvalueContext,
+                            location: Location) {
                 match *lvalue {
                     Lvalue::Var(_) |
                     Lvalue::Temp(_) |
@@ -560,28 +588,30 @@ fn super_lvalue(&mut self,
                     Lvalue::ReturnPointer => {
                     }
                     Lvalue::Static(ref $($mutability)* def_id) => {
-                        self.visit_def_id(def_id);
+                        self.visit_def_id(def_id, location);
                     }
                     Lvalue::Projection(ref $($mutability)* proj) => {
-                        self.visit_projection(proj, context);
+                        self.visit_projection(proj, context, location);
                     }
                 }
             }
 
             fn super_projection(&mut self,
                                 proj: & $($mutability)* LvalueProjection<'tcx>,
-                                context: LvalueContext) {
+                                context: LvalueContext,
+                                location: Location) {
                 let Projection {
                     ref $($mutability)* base,
                     ref $($mutability)* elem,
                 } = *proj;
-                self.visit_lvalue(base, LvalueContext::Projection);
-                self.visit_projection_elem(elem, context);
+                self.visit_lvalue(base, LvalueContext::Projection, location);
+                self.visit_projection_elem(elem, context, location);
             }
 
             fn super_projection_elem(&mut self,
                                      proj: & $($mutability)* LvalueElem<'tcx>,
-                                     _context: LvalueContext) {
+                                     _context: LvalueContext,
+                                     location: Location) {
                 match *proj {
                     ProjectionElem::Deref => {
                     }
@@ -591,7 +621,7 @@ fn super_projection_elem(&mut self,
                         self.visit_ty(ty);
                     }
                     ProjectionElem::Index(ref $($mutability)* operand) => {
-                        self.visit_operand(operand);
+                        self.visit_operand(operand, location);
                     }
                     ProjectionElem::ConstantIndex { offset: _,
                                                     min_length: _,
@@ -645,7 +675,8 @@ fn super_branch(&mut self,
             }
 
             fn super_constant(&mut self,
-                              constant: & $($mutability)* Constant<'tcx>) {
+                              constant: & $($mutability)* Constant<'tcx>,
+                              location: Location) {
                 let Constant {
                     ref $($mutability)* span,
                     ref $($mutability)* ty,
@@ -654,11 +685,12 @@ fn super_constant(&mut self,
 
                 self.visit_span(span);
                 self.visit_ty(ty);
-                self.visit_literal(literal);
+                self.visit_literal(literal, location);
             }
 
             fn super_typed_const_val(&mut self,
-                                     constant: & $($mutability)* TypedConstVal<'tcx>) {
+                                     constant: & $($mutability)* TypedConstVal<'tcx>,
+                                     location: Location) {
                 let TypedConstVal {
                     ref $($mutability)* span,
                     ref $($mutability)* ty,
@@ -667,19 +699,20 @@ fn super_typed_const_val(&mut self,
 
                 self.visit_span(span);
                 self.visit_ty(ty);
-                self.visit_const_usize(value);
+                self.visit_const_usize(value, location);
             }
 
             fn super_literal(&mut self,
-                             literal: & $($mutability)* Literal<'tcx>) {
+                             literal: & $($mutability)* Literal<'tcx>,
+                             location: Location) {
                 match *literal {
                     Literal::Item { ref $($mutability)* def_id,
                                     ref $($mutability)* substs } => {
-                        self.visit_def_id(def_id);
+                        self.visit_def_id(def_id, location);
                         self.visit_substs(substs);
                     }
                     Literal::Value { ref $($mutability)* value } => {
-                        self.visit_const_val(value);
+                        self.visit_const_val(value, location);
                     }
                     Literal::Promoted { index: _ } => {}
                 }
@@ -724,7 +757,7 @@ fn super_const_usize(&mut self, _substs: & $($mutability)* ConstUsize) {
 make_mir_visitor!(MutVisitor,mut);
 
 #[derive(Copy, Clone, Debug)]
-pub enum LvalueContext {
+pub enum LvalueContext<'tcx> {
     // Appears as LHS of an assignment
     Store,
 
@@ -738,7 +771,7 @@ pub enum LvalueContext {
     Inspect,
 
     // Being borrowed
-    Borrow { region: Region, kind: BorrowKind },
+    Borrow { region: &'tcx Region, kind: BorrowKind },
 
     // Being sliced -- this should be same as being borrowed, probably
     Slice { from_start: usize, from_end: usize },
index a991a1a9ba4b53a36b9be93d06a2f95e214e7b37..8a32797dbd75a82e59410042408129a16b6a874f 100644 (file)
@@ -891,6 +891,8 @@ fn parse_panic_strategy(slot: &mut PanicStrategy, v: Option<&str>) -> bool {
           "force overflow checks on or off"),
     trace_macros: bool = (false, parse_bool, [UNTRACKED],
           "for every macro invocation, print its name and arguments"),
+    debug_macros: bool = (false, parse_bool, [TRACKED],
+          "emit line numbers debug info inside macros"),
     enable_nonzeroing_move_hints: bool = (false, parse_bool, [TRACKED],
           "force nonzeroing move optimization on"),
     keep_hygiene_data: bool = (false, parse_bool, [UNTRACKED],
index d6f263fcebeb088f739bc5d3f55e164dc2e2df4c..3bdf6acdf9a5b4998d572a5cd8e0091ad0a23f9b 100644 (file)
@@ -232,8 +232,8 @@ fn impl_similar_to(&self,
                 if let Ok(..) = self.can_equate(&trait_self_ty, &impl_self_ty) {
                     self_match_impls.push(def_id);
 
-                    if trait_ref.substs.types[1..].iter()
-                        .zip(&impl_trait_ref.substs.types[1..])
+                    if trait_ref.substs.types().skip(1)
+                        .zip(impl_trait_ref.substs.types().skip(1))
                         .all(|(u,v)| self.fuzzy_match_tys(u, v))
                     {
                         fuzzy_match_impls.push(def_id);
@@ -477,10 +477,11 @@ pub fn report_selection_error(&self,
                                     return;
                                 }
 
-                                let mut err = struct_span_err!(
-                                    self.tcx.sess, span, E0277,
+                                let mut err = struct_span_err!(self.tcx.sess, span, E0277,
                                     "the trait bound `{}` is not satisfied",
                                     trait_ref.to_predicate());
+                                err.span_label(span, &format!("trait `{}` not satisfied",
+                                                              trait_ref.to_predicate()));
 
                                 // Try to report a help message
 
@@ -738,8 +739,7 @@ fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>) {
             ty::Predicate::Trait(ref data) => {
                 let trait_ref = data.to_poly_trait_ref();
                 let self_ty = trait_ref.self_ty();
-                let all_types = &trait_ref.substs().types;
-                if all_types.references_error() {
+                if predicate.references_error() {
                 } else {
                     // Typically, this ambiguity should only happen if
                     // there are unresolved type inference variables
index 837e33b3e7fc2798e2c27af83265ef52845afa17..6598aacc1d3d2d2ee5adffc807bdf4eb772d4c28 100644 (file)
@@ -93,7 +93,7 @@ pub struct FulfillmentContext<'tcx> {
 
 #[derive(Clone)]
 pub struct RegionObligation<'tcx> {
-    pub sub_region: ty::Region,
+    pub sub_region: &'tcx ty::Region,
     pub sup_type: Ty<'tcx>,
     pub cause: ObligationCause<'tcx>,
 }
@@ -142,7 +142,7 @@ pub fn must_defer(tcx: TyCtxt<'a, 'gcx, 'tcx>,
         // Auto trait obligations on `impl Trait`.
         if tcx.trait_has_default_impl(predicate.def_id()) {
             let substs = predicate.skip_binder().trait_ref.substs;
-            if substs.types.len() == 1 && substs.regions.is_empty() {
+            if substs.types().count() == 1 && substs.regions().next().is_none() {
                 if let ty::TyAnon(..) = predicate.skip_binder().self_ty().sty {
                     return true;
                 }
@@ -162,7 +162,7 @@ pub fn try_select(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>)
                 let concrete_ty = ty_scheme.ty.subst(tcx, substs);
                 let predicate = ty::TraitRef {
                     def_id: self.predicate.def_id(),
-                    substs: Substs::new_trait(tcx, vec![], vec![], concrete_ty)
+                    substs: Substs::new_trait(tcx, concrete_ty, &[])
                 }.to_predicate();
 
                 let original_obligation = Obligation::new(self.cause.clone(),
@@ -246,7 +246,7 @@ pub fn register_builtin_bound(&mut self,
 
     pub fn register_region_obligation(&mut self,
                                       t_a: Ty<'tcx>,
-                                      r_b: ty::Region,
+                                      r_b: &'tcx ty::Region,
                                       cause: ObligationCause<'tcx>)
     {
         register_region_obligation(t_a, r_b, cause, &mut self.region_obligations);
@@ -440,8 +440,7 @@ fn trait_ref_type_vars<'a, 'gcx, 'tcx>(selcx: &mut SelectionContext<'a, 'gcx, 't
 {
     t.skip_binder() // ok b/c this check doesn't care about regions
      .input_types()
-     .iter()
-     .map(|t| selcx.infcx().resolve_type_vars_if_possible(t))
+     .map(|t| selcx.infcx().resolve_type_vars_if_possible(&t))
      .filter(|t| t.has_infer_types())
      .flat_map(|t| t.walk())
      .filter(|t| match t.sty { ty::TyInfer(_) => true, _ => false })
@@ -581,7 +580,8 @@ fn process_predicate<'a, 'gcx, 'tcx>(
                         // Otherwise, we have something of the form
                         // `for<'a> T: 'a where 'a not in T`, which we can treat as `T: 'static`.
                         Some(t_a) => {
-                            register_region_obligation(t_a, ty::ReStatic,
+                            let r_static = selcx.tcx().mk_region(ty::ReStatic);
+                            register_region_obligation(t_a, r_static,
                                                        obligation.cause.clone(),
                                                        region_obligations);
                             Ok(Some(vec![]))
@@ -691,7 +691,7 @@ fn coinductive_obligation<'a,'gcx,'tcx>(selcx: &SelectionContext<'a,'gcx,'tcx>,
 }
 
 fn register_region_obligation<'tcx>(t_a: Ty<'tcx>,
-                                    r_b: ty::Region,
+                                    r_b: &'tcx ty::Region,
                                     cause: ObligationCause<'tcx>,
                                     region_obligations: &mut NodeMap<Vec<RegionObligation<'tcx>>>)
 {
index 25d2df8fdedb39a0a260703315e9fee84cc4bcc1..219d5200467622f8df1f708531206ce12b33a815 100644 (file)
@@ -145,7 +145,7 @@ fn supertraits_reference_self(self, trait_def_id: DefId) -> bool {
                 match predicate {
                     ty::Predicate::Trait(ref data) => {
                         // In the case of a trait predicate, we can skip the "self" type.
-                        data.0.trait_ref.input_types()[1..].iter().any(|t| t.has_self_ty())
+                        data.skip_binder().input_types().skip(1).any(|t| t.has_self_ty())
                     }
                     ty::Predicate::Projection(..) |
                     ty::Predicate::WellFormed(..) |
index 9ea738bd326eb7f18bf75d468433e935cc2c3989..b015de79be5c690e632d723359960134b3212d6e 100644 (file)
@@ -36,7 +36,7 @@
 use hir::def_id::DefId;
 use infer;
 use infer::{InferCtxt, InferOk, TypeFreshener, TypeOrigin};
-use ty::subst::{Subst, Substs};
+use ty::subst::{Kind, Subst, Substs};
 use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
 use traits;
 use ty::fast_reject;
@@ -644,8 +644,7 @@ fn evaluate_stack<'o>(&mut self,
         // This suffices to allow chains like `FnMut` implemented in
         // terms of `Fn` etc, but we could probably make this more
         // precise still.
-        let input_types = stack.fresh_trait_ref.0.input_types();
-        let unbound_input_types = input_types.iter().any(|ty| ty.is_fresh());
+        let unbound_input_types = stack.fresh_trait_ref.input_types().any(|ty| ty.is_fresh());
         if unbound_input_types && self.intercrate {
             debug!("evaluate_stack({:?}) --> unbound argument, intercrate -->  ambiguous",
                    stack.fresh_trait_ref);
@@ -1064,9 +1063,7 @@ fn should_update_candidate_cache(&mut self,
 
         match *candidate {
             Ok(Some(_)) | Err(_) => true,
-            Ok(None) => {
-                cache_fresh_trait_pred.0.trait_ref.substs.types.has_infer_types()
-            }
+            Ok(None) => cache_fresh_trait_pred.has_infer_types()
         }
     }
 
@@ -1250,7 +1247,7 @@ fn match_projection(&mut self,
                         obligation: &TraitObligation<'tcx>,
                         trait_bound: ty::PolyTraitRef<'tcx>,
                         skol_trait_ref: ty::TraitRef<'tcx>,
-                        skol_map: &infer::SkolemizationMap,
+                        skol_map: &infer::SkolemizationMap<'tcx>,
                         snapshot: &infer::CombinedSnapshot)
                         -> bool
     {
@@ -1603,7 +1600,7 @@ fn assemble_candidates_for_unsizing(&mut self,
                 return;
             }
         };
-        let target = obligation.predicate.skip_binder().input_types()[1];
+        let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1);
 
         debug!("assemble_candidates_for_unsizing(source={:?}, target={:?})",
                source, target);
@@ -1936,7 +1933,7 @@ fn constituent_types_for_ty(&self, t: Ty<'tcx>) -> Vec<Ty<'tcx>> {
 
             // for `PhantomData<T>`, we pass `T`
             ty::TyStruct(def, substs) if def.is_phantom_data() => {
-                substs.types.to_vec()
+                substs.types().collect()
             }
 
             ty::TyStruct(def, substs) | ty::TyEnum(def, substs) => {
@@ -1985,7 +1982,7 @@ fn collect_predicates_for_types(&mut self,
                                                   trait_def_id,
                                                   recursion_depth,
                                                   normalized_ty,
-                                                  vec![]);
+                                                  &[]);
                 obligations.push(skol_obligation);
                 this.infcx().plug_leaks(skol_map, snapshot, &obligations)
             })
@@ -2180,12 +2177,11 @@ fn confirm_default_impl_object_candidate(&mut self,
         match self_ty.sty {
             ty::TyTrait(ref data) => {
                 // OK to skip the binder, it is reintroduced below
-                let input_types = data.principal.skip_binder().input_types();
+                let input_types = data.principal.input_types();
                 let assoc_types = data.projection_bounds.iter()
                                       .map(|pb| pb.skip_binder().ty);
-                let all_types: Vec<_> = input_types.iter().cloned()
-                                                          .chain(assoc_types)
-                                                          .collect();
+                let all_types: Vec<_> = input_types.chain(assoc_types)
+                                                   .collect();
 
                 // reintroduce the two binding levels we skipped, then flatten into one
                 let all_types = ty::Binder(ty::Binder(all_types));
@@ -2267,7 +2263,7 @@ fn vtable_impl(&mut self,
                    mut substs: Normalized<'tcx, &'tcx Substs<'tcx>>,
                    cause: ObligationCause<'tcx>,
                    recursion_depth: usize,
-                   skol_map: infer::SkolemizationMap,
+                   skol_map: infer::SkolemizationMap<'tcx>,
                    snapshot: &infer::CombinedSnapshot)
                    -> VtableImplData<'tcx, PredicateObligation<'tcx>>
     {
@@ -2476,7 +2472,7 @@ fn confirm_builtin_unsize_candidate(&mut self,
         // regions here. See the comment there for more details.
         let source = self.infcx.shallow_resolve(
             tcx.no_late_bound_regions(&obligation.self_ty()).unwrap());
-        let target = obligation.predicate.skip_binder().input_types()[1];
+        let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1);
         let target = self.infcx.shallow_resolve(target);
 
         debug!("confirm_builtin_unsize_candidate(source={:?}, target={:?})",
@@ -2585,7 +2581,7 @@ fn confirm_builtin_unsize_candidate(&mut self,
                 } else {
                     return Err(Unimplemented);
                 };
-                let mut ty_params = BitVector::new(substs_a.types.len());
+                let mut ty_params = BitVector::new(substs_a.types().count());
                 let mut found = false;
                 for ty in field.walk() {
                     if let ty::TyParam(p) = ty.sty {
@@ -2601,14 +2597,14 @@ fn confirm_builtin_unsize_candidate(&mut self,
                 // TyError and ensure they do not affect any other fields.
                 // This could be checked after type collection for any struct
                 // with a potentially unsized trailing field.
-                let types = substs_a.types.iter().enumerate().map(|(i, ty)| {
+                let params = substs_a.params().iter().enumerate().map(|(i, &k)| {
                     if ty_params.contains(i) {
-                        tcx.types.err
+                        Kind::from(tcx.types.err)
                     } else {
-                        ty
+                        k
                     }
-                }).collect();
-                let substs = Substs::new(tcx, types, substs_a.regions.clone());
+                });
+                let substs = Substs::new(tcx, params);
                 for &ty in fields.split_last().unwrap().1 {
                     if ty.subst(tcx, substs).references_error() {
                         return Err(Unimplemented);
@@ -2621,15 +2617,14 @@ fn confirm_builtin_unsize_candidate(&mut self,
 
                 // Check that the source structure with the target's
                 // type parameters is a subtype of the target.
-                let types = substs_a.types.iter().enumerate().map(|(i, ty)| {
+                let params = substs_a.params().iter().enumerate().map(|(i, &k)| {
                     if ty_params.contains(i) {
-                        substs_b.types[i]
+                        Kind::from(substs_b.type_at(i))
                     } else {
-                        ty
+                        k
                     }
-                }).collect();
-                let substs = Substs::new(tcx, types, substs_a.regions.clone());
-                let new_struct = tcx.mk_struct(def, substs);
+                });
+                let new_struct = tcx.mk_struct(def, Substs::new(tcx, params));
                 let origin = TypeOrigin::Misc(obligation.cause.span);
                 let InferOk { obligations, .. } =
                     self.infcx.sub_types(false, origin, new_struct, target)
@@ -2642,7 +2637,7 @@ fn confirm_builtin_unsize_candidate(&mut self,
                     obligation.predicate.def_id(),
                     obligation.recursion_depth + 1,
                     inner_source,
-                    vec![inner_target]));
+                    &[inner_target]));
             }
 
             _ => bug!()
@@ -2665,7 +2660,8 @@ fn rematch_impl(&mut self,
                     impl_def_id: DefId,
                     obligation: &TraitObligation<'tcx>,
                     snapshot: &infer::CombinedSnapshot)
-                    -> (Normalized<'tcx, &'tcx Substs<'tcx>>, infer::SkolemizationMap)
+                    -> (Normalized<'tcx, &'tcx Substs<'tcx>>,
+                        infer::SkolemizationMap<'tcx>)
     {
         match self.match_impl(impl_def_id, obligation, snapshot) {
             Ok((substs, skol_map)) => (substs, skol_map),
@@ -2682,7 +2678,7 @@ fn match_impl(&mut self,
                   obligation: &TraitObligation<'tcx>,
                   snapshot: &infer::CombinedSnapshot)
                   -> Result<(Normalized<'tcx, &'tcx Substs<'tcx>>,
-                             infer::SkolemizationMap), ()>
+                             infer::SkolemizationMap<'tcx>), ()>
     {
         let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap();
 
@@ -2753,9 +2749,9 @@ fn fast_reject_trait_refs(&mut self,
         // substitution if we find that any of the input types, when
         // simplified, do not match.
 
-        obligation.predicate.0.input_types().iter()
+        obligation.predicate.skip_binder().input_types()
             .zip(impl_trait_ref.input_types())
-            .any(|(&obligation_ty, &impl_ty)| {
+            .any(|(obligation_ty, impl_ty)| {
                 let simplified_obligation_ty =
                     fast_reject::simplify_type(self.tcx(), obligation_ty, true);
                 let simplified_impl_ty =
@@ -2875,7 +2871,7 @@ fn impl_or_trait_obligations(&mut self,
                                  recursion_depth: usize,
                                  def_id: DefId, // of impl or trait
                                  substs: &Substs<'tcx>, // for impl or trait
-                                 skol_map: infer::SkolemizationMap,
+                                 skol_map: infer::SkolemizationMap<'tcx>,
                                  snapshot: &infer::CombinedSnapshot)
                                  -> Vec<PredicateObligation<'tcx>>
     {
index 1954ce1993c5e0d71eeb5e604ed6606c68c9f204..038de25312d35b631fb1f6fe41c4abb703d21246 100644 (file)
@@ -386,7 +386,7 @@ pub fn trait_ref_for_builtin_bound(self,
             Ok(def_id) => {
                 Ok(ty::TraitRef {
                     def_id: def_id,
-                    substs: Substs::new_trait(self, vec![], vec![], param_ty)
+                    substs: Substs::new_trait(self, param_ty, &[])
                 })
             }
             Err(e) => {
@@ -401,12 +401,12 @@ pub fn predicate_for_trait_def(self,
         trait_def_id: DefId,
         recursion_depth: usize,
         param_ty: Ty<'tcx>,
-        ty_params: Vec<Ty<'tcx>>)
+        ty_params: &[Ty<'tcx>])
         -> PredicateObligation<'tcx>
     {
         let trait_ref = ty::TraitRef {
             def_id: trait_def_id,
-            substs: Substs::new_trait(self, ty_params, vec![], param_ty)
+            substs: Substs::new_trait(self, param_ty, ty_params)
         };
         predicate_for_trait_ref(cause, trait_ref, recursion_depth)
     }
@@ -496,7 +496,7 @@ pub fn closure_trait_ref_and_return_type(self,
         };
         let trait_ref = ty::TraitRef {
             def_id: fn_trait_def_id,
-            substs: Substs::new_trait(self, vec![arguments_tuple], vec![], self_ty),
+            substs: Substs::new_trait(self, self_ty, &[arguments_tuple]),
         };
         ty::Binder((trait_ref, sig.0.output))
     }
index 39dba57c47b7c855fe1bf6cad60dc778dad0aa6c..b1846e03941489cafc665f586ccb687d39a458d9 100644 (file)
@@ -52,7 +52,8 @@ fn relate_with_variance<T: Relate<'tcx>>(&mut self,
         self.relate(a, b)
     }
 
-    fn regions(&mut self, a: ty::Region, b: ty::Region) -> RelateResult<'tcx, ty::Region> {
+    fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region)
+               -> RelateResult<'tcx, &'tcx ty::Region> {
         debug!("{}.regions({:?}, {:?})",
                self.tag(),
                a,
index 3501dd484608786b7a7a3403eae02852a0e9ca18..e048e618e84d66951cd38467f3b9b0c0d2037f2c 100644 (file)
@@ -213,7 +213,7 @@ pub struct Tables<'tcx> {
     pub method_map: ty::MethodMap<'tcx>,
 
     /// Borrows
-    pub upvar_capture_map: ty::UpvarCaptureMap,
+    pub upvar_capture_map: ty::UpvarCaptureMap<'tcx>,
 
     /// Records the type of each closure. The def ID is the ID of the
     /// expression defining the closure.
@@ -1152,12 +1152,17 @@ fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool {
 impl_interners!('tcx,
     type_list: mk_type_list(Vec<Ty<'tcx>>, keep_local) -> [Ty<'tcx>],
     substs: mk_substs(Substs<'tcx>, |substs: &Substs| {
-        keep_local(&substs.types) || keep_local(&substs.regions)
+        substs.params().iter().any(keep_local)
     }) -> Substs<'tcx>,
     bare_fn: mk_bare_fn(BareFnTy<'tcx>, |fty: &BareFnTy| {
         keep_local(&fty.sig)
     }) -> BareFnTy<'tcx>,
-    region: mk_region(Region, keep_local) -> Region
+    region: mk_region(Region, |r| {
+        match r {
+            &ty::ReVar(_) | &ty::ReSkolemized(..) => true,
+            _ => false
+        }
+    }) -> Region
 );
 
 impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
index 32c87fb615a5344131607f05898f283b9d998632..3d60d326b2b0f640f477f4436a60a6b50cf18ea0 100644 (file)
@@ -41,11 +41,11 @@ pub enum TypeError<'tcx> {
     FixedArraySize(ExpectedFound<usize>),
     TyParamSize(ExpectedFound<usize>),
     ArgCount,
-    RegionsDoesNotOutlive(Region, Region),
-    RegionsNotSame(Region, Region),
-    RegionsNoOverlap(Region, Region),
-    RegionsInsufficientlyPolymorphic(BoundRegion, Region),
-    RegionsOverlyPolymorphic(BoundRegion, Region),
+    RegionsDoesNotOutlive(&'tcx Region, &'tcx Region),
+    RegionsNotSame(&'tcx Region, &'tcx Region),
+    RegionsNoOverlap(&'tcx Region, &'tcx Region),
+    RegionsInsufficientlyPolymorphic(BoundRegion, &'tcx Region),
+    RegionsOverlyPolymorphic(BoundRegion, &'tcx Region),
     Sorts(ExpectedFound<Ty<'tcx>>),
     IntegerAsChar,
     IntMismatch(ExpectedFound<ty::IntVarValue>),
@@ -296,7 +296,7 @@ pub fn note_and_explain_type_err(self,
                 self.note_and_explain_region(db, "concrete lifetime that was found is ",
                                            conc_region, "");
             }
-            RegionsOverlyPolymorphic(_, ty::ReVar(_)) => {
+            RegionsOverlyPolymorphic(_, &ty::ReVar(_)) => {
                 // don't bother to print out the message below for
                 // inference variables, it's not very illuminating.
             }
index c6c37296e9e1242f82ace140e67d388dd8992e9d..1afd49ab47fbfeb686252bb807173bac5fc2a248 100644 (file)
@@ -137,7 +137,7 @@ fn add_sty(&mut self, st: &ty::TypeVariants) {
             }
 
             &ty::TyRef(r, ref m) => {
-                self.add_region(*r);
+                self.add_region(r);
                 self.add_ty(m.ty);
             }
 
@@ -176,8 +176,8 @@ fn add_fn_sig(&mut self, fn_sig: &ty::PolyFnSig) {
         self.add_bound_computation(&computation);
     }
 
-    fn add_region(&mut self, r: ty::Region) {
-        match r {
+    fn add_region(&mut self, r: &ty::Region) {
+        match *r {
             ty::ReVar(..) => {
                 self.add_flags(TypeFlags::HAS_RE_INFER);
                 self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX);
@@ -208,8 +208,11 @@ fn add_projection_ty(&mut self, projection_ty: &ty::ProjectionTy) {
     }
 
     fn add_substs(&mut self, substs: &Substs) {
-        self.add_tys(&substs.types);
-        for &r in &substs.regions {
+        for ty in substs.types() {
+            self.add_ty(ty);
+        }
+
+        for r in substs.regions() {
             self.add_region(r);
         }
     }
index 2e114a801d6ed4a86de846ab4c286ef6bd93e416..2c18d1d52547f2acd0e0fb10ce6330c51c7f320f 100644 (file)
@@ -169,7 +169,7 @@ fn fold_closure_ty(&mut self,
         fty.super_fold_with(self)
     }
 
-    fn fold_region(&mut self, r: ty::Region) -> ty::Region {
+    fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
         r.super_fold_with(self)
     }
 
@@ -188,7 +188,7 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
         t.super_visit_with(self)
     }
 
-    fn visit_region(&mut self, r: ty::Region) -> bool {
+    fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
         r.super_visit_with(self)
     }
 }
@@ -222,13 +222,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     /// whether any late-bound regions were skipped
     pub fn collect_regions<T>(self,
         value: &T,
-        region_set: &mut FnvHashSet<ty::Region>)
+        region_set: &mut FnvHashSet<&'tcx ty::Region>)
         -> bool
         where T : TypeFoldable<'tcx>
     {
         let mut have_bound_regions = false;
-        self.fold_regions(value, &mut have_bound_regions,
-                          |r, d| { region_set.insert(r.from_depth(d)); r });
+        self.fold_regions(value, &mut have_bound_regions, |r, d| {
+            region_set.insert(self.mk_region(r.from_depth(d)));
+            r
+        });
         have_bound_regions
     }
 
@@ -240,7 +242,7 @@ pub fn fold_regions<T,F>(self,
         skipped_regions: &mut bool,
         mut f: F)
         -> T
-        where F : FnMut(ty::Region, u32) -> ty::Region,
+        where F : FnMut(&'tcx ty::Region, u32) -> &'tcx ty::Region,
               T : TypeFoldable<'tcx>,
     {
         value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f))
@@ -260,14 +262,14 @@ pub struct RegionFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
     skipped_regions: &'a mut bool,
     current_depth: u32,
-    fld_r: &'a mut (FnMut(ty::Region, u32) -> ty::Region + 'a),
+    fld_r: &'a mut (FnMut(&'tcx ty::Region, u32) -> &'tcx ty::Region + 'a),
 }
 
 impl<'a, 'gcx, 'tcx> RegionFolder<'a, 'gcx, 'tcx> {
     pub fn new<F>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                   skipped_regions: &'a mut bool,
                   fld_r: &'a mut F) -> RegionFolder<'a, 'gcx, 'tcx>
-        where F : FnMut(ty::Region, u32) -> ty::Region
+        where F : FnMut(&'tcx ty::Region, u32) -> &'tcx ty::Region
     {
         RegionFolder {
             tcx: tcx,
@@ -288,8 +290,8 @@ fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> ty::Binde
         t
     }
 
-    fn fold_region(&mut self, r: ty::Region) -> ty::Region {
-        match r {
+    fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
+        match *r {
             ty::ReLateBound(debruijn, _) if debruijn.depth < self.current_depth => {
                 debug!("RegionFolder.fold_region({:?}) skipped bound region (current depth={})",
                        r, self.current_depth);
@@ -313,16 +315,16 @@ fn fold_region(&mut self, r: ty::Region) -> ty::Region {
 struct RegionReplacer<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
     current_depth: u32,
-    fld_r: &'a mut (FnMut(ty::BoundRegion) -> ty::Region + 'a),
-    map: FnvHashMap<ty::BoundRegion, ty::Region>
+    fld_r: &'a mut (FnMut(ty::BoundRegion) -> &'tcx ty::Region + 'a),
+    map: FnvHashMap<ty::BoundRegion, &'tcx ty::Region>
 }
 
 impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     pub fn replace_late_bound_regions<T,F>(self,
         value: &Binder<T>,
         mut f: F)
-        -> (T, FnvHashMap<ty::BoundRegion, ty::Region>)
-        where F : FnMut(ty::BoundRegion) -> ty::Region,
+        -> (T, FnvHashMap<ty::BoundRegion, &'tcx ty::Region>)
+        where F : FnMut(ty::BoundRegion) -> &'tcx ty::Region,
               T : TypeFoldable<'tcx>,
     {
         let mut replacer = RegionReplacer::new(self, &mut f);
@@ -340,7 +342,10 @@ pub fn liberate_late_bound_regions<T>(self,
         where T : TypeFoldable<'tcx>
     {
         self.replace_late_bound_regions(value, |br| {
-            ty::ReFree(ty::FreeRegion{scope: all_outlive_scope, bound_region: br})
+            self.mk_region(ty::ReFree(ty::FreeRegion {
+                scope: all_outlive_scope,
+                bound_region: br
+            }))
         }).0
     }
 
@@ -353,11 +358,11 @@ pub fn flatten_late_bound_regions<T>(self, bound2_value: &Binder<Binder<T>>)
         let bound0_value = bound2_value.skip_binder().skip_binder();
         let value = self.fold_regions(bound0_value, &mut false,
                                       |region, current_depth| {
-            match region {
+            match *region {
                 ty::ReLateBound(debruijn, br) if debruijn.depth >= current_depth => {
                     // should be true if no escaping regions from bound2_value
                     assert!(debruijn.depth - current_depth <= 1);
-                    ty::ReLateBound(ty::DebruijnIndex::new(current_depth), br)
+                    self.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(current_depth), br))
                 }
                 _ => {
                     region
@@ -411,7 +416,7 @@ fn collect_late_bound_regions<T>(&self, value: &Binder<T>, just_constraint: bool
     pub fn erase_late_bound_regions<T>(self, value: &Binder<T>) -> T
         where T : TypeFoldable<'tcx>
     {
-        self.replace_late_bound_regions(value, |_| ty::ReErased).0
+        self.replace_late_bound_regions(value, |_| self.mk_region(ty::ReErased)).0
     }
 
     /// Rewrite any late-bound regions so that they are anonymous.  Region numbers are
@@ -428,7 +433,7 @@ pub fn anonymize_late_bound_regions<T>(self, sig: &Binder<T>) -> Binder<T>
         let mut counter = 0;
         Binder(self.replace_late_bound_regions(sig, |_| {
             counter += 1;
-            ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrAnon(counter))
+            self.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrAnon(counter)))
         }).0)
     }
 }
@@ -436,7 +441,7 @@ pub fn anonymize_late_bound_regions<T>(self, sig: &Binder<T>) -> Binder<T>
 impl<'a, 'gcx, 'tcx> RegionReplacer<'a, 'gcx, 'tcx> {
     fn new<F>(tcx: TyCtxt<'a, 'gcx, 'tcx>, fld_r: &'a mut F)
               -> RegionReplacer<'a, 'gcx, 'tcx>
-        where F : FnMut(ty::BoundRegion) -> ty::Region
+        where F : FnMut(ty::BoundRegion) -> &'tcx ty::Region
     {
         RegionReplacer {
             tcx: tcx,
@@ -465,22 +470,22 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
         t.super_fold_with(self)
     }
 
-    fn fold_region(&mut self, r: ty::Region) -> ty::Region {
-        match r {
+    fn fold_region(&mut self, r:&'tcx  ty::Region) -> &'tcx ty::Region {
+        match *r {
             ty::ReLateBound(debruijn, br) if debruijn.depth == self.current_depth => {
                 let fld_r = &mut self.fld_r;
                 let region = *self.map.entry(br).or_insert_with(|| fld_r(br));
-                if let ty::ReLateBound(debruijn1, br) = region {
+                if let ty::ReLateBound(debruijn1, br) = *region {
                     // If the callback returns a late-bound region,
                     // that region should always use depth 1. Then we
                     // adjust it to the correct depth.
                     assert_eq!(debruijn1.depth, 1);
-                    ty::ReLateBound(debruijn, br)
+                    self.tcx.mk_region(ty::ReLateBound(debruijn, br))
                 } else {
                     region
                 }
             }
-            r => r
+            _ => r
         }
     }
 }
@@ -528,7 +533,7 @@ fn fold_binder<T>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T>
                 u.super_fold_with(self)
             }
 
-            fn fold_region(&mut self, r: ty::Region) -> ty::Region {
+            fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
                 // because late-bound regions affect subtyping, we can't
                 // erase the bound/free distinction, but we can replace
                 // all free regions with 'erased.
@@ -537,9 +542,9 @@ fn fold_region(&mut self, r: ty::Region) -> ty::Region {
                 // type system never "sees" those, they get substituted
                 // away. In trans, they will always be erased to 'erased
                 // whenever a substitution occurs.
-                match r {
+                match *r {
                     ty::ReLateBound(..) => r,
-                    _ => ty::ReErased
+                    _ => self.tcx().mk_region(ty::ReErased)
                 }
             }
         }
@@ -574,7 +579,7 @@ pub fn shift_regions<'a, 'gcx, 'tcx, T>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
            value, amount);
 
     value.fold_with(&mut RegionFolder::new(tcx, &mut false, &mut |region, _current_depth| {
-        shift_region(region, amount)
+        tcx.mk_region(shift_region(*region, amount))
     }))
 }
 
@@ -616,7 +621,7 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
         t.region_depth > self.depth
     }
 
-    fn visit_region(&mut self, r: ty::Region) -> bool {
+    fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
         r.escapes_depth(self.depth)
     }
 }
@@ -630,17 +635,18 @@ fn visit_ty(&mut self, t: Ty) -> bool {
         t.flags.get().intersects(self.flags)
     }
 
-    fn visit_region(&mut self, r: ty::Region) -> bool {
+    fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
         if self.flags.intersects(ty::TypeFlags::HAS_LOCAL_NAMES) {
             // does this represent a region that cannot be named
             // in a global way? used in fulfillment caching.
-            match r {
+            match *r {
                 ty::ReStatic | ty::ReEmpty | ty::ReErased => {}
                 _ => return true,
             }
         }
-        if self.flags.intersects(ty::TypeFlags::HAS_RE_INFER) {
-            match r {
+        if self.flags.intersects(ty::TypeFlags::HAS_RE_INFER |
+                                 ty::TypeFlags::KEEP_IN_LOCAL_TCX) {
+            match *r {
                 ty::ReVar(_) | ty::ReSkolemized(..) => { return true }
                 _ => {}
             }
@@ -688,8 +694,8 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
         t.super_visit_with(self)
     }
 
-    fn visit_region(&mut self, r: ty::Region) -> bool {
-        match r {
+    fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
+        match *r {
             ty::ReLateBound(debruijn, br) if debruijn.depth == self.current_depth => {
                 self.regions.insert(br);
             }
index 1dcc623d3655868cf931b3538b6bfb6ca2faa524..62bd30e2555921b029f69df921ac07254320ff24 100644 (file)
@@ -264,7 +264,7 @@ fn push_impl_path<T>(self,
         match self_ty.sty {
             ty::TyStruct(adt_def, substs) |
             ty::TyEnum(adt_def, substs) => {
-                if substs.types.is_empty() { // ignore regions
+                if substs.types().next().is_none() { // ignore regions
                     self.push_item_path(buffer, adt_def.did);
                 } else {
                     buffer.push(&format!("<{}>", self_ty));
index d5686906e6a7b7c467d99894b4f80a85aa6d5ab0..0e8bea86178f3097bc4021d656c592d6659a3e57 100644 (file)
@@ -38,7 +38,7 @@ fn to_dep_node(key: &$key) -> DepNode<DefId> { DepNode::$node_name(*key) }
 dep_map_ty! { ImplTraitRefs: ItemSignature(DefId) -> Option<ty::TraitRef<'tcx>> }
 dep_map_ty! { TraitDefs: ItemSignature(DefId) -> &'tcx ty::TraitDef<'tcx> }
 dep_map_ty! { AdtDefs: ItemSignature(DefId) -> ty::AdtDefMaster<'tcx> }
-dep_map_ty! { ItemVariances: ItemSignature(DefId) -> Rc<ty::ItemVariances> }
+dep_map_ty! { ItemVariances: ItemSignature(DefId) -> Rc<Vec<ty::Variance>> }
 dep_map_ty! { InherentImpls: InherentImpls(DefId) -> Rc<Vec<DefId>> }
 dep_map_ty! { ImplItems: ImplItems(DefId) -> Vec<ty::ImplOrTraitItemId> }
 dep_map_ty! { TraitItems: TraitItems(DefId) -> Rc<Vec<ty::ImplOrTraitItem<'tcx>>> }
index 6c82157c8ca7c900039325e6e015a378e48cd16c..759dc30037210166b0729595a1123786a68e2b21 100644 (file)
@@ -343,7 +343,7 @@ pub struct Method<'tcx> {
     pub generics: &'tcx Generics<'tcx>,
     pub predicates: GenericPredicates<'tcx>,
     pub fty: &'tcx BareFnTy<'tcx>,
-    pub explicit_self: ExplicitSelfCategory,
+    pub explicit_self: ExplicitSelfCategory<'tcx>,
     pub vis: Visibility,
     pub defaultness: hir::Defaultness,
     pub def_id: DefId,
@@ -355,7 +355,7 @@ pub fn new(name: Name,
                generics: &'tcx ty::Generics<'tcx>,
                predicates: GenericPredicates<'tcx>,
                fty: &'tcx BareFnTy<'tcx>,
-               explicit_self: ExplicitSelfCategory,
+               explicit_self: ExplicitSelfCategory<'tcx>,
                vis: Visibility,
                defaultness: hir::Defaultness,
                def_id: DefId,
@@ -417,21 +417,6 @@ pub struct AssociatedType<'tcx> {
     pub container: ImplOrTraitItemContainer,
 }
 
-#[derive(Clone, PartialEq, RustcDecodable, RustcEncodable)]
-pub struct ItemVariances {
-    pub types: Vec<Variance>,
-    pub regions: Vec<Variance>,
-}
-
-impl ItemVariances {
-    pub fn empty() -> ItemVariances {
-        ItemVariances {
-            types: vec![],
-            regions: vec![],
-        }
-    }
-}
-
 #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Copy)]
 pub enum Variance {
     Covariant,      // T<A> <: T<B> iff A <: B -- e.g., function return type
@@ -658,28 +643,28 @@ pub enum BorrowKind {
 /// Information describing the capture of an upvar. This is computed
 /// during `typeck`, specifically by `regionck`.
 #[derive(PartialEq, Clone, Debug, Copy)]
-pub enum UpvarCapture {
+pub enum UpvarCapture<'tcx> {
     /// Upvar is captured by value. This is always true when the
     /// closure is labeled `move`, but can also be true in other cases
     /// depending on inference.
     ByValue,
 
     /// Upvar is captured by reference.
-    ByRef(UpvarBorrow),
+    ByRef(UpvarBorrow<'tcx>),
 }
 
 #[derive(PartialEq, Clone, Copy)]
-pub struct UpvarBorrow {
+pub struct UpvarBorrow<'tcx> {
     /// The kind of borrow: by-ref upvars have access to shared
     /// immutable borrows, which are not part of the normal language
     /// syntax.
     pub kind: BorrowKind,
 
     /// Region of the resulting reference.
-    pub region: ty::Region,
+    pub region: &'tcx ty::Region,
 }
 
-pub type UpvarCaptureMap = FnvHashMap<UpvarId, UpvarCapture>;
+pub type UpvarCaptureMap<'tcx> = FnvHashMap<UpvarId, UpvarCapture<'tcx>>;
 
 #[derive(Copy, Clone)]
 pub struct ClosureUpvar<'tcx> {
@@ -700,7 +685,7 @@ pub enum IntVarValue {
 /// this is `None`, then the default is inherited from the
 /// surrounding context. See RFC #599 for details.
 #[derive(Copy, Clone)]
-pub enum ObjectLifetimeDefault {
+pub enum ObjectLifetimeDefault<'tcx> {
     /// Require an explicit annotation. Occurs when multiple
     /// `T:'a` constraints are found.
     Ambiguous,
@@ -709,7 +694,7 @@ pub enum ObjectLifetimeDefault {
     BaseDefault,
 
     /// Use the given region as the default.
-    Specific(Region),
+    Specific(&'tcx Region),
 }
 
 #[derive(Clone)]
@@ -719,18 +704,18 @@ pub struct TypeParameterDef<'tcx> {
     pub index: u32,
     pub default_def_id: DefId, // for use in error reporing about defaults
     pub default: Option<Ty<'tcx>>,
-    pub object_lifetime_default: ObjectLifetimeDefault,
+    pub object_lifetime_default: ObjectLifetimeDefault<'tcx>,
 }
 
 #[derive(Clone)]
-pub struct RegionParameterDef {
+pub struct RegionParameterDef<'tcx> {
     pub name: Name,
     pub def_id: DefId,
     pub index: u32,
-    pub bounds: Vec<ty::Region>,
+    pub bounds: Vec<&'tcx ty::Region>,
 }
 
-impl RegionParameterDef {
+impl<'tcx> RegionParameterDef<'tcx> {
     pub fn to_early_bound_region(&self) -> ty::Region {
         ty::ReEarlyBound(ty::EarlyBoundRegion {
             index: self.index,
@@ -750,11 +735,25 @@ pub struct Generics<'tcx> {
     pub parent: Option<DefId>,
     pub parent_regions: u32,
     pub parent_types: u32,
-    pub regions: Vec<RegionParameterDef>,
+    pub regions: Vec<RegionParameterDef<'tcx>>,
     pub types: Vec<TypeParameterDef<'tcx>>,
     pub has_self: bool,
 }
 
+impl<'tcx> Generics<'tcx> {
+    pub fn parent_count(&self) -> usize {
+        self.parent_regions as usize + self.parent_types as usize
+    }
+
+    pub fn own_count(&self) -> usize {
+        self.regions.len() + self.types.len()
+    }
+
+    pub fn count(&self) -> usize {
+        self.parent_count() + self.own_count()
+    }
+}
+
 /// Bounds on generics.
 #[derive(Clone)]
 pub struct GenericPredicates<'tcx> {
@@ -812,7 +811,7 @@ pub enum Predicate<'tcx> {
     Equate(PolyEquatePredicate<'tcx>),
 
     /// where 'a : 'b
-    RegionOutlives(PolyRegionOutlivesPredicate),
+    RegionOutlives(PolyRegionOutlivesPredicate<'tcx>),
 
     /// where T : 'a
     TypeOutlives(PolyTypeOutlivesPredicate<'tcx>),
@@ -951,7 +950,6 @@ fn dep_node(&self) -> DepNode<DefId> {
         // leads to more recompilation.
         let def_ids: Vec<_> =
             self.input_types()
-                .iter()
                 .flat_map(|t| t.walk())
                 .filter_map(|t| match t.sty {
                     ty::TyStruct(adt_def, _) |
@@ -964,8 +962,8 @@ fn dep_node(&self) -> DepNode<DefId> {
         DepNode::TraitSelect(self.def_id(), def_ids)
     }
 
-    pub fn input_types(&self) -> &[Ty<'tcx>] {
-        &self.trait_ref.substs.types
+    pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
+        self.trait_ref.input_types()
     }
 
     pub fn self_ty(&self) -> Ty<'tcx> {
@@ -992,8 +990,9 @@ pub fn dep_node(&self) -> DepNode<DefId> {
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B`
 pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
-pub type PolyRegionOutlivesPredicate = PolyOutlivesPredicate<ty::Region, ty::Region>;
-pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate<Ty<'tcx>, ty::Region>;
+pub type PolyRegionOutlivesPredicate<'tcx> = PolyOutlivesPredicate<&'tcx ty::Region,
+                                                                   &'tcx ty::Region>;
+pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate<Ty<'tcx>, &'tcx ty::Region>;
 
 /// This kind of predicate has no *direct* correspondent in the
 /// syntax, but it roughly corresponds to the syntactic forms:
@@ -1082,7 +1081,7 @@ fn to_predicate(&self) -> Predicate<'tcx> {
     }
 }
 
-impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate {
+impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> {
     fn to_predicate(&self) -> Predicate<'tcx> {
         Predicate::RegionOutlives(self.clone())
     }
@@ -1107,7 +1106,7 @@ impl<'tcx> Predicate<'tcx> {
     pub fn walk_tys(&self) -> IntoIter<Ty<'tcx>> {
         let vec: Vec<_> = match *self {
             ty::Predicate::Trait(ref data) => {
-                data.0.trait_ref.input_types().to_vec()
+                data.skip_binder().input_types().collect()
             }
             ty::Predicate::Rfc1592(ref data) => {
                 return data.walk_tys()
@@ -1123,10 +1122,7 @@ pub fn walk_tys(&self) -> IntoIter<Ty<'tcx>> {
             }
             ty::Predicate::Projection(ref data) => {
                 let trait_inputs = data.0.projection_ty.trait_ref.input_types();
-                trait_inputs.iter()
-                            .cloned()
-                            .chain(Some(data.0.ty))
-                            .collect()
+                trait_inputs.chain(Some(data.0.ty)).collect()
             }
             ty::Predicate::WellFormed(data) => {
                 vec![data]
@@ -1206,15 +1202,15 @@ pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>) -> TraitRef<'tcx> {
     }
 
     pub fn self_ty(&self) -> Ty<'tcx> {
-        self.substs.types[0]
+        self.substs.type_at(0)
     }
 
-    pub fn input_types(&self) -> &[Ty<'tcx>] {
+    pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
         // Select only the "input types" from a trait-reference. For
         // now this is all the types that appear in the
         // trait-reference, but it should eventually exclude
         // associated types.
-        &self.substs.types
+        self.substs.types()
     }
 }
 
@@ -1239,7 +1235,7 @@ pub struct ParameterEnvironment<'tcx> {
     /// indicates it must outlive at least the function body (the user
     /// may specify stronger requirements). This field indicates the
     /// region of the callee.
-    pub implicit_region_bound: ty::Region,
+    pub implicit_region_bound: &'tcx ty::Region,
 
     /// Obligations that the caller must satisfy. This is basically
     /// the set of bounds on the in-scope type parameters, translated
@@ -1866,7 +1862,7 @@ fn sized_constraint_for_ty(
                 };
                 let sized_predicate = Binder(TraitRef {
                     def_id: sized_trait,
-                    substs: Substs::new_trait(tcx, vec![], vec![], ty)
+                    substs: Substs::new_trait(tcx, ty, &[])
                 }).to_predicate();
                 let predicates = tcx.lookup_predicates(self.did).predicates;
                 if predicates.into_iter().any(|p| p == sized_predicate) {
@@ -2593,7 +2589,7 @@ pub fn lookup_simd(self, did: DefId) -> bool {
             || self.lookup_repr_hints(did).contains(&attr::ReprSimd)
     }
 
-    pub fn item_variances(self, item_id: DefId) -> Rc<ItemVariances> {
+    pub fn item_variances(self, item_id: DefId) -> Rc<Vec<ty::Variance>> {
         lookup_locally_or_in_crate_store(
             "item_variance_map", item_id, &self.item_variance_map,
             || Rc::new(self.sess.cstore.item_variances(item_id)))
@@ -2827,7 +2823,7 @@ pub fn empty_parameter_environment(self) -> ParameterEnvironment<'tcx> {
         ty::ParameterEnvironment {
             free_substs: Substs::empty(self),
             caller_bounds: Vec::new(),
-            implicit_region_bound: ty::ReEmpty,
+            implicit_region_bound: self.mk_region(ty::ReEmpty),
             free_id_outlive: free_id_outlive
         }
     }
@@ -2843,8 +2839,10 @@ pub fn construct_free_substs(self, def_id: DefId,
 
         let substs = Substs::for_item(self.global_tcx(), def_id, |def, _| {
             // map bound 'a => free 'a
-            ReFree(FreeRegion { scope: free_id_outlive,
-                                bound_region: def.to_bound_region() })
+            self.global_tcx().mk_region(ReFree(FreeRegion {
+                scope: free_id_outlive,
+                bound_region: def.to_bound_region()
+            }))
         }, |def, _| {
             // map T => T
             self.global_tcx().mk_param_from_def(def)
@@ -2894,7 +2892,7 @@ pub fn construct_parameter_environment(self,
 
         let unnormalized_env = ty::ParameterEnvironment {
             free_substs: free_substs,
-            implicit_region_bound: ty::ReScope(free_id_outlive),
+            implicit_region_bound: tcx.mk_region(ty::ReScope(free_id_outlive)),
             caller_bounds: predicates,
             free_id_outlive: free_id_outlive,
         };
@@ -2903,6 +2901,10 @@ pub fn construct_parameter_environment(self,
         traits::normalize_param_env_or_error(tcx, unnormalized_env, cause)
     }
 
+    pub fn node_scope_region(self, id: NodeId) -> &'tcx Region {
+        self.mk_region(ty::ReScope(self.region_maps.node_extent(id)))
+    }
+
     pub fn is_method_call(self, expr_id: NodeId) -> bool {
         self.tables.borrow().method_map.contains_key(&MethodCall::expr(expr_id))
     }
@@ -2912,7 +2914,7 @@ pub fn is_overloaded_autoderef(self, expr_id: NodeId, autoderefs: u32) -> bool {
                                                                             autoderefs))
     }
 
-    pub fn upvar_capture(self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
+    pub fn upvar_capture(self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture<'tcx>> {
         Some(self.tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone())
     }
 
@@ -2938,10 +2940,10 @@ pub fn span_of_impl(self, impl_did: DefId) -> Result<Span, InternedString> {
 
 /// The category of explicit self.
 #[derive(Clone, Copy, Eq, PartialEq, Debug)]
-pub enum ExplicitSelfCategory {
+pub enum ExplicitSelfCategory<'tcx> {
     Static,
     ByValue,
-    ByReference(Region, hir::Mutability),
+    ByReference(&'tcx Region, hir::Mutability),
     ByBox,
 }
 
index ee431681ad100488cb8c49f63d5f9c89766ce529..4d5b38212f600ee43c18bb29500b01c52dfa5853 100644 (file)
@@ -17,7 +17,7 @@
 
 #[derive(Debug)]
 pub enum Component<'tcx> {
-    Region(ty::Region),
+    Region(&'tcx ty::Region),
     Param(ty::ParamTy),
     UnresolvedInferenceVariable(ty::InferTy),
 
@@ -210,7 +210,7 @@ fn capture_components(&self, ty: Ty<'tcx>) -> Vec<Component<'tcx>> {
     }
 }
 
-fn push_region_constraints<'tcx>(out: &mut Vec<Component<'tcx>>, regions: Vec<ty::Region>) {
+fn push_region_constraints<'tcx>(out: &mut Vec<Component<'tcx>>, regions: Vec<&'tcx ty::Region>) {
     for r in regions {
         if !r.is_bound() {
             out.push(Component::Region(r));
index 8975a799be14328bd2ab057dbf7eafe5cf90e4e2..5c157ff32e7bbb846bd256f6b98c9c3315a07b61 100644 (file)
@@ -14,7 +14,7 @@
 //! type equality, etc.
 
 use hir::def_id::DefId;
-use ty::subst::Substs;
+use ty::subst::{Kind, Substs};
 use ty::{self, Ty, TyCtxt, TypeFoldable};
 use ty::error::{ExpectedFound, TypeError};
 use std::rc::Rc;
@@ -71,8 +71,8 @@ fn relate_with_variance<T: Relate<'tcx>>(&mut self,
     fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>)
            -> RelateResult<'tcx, Ty<'tcx>>;
 
-    fn regions(&mut self, a: ty::Region, b: ty::Region)
-               -> RelateResult<'tcx, ty::Region>;
+    fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region)
+               -> RelateResult<'tcx, &'tcx ty::Region>;
 
     fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
                   -> RelateResult<'tcx, ty::Binder<T>>
@@ -139,7 +139,7 @@ fn relate_item_substs<'a, 'gcx, 'tcx, R>(relation: &mut R,
 }
 
 pub fn relate_substs<'a, 'gcx, 'tcx, R>(relation: &mut R,
-                                        variances: Option<&ty::ItemVariances>,
+                                        variances: Option<&Vec<ty::Variance>>,
                                         a_subst: &'tcx Substs<'tcx>,
                                         b_subst: &'tcx Substs<'tcx>)
                                         -> RelateResult<'tcx, &'tcx Substs<'tcx>>
@@ -147,19 +147,18 @@ pub fn relate_substs<'a, 'gcx, 'tcx, R>(relation: &mut R,
 {
     let tcx = relation.tcx();
 
-    let types = a_subst.types.iter().enumerate().map(|(i, a_ty)| {
-        let b_ty = &b_subst.types[i];
-        let variance = variances.map_or(ty::Invariant, |v| v.types[i]);
-        relation.relate_with_variance(variance, a_ty, b_ty)
-    }).collect::<Result<_, _>>()?;
-
-    let regions = a_subst.regions.iter().enumerate().map(|(i, a_r)| {
-        let b_r = &b_subst.regions[i];
-        let variance = variances.map_or(ty::Invariant, |v| v.regions[i]);
-        relation.relate_with_variance(variance, a_r, b_r)
-    }).collect::<Result<_, _>>()?;
+    let params = a_subst.params().iter().zip(b_subst.params()).enumerate().map(|(i, (a, b))| {
+        let variance = variances.map_or(ty::Invariant, |v| v[i]);
+        if let (Some(a_ty), Some(b_ty)) = (a.as_type(), b.as_type()) {
+            Ok(Kind::from(relation.relate_with_variance(variance, &a_ty, &b_ty)?))
+        } else if let (Some(a_r), Some(b_r)) = (a.as_region(), b.as_region()) {
+            Ok(Kind::from(relation.relate_with_variance(variance, &a_r, &b_r)?))
+        } else {
+            bug!()
+        }
+    });
 
-    Ok(Substs::new(tcx, types, regions))
+    Substs::maybe_new(tcx, params)
 }
 
 impl<'tcx> Relate<'tcx> for &'tcx ty::BareFnTy<'tcx> {
@@ -473,9 +472,9 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
 
         (&ty::TyRef(a_r, ref a_mt), &ty::TyRef(b_r, ref b_mt)) =>
         {
-            let r = relation.relate_with_variance(ty::Contravariant, a_r, b_r)?;
+            let r = relation.relate_with_variance(ty::Contravariant, &a_r, &b_r)?;
             let mt = relation.relate(a_mt, b_mt)?;
-            Ok(tcx.mk_ref(tcx.mk_region(r), mt))
+            Ok(tcx.mk_ref(r, mt))
         }
 
         (&ty::TyArray(a_t, sz_a), &ty::TyArray(b_t, sz_b)) =>
@@ -571,11 +570,11 @@ fn relate<'a, 'gcx, R>(relation: &mut R,
     }
 }
 
-impl<'tcx> Relate<'tcx> for ty::Region {
+impl<'tcx> Relate<'tcx> for &'tcx ty::Region {
     fn relate<'a, 'gcx, R>(relation: &mut R,
-                           a: &ty::Region,
-                           b: &ty::Region)
-                           -> RelateResult<'tcx, ty::Region>
+                           a: &&'tcx ty::Region,
+                           b: &&'tcx ty::Region)
+                           -> RelateResult<'tcx, &'tcx ty::Region>
         where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
     {
         relation.regions(*a, *b)
index f7c4b9938c2794da4c37b619277b6346dd2dee9a..705cca056f24c0d9bf5d7095e2546325b477f7d1 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 use infer::type_variable;
-use ty::subst::Substs;
 use ty::{self, Lift, Ty, TyCtxt};
 use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
 
@@ -73,13 +72,6 @@ fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lif
     }
 }
 
-impl<'tcx> Lift<'tcx> for ty::Region {
-    type Lifted = Self;
-    fn lift_to_tcx(&self, _: TyCtxt) -> Option<ty::Region> {
-        Some(*self)
-    }
-}
-
 impl<'a, 'tcx> Lift<'tcx> for ty::TraitRef<'a> {
     type Lifted = ty::TraitRef<'tcx>;
     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
@@ -316,13 +308,21 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lif
             FixedArraySize(x) => FixedArraySize(x),
             TyParamSize(x) => TyParamSize(x),
             ArgCount => ArgCount,
-            RegionsDoesNotOutlive(a, b) => RegionsDoesNotOutlive(a, b),
-            RegionsNotSame(a, b) => RegionsNotSame(a, b),
-            RegionsNoOverlap(a, b) => RegionsNoOverlap(a, b),
+            RegionsDoesNotOutlive(a, b) => {
+                return tcx.lift(&(a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b))
+            }
+            RegionsNotSame(a, b) => {
+                return tcx.lift(&(a, b)).map(|(a, b)| RegionsNotSame(a, b))
+            }
+            RegionsNoOverlap(a, b) => {
+                return tcx.lift(&(a, b)).map(|(a, b)| RegionsNoOverlap(a, b))
+            }
             RegionsInsufficientlyPolymorphic(a, b) => {
-                RegionsInsufficientlyPolymorphic(a, b)
+                return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b))
+            }
+            RegionsOverlyPolymorphic(a, b) => {
+                return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b))
             }
-            RegionsOverlyPolymorphic(a, b) => RegionsOverlyPolymorphic(a, b),
             IntegerAsChar => IntegerAsChar,
             IntMismatch(x) => IntMismatch(x),
             FloatMismatch(x) => FloatMismatch(x),
@@ -655,7 +655,7 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
     }
 }
 
-impl<'tcx> TypeFoldable<'tcx> for ty::Region {
+impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Region {
     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
         *self
     }
@@ -673,41 +673,6 @@ fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
     }
 }
 
-impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Region {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
-        *self
-    }
-
-    fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
-        let region = folder.fold_region(**self);
-        folder.tcx().mk_region(region)
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
-        false
-    }
-
-    fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        visitor.visit_region(**self)
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for &'tcx Substs<'tcx> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
-        let types = self.types.fold_with(folder);
-        let regions = self.regions.fold_with(folder);
-        Substs::new(folder.tcx(), types, regions)
-    }
-
-    fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
-        folder.fold_substs(self)
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.types.visit_with(visitor) || self.regions.visit_with(visitor)
-    }
-}
-
 impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> {
     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
         ty::ClosureSubsts {
@@ -783,7 +748,7 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
     }
 }
 
-impl<'tcx> TypeFoldable<'tcx> for ty::ObjectLifetimeDefault {
+impl<'tcx> TypeFoldable<'tcx> for ty::ObjectLifetimeDefault<'tcx> {
     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
         match *self {
             ty::ObjectLifetimeDefault::Ambiguous =>
@@ -805,7 +770,7 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
     }
 }
 
-impl<'tcx> TypeFoldable<'tcx> for ty::RegionParameterDef {
+impl<'tcx> TypeFoldable<'tcx> for ty::RegionParameterDef<'tcx> {
     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
         ty::RegionParameterDef {
             name: self.name,
index 8aa81cc4743c9a639c598863af8fd956f5986215..0e3f18c4474eaed1b91788ee56b3c298eb38f7aa 100644 (file)
@@ -19,8 +19,8 @@
 
 use collections::enum_set::{self, EnumSet, CLike};
 use std::fmt;
-use std::ops;
 use std::mem;
+use std::ops;
 use syntax::abi;
 use syntax::ast::{self, Name};
 use syntax::parse::token::keywords;
@@ -293,7 +293,7 @@ fn decode<D: Decoder>(d: &mut D) -> Result<ClosureSubsts<'tcx>, D::Error> {
 #[derive(Clone, PartialEq, Eq, Hash)]
 pub struct TraitObject<'tcx> {
     pub principal: PolyExistentialTraitRef<'tcx>,
-    pub region_bound: ty::Region,
+    pub region_bound: &'tcx ty::Region,
     pub builtin_bounds: BuiltinBounds,
     pub projection_bounds: Vec<PolyExistentialProjection<'tcx>>,
 }
@@ -335,7 +335,7 @@ pub fn substs(&self) -> &'tcx Substs<'tcx> {
         self.0.substs
     }
 
-    pub fn input_types(&self) -> &[Ty<'tcx>] {
+    pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
         // FIXME(#20664) every use of this fn is probably a bug, it should yield Binder<>
         self.0.input_types()
     }
@@ -360,12 +360,12 @@ pub struct ExistentialTraitRef<'tcx> {
 }
 
 impl<'tcx> ExistentialTraitRef<'tcx> {
-    pub fn input_types(&self) -> &[Ty<'tcx>] {
+    pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
         // Select only the "input types" from a trait-reference. For
         // now this is all the types that appear in the
         // trait-reference, but it should eventually exclude
         // associated types.
-        &self.substs.types
+        self.substs.types()
     }
 }
 
@@ -376,7 +376,7 @@ pub fn def_id(&self) -> DefId {
         self.0.def_id
     }
 
-    pub fn input_types(&self) -> &[Ty<'tcx>] {
+    pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
         // FIXME(#20664) every use of this fn is probably a bug, it should yield Binder<>
         self.0.input_types()
     }
@@ -675,6 +675,15 @@ pub enum Region {
     ReErased,
 }
 
+impl<'tcx> Decodable for &'tcx Region {
+    fn decode<D: Decoder>(d: &mut D) -> Result<&'tcx Region, D::Error> {
+        let r = Decodable::decode(d)?;
+        cstore::tls::with_decoding_context(d, |dcx, _| {
+            Ok(dcx.tcx().mk_region(r))
+        })
+    }
+}
+
 #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
 pub struct EarlyBoundRegion {
     pub index: u32,
@@ -1206,26 +1215,26 @@ pub fn ty_adt_def(&self) -> Option<AdtDef<'tcx>> {
     /// Returns the regions directly referenced from this type (but
     /// not types reachable from this type via `walk_tys`). This
     /// ignores late-bound regions binders.
-    pub fn regions(&self) -> Vec<ty::Region> {
+    pub fn regions(&self) -> Vec<&'tcx ty::Region> {
         match self.sty {
             TyRef(region, _) => {
-                vec![*region]
+                vec![region]
             }
             TyTrait(ref obj) => {
                 let mut v = vec![obj.region_bound];
-                v.extend_from_slice(&obj.principal.skip_binder().substs.regions);
+                v.extend(obj.principal.skip_binder().substs.regions());
                 v
             }
             TyEnum(_, substs) |
             TyStruct(_, substs) |
             TyAnon(_, substs) => {
-                substs.regions.to_vec()
+                substs.regions().collect()
             }
             TyClosure(_, ref substs) => {
-                substs.func_substs.regions.to_vec()
+                substs.func_substs.regions().collect()
             }
             TyProjection(ref data) => {
-                data.trait_ref.substs.regions.to_vec()
+                data.trait_ref.substs.regions().collect()
             }
             TyFnDef(..) |
             TyFnPtr(_) |
index e1a19a7b7992ece6edcae09a1b47a11f422cbaea..0ccfea23309999d96d3fdbfa03151764824aa90a 100644 (file)
 use middle::cstore;
 use hir::def_id::DefId;
 use ty::{self, Ty, TyCtxt};
-use ty::fold::{TypeFoldable, TypeFolder};
+use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
 
 use serialize::{Encodable, Encoder, Decodable, Decoder};
 use syntax_pos::{Span, DUMMY_SP};
 
-///////////////////////////////////////////////////////////////////////////
+use core::nonzero::NonZero;
+use std::fmt;
+use std::iter;
+use std::marker::PhantomData;
+use std::mem;
+
+/// An entity in the Rust typesystem, which can be one of
+/// several kinds (only types and lifetimes for now).
+/// To reduce memory usage, a `Kind` is a interned pointer,
+/// with the lowest 2 bits being reserved for a tag to
+/// indicate the type (`Ty` or `Region`) it points to.
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
+pub struct Kind<'tcx> {
+    ptr: NonZero<usize>,
+    marker: PhantomData<(Ty<'tcx>, &'tcx ty::Region)>
+}
+
+const TAG_MASK: usize = 0b11;
+const TYPE_TAG: usize = 0b00;
+const REGION_TAG: usize = 0b01;
+
+impl<'tcx> From<Ty<'tcx>> for Kind<'tcx> {
+    fn from(ty: Ty<'tcx>) -> Kind<'tcx> {
+        // Ensure we can use the tag bits.
+        assert_eq!(mem::align_of_val(ty) & TAG_MASK, 0);
+
+        let ptr = ty as *const _ as usize;
+        Kind {
+            ptr: unsafe {
+                NonZero::new(ptr | TYPE_TAG)
+            },
+            marker: PhantomData
+        }
+    }
+}
+
+impl<'tcx> From<&'tcx ty::Region> for Kind<'tcx> {
+    fn from(r: &'tcx ty::Region) -> Kind<'tcx> {
+        // Ensure we can use the tag bits.
+        assert_eq!(mem::align_of_val(r) & TAG_MASK, 0);
+
+        let ptr = r as *const _ as usize;
+        Kind {
+            ptr: unsafe {
+                NonZero::new(ptr | REGION_TAG)
+            },
+            marker: PhantomData
+        }
+    }
+}
+
+impl<'tcx> Kind<'tcx> {
+    #[inline]
+    unsafe fn downcast<T>(self, tag: usize) -> Option<&'tcx T> {
+        let ptr = *self.ptr;
+        if ptr & TAG_MASK == tag {
+            Some(&*((ptr & !TAG_MASK) as *const _))
+        } else {
+            None
+        }
+    }
+
+    #[inline]
+    pub fn as_type(self) -> Option<Ty<'tcx>> {
+        unsafe {
+            self.downcast(TYPE_TAG)
+        }
+    }
+
+    #[inline]
+    pub fn as_region(self) -> Option<&'tcx ty::Region> {
+        unsafe {
+            self.downcast(REGION_TAG)
+        }
+    }
+}
+
+impl<'tcx> fmt::Debug for Kind<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        if let Some(ty) = self.as_type() {
+            write!(f, "{:?}", ty)
+        } else if let Some(r) = self.as_region() {
+            write!(f, "{:?}", r)
+        } else {
+            write!(f, "<unknwon @ {:p}>", *self.ptr as *const ())
+        }
+    }
+}
+
+impl<'tcx> TypeFoldable<'tcx> for Kind<'tcx> {
+    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+        if let Some(ty) = self.as_type() {
+            Kind::from(ty.fold_with(folder))
+        } else if let Some(r) = self.as_region() {
+            Kind::from(r.fold_with(folder))
+        } else {
+            bug!()
+        }
+    }
+
+    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
+        if let Some(ty) = self.as_type() {
+            ty.visit_with(visitor)
+        } else if let Some(r) = self.as_region() {
+            r.visit_with(visitor)
+        } else {
+            bug!()
+        }
+    }
+}
 
 /// A substitution mapping type/region parameters to new values.
-#[derive(Clone, PartialEq, Eq, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct Substs<'tcx> {
-    pub types: Vec<Ty<'tcx>>,
-    pub regions: Vec<ty::Region>,
+    params: Vec<Kind<'tcx>>
 }
 
 impl<'a, 'gcx, 'tcx> Substs<'tcx> {
-    pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
-               t: Vec<Ty<'tcx>>,
-               r: Vec<ty::Region>)
-               -> &'tcx Substs<'tcx>
-    {
-        tcx.mk_substs(Substs { types: t, regions: r })
+    pub fn new<I>(tcx: TyCtxt<'a, 'gcx, 'tcx>, params: I)
+                  -> &'tcx Substs<'tcx>
+    where I: IntoIterator<Item=Kind<'tcx>> {
+        tcx.mk_substs(Substs {
+            params: params.into_iter().collect()
+        })
+    }
+
+    pub fn maybe_new<I, E>(tcx: TyCtxt<'a, 'gcx, 'tcx>, params: I)
+                           -> Result<&'tcx Substs<'tcx>, E>
+    where I: IntoIterator<Item=Result<Kind<'tcx>, E>> {
+        Ok(tcx.mk_substs(Substs {
+            params: params.into_iter().collect::<Result<_, _>>()?
+        }))
     }
 
     pub fn new_trait(tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                     mut t: Vec<Ty<'tcx>>,
-                     r: Vec<ty::Region>,
-                     s: Ty<'tcx>)
+                     s: Ty<'tcx>,
+                     t: &[Ty<'tcx>])
                     -> &'tcx Substs<'tcx>
     {
-        t.insert(0, s);
-        Substs::new(tcx, t, r)
+        let t = iter::once(s).chain(t.iter().cloned());
+        Substs::new(tcx, t.map(Kind::from))
     }
 
     pub fn empty(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx Substs<'tcx> {
-        Substs::new(tcx, vec![], vec![])
+        Substs::new(tcx, vec![])
     }
 
     /// Creates a Substs for generic parameter definitions,
@@ -60,19 +175,16 @@ pub fn for_item<FR, FT>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                             mut mk_region: FR,
                             mut mk_type: FT)
                             -> &'tcx Substs<'tcx>
-    where FR: FnMut(&ty::RegionParameterDef, &Substs<'tcx>) -> ty::Region,
+    where FR: FnMut(&ty::RegionParameterDef, &Substs<'tcx>) -> &'tcx ty::Region,
           FT: FnMut(&ty::TypeParameterDef<'tcx>, &Substs<'tcx>) -> Ty<'tcx> {
         let defs = tcx.lookup_generics(def_id);
-        let num_regions = defs.parent_regions as usize + defs.regions.len();
-        let num_types = defs.parent_types as usize + defs.types.len();
         let mut substs = Substs {
-            regions: Vec::with_capacity(num_regions),
-            types: Vec::with_capacity(num_types)
+            params: Vec::with_capacity(defs.count())
         };
 
         substs.fill_item(tcx, defs, &mut mk_region, &mut mk_type);
 
-        Substs::new(tcx, substs.types, substs.regions)
+        tcx.mk_substs(substs)
     }
 
     fn fill_item<FR, FT>(&mut self,
@@ -80,36 +192,76 @@ fn fill_item<FR, FT>(&mut self,
                          defs: &ty::Generics<'tcx>,
                          mk_region: &mut FR,
                          mk_type: &mut FT)
-    where FR: FnMut(&ty::RegionParameterDef, &Substs<'tcx>) -> ty::Region,
+    where FR: FnMut(&ty::RegionParameterDef, &Substs<'tcx>) -> &'tcx ty::Region,
           FT: FnMut(&ty::TypeParameterDef<'tcx>, &Substs<'tcx>) -> Ty<'tcx> {
         if let Some(def_id) = defs.parent {
             let parent_defs = tcx.lookup_generics(def_id);
             self.fill_item(tcx, parent_defs, mk_region, mk_type);
         }
 
+        // Handle Self first, before all regions.
+        let mut types = defs.types.iter();
+        if defs.parent.is_none() && defs.has_self {
+            let def = types.next().unwrap();
+            let ty = mk_type(def, self);
+            assert_eq!(def.index as usize, self.params.len());
+            self.params.push(Kind::from(ty));
+        }
+
         for def in &defs.regions {
             let region = mk_region(def, self);
-            assert_eq!(def.index as usize, self.regions.len());
-            self.regions.push(region);
+            assert_eq!(def.index as usize, self.params.len());
+            self.params.push(Kind::from(region));
         }
 
-        for def in &defs.types {
+        for def in types {
             let ty = mk_type(def, self);
-            assert_eq!(def.index as usize, self.types.len());
-            self.types.push(ty);
+            assert_eq!(def.index as usize, self.params.len());
+            self.params.push(Kind::from(ty));
         }
     }
 
     pub fn is_noop(&self) -> bool {
-        self.regions.is_empty() && self.types.is_empty()
+        self.params.is_empty()
+    }
+
+    #[inline]
+    pub fn params(&self) -> &[Kind<'tcx>] {
+        &self.params
+    }
+
+    #[inline]
+    pub fn types(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
+        self.params.iter().filter_map(|k| k.as_type())
+    }
+
+    #[inline]
+    pub fn regions(&'a self) -> impl DoubleEndedIterator<Item=&'tcx ty::Region> + 'a {
+        self.params.iter().filter_map(|k| k.as_region())
+    }
+
+    #[inline]
+    pub fn type_at(&self, i: usize) -> Ty<'tcx> {
+        self.params[i].as_type().unwrap_or_else(|| {
+            bug!("expected type for param #{} in {:?}", i, self.params);
+        })
     }
 
+    #[inline]
+    pub fn region_at(&self, i: usize) -> &'tcx ty::Region {
+        self.params[i].as_region().unwrap_or_else(|| {
+            bug!("expected region for param #{} in {:?}", i, self.params);
+        })
+    }
+
+    #[inline]
     pub fn type_for_def(&self, ty_param_def: &ty::TypeParameterDef) -> Ty<'tcx> {
-        self.types[ty_param_def.index as usize]
+        self.type_at(ty_param_def.index as usize)
     }
 
-    pub fn region_for_def(&self, def: &ty::RegionParameterDef) -> ty::Region {
-        self.regions[def.index as usize]
+    #[inline]
+    pub fn region_for_def(&self, def: &ty::RegionParameterDef) -> &'tcx ty::Region {
+        self.region_at(def.index as usize)
     }
 
     /// Transform from substitutions for a child of `source_ancestor`
@@ -122,11 +274,27 @@ pub fn rebase_onto(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
                        target_substs: &Substs<'tcx>)
                        -> &'tcx Substs<'tcx> {
         let defs = tcx.lookup_generics(source_ancestor);
-        let regions = target_substs.regions.iter()
-            .chain(&self.regions[defs.regions.len()..]).cloned().collect();
-        let types = target_substs.types.iter()
-            .chain(&self.types[defs.types.len()..]).cloned().collect();
-        Substs::new(tcx, types, regions)
+        tcx.mk_substs(Substs {
+            params: target_substs.params.iter()
+                .chain(&self.params[defs.own_count()..]).cloned().collect()
+        })
+    }
+}
+
+impl<'tcx> TypeFoldable<'tcx> for &'tcx Substs<'tcx> {
+    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+        let params = self.params.iter().map(|k| k.fold_with(folder)).collect();
+        folder.tcx().mk_substs(Substs {
+            params: params
+        })
+    }
+
+    fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+        folder.fold_substs(self)
+    }
+
+    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
+        self.params.visit_with(visitor)
     }
 }
 
@@ -215,16 +383,18 @@ fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> ty::Binde
         t
     }
 
-    fn fold_region(&mut self, r: ty::Region) -> ty::Region {
+    fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
         // Note: This routine only handles regions that are bound on
         // type declarations and other outer declarations, not those
         // bound in *fn types*. Region substitution of the bound
         // regions that appear in a function signature is done using
         // the specialized routine `ty::replace_late_regions()`.
-        match r {
+        match *r {
             ty::ReEarlyBound(data) => {
-                match self.substs.regions.get(data.index as usize) {
-                    Some(&r) => {
+                let r = self.substs.params.get(data.index as usize)
+                            .and_then(|k| k.as_region());
+                match r {
+                    Some(r) => {
                         self.shift_region_through_binders(r)
                     }
                     None => {
@@ -278,9 +448,10 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
 impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
     fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>) -> Ty<'tcx> {
         // Look up the type in the substitutions. It really should be in there.
-        let opt_ty = self.substs.types.get(p.idx as usize);
+        let opt_ty = self.substs.params.get(p.idx as usize)
+                         .and_then(|k| k.as_type());
         let ty = match opt_ty {
-            Some(t) => *t,
+            Some(t) => t,
             None => {
                 let span = self.span.unwrap_or(DUMMY_SP);
                 span_bug!(
@@ -291,7 +462,7 @@ fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>) -> Ty<'tcx> {
                     source_ty,
                     p.idx,
                     self.root_ty,
-                    self.substs);
+                    self.substs.params);
             }
         };
 
@@ -354,8 +525,8 @@ fn shift_regions_through_binders(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
         result
     }
 
-    fn shift_region_through_binders(&self, region: ty::Region) -> ty::Region {
-        ty::fold::shift_region(region, self.region_binders_passed)
+    fn shift_region_through_binders(&self, region: &'tcx ty::Region) -> &'tcx ty::Region {
+        self.tcx().mk_region(ty::fold::shift_region(*region, self.region_binders_passed))
     }
 }
 
@@ -367,12 +538,11 @@ pub fn from_method(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                        substs: &Substs<'tcx>)
                        -> ty::TraitRef<'tcx> {
         let defs = tcx.lookup_generics(trait_id);
-        let regions = substs.regions[..defs.regions.len()].to_vec();
-        let types = substs.types[..defs.types.len()].to_vec();
 
+        let params = substs.params[..defs.own_count()].iter().cloned();
         ty::TraitRef {
             def_id: trait_id,
-            substs: Substs::new(tcx, types, regions)
+            substs: Substs::new(tcx, params)
         }
     }
 }
@@ -381,13 +551,13 @@ impl<'a, 'gcx, 'tcx> ty::ExistentialTraitRef<'tcx> {
     pub fn erase_self_ty(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                          trait_ref: ty::TraitRef<'tcx>)
                          -> ty::ExistentialTraitRef<'tcx> {
-        let Substs { mut types, regions } = trait_ref.substs.clone();
-
-        types.remove(0);
+        // Assert there is a Self.
+        trait_ref.substs.type_at(0);
 
+        let params = trait_ref.substs.params[1..].iter().cloned();
         ty::ExistentialTraitRef {
             def_id: trait_ref.def_id,
-            substs: Substs::new(tcx, types, regions)
+            substs: Substs::new(tcx, params)
         }
     }
 }
@@ -404,13 +574,11 @@ pub fn with_self_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
         assert!(!self_ty.has_escaping_regions());
 
         self.map_bound(|trait_ref| {
-            let Substs { mut types, regions } = trait_ref.substs.clone();
-
-            types.insert(0, self_ty);
-
+            let params = trait_ref.substs.params.iter().cloned();
+            let params = iter::once(Kind::from(self_ty)).chain(params);
             ty::TraitRef {
                 def_id: trait_ref.def_id,
-                substs: Substs::new(tcx, types, regions)
+                substs: Substs::new(tcx, params)
             }
         })
     }
index 51710c13a7deacb9f389d0735be5376747d6784f..dd5c6a9758abf263d49b0960d8b684932b141d56 100644 (file)
@@ -306,7 +306,7 @@ pub fn struct_lockstep_tails(self,
     pub fn required_region_bounds(self,
                                   erased_self_ty: Ty<'tcx>,
                                   predicates: Vec<ty::Predicate<'tcx>>)
-                                  -> Vec<ty::Region>    {
+                                  -> Vec<&'tcx ty::Region>    {
         debug!("required_region_bounds(erased_self_ty={:?}, predicates={:?})",
                erased_self_ty,
                predicates);
@@ -496,8 +496,8 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
         ty.super_visit_with(self)
     }
 
-    fn visit_region(&mut self, r: ty::Region) -> bool {
-        match r {
+    fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
+        match *r {
             ty::ReStatic | ty::ReErased => {
                 self.hash::<u32>(0);
             }
@@ -693,10 +693,7 @@ fn same_type<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
                         return false;
                     }
 
-                    let types_a = &substs_a.types;
-                    let types_b = &substs_b.types;
-
-                    types_a.iter().zip(types_b).all(|(&a, &b)| same_type(a, b))
+                    substs_a.types().zip(substs_b.types()).all(|(a, b)| same_type(a, b))
                 }
                 _ => {
                     a == b
index 8a9ee45351dfc26c73813eb2835e8e368570f9a9..409f5a85997bda10eb0fff2eb5b76b28862d6a61 100644 (file)
@@ -67,6 +67,12 @@ pub fn walk_shallow<'tcx>(ty: Ty<'tcx>) -> IntoIter<Ty<'tcx>> {
     stack.into_iter()
 }
 
+// We push types on the stack in reverse order so as to
+// maintain a pre-order traversal. As of the time of this
+// writing, the fact that the traversal is pre-order is not
+// known to be significant to any code, but it seems like the
+// natural order one would expect (basically, the order of the
+// types as they are written).
 fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) {
     match parent_ty.sty {
         ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) |
@@ -79,28 +85,28 @@ fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) {
             stack.push(mt.ty);
         }
         ty::TyProjection(ref data) => {
-            push_reversed(stack, &data.trait_ref.substs.types);
+            stack.extend(data.trait_ref.substs.types().rev());
         }
         ty::TyTrait(ref obj) => {
-            push_reversed(stack, obj.principal.input_types());
-            push_reversed(stack, &obj.projection_bounds.iter().map(|pred| {
+            stack.extend(obj.principal.input_types().rev());
+            stack.extend(obj.projection_bounds.iter().map(|pred| {
                 pred.0.ty
-            }).collect::<Vec<_>>());
+            }).rev());
         }
         ty::TyEnum(_, ref substs) |
         ty::TyStruct(_, ref substs) |
         ty::TyAnon(_, ref substs) => {
-            push_reversed(stack, &substs.types);
+            stack.extend(substs.types().rev());
         }
         ty::TyClosure(_, ref substs) => {
-            push_reversed(stack, &substs.func_substs.types);
-            push_reversed(stack, &substs.upvar_tys);
+            stack.extend(substs.func_substs.types().rev());
+            stack.extend(substs.upvar_tys.iter().cloned().rev());
         }
-        ty::TyTuple(ref ts) => {
-            push_reversed(stack, ts);
+        ty::TyTuple(ts) => {
+            stack.extend(ts.iter().cloned().rev());
         }
         ty::TyFnDef(_, substs, ref ft) => {
-            push_reversed(stack, &substs.types);
+            stack.extend(substs.types().rev());
             push_sig_subtypes(stack, &ft.sig);
         }
         ty::TyFnPtr(ref ft) => {
@@ -111,17 +117,5 @@ fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) {
 
 fn push_sig_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, sig: &ty::PolyFnSig<'tcx>) {
     stack.push(sig.0.output);
-    push_reversed(stack, &sig.0.inputs);
-}
-
-fn push_reversed<'tcx>(stack: &mut Vec<Ty<'tcx>>, tys: &[Ty<'tcx>]) {
-    // We push slices on the stack in reverse order so as to
-    // maintain a pre-order traversal. As of the time of this
-    // writing, the fact that the traversal is pre-order is not
-    // known to be significant to any code, but it seems like the
-    // natural order one would expect (basically, the order of the
-    // types as they are written).
-    for &ty in tys.iter().rev() {
-        stack.push(ty);
-    }
+    stack.extend(sig.0.inputs.iter().cloned().rev());
 }
index 54b19362b1d86e43afd1b1c36b5a089f95b374c2..1f166cb192fa33c0c686066909f8dea6026315d8 100644 (file)
@@ -115,9 +115,9 @@ pub fn predicate_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
 /// For `&'a T` to be WF, `T: 'a` must hold. So we can assume `T: 'a`.
 #[derive(Debug)]
 pub enum ImpliedBound<'tcx> {
-    RegionSubRegion(ty::Region, ty::Region),
-    RegionSubParam(ty::Region, ty::ParamTy),
-    RegionSubProjection(ty::Region, ty::ProjectionTy<'tcx>),
+    RegionSubRegion(&'tcx ty::Region, &'tcx ty::Region),
+    RegionSubParam(&'tcx ty::Region, ty::ParamTy),
+    RegionSubProjection(&'tcx ty::Region, ty::ProjectionTy<'tcx>),
 }
 
 /// Compute the implied bounds that a callee/impl can assume based on
@@ -196,7 +196,7 @@ pub fn implied_bounds<'a, 'gcx, 'tcx>(
 /// this down to determine what relationships would have to hold for
 /// `T: 'a` to hold. We get to assume that the caller has validated
 /// those relationships.
-fn implied_bounds_from_components<'tcx>(sub_region: ty::Region,
+fn implied_bounds_from_components<'tcx>(sub_region: &'tcx ty::Region,
                                         sup_components: Vec<Component<'tcx>>)
                                         -> Vec<ImpliedBound<'tcx>>
 {
@@ -260,8 +260,7 @@ fn compute_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>) {
 
         let cause = self.cause(traits::MiscObligation);
         self.out.extend(
-            trait_ref.substs.types
-                            .iter()
+            trait_ref.substs.types()
                             .filter(|ty| !ty.has_escaping_regions())
                             .map(|ty| traits::Obligation::new(cause.clone(),
                                                               ty::Predicate::WellFormed(ty))));
@@ -364,7 +363,7 @@ fn compute(&mut self, ty0: Ty<'tcx>) -> bool {
                                 cause,
                                 ty::Predicate::TypeOutlives(
                                     ty::Binder(
-                                        ty::OutlivesPredicate(mt.ty, *r)))));
+                                        ty::OutlivesPredicate(mt.ty, r)))));
                     }
                 }
 
@@ -535,7 +534,7 @@ pub fn object_region_bounds<'a, 'gcx, 'tcx>(
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
     principal: ty::PolyExistentialTraitRef<'tcx>,
     others: ty::BuiltinBounds)
-    -> Vec<ty::Region>
+    -> Vec<&'tcx ty::Region>
 {
     // Since we don't actually *know* the self type for an object,
     // this "open(err)" serves as a kind of dummy standin -- basically
index 02ad8fb7033ed2d50d9900bf2fe2d42864cd9748..24b68c66e46673d3934f33227212987a1a66bf22 100644 (file)
@@ -22,6 +22,8 @@
 
 use std::cell::Cell;
 use std::fmt;
+use std::usize;
+
 use syntax::abi::Abi;
 use syntax::parse::token;
 use syntax::ast::CRATE_NODE_ID;
@@ -80,15 +82,17 @@ pub fn parameterized(f: &mut fmt::Formatter,
         verbose = tcx.sess.verbose();
         has_self = generics.has_self;
 
+        let mut child_types = 0;
         if let Some(def_id) = generics.parent {
             // Methods.
             assert_eq!(ns, Ns::Value);
+            child_types = generics.types.len();
             generics = tcx.lookup_generics(def_id);
             num_regions = generics.regions.len();
             num_types = generics.types.len();
 
             if has_self {
-                write!(f, "<{} as ", substs.types[0])?;
+                write!(f, "<{} as ", substs.type_at(0))?;
             }
 
             item_name = Some(tcx.item_name(did));
@@ -107,8 +111,8 @@ pub fn parameterized(f: &mut fmt::Formatter,
         if !verbose {
             if generics.types.last().map_or(false, |def| def.default.is_some()) {
                 if let Some(substs) = tcx.lift(&substs) {
-                    let tps = &substs.types[..num_types];
-                    for (def, actual) in generics.types.iter().zip(tps).rev() {
+                    let tps = substs.types().rev().skip(child_types);
+                    for (def, actual) in generics.types.iter().rev().zip(tps) {
                         if def.default.subst(tcx, substs) != Some(actual) {
                             break;
                         }
@@ -124,7 +128,7 @@ pub fn parameterized(f: &mut fmt::Formatter,
 
     if !verbose && fn_trait_kind.is_some() && projections.len() == 1 {
         let projection_ty = projections[0].ty;
-        if let TyTuple(ref args) = substs.types[1].sty {
+        if let TyTuple(ref args) = substs.type_at(1).sty {
             return fn_sig(f, args, false, projection_ty);
         }
     }
@@ -139,13 +143,15 @@ pub fn parameterized(f: &mut fmt::Formatter,
         }
     };
 
-    let print_regions = |f: &mut fmt::Formatter, start: &str, regions: &[ty::Region]| {
+    let print_regions = |f: &mut fmt::Formatter, start: &str, skip, count| {
         // Don't print any regions if they're all erased.
-        if regions.iter().all(|r| *r == ty::ReErased) {
+        let regions = || substs.regions().skip(skip).take(count);
+        if regions().all(|r: &ty::Region| *r == ty::ReErased) {
             return Ok(());
         }
 
-        for region in regions {
+        for region in regions() {
+            let region: &ty::Region = region;
             start_or_continue(f, start, ", ")?;
             if verbose {
                 write!(f, "{:?}", region)?;
@@ -167,11 +173,12 @@ pub fn parameterized(f: &mut fmt::Formatter,
         Ok(())
     };
 
-    print_regions(f, "<", &substs.regions[..num_regions])?;
+    print_regions(f, "<", 0, num_regions)?;
 
-    let tps = &substs.types[..num_types];
+    let tps = substs.types().take(num_types - num_supplied_defaults)
+                            .skip(has_self as usize);
 
-    for &ty in &tps[has_self as usize..tps.len() - num_supplied_defaults] {
+    for ty in tps {
         start_or_continue(f, "<", ", ")?;
         write!(f, "{}", ty)?;
     }
@@ -197,10 +204,10 @@ pub fn parameterized(f: &mut fmt::Formatter,
             write!(f, "::{}", item_name)?;
         }
 
-        print_regions(f, "::<", &substs.regions[num_regions..])?;
+        print_regions(f, "::<", num_regions, usize::MAX)?;
 
         // FIXME: consider being smart with defaults here too
-        for ty in &substs.types[num_types..] {
+        for ty in substs.types().skip(num_types) {
             start_or_continue(f, "::<", ", ")?;
             write!(f, "{}", ty)?;
         }
@@ -240,7 +247,7 @@ fn in_binder<'a, 'gcx, 'tcx, T, U>(f: &mut fmt::Formatter,
 
     let new_value = tcx.replace_late_bound_regions(&value, |br| {
         let _ = start_or_continue(f, "for<", ", ");
-        ty::ReLateBound(ty::DebruijnIndex::new(1), match br {
+        let br = match br {
             ty::BrNamed(_, name, _) => {
                 let _ = write!(f, "{}", name);
                 br
@@ -254,7 +261,8 @@ fn in_binder<'a, 'gcx, 'tcx, T, U>(f: &mut fmt::Formatter,
                             name,
                             ty::Issue32330::WontChange)
             }
-        })
+        };
+        tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), br))
     }).0;
 
     start_or_continue(f, "", "> ")?;
@@ -344,7 +352,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl fmt::Debug for ty::RegionParameterDef {
+impl<'tcx> fmt::Debug for ty::RegionParameterDef<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "RegionParameterDef({}, {:?}, {}, {:?})",
                self.name,
@@ -368,13 +376,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl<'tcx> fmt::Debug for Substs<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "Substs[types={:?}, regions={:?}]",
-               self.types, self.regions)
-    }
-}
-
 impl<'tcx> fmt::Debug for ty::ItemSubsts<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "ItemSubsts({:?})", self.substs)
@@ -598,7 +599,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl<'tcx> fmt::Debug for ty::ObjectLifetimeDefault {
+impl<'tcx> fmt::Debug for ty::ObjectLifetimeDefault<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             ty::ObjectLifetimeDefault::Ambiguous => write!(f, "Ambiguous"),
@@ -654,13 +655,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl fmt::Debug for ty::ItemVariances {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "ItemVariances(types={:?}, regions={:?})",
-               self.types, self.regions)
-    }
-}
-
 impl<'tcx> fmt::Debug for ty::GenericPredicates<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "GenericPredicates({:?})", self.predicates)
@@ -793,13 +787,14 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region>> {
+impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, &'tcx ty::Region>> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
     }
 }
 
-impl fmt::Display for ty::Binder<ty::OutlivesPredicate<ty::Region, ty::Region>> {
+impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<&'tcx ty::Region,
+                                                             &'tcx ty::Region>> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
     }
@@ -973,7 +968,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl fmt::Debug for ty::UpvarBorrow {
+impl<'tcx> fmt::Debug for ty::UpvarBorrow<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "UpvarBorrow({:?}, {:?})",
                self.kind, self.region)
@@ -997,7 +992,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl fmt::Display for ty::ExplicitSelfCategory {
+impl<'tcx> fmt::Display for ty::ExplicitSelfCategory<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.write_str(match *self {
             ty::ExplicitSelfCategory::Static => "static",
index c1f162e5772bf41d81cffac9fa3a52bff9481341..e86fa9a05f372c4eb1e2503a5a996a6855ac74c8 100644 (file)
@@ -126,7 +126,7 @@ fn borrow(&mut self,
               borrow_id: ast::NodeId,
               borrow_span: Span,
               cmt: mc::cmt<'tcx>,
-              loan_region: ty::Region,
+              loan_region: &'tcx ty::Region,
               bk: ty::BorrowKind,
               loan_cause: euv::LoanCause)
     {
index 667bf16874ec4df7165acfc0d41da0076e67334e..9f95175d59d439217bdc5b9e3642b38e2640943b 100644 (file)
@@ -28,7 +28,7 @@ pub fn guarantee_lifetime<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
                                     span: Span,
                                     cause: euv::LoanCause,
                                     cmt: mc::cmt<'tcx>,
-                                    loan_region: ty::Region,
+                                    loan_region: &'tcx ty::Region,
                                     _: ty::BorrowKind)
                                     -> Result<(),()> {
     //! Reports error if `loan_region` is larger than S
@@ -56,7 +56,7 @@ struct GuaranteeLifetimeContext<'a, 'tcx: 'a> {
 
     span: Span,
     cause: euv::LoanCause,
-    loan_region: ty::Region,
+    loan_region: &'tcx ty::Region,
     cmt_original: mc::cmt<'tcx>
 }
 
@@ -92,7 +92,7 @@ fn check(&self, cmt: &mc::cmt<'tcx>, discr_scope: Option<ast::NodeId>) -> R {
         }
     }
 
-    fn check_scope(&self, max_scope: ty::Region) -> R {
+    fn check_scope(&self, max_scope: &'tcx ty::Region) -> R {
         //! Reports an error if `loan_region` is larger than `max_scope`
 
         if !self.bccx.is_subregion_of(self.loan_region, max_scope) {
@@ -102,7 +102,7 @@ fn check_scope(&self, max_scope: ty::Region) -> R {
         }
     }
 
-    fn scope(&self, cmt: &mc::cmt) -> ty::Region {
+    fn scope(&self, cmt: &mc::cmt<'tcx>) -> &'tcx ty::Region {
         //! Returns the maximal region scope for the which the
         //! lvalue `cmt` is guaranteed to be valid without any
         //! rooting etc, and presuming `cmt` is not mutated.
@@ -112,16 +112,15 @@ fn scope(&self, cmt: &mc::cmt) -> ty::Region {
                 temp_scope
             }
             Categorization::Upvar(..) => {
-                ty::ReScope(self.item_scope)
-            }
-            Categorization::StaticItem => {
-                ty::ReStatic
+                self.bccx.tcx.mk_region(ty::ReScope(self.item_scope))
             }
             Categorization::Local(local_id) => {
-                ty::ReScope(self.bccx.tcx.region_maps.var_scope(local_id))
+                self.bccx.tcx.mk_region(ty::ReScope(
+                    self.bccx.tcx.region_maps.var_scope(local_id)))
             }
+            Categorization::StaticItem |
             Categorization::Deref(_, _, mc::UnsafePtr(..)) => {
-                ty::ReStatic
+                self.bccx.tcx.mk_region(ty::ReStatic)
             }
             Categorization::Deref(_, _, mc::BorrowedPtr(_, r)) |
             Categorization::Deref(_, _, mc::Implicit(_, r)) => {
@@ -135,7 +134,7 @@ fn scope(&self, cmt: &mc::cmt) -> ty::Region {
         }
     }
 
-    fn report_error(&self, code: bckerr_code) {
+    fn report_error(&self, code: bckerr_code<'tcx>) {
         self.bccx.report(BckError { cmt: self.cmt_original.clone(),
                                     span: self.span,
                                     cause: BorrowViolation(self.cause),
index c982fc091d24c0d8ddebce581190335a86635ca8..a255564f01e255397f0c8a538e28df1c3d906096 100644 (file)
@@ -130,7 +130,7 @@ fn borrow(&mut self,
               borrow_id: ast::NodeId,
               borrow_span: Span,
               cmt: mc::cmt<'tcx>,
-              loan_region: ty::Region,
+              loan_region: &'tcx ty::Region,
               bk: ty::BorrowKind,
               loan_cause: euv::LoanCause)
     {
@@ -307,7 +307,7 @@ fn guarantee_valid(&mut self,
                        borrow_span: Span,
                        cmt: mc::cmt<'tcx>,
                        req_kind: ty::BorrowKind,
-                       loan_region: ty::Region,
+                       loan_region: &'tcx ty::Region,
                        cause: euv::LoanCause) {
         debug!("guarantee_valid(borrow_id={}, cmt={:?}, \
                 req_mutbl={:?}, loan_region={:?})",
@@ -318,7 +318,7 @@ fn guarantee_valid(&mut self,
 
         // a loan for the empty region can never be dereferenced, so
         // it is always safe
-        if loan_region == ty::ReEmpty {
+        if *loan_region == ty::ReEmpty {
             return;
         }
 
@@ -358,7 +358,7 @@ fn guarantee_valid(&mut self,
             }
 
             RestrictionResult::SafeIf(loan_path, restricted_paths) => {
-                let loan_scope = match loan_region {
+                let loan_scope = match *loan_region {
                     ty::ReScope(scope) => scope,
 
                     ty::ReFree(ref fr) => fr.scope,
index 3d9df4c8bd0082c2220af04904811d9d4a2a8146..d08f792b30c144251e1d3938db237025bc101d9c 100644 (file)
@@ -31,7 +31,7 @@ pub fn compute_restrictions<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
                                       span: Span,
                                       cause: euv::LoanCause,
                                       cmt: mc::cmt<'tcx>,
-                                      loan_region: ty::Region)
+                                      loan_region: &'tcx ty::Region)
                                       -> RestrictionResult<'tcx> {
     let ctxt = RestrictionsContext {
         bccx: bccx,
@@ -49,7 +49,7 @@ pub fn compute_restrictions<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
 struct RestrictionsContext<'a, 'tcx: 'a> {
     bccx: &'a BorrowckCtxt<'a, 'tcx>,
     span: Span,
-    loan_region: ty::Region,
+    loan_region: &'tcx ty::Region,
     cause: euv::LoanCause,
 }
 
@@ -157,7 +157,7 @@ fn restrict(&self,
     fn extend(&self,
               result: RestrictionResult<'tcx>,
               cmt: &mc::cmt<'tcx>,
-              elem: LoanPathElem) -> RestrictionResult<'tcx> {
+              elem: LoanPathElem<'tcx>) -> RestrictionResult<'tcx> {
         match result {
             RestrictionResult::Safe => RestrictionResult::Safe,
             RestrictionResult::SafeIf(base_lp, mut base_vec) => {
index 90858e4e8b8be2c4c717dfe91873d0d34a033a31..c46daf9c22537226dbadb5d422157eb399b4aab6 100644 (file)
@@ -9,10 +9,9 @@
 // except according to those terms.
 
 use rustc::ty::TyCtxt;
-use rustc::mir::repr::{self, Mir};
+use rustc::mir::repr::{self, Mir, Location};
 use rustc_data_structures::indexed_vec::Idx;
 
-use super::super::gather_moves::{Location};
 use super::super::gather_moves::{MoveOutIndex, MovePathIndex};
 use super::super::MoveDataParamEnv;
 use super::super::DropFlagState;
@@ -252,7 +251,7 @@ fn statement_effect(&self,
     {
         drop_flag_effects_for_location(
             self.tcx, self.mir, ctxt,
-            Location { block: bb, index: idx },
+            Location { block: bb, statement_index: idx },
             |path, s| Self::update_bits(sets, path, s)
         )
     }
@@ -265,7 +264,7 @@ fn terminator_effect(&self,
     {
         drop_flag_effects_for_location(
             self.tcx, self.mir, ctxt,
-            Location { block: bb, index: statements_len },
+            Location { block: bb, statement_index: statements_len },
             |path, s| Self::update_bits(sets, path, s)
         )
     }
@@ -314,7 +313,7 @@ fn statement_effect(&self,
     {
         drop_flag_effects_for_location(
             self.tcx, self.mir, ctxt,
-            Location { block: bb, index: idx },
+            Location { block: bb, statement_index: idx },
             |path, s| Self::update_bits(sets, path, s)
         )
     }
@@ -327,7 +326,7 @@ fn terminator_effect(&self,
     {
         drop_flag_effects_for_location(
             self.tcx, self.mir, ctxt,
-            Location { block: bb, index: statements_len },
+            Location { block: bb, statement_index: statements_len },
             |path, s| Self::update_bits(sets, path, s)
         )
     }
@@ -375,7 +374,7 @@ fn statement_effect(&self,
     {
         drop_flag_effects_for_location(
             self.tcx, self.mir, ctxt,
-            Location { block: bb, index: idx },
+            Location { block: bb, statement_index: idx },
             |path, s| Self::update_bits(sets, path, s)
         )
     }
@@ -388,7 +387,7 @@ fn terminator_effect(&self,
     {
         drop_flag_effects_for_location(
             self.tcx, self.mir, ctxt,
-            Location { block: bb, index: statements_len },
+            Location { block: bb, statement_index: statements_len },
             |path, s| Self::update_bits(sets, path, s)
         )
     }
@@ -431,7 +430,7 @@ fn statement_effect(&self,
         let path_map = &move_data.path_map;
         let rev_lookup = &move_data.rev_lookup;
 
-        let loc = Location { block: bb, index: idx };
+        let loc = Location { block: bb, statement_index: idx };
         debug!("stmt {:?} at loc {:?} moves out of move_indexes {:?}",
                stmt, loc, &loc_map[loc]);
         for move_index in &loc_map[loc] {
@@ -473,7 +472,7 @@ fn terminator_effect(&self,
         let (mir, move_data) = (self.mir, &ctxt.move_data);
         let term = mir[bb].terminator();
         let loc_map = &move_data.loc_map;
-        let loc = Location { block: bb, index: statements_len };
+        let loc = Location { block: bb, statement_index: statements_len };
         debug!("terminator {:?} at loc {:?} moves out of move_indexes {:?}",
                term, loc, &loc_map[loc]);
         let bits_per_block = self.bits_per_block(ctxt);
index 111646912ade30998060c70694305ce1dcbe5b8f..885bbe856c8fb441c9bfe14b864314afa08e3f16 100644 (file)
@@ -9,14 +9,14 @@
 // except according to those terms.
 
 use indexed_set::IdxSetBuf;
-use super::gather_moves::{MoveData, MovePathIndex, MovePathContent, Location};
+use super::gather_moves::{MoveData, MovePathIndex, MovePathContent};
 use super::dataflow::{MaybeInitializedLvals, MaybeUninitializedLvals};
 use super::dataflow::{DataflowResults};
 use super::{drop_flag_effects_for_location, on_all_children_bits};
 use super::{DropFlagState, MoveDataParamEnv};
 use super::patch::MirPatch;
 use rustc::ty::{self, Ty, TyCtxt};
-use rustc::ty::subst::{Subst, Substs};
+use rustc::ty::subst::{Kind, Subst, Substs};
 use rustc::mir::repr::*;
 use rustc::mir::transform::{Pass, MirPass, MirSource};
 use rustc::middle::const_val::ConstVal;
@@ -26,6 +26,7 @@
 use syntax_pos::Span;
 
 use std::fmt;
+use std::iter;
 use std::u32;
 
 pub struct ElaborateDrops;
@@ -146,9 +147,9 @@ fn initialization_data_at(&self, loc: Location) -> InitializationData {
             dead: self.flow_uninits.sets().on_entry_set_for(loc.block.index())
                 .to_owned(),
         };
-        for stmt in 0..loc.index {
+        for stmt in 0..loc.statement_index {
             data.apply_location(self.tcx, self.mir, self.env,
-                                Location { block: loc.block, index: stmt });
+                                Location { block: loc.block, statement_index: stmt });
         }
         data
     }
@@ -226,7 +227,7 @@ fn collect_drop_flags(&mut self)
 
             let init_data = self.initialization_data_at(Location {
                 block: bb,
-                index: data.statements.len()
+                statement_index: data.statements.len()
             });
 
             let path = self.move_data().rev_lookup.find(location);
@@ -249,7 +250,7 @@ fn collect_drop_flags(&mut self)
     fn elaborate_drops(&mut self)
     {
         for (bb, data) in self.mir.basic_blocks().iter_enumerated() {
-            let loc = Location { block: bb, index: data.statements.len() };
+            let loc = Location { block: bb, statement_index: data.statements.len() };
             let terminator = data.terminator();
 
             let resume_block = self.patch.resume_block();
@@ -359,9 +360,9 @@ fn elaborate_replace(
                 unwind: Some(unwind)
             }, bb);
             on_all_children_bits(self.tcx, self.mir, self.move_data(), path, |child| {
-                self.set_drop_flag(Location { block: target, index: 0 },
+                self.set_drop_flag(Location { block: target, statement_index: 0 },
                                    child, DropFlagState::Present);
-                self.set_drop_flag(Location { block: unwind, index: 0 },
+                self.set_drop_flag(Location { block: unwind, statement_index: 0 },
                                    child, DropFlagState::Present);
             });
         }
@@ -741,7 +742,7 @@ fn complete_drop<'a>(
         let drop_block = self.drop_block(c);
         if update_drop_flag {
             self.set_drop_flag(
-                Location { block: drop_block, index: 0 },
+                Location { block: drop_block, statement_index: 0 },
                 c.path,
                 DropFlagState::Absent
             );
@@ -859,7 +860,7 @@ fn unelaborated_free_block<'a>(
         let unit_temp = Lvalue::Temp(self.patch.new_temp(tcx.mk_nil()));
         let free_func = tcx.lang_items.require(lang_items::BoxFreeFnLangItem)
             .unwrap_or_else(|e| tcx.sess.fatal(&e));
-        let substs = Substs::new(tcx, vec![ty], vec![]);
+        let substs = Substs::new(tcx, iter::once(Kind::from(ty)));
         let fty = tcx.lookup_item_type(free_func).ty.subst(tcx, substs);
 
         self.patch.new_block(BasicBlockData {
@@ -924,7 +925,7 @@ fn set_drop_flag(&mut self, loc: Location, path: MovePathIndex, val: DropFlagSta
     }
 
     fn drop_flags_on_init(&mut self) {
-        let loc = Location { block: START_BLOCK, index: 0 };
+        let loc = Location { block: START_BLOCK, statement_index: 0 };
         let span = self.patch.source_info_for_location(self.mir, loc).span;
         let false_ = self.constant_bool(span, false);
         for flag in self.drop_flags.values() {
@@ -939,7 +940,7 @@ fn drop_flags_for_fn_rets(&mut self) {
             } = data.terminator().kind {
                 assert!(!self.patch.is_patched(bb));
 
-                let loc = Location { block: tgt, index: 0 };
+                let loc = Location { block: tgt, statement_index: 0 };
                 let path = self.move_data().rev_lookup.find(lv);
                 on_all_children_bits(
                     self.tcx, self.mir, self.move_data(), path,
@@ -950,7 +951,7 @@ fn drop_flags_for_fn_rets(&mut self) {
     }
 
     fn drop_flags_for_args(&mut self) {
-        let loc = Location { block: START_BLOCK, index: 0 };
+        let loc = Location { block: START_BLOCK, statement_index: 0 };
         super::drop_flag_effects_for_function_entry(
             self.tcx, self.mir, self.env, |path, ds| {
                 self.set_drop_flag(loc, path, ds);
@@ -990,7 +991,7 @@ fn drop_flags_for_locs(&mut self) {
                         }
                     }
                 }
-                let loc = Location { block: bb, index: i };
+                let loc = Location { block: bb, statement_index: i };
                 super::drop_flag_effects_for_location(
                     self.tcx, self.mir, self.env, loc, |path, ds| {
                         if ds == DropFlagState::Absent || allow_initializations {
@@ -1008,7 +1009,7 @@ fn drop_flags_for_locs(&mut self) {
             } = data.terminator().kind {
                 assert!(!self.patch.is_patched(bb));
 
-                let loc = Location { block: bb, index: data.statements.len() };
+                let loc = Location { block: bb, statement_index: data.statements.len() };
                 let path = self.move_data().rev_lookup.find(lv);
                 on_all_children_bits(
                     self.tcx, self.mir, self.move_data(), path,
index 8ae40e71bee58a6eac20fc76e55c66938aceab60..01bf8ed0e4b57679a379adf8854a6ad1cd5c1b1c 100644 (file)
@@ -160,8 +160,8 @@ impl Index<Location> for LocMap {
     type Output = [MoveOutIndex];
     fn index(&self, index: Location) -> &Self::Output {
         assert!(index.block.index() < self.map.len());
-        assert!(index.index < self.map[index.block.index()].len());
-        &self.map[index.block.index()][index.index]
+        assert!(index.statement_index < self.map[index.block.index()].len());
+        &self.map[index.block.index()][index.statement_index]
     }
 }
 
@@ -200,21 +200,6 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
-pub struct Location {
-    /// block where action is located
-    pub block: BasicBlock,
-    /// index within above block; statement when < statments.len) or
-    /// the terminator (when = statements.len).
-    pub index: usize,
-}
-
-impl fmt::Debug for Location {
-    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        write!(fmt, "{:?}[{}]", self.block, self.index)
-    }
-}
-
 #[derive(Debug)]
 pub struct MovePathData<'tcx> {
     move_paths: Vec<MovePath<'tcx>>,
@@ -569,7 +554,7 @@ fn gather_moves<'a, 'tcx>(mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> MoveD
         };
 
         for (i, stmt) in bb_data.statements.iter().enumerate() {
-            let source = Location { block: bb, index: i };
+            let source = Location { block: bb, statement_index: i };
             match stmt.kind {
                 StatementKind::Assign(ref lval, ref rval) => {
                     bb_ctxt.builder.create_move_path(lval);
@@ -631,14 +616,14 @@ fn gather_moves<'a, 'tcx>(mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> MoveD
 
             TerminatorKind::Return => {
                 let source = Location { block: bb,
-                                        index: bb_data.statements.len() };
+                                        statement_index: bb_data.statements.len() };
                 debug!("gather_moves Return on_move_out_lval return {:?}", source);
                 bb_ctxt.on_move_out_lval(SK::Return, &Lvalue::ReturnPointer, source);
             }
 
             TerminatorKind::If { ref cond, targets: _ } => {
                 let source = Location { block: bb,
-                                        index: bb_data.statements.len() };
+                                        statement_index: bb_data.statements.len() };
                 bb_ctxt.on_operand(SK::If, cond, source);
             }
 
@@ -669,7 +654,7 @@ fn gather_moves<'a, 'tcx>(mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> MoveD
 
             TerminatorKind::Drop { ref location, target: _, unwind: _ } => {
                 let source = Location { block: bb,
-                                        index: bb_data.statements.len() };
+                                        statement_index: bb_data.statements.len() };
                 bb_ctxt.on_move_out_lval(SK::Drop, location, source);
             }
             TerminatorKind::DropAndReplace { ref location, ref value, .. } => {
@@ -677,12 +662,12 @@ fn gather_moves<'a, 'tcx>(mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> MoveD
                 bb_ctxt.path_map.fill_to(assigned_path.index());
 
                 let source = Location { block: bb,
-                                        index: bb_data.statements.len() };
+                                        statement_index: bb_data.statements.len() };
                 bb_ctxt.on_operand(SK::Use, value, source);
             }
             TerminatorKind::Call { ref func, ref args, ref destination, cleanup: _ } => {
                 let source = Location { block: bb,
-                                        index: bb_data.statements.len() };
+                                        statement_index: bb_data.statements.len() };
                 bb_ctxt.on_operand(SK::CallFn, func, source);
                 for arg in args {
                     debug!("gather_moves Call on_operand {:?} {:?}", arg, source);
@@ -757,7 +742,7 @@ fn on_move_out_lval(&mut self,
                         stmt_kind: StmtKind,
                         lval: &Lvalue<'tcx>,
                         source: Location) {
-        let i = source.index;
+        let i = source.statement_index;
         let index = MoveOutIndex::new(self.moves.len());
 
         let path = self.builder.move_path_for(lval);
index dbee0ea9b00e97a870f41cb8b03b0da233d9878f..31380c6f71c99877a0ec7fdb2a852c3cdebd1a10 100644 (file)
@@ -19,7 +19,7 @@
 use rustc::hir::intravisit::{FnKind};
 
 use rustc::mir::repr;
-use rustc::mir::repr::{BasicBlock, BasicBlockData, Mir, Statement, Terminator};
+use rustc::mir::repr::{BasicBlock, BasicBlockData, Mir, Statement, Terminator, Location};
 use rustc::session::Session;
 use rustc::ty::{self, TyCtxt};
 
@@ -35,7 +35,7 @@
 use self::dataflow::{Dataflow, DataflowAnalysis, DataflowResults};
 use self::dataflow::{MaybeInitializedLvals, MaybeUninitializedLvals};
 use self::dataflow::{DefinitelyInitializedLvals};
-use self::gather_moves::{MoveData, MovePathIndex, Location};
+use self::gather_moves::{MoveData, MovePathIndex};
 use self::gather_moves::{MovePathContent, MovePathData};
 
 fn has_rustc_mir_with(attrs: &[ast::Attribute], name: &str) -> Option<P<MetaItem>> {
@@ -367,7 +367,7 @@ fn drop_flag_effects_for_location<'a, 'tcx, F>(
     }
 
     let block = &mir[loc.block];
-    match block.statements.get(loc.index) {
+    match block.statements.get(loc.statement_index) {
         Some(stmt) => match stmt.kind {
             repr::StatementKind::SetDiscriminant{ .. } => {
                 span_bug!(stmt.source_info.span, "SetDiscrimant should not exist during borrowck");
index 417e719a9dcb9f73cee1c24c6736cdaf532ed185..52cd1a9f949bf6219b7e1cd7e101a9a7c6ea0d8e 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::gather_moves::Location;
 use rustc::ty::Ty;
 use rustc::mir::repr::*;
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
@@ -89,7 +88,7 @@ pub fn terminator_loc(&self, mir: &Mir<'tcx>, bb: BasicBlock) -> Location {
         };
         Location {
             block: bb,
-            index: offset
+            statement_index: offset
         }
     }
 
@@ -149,12 +148,12 @@ pub fn apply(self, mir: &mut Mir<'tcx>) {
             }
             debug!("MirPatch: adding statement {:?} at loc {:?}+{}",
                    stmt, loc, delta);
-            loc.index += delta;
+            loc.statement_index += delta;
             let source_info = Self::source_info_for_index(
                 &mir[loc.block], loc
             );
             mir[loc.block].statements.insert(
-                loc.index, Statement {
+                loc.statement_index, Statement {
                     source_info: source_info,
                     kind: stmt
                 });
@@ -163,7 +162,7 @@ pub fn apply(self, mir: &mut Mir<'tcx>) {
     }
 
     pub fn source_info_for_index(data: &BasicBlockData, loc: Location) -> SourceInfo {
-        match data.statements.get(loc.index) {
+        match data.statements.get(loc.statement_index) {
             Some(stmt) => stmt.source_info,
             None => data.terminator().source_info
         }
index 225895adefa4ba7621826f71c07a611b72352e74..e8b44d85bf916c382e3637db0d049505d21913ab 100644 (file)
@@ -41,6 +41,7 @@
 use std::fmt;
 use std::mem;
 use std::rc::Rc;
+use std::hash::{Hash, Hasher};
 use syntax::ast;
 use syntax::attr::AttrMetaMethods;
 use syntax_pos::{MultiSpan, Span};
@@ -345,7 +346,7 @@ pub fn loan_path(&self) -> Rc<LoanPath<'tcx>> {
     }
 }
 
-#[derive(Eq, Hash)]
+#[derive(Eq)]
 pub struct LoanPath<'tcx> {
     kind: LoanPathKind<'tcx>,
     ty: ty::Ty<'tcx>,
@@ -353,10 +354,13 @@ pub struct LoanPath<'tcx> {
 
 impl<'tcx> PartialEq for LoanPath<'tcx> {
     fn eq(&self, that: &LoanPath<'tcx>) -> bool {
-        let r = self.kind == that.kind;
-        debug_assert!(self.ty == that.ty || !r,
-                      "Somehow loan paths are equal though their tys are not.");
-        r
+        self.kind == that.kind
+    }
+}
+
+impl<'tcx> Hash for LoanPath<'tcx> {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        self.kind.hash(state);
     }
 }
 
@@ -365,7 +369,7 @@ pub enum LoanPathKind<'tcx> {
     LpVar(ast::NodeId),                         // `x` in README.md
     LpUpvar(ty::UpvarId),                       // `x` captured by-value into closure
     LpDowncast(Rc<LoanPath<'tcx>>, DefId), // `x` downcast to particular enum variant
-    LpExtend(Rc<LoanPath<'tcx>>, mc::MutabilityCategory, LoanPathElem)
+    LpExtend(Rc<LoanPath<'tcx>>, mc::MutabilityCategory, LoanPathElem<'tcx>)
 }
 
 impl<'tcx> LoanPath<'tcx> {
@@ -410,8 +414,8 @@ fn cleaned(self) -> InteriorKind {
 // `enum E { X { foo: u32 }, Y { foo: u32 }}`
 // each `foo` is qualified by the definitition id of the variant (`X` or `Y`).
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
-pub enum LoanPathElem {
-    LpDeref(mc::PointerKind),
+pub enum LoanPathElem<'tcx> {
+    LpDeref(mc::PointerKind<'tcx>),
     LpInterior(Option<DefId>, InteriorKind),
 }
 
@@ -564,10 +568,11 @@ pub fn opt_loan_path<'tcx>(cmt: &mc::cmt<'tcx>) -> Option<Rc<LoanPath<'tcx>>> {
 
 // Errors that can occur
 #[derive(PartialEq)]
-pub enum bckerr_code {
+pub enum bckerr_code<'tcx> {
     err_mutbl,
-    err_out_of_scope(ty::Region, ty::Region, euv::LoanCause), // superscope, subscope, loan cause
-    err_borrowed_pointer_too_short(ty::Region, ty::Region), // loan, ptr
+    /// superscope, subscope, loan cause
+    err_out_of_scope(&'tcx ty::Region, &'tcx ty::Region, euv::LoanCause),
+    err_borrowed_pointer_too_short(&'tcx ty::Region, &'tcx ty::Region), // loan, ptr
 }
 
 // Combination of an error code and the categorization of the expression
@@ -577,7 +582,7 @@ pub struct BckError<'tcx> {
     span: Span,
     cause: AliasableViolationKind,
     cmt: mc::cmt<'tcx>,
-    code: bckerr_code
+    code: bckerr_code<'tcx>
 }
 
 #[derive(Copy, Clone, Debug, PartialEq)]
@@ -605,7 +610,7 @@ fn with_temp_region_map<F>(&mut self, id: ast::NodeId, f: F)
         self.free_region_map = old_free_region_map;
     }
 
-    pub fn is_subregion_of(&self, r_sub: ty::Region, r_sup: ty::Region)
+    pub fn is_subregion_of(&self, r_sub: &'tcx ty::Region, r_sup: &'tcx ty::Region)
                            -> bool
     {
         self.free_region_map.is_subregion_of(self.tcx, r_sub, r_sup)
@@ -614,9 +619,9 @@ pub fn is_subregion_of(&self, r_sub: ty::Region, r_sup: ty::Region)
     pub fn report(&self, err: BckError<'tcx>) {
         // Catch and handle some particular cases.
         match (&err.code, &err.cause) {
-            (&err_out_of_scope(ty::ReScope(_), ty::ReStatic, _),
+            (&err_out_of_scope(&ty::ReScope(_), &ty::ReStatic, _),
              &BorrowViolation(euv::ClosureCapture(span))) |
-            (&err_out_of_scope(ty::ReScope(_), ty::ReFree(..), _),
+            (&err_out_of_scope(&ty::ReScope(_), &ty::ReFree(..), _),
              &BorrowViolation(euv::ClosureCapture(span))) => {
                 return self.report_out_of_scope_escaping_closure_capture(&err, span);
             }
@@ -921,9 +926,11 @@ pub fn report_aliasability_violation(&self,
                 err
             }
             mc::AliasableBorrowed => {
-                struct_span_err!(
+                let mut e = struct_span_err!(
                     self.tcx.sess, span, E0389,
-                    "{} in a `&` reference", prefix)
+                    "{} in a `&` reference", prefix);
+                e.span_label(span, &"assignment into an immutable reference");
+                e
             }
         };
 
@@ -965,8 +972,8 @@ fn report_out_of_scope_escaping_closure_capture(&self,
             .emit();
     }
 
-    fn region_end_span(&self, region: ty::Region) -> Option<Span> {
-        match region {
+    fn region_end_span(&self, region: &'tcx ty::Region) -> Option<Span> {
+        match *region {
             ty::ReScope(scope) => {
                 match scope.span(&self.tcx.region_maps, &self.tcx.map) {
                     Some(s) => {
@@ -1194,8 +1201,8 @@ pub fn cmt_to_path_or_string(&self, cmt: &mc::cmt<'tcx>) -> String {
     }
 }
 
-fn statement_scope_span(tcx: TyCtxt, region: ty::Region) -> Option<Span> {
-    match region {
+fn statement_scope_span(tcx: TyCtxt, region: &ty::Region) -> Option<Span> {
+    match *region {
         ty::ReScope(scope) => {
             match tcx.map.find(scope.node_id(&tcx.region_maps)) {
                 Some(hir_map::NodeStmt(stmt)) => Some(stmt.span),
index 3c82358542876c4174181e245a3ef6c6b7bdfc5a..82c142c919e3471c0a58eda9a53d7e1a049f66e3 100644 (file)
@@ -1172,7 +1172,7 @@ fn borrow(&mut self,
               _: NodeId,
               span: Span,
               _: cmt,
-              _: Region,
+              _: &'tcx Region,
               kind: BorrowKind,
               _: LoanCause) {
         match kind {
index 6f57ae2941838d8185afde07b900a4b2aa635a5c..4e87c931cc19daf47c55c3d65e77a3fea4a1f5d7 100644 (file)
@@ -861,7 +861,7 @@ fn sort_lint_groups(lints: Vec<(&'static str, Vec<lint::LintId>, bool)>)
         for (name, to) in lints {
             let name = name.to_lowercase().replace("_", "-");
             let desc = to.into_iter()
-                         .map(|x| x.as_str().replace("_", "-"))
+                         .map(|x| x.to_string().replace("_", "-"))
                          .collect::<Vec<String>>()
                          .join(", ");
             println!("    {}  {}", padded(&name[..]), desc);
index 32d0bbbfdb6b7d8e179542345e71af35580856e2..460a6e68a5c5a20f4c4af373c67fdc40c80f8279 100644 (file)
 use rustc::middle::region::CodeExtentData;
 use rustc::middle::resolve_lifetime;
 use rustc::middle::stability;
-use rustc::ty::subst::{Subst, Substs};
+use rustc::ty::subst::{Kind, Subst, Substs};
 use rustc::traits::Reveal;
 use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc::infer::{self, InferOk, InferResult, TypeOrigin};
 use rustc_metadata::cstore::CStore;
 use rustc::hir::map as hir_map;
 use rustc::session::{self, config};
+use std::iter;
 use std::rc::Rc;
 use syntax::ast;
 use syntax::abi::Abi;
@@ -283,25 +284,26 @@ pub fn t_param(&self, index: u32) -> Ty<'tcx> {
     pub fn re_early_bound(&self,
                           index: u32,
                           name: &'static str)
-                          -> ty::Region {
+                          -> &'tcx ty::Region {
         let name = token::intern(name);
-        ty::ReEarlyBound(ty::EarlyBoundRegion {
+        self.infcx.tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
             index: index,
             name: name,
-        })
+        }))
     }
 
-    pub fn re_late_bound_with_debruijn(&self, id: u32, debruijn: ty::DebruijnIndex) -> ty::Region {
-        ty::ReLateBound(debruijn, ty::BrAnon(id))
+    pub fn re_late_bound_with_debruijn(&self, id: u32, debruijn: ty::DebruijnIndex)
+                                       -> &'tcx ty::Region {
+        self.infcx.tcx.mk_region(ty::ReLateBound(debruijn, ty::BrAnon(id)))
     }
 
-    pub fn t_rptr(&self, r: ty::Region) -> Ty<'tcx> {
-        self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), self.tcx().types.isize)
+    pub fn t_rptr(&self, r: &'tcx ty::Region) -> Ty<'tcx> {
+        self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize)
     }
 
     pub fn t_rptr_late_bound(&self, id: u32) -> Ty<'tcx> {
         let r = self.re_late_bound_with_debruijn(id, ty::DebruijnIndex::new(1));
-        self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), self.tcx().types.isize)
+        self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize)
     }
 
     pub fn t_rptr_late_bound_with_debruijn(&self,
@@ -309,7 +311,7 @@ pub fn t_rptr_late_bound_with_debruijn(&self,
                                            debruijn: ty::DebruijnIndex)
                                            -> Ty<'tcx> {
         let r = self.re_late_bound_with_debruijn(id, debruijn);
-        self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), self.tcx().types.isize)
+        self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize)
     }
 
     pub fn t_rptr_scope(&self, id: ast::NodeId) -> Ty<'tcx> {
@@ -317,16 +319,16 @@ pub fn t_rptr_scope(&self, id: ast::NodeId) -> Ty<'tcx> {
         self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), self.tcx().types.isize)
     }
 
-    pub fn re_free(&self, nid: ast::NodeId, id: u32) -> ty::Region {
-        ty::ReFree(ty::FreeRegion {
+    pub fn re_free(&self, nid: ast::NodeId, id: u32) -> &'tcx ty::Region {
+        self.infcx.tcx.mk_region(ty::ReFree(ty::FreeRegion {
             scope: self.tcx().region_maps.item_extent(nid),
             bound_region: ty::BrAnon(id),
-        })
+        }))
     }
 
     pub fn t_rptr_free(&self, nid: ast::NodeId, id: u32) -> Ty<'tcx> {
         let r = self.re_free(nid, id);
-        self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), self.tcx().types.isize)
+        self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize)
     }
 
     pub fn t_rptr_static(&self) -> Ty<'tcx> {
@@ -675,7 +677,7 @@ fn subst_ty_renumber_bound() {
             env.t_fn(&[t_param], env.t_nil())
         };
 
-        let substs = Substs::new(env.infcx.tcx, vec![t_rptr_bound1], vec![]);
+        let substs = Substs::new(env.infcx.tcx, iter::once(Kind::from(t_rptr_bound1)));
         let t_substituted = t_source.subst(env.infcx.tcx, substs);
 
         // t_expected = fn(&'a isize)
@@ -710,7 +712,7 @@ fn subst_ty_renumber_some_bounds() {
             env.t_pair(t_param, env.t_fn(&[t_param], env.t_nil()))
         };
 
-        let substs = Substs::new(env.infcx.tcx, vec![t_rptr_bound1], vec![]);
+        let substs = Substs::new(env.infcx.tcx, iter::once(Kind::from(t_rptr_bound1)));
         let t_substituted = t_source.subst(env.infcx.tcx, substs);
 
         // t_expected = (&'a isize, fn(&'a isize))
@@ -772,7 +774,7 @@ fn subst_region_renumber_region() {
             env.t_fn(&[env.t_rptr(re_early)], env.t_nil())
         };
 
-        let substs = Substs::new(env.infcx.tcx, vec![], vec![re_bound1]);
+        let substs = Substs::new(env.infcx.tcx, iter::once(Kind::from(re_bound1)));
         let t_substituted = t_source.subst(env.infcx.tcx, substs);
 
         // t_expected = fn(&'a isize)
index 793155cfa8f8f6fc8508af5fb262d6b9bd9df756..ed133d21b8a0f7c0792398c4549dbf54d3e50928 100644 (file)
@@ -724,7 +724,10 @@ fn emit_messages_default(&mut self,
         }
         match write!(&mut self.dst, "\n") {
             Err(e) => panic!("failed to emit error: {}", e),
-            _ => ()
+            _ => match self.dst.flush() {
+                Err(e) => panic!("failed to emit error: {}", e),
+                _ => ()
+            }
         }
     }
 }
@@ -749,6 +752,21 @@ fn overlaps(a1: &Annotation, a2: &Annotation) -> bool {
 fn emit_to_destination(rendered_buffer: &Vec<Vec<StyledString>>,
         lvl: &Level,
         dst: &mut Destination) -> io::Result<()> {
+    use lock;
+
+    // In order to prevent error message interleaving, where multiple error lines get intermixed
+    // when multiple compiler processes error simultaneously, we emit errors with additional
+    // steps.
+    //
+    // On Unix systems, we write into a buffered terminal rather than directly to a terminal. When
+    // the .flush() is called we take the buffer created from the buffered writes and write it at
+    // one shot.  Because the Unix systems use ANSI for the colors, which is a text-based styling
+    // scheme, this buffered approach works and maintains the styling.
+    //
+    // On Windows, styling happens through calls to a terminal API. This prevents us from using the
+    // same buffering approach.  Instead, we use a global Windows mutex, which we acquire long
+    // enough to output the full error message, then we release.
+    let _buffer_lock = lock::acquire_global_lock("rustc_errors");
     for line in rendered_buffer {
         for part in line {
             dst.apply_style(lvl.clone(), part.style)?;
@@ -757,6 +775,7 @@ fn emit_to_destination(rendered_buffer: &Vec<Vec<StyledString>>,
         }
         write!(dst, "\n")?;
     }
+    dst.flush()?;
     Ok(())
 }
 
@@ -783,14 +802,74 @@ fn GetConsoleMode(hConsoleHandle: HANDLE,
     }
 }
 
+pub type BufferedStderr = term::Terminal<Output = BufferedWriter> + Send;
+
 pub enum Destination {
     Terminal(Box<term::StderrTerminal>),
+    BufferedTerminal(Box<BufferedStderr>),
     Raw(Box<Write + Send>),
 }
 
+/// Buffered writer gives us a way on Unix to buffer up an entire error message before we output
+/// it.  This helps to prevent interleaving of multiple error messages when multiple compiler
+/// processes error simultaneously
+pub struct BufferedWriter {
+    buffer: Vec<u8>,
+}
+
+impl BufferedWriter {
+    // note: we use _new because the conditional compilation at its use site may make this
+    // this function unused on some platforms
+    fn _new() -> BufferedWriter {
+        BufferedWriter {
+            buffer: vec![]
+        }
+    }
+}
+
+impl Write for BufferedWriter {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        for b in buf {
+            self.buffer.push(*b);
+        }
+        Ok(buf.len())
+    }
+    fn flush(&mut self) -> io::Result<()> {
+        let mut stderr = io::stderr();
+        let result = (|| {
+            stderr.write_all(&self.buffer)?;
+            stderr.flush()
+        })();
+        self.buffer.clear();
+        result
+    }
+}
+
 impl Destination {
+    #[cfg(not(windows))]
+    /// When not on Windows, prefer the buffered terminal so that we can buffer an entire error
+    /// to be emitted at one time.
+    fn from_stderr() -> Destination {
+        let stderr: Option<Box<BufferedStderr>>  =
+            term::TerminfoTerminal::new(BufferedWriter::_new())
+                .map(|t| Box::new(t) as Box<BufferedStderr>);
+
+        match stderr {
+            Some(t) => BufferedTerminal(t),
+            None    => Raw(Box::new(io::stderr())),
+        }
+    }
+
+    #[cfg(windows)]
+    /// Return a normal, unbuffered terminal when on Windows.
     fn from_stderr() -> Destination {
-        match term::stderr() {
+        let stderr: Option<Box<term::StderrTerminal>> =
+            term::TerminfoTerminal::new(io::stderr())
+                .map(|t| Box::new(t) as Box<term::StderrTerminal>)
+                .or_else(|| term::WinConsole::new(io::stderr()).ok()
+                    .map(|t| Box::new(t) as Box<term::StderrTerminal>));
+
+        match stderr {
             Some(t) => Terminal(t),
             None    => Raw(Box::new(io::stderr())),
         }
@@ -839,6 +918,7 @@ fn apply_style(&mut self,
     fn start_attr(&mut self, attr: term::Attr) -> io::Result<()> {
         match *self {
             Terminal(ref mut t) => { t.attr(attr)?; }
+            BufferedTerminal(ref mut t) => { t.attr(attr)?; }
             Raw(_) => { }
         }
         Ok(())
@@ -847,6 +927,7 @@ fn start_attr(&mut self, attr: term::Attr) -> io::Result<()> {
     fn reset_attrs(&mut self) -> io::Result<()> {
         match *self {
             Terminal(ref mut t) => { t.reset()?; }
+            BufferedTerminal(ref mut t) => { t.reset()?; }
             Raw(_) => { }
         }
         Ok(())
@@ -857,12 +938,14 @@ impl Write for Destination {
     fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
         match *self {
             Terminal(ref mut t) => t.write(bytes),
+            BufferedTerminal(ref mut t) => t.write(bytes),
             Raw(ref mut w) => w.write(bytes),
         }
     }
     fn flush(&mut self) -> io::Result<()> {
         match *self {
             Terminal(ref mut t) => t.flush(),
+            BufferedTerminal(ref mut t) => t.flush(),
             Raw(ref mut w) => w.flush(),
         }
     }
index 4b3e53d931f136541dfc37a8472d665bc80bf858..c99bc47044853b5084ef722f96d9d5a87c927434 100644 (file)
@@ -50,6 +50,7 @@
 pub mod snippet;
 pub mod registry;
 pub mod styled_buffer;
+mod lock;
 
 use syntax_pos::{BytePos, Loc, FileLinesResult, FileName, MultiSpan, Span, NO_EXPANSION };
 use syntax_pos::{MacroBacktrace};
diff --git a/src/librustc_errors/lock.rs b/src/librustc_errors/lock.rs
new file mode 100644 (file)
index 0000000..0a9e0c4
--- /dev/null
@@ -0,0 +1,112 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Bindings to acquire a global named lock.
+//!
+//! This is intended to be used to synchronize multiple compiler processes to
+//! ensure that we can output complete errors without interleaving on Windows.
+//! Note that this is currently only needed for allowing only one 32-bit MSVC
+//! linker to execute at once on MSVC hosts, so this is only implemented for
+//! `cfg(windows)`. Also note that this may not always be used on Windows,
+//! only when targeting 32-bit MSVC.
+//!
+//! For more information about why this is necessary, see where this is called.
+
+use std::any::Any;
+
+#[cfg(windows)]
+#[allow(bad_style)]
+pub fn acquire_global_lock(name: &str) -> Box<Any> {
+    use std::ffi::CString;
+    use std::io;
+
+    type LPSECURITY_ATTRIBUTES = *mut u8;
+    type BOOL = i32;
+    type LPCSTR = *const u8;
+    type HANDLE = *mut u8;
+    type DWORD = u32;
+
+    const INFINITE: DWORD = !0;
+    const WAIT_OBJECT_0: DWORD = 0;
+    const WAIT_ABANDONED: DWORD = 0x00000080;
+
+    extern "system" {
+        fn CreateMutexA(lpMutexAttributes: LPSECURITY_ATTRIBUTES,
+                        bInitialOwner: BOOL,
+                        lpName: LPCSTR) -> HANDLE;
+        fn WaitForSingleObject(hHandle: HANDLE,
+                               dwMilliseconds: DWORD) -> DWORD;
+        fn ReleaseMutex(hMutex: HANDLE) -> BOOL;
+        fn CloseHandle(hObject: HANDLE) -> BOOL;
+    }
+
+    struct Handle(HANDLE);
+
+    impl Drop for Handle {
+        fn drop(&mut self) {
+            unsafe {
+                CloseHandle(self.0);
+            }
+        }
+    }
+
+    struct Guard(Handle);
+
+    impl Drop for Guard {
+        fn drop(&mut self) {
+            unsafe {
+                ReleaseMutex((self.0).0);
+            }
+        }
+    }
+
+    let cname = CString::new(name).unwrap();
+    unsafe {
+        // Create a named mutex, with no security attributes and also not
+        // acquired when we create it.
+        //
+        // This will silently create one if it doesn't already exist, or it'll
+        // open up a handle to one if it already exists.
+        let mutex = CreateMutexA(0 as *mut _, 0, cname.as_ptr() as *const u8);
+        if mutex.is_null() {
+            panic!("failed to create global mutex named `{}`: {}", name,
+                   io::Error::last_os_error());
+        }
+        let mutex = Handle(mutex);
+
+        // Acquire the lock through `WaitForSingleObject`.
+        //
+        // A return value of `WAIT_OBJECT_0` means we successfully acquired it.
+        //
+        // A return value of `WAIT_ABANDONED` means that the previous holder of
+        // the thread exited without calling `ReleaseMutex`. This can happen,
+        // for example, when the compiler crashes or is interrupted via ctrl-c
+        // or the like. In this case, however, we are still transferred
+        // ownership of the lock so we continue.
+        //
+        // If an error happens.. well... that's surprising!
+        match WaitForSingleObject(mutex.0, INFINITE) {
+            WAIT_OBJECT_0 | WAIT_ABANDONED => {}
+            code => {
+                panic!("WaitForSingleObject failed on global mutex named \
+                        `{}`: {} (ret={:x})", name,
+                       io::Error::last_os_error(), code);
+            }
+        }
+
+        // Return a guard which will call `ReleaseMutex` when dropped.
+        Box::new(Guard(mutex))
+    }
+}
+
+#[cfg(unix)]
+pub fn acquire_global_lock(_name: &str) -> Box<Any> {
+    Box::new(())
+}
index b2ffcac365bad34760351052003f8411d7265fb0..754910c246d6f599203a47dd72590b7927406867 100644 (file)
@@ -1796,6 +1796,11 @@ pub fn LLVMRustDIBuilderCreateLexicalBlock(Builder: DIBuilderRef,
                                                Col: c_uint)
                                                -> DILexicalBlock;
 
+    pub fn LLVMRustDIBuilderCreateLexicalBlockFile(Builder: DIBuilderRef,
+                                                   Scope: DIScope,
+                                                   File: DIFile)
+                                                   -> DILexicalBlock;
+
     pub fn LLVMRustDIBuilderCreateStaticVariable(Builder: DIBuilderRef,
                                                  Context: DIScope,
                                                  Name: *const c_char,
index ad52d346857ffb0ab25d7d85e779bacfb62d5775..0236f9c413ddc26e47662090196bda23a3ef9c57 100644 (file)
@@ -517,7 +517,7 @@ pub fn encode_cast_kind(ebml_w: &mut Encoder, kind: cast::CastKind) {
 // Encoding and decoding the side tables
 
 trait rbml_writer_helpers<'tcx> {
-    fn emit_region(&mut self, ecx: &e::EncodeContext, r: ty::Region);
+    fn emit_region(&mut self, ecx: &e::EncodeContext, r: &'tcx ty::Region);
     fn emit_ty<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, ty: Ty<'tcx>);
     fn emit_substs<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
                        substs: &Substs<'tcx>);
@@ -531,7 +531,7 @@ fn emit_auto_deref_ref<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
 }
 
 impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
-    fn emit_region(&mut self, ecx: &e::EncodeContext, r: ty::Region) {
+    fn emit_region(&mut self, ecx: &e::EncodeContext, r: &'tcx ty::Region) {
         self.emit_opaque(|this| Ok(tyencode::enc_region(&mut this.cursor,
                                                         &ecx.ty_str_ctxt(),
                                                         r)));
@@ -617,7 +617,7 @@ fn emit_autoref<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
                 &adjustment::AutoPtr(r, m) => {
                     this.emit_enum_variant("AutoPtr", 0, 2, |this| {
                         this.emit_enum_variant_arg(0,
-                            |this| Ok(this.emit_region(ecx, *r)));
+                            |this| Ok(this.emit_region(ecx, r)));
                         this.emit_enum_variant_arg(1, |this| m.encode(this))
                     })
                 }
@@ -824,7 +824,7 @@ fn read_ty_encoded<'a, 'b, F, R>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>,
                                      f: F) -> R
         where F: for<'x> FnOnce(&mut tydecode::TyDecoder<'x, 'tcx>) -> R;
 
-    fn read_region(&mut self, dcx: &DecodeContext) -> ty::Region;
+    fn read_region<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> &'tcx ty::Region;
     fn read_ty<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> Ty<'tcx>;
     fn read_tys<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> Vec<Ty<'tcx>>;
     fn read_trait_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
@@ -835,8 +835,8 @@ fn read_predicate<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
                               -> ty::Predicate<'tcx>;
     fn read_substs<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
                            -> &'tcx Substs<'tcx>;
-    fn read_upvar_capture(&mut self, dcx: &DecodeContext)
-                          -> ty::UpvarCapture;
+    fn read_upvar_capture<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
+                                  -> ty::UpvarCapture<'tcx>;
     fn read_auto_adjustment<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
                                     -> adjustment::AutoAdjustment<'tcx>;
     fn read_cast_kind<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
@@ -908,7 +908,7 @@ fn type_string(doc: rbml::Doc) -> String {
             str
         }
     }
-    fn read_region(&mut self, dcx: &DecodeContext) -> ty::Region {
+    fn read_region<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> &'tcx ty::Region {
         // Note: regions types embed local node ids.  In principle, we
         // should translate these node ids into the new decode
         // context.  However, we do not bother, because region types
@@ -948,7 +948,8 @@ fn read_substs<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
                .parse_substs())
         }).unwrap()
     }
-    fn read_upvar_capture(&mut self, dcx: &DecodeContext) -> ty::UpvarCapture {
+    fn read_upvar_capture<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
+                                  -> ty::UpvarCapture<'tcx> {
         self.read_enum("UpvarCapture", |this| {
             let variants = ["ByValue", "ByRef"];
             this.read_enum_variant(&variants, |this, i| {
@@ -1032,7 +1033,7 @@ fn read_autoref<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
             this.read_enum_variant(&variants, |this, i| {
                 Ok(match i {
                     0 => {
-                        let r: ty::Region =
+                        let r: &'tcx ty::Region =
                             this.read_enum_variant_arg(0, |this| {
                                 Ok(this.read_region(dcx))
                             }).unwrap();
@@ -1041,7 +1042,7 @@ fn read_autoref<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
                                 Decodable::decode(this)
                             }).unwrap();
 
-                        adjustment::AutoPtr(dcx.tcx.mk_region(r), m)
+                        adjustment::AutoPtr(r, m)
                     }
                     1 => {
                         let m: hir::Mutability =
index 94426dcbf1d8d0efdd424588d623b7dabd3b9c2a..0fd7b683067b7441798446c8b5ad19c25c2c4307 100644 (file)
@@ -73,7 +73,7 @@ fn closure_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::Clos
         decoder::closure_ty(&cdata, def_id.index, tcx)
     }
 
-    fn item_variances(&self, def: DefId) -> ty::ItemVariances {
+    fn item_variances(&self, def: DefId) -> Vec<ty::Variance> {
         self.dep_graph.read(DepNode::MetaData(def));
         let cdata = self.get_crate_data(def.krate);
         decoder::get_item_variances(&cdata, def.index)
@@ -291,13 +291,6 @@ fn is_foreign_item(&self, did: DefId) -> bool {
         decoder::is_foreign_item(&cdata, did.index)
     }
 
-    fn is_static_method(&self, def: DefId) -> bool
-    {
-        self.dep_graph.read(DepNode::MetaData(def));
-        let cdata = self.get_crate_data(def.krate);
-        decoder::is_static_method(&cdata, def.index)
-    }
-
     fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool
     {
         self.do_is_statically_included_foreign_item(id)
index d63e0866a9d6b6949b109a88ea52a0ba82cc39ce..afcd25a79c5a135169f6d002049864ef71e0fb40 100644 (file)
@@ -42,6 +42,7 @@
 
 use rustc::mir;
 use rustc::mir::visit::MutVisitor;
+use rustc::mir::repr::Location;
 
 use std::cell::Cell;
 use std::io;
@@ -86,7 +87,7 @@ pub fn load_index(data: &[u8]) -> index::Index {
 
 pub fn crate_rustc_version(data: &[u8]) -> Option<String> {
     let doc = rbml::Doc::new(data);
-    reader::maybe_get_doc(doc, tag_rustc_version).map(|s| s.as_str())
+    reader::maybe_get_doc(doc, tag_rustc_version).map(|s| s.to_string())
 }
 
 pub fn load_xrefs(data: &[u8]) -> index::DenseIndex {
@@ -207,7 +208,7 @@ fn item_defaultness(item: rbml::Doc) -> hir::Defaultness {
 
 fn item_sort(item: rbml::Doc) -> Option<char> {
     reader::tagged_docs(item, tag_item_trait_item_sort).nth(0).map(|doc| {
-        doc.as_str_slice().as_bytes()[0] as char
+        doc.as_str().as_bytes()[0] as char
     })
 }
 
@@ -282,7 +283,7 @@ fn item_name(item: rbml::Doc) -> ast::Name {
 
 fn maybe_item_name(item: rbml::Doc) -> Option<ast::Name> {
     reader::maybe_get_doc(item, tag_paths_data_name).map(|name| {
-        let string = name.as_str_slice();
+        let string = name.as_str();
         token::intern(string)
     })
 }
@@ -368,7 +369,7 @@ fn parse_polarity(item_doc: rbml::Doc) -> hir::ImplPolarity {
 fn parse_associated_type_names(item_doc: rbml::Doc) -> Vec<ast::Name> {
     let names_doc = reader::get_doc(item_doc, tag_associated_type_names);
     reader::tagged_docs(names_doc, tag_associated_type_name)
-        .map(|name_doc| token::intern(name_doc.as_str_slice()))
+        .map(|name_doc| token::intern(name_doc.as_str()))
         .collect()
 }
 
@@ -682,7 +683,7 @@ fn each_child_of_item_or_crate<F, G>(cdata: Cmd,
 
         let name_doc = reader::get_doc(reexport_doc,
                                        tag_items_data_item_reexport_name);
-        let name = name_doc.as_str_slice();
+        let name = name_doc.as_str();
 
         // This reexport may be in yet another crate.
         let crate_data = if child_def_id.krate == cdata.cnum {
@@ -846,7 +847,7 @@ struct MirDefIdAndSpanTranslator<'cdata, 'codemap> {
     impl<'v, 'cdata, 'codemap> mir::visit::MutVisitor<'v>
         for MirDefIdAndSpanTranslator<'cdata, 'codemap>
     {
-        fn visit_def_id(&mut self, def_id: &mut DefId) {
+        fn visit_def_id(&mut self, def_id: &mut DefId, _: Location) {
             *def_id = translate_def_id(self.crate_metadata, *def_id);
         }
 
@@ -859,7 +860,8 @@ fn visit_span(&mut self, span: &mut Span) {
     }
 }
 
-fn get_explicit_self(item: rbml::Doc) -> ty::ExplicitSelfCategory {
+fn get_explicit_self<'a, 'tcx>(item: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>)
+                               -> ty::ExplicitSelfCategory<'tcx> {
     fn get_mutability(ch: u8) -> hir::Mutability {
         match ch as char {
             'i' => hir::MutImmutable,
@@ -869,7 +871,7 @@ fn get_mutability(ch: u8) -> hir::Mutability {
     }
 
     let explicit_self_doc = reader::get_doc(item, tag_item_trait_method_explicit_self);
-    let string = explicit_self_doc.as_str_slice();
+    let string = explicit_self_doc.as_str();
 
     let explicit_self_kind = string.as_bytes()[0];
     match explicit_self_kind as char {
@@ -879,7 +881,7 @@ fn get_mutability(ch: u8) -> hir::Mutability {
         // FIXME(#4846) expl. region
         '&' => {
             ty::ExplicitSelfCategory::ByReference(
-                ty::ReEmpty,
+                tcx.mk_region(ty::ReEmpty),
                 get_mutability(string.as_bytes()[1]))
         }
         _ => bug!("unknown self type code: `{}`", explicit_self_kind as char)
@@ -905,16 +907,6 @@ pub fn get_trait_name(cdata: Cmd, id: DefIndex) -> ast::Name {
     item_name(doc)
 }
 
-pub fn is_static_method(cdata: Cmd, id: DefIndex) -> bool {
-    let doc = cdata.lookup_item(id);
-    match item_sort(doc) {
-        Some('r') | Some('p') => {
-            get_explicit_self(doc) == ty::ExplicitSelfCategory::Static
-        }
-        _ => false
-    }
-}
-
 pub fn get_impl_or_trait_item<'a, 'tcx>(cdata: Cmd, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>)
                                         -> Option<ty::ImplOrTraitItem<'tcx>> {
     let item_doc = cdata.lookup_item(id);
@@ -959,7 +951,7 @@ pub fn get_impl_or_trait_item<'a, 'tcx>(cdata: Cmd, id: DefIndex, tcx: TyCtxt<'a
                     "the type {:?} of the method {:?} is not a function?",
                     ity, name)
             };
-            let explicit_self = get_explicit_self(item_doc);
+            let explicit_self = get_explicit_self(item_doc, tcx);
 
             ty::MethodTraitItem(Rc::new(ty::Method::new(name,
                                                         generics,
@@ -1000,7 +992,7 @@ pub fn get_trait_item_def_ids(cdata: Cmd, id: DefIndex)
     }).collect()
 }
 
-pub fn get_item_variances(cdata: Cmd, id: DefIndex) -> ty::ItemVariances {
+pub fn get_item_variances(cdata: Cmd, id: DefIndex) -> Vec<ty::Variance> {
     let item_doc = cdata.lookup_item(id);
     let variance_doc = reader::get_doc(item_doc, tag_item_variances);
     let mut decoder = reader::Decoder::new(variance_doc);
@@ -1124,19 +1116,19 @@ pub fn get_struct_field_names(cdata: Cmd, id: DefIndex) -> Vec<ast::Name> {
 fn get_meta_items(md: rbml::Doc) -> Vec<P<ast::MetaItem>> {
     reader::tagged_docs(md, tag_meta_item_word).map(|meta_item_doc| {
         let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
-        let n = token::intern_and_get_ident(nd.as_str_slice());
+        let n = token::intern_and_get_ident(nd.as_str());
         attr::mk_word_item(n)
     }).chain(reader::tagged_docs(md, tag_meta_item_name_value).map(|meta_item_doc| {
         let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
         let vd = reader::get_doc(meta_item_doc, tag_meta_item_value);
-        let n = token::intern_and_get_ident(nd.as_str_slice());
-        let v = token::intern_and_get_ident(vd.as_str_slice());
+        let n = token::intern_and_get_ident(nd.as_str());
+        let v = token::intern_and_get_ident(vd.as_str());
         // FIXME (#623): Should be able to decode MetaItemKind::NameValue variants,
         // but currently the encoder just drops them
         attr::mk_name_value_item_str(n, v)
     })).chain(reader::tagged_docs(md, tag_meta_item_list).map(|meta_item_doc| {
         let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
-        let n = token::intern_and_get_ident(nd.as_str_slice());
+        let n = token::intern_and_get_ident(nd.as_str());
         let subitems = get_meta_items(meta_item_doc);
         attr::mk_list_item(n, subitems)
     })).collect()
@@ -1191,7 +1183,7 @@ pub fn get_crate_deps(data: &[u8]) -> Vec<CrateDep> {
 
     fn docstr(doc: rbml::Doc, tag_: usize) -> String {
         let d = reader::get_doc(doc, tag_);
-        d.as_str_slice().to_string()
+        d.as_str().to_string()
     }
 
     reader::tagged_docs(depsdoc, tag_crate_dep).enumerate().map(|(crate_num, depdoc)| {
@@ -1233,14 +1225,14 @@ pub fn get_crate_hash(data: &[u8]) -> Svh {
 pub fn maybe_get_crate_name(data: &[u8]) -> Option<&str> {
     let cratedoc = rbml::Doc::new(data);
     reader::maybe_get_doc(cratedoc, tag_crate_crate_name).map(|doc| {
-        doc.as_str_slice()
+        doc.as_str()
     })
 }
 
 pub fn get_crate_disambiguator<'a>(data: &'a [u8]) -> &'a str {
     let crate_doc = rbml::Doc::new(data);
     let disambiguator_doc = reader::get_doc(crate_doc, tag_crate_disambiguator);
-    let slice: &'a str = disambiguator_doc.as_str_slice();
+    let slice: &'a str = disambiguator_doc.as_str();
     slice
 }
 
@@ -1446,11 +1438,12 @@ pub fn get_dylib_dependency_formats(cdata: Cmd)
                                   tag_dylib_dependency_formats);
     let mut result = Vec::new();
 
-    debug!("found dylib deps: {}", formats.as_str_slice());
-    for spec in formats.as_str_slice().split(',') {
+    debug!("found dylib deps: {}", formats.as_str());
+    for spec in formats.as_str().split(',') {
         if spec.is_empty() { continue }
-        let cnum = spec.split(':').nth(0).unwrap();
-        let link = spec.split(':').nth(1).unwrap();
+        let mut split = spec.split(':');
+        let cnum = split.next().unwrap();
+        let link = split.next().unwrap();
         let cnum: ast::CrateNum = cnum.parse().unwrap();
         let cnum = cdata.cnum_map.borrow()[cnum];
         result.push((cnum, if link == "d" {
@@ -1476,7 +1469,7 @@ pub fn get_method_arg_names(cdata: Cmd, id: DefIndex) -> Vec<String> {
     match reader::maybe_get_doc(method_doc, tag_method_argument_names) {
         Some(args_doc) => {
             reader::tagged_docs(args_doc, tag_method_argument_name).map(|name_doc| {
-                name_doc.as_str_slice().to_string()
+                name_doc.as_str().to_string()
             }).collect()
         },
         None => vec![],
@@ -1641,7 +1634,7 @@ fn item_def_key(item_doc: rbml::Doc) -> hir_map::DefKey {
             let mut decoder = reader::Decoder::new(def_key_doc);
             let simple_key = def_key::DefKey::decode(&mut decoder).unwrap();
             let name = reader::maybe_get_doc(item_doc, tag_paths_data_name).map(|name| {
-                token::intern(name.as_str_slice()).as_str()
+                token::intern(name.as_str()).as_str()
             });
             def_key::recover_def_key(simple_key, name)
         }
index c76cf2363923741b12a2db7c2e1421fe2fe61c78..f51299226fe7da904ff2f689e194d4eb8ad36cd6 100644 (file)
@@ -20,7 +20,7 @@
 
 use rustc::hir::def_id::{DefId, DefIndex};
 use middle::region;
-use rustc::ty::subst::Substs;
+use rustc::ty::subst::{Kind, Substs};
 use rustc::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
 
 use rbml;
@@ -129,19 +129,19 @@ fn parse_size(&mut self) -> Option<usize> {
     }
 
     pub fn parse_substs(&mut self) -> &'tcx Substs<'tcx> {
-        let mut regions = vec![];
-        let mut types = vec![];
+        let mut params = vec![];
         assert_eq!(self.next(), '[');
-        while self.peek() != '|' {
-            regions.push(self.parse_region());
-        }
-        assert_eq!(self.next(), '|');
         while self.peek() != ']' {
-            types.push(self.parse_ty());
+            let k = match self.next() {
+                'r' => Kind::from(self.parse_region()),
+                't' => Kind::from(self.parse_ty()),
+                _ => bug!()
+            };
+            params.push(k);
         }
         assert_eq!(self.next(), ']');
 
-        Substs::new(self.tcx, types, regions)
+        Substs::new(self.tcx, params)
     }
 
     pub fn parse_generics(&mut self) -> &'tcx ty::Generics<'tcx> {
@@ -207,8 +207,8 @@ fn parse_bound_region(&mut self) -> ty::BoundRegion {
         }
     }
 
-    pub fn parse_region(&mut self) -> ty::Region {
-        match self.next() {
+    pub fn parse_region(&mut self) -> &'tcx ty::Region {
+        self.tcx.mk_region(match self.next() {
             'b' => {
                 assert_eq!(self.next(), '[');
                 let id = ty::DebruijnIndex::new(self.parse_u32());
@@ -245,7 +245,7 @@ pub fn parse_region(&mut self) -> ty::Region {
             'e' => ty::ReEmpty,
             'E' => ty::ReErased,
             _ => bug!("parse_region: bad input")
-        }
+        })
     }
 
     fn parse_scope(&mut self) -> region::CodeExtent {
@@ -403,9 +403,7 @@ pub fn parse_ty(&mut self) -> Ty<'tcx> {
             '~' => return tcx.mk_box(self.parse_ty()),
             '*' => return tcx.mk_ptr(self.parse_mt()),
             '&' => {
-                let r = self.parse_region();
-                let mt = self.parse_mt();
-                return tcx.mk_ref(tcx.mk_region(r), mt);
+                return tcx.mk_ref(self.parse_region(), self.parse_mt());
             }
             'V' => {
                 let t = self.parse_ty();
@@ -657,7 +655,7 @@ fn parse_type_param_def(&mut self) -> ty::TypeParameterDef<'tcx> {
         }
     }
 
-    fn parse_region_param_def(&mut self) -> ty::RegionParameterDef {
+    fn parse_region_param_def(&mut self) -> ty::RegionParameterDef<'tcx> {
         let name = self.parse_name(':');
         let def_id = self.parse_def();
         let index = self.parse_u32();
@@ -681,7 +679,7 @@ fn parse_region_param_def(&mut self) -> ty::RegionParameterDef {
     }
 
 
-    fn parse_object_lifetime_default(&mut self) -> ty::ObjectLifetimeDefault {
+    fn parse_object_lifetime_default(&mut self) -> ty::ObjectLifetimeDefault<'tcx> {
         match self.next() {
             'a' => ty::ObjectLifetimeDefault::Ambiguous,
             'b' => ty::ObjectLifetimeDefault::BaseDefault,
index 90fd8a0eb2f654f2fa69e25c3b10ab5b426eb831..7255eae61d4533cd75b205caae28b6f7f256e121 100644 (file)
@@ -133,7 +133,7 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx
         ty::TyRawPtr(mt) => { write!(w, "*"); enc_mt(w, cx, mt); }
         ty::TyRef(r, mt) => {
             write!(w, "&");
-            enc_region(w, cx, *r);
+            enc_region(w, cx, r);
             enc_mt(w, cx, mt);
         }
         ty::TyArray(t, sz) => {
@@ -251,12 +251,16 @@ fn enc_opt<T, F>(w: &mut Cursor<Vec<u8>>, t: Option<T>, enc_f: F) where
 pub fn enc_substs<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
                             substs: &Substs<'tcx>) {
     write!(w, "[");
-    for &r in &substs.regions {
-        enc_region(w, cx, r);
-    }
-    write!(w, "|");
-    for &ty in &substs.types {
-        enc_ty(w, cx, ty);
+    for &k in substs.params() {
+        if let Some(ty) = k.as_type() {
+            write!(w, "t");
+            enc_ty(w, cx, ty);
+        } else if let Some(r) = k.as_region() {
+            write!(w, "r");
+            enc_region(w, cx, r);
+        } else {
+            bug!()
+        }
     }
     write!(w, "]");
 }
@@ -286,8 +290,8 @@ pub fn enc_generics<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
     }
 }
 
-pub fn enc_region(w: &mut Cursor<Vec<u8>>, cx: &ctxt, r: ty::Region) {
-    match r {
+pub fn enc_region(w: &mut Cursor<Vec<u8>>, cx: &ctxt, r: &ty::Region) {
+    match *r {
         ty::ReLateBound(id, br) => {
             write!(w, "b[{}|", id.depth);
             enc_bound_region(w, cx, br);
index 83f8c3b42c850a1eb52d28f78daed875f71a0749..026a79b32b8f735680af4685e7646bded4ff28c7 100644 (file)
@@ -13,7 +13,7 @@
 
 //! Routines for manipulating the control-flow graph.
 
-use build::{CFG, Location};
+use build::CFG;
 use rustc::mir::repr::*;
 
 impl<'tcx> CFG<'tcx> {
index ec390704d078976df454152ab796dba0a014fbfe..1b64b4d0b5317861712ebae924b4fec20e60fa32 100644 (file)
@@ -278,7 +278,7 @@ struct Binding<'tcx> {
     var_id: NodeId,
     var_ty: Ty<'tcx>,
     mutability: Mutability,
-    binding_mode: BindingMode,
+    binding_mode: BindingMode<'tcx>,
 }
 
 #[derive(Clone, Debug)]
index 8c9ed53c8ab4de2794b1c5ce499af946d38d29f7..bf43bfb326a581a3bc7980776e9977264e639acc 100644 (file)
@@ -293,7 +293,7 @@ pub fn perform_test(&mut self,
                     assert!(ty.is_slice());
                     let eq_def_id = self.hir.tcx().lang_items.eq_trait().unwrap();
                     let ty = mt.ty;
-                    let (mty, method) = self.hir.trait_method(eq_def_id, "eq", ty, vec![ty]);
+                    let (mty, method) = self.hir.trait_method(eq_def_id, "eq", ty, &[ty]);
 
                     let bool_ty = self.hir.bool_ty();
                     let eq_result = self.temp(bool_ty);
index 26eb782a73b0031c656e5353801828d421726502..59d6cf118596990bbe8db97410b6e6febdd3ae2c 100644 (file)
@@ -101,16 +101,6 @@ pub struct ScopeAuxiliary {
     pub postdoms: Vec<Location>,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
-pub struct Location {
-    /// the location is within this block
-    pub block: BasicBlock,
-
-    /// the location is the start of the this statement; or, if `statement_index`
-    /// == num-statements, then the start of the terminator.
-    pub statement_index: usize,
-}
-
 pub type ScopeAuxiliaryVec = IndexVec<ScopeId, ScopeAuxiliary>;
 
 ///////////////////////////////////////////////////////////////////////////
index 2f83c0ef1bebbc4bcadb36afa537eeed1c483c79..0b33e5a145083fabc58475ea20d0f153480413cb 100644 (file)
 use build::{BlockAnd, BlockAndExtension, Builder, CFG, ScopeAuxiliary, ScopeId};
 use rustc::middle::region::{CodeExtent, CodeExtentData};
 use rustc::middle::lang_items;
-use rustc::ty::subst::{Substs, Subst};
+use rustc::ty::subst::{Kind, Substs, Subst};
 use rustc::ty::{Ty, TyCtxt};
 use rustc::mir::repr::*;
 use syntax_pos::Span;
 use rustc_data_structures::indexed_vec::Idx;
 use rustc_data_structures::fnv::FnvHashMap;
 
+use std::iter;
+
 pub struct Scope<'tcx> {
     /// the scope-id within the scope_auxiliary
     id: ScopeId,
@@ -789,7 +791,7 @@ fn build_free<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                               -> TerminatorKind<'tcx> {
     let free_func = tcx.lang_items.require(lang_items::BoxFreeFnLangItem)
                        .unwrap_or_else(|e| tcx.sess.fatal(&e));
-    let substs = Substs::new(tcx, vec![data.item_ty], vec![]);
+    let substs = Substs::new(tcx, iter::once(Kind::from(data.item_ty)));
     TerminatorKind::Call {
         func: Operand::Constant(Constant {
             span: data.span,
index a61fdb79df822588fb61ca54dbd456f686ea4ff0..6e8a5771eea949a1ad4ea2af600e8548120d0b07 100644 (file)
@@ -108,7 +108,7 @@ fn make_mirror<'a, 'gcx>(self, cx: &mut Cx<'a, 'gcx, 'tcx>) -> Expr<'tcx> {
                                 region, ty::TypeAndMut { ty: expr.ty, mutbl: mutbl }),
                             span: expr.span,
                             kind: ExprKind::Borrow {
-                                region: *region,
+                                region: region,
                                 borrow_kind: to_borrow_kind(mutbl),
                                 arg: expr.to_ref()
                             }
@@ -137,7 +137,7 @@ fn make_mirror<'a, 'gcx>(self, cx: &mut Cx<'a, 'gcx, 'tcx>) -> Expr<'tcx> {
                                 ty: adjusted_ty,
                                 span: self.span,
                                 kind: ExprKind::Borrow {
-                                    region: *r,
+                                    region: r,
                                     borrow_kind: to_borrow_kind(m),
                                     arg: expr.to_ref(),
                                 },
@@ -154,7 +154,7 @@ fn make_mirror<'a, 'gcx>(self, cx: &mut Cx<'a, 'gcx, 'tcx>) -> Expr<'tcx> {
                                 ty: cx.tcx.mk_ref(region, ty::TypeAndMut { ty: expr.ty, mutbl: m }),
                                 span: self.span,
                                 kind: ExprKind::Borrow {
-                                    region: *region,
+                                    region: region,
                                     borrow_kind: to_borrow_kind(m),
                                     arg: expr.to_ref(),
                                 },
@@ -310,7 +310,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                 _ => span_bug!(expr.span, "type of & not region"),
             };
             ExprKind::Borrow {
-                region: *region,
+                region: region,
                 borrow_kind: to_borrow_kind(mutbl),
                 arg: expr.to_ref(),
             }
@@ -842,8 +842,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                     ExprKind::Deref {
                         arg: Expr {
                             temp_lifetime: temp_lifetime,
-                            ty: cx.tcx.mk_ref(
-                                cx.tcx.mk_region(borrow.region),
+                            ty: cx.tcx.mk_ref(borrow.region,
                                 ty::TypeAndMut {
                                     ty: var_ty,
                                     mutbl: borrow.kind.to_mutbl_lossy()
@@ -907,8 +906,7 @@ fn overloaded_operator<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
         }
 
         PassArgs::ByRef => {
-            let scope = cx.tcx.region_maps.node_extent(expr.id);
-            let region = cx.tcx.mk_region(ty::ReScope(scope));
+            let region = cx.tcx.node_scope_region(expr.id);
             let temp_lifetime = cx.tcx.region_maps.temporary_scope(expr.id);
             argrefs.extend(
                 args.iter()
@@ -922,7 +920,7 @@ fn overloaded_operator<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                             temp_lifetime: temp_lifetime,
                             ty: adjusted_ty,
                             span: expr.span,
-                            kind: ExprKind::Borrow { region: *region,
+                            kind: ExprKind::Borrow { region: region,
                                                      borrow_kind: BorrowKind::Shared,
                                                      arg: arg.to_ref() }
                         }.to_ref()
index 972e7f5be7075ed339a7cba7754e5f5bfb42d692..a38b429333b70f643aec7a315fb16f3d4d294b5b 100644 (file)
@@ -144,10 +144,10 @@ pub fn trait_method(&mut self,
                         trait_def_id: DefId,
                         method_name: &str,
                         self_ty: Ty<'tcx>,
-                        params: Vec<Ty<'tcx>>)
+                        params: &[Ty<'tcx>])
                         -> (Ty<'tcx>, Literal<'tcx>) {
         let method_name = token::intern(method_name);
-        let substs = Substs::new_trait(self.tcx, params, vec![], self_ty);
+        let substs = Substs::new_trait(self.tcx, self_ty, params);
         for trait_item in self.tcx.trait_items(trait_def_id).iter() {
             match *trait_item {
                 ty::ImplOrTraitItem::MethodTraitItem(ref method) => {
index c54c8bfb5981ed6d8469510cc76c47a212992f36..0bd22cd2d9308c4a35b9cee16b9d88b2b10d9ee0 100644 (file)
@@ -161,7 +161,7 @@ fn to_pattern(&mut self, pat: &hir::Pat) -> Pattern<'tcx> {
                 let id = self.cx.tcx.expect_def(pat.id).var_id();
                 let var_ty = self.cx.tcx.node_id_to_type(pat.id);
                 let region = match var_ty.sty {
-                    ty::TyRef(&r, _) => Some(r),
+                    ty::TyRef(r, _) => Some(r),
                     _ => None,
                 };
                 let (mutability, mode) = match bm {
index 2a5b7d0fb29024950cc727c92a407532a4810324..353f2433353028198f42c9a137600218f0368dac 100644 (file)
@@ -193,7 +193,7 @@ pub enum ExprKind<'tcx> {
         id: DefId,
     },
     Borrow {
-        region: Region,
+        region: &'tcx Region,
         borrow_kind: BorrowKind,
         arg: ExprRef<'tcx>,
     },
@@ -284,7 +284,7 @@ pub enum PatternKind<'tcx> {
     Binding {
         mutability: Mutability,
         name: ast::Name,
-        mode: BindingMode,
+        mode: BindingMode<'tcx>,
         var: ast::NodeId,
         ty: Ty<'tcx>,
         subpattern: Option<Pattern<'tcx>>,
@@ -332,9 +332,9 @@ pub enum PatternKind<'tcx> {
 }
 
 #[derive(Copy, Clone, Debug)]
-pub enum BindingMode {
+pub enum BindingMode<'tcx> {
     ByValue,
-    ByRef(Region, BorrowKind),
+    ByRef(&'tcx Region, BorrowKind),
 }
 
 #[derive(Clone, Debug)]
index c58491096b94f0d3957442e3738f9c14c19e3b80..d46a7b2bb9506fe22c446e414ad5fd92431446b3 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use build::{Location, ScopeAuxiliaryVec, ScopeId};
+use build::{ScopeAuxiliaryVec, ScopeId};
 use rustc::hir;
 use rustc::hir::def_id::DefId;
 use rustc::mir::repr::*;
index 818f060ed445ccff0404d04554de1508991a515b..32fddd293cacd770c4cef456f372e2d45e2e31e2 100644 (file)
 pub struct NoLandingPads;
 
 impl<'tcx> MutVisitor<'tcx> for NoLandingPads {
-    fn visit_terminator(&mut self, bb: BasicBlock, terminator: &mut Terminator<'tcx>) {
+    fn visit_terminator(&mut self,
+                        bb: BasicBlock,
+                        terminator: &mut Terminator<'tcx>,
+                        location: Location) {
         match terminator.kind {
             TerminatorKind::Goto { .. } |
             TerminatorKind::Resume |
@@ -37,7 +40,7 @@ fn visit_terminator(&mut self, bb: BasicBlock, terminator: &mut Terminator<'tcx>
                 unwind.take();
             },
         }
-        self.super_terminator(bb, terminator);
+        self.super_terminator(bb, terminator, location);
     }
 }
 
index 21b406c3bf5c99ba1e26d2822d62a3d356c1760e..f864f1678f23690747f3ab055006063d95732363 100644 (file)
 use rustc::ty::TyCtxt;
 use syntax_pos::Span;
 
-use build::Location;
-
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 
 use std::mem;
+use std::usize;
 
 /// State of a temporary during collection and promotion.
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
@@ -77,13 +76,12 @@ pub enum Candidate {
 
 struct TempCollector {
     temps: IndexVec<Temp, TempState>,
-    location: Location,
     span: Span
 }
 
 impl<'tcx> Visitor<'tcx> for TempCollector {
-    fn visit_lvalue(&mut self, lvalue: &Lvalue<'tcx>, context: LvalueContext) {
-        self.super_lvalue(lvalue, context);
+    fn visit_lvalue(&mut self, lvalue: &Lvalue<'tcx>, context: LvalueContext, location: Location) {
+        self.super_lvalue(lvalue, context, location);
         if let Lvalue::Temp(index) = *lvalue {
             // Ignore drops, if the temp gets promoted,
             // then it's constant and thus drop is noop.
@@ -101,7 +99,7 @@ fn visit_lvalue(&mut self, lvalue: &Lvalue<'tcx>, context: LvalueContext) {
                     LvalueContext::Store |
                     LvalueContext::Call => {
                         *temp = TempState::Defined {
-                            location: self.location,
+                            location: location,
                             uses: 0
                         };
                         return;
@@ -126,27 +124,11 @@ fn visit_lvalue(&mut self, lvalue: &Lvalue<'tcx>, context: LvalueContext) {
     fn visit_source_info(&mut self, source_info: &SourceInfo) {
         self.span = source_info.span;
     }
-
-    fn visit_statement(&mut self, bb: BasicBlock, statement: &Statement<'tcx>) {
-        assert_eq!(self.location.block, bb);
-        self.super_statement(bb, statement);
-        self.location.statement_index += 1;
-    }
-
-    fn visit_basic_block_data(&mut self, bb: BasicBlock, data: &BasicBlockData<'tcx>) {
-        self.location.statement_index = 0;
-        self.location.block = bb;
-        self.super_basic_block_data(bb, data);
-    }
 }
 
 pub fn collect_temps(mir: &Mir, rpo: &mut ReversePostorder) -> IndexVec<Temp, TempState> {
     let mut collector = TempCollector {
         temps: IndexVec::from_elem(TempState::Undefined, &mir.temp_decls),
-        location: Location {
-            block: START_BLOCK,
-            statement_index: 0
-        },
         span: mir.span
     };
     for (bb, data) in rpo {
@@ -266,9 +248,15 @@ fn promote_temp(&mut self, temp: Temp) -> Temp {
 
         // Then, recurse for components in the Rvalue or Call.
         if stmt_idx < no_stmts {
-            self.visit_rvalue(rvalue.as_mut().unwrap());
+            self.visit_rvalue(rvalue.as_mut().unwrap(), Location {
+                block: bb,
+                statement_index: stmt_idx
+            });
         } else {
-            self.visit_terminator_kind(bb, call.as_mut().unwrap());
+            self.visit_terminator_kind(bb, call.as_mut().unwrap(), Location {
+                block: bb,
+                statement_index: no_stmts
+            });
         }
 
         let new_temp = self.promoted.temp_decls.push(TempDecl {
@@ -327,7 +315,10 @@ fn promote_candidate(mut self, candidate: Candidate) {
                 }
             }
         };
-        self.visit_rvalue(&mut rvalue);
+        self.visit_rvalue(&mut rvalue, Location{
+            block: BasicBlock::new(0),
+            statement_index: usize::MAX
+        });
         self.assign(Lvalue::ReturnPointer, rvalue, span);
         self.source.promoted.push(self.promoted);
     }
@@ -335,11 +326,14 @@ fn promote_candidate(mut self, candidate: Candidate) {
 
 /// Replaces all temporaries with their promoted counterparts.
 impl<'a, 'tcx> MutVisitor<'tcx> for Promoter<'a, 'tcx> {
-    fn visit_lvalue(&mut self, lvalue: &mut Lvalue<'tcx>, context: LvalueContext) {
+    fn visit_lvalue(&mut self,
+                    lvalue: &mut Lvalue<'tcx>,
+                    context: LvalueContext,
+                    location: Location) {
         if let Lvalue::Temp(ref mut temp) = *lvalue {
             *temp = self.promote_temp(*temp);
         }
-        self.super_lvalue(lvalue, context);
+        self.super_lvalue(lvalue, context, location);
     }
 }
 
index bcdc0d2ea3f9dfb11d864722a3672984a96d327c..9e076851bc37d9b6c900482283ecaf3cb6f6bcc2 100644 (file)
@@ -36,8 +36,7 @@
 
 use std::collections::hash_map::Entry;
 use std::fmt;
-
-use build::Location;
+use std::usize;
 
 use super::promote_consts::{self, Candidate, TempState};
 
@@ -147,7 +146,6 @@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     return_qualif: Option<Qualif>,
     qualif: Qualif,
     const_fn_arg_vars: BitVector,
-    location: Location,
     temp_promotion_state: IndexVec<Temp, TempState>,
     promotion_candidates: Vec<Candidate>
 }
@@ -178,10 +176,6 @@ fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             return_qualif: None,
             qualif: Qualif::empty(),
             const_fn_arg_vars: BitVector::new(mir.var_decls.len()),
-            location: Location {
-                block: START_BLOCK,
-                statement_index: 0
-            },
             temp_promotion_state: temps,
             promotion_candidates: vec![]
         }
@@ -293,7 +287,7 @@ fn try_consume(&mut self) -> bool {
     }
 
     /// Assign the current qualification to the given destination.
-    fn assign(&mut self, dest: &Lvalue<'tcx>) {
+    fn assign(&mut self, dest: &Lvalue<'tcx>, location: Location) {
         let qualif = self.qualif;
         let span = self.span;
         let store = |slot: &mut Option<Qualif>| {
@@ -331,7 +325,7 @@ fn assign(&mut self, dest: &Lvalue<'tcx>) {
             // This must be an explicit assignment.
             _ => {
                 // Catch more errors in the destination.
-                self.visit_lvalue(dest, LvalueContext::Store);
+                self.visit_lvalue(dest, LvalueContext::Store, location);
                 self.statement_like();
             }
         }
@@ -399,7 +393,10 @@ fn qualify_const(&mut self) -> Qualif {
                     self.qualif = Qualif::NOT_CONST;
                     for index in 0..mir.var_decls.len() {
                         if !self.const_fn_arg_vars.contains(index) {
-                            self.assign(&Lvalue::Var(Var::new(index)));
+                            self.assign(&Lvalue::Var(Var::new(index)), Location {
+                                block: bb,
+                                statement_index: usize::MAX,
+                            });
                         }
                     }
 
@@ -445,7 +442,7 @@ fn qualify_const(&mut self) -> Qualif {
 /// For functions (constant or not), it also records
 /// candidates for promotion in promotion_candidates.
 impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
-    fn visit_lvalue(&mut self, lvalue: &Lvalue<'tcx>, context: LvalueContext) {
+    fn visit_lvalue(&mut self, lvalue: &Lvalue<'tcx>, context: LvalueContext, location: Location) {
         match *lvalue {
             Lvalue::Arg(_) => {
                 self.add(Qualif::FN_ARGUMENT);
@@ -477,7 +474,7 @@ fn visit_lvalue(&mut self, lvalue: &Lvalue<'tcx>, context: LvalueContext) {
             }
             Lvalue::Projection(ref proj) => {
                 self.nest(|this| {
-                    this.super_lvalue(lvalue, context);
+                    this.super_lvalue(lvalue, context, location);
                     match proj.elem {
                         ProjectionElem::Deref => {
                             if !this.try_consume() {
@@ -527,11 +524,11 @@ fn visit_lvalue(&mut self, lvalue: &Lvalue<'tcx>, context: LvalueContext) {
         }
     }
 
-    fn visit_operand(&mut self, operand: &Operand<'tcx>) {
+    fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
         match *operand {
             Operand::Consume(_) => {
                 self.nest(|this| {
-                    this.super_operand(operand);
+                    this.super_operand(operand, location);
                     this.try_consume();
                 });
             }
@@ -543,7 +540,7 @@ fn visit_operand(&mut self, operand: &Operand<'tcx>) {
 
                 if let Literal::Item { def_id, substs } = constant.literal {
                     // Don't peek inside generic (associated) constants.
-                    if !substs.types.is_empty() {
+                    if substs.types().next().is_some() {
                         self.add_type(constant.ty);
                     } else {
                         let qualif = qualify_const_item_cached(self.tcx,
@@ -570,9 +567,9 @@ fn visit_operand(&mut self, operand: &Operand<'tcx>) {
         }
     }
 
-    fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>) {
+    fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
         // Recurse through operands and lvalues.
-        self.super_rvalue(rvalue);
+        self.super_rvalue(rvalue, location);
 
         match *rvalue {
             Rvalue::Use(_) |
@@ -648,7 +645,7 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>) {
                 }
 
                 // We might have a candidate for promotion.
-                let candidate = Candidate::Ref(self.location);
+                let candidate = Candidate::Ref(location);
                 if self.mode == Mode::Fn || self.mode == Mode::ConstFn {
                     if !self.qualif.intersects(Qualif::NEVER_PROMOTE) {
                         // We can only promote direct borrows of temps.
@@ -733,9 +730,12 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>) {
         }
     }
 
-    fn visit_terminator_kind(&mut self, bb: BasicBlock, kind: &TerminatorKind<'tcx>) {
+    fn visit_terminator_kind(&mut self,
+                             bb: BasicBlock,
+                             kind: &TerminatorKind<'tcx>,
+                             location: Location) {
         if let TerminatorKind::Call { ref func, ref args, ref destination, .. } = *kind {
-            self.visit_operand(func);
+            self.visit_operand(func, location);
 
             let fn_ty = func.ty(self.mir, self.tcx);
             let (is_shuffle, is_const_fn) = match fn_ty.sty {
@@ -749,7 +749,7 @@ fn visit_terminator_kind(&mut self, bb: BasicBlock, kind: &TerminatorKind<'tcx>)
 
             for (i, arg) in args.iter().enumerate() {
                 self.nest(|this| {
-                    this.visit_operand(arg);
+                    this.visit_operand(arg, location);
                     if is_shuffle && i == 2 && this.mode == Mode::Fn {
                         let candidate = Candidate::ShuffleIndices(bb);
                         if !this.qualif.intersects(Qualif::NEVER_PROMOTE) {
@@ -827,16 +827,20 @@ struct and enum constructors",
                         self.deny_drop();
                     }
                 }
-                self.assign(dest);
+                self.assign(dest, location);
             }
         } else {
             // Qualify any operands inside other terminators.
-            self.super_terminator_kind(bb, kind);
+            self.super_terminator_kind(bb, kind, location);
         }
     }
 
-    fn visit_assign(&mut self, _: BasicBlock, dest: &Lvalue<'tcx>, rvalue: &Rvalue<'tcx>) {
-        self.visit_rvalue(rvalue);
+    fn visit_assign(&mut self,
+                    _: BasicBlock,
+                    dest: &Lvalue<'tcx>,
+                    rvalue: &Rvalue<'tcx>,
+                    location: Location) {
+        self.visit_rvalue(rvalue, location);
 
         // Check the allowed const fn argument forms.
         if let (Mode::ConstFn, &Lvalue::Var(index)) = (self.mode, dest) {
@@ -857,38 +861,32 @@ fn visit_assign(&mut self, _: BasicBlock, dest: &Lvalue<'tcx>, rvalue: &Rvalue<'
             }
         }
 
-        self.assign(dest);
+        self.assign(dest, location);
     }
 
     fn visit_source_info(&mut self, source_info: &SourceInfo) {
         self.span = source_info.span;
     }
 
-    fn visit_statement(&mut self, bb: BasicBlock, statement: &Statement<'tcx>) {
-        assert_eq!(self.location.block, bb);
+    fn visit_statement(&mut self, bb: BasicBlock, statement: &Statement<'tcx>, location: Location) {
         self.nest(|this| {
             this.visit_source_info(&statement.source_info);
             match statement.kind {
                 StatementKind::Assign(ref lvalue, ref rvalue) => {
-                    this.visit_assign(bb, lvalue, rvalue);
+                    this.visit_assign(bb, lvalue, rvalue, location);
                 }
                 StatementKind::SetDiscriminant { .. } |
                 StatementKind::StorageLive(_) |
                 StatementKind::StorageDead(_) => {}
             }
         });
-        self.location.statement_index += 1;
-    }
-
-    fn visit_terminator(&mut self, bb: BasicBlock, terminator: &Terminator<'tcx>) {
-        assert_eq!(self.location.block, bb);
-        self.nest(|this| this.super_terminator(bb, terminator));
     }
 
-    fn visit_basic_block_data(&mut self, bb: BasicBlock, data: &BasicBlockData<'tcx>) {
-        self.location.statement_index = 0;
-        self.location.block = bb;
-        self.super_basic_block_data(bb, data);
+    fn visit_terminator(&mut self,
+                        bb: BasicBlock,
+                        terminator: &Terminator<'tcx>,
+                        location: Location) {
+        self.nest(|this| this.super_terminator(bb, terminator, location));
     }
 }
 
index bbd2a93659b0aff480d70a5ba03d7113c597083c..21d4ae595e8ac2462023fdca6fe34b0a81cd9419 100644 (file)
@@ -68,17 +68,20 @@ fn visit_span(&mut self, span: &Span) {
         }
     }
 
-    fn visit_lvalue(&mut self, lvalue: &Lvalue<'tcx>, _context: visit::LvalueContext) {
-        self.sanitize_lvalue(lvalue);
+    fn visit_lvalue(&mut self,
+                    lvalue: &Lvalue<'tcx>,
+                    _context: visit::LvalueContext,
+                    location: Location) {
+        self.sanitize_lvalue(lvalue, location);
     }
 
-    fn visit_constant(&mut self, constant: &Constant<'tcx>) {
-        self.super_constant(constant);
+    fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
+        self.super_constant(constant, location);
         self.sanitize_type(constant, constant.ty);
     }
 
-    fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>) {
-        self.super_rvalue(rvalue);
+    fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
+        self.super_rvalue(rvalue, location);
         if let Some(ty) = rvalue.ty(self.mir, self.tcx()) {
             self.sanitize_type(rvalue, ty);
         }
@@ -124,7 +127,7 @@ fn sanitize_type(&mut self, parent: &fmt::Debug, ty: Ty<'tcx>) -> Ty<'tcx> {
         }
     }
 
-    fn sanitize_lvalue(&mut self, lvalue: &Lvalue<'tcx>) -> LvalueTy<'tcx> {
+    fn sanitize_lvalue(&mut self, lvalue: &Lvalue<'tcx>, location: Location) -> LvalueTy<'tcx> {
         debug!("sanitize_lvalue: {:?}", lvalue);
         match *lvalue {
             Lvalue::Var(index) => LvalueTy::Ty { ty: self.mir.var_decls[index].ty },
@@ -136,14 +139,14 @@ fn sanitize_lvalue(&mut self, lvalue: &Lvalue<'tcx>) -> LvalueTy<'tcx> {
                 LvalueTy::Ty { ty: self.mir.return_ty }
             }
             Lvalue::Projection(ref proj) => {
-                let base_ty = self.sanitize_lvalue(&proj.base);
+                let base_ty = self.sanitize_lvalue(&proj.base, location);
                 if let LvalueTy::Ty { ty } = base_ty {
                     if ty.references_error() {
                         assert!(self.errors_reported);
                         return LvalueTy::Ty { ty: self.tcx().types.err };
                     }
                 }
-                self.sanitize_projection(base_ty, &proj.elem, lvalue)
+                self.sanitize_projection(base_ty, &proj.elem, lvalue, location)
             }
         }
     }
@@ -151,7 +154,8 @@ fn sanitize_lvalue(&mut self, lvalue: &Lvalue<'tcx>) -> LvalueTy<'tcx> {
     fn sanitize_projection(&mut self,
                            base: LvalueTy<'tcx>,
                            pi: &LvalueElem<'tcx>,
-                           lvalue: &Lvalue<'tcx>)
+                           lvalue: &Lvalue<'tcx>,
+                           location: Location)
                            -> LvalueTy<'tcx> {
         debug!("sanitize_projection: {:?} {:?} {:?}", base, pi, lvalue);
         let tcx = self.tcx();
@@ -168,7 +172,7 @@ fn sanitize_projection(&mut self,
                 }
             }
             ProjectionElem::Index(ref i) => {
-                self.visit_operand(i);
+                self.visit_operand(i, location);
                 let index_ty = i.ty(self.mir, tcx);
                 if index_ty != tcx.types.usize {
                     LvalueTy::Ty {
index b116ab7b3161abf628712357973b2d0b023a45b2..4aae6d690c4df3ccf1bebce7d206b8eff82983cb 100644 (file)
@@ -683,7 +683,7 @@ fn borrow(&mut self,
               borrow_id: ast::NodeId,
               _borrow_span: Span,
               cmt: mc::cmt<'tcx>,
-              _loan_region: ty::Region,
+              _loan_region: &'tcx ty::Region,
               bk: ty::BorrowKind,
               loan_cause: euv::LoanCause) {
         // Kind of hacky, but we allow Unsafe coercions in constants.
index 782ee34edd4f98ec90c45b2716b332bd2e19b79f..c3ef5a72a2944e8b2c2a092e69d8535599679c88 100644 (file)
@@ -88,7 +88,7 @@ fn borrow(&mut self,
               _borrow_id: ast::NodeId,
               _borrow_span: Span,
               _cmt: mc::cmt,
-              _loan_region: ty::Region,
+              _loan_region: &'tcx ty::Region,
               _bk: ty::BorrowKind,
               _loan_cause: euv::LoanCause) {
     }
index 25a1479c289488c43af1001a3b26db4556300efa..9b02cbe6721f34e6dd3118250373c1345240fa02 100644 (file)
 use rustc::middle::{cstore, weak_lang_items};
 use rustc::hir::def_id::DefId;
 use rustc::hir::map as hir_map;
-use rustc::ty::{self, TyCtxt, TypeFoldable};
+use rustc::ty::{Ty, TyCtxt, TypeFoldable};
 use rustc::ty::item_path::{self, ItemPathBuffer, RootMode};
+use rustc::ty::subst::Substs;
 use rustc::hir::map::definitions::{DefPath, DefPathData};
 
 use syntax::attr;
@@ -126,14 +127,14 @@ fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
                              // parameters substituted; this is
                              // included in the hash as a kind of
                              // safeguard.
-                             item_type: ty::Ty<'tcx>,
+                             item_type: Ty<'tcx>,
 
                              // values for generic type parameters,
                              // if any.
-                             parameters: &[ty::Ty<'tcx>])
+                             substs: Option<&Substs<'tcx>>)
                              -> String {
     debug!("get_symbol_hash(def_path={:?}, parameters={:?})",
-           def_path, parameters);
+           def_path, substs);
 
     let tcx = scx.tcx();
 
@@ -154,11 +155,13 @@ fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
     hash_state.input(&encoded_item_type[..]);
 
     // also include any type parameters (for generic items)
-    for t in parameters {
-       assert!(!t.has_erasable_regions());
-       assert!(!t.needs_subst());
-       let encoded_type = tcx.sess.cstore.encode_type(tcx, t, def_id_to_string);
-       hash_state.input(&encoded_type[..]);
+    if let Some(substs) = substs {
+        for t in substs.types() {
+            assert!(!t.has_erasable_regions());
+            assert!(!t.needs_subst());
+            let encoded_type = tcx.sess.cstore.encode_type(tcx, t, def_id_to_string);
+            hash_state.input(&encoded_type[..]);
+        }
     }
 
     return format!("h{}", truncated_hash_result(&mut *hash_state));
@@ -252,7 +255,7 @@ pub fn symbol_name(self, scx: &SharedCrateContext<'a, 'tcx>) -> String {
         // and should not matter anyhow.
         let instance_ty = scx.tcx().erase_regions(&instance_ty.ty);
 
-        let hash = get_symbol_hash(scx, &def_path, instance_ty, &substs.types);
+        let hash = get_symbol_hash(scx, &def_path, instance_ty, Some(substs));
 
         let mut buffer = SymbolPathBuffer {
             names: Vec::with_capacity(def_path.data.len())
@@ -282,14 +285,14 @@ fn push(&mut self, text: &str) {
 }
 
 pub fn exported_name_from_type_and_prefix<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
-                                                    t: ty::Ty<'tcx>,
+                                                    t: Ty<'tcx>,
                                                     prefix: &str)
                                                     -> String {
     let empty_def_path = DefPath {
         data: vec![],
         krate: cstore::LOCAL_CRATE,
     };
-    let hash = get_symbol_hash(scx, &empty_def_path, t, &[]);
+    let hash = get_symbol_hash(scx, &empty_def_path, t, None);
     let path = [token::intern_and_get_ident(prefix)];
     mangle(path.iter().cloned(), Some(&hash[..]))
 }
@@ -297,7 +300,7 @@ pub fn exported_name_from_type_and_prefix<'a, 'tcx>(scx: &SharedCrateContext<'a,
 /// Only symbols that are invisible outside their compilation unit should use a
 /// name generated by this function.
 pub fn internal_name_from_type_and_suffix<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
-                                                    t: ty::Ty<'tcx>,
+                                                    t: Ty<'tcx>,
                                                     suffix: &str)
                                                     -> String {
     let path = [token::intern(&t.to_string()).as_str(),
@@ -306,7 +309,7 @@ pub fn internal_name_from_type_and_suffix<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>
         data: vec![],
         krate: cstore::LOCAL_CRATE,
     };
-    let hash = get_symbol_hash(ccx.shared(), &def_path, t, &[]);
+    let hash = get_symbol_hash(ccx.shared(), &def_path, t, None);
     mangle(path.iter().cloned(), Some(&hash[..]))
 }
 
index 165884c8f55a2a9eb4605c9dd2356e7c4444700b..5e431193a2c4cac96366bd61e1376b283a01b573 100644 (file)
@@ -514,7 +514,7 @@ pub fn custom_coerce_unsize_info<'scx, 'tcx>(scx: &SharedCrateContext<'scx, 'tcx
                                              -> CustomCoerceUnsized {
     let trait_ref = ty::Binder(ty::TraitRef {
         def_id: scx.tcx().lang_items.coerce_unsized_trait().unwrap(),
-        substs: Substs::new_trait(scx.tcx(), vec![target_ty], vec![], source_ty)
+        substs: Substs::new_trait(scx.tcx(), source_ty, &[target_ty])
     });
 
     match fulfill_obligation(scx, DUMMY_SP, trait_ref) {
index 9aa486dc62811604f7dbda71f3543994d12c21f7..a30f8f291a6775c676dc1527984b2b922c4e1314 100644 (file)
@@ -400,9 +400,9 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
     debug!("get_fn(def_id={:?}, substs={:?})", def_id, substs);
 
-    assert!(!substs.types.needs_infer());
-    assert!(!substs.types.has_escaping_regions());
-    assert!(!substs.types.has_param_types());
+    assert!(!substs.needs_infer());
+    assert!(!substs.has_escaping_regions());
+    assert!(!substs.has_param_types());
 
     let substs = tcx.normalize_associated_type(&substs);
     let instance = Instance::new(def_id, substs);
index 76910304eebb0e40c43717fbe1c4f8cf1c3ad2ff..ba979813aa1f071fe50df7f3d5f134f899a5ee31 100644 (file)
 use rustc::mir::repr as mir;
 use rustc::mir::visit as mir_visit;
 use rustc::mir::visit::Visitor as MirVisitor;
+use rustc::mir::repr::Location;
 
 use rustc_const_eval as const_eval;
 
@@ -446,7 +447,7 @@ struct MirNeighborCollector<'a, 'tcx: 'a> {
 
 impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
 
-    fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>) {
+    fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) {
         debug!("visiting rvalue {:?}", *rvalue);
 
         match *rvalue {
@@ -517,12 +518,13 @@ fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>) {
             _ => { /* not interesting */ }
         }
 
-        self.super_rvalue(rvalue);
+        self.super_rvalue(rvalue, location);
     }
 
     fn visit_lvalue(&mut self,
                     lvalue: &mir::Lvalue<'tcx>,
-                    context: mir_visit::LvalueContext) {
+                    context: mir_visit::LvalueContext,
+                    location: Location) {
         debug!("visiting lvalue {:?}", *lvalue);
 
         if let mir_visit::LvalueContext::Drop = context {
@@ -537,10 +539,10 @@ fn visit_lvalue(&mut self,
             self.output.push(TransItem::DropGlue(DropGlueKind::Ty(ty)));
         }
 
-        self.super_lvalue(lvalue, context);
+        self.super_lvalue(lvalue, context, location);
     }
 
-    fn visit_operand(&mut self, operand: &mir::Operand<'tcx>) {
+    fn visit_operand(&mut self, operand: &mir::Operand<'tcx>, location: Location) {
         debug!("visiting operand {:?}", *operand);
 
         let callee = match *operand {
@@ -620,7 +622,7 @@ fn visit_operand(&mut self, operand: &mir::Operand<'tcx>) {
             }
         }
 
-        self.super_operand(operand);
+        self.super_operand(operand, location);
 
         fn can_result_in_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                               def_id: DefId)
@@ -654,7 +656,8 @@ fn can_result_in_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // we would not register drop-glues.
     fn visit_terminator_kind(&mut self,
                              block: mir::BasicBlock,
-                             kind: &mir::TerminatorKind<'tcx>) {
+                             kind: &mir::TerminatorKind<'tcx>,
+                             location: Location) {
         let tcx = self.scx.tcx();
         match *kind {
             mir::TerminatorKind::Call {
@@ -682,7 +685,7 @@ fn visit_terminator_kind(&mut self,
             _ => { /* Nothing to do. */ }
         }
 
-        self.super_terminator_kind(block, kind);
+        self.super_terminator_kind(block, kind, location);
 
         fn is_drop_in_place_intrinsic<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                                 def_id: DefId,
@@ -753,7 +756,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
                                    .drop_trait()
                                    .unwrap();
 
-        let self_type_substs = Substs::new_trait(scx.tcx(), vec![], vec![], ty);
+        let self_type_substs = Substs::new_trait(scx.tcx(), ty, &[]);
 
         let trait_ref = ty::TraitRef {
             def_id: drop_trait_def_id,
@@ -1235,7 +1238,7 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     // The substitutions we have are on the impl, so we grab
                     // the method type from the impl to substitute into.
                     let impl_substs = Substs::for_item(tcx, impl_def_id,
-                                                       |_, _| ty::ReErased,
+                                                       |_, _| tcx.mk_region(ty::ReErased),
                                                        |_, _| tcx.types.err);
                     let mth = meth::get_impl_method(tcx,
                                                     callee_substs,
index c5053e4feee6200bc7e98e511f93bdc6a07a1312..5055ed86a038662de131f7215739becf79ab406e 100644 (file)
@@ -265,7 +265,7 @@ pub fn BuilderRef_res(b: BuilderRef) -> BuilderRef_res {
 }
 
 pub fn validate_substs(substs: &Substs) {
-    assert!(!substs.types.needs_infer());
+    assert!(!substs.needs_infer());
 }
 
 // Function context.  Every LLVM function we create will have one of
index 0a295b251b31e4ff85ddc4c028b43b1735562219..71184dd3f814d11fcf300122c6ea9610ea17541a 100644 (file)
@@ -563,7 +563,9 @@ pub fn translation_items(&self) -> &RefCell<FnvHashSet<TransItem<'tcx>>> {
     /// Given the def-id of some item that has no type parameters, make
     /// a suitable "empty substs" for it.
     pub fn empty_substs_for_def_id(&self, item_def_id: DefId) -> &'tcx Substs<'tcx> {
-        Substs::for_item(self.tcx(), item_def_id, |_, _| ty::ReErased, |_, _| {
+        Substs::for_item(self.tcx(), item_def_id,
+                         |_, _| self.tcx().mk_region(ty::ReErased),
+                         |_, _| {
             bug!("empty_substs_for_def_id: {:?} has type parameters", item_def_id)
         })
     }
index 58cf85747374ae45c0a88bea7aadfab69097d3fa..21716d55ac6fa33c67d950d467f4d49deae26574 100644 (file)
 use rustc_data_structures::bitvec::BitVector;
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
 
+use syntax_pos::BytePos;
+
+#[derive(Clone, Copy, Debug)]
+pub struct MirDebugScope {
+    pub scope_metadata: DIScope,
+    // Start and end offsets of the file to which this DIScope belongs.
+    // These are used to quickly determine whether some span refers to the same file.
+    pub file_start_pos: BytePos,
+    pub file_end_pos: BytePos,
+}
+
+impl MirDebugScope {
+    pub fn is_valid(&self) -> bool {
+        !self.scope_metadata.is_null()
+    }
+}
+
 /// Produce DIScope DIEs for each MIR Scope which has variables defined in it.
 /// If debuginfo is disabled, the returned vector is empty.
-pub fn create_mir_scopes(fcx: &FunctionContext) -> IndexVec<VisibilityScope, DIScope> {
+pub fn create_mir_scopes(fcx: &FunctionContext) -> IndexVec<VisibilityScope, MirDebugScope> {
     let mir = fcx.mir.clone().expect("create_mir_scopes: missing MIR for fn");
-    let mut scopes = IndexVec::from_elem(ptr::null_mut(), &mir.visibility_scopes);
+    let null_scope = MirDebugScope {
+        scope_metadata: ptr::null_mut(),
+        file_start_pos: BytePos(0),
+        file_end_pos: BytePos(0)
+    };
+    let mut scopes = IndexVec::from_elem(null_scope, &mir.visibility_scopes);
 
     let fn_metadata = match fcx.debug_context {
         FunctionDebugContext::RegularContext(box ref data) => data.fn_metadata,
@@ -59,8 +81,8 @@ fn make_mir_scope(ccx: &CrateContext,
                   has_variables: &BitVector,
                   fn_metadata: DISubprogram,
                   scope: VisibilityScope,
-                  scopes: &mut IndexVec<VisibilityScope, DIScope>) {
-    if !scopes[scope].is_null() {
+                  scopes: &mut IndexVec<VisibilityScope, MirDebugScope>) {
+    if scopes[scope].is_valid() {
         return;
     }
 
@@ -70,7 +92,12 @@ fn make_mir_scope(ccx: &CrateContext,
         scopes[parent]
     } else {
         // The root is the function itself.
-        scopes[scope] = fn_metadata;
+        let loc = span_start(ccx, mir.span);
+        scopes[scope] = MirDebugScope {
+            scope_metadata: fn_metadata,
+            file_start_pos: loc.file.start_pos,
+            file_end_pos: loc.file.end_pos,
+        };
         return;
     };
 
@@ -81,20 +108,25 @@ fn make_mir_scope(ccx: &CrateContext,
         // However, we don't skip creating a nested scope if
         // our parent is the root, because we might want to
         // put arguments in the root and not have shadowing.
-        if parent_scope != fn_metadata {
+        if parent_scope.scope_metadata != fn_metadata {
             scopes[scope] = parent_scope;
             return;
         }
     }
 
     let loc = span_start(ccx, scope_data.span);
-    scopes[scope] = unsafe {
     let file_metadata = file_metadata(ccx, &loc.file.name, &loc.file.abs_path);
+    let scope_metadata = unsafe {
         llvm::LLVMRustDIBuilderCreateLexicalBlock(
             DIB(ccx),
-            parent_scope,
+            parent_scope.scope_metadata,
             file_metadata,
             loc.line as c_uint,
             loc.col.to_usize() as c_uint)
     };
+    scopes[scope] = MirDebugScope {
+        scope_metadata: scope_metadata,
+        file_start_pos: loc.file.start_pos,
+        file_end_pos: loc.file.end_pos,
+    };
 }
index ba91b44343868decf494f3fde8396616c62bff71..67d4a0e044c9c8ac7d7b6594255269615a3ba6c5 100644 (file)
@@ -22,7 +22,7 @@
 use session::Session;
 
 use llvm::{self, ValueRef};
-use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType};
+use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType, DILexicalBlock};
 
 use rustc::hir::def_id::DefId;
 use rustc::ty::subst::Substs;
@@ -342,11 +342,10 @@ fn from_def_id_and_substs<'a, 'tcx>(type_map: &mut TypeMap<'tcx>,
             // Add the def-index as the second part
             output.push_str(&format!("{:x}", def_id.index.as_usize()));
 
-            let tps = &substs.types;
-            if !tps.is_empty() {
+            if substs.types().next().is_some() {
                 output.push('<');
 
-                for &type_parameter in tps {
+                for type_parameter in substs.types() {
                     let param_type_id =
                         type_map.get_unique_type_id_of_type(cx, type_parameter);
                     let param_type_id =
@@ -1839,3 +1838,17 @@ pub fn create_global_var_metadata(cx: &CrateContext,
                                                     ptr::null_mut());
     }
 }
+
+// Creates an "extension" of an existing DIScope into another file.
+pub fn extend_scope_to_file(ccx: &CrateContext,
+                            scope_metadata: DIScope,
+                            file: &syntax_pos::FileMap)
+                            -> DILexicalBlock {
+    let file_metadata = file_metadata(ccx, &file.name, &file.abs_path);
+    unsafe {
+        llvm::LLVMRustDIBuilderCreateLexicalBlockFile(
+            DIB(ccx),
+            scope_metadata,
+            file_metadata)
+    }
+}
\ No newline at end of file
index cbf423b0739a399f3e61f0ced5ba0a5b44f50efd..5e248261e11852a54ecd69d69d0ce0d6172a3ad1 100644 (file)
 mod create_scope_map;
 mod source_loc;
 
-pub use self::create_scope_map::create_mir_scopes;
+pub use self::create_scope_map::{create_mir_scopes, MirDebugScope};
 pub use self::source_loc::start_emitting_source_locations;
 pub use self::metadata::create_global_var_metadata;
+pub use self::metadata::extend_scope_to_file;
 
 #[allow(non_upper_case_globals)]
 const DW_TAG_auto_variable: c_uint = 0x100;
@@ -343,37 +344,35 @@ fn get_function_signature<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     fn get_template_parameters<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                          generics: &ty::Generics<'tcx>,
-                                         param_substs: &Substs<'tcx>,
+                                         substs: &Substs<'tcx>,
                                          file_metadata: DIFile,
                                          name_to_append_suffix_to: &mut String)
                                          -> DIArray
     {
-        let actual_types = &param_substs.types;
-
-        if actual_types.is_empty() {
+        if substs.types().next().is_none() {
             return create_DIArray(DIB(cx), &[]);
         }
 
         name_to_append_suffix_to.push('<');
-        for (i, &actual_type) in actual_types.iter().enumerate() {
+        for (i, actual_type) in substs.types().enumerate() {
+            if i != 0 {
+                name_to_append_suffix_to.push_str(",");
+            }
+
             let actual_type = cx.tcx().normalize_associated_type(&actual_type);
             // Add actual type name to <...> clause of function name
             let actual_type_name = compute_debuginfo_type_name(cx,
                                                                actual_type,
                                                                true);
             name_to_append_suffix_to.push_str(&actual_type_name[..]);
-
-            if i != actual_types.len() - 1 {
-                name_to_append_suffix_to.push_str(",");
-            }
         }
         name_to_append_suffix_to.push('>');
 
         // Again, only create type information if full debuginfo is enabled
         let template_params: Vec<_> = if cx.sess().opts.debuginfo == FullDebugInfo {
             let names = get_type_parameter_names(cx, generics);
-            actual_types.iter().zip(names).map(|(ty, name)| {
-                let actual_type = cx.tcx().normalize_associated_type(ty);
+            substs.types().zip(names).map(|(ty, name)| {
+                let actual_type = cx.tcx().normalize_associated_type(&ty);
                 let actual_type_metadata = type_metadata(cx, actual_type, syntax_pos::DUMMY_SP);
                 let name = CString::new(name.as_str().as_bytes()).unwrap();
                 unsafe {
@@ -418,7 +417,15 @@ fn get_containing_scope<'ccx, 'tcx>(cx: &CrateContext<'ccx, 'tcx>,
                 let impl_self_ty = monomorphize::apply_param_substs(cx.tcx(),
                                                                     instance.substs,
                                                                     &impl_self_ty);
-                Some(type_metadata(cx, impl_self_ty, syntax_pos::DUMMY_SP))
+
+                // Only "class" methods are generally understood by LLVM,
+                // so avoid methods on other types (e.g. `<*mut T>::null`).
+                match impl_self_ty.sty {
+                    ty::TyStruct(..) | ty::TyEnum(..) => {
+                        Some(type_metadata(cx, impl_self_ty, syntax_pos::DUMMY_SP))
+                    }
+                    _ => None
+                }
             } else {
                 // For trait method impls we still use the "parallel namespace"
                 // strategy
index 2a996ca75a37e78597be98fafdf760ca2f0d291b..f757578e6954def808863c0a174668972d89c17b 100644 (file)
@@ -175,13 +175,13 @@ fn push_item_name(cx: &CrateContext,
     fn push_type_params<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                   substs: &Substs<'tcx>,
                                   output: &mut String) {
-        if substs.types.is_empty() {
+        if substs.types().next().is_none() {
             return;
         }
 
         output.push('<');
 
-        for &type_parameter in &substs.types {
+        for type_parameter in substs.types() {
             push_debuginfo_type_name(cx, type_parameter, true, output);
             output.push_str(", ");
         }
index 6a072c84dd9b39e39d6b3faa33e22c7950213f8d..f29d85f3b52f06aff255178a7c35db4e72902d86 100644 (file)
@@ -302,7 +302,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     let trait_ref = ty::Binder(ty::TraitRef {
         def_id: tcx.lang_items.drop_trait().unwrap(),
-        substs: Substs::new_trait(tcx, vec![], vec![], t)
+        substs: Substs::new_trait(tcx, t, &[])
     });
     let vtbl = match fulfill_obligation(bcx.ccx().shared(), DUMMY_SP, trait_ref) {
         traits::VtableImpl(data) => data,
index 7faff98aea4425b490468d27b581cca86afdb58b..8bef7584db9e22639be49f5fd6ae451e1f96f468 100644 (file)
@@ -146,12 +146,12 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             Call(bcx, llfn, &[], call_debug_location)
         }
         (_, "size_of") => {
-            let tp_ty = substs.types[0];
+            let tp_ty = substs.type_at(0);
             let lltp_ty = type_of::type_of(ccx, tp_ty);
             C_uint(ccx, machine::llsize_of_alloc(ccx, lltp_ty))
         }
         (_, "size_of_val") => {
-            let tp_ty = substs.types[0];
+            let tp_ty = substs.type_at(0);
             if !type_is_sized(tcx, tp_ty) {
                 let (llsize, _) =
                     glue::size_and_align_of_dst(&bcx.build(), tp_ty, llargs[1]);
@@ -162,11 +162,11 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             }
         }
         (_, "min_align_of") => {
-            let tp_ty = substs.types[0];
+            let tp_ty = substs.type_at(0);
             C_uint(ccx, type_of::align_of(ccx, tp_ty))
         }
         (_, "min_align_of_val") => {
-            let tp_ty = substs.types[0];
+            let tp_ty = substs.type_at(0);
             if !type_is_sized(tcx, tp_ty) {
                 let (_, llalign) =
                     glue::size_and_align_of_dst(&bcx.build(), tp_ty, llargs[1]);
@@ -176,12 +176,12 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             }
         }
         (_, "pref_align_of") => {
-            let tp_ty = substs.types[0];
+            let tp_ty = substs.type_at(0);
             let lltp_ty = type_of::type_of(ccx, tp_ty);
             C_uint(ccx, machine::llalign_of_pref(ccx, lltp_ty))
         }
         (_, "drop_in_place") => {
-            let tp_ty = substs.types[0];
+            let tp_ty = substs.type_at(0);
             let is_sized = type_is_sized(tcx, tp_ty);
             let ptr = if is_sized {
                 llargs[0]
@@ -199,15 +199,15 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             C_nil(ccx)
         }
         (_, "type_name") => {
-            let tp_ty = substs.types[0];
+            let tp_ty = substs.type_at(0);
             let ty_name = token::intern_and_get_ident(&tp_ty.to_string());
             C_str_slice(ccx, ty_name)
         }
         (_, "type_id") => {
-            C_u64(ccx, ccx.tcx().type_id_hash(substs.types[0]))
+            C_u64(ccx, ccx.tcx().type_id_hash(substs.type_at(0)))
         }
         (_, "init") => {
-            let tp_ty = substs.types[0];
+            let tp_ty = substs.type_at(0);
             if !type_is_zero_size(ccx, tp_ty) {
                 // Just zero out the stack slot. (See comment on base::memzero for explanation)
                 init_zero_mem(bcx, llresult, tp_ty);
@@ -219,7 +219,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             C_nil(ccx)
         }
         (_, "needs_drop") => {
-            let tp_ty = substs.types[0];
+            let tp_ty = substs.type_at(0);
 
             C_bool(ccx, bcx.fcx.type_needs_drop(tp_ty))
         }
@@ -238,7 +238,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             copy_intrinsic(bcx,
                            false,
                            false,
-                           substs.types[0],
+                           substs.type_at(0),
                            llargs[1],
                            llargs[0],
                            llargs[2],
@@ -248,7 +248,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             copy_intrinsic(bcx,
                            true,
                            false,
-                           substs.types[0],
+                           substs.type_at(0),
                            llargs[1],
                            llargs[0],
                            llargs[2],
@@ -257,7 +257,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
         (_, "write_bytes") => {
             memset_intrinsic(bcx,
                              false,
-                             substs.types[0],
+                             substs.type_at(0),
                              llargs[0],
                              llargs[1],
                              llargs[2],
@@ -268,7 +268,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             copy_intrinsic(bcx,
                            false,
                            true,
-                           substs.types[0],
+                           substs.type_at(0),
                            llargs[0],
                            llargs[1],
                            llargs[2],
@@ -278,7 +278,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             copy_intrinsic(bcx,
                            true,
                            true,
-                           substs.types[0],
+                           substs.type_at(0),
                            llargs[0],
                            llargs[1],
                            llargs[2],
@@ -287,14 +287,14 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
         (_, "volatile_set_memory") => {
             memset_intrinsic(bcx,
                              true,
-                             substs.types[0],
+                             substs.type_at(0),
                              llargs[0],
                              llargs[1],
                              llargs[2],
                              call_debug_location)
         }
         (_, "volatile_load") => {
-            let tp_ty = substs.types[0];
+            let tp_ty = substs.type_at(0);
             let mut ptr = llargs[0];
             if let Some(ty) = fn_ty.ret.cast {
                 ptr = PointerCast(bcx, ptr, ty.ptr_to());
@@ -306,7 +306,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             to_immediate(bcx, load, tp_ty)
         },
         (_, "volatile_store") => {
-            let tp_ty = substs.types[0];
+            let tp_ty = substs.type_at(0);
             if type_is_fat_ptr(bcx.tcx(), tp_ty) {
                 VolatileStore(bcx, llargs[1], get_dataptr(bcx, llargs[0]));
                 VolatileStore(bcx, llargs[2], get_meta(bcx, llargs[0]));
@@ -406,7 +406,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
         },
 
         (_, "discriminant_value") => {
-            let val_ty = substs.types[0];
+            let val_ty = substs.type_at(0);
             match val_ty.sty {
                 ty::TyEnum(..) => {
                     let repr = adt::represent_type(ccx, val_ty);
@@ -458,7 +458,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
 
             match split[1] {
                 "cxchg" | "cxchgweak" => {
-                    let sty = &substs.types[0].sty;
+                    let sty = &substs.type_at(0).sty;
                     if int_type_width_signed(sty, ccx).is_some() {
                         let weak = if split[1] == "cxchgweak" { llvm::True } else { llvm::False };
                         let val = AtomicCmpXchg(bcx, llargs[0], llargs[1], llargs[2],
@@ -477,7 +477,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                 }
 
                 "load" => {
-                    let sty = &substs.types[0].sty;
+                    let sty = &substs.type_at(0).sty;
                     if int_type_width_signed(sty, ccx).is_some() {
                         AtomicLoad(bcx, llargs[0], order)
                     } else {
@@ -490,7 +490,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                 }
 
                 "store" => {
-                    let sty = &substs.types[0].sty;
+                    let sty = &substs.type_at(0).sty;
                     if int_type_width_signed(sty, ccx).is_some() {
                         AtomicStore(bcx, llargs[1], llargs[0], order);
                     } else {
@@ -529,7 +529,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                         _ => ccx.sess().fatal("unknown atomic operation")
                     };
 
-                    let sty = &substs.types[0].sty;
+                    let sty = &substs.type_at(0).sty;
                     if int_type_width_signed(sty, ccx).is_some() {
                         AtomicRMW(bcx, atom_op, llargs[0], llargs[1], order)
                     } else {
index 97c77ee3d8c7270ce17660896bd38c5f6b5303b2..483bc99c310fccb86f8983395e2298f3d3cc20ce 100644 (file)
@@ -265,7 +265,7 @@ pub fn get_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             // the method may have some early-bound lifetimes, add
             // regions for those
             let method_substs = Substs::for_item(tcx, trait_method_def_id,
-                                                 |_, _| ty::ReErased,
+                                                 |_, _| tcx.mk_region(ty::ReErased),
                                                  |_, _| tcx.types.err);
 
             // The substitutions we have are on the impl, so we grab
@@ -307,7 +307,7 @@ pub fn get_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                  name: Name)
                                  -> ImplMethod<'tcx>
 {
-    assert!(!substs.types.needs_infer());
+    assert!(!substs.needs_infer());
 
     let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap();
     let trait_def = tcx.lookup_trait_def(trait_def_id);
index e0d959f4774a64e3a2952f85bb6dcf081f931025..cfd1ec09968616d7f118382e19809ef09c9d4852 100644 (file)
@@ -15,6 +15,7 @@
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
 use rustc::mir::repr as mir;
 use rustc::mir::repr::TerminatorKind;
+use rustc::mir::repr::Location;
 use rustc::mir::visit::{Visitor, LvalueContext};
 use rustc::mir::traversal;
 use common::{self, Block, BlockAndBuilder};
@@ -48,6 +49,12 @@ pub fn lvalue_locals<'bcx, 'tcx>(bcx: Block<'bcx,'tcx>,
                     common::type_is_fat_ptr(bcx.tcx(), ty));
         } else if common::type_is_imm_pair(bcx.ccx(), ty) {
             // We allow pairs and uses of any of their 2 fields.
+        } else if !analyzer.seen_assigned.contains(index) {
+            // No assignment has been seen, which means that
+            // either the local has been marked as lvalue
+            // already, or there is no possible initialization
+            // for the local, making any reads invalid.
+            // This is useful in weeding out dead temps.
         } else {
             // These sorts of types require an alloca. Note that
             // type_is_immediate() may *still* be true, particularly
@@ -98,7 +105,8 @@ impl<'mir, 'bcx, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'bcx, 'tcx> {
     fn visit_assign(&mut self,
                     block: mir::BasicBlock,
                     lvalue: &mir::Lvalue<'tcx>,
-                    rvalue: &mir::Rvalue<'tcx>) {
+                    rvalue: &mir::Rvalue<'tcx>,
+                    location: Location) {
         debug!("visit_assign(block={:?}, lvalue={:?}, rvalue={:?})", block, lvalue, rvalue);
 
         if let Some(index) = self.mir.local_index(lvalue) {
@@ -107,15 +115,16 @@ fn visit_assign(&mut self,
                 self.mark_as_lvalue(index);
             }
         } else {
-            self.visit_lvalue(lvalue, LvalueContext::Store);
+            self.visit_lvalue(lvalue, LvalueContext::Store, location);
         }
 
-        self.visit_rvalue(rvalue);
+        self.visit_rvalue(rvalue, location);
     }
 
     fn visit_terminator_kind(&mut self,
                              block: mir::BasicBlock,
-                             kind: &mir::TerminatorKind<'tcx>) {
+                             kind: &mir::TerminatorKind<'tcx>,
+                             location: Location) {
         match *kind {
             mir::TerminatorKind::Call {
                 func: mir::Operand::Constant(mir::Constant {
@@ -127,18 +136,19 @@ fn visit_terminator_kind(&mut self,
                 // is not guaranteed to be statically dominated by the
                 // definition of x, so x must always be in an alloca.
                 if let mir::Operand::Consume(ref lvalue) = args[0] {
-                    self.visit_lvalue(lvalue, LvalueContext::Drop);
+                    self.visit_lvalue(lvalue, LvalueContext::Drop, location);
                 }
             }
             _ => {}
         }
 
-        self.super_terminator_kind(block, kind);
+        self.super_terminator_kind(block, kind, location);
     }
 
     fn visit_lvalue(&mut self,
                     lvalue: &mir::Lvalue<'tcx>,
-                    context: LvalueContext) {
+                    context: LvalueContext,
+                    location: Location) {
         debug!("visit_lvalue(lvalue={:?}, context={:?})", lvalue, context);
 
         // Allow uses of projections of immediate pair fields.
@@ -190,11 +200,11 @@ fn visit_lvalue(&mut self,
         // A deref projection only reads the pointer, never needs the lvalue.
         if let mir::Lvalue::Projection(ref proj) = *lvalue {
             if let mir::ProjectionElem::Deref = proj.elem {
-                return self.visit_lvalue(&proj.base, LvalueContext::Consume);
+                return self.visit_lvalue(&proj.base, LvalueContext::Consume, location);
             }
         }
 
-        self.super_lvalue(lvalue, context);
+        self.super_lvalue(lvalue, context, location);
     }
 }
 
index 474b2552e70796ce4ae6d89624ff1c87b9ac1d91..1934f7b870d187be0f06dbd18ca2b306a20c7570 100644 (file)
 
 use libc::c_uint;
 use llvm::{self, ValueRef};
-use llvm::debuginfo::DIScope;
 use rustc::ty;
 use rustc::mir::repr as mir;
 use rustc::mir::tcx::LvalueTy;
 use session::config::FullDebugInfo;
 use base;
 use common::{self, Block, BlockAndBuilder, CrateContext, FunctionContext, C_null};
-use debuginfo::{self, declare_local, DebugLoc, VariableAccess, VariableKind};
+use debuginfo::{self, declare_local, DebugLoc, VariableAccess, VariableKind, FunctionDebugContext};
 use machine;
 use type_of;
 
-use syntax_pos::DUMMY_SP;
+use syntax_pos::{DUMMY_SP, NO_EXPANSION, COMMAND_LINE_EXPN, BytePos};
 use syntax::parse::token::keywords;
 
 use std::ops::Deref;
@@ -103,12 +102,67 @@ pub struct MirContext<'bcx, 'tcx:'bcx> {
     locals: IndexVec<mir::Local, LocalRef<'tcx>>,
 
     /// Debug information for MIR scopes.
-    scopes: IndexVec<mir::VisibilityScope, DIScope>
+    scopes: IndexVec<mir::VisibilityScope, debuginfo::MirDebugScope>,
 }
 
 impl<'blk, 'tcx> MirContext<'blk, 'tcx> {
-    pub fn debug_loc(&self, source_info: mir::SourceInfo) -> DebugLoc {
-        DebugLoc::ScopeAt(self.scopes[source_info.scope], source_info.span)
+    pub fn debug_loc(&mut self, source_info: mir::SourceInfo) -> DebugLoc {
+        // Bail out if debug info emission is not enabled.
+        match self.fcx.debug_context {
+            FunctionDebugContext::DebugInfoDisabled |
+            FunctionDebugContext::FunctionWithoutDebugInfo => {
+                // Can't return DebugLoc::None here because intrinsic::trans_intrinsic_call()
+                // relies on debug location to obtain span of the call site.
+                return DebugLoc::ScopeAt(self.scopes[source_info.scope].scope_metadata,
+                                         source_info.span);
+            }
+            FunctionDebugContext::RegularContext(_) =>{}
+        }
+
+        // In order to have a good line stepping behavior in debugger, we overwrite debug
+        // locations of macro expansions with that of the outermost expansion site
+        // (unless the crate is being compiled with `-Z debug-macros`).
+        if source_info.span.expn_id == NO_EXPANSION ||
+            source_info.span.expn_id == COMMAND_LINE_EXPN ||
+            self.fcx.ccx.sess().opts.debugging_opts.debug_macros {
+
+            let scope_metadata = self.scope_metadata_for_loc(source_info.scope,
+                                                             source_info.span.lo);
+            DebugLoc::ScopeAt(scope_metadata, source_info.span)
+        } else {
+            let cm = self.fcx.ccx.sess().codemap();
+            // Walk up the macro expansion chain until we reach a non-expanded span.
+            let mut span = source_info.span;
+            while span.expn_id != NO_EXPANSION && span.expn_id != COMMAND_LINE_EXPN {
+                if let Some(callsite_span) = cm.with_expn_info(span.expn_id,
+                                                    |ei| ei.map(|ei| ei.call_site.clone())) {
+                    span = callsite_span;
+                } else {
+                    break;
+                }
+            }
+            let scope_metadata = self.scope_metadata_for_loc(source_info.scope, span.lo);
+            // Use span of the outermost call site, while keeping the original lexical scope
+            DebugLoc::ScopeAt(scope_metadata, span)
+        }
+    }
+
+    // DILocations inherit source file name from the parent DIScope.  Due to macro expansions
+    // it may so happen that the current span belongs to a different file than the DIScope
+    // corresponding to span's containing visibility scope.  If so, we need to create a DIScope
+    // "extension" into that file.
+    fn scope_metadata_for_loc(&self, scope_id: mir::VisibilityScope, pos: BytePos)
+                               -> llvm::debuginfo::DIScope {
+        let scope_metadata = self.scopes[scope_id].scope_metadata;
+        if pos < self.scopes[scope_id].file_start_pos ||
+           pos >= self.scopes[scope_id].file_end_pos {
+            let cm = self.fcx.ccx.sess().codemap();
+            debuginfo::extend_scope_to_file(self.fcx.ccx,
+                                            scope_metadata,
+                                            &cm.lookup_char_pos(pos).file)
+        } else {
+            scope_metadata
+        }
     }
 }
 
@@ -155,16 +209,38 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
          analyze::cleanup_kinds(bcx, &mir))
     });
 
+    // Allocate a `Block` for every basic block
+    let block_bcxs: IndexVec<mir::BasicBlock, Block<'blk,'tcx>> =
+        mir.basic_blocks().indices().map(|bb| {
+            if bb == mir::START_BLOCK {
+                fcx.new_block("start")
+            } else {
+                fcx.new_block(&format!("{:?}", bb))
+            }
+        }).collect();
+
     // Compute debuginfo scopes from MIR scopes.
     let scopes = debuginfo::create_mir_scopes(fcx);
 
+    let mut mircx = MirContext {
+        mir: mir.clone(),
+        fcx: fcx,
+        llpersonalityslot: None,
+        blocks: block_bcxs,
+        unreachable_block: None,
+        cleanup_kinds: cleanup_kinds,
+        landing_pads: IndexVec::from_elem(None, mir.basic_blocks()),
+        scopes: scopes,
+        locals: IndexVec::new(),
+    };
+
     // Allocate variable and temp allocas
-    let locals = {
-        let args = arg_local_refs(&bcx, &mir, &scopes, &lvalue_locals);
+    mircx.locals = {
+        let args = arg_local_refs(&bcx, &mir, &mircx.scopes, &lvalue_locals);
         let vars = mir.var_decls.iter().enumerate().map(|(i, decl)| {
             let ty = bcx.monomorphize(&decl.ty);
-            let scope = scopes[decl.source_info.scope];
-            let dbg = !scope.is_null() && bcx.sess().opts.debuginfo == FullDebugInfo;
+            let debug_scope = mircx.scopes[decl.source_info.scope];
+            let dbg = debug_scope.is_valid() && bcx.sess().opts.debuginfo == FullDebugInfo;
 
             let local = mir.local_index(&mir::Lvalue::Var(mir::Var::new(i))).unwrap();
             if !lvalue_locals.contains(local.index()) && !dbg {
@@ -173,11 +249,16 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
 
             let lvalue = LvalueRef::alloca(&bcx, ty, &decl.name.as_str());
             if dbg {
-                bcx.with_block(|bcx| {
-                    declare_local(bcx, decl.name, ty, scope,
-                                VariableAccess::DirectVariable { alloca: lvalue.llval },
-                                VariableKind::LocalVariable, decl.source_info.span);
-                });
+                let dbg_loc = mircx.debug_loc(decl.source_info);
+                if let DebugLoc::ScopeAt(scope, span) = dbg_loc {
+                    bcx.with_block(|bcx| {
+                        declare_local(bcx, decl.name, ty, scope,
+                                    VariableAccess::DirectVariable { alloca: lvalue.llval },
+                                    VariableKind::LocalVariable, span);
+                    });
+                } else {
+                    panic!("Unexpected");
+                }
             }
             LocalRef::Lvalue(lvalue)
         });
@@ -203,18 +284,8 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
         })).collect()
     };
 
-    // Allocate a `Block` for every basic block
-    let block_bcxs: IndexVec<mir::BasicBlock, Block<'blk,'tcx>> =
-        mir.basic_blocks().indices().map(|bb| {
-            if bb == mir::START_BLOCK {
-                fcx.new_block("start")
-            } else {
-                fcx.new_block(&format!("{:?}", bb))
-            }
-        }).collect();
-
     // Branch to the START block
-    let start_bcx = block_bcxs[mir::START_BLOCK];
+    let start_bcx = mircx.blocks[mir::START_BLOCK];
     bcx.br(start_bcx.llbb);
 
     // Up until here, IR instructions for this function have explicitly not been annotated with
@@ -222,18 +293,6 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
     // emitting should be enabled.
     debuginfo::start_emitting_source_locations(fcx);
 
-    let mut mircx = MirContext {
-        mir: mir.clone(),
-        fcx: fcx,
-        llpersonalityslot: None,
-        blocks: block_bcxs,
-        unreachable_block: None,
-        cleanup_kinds: cleanup_kinds,
-        landing_pads: IndexVec::from_elem(None, mir.basic_blocks()),
-        locals: locals,
-        scopes: scopes
-    };
-
     let mut visited = BitVector::new(mir.basic_blocks().len());
 
     let mut rpo = traversal::reverse_postorder(&mir);
@@ -271,7 +330,7 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
 /// indirect.
 fn arg_local_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
                               mir: &mir::Mir<'tcx>,
-                              scopes: &IndexVec<mir::VisibilityScope, DIScope>,
+                              scopes: &IndexVec<mir::VisibilityScope, debuginfo::MirDebugScope>,
                               lvalue_locals: &BitVector)
                               -> Vec<LocalRef<'tcx>> {
     let fcx = bcx.fcx();
@@ -281,8 +340,8 @@ fn arg_local_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
 
     // Get the argument scope, if it exists and if we need it.
     let arg_scope = scopes[mir::ARGUMENT_VISIBILITY_SCOPE];
-    let arg_scope = if !arg_scope.is_null() && bcx.sess().opts.debuginfo == FullDebugInfo {
-        Some(arg_scope)
+    let arg_scope = if arg_scope.is_valid() && bcx.sess().opts.debuginfo == FullDebugInfo {
+        Some(arg_scope.scope_metadata)
     } else {
         None
     };
index 020ac8d643b86df29e82959ef6a4e4062158a36f..0ffb83067f91c57389070d4097a190ac12307f10 100644 (file)
@@ -32,7 +32,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 impl<'tcx> Instance<'tcx> {
     pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>)
                -> Instance<'tcx> {
-        assert!(substs.regions.iter().all(|&r| r == ty::ReErased));
+        assert!(substs.regions().all(|&r| r == ty::ReErased));
         Instance { def: def_id, substs: substs }
     }
     pub fn mono<'a>(scx: &SharedCrateContext<'a, 'tcx>, def_id: DefId) -> Instance<'tcx> {
index 87d0ea0fe81f30d83b20ac75099a7c0ca098d1d9..7341e8db41de5bf4e83b3c1ea29924a94836cd8a 100644 (file)
@@ -342,7 +342,7 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                         TransItem::DropGlue(..) => unreachable!(),
                         // Is there any benefit to using ExternalLinkage?:
                         TransItem::Fn(ref instance) => {
-                            if instance.substs.types.is_empty() {
+                            if instance.substs.types().next().is_none() {
                                 // This is a non-generic functions, we always
                                 // make it visible externally on the chance that
                                 // it might be used in another codegen unit.
@@ -487,7 +487,7 @@ fn characteristic_def_id_of_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             // DefId, we use the location of the impl after all.
 
             if tcx.trait_of_item(instance.def).is_some() {
-                let self_ty = instance.substs.types[0];
+                let self_ty = instance.substs.type_at(0);
                 // This is an implementation of a trait method.
                 return characteristic_def_id_of_type(self_ty).or(Some(instance.def));
             }
index 90dcc3a61fd7ebda35f10c6bff6c5d29032612a7..2c91c408487b8513319d06b163be261fcfda2887 100644 (file)
@@ -171,8 +171,8 @@ fn predefine_fn(ccx: &CrateContext<'a, 'tcx>,
                     instance: Instance<'tcx>,
                     linkage: llvm::Linkage,
                     symbol_name: &str) {
-        assert!(!instance.substs.types.needs_infer() &&
-                !instance.substs.types.has_param_types());
+        assert!(!instance.substs.needs_infer() &&
+                !instance.substs.has_param_types());
 
         let item_ty = ccx.tcx().lookup_item_type(instance.def).ty;
         let item_ty = ccx.tcx().erase_regions(&item_ty);
@@ -244,7 +244,7 @@ pub fn compute_symbol_name(&self,
     pub fn requests_inline(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool {
         match *self {
             TransItem::Fn(ref instance) => {
-                !instance.substs.types.is_empty() || {
+                instance.substs.types().next().is_some() || {
                     let attributes = tcx.get_attrs(instance.def);
                     attr::requests_inline(&attributes[..])
                 }
@@ -264,8 +264,9 @@ pub fn is_from_extern_crate(&self) -> bool {
 
     pub fn is_instantiated_only_on_demand(&self) -> bool {
         match *self {
-            TransItem::Fn(ref instance) => !instance.def.is_local() ||
-                                           !instance.substs.types.is_empty(),
+            TransItem::Fn(ref instance) => {
+                !instance.def.is_local() || instance.substs.types().next().is_some()
+            }
             TransItem::DropGlue(..) => true,
             TransItem::Static(..)   => false,
         }
@@ -273,7 +274,9 @@ pub fn is_instantiated_only_on_demand(&self) -> bool {
 
     pub fn is_generic_fn(&self) -> bool {
         match *self {
-            TransItem::Fn(ref instance) => !instance.substs.types.is_empty(),
+            TransItem::Fn(ref instance) => {
+                instance.substs.types().next().is_some()
+            }
             TransItem::DropGlue(..) |
             TransItem::Static(..)   => false,
         }
@@ -374,7 +377,7 @@ pub fn to_raw_string(&self) -> String {
 /// Same as `unique_type_name()` but with the result pushed onto the given
 /// `output` parameter.
 pub fn push_unique_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                       t: ty::Ty<'tcx>,
+                                       t: Ty<'tcx>,
                                        output: &mut String) {
     match t.sty {
         ty::TyBool              => output.push_str("bool"),
@@ -396,7 +399,7 @@ pub fn push_unique_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         ty::TyStruct(adt_def, substs) |
         ty::TyEnum(adt_def, substs) => {
             push_item_name(tcx, adt_def.did, output);
-            push_type_params(tcx, &substs.types, &[], output);
+            push_type_params(tcx, substs, &[], output);
         },
         ty::TyTuple(component_types) => {
             output.push('(');
@@ -446,7 +449,7 @@ pub fn push_unique_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         ty::TyTrait(ref trait_data) => {
             push_item_name(tcx, trait_data.principal.def_id(), output);
             push_type_params(tcx,
-                             &trait_data.principal.skip_binder().substs.types,
+                             trait_data.principal.skip_binder().substs,
                              &trait_data.projection_bounds,
                              output);
         },
@@ -494,7 +497,7 @@ pub fn push_unique_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             output.push_str("{");
             output.push_str(&format!("{}:{}", def_id.krate, def_id.index.as_usize()));
             output.push_str("}");
-            push_type_params(tcx, &closure_substs.func_substs.types, &[], output);
+            push_type_params(tcx, closure_substs.func_substs, &[], output);
         }
         ty::TyError |
         ty::TyInfer(_) |
@@ -529,16 +532,16 @@ fn push_item_name(tcx: TyCtxt,
 }
 
 fn push_type_params<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                              types: &[Ty<'tcx>],
+                              substs: &Substs<'tcx>,
                               projections: &[ty::PolyExistentialProjection<'tcx>],
                               output: &mut String) {
-    if types.is_empty() && projections.is_empty() {
+    if substs.types().next().is_none() && projections.is_empty() {
         return;
     }
 
     output.push('<');
 
-    for &type_parameter in types {
+    for type_parameter in substs.types() {
         push_unique_type_name(tcx, type_parameter, output);
         output.push_str(", ");
     }
@@ -562,7 +565,7 @@ fn push_instance_as_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                      instance: Instance<'tcx>,
                                      output: &mut String) {
     push_item_name(tcx, instance.def, output);
-    push_type_params(tcx, &instance.substs.types, &[], output);
+    push_type_params(tcx, instance.substs, &[], output);
 }
 
 pub fn def_id_to_string(tcx: TyCtxt, def_id: DefId) -> String {
@@ -572,7 +575,7 @@ pub fn def_id_to_string(tcx: TyCtxt, def_id: DefId) -> String {
 }
 
 pub fn type_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                ty: ty::Ty<'tcx>)
+                                ty: Ty<'tcx>)
                                 -> String {
     let mut output = String::new();
     push_unique_type_name(tcx, ty, &mut output);
index 6862002ed83b25a448e2319656cb7610d506b6be..b47d2cd0f204b8d37ad9327f6bd18916b5b8d140 100644 (file)
@@ -17,6 +17,7 @@
 use machine;
 use rustc::traits::Reveal;
 use rustc::ty::{self, Ty, TypeFoldable};
+use rustc::ty::subst::Substs;
 
 use type_::Type;
 
@@ -256,7 +257,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
           // avoids creating more than one copy of the enum when one
           // of the enum's variants refers to the enum itself.
           let repr = adt::represent_type(cx, t);
-          let name = llvm_type_name(cx, def.did, &substs.types);
+          let name = llvm_type_name(cx, def.did, substs);
           adt::incomplete_type_of(cx, &repr, &name[..])
       }
       ty::TyClosure(..) => {
@@ -330,7 +331,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
               // in *after* placing it into the type cache. This prevents
               // infinite recursion with recursive struct types.
               let repr = adt::represent_type(cx, t);
-              let name = llvm_type_name(cx, def.did, &substs.types);
+              let name = llvm_type_name(cx, def.did, substs);
               adt::incomplete_type_of(cx, &repr, &name[..])
           }
       }
@@ -367,10 +368,10 @@ pub fn align_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>)
 
 fn llvm_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                             did: DefId,
-                            tps: &[Ty<'tcx>])
+                            substs: &Substs<'tcx>)
                             -> String {
     let base = cx.tcx().item_path_str(did);
-    let strings: Vec<String> = tps.iter().map(|t| t.to_string()).collect();
+    let strings: Vec<String> = substs.types().map(|t| t.to_string()).collect();
     let tstr = if strings.is_empty() {
         base
     } else {
index f6984f42cab341301d52864b2b6e691d1e5217ac..f24a7cf2121ebe7ab67c22e508b9ec3885d8a014 100644 (file)
@@ -178,8 +178,9 @@ struct ConvertedBinding<'tcx> {
 /// This type must not appear anywhere in other converted types.
 const TRAIT_OBJECT_DUMMY_SELF: ty::TypeVariants<'static> = ty::TyInfer(ty::FreshTy(0));
 
-pub fn ast_region_to_region(tcx: TyCtxt, lifetime: &hir::Lifetime)
-                            -> ty::Region {
+pub fn ast_region_to_region<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
+                                            lifetime: &hir::Lifetime)
+                                            -> &'tcx ty::Region {
     let r = match tcx.named_region_map.defs.get(&lifetime.id) {
         None => {
             // should have been recorded by the `resolve_lifetime` pass
@@ -238,7 +239,7 @@ pub fn ast_region_to_region(tcx: TyCtxt, lifetime: &hir::Lifetime)
            lifetime.id,
            r);
 
-    r
+    tcx.mk_region(r)
 }
 
 fn report_elision_failure(
@@ -313,14 +314,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
     pub fn opt_ast_region_to_region(&self,
         rscope: &RegionScope,
         default_span: Span,
-        opt_lifetime: &Option<hir::Lifetime>) -> ty::Region
+        opt_lifetime: &Option<hir::Lifetime>) -> &'tcx ty::Region
     {
         let r = match *opt_lifetime {
             Some(ref lifetime) => {
                 ast_region_to_region(self.tcx(), lifetime)
             }
 
-            None => match rscope.anon_regions(default_span, 1) {
+            None => self.tcx().mk_region(match rscope.anon_regions(default_span, 1) {
                 Ok(rs) => rs[0],
                 Err(params) => {
                     let ampersand_span = Span { hi: default_span.lo, ..default_span};
@@ -335,7 +336,7 @@ pub fn opt_ast_region_to_region(&self,
                     err.emit();
                     ty::ReStatic
                 }
-            }
+            })
         };
 
         debug!("opt_ast_region_to_region(opt_lifetime={:?}) yields {:?}",
@@ -366,7 +367,7 @@ pub fn ast_path_substs_for_ty(&self,
                     .emit();
 
                 return Substs::for_item(tcx, def_id, |_, _| {
-                    ty::ReStatic
+                    tcx.mk_region(ty::ReStatic)
                 }, |_, _| {
                     tcx.types.err
                 });
@@ -431,7 +432,7 @@ fn create_substs_for_ast_path(&self,
         let expected_num_region_params = decl_generics.regions.len();
         let supplied_num_region_params = lifetimes.len();
         let regions = if expected_num_region_params == supplied_num_region_params {
-            lifetimes.iter().map(|l| ast_region_to_region(tcx, l)).collect()
+            lifetimes.iter().map(|l| *ast_region_to_region(tcx, l)).collect()
         } else {
             let anon_regions =
                 rscope.anon_regions(span, expected_num_region_params);
@@ -472,7 +473,8 @@ fn create_substs_for_ast_path(&self,
 
         let mut output_assoc_binding = None;
         let substs = Substs::for_item(tcx, def_id, |def, _| {
-            regions[def.index as usize]
+            let i = def.index as usize - self_ty.is_some() as usize;
+            tcx.mk_region(regions[i])
         }, |def, substs| {
             let i = def.index as usize;
 
@@ -481,7 +483,7 @@ fn create_substs_for_ast_path(&self,
                 return ty;
             }
 
-            let i = i - self_ty.is_some() as usize;
+            let i = i - self_ty.is_some() as usize - decl_generics.regions.len();
             if num_types_provided.map_or(false, |n| i < n) {
                 // A provided type parameter.
                 match *parameters {
@@ -588,7 +590,7 @@ fn find_implied_output_region(&self,
         }
 
         if lifetimes_for_params.iter().map(|e| e.lifetime_count).sum::<usize>() == 1 {
-            Ok(possible_implied_output_region.unwrap())
+            Ok(*possible_implied_output_region.unwrap())
         } else {
             Err(Some(lifetimes_for_params))
         }
@@ -937,8 +939,8 @@ fn ast_path_to_ty(&self,
 
         // FIXME(#12938): This is a hack until we have full support for DST.
         if Some(did) == self.tcx().lang_items.owned_box() {
-            assert_eq!(substs.types.len(), 1);
-            return self.tcx().mk_box(substs.types[0]);
+            assert_eq!(substs.types().count(), 1);
+            return self.tcx().mk_box(substs.type_at(0));
         }
 
         decl_ty.subst(self.tcx(), substs)
@@ -1100,7 +1102,7 @@ fn trait_path_to_object_type(&self,
         let region_bound = match region_bound {
             Some(r) => r,
             None => {
-                match rscope.object_lifetime_default(span) {
+                tcx.mk_region(match rscope.object_lifetime_default(span) {
                     Some(r) => r,
                     None => {
                         span_err!(self.tcx().sess, span, E0228,
@@ -1108,7 +1110,7 @@ fn trait_path_to_object_type(&self,
                                    from context; please supply an explicit bound");
                         ty::ReStatic
                     }
-                }
+                })
             }
         };
 
@@ -1643,7 +1645,7 @@ pub fn ast_ty_to_ty(&self, rscope: &RegionScope, ast_ty: &hir::Ty) -> Ty<'tcx> {
                         rscope,
                         ty::ObjectLifetimeDefault::Specific(r));
                 let t = self.ast_ty_to_ty(rscope1, &mt.ty);
-                tcx.mk_ref(tcx.mk_region(r), ty::TypeAndMut {ty: t, mutbl: mt.mutbl})
+                tcx.mk_ref(r, ty::TypeAndMut {ty: t, mutbl: mt.mutbl})
             }
             hir::TyNever => {
                 tcx.types.never
@@ -1801,7 +1803,7 @@ pub fn ty_of_method(&self,
                         sig: &hir::MethodSig,
                         untransformed_self_ty: Ty<'tcx>,
                         anon_scope: Option<AnonTypeScope>)
-                        -> (&'tcx ty::BareFnTy<'tcx>, ty::ExplicitSelfCategory) {
+                        -> (&'tcx ty::BareFnTy<'tcx>, ty::ExplicitSelfCategory<'tcx>) {
         self.ty_of_method_or_bare_fn(sig.unsafety,
                                      sig.abi,
                                      Some(untransformed_self_ty),
@@ -1826,7 +1828,7 @@ fn ty_of_method_or_bare_fn(&self,
                                decl: &hir::FnDecl,
                                arg_anon_scope: Option<AnonTypeScope>,
                                ret_anon_scope: Option<AnonTypeScope>)
-                               -> (&'tcx ty::BareFnTy<'tcx>, ty::ExplicitSelfCategory)
+                               -> (&'tcx ty::BareFnTy<'tcx>, ty::ExplicitSelfCategory<'tcx>)
     {
         debug!("ty_of_method_or_bare_fn");
 
@@ -1863,7 +1865,7 @@ fn ty_of_method_or_bare_fn(&self,
         // reference) in the arguments, then any anonymous regions in the output
         // have that lifetime.
         let implied_output_region = match explicit_self_category {
-            ty::ExplicitSelfCategory::ByReference(region, _) => Ok(region),
+            ty::ExplicitSelfCategory::ByReference(region, _) => Ok(*region),
             _ => self.find_implied_output_region(&arg_tys, arg_pats)
         };
 
@@ -1890,7 +1892,7 @@ fn determine_self_type<'a>(&self,
                                rscope: &RegionScope,
                                untransformed_self_ty: Ty<'tcx>,
                                explicit_self: &hir::ExplicitSelf)
-                               -> (Ty<'tcx>, ty::ExplicitSelfCategory)
+                               -> (Ty<'tcx>, ty::ExplicitSelfCategory<'tcx>)
     {
         return match explicit_self.node {
             SelfKind::Value(..) => {
@@ -1902,8 +1904,7 @@ fn determine_self_type<'a>(&self,
                                              rscope,
                                              explicit_self.span,
                                              lifetime);
-                (self.tcx().mk_ref(
-                    self.tcx().mk_region(region),
+                (self.tcx().mk_ref(region,
                     ty::TypeAndMut {
                         ty: untransformed_self_ty,
                         mutbl: mutability
@@ -1957,7 +1958,7 @@ fn determine_self_type<'a>(&self,
                     ty::ExplicitSelfCategory::ByValue
                 } else {
                     match explicit_type.sty {
-                        ty::TyRef(r, mt) => ty::ExplicitSelfCategory::ByReference(*r, mt.mutbl),
+                        ty::TyRef(r, mt) => ty::ExplicitSelfCategory::ByReference(r, mt.mutbl),
                         ty::TyBox(_) => ty::ExplicitSelfCategory::ByBox,
                         _ => ty::ExplicitSelfCategory::ByValue,
                     }
@@ -2070,7 +2071,7 @@ fn compute_object_lifetime_bound(&self,
         explicit_region_bounds: &[&hir::Lifetime],
         principal_trait_ref: ty::PolyExistentialTraitRef<'tcx>,
         builtin_bounds: ty::BuiltinBounds)
-        -> Option<ty::Region> // if None, use the default
+        -> Option<&'tcx ty::Region> // if None, use the default
     {
         let tcx = self.tcx();
 
@@ -2093,7 +2094,7 @@ fn compute_object_lifetime_bound(&self,
 
         if let Err(ErrorReported) =
                 self.ensure_super_predicates(span, principal_trait_ref.def_id()) {
-            return Some(ty::ReStatic);
+            return Some(tcx.mk_region(ty::ReStatic));
         }
 
         // No explicit region bound specified. Therefore, examine trait
@@ -2109,8 +2110,8 @@ fn compute_object_lifetime_bound(&self,
 
         // If any of the derived region bounds are 'static, that is always
         // the best choice.
-        if derived_region_bounds.iter().any(|r| ty::ReStatic == *r) {
-            return Some(ty::ReStatic);
+        if derived_region_bounds.iter().any(|&r| ty::ReStatic == *r) {
+            return Some(tcx.mk_region(ty::ReStatic));
         }
 
         // Determine whether there is exactly one unique region in the set
@@ -2242,7 +2243,7 @@ fn report_lifetime_number_error(tcx: TyCtxt, span: Span, number: usize, expected
 // and return from functions in multiple places.
 #[derive(PartialEq, Eq, Clone, Debug)]
 pub struct Bounds<'tcx> {
-    pub region_bounds: Vec<ty::Region>,
+    pub region_bounds: Vec<&'tcx ty::Region>,
     pub builtin_bounds: ty::BuiltinBounds,
     pub trait_bounds: Vec<ty::PolyTraitRef<'tcx>>,
     pub projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
@@ -2264,7 +2265,7 @@ pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, param_ty: Ty<'tcx>)
         for &region_bound in &self.region_bounds {
             // account for the binder being introduced below; no need to shift `param_ty`
             // because, at present at least, it can only refer to early-bound regions
-            let region_bound = ty::fold::shift_region(region_bound, 1);
+            let region_bound = tcx.mk_region(ty::fold::shift_region(*region_bound, 1));
             vec.push(ty::Binder(ty::OutlivesPredicate(param_ty, region_bound)).to_predicate());
         }
 
index 52073359c0fd99ea331c08566d1a281303151598..78175c85b19bf3c6533c40039b5ca43b5b46f8e2 100644 (file)
@@ -122,7 +122,7 @@ pub fn check_pat(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>) {
                         // and T is the expected type.
                         let region_var = self.next_region_var(infer::PatternRegion(pat.span));
                         let mt = ty::TypeAndMut { ty: expected, mutbl: mutbl };
-                        let region_ty = tcx.mk_ref(tcx.mk_region(region_var), mt);
+                        let region_ty = tcx.mk_ref(region_var, mt);
 
                         // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)` is
                         // required. However, we use equality, which is stronger. See (*) for
@@ -220,7 +220,7 @@ pub fn check_pat(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>) {
                             let inner_ty = self.next_ty_var();
                             let mt = ty::TypeAndMut { ty: inner_ty, mutbl: mutbl };
                             let region = self.next_region_var(infer::PatternRegion(pat.span));
-                            let rptr_ty = tcx.mk_ref(tcx.mk_region(region), mt);
+                            let rptr_ty = tcx.mk_ref(region, mt);
                             self.demand_eqtype(pat.span, expected, rptr_ty);
                             (rptr_ty, inner_ty)
                         }
index 9a3cbabe553314fd77bf3719a3686c8aba61bc62..19261a2447f9100ed8b7dee42319073e7ad4fdc0 100644 (file)
@@ -101,7 +101,7 @@ fn overloaded_deref_ty(&mut self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
                 Some(f) => f,
                 None => return None
             },
-            substs: Substs::new_trait(tcx, vec![], vec![], self.cur_ty)
+            substs: Substs::new_trait(tcx, self.cur_ty, &[])
         };
 
         let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id);
index 377ca5eaebe302745e97093c011a20cb5ae1571f..46e8c27f6d33bbb38e77cc13d249af197c11c99e 100644 (file)
@@ -203,7 +203,7 @@ fn deduce_sig_from_projection(&self,
             return None;
         }
 
-        let arg_param_ty = trait_ref.substs().types[1];
+        let arg_param_ty = trait_ref.substs().type_at(1);
         let arg_param_ty = self.resolve_type_vars_if_possible(&arg_param_ty);
         debug!("deduce_sig_from_projection: arg_param_ty {:?}", arg_param_ty);
 
index 4a0d529812891f48049e128824b5cec7cf8b1ece..26a47055289761b72500e2f96258e74d5f1445c8 100644 (file)
@@ -336,7 +336,7 @@ fn coerce_borrowed_pointer<'a, E, I>(&self,
                 if r_borrow_var.is_none() { // create var lazilly, at most once
                     let coercion = Coercion(span);
                     let r = self.next_region_var(coercion);
-                    r_borrow_var = Some(self.tcx.mk_region(r)); // [4] above
+                    r_borrow_var = Some(r); // [4] above
                 }
                 r_borrow_var.unwrap()
             };
@@ -436,8 +436,7 @@ fn coerce_unsized(&self,
 
                 let coercion = Coercion(self.origin.span());
                 let r_borrow = self.next_region_var(coercion);
-                let region = self.tcx.mk_region(r_borrow);
-                (mt_a.ty, Some(AutoPtr(region, mt_b.mutbl)))
+                (mt_a.ty, Some(AutoPtr(r_borrow, mt_b.mutbl)))
             }
             (&ty::TyRef(_, mt_a), &ty::TyRawPtr(mt_b)) => {
                 coerce_mutbls(mt_a.mutbl, mt_b.mutbl)?;
@@ -459,7 +458,7 @@ fn coerce_unsized(&self,
                                                          coerce_unsized_did,
                                                          0,
                                                          source,
-                                                         vec![target]));
+                                                         &[target]));
 
         // Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid
         // emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where
index 78476e814006fc6ecbfead875a005785997462b1..1604f34d575528209544e2eb2a52aa2890e67d01 100644 (file)
@@ -299,11 +299,10 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                                  impl_m_span,
                                                  impl_m_body_id,
                                                  &impl_sig);
-        let impl_args = impl_sig.inputs.clone();
         let impl_fty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy {
             unsafety: impl_m.fty.unsafety,
             abi: impl_m.fty.abi,
-            sig: ty::Binder(impl_sig)
+            sig: ty::Binder(impl_sig.clone())
         }));
         debug!("compare_impl_method: impl_fty={:?}", impl_fty);
 
@@ -318,11 +317,10 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                                  impl_m_span,
                                                  impl_m_body_id,
                                                  &trait_sig);
-        let trait_args = trait_sig.inputs.clone();
         let trait_fty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy {
             unsafety: trait_m.fty.unsafety,
             abi: trait_m.fty.abi,
-            sig: ty::Binder(trait_sig)
+            sig: ty::Binder(trait_sig.clone())
         }));
 
         debug!("compare_impl_method: trait_fty={:?}", trait_fty);
@@ -332,65 +330,9 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                    impl_fty,
                    trait_fty);
 
-            let impl_m_iter = match tcx.map.expect_impl_item(impl_m_node_id).node {
-                ImplItemKind::Method(ref impl_m_sig, _) => impl_m_sig.decl.inputs.iter(),
-                _ => bug!("{:?} is not a method", impl_m)
-            };
-
-            let (impl_err_span, trait_err_span) = match terr {
-                TypeError::Mutability => {
-                    if let Some(trait_m_node_id) = tcx.map.as_local_node_id(trait_m.def_id) {
-                        let trait_m_iter = match tcx.map.expect_trait_item(trait_m_node_id).node {
-                            TraitItem_::MethodTraitItem(ref trait_m_sig, _) =>
-                                trait_m_sig.decl.inputs.iter(),
-                            _ => bug!("{:?} is not a MethodTraitItem", trait_m)
-                        };
-
-                        impl_m_iter.zip(trait_m_iter).find(|&(ref impl_arg, ref trait_arg)| {
-                            match (&impl_arg.ty.node, &trait_arg.ty.node) {
-                                (&Ty_::TyRptr(_, ref impl_mt), &Ty_::TyRptr(_, ref trait_mt)) |
-                                (&Ty_::TyPtr(ref impl_mt), &Ty_::TyPtr(ref trait_mt)) =>
-                                    impl_mt.mutbl != trait_mt.mutbl,
-                                _ => false
-                            }
-                        }).map(|(ref impl_arg, ref trait_arg)| {
-                            match (impl_arg.to_self(), trait_arg.to_self()) {
-                                (Some(impl_self), Some(trait_self)) =>
-                                    (impl_self.span, Some(trait_self.span)),
-                                (None, None) => (impl_arg.ty.span, Some(trait_arg.ty.span)),
-                                _ => bug!("impl and trait fns have different first args, \
-                                           impl: {:?}, trait: {:?}", impl_arg, trait_arg)
-                            }
-                        }).unwrap_or((origin.span(), tcx.map.span_if_local(trait_m.def_id)))
-                    } else {
-                        (origin.span(), tcx.map.span_if_local(trait_m.def_id))
-                    }
-                }
-                TypeError::Sorts(ExpectedFound { expected, found }) => {
-                    if let Some(trait_m_node_id) = tcx.map.as_local_node_id(trait_m.def_id) {
-                        let trait_m_iter = match tcx.map.expect_trait_item(trait_m_node_id).node {
-                            TraitItem_::MethodTraitItem(ref trait_m_sig, _) =>
-                                trait_m_sig.decl.inputs.iter(),
-                            _ => bug!("{:?} is not a MethodTraitItem", trait_m)
-                        };
-                        let impl_iter = impl_args.iter();
-                        let trait_iter = trait_args.iter();
-                        let arg_idx = impl_iter.zip(trait_iter)
-                                               .position(|(impl_arg_ty, trait_arg_ty)| {
-                                                *impl_arg_ty == found && *trait_arg_ty == expected
-                                               }).unwrap();
-                        impl_m_iter.zip(trait_m_iter)
-                                   .nth(arg_idx)
-                                   .map(|(impl_arg, trait_arg)|
-                                        (impl_arg.ty.span, Some(trait_arg.ty.span)))
-                                   .unwrap_or(
-                                    (origin.span(), tcx.map.span_if_local(trait_m.def_id)))
-                    } else {
-                        (origin.span(), tcx.map.span_if_local(trait_m.def_id))
-                    }
-                }
-                _ => (origin.span(), tcx.map.span_if_local(trait_m.def_id))
-            };
+            let (impl_err_span, trait_err_span) =
+                extract_spans_for_error_reporting(&infcx, &terr, origin, impl_m,
+                    impl_sig, trait_m, trait_sig);
 
             let origin = TypeOrigin::MethodCompatCheck(impl_err_span);
 
@@ -479,6 +421,86 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
 
         return true;
     }
+
+    fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
+                                                         terr: &TypeError,
+                                                         origin: TypeOrigin,
+                                                         impl_m: &ty::Method,
+                                                         impl_sig: ty::FnSig<'tcx>,
+                                                         trait_m: &ty::Method,
+                                                         trait_sig: ty::FnSig<'tcx>)
+                                                        -> (Span, Option<Span>) {
+        let tcx = infcx.tcx;
+        let impl_m_node_id = tcx.map.as_local_node_id(impl_m.def_id).unwrap();
+        let (impl_m_output, impl_m_iter) = match tcx.map.expect_impl_item(impl_m_node_id).node {
+            ImplItemKind::Method(ref impl_m_sig, _) =>
+                (&impl_m_sig.decl.output, impl_m_sig.decl.inputs.iter()),
+            _ => bug!("{:?} is not a method", impl_m)
+        };
+
+        match *terr {
+            TypeError::Mutability => {
+                if let Some(trait_m_node_id) = tcx.map.as_local_node_id(trait_m.def_id) {
+                    let trait_m_iter = match tcx.map.expect_trait_item(trait_m_node_id).node {
+                        TraitItem_::MethodTraitItem(ref trait_m_sig, _) =>
+                            trait_m_sig.decl.inputs.iter(),
+                        _ => bug!("{:?} is not a MethodTraitItem", trait_m)
+                    };
+
+                    impl_m_iter.zip(trait_m_iter).find(|&(ref impl_arg, ref trait_arg)| {
+                        match (&impl_arg.ty.node, &trait_arg.ty.node) {
+                            (&Ty_::TyRptr(_, ref impl_mt), &Ty_::TyRptr(_, ref trait_mt)) |
+                            (&Ty_::TyPtr(ref impl_mt), &Ty_::TyPtr(ref trait_mt)) =>
+                                impl_mt.mutbl != trait_mt.mutbl,
+                            _ => false
+                        }
+                    }).map(|(ref impl_arg, ref trait_arg)| {
+                        match (impl_arg.to_self(), trait_arg.to_self()) {
+                            (Some(impl_self), Some(trait_self)) =>
+                                (impl_self.span, Some(trait_self.span)),
+                            (None, None) => (impl_arg.ty.span, Some(trait_arg.ty.span)),
+                            _ => bug!("impl and trait fns have different first args, \
+                                       impl: {:?}, trait: {:?}", impl_arg, trait_arg)
+                        }
+                    }).unwrap_or((origin.span(), tcx.map.span_if_local(trait_m.def_id)))
+                } else {
+                    (origin.span(), tcx.map.span_if_local(trait_m.def_id))
+                }
+            }
+            TypeError::Sorts(ExpectedFound { .. }) => {
+                if let Some(trait_m_node_id) = tcx.map.as_local_node_id(trait_m.def_id) {
+                    let (trait_m_output, trait_m_iter) =
+                    match tcx.map.expect_trait_item(trait_m_node_id).node {
+                        TraitItem_::MethodTraitItem(ref trait_m_sig, _) =>
+                            (&trait_m_sig.decl.output, trait_m_sig.decl.inputs.iter()),
+                        _ => bug!("{:?} is not a MethodTraitItem", trait_m)
+                    };
+
+                    let impl_iter = impl_sig.inputs.iter();
+                    let trait_iter = trait_sig.inputs.iter();
+                    impl_iter.zip(trait_iter).zip(impl_m_iter).zip(trait_m_iter)
+                        .filter_map(|(((impl_arg_ty, trait_arg_ty), impl_arg), trait_arg)| {
+                            match infcx.sub_types(true, origin, trait_arg_ty, impl_arg_ty) {
+                                Ok(_) => None,
+                                Err(_) => Some((impl_arg.ty.span, Some(trait_arg.ty.span)))
+                            }
+                        })
+                        .next()
+                        .unwrap_or_else(|| {
+                            if infcx.sub_types(false, origin, impl_sig.output,
+                                               trait_sig.output).is_err() {
+                                (impl_m_output.span(), Some(trait_m_output.span()))
+                            } else {
+                                (origin.span(), tcx.map.span_if_local(trait_m.def_id))
+                            }
+                        })
+                } else {
+                    (origin.span(), tcx.map.span_if_local(trait_m.def_id))
+                }
+            }
+            _ => (origin.span(), tcx.map.span_if_local(trait_m.def_id))
+        }
+    }
 }
 
 pub fn compare_const_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
index 82545d564a20c807f69fd91e3e7b82d4f877cf2b..cede9d871ff4d6a77b3f9fccc40457c6e57504c8 100644 (file)
@@ -412,7 +412,7 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'gcx, 'tcx>(
                ty);
 
         cx.rcx.type_must_outlive(infer::SubregionOrigin::SafeDestructor(cx.span),
-                                 ty, ty::ReScope(cx.parent_scope));
+                                 ty, tcx.mk_region(ty::ReScope(cx.parent_scope)));
 
         return Ok(());
     }
@@ -438,7 +438,7 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'gcx, 'tcx>(
 
         ty::TyStruct(def, substs) if def.is_phantom_data() => {
             // PhantomData<T> - behaves identically to T
-            let ity = substs.types[0];
+            let ity = substs.type_at(0);
             iterate_over_potentially_unsafe_regions_in_type(
                 cx, context, ity, depth+1)
         }
index 7f9e715b7fafc634798dc1090f7b238ef6c9e99c..ed3e645eeebebe59af0cb3a90c530038f5aa2a4a 100644 (file)
@@ -37,7 +37,7 @@ fn equate_intrinsic_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     let i_ty = tcx.lookup_item_type(def_id);
 
     let substs = Substs::for_item(tcx, def_id,
-                                  |_, _| ty::ReErased,
+                                  |_, _| tcx.mk_region(ty::ReErased),
                                   |def, _| tcx.mk_param_from_def(def));
 
     let fty = tcx.mk_fn_def(def_id, substs, tcx.mk_bare_fn(ty::BareFnTy {
@@ -51,12 +51,17 @@ fn equate_intrinsic_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     }));
     let i_n_tps = i_ty.generics.types.len();
     if i_n_tps != n_tps {
-        struct_span_err!(tcx.sess, it.span, E0094,
-            "intrinsic has wrong number of type \
-             parameters: found {}, expected {}",
-             i_n_tps, n_tps)
-             .span_label(it.span, &format!("expected {} type parameter", n_tps))
-             .emit();
+        let span = match it.node {
+            hir::ForeignItemFn(_, ref generics) => generics.span().unwrap_or(it.span),
+            hir::ForeignItemStatic(_, _) => it.span
+        };
+
+        struct_span_err!(tcx.sess, span, E0094,
+                        "intrinsic has wrong number of type \
+                        parameters: found {}, expected {}",
+                        i_n_tps, n_tps)
+            .span_label(span, &format!("expected {} type parameter", n_tps))
+            .emit();
     } else {
         require_same_types(ccx,
                            TypeOrigin::IntrinsicType(it.span),
index 9e0b38fd9fe517a163c9cffcdfce403b394f8b31..be77ca435a18c8f27e580abf1c6c94709c52d599 100644 (file)
@@ -145,7 +145,7 @@ fn adjust_self_ty(&mut self,
     {
         let (autoref, unsize) = if let Some(mutbl) = pick.autoref {
             let region = self.next_region_var(infer::Autoref(self.span));
-            let autoref = AutoPtr(self.tcx.mk_region(region), mutbl);
+            let autoref = AutoPtr(region, mutbl);
             (Some(autoref), pick.unsize.map(|target| {
                 target.adjust_for_autoref(self.tcx, Some(autoref))
             }))
@@ -327,19 +327,22 @@ fn instantiate_method_substs(&mut self,
         // parameters from the type and those from the method.
         //
         // FIXME -- permit users to manually specify lifetimes
+        let supplied_start = substs.params().len() + method.generics.regions.len();
         Substs::for_item(self.tcx, method.def_id, |def, _| {
-            if let Some(&r) = substs.regions.get(def.index as usize) {
-                r
+            let i = def.index as usize;
+            if i < substs.params().len() {
+                substs.region_at(i)
             } else {
                 self.region_var_for_def(self.span, def)
             }
         }, |def, cur_substs| {
-            if let Some(&ty) = substs.types.get(def.index as usize) {
-                ty
+            let i = def.index as usize;
+            if i < substs.params().len() {
+                substs.type_at(i)
             } else if supplied_method_types.is_empty() {
                 self.type_var_for_def(self.span, def, cur_substs)
             } else {
-                supplied_method_types[def.index as usize - substs.types.len()]
+                supplied_method_types[i - supplied_start]
             }
         })
     }
index c306463ec1de0795b7352e6a01cf89a90462543c..a64982cd1bf819efb9ad8960abb7bd9cfe531e3b 100644 (file)
@@ -519,9 +519,9 @@ fn assemble_inherent_candidates_from_param(&mut self,
                        trait_ref.substs,
                        m);
                 assert_eq!(m.generics.parent_types as usize,
-                           trait_ref.substs.types.len());
+                           trait_ref.substs.types().count());
                 assert_eq!(m.generics.parent_regions as usize,
-                           trait_ref.substs.regions.len());
+                           trait_ref.substs.regions().count());
             }
 
             // Because this trait derives from a where-clause, it
@@ -529,7 +529,7 @@ fn assemble_inherent_candidates_from_param(&mut self,
             // artifacts. This means it is safe to put into the
             // `WhereClauseCandidate` and (eventually) into the
             // `WhereClausePick`.
-            assert!(!trait_ref.substs.types.needs_infer());
+            assert!(!trait_ref.substs.needs_infer());
 
             this.inherent_candidates.push(Candidate {
                 xform_self_ty: xform_self_ty,
@@ -1220,8 +1220,8 @@ fn xform_method_self_ty(&self,
         // are given do not include type/lifetime parameters for the
         // method yet. So create fresh variables here for those too,
         // if there are any.
-        assert_eq!(substs.types.len(), method.generics.parent_types as usize);
-        assert_eq!(substs.regions.len(), method.generics.parent_regions as usize);
+        assert_eq!(substs.types().count(), method.generics.parent_types as usize);
+        assert_eq!(substs.regions().count(), method.generics.parent_regions as usize);
 
         if self.mode == Mode::Path {
             return impl_ty;
@@ -1236,16 +1236,18 @@ fn xform_method_self_ty(&self,
             xform_self_ty.subst(self.tcx, substs)
         } else {
             let substs = Substs::for_item(self.tcx, method.def_id, |def, _| {
-                if let Some(&r) = substs.regions.get(def.index as usize) {
-                    r
+                let i = def.index as usize;
+                if i < substs.params().len() {
+                    substs.region_at(i)
                 } else {
                     // In general, during probe we erase regions. See
                     // `impl_self_ty()` for an explanation.
-                    ty::ReErased
+                    self.tcx.mk_region(ty::ReErased)
                 }
             }, |def, cur_substs| {
-                if let Some(&ty) = substs.types.get(def.index as usize) {
-                    ty
+                let i = def.index as usize;
+                if i < substs.params().len() {
+                    substs.type_at(i)
                 } else {
                     self.type_var_for_def(self.span, def, cur_substs)
                 }
@@ -1262,7 +1264,7 @@ fn impl_ty_and_substs(&self,
         let impl_ty = self.tcx.lookup_item_type(impl_def_id).ty;
 
         let substs = Substs::for_item(self.tcx, impl_def_id,
-                                      |_, _| ty::ReErased,
+                                      |_, _| self.tcx.mk_region(ty::ReErased),
                                       |_, _| self.next_ty_var());
 
         (impl_ty, substs)
@@ -1324,7 +1326,7 @@ fn to_unadjusted_pick(&self) -> Pick<'tcx> {
                     // inference variables or other artifacts. This
                     // means they are safe to put into the
                     // `WhereClausePick`.
-                    assert!(!trait_ref.substs().types.needs_infer());
+                    assert!(!trait_ref.substs().needs_infer());
 
                     WhereClausePick(trait_ref.clone())
                 }
index 573dae46456baa2f3b78146e3bab014e63112671..f9699a55f50687e601c783e7ebd6972ca908efb2 100644 (file)
@@ -54,7 +54,7 @@ fn is_fn_ty(&self, ty: &Ty<'tcx>, span: Span) -> bool {
 
                 self.autoderef(span, ty).any(|(ty, _)| self.probe(|_| {
                     let fn_once_substs =
-                        Substs::new_trait(tcx, vec![self.next_ty_var()], vec![], ty);
+                        Substs::new_trait(tcx, ty, &[self.next_ty_var()]);
                     let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs);
                     let poly_trait_ref = trait_ref.to_poly_trait_ref();
                     let obligation = Obligation::misc(span,
index 16300d869abf50ae87527a5e3d10d7aa01913301..e972a5ca7fb3894848b2816b77f880e624d6a935 100644 (file)
@@ -770,7 +770,7 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
       }
       hir::ItemTy(_, ref generics) => {
         let pty_ty = ccx.tcx.node_id_to_type(it.id);
-        check_bounds_are_used(ccx, &generics.ty_params, pty_ty);
+        check_bounds_are_used(ccx, generics, pty_ty);
       }
       hir::ItemForeignMod(ref m) => {
         if m.abi == Abi::RustIntrinsic {
@@ -1422,13 +1422,13 @@ fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
         // (and anyway, within a fn body the right region may not even
         // be something the user can write explicitly, since it might
         // be some expression).
-        self.next_region_var(infer::MiscVariable(span))
+        *self.next_region_var(infer::MiscVariable(span))
     }
 
     fn anon_regions(&self, span: Span, count: usize)
                     -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
         Ok((0..count).map(|_| {
-            self.next_region_var(infer::MiscVariable(span))
+            *self.next_region_var(infer::MiscVariable(span))
         }).collect())
     }
 }
@@ -1862,7 +1862,7 @@ pub fn opt_node_ty_substs<F>(&self,
     /// outlive the region `r`.
     pub fn register_region_obligation(&self,
                                       ty: Ty<'tcx>,
-                                      region: ty::Region,
+                                      region: &'tcx ty::Region,
                                       cause: traits::ObligationCause<'tcx>)
     {
         let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
@@ -1893,13 +1893,13 @@ pub fn register_old_wf_obligation(&self,
         //
         // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
         let cause = traits::ObligationCause::new(span, self.body_id, code);
-        self.register_region_obligation(ty, ty::ReEmpty, cause);
+        self.register_region_obligation(ty, self.tcx.mk_region(ty::ReEmpty), cause);
     }
 
     /// Registers obligations that all types appearing in `substs` are well-formed.
     pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
     {
-        for &ty in &substs.types {
+        for ty in substs.types() {
             self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
         }
     }
@@ -3454,7 +3454,7 @@ fn check_expr_with_expectation_and_lvalue_pref(&self,
                 // value whose address was taken can actually be made to live
                 // as long as it needs to live.
                 let region = self.next_region_var(infer::AddrOfRegion(expr.span));
-                tcx.mk_ref(tcx.mk_region(region), tm)
+                tcx.mk_ref(region, tm)
             };
             self.write_ty(id, oprnd_t);
           }
@@ -4242,18 +4242,23 @@ pub fn instantiate_value_path(&self,
         self.check_path_parameter_count(span, !require_type_space, &mut type_segment);
         self.check_path_parameter_count(span, true, &mut fn_segment);
 
+        let (fn_start, has_self) = match (type_segment, fn_segment) {
+            (_, Some((_, generics))) => {
+                (generics.parent_count(), generics.has_self)
+            }
+            (Some((_, generics)), None) => {
+                (generics.own_count(), generics.has_self)
+            }
+            (None, None) => (0, false)
+        };
         let substs = Substs::for_item(self.tcx, def.def_id(), |def, _| {
             let mut i = def.index as usize;
-            let type_regions = match (type_segment, fn_segment) {
-                (_, Some((_, generics))) => generics.parent_regions as usize,
-                (Some((_, generics)), None) => generics.regions.len(),
-                (None, None) => 0
-            };
 
-            let segment = if i < type_regions {
+            let segment = if i < fn_start {
+                i -= has_self as usize;
                 type_segment
             } else {
-                i -= type_regions;
+                i -= fn_start;
                 fn_segment
             };
             let lifetimes = match segment.map(|(s, _)| &s.parameters) {
@@ -4269,18 +4274,9 @@ pub fn instantiate_value_path(&self,
             }
         }, |def, substs| {
             let mut i = def.index as usize;
-            let (type_types, has_self) = match (type_segment, fn_segment) {
-                (_, Some((_, generics))) => {
-                    (generics.parent_types as usize, generics.has_self)
-                }
-                (Some((_, generics)), None) => {
-                    (generics.types.len(), generics.has_self)
-                }
-                (None, None) => (0, false)
-            };
 
-            let can_omit = i >= type_types || !require_type_space;
-            let segment = if i < type_types {
+            let can_omit = i >= fn_start || !require_type_space;
+            let segment = if i < fn_start {
                 // Handle Self first, so we can adjust the index to match the AST.
                 if has_self && i == 0 {
                     return opt_self_ty.unwrap_or_else(|| {
@@ -4290,7 +4286,7 @@ pub fn instantiate_value_path(&self,
                 i -= has_self as usize;
                 type_segment
             } else {
-                i -= type_types;
+                i -= fn_start;
                 fn_segment
             };
             let types = match segment.map(|(s, _)| &s.parameters) {
@@ -4299,6 +4295,11 @@ pub fn instantiate_value_path(&self,
                 None => &[]
             };
 
+            // Skip over the lifetimes in the same segment.
+            if let Some((_, generics)) = segment {
+                i -= generics.regions.len();
+            }
+
             let omitted = can_omit && types.is_empty();
             if let Some(ast_ty) = types.get(i) {
                 // A provided type parameter.
@@ -4502,28 +4503,28 @@ pub fn may_break(tcx: TyCtxt, id: ast::NodeId, b: &hir::Block) -> bool {
 }
 
 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
-                                       tps: &[hir::TyParam],
+                                       generics: &hir::Generics,
                                        ty: Ty<'tcx>) {
     debug!("check_bounds_are_used(n_tps={}, ty={:?})",
-           tps.len(),  ty);
+           generics.ty_params.len(),  ty);
 
     // make a vector of booleans initially false, set to true when used
-    if tps.is_empty() { return; }
-    let mut tps_used = vec![false; tps.len()];
+    if generics.ty_params.is_empty() { return; }
+    let mut tps_used = vec![false; generics.ty_params.len()];
 
     for leaf_ty in ty.walk() {
         if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
             debug!("Found use of ty param num {}", idx);
-            tps_used[idx as usize] = true;
+            tps_used[idx as usize - generics.lifetimes.len()] = true;
         }
     }
 
-    for (i, b) in tps_used.iter().enumerate() {
-        if !*b {
-            struct_span_err!(ccx.tcx.sess, tps[i].span, E0091,
+    for (&used, param) in tps_used.iter().zip(&generics.ty_params) {
+        if !used {
+            struct_span_err!(ccx.tcx.sess, param.span, E0091,
                 "type parameter `{}` is unused",
-                tps[i].name)
-                .span_label(tps[i].span, &format!("unused type parameter"))
+                param.name)
+                .span_label(param.span, &format!("unused type parameter"))
                 .emit();
         }
     }
index 859d5ff0543d01bcf6f56d0c55bd60c0ad7ea620..cef2bb07e35ca065991bf0dd4f2f8ee08b0d9358 100644 (file)
@@ -169,7 +169,7 @@ pub fn regionck_fn(&self,
 pub struct RegionCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     pub fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
 
-    region_bound_pairs: Vec<(ty::Region, GenericKind<'tcx>)>,
+    region_bound_pairs: Vec<(&'tcx ty::Region, GenericKind<'tcx>)>,
 
     free_region_map: FreeRegionMap,
 
@@ -324,9 +324,10 @@ fn visit_fn_body(&mut self,
         let call_site_scope = self.call_site_scope.unwrap();
         debug!("visit_fn_body body.id {} call_site_scope: {:?}",
                body.id, call_site_scope);
+        let call_site_region = self.tcx.mk_region(ty::ReScope(call_site_scope));
         self.type_of_node_must_outlive(infer::CallReturn(span),
                                        body.id,
-                                       ty::ReScope(call_site_scope));
+                                       call_site_region);
 
         self.region_bound_pairs.truncate(old_region_bounds_pairs_len);
 
@@ -407,8 +408,8 @@ fn relate_free_regions(&mut self,
             for implication in implied_bounds {
                 debug!("implication: {:?}", implication);
                 match implication {
-                    ImpliedBound::RegionSubRegion(ty::ReFree(free_a),
-                                                  ty::ReVar(vid_b)) => {
+                    ImpliedBound::RegionSubRegion(&ty::ReFree(free_a),
+                                                  &ty::ReVar(vid_b)) => {
                         self.add_given(free_a, vid_b);
                     }
                     ImpliedBound::RegionSubParam(r_a, param_b) => {
@@ -476,9 +477,10 @@ fn constrain_bindings_in_pat(&mut self, pat: &hir::Pat) {
             // variable's type enclose at least the variable's scope.
 
             let var_scope = tcx.region_maps.var_scope(id);
+            let var_region = self.tcx.mk_region(ty::ReScope(var_scope));
 
             let origin = infer::BindingTypeIsNotValidAtDecl(span);
-            self.type_of_node_must_outlive(origin, id, ty::ReScope(var_scope));
+            self.type_of_node_must_outlive(origin, id, var_region);
 
             let typ = self.resolve_node_type(id);
             dropck::check_safety_of_destructor_if_necessary(self, typ, span, var_scope);
@@ -525,7 +527,7 @@ fn visit_expr(&mut self, expr: &hir::Expr) {
         // scope of that expression. This also guarantees basic WF.
         let expr_ty = self.resolve_node_type(expr.id);
         // the region corresponding to this expression
-        let expr_region = ty::ReScope(self.tcx.region_maps.node_extent(expr.id));
+        let expr_region = self.tcx.node_scope_region(expr.id);
         self.type_must_outlive(infer::ExprTypeIsNotInScope(expr_ty, expr.span),
                                expr_ty, expr_region);
 
@@ -713,7 +715,7 @@ fn visit_expr(&mut self, expr: &hir::Expr) {
                     None => self.resolve_node_type(base.id)
                 };
                 if let ty::TyRef(r_ptr, _) = base_ty.sty {
-                    self.mk_subregion_due_to_dereference(expr.span, expr_region, *r_ptr);
+                    self.mk_subregion_due_to_dereference(expr.span, expr_region, r_ptr);
                 }
 
                 intravisit::walk_expr(self, expr);
@@ -780,9 +782,10 @@ fn visit_expr(&mut self, expr: &hir::Expr) {
                 let call_site_scope = self.call_site_scope;
                 debug!("visit_expr ExprRet ret_expr.id {} call_site_scope: {:?}",
                        ret_expr.id, call_site_scope);
+                let call_site_region = self.tcx.mk_region(ty::ReScope(call_site_scope.unwrap()));
                 self.type_of_node_must_outlive(infer::CallReturn(ret_expr.span),
                                                ret_expr.id,
-                                               ty::ReScope(call_site_scope.unwrap()));
+                                               call_site_region);
                 intravisit::walk_expr(self, expr);
             }
 
@@ -819,7 +822,7 @@ fn walk_cast(&mut self,
             /*From:*/ (&ty::TyRef(from_r, ref from_mt),
             /*To:  */  &ty::TyRef(to_r, ref to_mt)) => {
                 // Target cannot outlive source, naturally.
-                self.sub_regions(infer::Reborrow(cast_expr.span), *to_r, *from_r);
+                self.sub_regions(infer::Reborrow(cast_expr.span), to_r, from_r);
                 self.walk_cast(cast_expr, from_mt.ty, to_mt.ty);
             }
 
@@ -889,7 +892,7 @@ fn constrain_call<'b, I: Iterator<Item=&'b hir::Expr>>(&mut self,
         //
         // FIXME(#6268) to support nested method calls, should be callee_id
         let callee_scope = self.tcx.region_maps.node_extent(call_expr.id);
-        let callee_region = ty::ReScope(callee_scope);
+        let callee_region = self.tcx.mk_region(ty::ReScope(callee_scope));
 
         debug!("callee_region={:?}", callee_region);
 
@@ -933,8 +936,7 @@ fn constrain_autoderefs(&mut self,
                derefs,
                derefd_ty);
 
-        let s_deref_expr = self.tcx.region_maps.node_extent(deref_expr.id);
-        let r_deref_expr = ty::ReScope(s_deref_expr);
+        let r_deref_expr = self.tcx.node_scope_region(deref_expr.id);
         for i in 0..derefs {
             let method_call = MethodCall::autoderef(deref_expr.id, i as u32);
             debug!("constrain_autoderefs: method_call={:?} (of {:?} total)", method_call, derefs);
@@ -989,7 +991,7 @@ fn constrain_autoderefs(&mut self,
 
             if let ty::TyRef(r_ptr, _) =  derefd_ty.sty {
                 self.mk_subregion_due_to_dereference(deref_expr.span,
-                                                     r_deref_expr, *r_ptr);
+                                                     r_deref_expr, r_ptr);
             }
 
             match derefd_ty.builtin_deref(true, ty::NoPreference) {
@@ -1003,8 +1005,8 @@ fn constrain_autoderefs(&mut self,
 
     pub fn mk_subregion_due_to_dereference(&mut self,
                                            deref_span: Span,
-                                           minimum_lifetime: ty::Region,
-                                           maximum_lifetime: ty::Region) {
+                                           minimum_lifetime: &'tcx ty::Region,
+                                           maximum_lifetime: &'tcx ty::Region) {
         self.sub_regions(infer::DerefPointer(deref_span),
                          minimum_lifetime, maximum_lifetime)
     }
@@ -1014,7 +1016,7 @@ fn check_safety_of_rvalue_destructor_if_necessary(&mut self,
                                                      span: Span) {
         match cmt.cat {
             Categorization::Rvalue(region) => {
-                match region {
+                match *region {
                     ty::ReScope(rvalue_scope) => {
                         let typ = self.resolve_type(cmt.ty);
                         dropck::check_safety_of_destructor_if_necessary(self,
@@ -1023,7 +1025,7 @@ fn check_safety_of_rvalue_destructor_if_necessary(&mut self,
                                                                         rvalue_scope);
                     }
                     ty::ReStatic => {}
-                    region => {
+                    _ => {
                         span_bug!(span,
                                   "unexpected rvalue region in rvalue \
                                    destructor safety checking: `{:?}`",
@@ -1049,7 +1051,7 @@ fn constrain_index(&mut self,
             match mt.ty.sty {
                 ty::TySlice(_) | ty::TyStr => {
                     self.sub_regions(infer::IndexSlice(index_expr.span),
-                                     r_index_expr, *r_ptr);
+                                     self.tcx.mk_region(r_index_expr), r_ptr);
                 }
                 _ => {}
             }
@@ -1061,7 +1063,7 @@ fn constrain_index(&mut self,
     fn type_of_node_must_outlive(&mut self,
         origin: infer::SubregionOrigin<'tcx>,
         id: ast::NodeId,
-        minimum_lifetime: ty::Region)
+        minimum_lifetime: &'tcx ty::Region)
     {
         let tcx = self.tcx;
 
@@ -1132,7 +1134,7 @@ fn link_fn_args(&self, body_scope: CodeExtent, args: &[hir::Arg]) {
         let mc = mc::MemCategorizationContext::new(self);
         for arg in args {
             let arg_ty = self.node_ty(arg.id);
-            let re_scope = ty::ReScope(body_scope);
+            let re_scope = self.tcx.mk_region(ty::ReScope(body_scope));
             let arg_cmt = mc.cat_rvalue(arg.id, arg.ty.span, re_scope, arg_ty);
             debug!("arg_ty={:?} arg_cmt={:?} arg={:?}",
                    arg_ty,
@@ -1168,7 +1170,7 @@ fn link_pattern<'t>(&self,
     fn link_autoref(&self,
                     expr: &hir::Expr,
                     autoderefs: usize,
-                    autoref: &adjustment::AutoRef)
+                    autoref: &adjustment::AutoRef<'tcx>)
     {
         debug!("link_autoref(autoref={:?})", autoref);
         let mc = mc::MemCategorizationContext::new(self);
@@ -1182,8 +1184,8 @@ fn link_autoref(&self,
             }
 
             adjustment::AutoUnsafe(m) => {
-                let r = ty::ReScope(self.tcx.region_maps.node_extent(expr.id));
-                self.link_region(expr.span, &r, ty::BorrowKind::from_mutbl(m), expr_cmt);
+                let r = self.tcx.node_scope_region(expr.id);
+                self.link_region(expr.span, r, ty::BorrowKind::from_mutbl(m), expr_cmt);
             }
         }
     }
@@ -1197,8 +1199,8 @@ fn link_by_ref(&self,
                expr, callee_scope);
         let mc = mc::MemCategorizationContext::new(self);
         let expr_cmt = ignore_err!(mc.cat_expr(expr));
-        let borrow_region = ty::ReScope(callee_scope);
-        self.link_region(expr.span, &borrow_region, ty::ImmBorrow, expr_cmt);
+        let borrow_region = self.tcx.mk_region(ty::ReScope(callee_scope));
+        self.link_region(expr.span, borrow_region, ty::ImmBorrow, expr_cmt);
     }
 
     /// Like `link_region()`, except that the region is extracted from the type of `id`,
@@ -1212,9 +1214,9 @@ fn link_region_from_node_type(&self,
                id, mutbl, cmt_borrowed);
 
         let rptr_ty = self.resolve_node_type(id);
-        if let ty::TyRef(&r, _) = rptr_ty.sty {
+        if let ty::TyRef(r, _) = rptr_ty.sty {
             debug!("rptr_ty={}",  rptr_ty);
-            self.link_region(span, &r, ty::BorrowKind::from_mutbl(mutbl),
+            self.link_region(span, r, ty::BorrowKind::from_mutbl(mutbl),
                              cmt_borrowed);
         }
     }
@@ -1225,14 +1227,14 @@ fn link_region_from_node_type(&self,
     /// between regions, as explained in `link_reborrowed_region()`.
     fn link_region(&self,
                    span: Span,
-                   borrow_region: &ty::Region,
+                   borrow_region: &'tcx ty::Region,
                    borrow_kind: ty::BorrowKind,
                    borrow_cmt: mc::cmt<'tcx>) {
         let mut borrow_cmt = borrow_cmt;
         let mut borrow_kind = borrow_kind;
 
         let origin = infer::DataBorrowed(borrow_cmt.ty, span);
-        self.type_must_outlive(origin, borrow_cmt.ty, *borrow_region);
+        self.type_must_outlive(origin, borrow_cmt.ty, borrow_region);
 
         loop {
             debug!("link_region(borrow_region={:?}, borrow_kind={:?}, borrow_cmt={:?})",
@@ -1322,10 +1324,10 @@ fn link_region(&self,
     /// recurse and process `ref_cmt` (see case 2 above).
     fn link_reborrowed_region(&self,
                               span: Span,
-                              borrow_region: &ty::Region,
+                              borrow_region: &'tcx ty::Region,
                               borrow_kind: ty::BorrowKind,
                               ref_cmt: mc::cmt<'tcx>,
-                              ref_region: ty::Region,
+                              ref_region: &'tcx ty::Region,
                               mut ref_kind: ty::BorrowKind,
                               note: mc::Note)
                               -> Option<(mc::cmt<'tcx>, ty::BorrowKind)>
@@ -1364,7 +1366,7 @@ fn link_reborrowed_region(&self,
         debug!("link_reborrowed_region: {:?} <= {:?}",
                borrow_region,
                ref_region);
-        self.sub_regions(cause, *borrow_region, ref_region);
+        self.sub_regions(cause, borrow_region, ref_region);
 
         // If we end up needing to recurse and establish a region link
         // with `ref_cmt`, calculate what borrow kind we will end up
@@ -1436,7 +1438,7 @@ fn substs_wf_in_scope(&mut self,
                           origin: infer::ParameterOrigin,
                           substs: &Substs<'tcx>,
                           expr_span: Span,
-                          expr_region: ty::Region) {
+                          expr_region: &'tcx ty::Region) {
         debug!("substs_wf_in_scope(substs={:?}, \
                 expr_region={:?}, \
                 origin={:?}, \
@@ -1445,11 +1447,11 @@ fn substs_wf_in_scope(&mut self,
 
         let origin = infer::ParameterInScope(origin, expr_span);
 
-        for &region in &substs.regions {
+        for region in substs.regions() {
             self.sub_regions(origin.clone(), expr_region, region);
         }
 
-        for &ty in &substs.types {
+        for ty in substs.types() {
             let ty = self.resolve_type(ty);
             self.type_must_outlive(origin.clone(), ty, expr_region);
         }
@@ -1461,7 +1463,7 @@ fn substs_wf_in_scope(&mut self,
     pub fn type_must_outlive(&self,
                              origin: infer::SubregionOrigin<'tcx>,
                              ty: Ty<'tcx>,
-                             region: ty::Region)
+                             region: &'tcx ty::Region)
     {
         let ty = self.resolve_type(ty);
 
@@ -1479,7 +1481,7 @@ pub fn type_must_outlive(&self,
     fn components_must_outlive(&self,
                                origin: infer::SubregionOrigin<'tcx>,
                                components: Vec<ty::outlives::Component<'tcx>>,
-                               region: ty::Region)
+                               region: &'tcx ty::Region)
     {
         for component in components {
             let origin = origin.clone();
@@ -1510,7 +1512,7 @@ fn components_must_outlive(&self,
 
     fn param_ty_must_outlive(&self,
                              origin: infer::SubregionOrigin<'tcx>,
-                             region: ty::Region,
+                             region: &'tcx ty::Region,
                              param_ty: ty::ParamTy) {
         debug!("param_ty_must_outlive(region={:?}, param_ty={:?}, origin={:?})",
                region, param_ty, origin);
@@ -1522,7 +1524,7 @@ fn param_ty_must_outlive(&self,
 
     fn projection_must_outlive(&self,
                                origin: infer::SubregionOrigin<'tcx>,
-                               region: ty::Region,
+                               region: &'tcx ty::Region,
                                projection_ty: ty::ProjectionTy<'tcx>)
     {
         debug!("projection_must_outlive(region={:?}, projection_ty={:?}, origin={:?})",
@@ -1552,7 +1554,7 @@ fn projection_must_outlive(&self,
 
         // If we know that the projection outlives 'static, then we're
         // done here.
-        if env_bounds.contains(&ty::ReStatic) {
+        if env_bounds.contains(&&ty::ReStatic) {
             debug!("projection_must_outlive: 'static as declared bound");
             return;
         }
@@ -1575,11 +1577,11 @@ fn projection_must_outlive(&self,
         if env_bounds.is_empty() && needs_infer {
             debug!("projection_must_outlive: no declared bounds");
 
-            for &component_ty in &projection_ty.trait_ref.substs.types {
+            for component_ty in projection_ty.trait_ref.substs.types() {
                 self.type_must_outlive(origin.clone(), component_ty, region);
             }
 
-            for &r in &projection_ty.trait_ref.substs.regions {
+            for r in projection_ty.trait_ref.substs.regions() {
                 self.sub_regions(origin.clone(), region, r);
             }
 
@@ -1597,10 +1599,7 @@ fn projection_must_outlive(&self,
         if !env_bounds.is_empty() && env_bounds[1..].iter().all(|b| *b == env_bounds[0]) {
             let unique_bound = env_bounds[0];
             debug!("projection_must_outlive: unique declared bound = {:?}", unique_bound);
-            if projection_ty.trait_ref.substs.regions
-                                             .iter()
-                                             .any(|r| env_bounds.contains(r))
-            {
+            if projection_ty.trait_ref.substs.regions().any(|r| env_bounds.contains(&r)) {
                 debug!("projection_must_outlive: unique declared bound appears in trait ref");
                 self.sub_regions(origin.clone(), region, unique_bound);
                 return;
@@ -1617,7 +1616,7 @@ fn projection_must_outlive(&self,
         self.verify_generic_bound(origin, generic.clone(), region, verify_bound);
     }
 
-    fn type_bound(&self, span: Span, ty: Ty<'tcx>) -> VerifyBound {
+    fn type_bound(&self, span: Span, ty: Ty<'tcx>) -> VerifyBound<'tcx> {
         match ty.sty {
             ty::TyParam(p) => {
                 self.param_bound(p)
@@ -1632,7 +1631,7 @@ fn type_bound(&self, span: Span, ty: Ty<'tcx>) -> VerifyBound {
         }
     }
 
-    fn param_bound(&self, param_ty: ty::ParamTy) -> VerifyBound {
+    fn param_bound(&self, param_ty: ty::ParamTy) -> VerifyBound<'tcx> {
         let param_env = &self.parameter_environment;
 
         debug!("param_bound(param_ty={:?})",
@@ -1650,7 +1649,7 @@ fn param_bound(&self, param_ty: ty::ParamTy) -> VerifyBound {
     fn projection_declared_bounds(&self,
                                   span: Span,
                                   projection_ty: ty::ProjectionTy<'tcx>)
-                                  -> Vec<ty::Region>
+                                  -> Vec<&'tcx ty::Region>
     {
         // First assemble bounds from where clauses and traits.
 
@@ -1665,9 +1664,9 @@ fn projection_declared_bounds(&self,
 
     fn projection_bound(&self,
                         span: Span,
-                        declared_bounds: Vec<ty::Region>,
+                        declared_bounds: Vec<&'tcx ty::Region>,
                         projection_ty: ty::ProjectionTy<'tcx>)
-                        -> VerifyBound {
+                        -> VerifyBound<'tcx> {
         debug!("projection_bound(declared_bounds={:?}, projection_ty={:?})",
                declared_bounds, projection_ty);
 
@@ -1679,7 +1678,7 @@ fn projection_bound(&self,
         VerifyBound::AnyRegion(declared_bounds).or(recursive_bound)
     }
 
-    fn recursive_type_bound(&self, span: Span, ty: Ty<'tcx>) -> VerifyBound {
+    fn recursive_type_bound(&self, span: Span, ty: Ty<'tcx>) -> VerifyBound<'tcx> {
         let mut bounds = vec![];
 
         for subty in ty.walk_shallow() {
@@ -1701,7 +1700,7 @@ fn recursive_type_bound(&self, span: Span, ty: Ty<'tcx>) -> VerifyBound {
     }
 
     fn declared_generic_bounds_from_env(&self, generic: GenericKind<'tcx>)
-                                        -> Vec<ty::Region>
+                                        -> Vec<&'tcx ty::Region>
     {
         let param_env = &self.parameter_environment;
 
@@ -1735,7 +1734,7 @@ fn declared_generic_bounds_from_env(&self, generic: GenericKind<'tcx>)
     fn declared_projection_bounds_from_trait(&self,
                                              span: Span,
                                              projection_ty: ty::ProjectionTy<'tcx>)
-                                             -> Vec<ty::Region>
+                                             -> Vec<&'tcx ty::Region>
     {
         debug!("projection_bounds(projection_ty={:?})",
                projection_ty);
index 030491b521d95679e38b0f72cfdc975a7ba468ae..a85e295784e977e5eeab71761fd11ca348ffb7fb 100644 (file)
@@ -252,7 +252,7 @@ fn final_upvar_tys(&mut self, closure_id: ast::NodeId) -> Vec<Ty<'tcx>> {
                         match capture {
                             ty::UpvarCapture::ByValue => freevar_ty,
                             ty::UpvarCapture::ByRef(borrow) =>
-                                tcx.mk_ref(tcx.mk_region(borrow.region),
+                                tcx.mk_ref(borrow.region,
                                            ty::TypeAndMut {
                                                ty: freevar_ty,
                                                mutbl: borrow.kind.to_mutbl_lossy(),
@@ -536,7 +536,7 @@ fn borrow(&mut self,
               borrow_id: ast::NodeId,
               _borrow_span: Span,
               cmt: mc::cmt<'tcx>,
-              _loan_region: ty::Region,
+              _loan_region: &'tcx ty::Region,
               bk: ty::BorrowKind,
               _loan_cause: euv::LoanCause)
     {
index bcad7dd3bd0fa78ef03e7a729b3c95f1fdfc7ee1..38ec7ba686f6f5e1b60372fd4af297510e2f8daa 100644 (file)
@@ -416,7 +416,7 @@ fn check_method_receiver<'fcx, 'tcx>(&mut self,
             ty::ExplicitSelfCategory::Static => return,
             ty::ExplicitSelfCategory::ByValue => self_ty,
             ty::ExplicitSelfCategory::ByReference(region, mutability) => {
-                fcx.tcx.mk_ref(fcx.tcx.mk_region(region), ty::TypeAndMut {
+                fcx.tcx.mk_ref(region, ty::TypeAndMut {
                     ty: self_ty,
                     mutbl: mutability
                 })
@@ -457,7 +457,7 @@ fn check_variances_for_type_defn(&self,
         let variances = self.tcx().item_variances(item_def_id);
 
         let mut constrained_parameters: HashSet<_> =
-            variances.types
+            variances[ast_generics.lifetimes.len()..]
                      .iter().enumerate()
                      .filter(|&(_, &variance)| variance != ty::Bivariant)
                      .map(|(index, _)| self.param_ty(ast_generics, index))
@@ -468,22 +468,22 @@ fn check_variances_for_type_defn(&self,
                                          None,
                                          &mut constrained_parameters);
 
-        for (index, _) in variances.types.iter().enumerate() {
-            let param_ty = self.param_ty(ast_generics, index);
-            if constrained_parameters.contains(&Parameter::Type(param_ty)) {
-                continue;
-            }
-            let span = ast_generics.ty_params[index].span;
-            self.report_bivariance(span, param_ty.name);
-        }
-
-        for (index, &variance) in variances.regions.iter().enumerate() {
-            if variance != ty::Bivariant {
-                continue;
-            }
+        for (index, &variance) in variances.iter().enumerate() {
+            let (span, name) = if index < ast_generics.lifetimes.len() {
+                if variance != ty::Bivariant {
+                    continue;
+                }
 
-            let span = ast_generics.lifetimes[index].lifetime.span;
-            let name = ast_generics.lifetimes[index].lifetime.name;
+                (ast_generics.lifetimes[index].lifetime.span,
+                 ast_generics.lifetimes[index].lifetime.name)
+            } else {
+                let index = index - ast_generics.lifetimes.len();
+                let param_ty = self.param_ty(ast_generics, index);
+                if constrained_parameters.contains(&Parameter::Type(param_ty)) {
+                    continue;
+                }
+                (ast_generics.ty_params[index].span, param_ty.name)
+            };
             self.report_bivariance(span, name);
         }
     }
@@ -597,7 +597,7 @@ fn impl_implied_bounds(&self, impl_def_id: DefId, span: Span) -> Vec<Ty<'tcx>> {
                 // Trait impl: take implied bounds from all types that
                 // appear in the trait reference.
                 let trait_ref = self.instantiate_type_scheme(span, free_substs, trait_ref);
-                trait_ref.substs.types.to_vec()
+                trait_ref.substs.types().collect()
             }
 
             None => {
index cfc1292c34b78af0275585300c5acb9bd5f36d1e..3bd0e890bb8119fd4e8bf5196145d9185f1c47a6 100644 (file)
@@ -87,7 +87,7 @@ struct WritebackCx<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
     // early-bound versions of them, visible from the
     // outside of the function. This is needed by, and
     // only populated if there are any `impl Trait`.
-    free_to_bound_regions: DefIdMap<ty::Region>
+    free_to_bound_regions: DefIdMap<&'gcx ty::Region>
 }
 
 impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
@@ -102,16 +102,22 @@ fn new(fcx: &'cx FnCtxt<'cx, 'gcx, 'tcx>) -> WritebackCx<'cx, 'gcx, 'tcx> {
             return wbcx;
         }
 
+        let gcx = fcx.tcx.global_tcx();
         let free_substs = fcx.parameter_environment.free_substs;
-        for (i, r) in free_substs.regions.iter().enumerate() {
+        for (i, k) in free_substs.params().iter().enumerate() {
+            let r = if let Some(r) = k.as_region() {
+                r
+            } else {
+                continue;
+            };
             match *r {
                 ty::ReFree(ty::FreeRegion {
                     bound_region: ty::BoundRegion::BrNamed(def_id, name, _), ..
                 }) => {
-                    let bound_region = ty::ReEarlyBound(ty::EarlyBoundRegion {
+                    let bound_region = gcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
                         index: i as u32,
                         name: name,
-                    });
+                    }));
                     wbcx.free_to_bound_regions.insert(def_id, bound_region);
                 }
                 _ => {
@@ -311,9 +317,9 @@ fn visit_anon_types(&self, item_id: ast::NodeId) {
             // Convert the type from the function into a type valid outside
             // the function, by replacing free regions with early-bound ones.
             let outside_ty = gcx.fold_regions(&inside_ty, &mut false, |r, _| {
-                match r {
+                match *r {
                     // 'static is valid everywhere.
-                    ty::ReStatic => ty::ReStatic,
+                    ty::ReStatic => gcx.mk_region(ty::ReStatic),
 
                     // Free regions that come from early-bound regions are valid.
                     ty::ReFree(ty::FreeRegion {
@@ -331,7 +337,7 @@ fn visit_anon_types(&self, item_id: ast::NodeId) {
                         span_err!(self.tcx().sess, span, E0564,
                                   "only named lifetimes are allowed in `impl Trait`, \
                                    but `{}` was found in the type `{}`", r, inside_ty);
-                        ty::ReStatic
+                        gcx.mk_region(ty::ReStatic)
                     }
 
                     ty::ReVar(_) |
@@ -626,12 +632,12 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
         }
     }
 
-    fn fold_region(&mut self, r: ty::Region) -> ty::Region {
+    fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
         match self.infcx.fully_resolve(&r) {
             Ok(r) => r,
             Err(e) => {
                 self.report_error(e);
-                ty::ReStatic
+                self.tcx.mk_region(ty::ReStatic)
             }
         }
     }
index d00cbf0221e0e76dbc53c8e0606c71f74f65ecfa..7d6cee7b3bac16767e64d653f5a727b166f22061 100644 (file)
@@ -386,7 +386,7 @@ fn check_implementations_of_coerce_unsized(&self) {
 
             let source = tcx.lookup_item_type(impl_did).ty;
             let trait_ref = self.crate_context.tcx.impl_trait_ref(impl_did).unwrap();
-            let target = trait_ref.substs.types[1];
+            let target = trait_ref.substs.type_at(1);
             debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (bound)",
                    source, target);
 
@@ -413,7 +413,7 @@ fn check_implementations_of_coerce_unsized(&self) {
                     (&ty::TyBox(a), &ty::TyBox(b)) => (a, b, unsize_trait, None),
 
                     (&ty::TyRef(r_a, mt_a), &ty::TyRef(r_b, mt_b)) => {
-                        infcx.sub_regions(infer::RelateObjectBound(span), *r_b, *r_a);
+                        infcx.sub_regions(infer::RelateObjectBound(span), r_b, r_a);
                         check_mutbl(mt_a, mt_b, &|ty| tcx.mk_imm_ref(r_b, ty))
                     }
 
@@ -498,7 +498,7 @@ fn check_implementations_of_coerce_unsized(&self) {
                 // Register an obligation for `A: Trait<B>`.
                 let cause = traits::ObligationCause::misc(span, impl_node_id);
                 let predicate = tcx.predicate_for_trait_def(cause, trait_def_id, 0,
-                                                            source, vec![target]);
+                                                            source, &[target]);
                 fulfill_cx.register_predicate_obligation(&infcx, predicate);
 
                 // Check that all transitive obligations are satisfied.
index 7e1fb32881d6fa203e8568e1b00bff76499ec8f1..0074d3930e29f66402855d86f1df085f2ffa56c0 100644 (file)
@@ -1486,6 +1486,7 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
 
         let has_self = opt_self.is_some();
         let mut parent_has_self = false;
+        let mut own_start = has_self as u32;
         let (parent_regions, parent_types) = parent_def_id.map_or((0, 0), |def_id| {
             let generics = generics_of_def_id(ccx, def_id);
             assert_eq!(generics.parent, None);
@@ -1493,6 +1494,7 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
             assert_eq!(generics.parent_types, 0);
             assert_eq!(has_self, false);
             parent_has_self = generics.has_self;
+            own_start = generics.count() as u32;
             (generics.regions.len() as u32, generics.types.len() as u32)
         });
 
@@ -1500,17 +1502,18 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
         let regions = early_lifetimes.iter().enumerate().map(|(i, l)| {
             ty::RegionParameterDef {
                 name: l.lifetime.name,
-                index: parent_regions + i as u32,
+                index: own_start + i as u32,
                 def_id: tcx.map.local_def_id(l.lifetime.id),
                 bounds: l.bounds.iter().map(|l| {
                     ast_region_to_region(tcx, l)
                 }).collect()
             }
-        }).collect();
+        }).collect::<Vec<_>>();
 
         // Now create the real type parameters.
+        let type_start = own_start + regions.len() as u32;
         let types = ast_generics.ty_params.iter().enumerate().map(|(i, p)| {
-            let i = parent_types + has_self as u32 + i as u32;
+            let i = type_start + i as u32;
             get_or_create_type_parameter_def(ccx, ast_generics, i, p, allow_defaults)
         });
         let types: Vec<_> = opt_self.into_iter().chain(types).collect();
@@ -1529,8 +1532,8 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
 
         tcx.alloc_generics(ty::Generics {
             parent: parent_def_id,
-            parent_regions: parent_regions as u32,
-            parent_types: parent_types as u32,
+            parent_regions: parent_regions,
+            parent_types: parent_types,
             regions: regions,
             types: types,
             has_self: has_self || parent_has_self
@@ -1741,12 +1744,12 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                                   -> ty::GenericPredicates<'tcx>
 {
     let tcx = ccx.tcx;
-    let (parent_regions, parent_types) = parent.map_or((0, 0), |def_id| {
+    let parent_count = parent.map_or(0, |def_id| {
         let generics = generics_of_def_id(ccx, def_id);
         assert_eq!(generics.parent, None);
         assert_eq!(generics.parent_regions, 0);
         assert_eq!(generics.parent_types, 0);
-        (generics.regions.len() as u32, generics.types.len() as u32)
+        generics.count() as u32
     });
     let ref base_predicates = match parent {
         Some(def_id) => {
@@ -1762,10 +1765,29 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
     };
     let mut predicates = super_predicates;
 
+    // Collect the region predicates that were declared inline as
+    // well. In the case of parameters declared on a fn or method, we
+    // have to be careful to only iterate over early-bound regions.
+    let own_start = parent_count + has_self as u32;
+    let early_lifetimes = early_bound_lifetimes_from_generics(ccx, ast_generics);
+    for (index, param) in early_lifetimes.iter().enumerate() {
+        let index = own_start + index as u32;
+        let region = ccx.tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
+            index: index,
+            name: param.lifetime.name
+        }));
+        for bound in &param.bounds {
+            let bound_region = ast_region_to_region(ccx.tcx, bound);
+            let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
+            predicates.push(outlives.to_predicate());
+        }
+    }
+
     // Collect the predicates that were written inline by the user on each
     // type parameter (e.g., `<T:Foo>`).
+    let type_start = own_start + early_lifetimes.len() as u32;
     for (index, param) in ast_generics.ty_params.iter().enumerate() {
-        let index = parent_types + has_self as u32 + index as u32;
+        let index = type_start + index as u32;
         let param_ty = ty::ParamTy::new(index, param.name).to_ty(ccx.tcx);
         let bounds = compute_bounds(&ccx.icx(&(base_predicates, ast_generics)),
                                     param_ty,
@@ -1776,24 +1798,6 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
         predicates.extend(bounds.predicates(ccx.tcx, param_ty));
     }
 
-    // Collect the region predicates that were declared inline as
-    // well. In the case of parameters declared on a fn or method, we
-    // have to be careful to only iterate over early-bound regions.
-    let early_lifetimes = early_bound_lifetimes_from_generics(ccx, ast_generics);
-    for (index, param) in early_lifetimes.iter().enumerate() {
-        let index = parent_regions + index as u32;
-        let region =
-            ty::ReEarlyBound(ty::EarlyBoundRegion {
-                index: index,
-                name: param.lifetime.name
-            });
-        for bound in &param.bounds {
-            let bound_region = ast_region_to_region(ccx.tcx, bound);
-            let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
-            predicates.push(outlives.to_predicate());
-        }
-    }
-
     // Add in the bounds that appear in the where-clause
     let where_clause = &ast_generics.where_clause;
     for predicate in &where_clause.predicates {
@@ -1919,7 +1923,7 @@ fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                                             param_id: ast::NodeId,
                                             param_bounds: &[hir::TyParamBound],
                                             where_clause: &hir::WhereClause)
-                                            -> ty::ObjectLifetimeDefault
+                                            -> ty::ObjectLifetimeDefault<'tcx>
 {
     let inline_bounds = from_bounds(ccx, param_bounds);
     let where_bounds = from_predicates(ccx, param_id, &where_clause.predicates);
@@ -1937,7 +1941,7 @@ fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
 
     fn from_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                             bounds: &[hir::TyParamBound])
-                            -> Vec<ty::Region>
+                            -> Vec<&'tcx ty::Region>
     {
         bounds.iter()
               .filter_map(|bound| {
@@ -1954,7 +1958,7 @@ fn from_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
     fn from_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                                 param_id: ast::NodeId,
                                 predicates: &[hir::WherePredicate])
-                                -> Vec<ty::Region>
+                                -> Vec<&'tcx ty::Region>
     {
         predicates.iter()
                   .flat_map(|predicate| {
@@ -2126,7 +2130,7 @@ pub fn mk_item_substs<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
     }
 
     Substs::for_item(tcx, def_id,
-                     |def, _| def.to_early_bound_region(),
+                     |def, _| tcx.mk_region(def.to_early_bound_region()),
                      |def, _| tcx.mk_param_from_def(def))
 }
 
index 7d3bd095a3a888c930b813f17654334ae4e92ded..637df52e3cb03e2fb40c6746c7503c4b293796be 100644 (file)
@@ -58,8 +58,8 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
         t.super_visit_with(self)
     }
 
-    fn visit_region(&mut self, r: ty::Region) -> bool {
-        match r {
+    fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
+        match *r {
             ty::ReEarlyBound(data) => {
                 self.parameters.push(Parameter::Region(data));
             }
index 8a8232535c77592ae9936d6545899bc1e257ad58..2a989105c9cb49b258c80d1f76e5fd0dd8c8dd21 100644 (file)
@@ -172,7 +172,7 @@ fn write_substs_to_tcx<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                node_id,
                item_substs);
 
-        assert!(!item_substs.substs.types.needs_infer());
+        assert!(!item_substs.substs.needs_infer());
 
         ccx.tcx.tables.borrow_mut().item_substs.insert(node_id, item_substs);
     }
index 9aca779dd89c4f7ee01758eee09ae012eefff077..f5b13c4207d905aaec9066559b8dc0b100140ae8 100644 (file)
@@ -257,12 +257,12 @@ fn anon_regions(&self,
 /// A scope which overrides the default object lifetime but has no other effect.
 pub struct ObjectLifetimeDefaultRscope<'r> {
     base_scope: &'r (RegionScope+'r),
-    default: ty::ObjectLifetimeDefault,
+    default: ty::ObjectLifetimeDefault<'r>,
 }
 
 impl<'r> ObjectLifetimeDefaultRscope<'r> {
     pub fn new(base_scope: &'r (RegionScope+'r),
-               default: ty::ObjectLifetimeDefault)
+               default: ty::ObjectLifetimeDefault<'r>)
                -> ObjectLifetimeDefaultRscope<'r>
     {
         ObjectLifetimeDefaultRscope {
@@ -283,7 +283,7 @@ fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
                 Some(self.base_object_lifetime_default(span)),
 
             ty::ObjectLifetimeDefault::Specific(r) =>
-                Some(r),
+                Some(*r),
         }
     }
 
index 536fa629fd611837154ddb733c386f7a09da7af2..2cf84b5745af4a0ec0c2e25fd4a84794a473407e 100644 (file)
@@ -26,7 +26,6 @@
 
 use super::terms::*;
 use super::terms::VarianceTerm::*;
-use super::terms::ParamKind::*;
 use super::xform::*;
 
 pub struct ConstraintContext<'a, 'tcx: 'a> {
@@ -209,7 +208,6 @@ macro_rules! cannot_happen { () => { {
     fn declared_variance(&self,
                          param_def_id: DefId,
                          item_def_id: DefId,
-                         kind: ParamKind,
                          index: usize)
                          -> VarianceTermPtr<'a> {
         assert_eq!(param_def_id.krate, item_def_id.krate);
@@ -224,11 +222,7 @@ fn declared_variance(&self,
             // Parameter on an item defined within another crate:
             // variance already inferred, just look it up.
             let variances = self.tcx().item_variances(item_def_id);
-            let variance = match kind {
-                TypeParam => variances.types[index],
-                RegionParam => variances.regions[index],
-            };
-            self.constant_term(variance)
+            self.constant_term(variances[index])
         }
     }
 
@@ -330,7 +324,7 @@ fn add_constraints_from_ty(&mut self,
 
             ty::TyRef(region, ref mt) => {
                 let contra = self.contravariant(variance);
-                self.add_constraints_from_region(generics, *region, contra);
+                self.add_constraints_from_region(generics, region, contra);
                 self.add_constraints_from_mt(generics, mt, variance);
             }
 
@@ -401,8 +395,11 @@ fn add_constraints_from_ty(&mut self,
 
             ty::TyParam(ref data) => {
                 assert_eq!(generics.parent, None);
-                assert!((data.idx as usize) < generics.types.len());
-                let def_id = generics.types[data.idx as usize].def_id;
+                let mut i = data.idx as usize;
+                if !generics.has_self || i > 0 {
+                    i -= generics.regions.len();
+                }
+                let def_id = generics.types[i].def_id;
                 let node_id = self.tcx().map.as_local_node_id(def_id).unwrap();
                 match self.terms_cx.inferred_map.get(&node_id) {
                     Some(&index) => {
@@ -449,7 +446,7 @@ fn add_constraints_from_substs(&mut self,
 
         for p in type_param_defs {
             let variance_decl =
-                self.declared_variance(p.def_id, def_id, TypeParam, p.index as usize);
+                self.declared_variance(p.def_id, def_id, p.index as usize);
             let variance_i = self.xform(variance, variance_decl);
             let substs_ty = substs.type_for_def(p);
             debug!("add_constraints_from_substs: variance_decl={:?} variance_i={:?}",
@@ -459,7 +456,7 @@ fn add_constraints_from_substs(&mut self,
 
         for p in region_param_defs {
             let variance_decl =
-                self.declared_variance(p.def_id, def_id, RegionParam, p.index as usize);
+                self.declared_variance(p.def_id, def_id, p.index as usize);
             let variance_i = self.xform(variance, variance_decl);
             let substs_r = substs.region_for_def(p);
             self.add_constraints_from_region(generics, substs_r, variance_i);
@@ -483,13 +480,13 @@ fn add_constraints_from_sig(&mut self,
     /// context with ambient variance `variance`
     fn add_constraints_from_region(&mut self,
                                    generics: &ty::Generics<'tcx>,
-                                   region: ty::Region,
+                                   region: &'tcx ty::Region,
                                    variance: VarianceTermPtr<'a>) {
-        match region {
+        match *region {
             ty::ReEarlyBound(ref data) => {
                 assert_eq!(generics.parent, None);
-                assert!((data.index as usize) < generics.regions.len());
-                let def_id = generics.regions[data.index as usize].def_id;
+                let i = data.index as usize - generics.has_self as usize;
+                let def_id = generics.regions[i].def_id;
                 let node_id = self.tcx().map.as_local_node_id(def_id).unwrap();
                 if self.is_to_be_inferred(node_id) {
                     let index = self.inferred_index(node_id);
index d3b63119bcb324fad45016f1ea72e4b2ea98eae7..82b63d0cc09377fd015c9bbeb9d6a755ed4689b6 100644 (file)
@@ -21,7 +21,6 @@
 use super::constraints::*;
 use super::terms::*;
 use super::terms::VarianceTerm::*;
-use super::terms::ParamKind::*;
 use super::xform::*;
 
 struct SolveContext<'a, 'tcx: 'a> {
@@ -109,24 +108,16 @@ fn write(&self) {
         while index < num_inferred {
             let item_id = inferred_infos[index].item_id;
 
-            let mut item_variances = ty::ItemVariances::empty();
+            let mut item_variances = vec![];
 
             while index < num_inferred && inferred_infos[index].item_id == item_id {
                 let info = &inferred_infos[index];
                 let variance = solutions[index];
-                debug!("Index {} Info {} / {:?} Variance {:?}",
-                       index, info.index, info.kind, variance);
-                match info.kind {
-                    TypeParam => {
-                        assert_eq!(item_variances.types.len(), info.index);
-                        item_variances.types.push(variance);
-                    }
-                    RegionParam => {
-                        assert_eq!(item_variances.regions.len(), info.index);
-                        item_variances.regions.push(variance);
-                    }
-                }
+                debug!("Index {} Info {} Variance {:?}",
+                       index, info.index, variance);
 
+                assert_eq!(item_variances.len(), info.index);
+                item_variances.push(variance);
                 index += 1;
             }
 
index d30cbc8f117cf03c98668f4409789aad0e660e91..c0b53787177d5ff9e0e175506de66d525aa3f93d 100644 (file)
@@ -31,7 +31,6 @@
 use util::nodemap::NodeMap;
 
 use self::VarianceTerm::*;
-use self::ParamKind::*;
 
 pub type VarianceTermPtr<'a> = &'a VarianceTerm<'a>;
 
@@ -61,7 +60,7 @@ pub struct TermsContext<'a, 'tcx: 'a> {
     pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
     pub arena: &'a TypedArena<VarianceTerm<'a>>,
 
-    pub empty_variances: Rc<ty::ItemVariances>,
+    pub empty_variances: Rc<Vec<ty::Variance>>,
 
     // For marker types, UnsafeCell, and other lang items where
     // variance is hardcoded, records the item-id and the hardcoded
@@ -76,15 +75,8 @@ pub struct TermsContext<'a, 'tcx: 'a> {
     pub inferred_infos: Vec<InferredInfo<'a>> ,
 }
 
-#[derive(Copy, Clone, Debug, PartialEq)]
-pub enum ParamKind {
-    TypeParam,
-    RegionParam,
-}
-
 pub struct InferredInfo<'a> {
     pub item_id: ast::NodeId,
-    pub kind: ParamKind,
     pub index: usize,
     pub param_id: ast::NodeId,
     pub term: VarianceTermPtr<'a>,
@@ -110,7 +102,7 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>(
 
         // cache and share the variance struct used for items with
         // no type/region parameters
-        empty_variances: Rc::new(ty::ItemVariances::empty())
+        empty_variances: Rc::new(vec![])
     };
 
     // See README.md for a discussion on dep-graph management.
@@ -162,17 +154,19 @@ fn add_inferreds_for_item(&mut self,
 
         let inferreds_on_entry = self.num_inferred();
 
+        if has_self {
+            self.add_inferred(item_id, 0, item_id);
+        }
+
         for (i, p) in generics.lifetimes.iter().enumerate() {
             let id = p.lifetime.id;
-            self.add_inferred(item_id, RegionParam, i, id);
+            let i = has_self as usize + i;
+            self.add_inferred(item_id, i, id);
         }
 
-        if has_self {
-            self.add_inferred(item_id, TypeParam, 0, item_id);
-        }
         for (i, p) in generics.ty_params.iter().enumerate() {
-            let i = has_self as usize + i;
-            self.add_inferred(item_id, TypeParam, i, p.id);
+            let i = has_self as usize + generics.lifetimes.len() + i;
+            self.add_inferred(item_id, i, p.id);
         }
 
         // If this item has no type or lifetime parameters,
@@ -194,14 +188,12 @@ fn add_inferreds_for_item(&mut self,
 
     fn add_inferred(&mut self,
                     item_id: ast::NodeId,
-                    kind: ParamKind,
                     index: usize,
                     param_id: ast::NodeId) {
         let inf_index = InferredIndex(self.inferred_infos.len());
         let term = self.arena.alloc(InferredTerm(inf_index));
         let initial_variance = self.pick_initial_variance(item_id, index);
         self.inferred_infos.push(InferredInfo { item_id: item_id,
-                                                kind: kind,
                                                 index: index,
                                                 param_id: param_id,
                                                 term: term,
@@ -211,13 +203,12 @@ fn add_inferred(&mut self,
 
         debug!("add_inferred(item_path={}, \
                 item_id={}, \
-                kind={:?}, \
                 index={}, \
                 param_id={}, \
                 inf_index={:?}, \
                 initial_variance={:?})",
                self.tcx.item_path_str(self.tcx.map.local_def_id(item_id)),
-               item_id, kind, index, param_id, inf_index,
+               item_id, index, param_id, inf_index,
                initial_variance);
     }
 
index 39b1a04e98e6985a7bdf400a46df9b9bd0ecc4a3..c8620254b6f42c6696c0adb0568957bf53dccf27 100644 (file)
@@ -12,7 +12,6 @@
 //! that clean them.
 
 pub use self::Type::*;
-pub use self::PrimitiveType::*;
 pub use self::TypeKind::*;
 pub use self::VariantKind::*;
 pub use self::Mutability::*;
@@ -287,34 +286,34 @@ pub fn is_crate(&self) -> bool {
         }
     }
     pub fn is_mod(&self) -> bool {
-        ItemType::from_item(self) == ItemType::Module
+        ItemType::from(self) == ItemType::Module
     }
     pub fn is_trait(&self) -> bool {
-        ItemType::from_item(self) == ItemType::Trait
+        ItemType::from(self) == ItemType::Trait
     }
     pub fn is_struct(&self) -> bool {
-        ItemType::from_item(self) == ItemType::Struct
+        ItemType::from(self) == ItemType::Struct
     }
     pub fn is_enum(&self) -> bool {
-        ItemType::from_item(self) == ItemType::Module
+        ItemType::from(self) == ItemType::Module
     }
     pub fn is_fn(&self) -> bool {
-        ItemType::from_item(self) == ItemType::Function
+        ItemType::from(self) == ItemType::Function
     }
     pub fn is_associated_type(&self) -> bool {
-        ItemType::from_item(self) == ItemType::AssociatedType
+        ItemType::from(self) == ItemType::AssociatedType
     }
     pub fn is_associated_const(&self) -> bool {
-        ItemType::from_item(self) == ItemType::AssociatedConst
+        ItemType::from(self) == ItemType::AssociatedConst
     }
     pub fn is_method(&self) -> bool {
-        ItemType::from_item(self) == ItemType::Method
+        ItemType::from(self) == ItemType::Method
     }
     pub fn is_ty_method(&self) -> bool {
-        ItemType::from_item(self) == ItemType::TyMethod
+        ItemType::from(self) == ItemType::TyMethod
     }
     pub fn is_primitive(&self) -> bool {
-        ItemType::from_item(self) == ItemType::Primitive
+        ItemType::from(self) == ItemType::Primitive
     }
     pub fn is_stripped(&self) -> bool {
         match self.inner { StrippedItem(..) => true, _ => false }
@@ -380,6 +379,23 @@ pub enum ItemEnum {
     StrippedItem(Box<ItemEnum>),
 }
 
+impl ItemEnum {
+    pub fn generics(&self) -> Option<&Generics> {
+        Some(match *self {
+            ItemEnum::StructItem(ref s) => &s.generics,
+            ItemEnum::EnumItem(ref e) => &e.generics,
+            ItemEnum::FunctionItem(ref f) => &f.generics,
+            ItemEnum::TypedefItem(ref t, _) => &t.generics,
+            ItemEnum::TraitItem(ref t) => &t.generics,
+            ItemEnum::ImplItem(ref i) => &i.generics,
+            ItemEnum::TyMethodItem(ref i) => &i.generics,
+            ItemEnum::MethodItem(ref i) => &i.generics,
+            ItemEnum::ForeignFunctionItem(ref f) => &f.generics,
+            _ => return None,
+        })
+    }
+}
+
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Module {
     pub items: Vec<Item>,
@@ -626,8 +642,8 @@ fn clean(&self, cx: &DocContext) -> TyParamBound {
 
 fn external_path_params(cx: &DocContext, trait_did: Option<DefId>, has_self: bool,
                         bindings: Vec<TypeBinding>, substs: &Substs) -> PathParameters {
-    let lifetimes = substs.regions.iter().filter_map(|v| v.clean(cx)).collect();
-    let types = substs.types[has_self as usize..].to_vec();
+    let lifetimes = substs.regions().filter_map(|v| v.clean(cx)).collect();
+    let types = substs.types().skip(has_self as usize).collect::<Vec<_>>();
 
     match (trait_did, cx.tcx_opt()) {
         // Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C
@@ -721,12 +737,11 @@ fn clean(&self, cx: &DocContext) -> TyParamBound {
         let path = external_path(cx, &tcx.item_name(self.def_id).as_str(),
                                  Some(self.def_id), true, vec![], self.substs);
 
-        debug!("ty::TraitRef\n  substs.types: {:?}\n",
-               &self.input_types()[1..]);
+        debug!("ty::TraitRef\n  subst: {:?}\n", self.substs);
 
         // collect any late bound regions
         let mut late_bounds = vec![];
-        for &ty_s in &self.input_types()[1..] {
+        for ty_s in self.input_types().skip(1) {
             if let ty::TyTuple(ts) = ty_s.sty {
                 for &ty_s in ts {
                     if let ty::TyRef(ref reg, _) = ty_s.sty {
@@ -759,9 +774,9 @@ fn clean(&self, cx: &DocContext) -> TyParamBound {
 impl<'tcx> Clean<Option<Vec<TyParamBound>>> for Substs<'tcx> {
     fn clean(&self, cx: &DocContext) -> Option<Vec<TyParamBound>> {
         let mut v = Vec::new();
-        v.extend(self.regions.iter().filter_map(|r| r.clean(cx))
+        v.extend(self.regions().filter_map(|r| r.clean(cx))
                      .map(RegionBound));
-        v.extend(self.types.iter().map(|t| TraitBound(PolyTrait {
+        v.extend(self.types().map(|t| TraitBound(PolyTrait {
             trait_: t.clean(cx),
             lifetimes: vec![]
         }, hir::TraitBoundModifier::None)));
@@ -806,7 +821,7 @@ fn clean(&self, _: &DocContext) -> Lifetime {
     }
 }
 
-impl Clean<Lifetime> for ty::RegionParameterDef {
+impl<'tcx> Clean<Lifetime> for ty::RegionParameterDef<'tcx> {
     fn clean(&self, _: &DocContext) -> Lifetime {
         Lifetime(self.name.to_string())
     }
@@ -898,7 +913,7 @@ fn clean(&self, cx: &DocContext) -> WherePredicate {
     }
 }
 
-impl Clean<WherePredicate> for ty::OutlivesPredicate<ty::Region, ty::Region> {
+impl<'tcx> Clean<WherePredicate> for ty::OutlivesPredicate<&'tcx ty::Region, &'tcx ty::Region> {
     fn clean(&self, cx: &DocContext) -> WherePredicate {
         let ty::OutlivesPredicate(ref a, ref b) = *self;
         WherePredicate::RegionPredicate {
@@ -908,7 +923,7 @@ fn clean(&self, cx: &DocContext) -> WherePredicate {
     }
 }
 
-impl<'tcx> Clean<WherePredicate> for ty::OutlivesPredicate<ty::Ty<'tcx>, ty::Region> {
+impl<'tcx> Clean<WherePredicate> for ty::OutlivesPredicate<ty::Ty<'tcx>, &'tcx ty::Region> {
     fn clean(&self, cx: &DocContext) -> WherePredicate {
         let ty::OutlivesPredicate(ref ty, ref lt) = *self;
 
@@ -1469,8 +1484,8 @@ pub enum PrimitiveType {
     Str,
     Slice,
     Array,
-    PrimitiveTuple,
-    PrimitiveRawPointer,
+    Tuple,
+    RawPointer,
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Copy, Debug)]
@@ -1500,12 +1515,12 @@ impl Type {
     pub fn primitive_type(&self) -> Option<PrimitiveType> {
         match *self {
             Primitive(p) | BorrowedRef { type_: box Primitive(p), ..} => Some(p),
-            Vector(..) | BorrowedRef{ type_: box Vector(..), ..  } => Some(Slice),
+            Vector(..) | BorrowedRef{ type_: box Vector(..), ..  } => Some(PrimitiveType::Slice),
             FixedVector(..) | BorrowedRef { type_: box FixedVector(..), .. } => {
-                Some(Array)
+                Some(PrimitiveType::Array)
             }
-            Tuple(..) => Some(PrimitiveTuple),
-            RawPointer(..) => Some(PrimitiveRawPointer),
+            Tuple(..) => Some(PrimitiveType::Tuple),
+            RawPointer(..) => Some(PrimitiveType::RawPointer),
             _ => None,
         }
     }
@@ -1530,25 +1545,25 @@ fn def_id(&self) -> Option<DefId> {
 impl PrimitiveType {
     fn from_str(s: &str) -> Option<PrimitiveType> {
         match s {
-            "isize" => Some(Isize),
-            "i8" => Some(I8),
-            "i16" => Some(I16),
-            "i32" => Some(I32),
-            "i64" => Some(I64),
-            "usize" => Some(Usize),
-            "u8" => Some(U8),
-            "u16" => Some(U16),
-            "u32" => Some(U32),
-            "u64" => Some(U64),
-            "bool" => Some(Bool),
-            "char" => Some(Char),
-            "str" => Some(Str),
-            "f32" => Some(F32),
-            "f64" => Some(F64),
-            "array" => Some(Array),
-            "slice" => Some(Slice),
-            "tuple" => Some(PrimitiveTuple),
-            "pointer" => Some(PrimitiveRawPointer),
+            "isize" => Some(PrimitiveType::Isize),
+            "i8" => Some(PrimitiveType::I8),
+            "i16" => Some(PrimitiveType::I16),
+            "i32" => Some(PrimitiveType::I32),
+            "i64" => Some(PrimitiveType::I64),
+            "usize" => Some(PrimitiveType::Usize),
+            "u8" => Some(PrimitiveType::U8),
+            "u16" => Some(PrimitiveType::U16),
+            "u32" => Some(PrimitiveType::U32),
+            "u64" => Some(PrimitiveType::U64),
+            "bool" => Some(PrimitiveType::Bool),
+            "char" => Some(PrimitiveType::Char),
+            "str" => Some(PrimitiveType::Str),
+            "f32" => Some(PrimitiveType::F32),
+            "f64" => Some(PrimitiveType::F64),
+            "array" => Some(PrimitiveType::Array),
+            "slice" => Some(PrimitiveType::Slice),
+            "tuple" => Some(PrimitiveType::Tuple),
+            "pointer" => Some(PrimitiveType::RawPointer),
             _ => None,
         }
     }
@@ -1568,25 +1583,25 @@ fn find(attrs: &[Attribute]) -> Option<PrimitiveType> {
 
     pub fn to_string(&self) -> &'static str {
         match *self {
-            Isize => "isize",
-            I8 => "i8",
-            I16 => "i16",
-            I32 => "i32",
-            I64 => "i64",
-            Usize => "usize",
-            U8 => "u8",
-            U16 => "u16",
-            U32 => "u32",
-            U64 => "u64",
-            F32 => "f32",
-            F64 => "f64",
-            Str => "str",
-            Bool => "bool",
-            Char => "char",
-            Array => "array",
-            Slice => "slice",
-            PrimitiveTuple => "tuple",
-            PrimitiveRawPointer => "pointer",
+            PrimitiveType::Isize => "isize",
+            PrimitiveType::I8 => "i8",
+            PrimitiveType::I16 => "i16",
+            PrimitiveType::I32 => "i32",
+            PrimitiveType::I64 => "i64",
+            PrimitiveType::Usize => "usize",
+            PrimitiveType::U8 => "u8",
+            PrimitiveType::U16 => "u16",
+            PrimitiveType::U32 => "u32",
+            PrimitiveType::U64 => "u64",
+            PrimitiveType::F32 => "f32",
+            PrimitiveType::F64 => "f64",
+            PrimitiveType::Str => "str",
+            PrimitiveType::Bool => "bool",
+            PrimitiveType::Char => "char",
+            PrimitiveType::Array => "array",
+            PrimitiveType::Slice => "slice",
+            PrimitiveType::Tuple => "tuple",
+            PrimitiveType::RawPointer => "pointer",
         }
     }
 
@@ -1603,6 +1618,38 @@ pub fn to_def_index(&self) -> DefIndex {
     }
 }
 
+impl From<ast::IntTy> for PrimitiveType {
+    fn from(int_ty: ast::IntTy) -> PrimitiveType {
+        match int_ty {
+            ast::IntTy::Is => PrimitiveType::Isize,
+            ast::IntTy::I8 => PrimitiveType::I8,
+            ast::IntTy::I16 => PrimitiveType::I16,
+            ast::IntTy::I32 => PrimitiveType::I32,
+            ast::IntTy::I64 => PrimitiveType::I64,
+        }
+    }
+}
+
+impl From<ast::UintTy> for PrimitiveType {
+    fn from(uint_ty: ast::UintTy) -> PrimitiveType {
+        match uint_ty {
+            ast::UintTy::Us => PrimitiveType::Usize,
+            ast::UintTy::U8 => PrimitiveType::U8,
+            ast::UintTy::U16 => PrimitiveType::U16,
+            ast::UintTy::U32 => PrimitiveType::U32,
+            ast::UintTy::U64 => PrimitiveType::U64,
+        }
+    }
+}
+
+impl From<ast::FloatTy> for PrimitiveType {
+    fn from(float_ty: ast::FloatTy) -> PrimitiveType {
+        match float_ty {
+            ast::FloatTy::F32 => PrimitiveType::F32,
+            ast::FloatTy::F64 => PrimitiveType::F64,
+        }
+    }
+}
 
 // Poor man's type parameter substitution at HIR level.
 // Used to replace private type aliases in public signatures with their aliased types.
@@ -1754,21 +1801,12 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
     fn clean(&self, cx: &DocContext) -> Type {
         match self.sty {
             ty::TyNever => Never,
-            ty::TyBool => Primitive(Bool),
-            ty::TyChar => Primitive(Char),
-            ty::TyInt(ast::IntTy::Is) => Primitive(Isize),
-            ty::TyInt(ast::IntTy::I8) => Primitive(I8),
-            ty::TyInt(ast::IntTy::I16) => Primitive(I16),
-            ty::TyInt(ast::IntTy::I32) => Primitive(I32),
-            ty::TyInt(ast::IntTy::I64) => Primitive(I64),
-            ty::TyUint(ast::UintTy::Us) => Primitive(Usize),
-            ty::TyUint(ast::UintTy::U8) => Primitive(U8),
-            ty::TyUint(ast::UintTy::U16) => Primitive(U16),
-            ty::TyUint(ast::UintTy::U32) => Primitive(U32),
-            ty::TyUint(ast::UintTy::U64) => Primitive(U64),
-            ty::TyFloat(ast::FloatTy::F32) => Primitive(F32),
-            ty::TyFloat(ast::FloatTy::F64) => Primitive(F64),
-            ty::TyStr => Primitive(Str),
+            ty::TyBool => Primitive(PrimitiveType::Bool),
+            ty::TyChar => Primitive(PrimitiveType::Char),
+            ty::TyInt(int_ty) => Primitive(int_ty.into()),
+            ty::TyUint(uint_ty) => Primitive(uint_ty.into()),
+            ty::TyFloat(float_ty) => Primitive(float_ty.into()),
+            ty::TyStr => Primitive(PrimitiveType::Str),
             ty::TyBox(t) => {
                 let box_did = cx.tcx_opt().and_then(|tcx| {
                     tcx.lang_items.owned_box()
@@ -2421,25 +2459,25 @@ fn build_deref_target_impls(cx: &DocContext,
             }
         };
         let did = match primitive {
-            Isize => tcx.lang_items.isize_impl(),
-            I8 => tcx.lang_items.i8_impl(),
-            I16 => tcx.lang_items.i16_impl(),
-            I32 => tcx.lang_items.i32_impl(),
-            I64 => tcx.lang_items.i64_impl(),
-            Usize => tcx.lang_items.usize_impl(),
-            U8 => tcx.lang_items.u8_impl(),
-            U16 => tcx.lang_items.u16_impl(),
-            U32 => tcx.lang_items.u32_impl(),
-            U64 => tcx.lang_items.u64_impl(),
-            F32 => tcx.lang_items.f32_impl(),
-            F64 => tcx.lang_items.f64_impl(),
-            Char => tcx.lang_items.char_impl(),
-            Bool => None,
-            Str => tcx.lang_items.str_impl(),
-            Slice => tcx.lang_items.slice_impl(),
-            Array => tcx.lang_items.slice_impl(),
-            PrimitiveTuple => None,
-            PrimitiveRawPointer => tcx.lang_items.const_ptr_impl(),
+            PrimitiveType::Isize => tcx.lang_items.isize_impl(),
+            PrimitiveType::I8 => tcx.lang_items.i8_impl(),
+            PrimitiveType::I16 => tcx.lang_items.i16_impl(),
+            PrimitiveType::I32 => tcx.lang_items.i32_impl(),
+            PrimitiveType::I64 => tcx.lang_items.i64_impl(),
+            PrimitiveType::Usize => tcx.lang_items.usize_impl(),
+            PrimitiveType::U8 => tcx.lang_items.u8_impl(),
+            PrimitiveType::U16 => tcx.lang_items.u16_impl(),
+            PrimitiveType::U32 => tcx.lang_items.u32_impl(),
+            PrimitiveType::U64 => tcx.lang_items.u64_impl(),
+            PrimitiveType::F32 => tcx.lang_items.f32_impl(),
+            PrimitiveType::F64 => tcx.lang_items.f64_impl(),
+            PrimitiveType::Char => tcx.lang_items.char_impl(),
+            PrimitiveType::Bool => None,
+            PrimitiveType::Str => tcx.lang_items.str_impl(),
+            PrimitiveType::Slice => tcx.lang_items.slice_impl(),
+            PrimitiveType::Array => tcx.lang_items.slice_impl(),
+            PrimitiveType::Tuple => None,
+            PrimitiveType::RawPointer => tcx.lang_items.const_ptr_impl(),
         };
         if let Some(did) = did {
             if !did.is_local() {
@@ -2722,21 +2760,12 @@ fn resolve_type(cx: &DocContext,
 
     let is_generic = match def {
         Def::PrimTy(p) => match p {
-            hir::TyStr => return Primitive(Str),
-            hir::TyBool => return Primitive(Bool),
-            hir::TyChar => return Primitive(Char),
-            hir::TyInt(ast::IntTy::Is) => return Primitive(Isize),
-            hir::TyInt(ast::IntTy::I8) => return Primitive(I8),
-            hir::TyInt(ast::IntTy::I16) => return Primitive(I16),
-            hir::TyInt(ast::IntTy::I32) => return Primitive(I32),
-            hir::TyInt(ast::IntTy::I64) => return Primitive(I64),
-            hir::TyUint(ast::UintTy::Us) => return Primitive(Usize),
-            hir::TyUint(ast::UintTy::U8) => return Primitive(U8),
-            hir::TyUint(ast::UintTy::U16) => return Primitive(U16),
-            hir::TyUint(ast::UintTy::U32) => return Primitive(U32),
-            hir::TyUint(ast::UintTy::U64) => return Primitive(U64),
-            hir::TyFloat(ast::FloatTy::F32) => return Primitive(F32),
-            hir::TyFloat(ast::FloatTy::F64) => return Primitive(F64),
+            hir::TyStr => return Primitive(PrimitiveType::Str),
+            hir::TyBool => return Primitive(PrimitiveType::Bool),
+            hir::TyChar => return Primitive(PrimitiveType::Char),
+            hir::TyInt(int_ty) => return Primitive(int_ty.into()),
+            hir::TyUint(uint_ty) => return Primitive(uint_ty.into()),
+            hir::TyFloat(float_ty) => return Primitive(float_ty.into()),
         },
         Def::SelfTy(..) if path.segments.len() == 1 => {
             return Generic(keywords::SelfType.name().to_string());
index f8b852074dd2b1a3180107e1c8523de9cb7eb6db..65992798ab0995382ef32a4457c53e42347c00a6 100644 (file)
@@ -23,7 +23,7 @@
 use syntax::abi::Abi;
 use rustc::hir;
 
-use clean;
+use clean::{self, PrimitiveType};
 use core::DocAccessLevels;
 use html::item_type::ItemType;
 use html::escape::Escape;
@@ -468,39 +468,39 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             }
             clean::Tuple(ref typs) => {
                 match &typs[..] {
-                    &[] => primitive_link(f, clean::PrimitiveTuple, "()"),
+                    &[] => primitive_link(f, PrimitiveType::Tuple, "()"),
                     &[ref one] => {
-                        primitive_link(f, clean::PrimitiveTuple, "(")?;
+                        primitive_link(f, PrimitiveType::Tuple, "(")?;
                         write!(f, "{},", one)?;
-                        primitive_link(f, clean::PrimitiveTuple, ")")
+                        primitive_link(f, PrimitiveType::Tuple, ")")
                     }
                     many => {
-                        primitive_link(f, clean::PrimitiveTuple, "(")?;
+                        primitive_link(f, PrimitiveType::Tuple, "(")?;
                         write!(f, "{}", CommaSep(&many))?;
-                        primitive_link(f, clean::PrimitiveTuple, ")")
+                        primitive_link(f, PrimitiveType::Tuple, ")")
                     }
                 }
             }
             clean::Vector(ref t) => {
-                primitive_link(f, clean::Slice, &format!("["))?;
+                primitive_link(f, PrimitiveType::Slice, &format!("["))?;
                 write!(f, "{}", t)?;
-                primitive_link(f, clean::Slice, &format!("]"))
+                primitive_link(f, PrimitiveType::Slice, &format!("]"))
             }
             clean::FixedVector(ref t, ref s) => {
-                primitive_link(f, clean::PrimitiveType::Array, "[")?;
+                primitive_link(f, PrimitiveType::Array, "[")?;
                 write!(f, "{}", t)?;
-                primitive_link(f, clean::PrimitiveType::Array,
+                primitive_link(f, PrimitiveType::Array,
                                &format!("; {}]", Escape(s)))
             }
             clean::Never => f.write_str("!"),
             clean::RawPointer(m, ref t) => {
                 match **t {
                     clean::Generic(_) | clean::ResolvedPath {is_generic: true, ..} => {
-                        primitive_link(f, clean::PrimitiveType::PrimitiveRawPointer,
+                        primitive_link(f, clean::PrimitiveType::RawPointer,
                                        &format!("*{}{}", RawMutableSpace(m), t))
                     }
                     _ => {
-                        primitive_link(f, clean::PrimitiveType::PrimitiveRawPointer,
+                        primitive_link(f, clean::PrimitiveType::RawPointer,
                                        &format!("*{}", RawMutableSpace(m)))?;
                         write!(f, "{}", t)
                     }
@@ -516,12 +516,13 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                     clean::Vector(ref bt) => { // BorrowedRef{ ... Vector(T) } is &[T]
                         match **bt {
                             clean::Generic(_) =>
-                                primitive_link(f, clean::Slice,
+                                primitive_link(f, PrimitiveType::Slice,
                                     &format!("&amp;{}{}[{}]", lt, m, **bt)),
                             _ => {
-                                primitive_link(f, clean::Slice, &format!("&amp;{}{}[", lt, m))?;
+                                primitive_link(f, PrimitiveType::Slice,
+                                               &format!("&amp;{}{}[", lt, m))?;
                                 write!(f, "{}", **bt)?;
-                                primitive_link(f, clean::Slice, "]")
+                                primitive_link(f, PrimitiveType::Slice, "]")
                             }
                         }
                     }
index 6b462a76f04ed4a7dc03a31622b1ea02cf0d68eb..be192179284676b9b76fa40162cf22c4ef8ffc31 100644 (file)
@@ -50,8 +50,8 @@ pub enum NameSpace {
     Macro,
 }
 
-impl ItemType {
-    pub fn from_item(item: &clean::Item) -> ItemType {
+impl<'a> From<&'a clean::Item> for ItemType {
+    fn from(item: &'a clean::Item) -> ItemType {
         let inner = match item.inner {
             clean::StrippedItem(box ref item) => item,
             ref inner@_ => inner,
@@ -83,8 +83,10 @@ pub fn from_item(item: &clean::Item) -> ItemType {
             clean::StrippedItem(..)        => unreachable!(),
         }
     }
+}
 
-    pub fn from_type_kind(kind: clean::TypeKind) -> ItemType {
+impl From<clean::TypeKind> for ItemType {
+    fn from(kind: clean::TypeKind) -> ItemType {
         match kind {
             clean::TypeStruct   => ItemType::Struct,
             clean::TypeEnum     => ItemType::Enum,
@@ -97,7 +99,9 @@ pub fn from_type_kind(kind: clean::TypeKind) -> ItemType {
             clean::TypeTypedef  => ItemType::Typedef,
         }
     }
+}
 
+impl ItemType {
     pub fn css_class(&self) -> &'static str {
         match *self {
             ItemType::Module          => "mod",
index e02cfb96dddf17a0170f61008e82455f03480f4a..6993f85c3d9a47f1a0d39697f0e04191b760a522 100644 (file)
@@ -509,7 +509,7 @@ pub fn run(mut krate: clean::Crate,
     } = renderinfo;
 
     let external_paths = external_paths.into_iter()
-        .map(|(k, (v, t))| (k, (v, ItemType::from_type_kind(t))))
+        .map(|(k, (v, t))| (k, (v, ItemType::from(t))))
         .collect();
 
     let mut cache = Cache {
@@ -833,7 +833,7 @@ fn mkdir(path: &Path) -> io::Result<()> {
 
 /// Returns a documentation-level item type from the item.
 fn item_type(item: &clean::Item) -> ItemType {
-    ItemType::from_item(item)
+    ItemType::from(item)
 }
 
 /// Takes a path to a source file and cleans the path to it. This canonicalizes
@@ -997,17 +997,8 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
 
         // Register any generics to their corresponding string. This is used
         // when pretty-printing types
-        match item.inner {
-            clean::StructItem(ref s)          => self.generics(&s.generics),
-            clean::EnumItem(ref e)            => self.generics(&e.generics),
-            clean::FunctionItem(ref f)        => self.generics(&f.generics),
-            clean::TypedefItem(ref t, _)      => self.generics(&t.generics),
-            clean::TraitItem(ref t)           => self.generics(&t.generics),
-            clean::ImplItem(ref i)            => self.generics(&i.generics),
-            clean::TyMethodItem(ref i)        => self.generics(&i.generics),
-            clean::MethodItem(ref i)          => self.generics(&i.generics),
-            clean::ForeignFunctionItem(ref f) => self.generics(&f.generics),
-            _ => {}
+        if let Some(generics) = item.inner.generics() {
+            self.generics(generics);
         }
 
         if !self.seen_mod {
@@ -1362,7 +1353,7 @@ fn item<F>(&mut self, item: clean::Item, mut f: F) -> Result<(), Error> where
         // these modules are recursed into, but not rendered normally
         // (a flag on the context).
         if !self.render_redirect_pages {
-            self.render_redirect_pages = self.maybe_ignore_item(&item);
+            self.render_redirect_pages = maybe_ignore_item(&item);
         }
 
         if item.is_mod() {
@@ -1445,7 +1436,7 @@ fn build_sidebar_items(&self, m: &clean::Module) -> BTreeMap<String, Vec<NameDoc
         // BTreeMap instead of HashMap to get a sorted output
         let mut map = BTreeMap::new();
         for item in &m.items {
-            if self.maybe_ignore_item(item) { continue }
+            if maybe_ignore_item(item) { continue }
 
             let short = item_type(item).css_class();
             let myname = match item.name {
@@ -1462,17 +1453,6 @@ fn build_sidebar_items(&self, m: &clean::Module) -> BTreeMap<String, Vec<NameDoc
         }
         return map;
     }
-
-    fn maybe_ignore_item(&self, it: &clean::Item) -> bool {
-        match it.inner {
-            clean::StrippedItem(..) => true,
-            clean::ModuleItem(ref m) => {
-                it.doc_value().is_none() && m.items.is_empty()
-                                         && it.visibility != Some(clean::Public)
-            },
-            _ => false,
-        }
-    }
 }
 
 impl<'a> Item<'a> {
@@ -1715,7 +1695,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
         if let clean::DefaultImplItem(..) = items[*i].inner {
             return false;
         }
-        !cx.maybe_ignore_item(&items[*i])
+        !maybe_ignore_item(&items[*i])
     }).collect::<Vec<usize>>();
 
     // the order of item types in the listing
@@ -1863,6 +1843,17 @@ fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: usize, idx2: usize) -> Ordering
     Ok(())
 }
 
+fn maybe_ignore_item(it: &clean::Item) -> bool {
+    match it.inner {
+        clean::StrippedItem(..) => true,
+        clean::ModuleItem(ref m) => {
+            it.doc_value().is_none() && m.items.is_empty()
+                                     && it.visibility != Some(clean::Public)
+        },
+        _ => false,
+    }
+}
+
 fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<String> {
     let mut stability = vec![];
 
index 070d7ca1eef0fcb02ffd66e40aaef41046950395..a063b85646809f3e2c89c7b58b24bf9c0699b8c5 100644 (file)
@@ -12,8 +12,6 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use prelude::v1::*;
-
 use mem;
 use ops::Range;
 use iter::FusedIterator;
@@ -454,7 +452,6 @@ impl FusedIterator for EscapeDefault {}
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
     use super::*;
     use char::from_u32;
 
index ba27fafa59a3be2ea7d48dc30cac2b184f59b89a..14da36ca4834e272dce558e8fdb2f49bbe0e44ac 100644 (file)
@@ -2059,8 +2059,6 @@ fn drain<'new>(d: Drain<'static, &'static str, &'static str>)
 
 #[cfg(test)]
 mod test_map {
-    use prelude::v1::*;
-
     use super::HashMap;
     use super::Entry::{Occupied, Vacant};
     use cell::RefCell;
index 96efff86abf17b2d3cac0fad53e102f0e112b9b7..ca5137e957362993a3ca3adc36bf0bab3c8fb91b 100644 (file)
@@ -1067,8 +1067,6 @@ fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { d }
 
 #[cfg(test)]
 mod test_set {
-    use prelude::v1::*;
-
     use super::HashSet;
 
     #[test]
index 753411991abeadab7cb77c8265c857a44e0891fd..7a94c39621808865c513bf52a589a3f22ee87fd6 100644 (file)
@@ -16,8 +16,6 @@
 
 #![stable(feature = "env", since = "1.0.0")]
 
-use prelude::v1::*;
-
 use error::Error;
 use ffi::{OsStr, OsString};
 use fmt;
@@ -950,7 +948,6 @@ mod arch {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
     use super::*;
 
     use iter::repeat;
index 914599271aca279044667c6ff0cb572d0a7d2ce2..ab537f39bf96a268a2c8161ca30e70cce9b0a9ec 100644 (file)
 // reconsider what crate these items belong in.
 
 use any::TypeId;
-use boxed::Box;
 use cell;
 use char;
 use fmt::{self, Debug, Display};
-use marker::{Send, Sync, Reflect};
+use marker::Reflect;
 use mem::transmute;
 use num;
-use raw::TraitObject;
 use str;
-use string::{self, String};
+use string;
 
 /// Base functionality for all errors in Rust.
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -327,11 +325,7 @@ pub fn is<T: Error + 'static>(&self) -> bool {
     pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
         if self.is::<T>() {
             unsafe {
-                // Get the raw representation of the trait object
-                let to: TraitObject = transmute(self);
-
-                // Extract the data pointer
-                Some(&*(to.data as *const T))
+                Some(&*(self as *const Error as *const T))
             }
         } else {
             None
@@ -345,11 +339,7 @@ pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
     pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
         if self.is::<T>() {
             unsafe {
-                // Get the raw representation of the trait object
-                let to: TraitObject = transmute(self);
-
-                // Extract the data pointer
-                Some(&mut *(to.data as *const T as *mut T))
+                Some(&mut *(self as *mut Error as *mut T))
             }
         } else {
             None
@@ -410,13 +400,8 @@ impl Error {
     pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Error>> {
         if self.is::<T>() {
             unsafe {
-                // Get the raw representation of the trait object
-                let raw = Box::into_raw(self);
-                let to: TraitObject =
-                    transmute::<*mut Error, TraitObject>(raw);
-
-                // Extract the data pointer
-                Ok(Box::from_raw(to.data as *mut T))
+                let raw: *mut Error = Box::into_raw(self);
+                Ok(Box::from_raw(raw as *mut T))
             }
         } else {
             Err(self)
@@ -454,7 +439,6 @@ pub fn downcast<T: Error + 'static>(self: Box<Self>)
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
     use super::Error;
     use fmt;
 
index 5dae1a09bf410f7330a3786c8270b32fbc1b90ff..38222c014f61b165d5eec6f1f159f477a158479a 100644 (file)
@@ -9,25 +9,18 @@
 // except according to those terms.
 
 use ascii;
-use borrow::{Cow, ToOwned, Borrow};
-use boxed::Box;
-use convert::{Into, From};
-use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
+use borrow::{Cow, Borrow};
+use cmp::Ordering;
 use error::Error;
 use fmt::{self, Write};
 use io;
-use iter::Iterator;
 use libc;
 use mem;
 use memchr;
 use ops;
-use option::Option::{self, Some, None};
 use os::raw::c_char;
-use result::Result::{self, Ok, Err};
 use slice;
 use str::{self, Utf8Error};
-use string::String;
-use vec::Vec;
 
 /// A type representing an owned C-compatible string
 ///
@@ -700,7 +693,6 @@ fn as_ref(&self) -> &CStr {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
     use super::*;
     use os::raw::c_char;
     use borrow::Cow::{Borrowed, Owned};
index 3d23a9a2383fffceb80da292b0ed4444c57205d5..36cf4ef758d8e40d7d1d512d11ab7176f67d0216 100644 (file)
@@ -8,14 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use borrow::{Borrow, Cow, ToOwned};
+use borrow::{Borrow, Cow};
 use fmt::{self, Debug};
 use mem;
-use string::String;
 use ops;
 use cmp;
 use hash::{Hash, Hasher};
-use vec::Vec;
 
 use sys::os_str::{Buf, Slice};
 use sys_common::{AsInner, IntoInner, FromInner};
index b78db24e44b70784d202a6cff358804e88bda909..f2374e722c1e38013f527544e630a2c6068eb424 100644 (file)
@@ -23,7 +23,6 @@
 use path::{Path, PathBuf};
 use sys::fs as fs_imp;
 use sys_common::{AsInnerMut, FromInner, AsInner, IntoInner};
-use vec::Vec;
 use time::SystemTime;
 
 /// A reference to an open file on the filesystem.
@@ -1677,7 +1676,6 @@ fn as_inner_mut(&mut self) -> &mut fs_imp::DirBuilder {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
     use io::prelude::*;
 
     use fs::{self, File, OpenOptions};
index a92ca95f4ee7ef024925b51f20879d21b14d7f96..a26a932ad2de6c076f9d3d0720ce4135802aebf1 100644 (file)
@@ -10,7 +10,6 @@
 
 //! Buffering wrappers for I/O traits
 
-use prelude::v1::*;
 use io::prelude::*;
 
 use marker::Reflect;
@@ -788,7 +787,6 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
     use io::prelude::*;
     use io::{self, BufReader, BufWriter, LineWriter, SeekFrom};
     use sync::atomic::{AtomicUsize, Ordering};
index 2d780559db1229b5382bdf831ec4b117f93ff43d..1b836b745372f00ed8189a6b4e2b956b1c5e5e12 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
 use io::prelude::*;
 
 use cmp;
@@ -284,7 +283,6 @@ fn flush(&mut self) -> io::Result<()> { Ok(()) }
 mod tests {
     use io::prelude::*;
     use io::{Cursor, SeekFrom};
-    use vec::Vec;
 
     #[test]
     fn test_vec_writer() {
index 5333b0a531eaebd671245e8081c71a4cb72cc028..d90be2e08a9fc6dec04ea0f7a2ca4f03cf486924 100644 (file)
@@ -8,12 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use boxed::Box;
-use convert::Into;
 use error;
 use fmt;
-use marker::{Send, Sync};
-use option::Option::{self, Some, None};
 use result;
 use sys;
 
@@ -522,7 +518,6 @@ fn _is_sync_send<T: Sync+Send>() {}
 
 #[cfg(test)]
 mod test {
-    use prelude::v1::*;
     use super::{Error, ErrorKind};
     use error;
     use fmt;
index 317993815630b93fa698649c422d7ffa4eed0093..cd05e6b5de9d25262a13d6d16a943967c86bd3f5 100644 (file)
@@ -8,13 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use boxed::Box;
 use cmp;
 use io::{self, SeekFrom, Read, Write, Seek, BufRead, Error, ErrorKind};
 use fmt;
 use mem;
-use string::String;
-use vec::Vec;
 
 // =============================================================================
 // Forwarding implementations
@@ -228,7 +225,6 @@ fn flush(&mut self) -> io::Result<()> { Ok(()) }
 #[cfg(test)]
 mod tests {
     use io::prelude::*;
-    use vec::Vec;
     use test;
 
     #[bench]
index 11551601207506b331be7192d51836f5a18454a3..ce205c3b11ca5ee14542e5c208189320152d20c1 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
-
 use cell::Cell;
 use ptr;
 use sync::Arc;
index 307d014fd68c6a264f748ce6e02721ce0cb0bf41..1053792cd439bc4ef414f507a66973451f4ec51d 100644 (file)
 use rustc_unicode::str as core_str;
 use error as std_error;
 use fmt;
-use iter::{Iterator};
-use marker::Sized;
-use ops::{Drop, FnOnce};
-use option::Option::{self, Some, None};
-use result::Result::{Ok, Err};
 use result;
-use string::String;
 use str;
-use vec::Vec;
 use memchr;
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1734,7 +1727,6 @@ fn next(&mut self) -> Option<Result<String>> {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
     use io::prelude::*;
     use io;
     use super::Cursor;
index b8b66a58359e7013d135713767a4936c1a3d8c0d..9a782e95f6e5f994fd2cabe77cd59512a99ef90f 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
 use io::prelude::*;
 
 use cell::{RefCell, BorrowState};
index c8b52fc046769b9ca59986a6ec5e621dee8b9d6b..2c6880281b5e60088b36c6497ba747056b19fab9 100644 (file)
@@ -167,8 +167,6 @@ fn flush(&mut self) -> io::Result<()> { Ok(()) }
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
-
     use io::prelude::*;
     use io::{copy, sink, empty, repeat};
 
index 2b15f3dd9455c5c5cadd9b8faef1195a1ea9ad27..44d1fbfdb70b3419ba6e7dbfcdab6b7830f58773 100644 (file)
 #![feature(optin_builtin_traits)]
 #![feature(panic_unwind)]
 #![feature(placement_in_syntax)]
+#![feature(prelude_import)]
 #![feature(question_mark)]
 #![feature(rand)]
 #![feature(raw)]
 #![allow(unused_features)] // std may use features in a platform-specific way
 #![cfg_attr(not(stage0), deny(warnings))]
 
+#[prelude_import]
+#[allow(unused)]
+use prelude::v1::*;
+
 #[cfg(test)] extern crate test;
 
 // We want to reexport a few macros from core but libcore has already been
index a408b4378e19e6b14cdb0f68478adf628f527dc0..03f55f7ad61864cf3ed90ed794b36e41728873c0 100644 (file)
@@ -209,7 +209,7 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> {
         let end_align = (ptr as usize + len) & (usize_bytes - 1);
         let mut offset;
         if end_align > 0 {
-            offset = len - cmp::min(usize_bytes - end_align, len);
+            offset = if end_align >= len { 0 } else { len - end_align };
             if let Some(index) = text[offset..].iter().rposition(|elt| *elt == x) {
                 return Some(offset + index);
             }
@@ -309,6 +309,17 @@ fn no_match_empty_reversed() {
     fn no_match_reversed() {
         assert_eq!(None, memrchr(b'a', b"xyz"));
     }
+
+    #[test]
+    fn each_alignment_reversed() {
+        let mut data = [1u8; 64];
+        let needle = 2;
+        let pos = 40;
+        data[pos] = needle;
+        for start in 0..16 {
+            assert_eq!(Some(pos - start), memrchr(needle, &data[start..]));
+        }
+    }
 }
 
 #[cfg(test)]
@@ -385,4 +396,15 @@ fn no_match_empty_reversed() {
     fn no_match_reversed() {
         assert_eq!(None, memrchr(b'a', b"xyz"));
     }
+
+    #[test]
+    fn each_alignment() {
+        let mut data = [1u8; 64];
+        let needle = 2;
+        let pos = 40;
+        data[pos] = needle;
+        for start in 0..16 {
+            assert_eq!(Some(pos - start), memchr(needle, &data[start..]));
+        }
+    }
 }
index b93ca8277e636bb7b3b8ff1ed30cd84db1a20ef1..d0b59b42c1798a73a2ca56e75d553849ea5a9672 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
-
 use fmt;
 use hash;
 use io;
@@ -523,7 +521,6 @@ fn to_socket_addrs(&self) -> io::Result<T::Iter> {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
     use net::*;
     use net::test::{tsa, sa6, sa4};
 
index 4c3b993497cf5b160bbe4171e8c5a8a388fa7a91..c6a7a77e68a6b369c4cfd06f33e1cb67d7a95d1a 100644 (file)
@@ -653,7 +653,6 @@ fn from_inner(addr: c::in6_addr) -> Ipv6Addr {
 // Tests for this module
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
     use net::*;
     use net::Ipv6MulticastScope::*;
     use net::test::{tsa, sa6, sa4};
index 11a16b271133be76cbc9ca1c386588a43b091ae6..2a78afa85f7f03ff9ce7cbe7b3ffa59c307ee6fd 100644 (file)
@@ -12,8 +12,6 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use prelude::v1::*;
-
 use io::{self, Error, ErrorKind};
 use sys_common::net as net_imp;
 
index 5851ce7135d2745c08faf78a6c990029db2fdbba..854d87c4cbead7114f36996d18db46c8bf1c4bf9 100644 (file)
@@ -13,8 +13,6 @@
 //! This module is "publicly exported" through the `FromStr` implementations
 //! below.
 
-use prelude::v1::*;
-
 use error::Error;
 use fmt;
 use net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
index 76617f159707dd2233da5ce8ab72b247bf05b84e..dcd3652af876b43d61881ee95f627cb8115d781d 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
 use io::prelude::*;
 
 use fmt;
@@ -438,8 +437,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
-
     use io::ErrorKind;
     use io::prelude::*;
     use net::*;
index 9665fd722872fc54891d84a11e211fd194cc5741..98ac61f6461132d94f320d11ba31b7bb516803c4 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
-
 use env;
 use net::{SocketAddr, SocketAddrV4, SocketAddrV6, Ipv4Addr, Ipv6Addr, ToSocketAddrs};
 use sync::atomic::{AtomicUsize, Ordering};
index 9d0279deb1bcb2bfc33ae32e4a8158c8cdb9d73a..781f026c12c7795e1b2c82fae0506c5b40d8b566 100644 (file)
@@ -355,8 +355,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
-
     use io::ErrorKind;
     use net::*;
     use net::test::{next_test_ip4, next_test_ip6};
index 20804d62dfab663401f07293496b3c4d1066973d..d1c2fc3d3fce9371a3584bf88f07f120834f139c 100644 (file)
@@ -24,9 +24,7 @@
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::num::Wrapping;
 
-#[cfg(test)] use cmp::PartialEq;
 #[cfg(test)] use fmt;
-#[cfg(test)] use marker::Copy;
 #[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem};
 
 /// Helper function for testing numeric operations
@@ -52,7 +50,6 @@ mod tests {
     use u32;
     use u64;
     use usize;
-    use string::ToString;
     use ops::Mul;
 
     #[test]
@@ -287,7 +284,6 @@ fn test_uint_from_str_overflow() {
 mod bench {
     extern crate test;
     use self::test::Bencher;
-    use prelude::v1::*;
 
     #[bench]
     fn bench_pow_function(b: &mut Bencher) {
index 2f67081e0d71093c29625a4de7c292112cca4dad..47f594a9b0c1efe0494e15098d8848f89433a164 100644 (file)
@@ -13,7 +13,6 @@
 #![stable(feature = "std_panic", since = "1.9.0")]
 
 use any::Any;
-use boxed::Box;
 use cell::UnsafeCell;
 use ops::{Deref, DerefMut};
 use panicking;
index 5961fd59699c1b8d0a92341e6c78f69729f0b648..0c10dcbdad6463c613cacaf6d378b5f37c132823 100644 (file)
@@ -17,7 +17,6 @@
 //! * Executing a panic up to doing the actual implementation
 //! * Shims around "try"
 
-use prelude::v1::*;
 use io::prelude::*;
 
 use any::Any;
index bc8fd66a438f588adf640bebb61866e2f7e63c5b..67219b6fd1b9c1479466f8b099d2cdb55d9381b3 100644 (file)
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use ascii::*;
-use borrow::{Borrow, ToOwned, Cow};
+use borrow::{Borrow, Cow};
 use cmp;
 use error::Error;
 use fmt;
 use iter::{self, FusedIterator};
 use mem;
 use ops::{self, Deref};
-use string::String;
-use vec::Vec;
 
 use ffi::{OsStr, OsString};
 
@@ -2152,8 +2150,6 @@ fn description(&self) -> &str { "prefix not found" }
 #[cfg(test)]
 mod tests {
     use super::*;
-    use string::{ToString, String};
-    use vec::Vec;
 
     macro_rules! t(
         ($path:expr, iter: $iter:expr) => (
index 660c098d30bc29d157bfb8888ae6e145482aa152..f0c4443070074aa3318f11605b11ba8abebf8b97 100644 (file)
@@ -12,7 +12,6 @@
 
 #![stable(feature = "process", since = "1.0.0")]
 
-use prelude::v1::*;
 use io::prelude::*;
 
 use ffi::OsStr;
@@ -810,7 +809,6 @@ pub fn exit(code: i32) -> ! {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
     use io::prelude::*;
 
     use io::ErrorKind;
index a3d9e4db7d19a4b0927b5e30356b813c412438d7..e3de1efaa31e3051457741b68523d92c37a3ea53 100644 (file)
@@ -30,7 +30,6 @@
 #[cfg(not(test))]
 #[lang = "start"]
 fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize {
-    use borrow::ToOwned;
     use mem;
     use panic;
     use sys;
index b1267acdee61a177fdd9b9fa8a077d613d58efab..ac0f400379e3cabf3504a10b496426774e2c0659 100644 (file)
@@ -113,8 +113,6 @@ pub fn is_leader(&self) -> bool { self.0 }
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
-
     use sync::{Arc, Barrier};
     use sync::mpsc::{channel, TryRecvError};
     use thread;
index 3c52ebc72f2cb279f187dbfdd1a1c15af580eebe..1f480f6d4a987e09ac6dc429e3f454579472ec11 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
-
 use sync::atomic::{AtomicUsize, Ordering};
 use sync::{mutex, MutexGuard, PoisonError};
 use sys_common::condvar as sys;
@@ -245,8 +243,6 @@ fn drop(&mut self) {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
-
     use sync::mpsc::channel;
     use sync::{Condvar, Mutex, Arc};
     use thread;
index 4a70de0e7d8fccf7bba8b7de64fc53339c1e5ef2..0f9ef6fabb005eb06f6f5fb307fed95c38b6a300 100644 (file)
@@ -13,9 +13,7 @@
 use thread::{self, Thread};
 use sync::atomic::{AtomicBool, Ordering};
 use sync::Arc;
-use marker::{Sync, Send};
 use mem;
-use clone::Clone;
 use time::Instant;
 
 struct Inner {
index d8b8c6a77a26629510b33d4f5b58f5e772bc3e3b..3d9f81413dc734202b1e8a6df174ed35703b2d2b 100644 (file)
@@ -1270,8 +1270,6 @@ fn cause(&self) -> Option<&error::Error> {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
-
     use env;
     use super::*;
     use thread;
@@ -1946,8 +1944,6 @@ fn destroy_upgraded_shared_port_when_sender_still_active() {
 
 #[cfg(test)]
 mod sync_tests {
-    use prelude::v1::*;
-
     use env;
     use thread;
     use super::*;
index 6a6c19cfcc308662bd09240da247fa93a3ef11cf..d926043fbbcd074e37fae9807f07b6a34cbfcce8 100644 (file)
@@ -148,8 +148,6 @@ fn drop(&mut self) {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
-
     use sync::mpsc::channel;
     use super::{Queue, Data, Empty, Inconsistent};
     use sync::Arc;
index 5aa4ce81b8ae43c53c4b9ecf8a19fcae72230106..677544d335e7a6d21df49c81402042a5a85374fc 100644 (file)
@@ -369,8 +369,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 #[cfg(test)]
 #[allow(unused_imports)]
 mod tests {
-    use prelude::v1::*;
-
     use thread;
     use sync::mpsc::*;
 
index 02506e7c2f3d91f7bf173e8e5da5949dec27d4ad..724d7b1be730d59953620950ffa5ca20f55b5172 100644 (file)
@@ -233,8 +233,6 @@ fn drop(&mut self) {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
-
     use sync::Arc;
     use super::Queue;
     use thread;
index 9d13a71ff95ee29098873374f2e50ec7a9274a38..9985daaba8f69a2eac4772cf2c91e11517b0f077 100644 (file)
@@ -36,7 +36,6 @@
 pub use self::Failure::*;
 use self::Blocker::*;
 
-use vec::Vec;
 use core::mem;
 use core::ptr;
 
index 6bc458397f1632282a8946cff69c45d1214e31de..c8ae88c233106461b12dd1f161c1c4af738d1244 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
-
 use cell::UnsafeCell;
 use fmt;
 use marker;
@@ -355,8 +353,6 @@ pub fn guard_poison<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a poison::Fla
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
-
     use sync::mpsc::channel;
     use sync::{Arc, Mutex, Condvar};
     use sync::atomic::{AtomicUsize, Ordering};
index 54c1fe6c5640cebcb7312d0ad67fe8233c316b92..86d2986959c999abee5e10c3761f16f4fa0253fc 100644 (file)
@@ -369,8 +369,6 @@ pub fn poisoned(&self) -> bool {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
-
     use panic;
     use sync::mpsc::channel;
     use thread;
index 65b5686de869ca7fb05f9369a3435753612d5a35..4801bcffd081c69751c652c42e316229acb79a9f 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
-
 use cell::UnsafeCell;
 use fmt;
 use marker;
@@ -385,8 +383,6 @@ fn drop(&mut self) {
 mod tests {
     #![allow(deprecated)] // rand
 
-    use prelude::v1::*;
-
     use rand::{self, Rng};
     use sync::mpsc::channel;
     use thread;
@@ -552,8 +548,6 @@ fn test_rwlock_unsized() {
 
     #[test]
     fn test_rwlock_try_write() {
-        use mem::drop;
-
         let lock = RwLock::new(0isize);
         let read_guard = lock.read().unwrap();
 
index e877391fb8b5629283419cfe5fb6b4fbf9dff82f..fad2c277da417f8f27fa1fe9687e2d949d2929d9 100644 (file)
@@ -21,8 +21,6 @@
 
 #![allow(dead_code)] // different code on OSX/linux/etc
 
-use vec::Vec;
-
 /// One-time global initialization.
 pub unsafe fn init(argc: isize, argv: *const *const u8) { imp::init(argc, argv) }
 
@@ -42,8 +40,6 @@ pub fn clone() -> Option<Vec<Vec<u8>>> { imp::clone() }
           target_os = "solaris",
           target_os = "emscripten"))]
 mod imp {
-    use prelude::v1::*;
-
     use libc::c_char;
     use mem;
     use ffi::CStr;
@@ -91,8 +87,6 @@ fn get_global_ptr() -> *mut Option<Box<Vec<Vec<u8>>>> {
           target_os = "ios",
           target_os = "windows"))]
 mod imp {
-    use vec::Vec;
-
     pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
     }
 
index b2683750d67e2d8c4481103e45ecc2e04bbf0449..ce6fd4cb0754b1cc9297b4a97394b08aebc1356c 100644 (file)
 //! Documentation can be found on the `rt::at_exit` function.
 
 use alloc::boxed::FnBox;
-use boxed::Box;
 use ptr;
 use sys_common::mutex::Mutex;
-use vec::Vec;
 
 type Queue = Vec<Box<FnBox()>>;
 
index 4c23ceb63f287bd4a7c9c5efbc344404ed435d98..c1d1792363d7073cecc8bcc70225db09ff1e7019 100644 (file)
@@ -191,7 +191,6 @@ macro_rules! demangle {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
     use sys_common;
     macro_rules! t { ($a:expr, $b:expr) => ({
         let mut m = Vec::new();
index 7b08852ba51d1fbfa8fa5d451bffcd6f851204df..3cd70eddb858c1d0f8566855ff2fb0aca5fa478c 100644 (file)
@@ -7,7 +7,6 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-use prelude::v1::*;
 use io;
 use io::ErrorKind;
 use io::Read;
@@ -53,7 +52,6 @@ pub unsafe fn read_to_end_uninitialized(r: &mut Read, buf: &mut Vec<u8>) -> io::
 
 #[cfg(test)]
 pub mod test {
-    use prelude::v1::*;
     use path::{Path, PathBuf};
     use env;
     use rand::{self, Rng};
@@ -93,7 +91,6 @@ pub fn tmpdir() -> TempDir {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
     use io::prelude::*;
     use super::*;
     use io;
index a1f3f477b3ab7dfa4f64eadac9847bc8568d4f92..d1ca676510714d1548ae005c08fc4e10d523f90f 100644 (file)
@@ -10,7 +10,6 @@
 
 #![allow(missing_docs)]
 
-use boxed::Box;
 use sync::Once;
 use sys;
 
index 7a2183c522f5b92154b198e55aea3cdc4455a5f4..d1a738770d3893fb66189c036009fd62375984db 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use marker::Sync;
 use sys::mutex as imp;
 
 /// An OS-based mutual exclusion lock.
index 442618c55b337f5dc157db2e81893ff8e481e496..a777cfe35e56d4125a9a565584ae96ebc1fca11a 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
-
 use cmp;
 use ffi::CString;
 use fmt;
@@ -608,8 +606,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
-
     use super::*;
     use collections::HashMap;
 
index 39d4104246732f56d0333aa58aa8ddada075284d..cbdeaad7f6bd3acfbff16c2cb7fa25ab688f904a 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
-
 use fmt;
 use marker;
 use ops::Deref;
@@ -160,7 +158,6 @@ fn drop(&mut self) {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
     use sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
     use cell::RefCell;
     use sync::Arc;
index 16f4f01bf39fe9b058fb03817dac3821dd480b19..3ee160da5fa5b7876ab1a2c957b77c9cc3aa75f8 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
-
 use alloc::boxed::FnBox;
 use libc;
 use sys::stack_overflow;
index 0467c67167bd518d85d7a9fd2c419e17a404e4d3..95d8b6cc9516d2e3e5573863d9287ed65d70e105 100644 (file)
@@ -11,7 +11,6 @@
 #![allow(dead_code)] // stack_guard isn't used right now on all platforms
 
 use cell::RefCell;
-use string::String;
 use thread::Thread;
 use thread::LocalKeyState;
 
index 56885cdd56d99a348a75228e287e64ee3038079b..25a9d5720d9338bfb14ed8dba43bd03edaf36362 100644 (file)
@@ -233,7 +233,6 @@ fn drop(&mut self) {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
     use super::{Key, StaticKey};
 
     fn assert_sync<T: Sync>() {}
index c1b4f8a8c88c501d9dc174c8f7186001a9f37b15..8d357aa78c9e93568b91f508ea373052a523b58d 100644 (file)
@@ -37,9 +37,7 @@
 use ops;
 use slice;
 use str;
-use string::String;
 use sys_common::AsInner;
-use vec::Vec;
 
 const UTF8_REPLACEMENT_CHARACTER: &'static [u8] = b"\xEF\xBF\xBD";
 
@@ -807,7 +805,6 @@ fn make_ascii_lowercase(&mut self) { self.bytes.make_ascii_lowercase() }
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
     use borrow::Cow;
     use super::*;
 
index 825e74cabdebb6b3c4264ad247ed90741fcf8c9a..d59b4fc0b70b8032a961d9123da86e7b5c2276ac 100644 (file)
@@ -14,7 +14,6 @@
 
 use ffi::{OsStr, OsString};
 use mem;
-use prelude::v1::*;
 use sys::os_str::Buf;
 use sys_common::{FromInner, IntoInner, AsInner};
 
index a4564b9543b3430cdd810b87ecf5c5bf65b434c2..3f93fce1935611f236f611d3eb5ed9652617d851 100644 (file)
@@ -14,7 +14,6 @@
 
 use libc;
 
-use prelude::v1::*;
 use ascii;
 use ffi::OsStr;
 use fmt;
@@ -789,7 +788,6 @@ fn into_raw_fd(self) -> RawFd {
 
 #[cfg(test)]
 mod test {
-    use prelude::v1::*;
     use thread;
     use io;
     use io::prelude::*;
index dd70ba2e490ad53e825660e12f5226d8354767e0..5bd92f2eb574d7a85281000626fb72bcd1baf99c 100644 (file)
@@ -12,8 +12,6 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use prelude::v1::*;
-
 use io;
 use os::unix::io::{FromRawFd, RawFd, AsRawFd, IntoRawFd};
 use process;
index b99f4a2eacde563d489fa690b06bbb19fea50f35..b2b1f16f20a9aed7b5542f283718aa43b6f34fe0 100644 (file)
@@ -10,8 +10,6 @@
 
 #![unstable(reason = "not public", issue = "0", feature = "fd")]
 
-use prelude::v1::*;
-
 use io::{self, Read};
 use libc::{self, c_int, size_t, c_void};
 use mem;
index 3b132744f7055ce176e0f0689aca601b53a454c6..e6fe3eb112a6093ea038044132736d8bdb5ef40e 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
 use os::unix::prelude::*;
 
 use ffi::{CString, CStr, OsString, OsStr};
@@ -534,7 +533,6 @@ impl fmt::Debug for File {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         #[cfg(target_os = "linux")]
         fn get_path(fd: c_int) -> Option<PathBuf> {
-            use string::ToString;
             let mut p = PathBuf::from("/proc/self/fd");
             p.push(&fd.to_string());
             readlink(&p).ok()
index 6f1b70acb60bc35c3c9f5dfc0cc60c71403bcf76..3f77abd7f44d8f4f56be637a66781da946f300a6 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
-
 use ffi::CStr;
 use io;
 use libc::{self, c_int, size_t, sockaddr, socklen_t};
index c29e87f91c9a7e247471f2c4749e3264e663d572..e61804efd50f6882d5f6e698e935bd8163f5b569 100644 (file)
@@ -12,7 +12,6 @@
 
 #![allow(unused_imports)] // lots of cfg code here
 
-use prelude::v1::*;
 use os::unix::prelude::*;
 
 use error::Error as StdError;
index d5eea5d1f3be563887c6545c818cae8f372e1663..5a733c0cb87637f7a235782b0bc3a415d60c4aca 100644 (file)
@@ -13,9 +13,7 @@
 
 use borrow::Cow;
 use fmt::{self, Debug};
-use vec::Vec;
 use str;
-use string::String;
 use mem;
 use sys_common::{AsInner, IntoInner};
 
index 010594133387a4602261369cf4b0e89cfb81e642..ffe8032e46055e9f6af9e63491e26d463117a4ab 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
-
 use cmp;
 use io;
 use libc::{self, c_int};
index d68867fb3d2ce9d164466ef0a1164a1f8fb008c9..50014f51f6cf46420fbaaa2a3e2e68db15933f3e 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
 use os::unix::prelude::*;
 
 use collections::hash_map::{HashMap, Entry};
@@ -593,7 +592,6 @@ pub fn wait(&mut self) -> io::Result<ExitStatus> {
 #[cfg(test)]
 mod tests {
     use super::*;
-    use prelude::v1::*;
 
     use ffi::OsStr;
     use mem;
index 25a7a3ce50dc431a7d22c5cfd215d0c25de29f82..e4ca8344ee2873d31ce9c10c8e8dae16594c66ac 100644 (file)
 
 pub use self::imp::OsRng;
 
-#[cfg(all(unix, not(target_os = "ios"), not(target_os = "openbsd")))]
+use mem;
+
+fn next_u32(mut fill_buf: &mut FnMut(&mut [u8])) -> u32 {
+    let mut buf: [u8; 4] = [0; 4];
+    fill_buf(&mut buf);
+    unsafe { mem::transmute::<[u8; 4], u32>(buf) }
+}
+
+fn next_u64(mut fill_buf: &mut FnMut(&mut [u8])) -> u64 {
+    let mut buf: [u8; 8] = [0; 8];
+    fill_buf(&mut buf);
+    unsafe { mem::transmute::<[u8; 8], u64>(buf) }
+}
+
+#[cfg(all(unix,
+          not(target_os = "ios"),
+          not(target_os = "openbsd"),
+          not(target_os = "freebsd")))]
 mod imp {
     use self::OsRngInner::*;
+    use super::{next_u32, next_u64};
 
     use fs::File;
     use io;
     use libc;
-    use mem;
     use rand::Rng;
     use rand::reader::ReaderRng;
     use sys::os::errno;
@@ -87,18 +104,6 @@ fn getrandom_fill_bytes(v: &mut [u8]) {
         }
     }
 
-    fn getrandom_next_u32() -> u32 {
-        let mut buf: [u8; 4] = [0; 4];
-        getrandom_fill_bytes(&mut buf);
-        unsafe { mem::transmute::<[u8; 4], u32>(buf) }
-    }
-
-    fn getrandom_next_u64() -> u64 {
-        let mut buf: [u8; 8] = [0; 8];
-        getrandom_fill_bytes(&mut buf);
-        unsafe { mem::transmute::<[u8; 8], u64>(buf) }
-    }
-
     #[cfg(all(target_os = "linux",
               any(target_arch = "x86_64",
                   target_arch = "x86",
@@ -163,13 +168,13 @@ pub fn new() -> io::Result<OsRng> {
     impl Rng for OsRng {
         fn next_u32(&mut self) -> u32 {
             match self.inner {
-                OsGetrandomRng => getrandom_next_u32(),
+                OsGetrandomRng => next_u32(&mut getrandom_fill_bytes),
                 OsReaderRng(ref mut rng) => rng.next_u32(),
             }
         }
         fn next_u64(&mut self) -> u64 {
             match self.inner {
-                OsGetrandomRng => getrandom_next_u64(),
+                OsGetrandomRng => next_u64(&mut getrandom_fill_bytes),
                 OsReaderRng(ref mut rng) => rng.next_u64(),
             }
         }
@@ -184,9 +189,10 @@ fn fill_bytes(&mut self, v: &mut [u8]) {
 
 #[cfg(target_os = "openbsd")]
 mod imp {
+    use super::{next_u32, next_u64};
+
     use io;
     use libc;
-    use mem;
     use sys::os::errno;
     use rand::Rng;
 
@@ -205,14 +211,10 @@ pub fn new() -> io::Result<OsRng> {
 
     impl Rng for OsRng {
         fn next_u32(&mut self) -> u32 {
-            let mut v = [0; 4];
-            self.fill_bytes(&mut v);
-            unsafe { mem::transmute(v) }
+            next_u32(&mut |v| self.fill_bytes(v))
         }
         fn next_u64(&mut self) -> u64 {
-            let mut v = [0; 8];
-            self.fill_bytes(&mut v);
-            unsafe { mem::transmute(v) }
+            next_u64(&mut |v| self.fill_bytes(v))
         }
         fn fill_bytes(&mut self, v: &mut [u8]) {
             // getentropy(2) permits a maximum buffer size of 256 bytes
@@ -230,8 +232,9 @@ fn fill_bytes(&mut self, v: &mut [u8]) {
 
 #[cfg(target_os = "ios")]
 mod imp {
+    use super::{next_u32, next_u64};
+
     use io;
-    use mem;
     use ptr;
     use rand::Rng;
     use libc::{c_int, size_t};
@@ -265,14 +268,10 @@ pub fn new() -> io::Result<OsRng> {
 
     impl Rng for OsRng {
         fn next_u32(&mut self) -> u32 {
-            let mut v = [0; 4];
-            self.fill_bytes(&mut v);
-            unsafe { mem::transmute(v) }
+            next_u32(&mut |v| self.fill_bytes(v))
         }
         fn next_u64(&mut self) -> u64 {
-            let mut v = [0; 8];
-            self.fill_bytes(&mut v);
-            unsafe { mem::transmute(v) }
+            next_u64(&mut |v| self.fill_bytes(v))
         }
         fn fill_bytes(&mut self, v: &mut [u8]) {
             let ret = unsafe {
@@ -286,3 +285,51 @@ fn fill_bytes(&mut self, v: &mut [u8]) {
         }
     }
 }
+
+#[cfg(target_os = "freebsd")]
+mod imp {
+    use super::{next_u32, next_u64};
+
+    use io;
+    use libc;
+    use rand::Rng;
+    use ptr;
+
+    pub struct OsRng {
+        // dummy field to ensure that this struct cannot be constructed outside
+        // of this module
+        _dummy: (),
+    }
+
+    impl OsRng {
+        /// Create a new `OsRng`.
+        pub fn new() -> io::Result<OsRng> {
+            Ok(OsRng { _dummy: () })
+        }
+    }
+
+    impl Rng for OsRng {
+        fn next_u32(&mut self) -> u32 {
+            next_u32(&mut |v| self.fill_bytes(v))
+        }
+        fn next_u64(&mut self) -> u64 {
+            next_u64(&mut |v| self.fill_bytes(v))
+        }
+        fn fill_bytes(&mut self, v: &mut [u8]) {
+            let mib = [libc::CTL_KERN, libc::KERN_ARND];
+            // kern.arandom permits a maximum buffer size of 256 bytes
+            for s in v.chunks_mut(256) {
+                let mut s_len = s.len();
+                let ret = unsafe {
+                    libc::sysctl(mib.as_ptr(), mib.len() as libc::c_uint,
+                                 s.as_mut_ptr() as *mut _, &mut s_len,
+                                 ptr::null(), 0)
+                };
+                if ret == -1 || s_len != s.len() {
+                    panic!("kern.arandom sysctl failed! (returned {}, s.len() {}, oldlenp {})",
+                           ret, s.len(), s_len);
+                }
+            }
+        }
+    }
+}
index 37d1d9a969ed8d7a435a0fdf4b9818938348a1cf..972bdbc38186b06eab0373222b9b492e41e1d137 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
-
 use io;
 use libc;
 use sys::fd::FileDesc;
index 75e10d2585308cecb85d17e374fff32c0842509f..5db7086e42752b1387227bba79c10a30818b70aa 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
-
 use alloc::boxed::FnBox;
 use cmp;
 use ffi::CStr;
@@ -193,8 +191,6 @@ pub unsafe fn init() -> Option<usize> { None }
           target_os = "solaris"))]
 #[cfg_attr(test, allow(dead_code))]
 pub mod guard {
-    use prelude::v1::*;
-
     use libc;
     use libc::mmap;
     use libc::{PROT_NONE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED};
index acbfacce8bd7f073e165ded5210a39e94f016825..cd42b7d05ee384d4ec7b9b918d2c5def938b9420 100644 (file)
@@ -21,8 +21,6 @@
 //! manner we pay a semi-large one-time cost up front for detecting whether a
 //! function is available but afterwards it's just a load and a jump.
 
-use prelude::v1::*;
-
 use ffi::CString;
 use sync::atomic::{AtomicUsize, Ordering};
 use sys::c;
index dde13ec8364b63533fd4421046f49a485cea1c06..5227280808f5bdfa9fba3bfd056a2840b8e32b6e 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
 use os::windows::prelude::*;
 
 use ffi::{CString, OsStr};
index 4e6cef9a28d8f32147d5db051c5e95c2f5469a69..fe448cdd78feb9ee71ad2ff6011b06622e1ed36c 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
 use os::windows::prelude::*;
 
 use ffi::OsString;
index d10abae2865271dadfc6af7a3c1f3fa62cd41da9..97e746ee345763cc75e3723c5fbfb6f0d7a4deb5 100644 (file)
@@ -10,8 +10,6 @@
 
 #![unstable(issue = "0", feature = "windows_handle")]
 
-use prelude::v1::*;
-
 use cmp;
 use io::{ErrorKind, Read};
 use io;
index 12219c1e9d42bf750717bdb1c8f16b169c17d1e7..9741a704e8fe51e1ab5667157fe37be52b3cac07 100644 (file)
@@ -10,8 +10,6 @@
 
 #![allow(missing_docs, bad_style)]
 
-use prelude::v1::*;
-
 use ffi::{OsStr, OsString};
 use io::{self, ErrorKind};
 use os::windows::ffi::{OsStrExt, OsStringExt};
index 8762b34e3da484df7fbf49854f4ac57f754a8a1d..855603685905958de4bf5494a677bc4bc23e4497 100644 (file)
@@ -29,8 +29,6 @@
 //! CriticalSection is used and we keep track of who's holding the mutex to
 //! detect recursive locks.
 
-use prelude::v1::*;
-
 use cell::UnsafeCell;
 use mem;
 use sync::atomic::{AtomicUsize, Ordering};
index 71e164f012f1f7c4dfe9cba2ef212660414da296..aca6994503ff8aa46495e32747fda5c7c1e8a127 100644 (file)
@@ -10,8 +10,6 @@
 
 #![unstable(issue = "0", feature = "windows_net")]
 
-use prelude::v1::*;
-
 use cmp;
 use io::{self, Read};
 use libc::{c_int, c_void, c_ulong};
index 0cea7f81e363237fa745023505916db18df864fc..260fc3c4db62ef8371929b95cdcb36e1b1754930 100644 (file)
@@ -12,7 +12,6 @@
 
 #![allow(bad_style)]
 
-use prelude::v1::*;
 use os::windows::prelude::*;
 
 use error::Error as StdError;
index 26767a1349e6fc12a121fbef639843292333ba1d..a065c7a7fd013e3f4f1e7a2f4fd95583d6c63271 100644 (file)
@@ -14,9 +14,6 @@
 use borrow::Cow;
 use fmt::{self, Debug};
 use sys_common::wtf8::{Wtf8, Wtf8Buf};
-use string::String;
-use result::Result;
-use option::Option;
 use mem;
 use sys_common::{AsInner, IntoInner};
 
index 6e9c67051a6eb3559c17a3d2d813df4b685816df..ed7e88e72cd5609d69fa296ab0e811bd733db231 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
 use os::windows::prelude::*;
 
 use ffi::OsStr;
index 3ca75cf3643769e977e2802df9f1377ce951d22e..d371714ff0e690822d7af30d78cf9948224c5ba9 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
-
 use ascii::*;
 use collections::HashMap;
 use collections;
@@ -491,7 +489,6 @@ fn make_dirp(d: Option<&OsString>) -> io::Result<(*const u16, Vec<u16>)> {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
     use ffi::{OsStr, OsString};
     use super::make_command_line;
 
index fa3cab2191edde5ba25924ef0a838e235b6aae75..01249f05f620252134d8c53d5a4c7ea1edca267a 100644 (file)
@@ -10,7 +10,6 @@
 
 #![unstable(issue = "0", feature = "windows_stdio")]
 
-use prelude::v1::*;
 use io::prelude::*;
 
 use cmp;
index 0383e92c79ec7b24a2c1d0c8ff4575e404c4ac1a..5a376a867ee6448288bac2cd1c534a7bb56e77a9 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
-
 use alloc::boxed::FnBox;
 use io;
 use ffi::CStr;
index 59da74b728797cdc20457187c77ed379222575e9..5d3084094fbddd4f02b375b724303fd8734ac157 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::v1::*;
-
 use ptr;
 use sys::c;
 use sys_common::mutex::Mutex;
index 152b9771086b80c7a32017eab810b14a0a152a96..c44dee49f14a69373eed7cbcf6952358b701f8e5 100644 (file)
@@ -369,7 +369,6 @@ unsafe fn register_dtor(&self) {
     // Due to rust-lang/rust#18804, make sure this is not generic!
     #[cfg(target_os = "linux")]
     unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
-        use prelude::v1::*;
         use mem;
         use libc;
         use sys_common::thread_local as os;
@@ -460,8 +459,6 @@ fn _tlv_atexit(dtor: unsafe extern fn(*mut u8),
 
 #[doc(hidden)]
 pub mod os {
-    use prelude::v1::*;
-
     use cell::{Cell, UnsafeCell};
     use marker;
     use ptr;
@@ -529,8 +526,6 @@ pub fn get(&'static self) -> Option<&'static UnsafeCell<Option<T>>> {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
-
     use sync::mpsc::{channel, Sender};
     use cell::{Cell, UnsafeCell};
     use super::LocalKeyState;
@@ -693,8 +688,6 @@ fn drop(&mut self) {
 
 #[cfg(test)]
 mod dynamic_tests {
-    use prelude::v1::*;
-
     use cell::RefCell;
     use collections::HashMap;
 
index f06c105d30e6500eee11e92e8f8c73ecdd4c07ff..f3e1710f50b0d8ec3e50b6f7dff215ce1d71df22 100644 (file)
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use prelude::v1::*;
-
 use any::Any;
 use cell::UnsafeCell;
 use ffi::{CStr, CString};
@@ -732,8 +730,6 @@ fn _assert_both<T: Send + Sync>() {}
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
-
     use any::Any;
     use sync::mpsc::{channel, Sender};
     use result;
@@ -786,8 +782,6 @@ fn test_join_panic() {
 
     #[test]
     fn test_spawn_sched() {
-        use clone::Clone;
-
         let (tx, rx) = channel();
 
         fn f(i: i32, tx: Sender<()>) {
index 031d9a2d3f46e781debb012b0325b787345ddcfb..26599208ec0091270f6f18767541ae38d92e4c71 100644 (file)
@@ -491,18 +491,7 @@ fn expand_trait_item(ti: ast::TraitItem, fld: &mut MacroExpander)
 pub fn expand_type(t: P<ast::Ty>, fld: &mut MacroExpander) -> P<ast::Ty> {
     let t = match t.node.clone() {
         ast::TyKind::Mac(mac) => {
-            if fld.cx.ecfg.features.unwrap().type_macros {
-                expand_mac_invoc(mac, None, Vec::new(), t.span, fld)
-            } else {
-                feature_gate::emit_feature_err(
-                    &fld.cx.parse_sess.span_diagnostic,
-                    "type_macros",
-                    t.span,
-                    feature_gate::GateIssue::Language,
-                    "type macros are experimental");
-
-                DummyResult::raw_ty(t.span)
-            }
+            expand_mac_invoc(mac, None, Vec::new(), t.span, fld)
         }
         _ => t
     };
index d746f8e21141f4001d3e7823c4561474f68a8803..dc68e0646346473cca52a5ed9dceadbc296770ea 100644 (file)
@@ -213,9 +213,6 @@ pub fn new() -> Features {
     // Allows associated type defaults
     (active, associated_type_defaults, "1.2.0", Some(29661)),
 
-    // Allows macros to appear in the type position.
-    (active, type_macros, "1.3.0", Some(27245)),
-
     // allow `repr(simd)`, and importing the various simd intrinsics
     (active, repr_simd, "1.4.0", Some(27731)),
 
@@ -321,6 +318,8 @@ pub fn new() -> Features {
     // mean anything
     (accepted, test_accepted_feature, "1.0.0", None),
     (accepted, tuple_indexing, "1.0.0", None),
+    // Allows macros to appear in the type position.
+    (accepted, type_macros, "1.13.0", Some(27245)),
     (accepted, while_let, "1.0.0", None),
     // Allows `#[deprecated]` attribute
     (accepted, deprecated, "1.9.0", Some(29935))
index 9443df6321bd045a943870bb9af7a46db54ef2b4..1646246069eadf196251a113fcfb36b772e0f02d 100644 (file)
@@ -4087,9 +4087,30 @@ pub fn parse_block(&mut self) -> PResult<'a, P<Block>> {
         if !self.eat(&token::OpenDelim(token::Brace)) {
             let sp = self.span;
             let tok = self.this_token_to_string();
-            return Err(self.span_fatal_help(sp,
-                                 &format!("expected `{{`, found `{}`", tok),
-                                 "place this code inside a block"));
+            let mut e = self.span_fatal(sp, &format!("expected `{{`, found `{}`", tok));
+
+            // Check to see if the user has written something like
+            //
+            //    if (cond)
+            //      bar;
+            //
+            // Which is valid in other languages, but not Rust.
+            match self.parse_stmt_without_recovery(false) {
+                Ok(Some(stmt)) => {
+                    let mut stmt_span = stmt.span;
+                    // expand the span to include the semicolon, if it exists
+                    if self.eat(&token::Semi) {
+                        stmt_span.hi = self.last_span.hi;
+                    }
+                    e.span_help(stmt_span, "try placing this code inside a block");
+                }
+                Err(mut e) => {
+                    self.recover_stmt_(SemiColonMode::Break);
+                    e.cancel();
+                }
+                _ => ()
+            }
+            return Err(e);
         }
 
         self.parse_block_tail(lo, BlockCheckMode::Default)
index 0da25e7ac57b7a7eea4628692251f0b92743d3cd..82fb2b0918f79fcfedb4f37614103f47bbd1dee3 100644 (file)
@@ -521,6 +521,15 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
         ));
 }
 
+extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateLexicalBlockFile(
+    LLVMRustDIBuilderRef Builder,
+    LLVMRustMetadataRef Scope,
+    LLVMRustMetadataRef File) {
+    return wrap(Builder->createLexicalBlockFile(
+        unwrapDI<DIDescriptor>(Scope),
+        unwrapDI<DIFile>(File)));
+}
+
 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStaticVariable(
     LLVMRustDIBuilderRef Builder,
     LLVMRustMetadataRef Context,
index 7737f12ac371400c5f8e372475b70591b16198f5..12f9417f944cded5ea6f4cc4d3c9817b5efad5c6 100644 (file)
@@ -17,5 +17,8 @@ fn some_func<T: Foo>(foo: T) {
 }
 
 fn main() {
-    some_func(5i32); //~ ERROR E0277
+    some_func(5i32);
+    //~^ ERROR the trait bound `i32: Foo` is not satisfied
+    //~| NOTE trait `i32: Foo` not satisfied
+    //~| NOTE required by `some_func`
 }
index 445831bf8d7f7d4ba885c791d534d8cab90f6191..584dfd5fa440cd4a8f7436b98971f5487c830d8b 100644 (file)
@@ -16,5 +16,6 @@ fn main() {
     let mut fancy = FancyNum{ num: 5 };
     let fancy_ref = &(&mut fancy);
     fancy_ref.num = 6; //~ ERROR E0389
+                       //~^ NOTE assignment into an immutable reference
     println!("{}", fancy_ref.num);
 }
index 48bfa84fa8666cb6a5e29db6c3c5d2d18b1554b0..084616964674f3ab85423beb904fb9d12b16ac61 100644 (file)
@@ -31,5 +31,6 @@ trait Add<RHS=Self> {
 fn ice<A>(a: A) {
     let r = loop {};
     r = r + a;
-    //~^ ERROR E0277
+    //~^ ERROR the trait bound `(): Add<A>` is not satisfied
+    //~| NOTE trait `(): Add<A>` not satisfied
 }
index 7839fb45d1c34ebfb7adce6e6f1e71cbc7345808..b6e81504a9d24a2b1ac587145a84bae2809e595d 100644 (file)
@@ -92,6 +92,7 @@ fn main()
     let _ = v as *const [u8]; //~ ERROR cannot cast
     let _ = fat_v as *const Foo;
     //~^ ERROR the trait bound `[u8]: std::marker::Sized` is not satisfied
+    //~| NOTE trait `[u8]: std::marker::Sized` not satisfied
     //~| NOTE `[u8]` does not have a constant size known at compile-time
     //~| NOTE required for the cast to the object type `Foo`
     let _ = foo as *const str; //~ ERROR casting
@@ -106,6 +107,7 @@ fn main()
     let a : *const str = "hello";
     let _ = a as *const Foo;
     //~^ ERROR the trait bound `str: std::marker::Sized` is not satisfied
+    //~| NOTE trait `str: std::marker::Sized` not satisfied
     //~| NOTE `str` does not have a constant size known at compile-time
     //~| NOTE required for the cast to the object type `Foo`
 
index 72a5c5fff608457b2d5770316c4ba62b6a9cf341..a73164b957c831a8896859fb196858d2b3fb493d 100644 (file)
 
 const CONST_0: Debug+Sync = *(&0 as &(Debug+Sync));
 //~^ ERROR `std::fmt::Debug + Sync + 'static: std::marker::Sized` is not satisfied
+//~| NOTE `std::fmt::Debug + Sync + 'static: std::marker::Sized` not satisfied
 //~| NOTE does not have a constant size known at compile-time
 //~| NOTE constant expressions must have a statically known size
 
 const CONST_FOO: str = *"foo";
 //~^ ERROR `str: std::marker::Sized` is not satisfied
+//~| NOTE `str: std::marker::Sized` not satisfied
 //~| NOTE does not have a constant size known at compile-time
 //~| NOTE constant expressions must have a statically known size
 
 static STATIC_1: Debug+Sync = *(&1 as &(Debug+Sync));
 //~^ ERROR `std::fmt::Debug + Sync + 'static: std::marker::Sized` is not satisfied
+//~| NOTE `std::fmt::Debug + Sync + 'static: std::marker::Sized` not satisfied
 //~| NOTE does not have a constant size known at compile-time
 //~| NOTE constant expressions must have a statically known size
 
 static STATIC_BAR: str = *"bar";
 //~^ ERROR `str: std::marker::Sized` is not satisfied
+//~| NOTE `str: std::marker::Sized` not satisfied
 //~| NOTE does not have a constant size known at compile-time
 //~| NOTE constant expressions must have a statically known size
 
index 2c78ce2db29afe76ebf64ff08ea381c4e4f45e47..60ad266e7f7daaaf7857c03dc2f4d2c9cffa8dc3 100644 (file)
@@ -26,6 +26,7 @@ fn send<T: Send>(_: T) {}
 fn main() {
     send(before());
     //~^ ERROR the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied
+    //~| NOTE trait `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` not satisfied
     //~| NOTE `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
     //~| NOTE required because it appears within the type `[closure
     //~| NOTE required because it appears within the type `impl std::ops::Fn<(i32,)>`
@@ -33,6 +34,7 @@ fn main() {
 
     send(after());
     //~^ ERROR the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied
+    //~| NOTE trait `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` not satisfied
     //~| NOTE `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
     //~| NOTE required because it appears within the type `[closure
     //~| NOTE required because it appears within the type `impl std::ops::Fn<(i32,)>`
@@ -52,6 +54,7 @@ fn after() -> impl Fn(i32) {
 fn cycle1() -> impl Clone {
     send(cycle2().clone());
     //~^ ERROR the trait bound `std::rc::Rc<std::string::String>: std::marker::Send` is not satisfied
+    //~| NOTE trait `std::rc::Rc<std::string::String>: std::marker::Send` not satisfied
     //~| NOTE `std::rc::Rc<std::string::String>` cannot be sent between threads safely
     //~| NOTE required because it appears within the type `impl std::clone::Clone`
     //~| NOTE required by `send`
@@ -62,6 +65,7 @@ fn cycle1() -> impl Clone {
 fn cycle2() -> impl Clone {
     send(cycle1().clone());
     //~^ ERROR the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied
+    //~| NOTE trait `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` not satisfied
     //~| NOTE `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
     //~| NOTE required because it appears within the type `impl std::clone::Clone`
     //~| NOTE required by `send`
index 95a52cb232a490ddcb95106dd58139c02cb43b7c..fa0b75da999c29127d17e8f42b975f8dda479376 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(type_macros)]
-
 macro_rules! t {
     () => ( String ; );     //~ ERROR macro expansion ignores token `;`
 }
index e8ca1c1fa98ff4a99c755f274b3a7d3aa2c8f799..20e5b1d72d3d71a9f8ce4c9e716b1f1362db9f8c 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(type_macros, concat_idents)]
+#![feature(concat_idents)]
 
 #[derive(Debug)] //~ NOTE in this expansion
 struct Baz<T>(
diff --git a/src/test/compile-fail/issue-35869.rs b/src/test/compile-fail/issue-35869.rs
new file mode 100644 (file)
index 0000000..8b7fc80
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(conservative_impl_trait)]
+
+trait Foo {
+    fn foo(fn(u8) -> ()); //~ NOTE type in trait
+    fn bar(Option<u8>); //~ NOTE type in trait
+    fn baz((u8, u16)); //~ NOTE type in trait
+    fn qux() -> u8; //~ NOTE type in trait
+}
+
+struct Bar;
+
+impl Foo for Bar {
+    fn foo(_: fn(u16) -> ()) {}
+    //~^ ERROR method `foo` has an incompatible type for trait
+    //~| NOTE expected u8
+    fn bar(_: Option<u16>) {}
+    //~^ ERROR method `bar` has an incompatible type for trait
+    //~| NOTE expected u8
+    fn baz(_: (u16, u16)) {}
+    //~^ ERROR method `baz` has an incompatible type for trait
+    //~| NOTE expected u8
+    fn qux() -> u16 { 5u16 }
+    //~^ ERROR method `qux` has an incompatible type for trait
+    //~| NOTE expected u8
+}
+
+fn main() {}
index 5d07f0747ff435316db7367cd4ea210baa74e02d..4aa0a3023bb109ed5398458c65e258329a1e6928 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(type_macros)]
-
 // (typeof used because it's surprisingly hard to find an unparsed token after a stmt)
 macro_rules! m {
     () => ( i ; typeof );   //~ ERROR expected expression, found reserved keyword `typeof`
index a69188da58d1667686ab896b9d0d005805b76337..4a6dbf014a1cace35ae973c1daa5cf77ca3bade8 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(type_macros)]
-
 macro_rules! foo {
     ($a:expr) => $a; //~ ERROR macro rhs must be delimited
 }
diff --git a/src/test/compile-fail/missing-block-hint.rs b/src/test/compile-fail/missing-block-hint.rs
new file mode 100644 (file)
index 0000000..1f29ff4
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    {
+        if (foo) => {} //~ ERROR expected `{`, found `=>`
+    }
+    {
+        if (foo)
+            bar; //~ ERROR expected `{`, found `bar`
+                 //^ HELP try placing this code inside a block
+    }
+}
index 0df8c41ffe1a8e52ae7fa2f710305af478c78348..cc7c2f4f796d93bd0b8711aa566cc8073d7964ec 100644 (file)
@@ -42,14 +42,17 @@ fn index(&self, _index: Bar<usize>) -> &i32 {
 fn main() {
     Index::index(&[] as &[i32], 2u32);
     //~^ ERROR E0277
+    //~| NOTE not satisfied
     //~| NOTE trait message
     //~| NOTE required by
     Index::index(&[] as &[i32], Foo(2u32));
     //~^ ERROR E0277
+    //~| NOTE not satisfied
     //~| NOTE on impl for Foo
     //~| NOTE required by
     Index::index(&[] as &[i32], Bar(2u32));
     //~^ ERROR E0277
+    //~| NOTE not satisfied
     //~| NOTE on impl for Bar
     //~| NOTE required by
 }
index 4471b625d7912fd4b79ac1913aaaa3cb687e4774..c22e48bede4efdd61f87ee53f579125ffcb5b431 100644 (file)
@@ -30,6 +30,7 @@ fn index(&self, index: usize) -> &i32 {
 #[rustc_error]
 fn main() {
     Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32); //~ ERROR E0277
+                                                     //~| NOTE not satisfied
                                                      //~| NOTE a usize is required
                                                      //~| NOTE required by
 }
index 39ce1b33ca13122b275642f24761987f645aab0f..9ea2809374cd83adf601215bc52c3d23c5f996fb 100644 (file)
@@ -35,7 +35,9 @@ pub fn main() {
     //~^ ERROR
     //~^^ NOTE a collection of type `std::option::Option<std::vec::Vec<u8>>` cannot be built from an iterator over elements of type `&u8`
     //~^^^ NOTE required by `collect`
+    //~| NOTE trait `std::option::Option<std::vec::Vec<u8>>: MyFromIterator<&u8>` not satisfied
     let x: String = foobar(); //~ ERROR
     //~^ NOTE test error `std::string::String` with `u8` `_` `u32`
     //~^^ NOTE required by `foobar`
+    //~| NOTE trait `std::string::String: Foo<u8, _, u32>` not satisfied
 }
index 6a8f9d471e1692254619e788ed400abfec7299a3..5c548b5d5bf20760ad1d3c69f78c1f6da03a12a3 100644 (file)
@@ -18,7 +18,9 @@
 fn main() {
     let x = &[1, 2, 3] as &[i32];
     x[1i32]; //~ ERROR E0277
+             //~| NOTE trait `[i32]: std::ops::Index<i32>` not satisfied
              //~| NOTE slice indices are of type `usize`
     x[..1i32]; //~ ERROR E0277
+               //~| NOTE trait `[i32]: std::ops::Index<std::ops::RangeTo<i32>>` not satisfied
                //~| NOTE slice indices are of type `usize`
 }
index 9cc53386d465c50484f6e57d926a1a0ca96299b5..f3dcf405a68a6276abc0e99abc36df62e5baef40 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(pub_restricted, type_macros)]
+#![feature(pub_restricted)]
 
 mod foo {
     type T = ();
index 01466c6a85a5ae5c94e7887bd22c68e308668b3e..3bf8ca30a6c3fe42df1b46936704d56cdce21c24 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(pub_restricted, type_macros)]
+#![feature(pub_restricted)]
 
 macro_rules! define_struct {
     ($t:ty) => {
index ef187a1daed37106f6529f2df1a46deeb012cfe6..febe224fb84dcf14ce2294d6b1940109b13e9843 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(pub_restricted, type_macros)]
+#![feature(pub_restricted)]
 
 macro_rules! define_struct {
     ($t:ty) => {
index 3e36b126523a7f84828dd5fd7180ae54724c5aaf..f06e3544e575dec1874a39eb9dc1eeb2b735aae0 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(concat_idents, type_macros)]
+#![feature(concat_idents)]
 
 pub fn main() {
     struct Foo;
index a8ff1bae7a71a7ebe1a114721776811cf99bc7ba..d15e3536d60ca0633cf5a91ed390e1da4e4cd376 100644 (file)
@@ -16,11 +16,13 @@ fn check<T: Iterator, U: ?Sized>() {
     // suggest a where-clause, if needed
     mem::size_of::<U>();
     //~^ ERROR `U: std::marker::Sized` is not satisfied
+    //~| NOTE trait `U: std::marker::Sized` not satisfied
     //~| HELP consider adding a `where U: std::marker::Sized` bound
     //~| NOTE required by `std::mem::size_of`
 
     mem::size_of::<Misc<U>>();
     //~^ ERROR `U: std::marker::Sized` is not satisfied
+    //~| NOTE trait `U: std::marker::Sized` not satisfied
     //~| HELP consider adding a `where U: std::marker::Sized` bound
     //~| NOTE required because it appears within the type `Misc<U>`
     //~| NOTE required by `std::mem::size_of`
@@ -29,11 +31,13 @@ fn check<T: Iterator, U: ?Sized>() {
 
     <u64 as From<T>>::from;
     //~^ ERROR `u64: std::convert::From<T>` is not satisfied
+    //~| NOTE trait `u64: std::convert::From<T>` not satisfied
     //~| HELP consider adding a `where u64: std::convert::From<T>` bound
     //~| NOTE required by `std::convert::From::from`
 
     <u64 as From<<T as Iterator>::Item>>::from;
     //~^ ERROR `u64: std::convert::From<<T as std::iter::Iterator>::Item>` is not satisfied
+    //~| NOTE trait `u64: std::convert::From<<T as std::iter::Iterator>::Item>` not satisfied
     //~| HELP consider adding a `where u64:
     //~| NOTE required by `std::convert::From::from`
 
@@ -41,17 +45,20 @@ fn check<T: Iterator, U: ?Sized>() {
 
     <Misc<_> as From<T>>::from;
     //~^ ERROR `Misc<_>: std::convert::From<T>` is not satisfied
+    //~| NOTE trait `Misc<_>: std::convert::From<T>` not satisfied
     //~| NOTE required by `std::convert::From::from`
 
     // ... and also not if the error is not related to the type
 
     mem::size_of::<[T]>();
     //~^ ERROR `[T]: std::marker::Sized` is not satisfied
+    //~| NOTE `[T]: std::marker::Sized` not satisfied
     //~| NOTE `[T]` does not have a constant size
     //~| NOTE required by `std::mem::size_of`
 
     mem::size_of::<[&U]>();
     //~^ ERROR `[&U]: std::marker::Sized` is not satisfied
+    //~| NOTE `[&U]: std::marker::Sized` not satisfied
     //~| NOTE `[&U]` does not have a constant size
     //~| NOTE required by `std::mem::size_of`
 }
diff --git a/src/test/compile-fail/type-macros-fail.rs b/src/test/compile-fail/type-macros-fail.rs
deleted file mode 100644 (file)
index 4712e2b..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-macro_rules! Id {
-    ($T:tt) => ($T);
-}
-
-struct Foo<T> {
-    x: Id!(T)
-    //~^ ERROR: type macros are experimental (see issue #27245)
-}
-
-fn main() {
-    let foo = Foo { x: i32 };
-}
index 5539a26d2a1702df997d0457a511c76c9ea8ae67..7dbfc6ac1257d082732d314232599c32c460cef8 100644 (file)
@@ -20,12 +20,12 @@ fn method(&'a self) { }
 }
 
 #[rustc_variance]
-struct Foo<'a, T : Trait<'a>> { //~ ERROR ItemVariances(types=[+], regions=[-])
+struct Foo<'a, T : Trait<'a>> { //~ ERROR [-, +]
     field: (T, &'a ())
 }
 
 #[rustc_variance]
-struct Bar<'a, T : Trait<'a>> { //~ ERROR ItemVariances(types=[o], regions=[o])
+struct Bar<'a, T : Trait<'a>> { //~ ERROR [o, o]
     field: <T as Trait<'a>>::Type
 }
 
index 2f422bfd38cc7fcb340f3068b8a109e6faf3221e..1f54771e3676abd00677dc05b75672c2d619a1ec 100644 (file)
@@ -18,7 +18,7 @@
 // For better or worse, associated types are invariant, and hence we
 // get an invariant result for `'a`.
 #[rustc_variance]
-struct Foo<'a> { //~ ERROR regions=[o]
+struct Foo<'a> { //~ ERROR [o]
     x: Box<Fn(i32) -> &'a i32 + 'static>
 }
 
index 99416057b25408341ea5b60582dbaf79de2376b2..41d204a541b5ad9b4481dd1fe51abff1d3afb359 100644 (file)
 #![feature(rustc_attrs)]
 
 #[rustc_variance]
-trait Foo: 'static { //~ ERROR types=[o]
+trait Foo: 'static { //~ ERROR [o]
 }
 
 #[rustc_variance]
-trait Bar<T> { //~ ERROR types=[o, o]
+trait Bar<T> { //~ ERROR [o, o]
     fn do_it(&self)
         where T: 'static;
 }
index 78591063de8abc4db2094b6a42a1c1dd63562bd1..bf46edcfab8b172ffc4affd0eff34f98625e62af 100644 (file)
@@ -16,7 +16,7 @@
 // Regions that just appear in normal spots are contravariant:
 
 #[rustc_variance]
-struct Test2<'a, 'b, 'c> { //~ ERROR regions=[-, -, -]
+struct Test2<'a, 'b, 'c> { //~ ERROR [-, -, -]
     x: &'a isize,
     y: &'b [isize],
     c: &'c str
@@ -25,7 +25,7 @@ struct Test2<'a, 'b, 'c> { //~ ERROR regions=[-, -, -]
 // Those same annotations in function arguments become covariant:
 
 #[rustc_variance]
-struct Test3<'a, 'b, 'c> { //~ ERROR regions=[+, +, +]
+struct Test3<'a, 'b, 'c> { //~ ERROR [+, +, +]
     x: extern "Rust" fn(&'a isize),
     y: extern "Rust" fn(&'b [isize]),
     c: extern "Rust" fn(&'c str),
@@ -34,7 +34,7 @@ struct Test3<'a, 'b, 'c> { //~ ERROR regions=[+, +, +]
 // Mutability induces invariance:
 
 #[rustc_variance]
-struct Test4<'a, 'b:'a> { //~ ERROR regions=[-, o]
+struct Test4<'a, 'b:'a> { //~ ERROR [-, o]
     x: &'a mut &'b isize,
 }
 
@@ -42,7 +42,7 @@ struct Test4<'a, 'b:'a> { //~ ERROR regions=[-, o]
 // contravariant context:
 
 #[rustc_variance]
-struct Test5<'a, 'b:'a> { //~ ERROR regions=[+, o]
+struct Test5<'a, 'b:'a> { //~ ERROR [+, o]
     x: extern "Rust" fn(&'a mut &'b isize),
 }
 
@@ -52,14 +52,14 @@ struct Test5<'a, 'b:'a> { //~ ERROR regions=[+, o]
 // argument list occurs in an invariant context.
 
 #[rustc_variance]
-struct Test6<'a, 'b:'a> { //~ ERROR regions=[-, o]
+struct Test6<'a, 'b:'a> { //~ ERROR [-, o]
     x: &'a mut extern "Rust" fn(&'b isize),
 }
 
 // No uses at all is bivariant:
 
 #[rustc_variance]
-struct Test7<'a> { //~ ERROR regions=[*]
+struct Test7<'a> { //~ ERROR [*]
     //~^ ERROR parameter `'a` is never used
     x: isize
 }
@@ -67,7 +67,7 @@ struct Test7<'a> { //~ ERROR regions=[*]
 // Try enums too.
 
 #[rustc_variance]
-enum Test8<'a, 'b, 'c:'b> { //~ ERROR regions=[+, -, o]
+enum Test8<'a, 'b, 'c:'b> { //~ ERROR [+, -, o]
     Test8A(extern "Rust" fn(&'a isize)),
     Test8B(&'b [isize]),
     Test8C(&'b mut &'c str),
index d8af30da163bf8a735550357ce20257c5d865525..e28828f62e52d655f4b65e7888ac9b7d17131b2d 100644 (file)
@@ -15,7 +15,7 @@
 #![feature(rustc_attrs)]
 
 #[rustc_variance]
-enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[+, -, o, *]
+enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR [+, -, o, *]
     //~^ ERROR parameter `'d` is never used
     Test8A(extern "Rust" fn(&'a isize)),
     Test8B(&'b [isize]),
@@ -23,25 +23,25 @@ enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[+, -, o, *]
 }
 
 #[rustc_variance]
-struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR regions=[*, o, -, +]
+struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR [*, o, -, +]
     //~^ ERROR parameter `'w` is never used
     f: Base<'z, 'y, 'x, 'w>
 }
 
 #[rustc_variance] // Combine - and + to yield o
-struct Derived2<'a, 'b:'a, 'c> { //~ ERROR regions=[o, o, *]
+struct Derived2<'a, 'b:'a, 'c> { //~ ERROR [o, o, *]
     //~^ ERROR parameter `'c` is never used
     f: Base<'a, 'a, 'b, 'c>
 }
 
 #[rustc_variance] // Combine + and o to yield o (just pay attention to 'a here)
-struct Derived3<'a:'b, 'b, 'c> { //~ ERROR regions=[o, -, *]
+struct Derived3<'a:'b, 'b, 'c> { //~ ERROR [o, -, *]
     //~^ ERROR parameter `'c` is never used
     f: Base<'a, 'b, 'a, 'c>
 }
 
 #[rustc_variance] // Combine + and * to yield + (just pay attention to 'a here)
-struct Derived4<'a, 'b, 'c:'b> { //~ ERROR regions=[+, -, o]
+struct Derived4<'a, 'b, 'c:'b> { //~ ERROR [+, -, o]
     f: Base<'a, 'b, 'c, 'a>
 }
 
index 150a1aa56fe721e956614328416e07c1b0eff0ca..4c737a7594d260125b4486e257d6820ff89aaed7 100644 (file)
 // influence variance.
 
 #[rustc_variance]
-trait Getter<T> { //~ ERROR types=[o, o]
+trait Getter<T> { //~ ERROR [o, o]
     fn get(&self) -> T;
 }
 
 #[rustc_variance]
-trait Setter<T> { //~ ERROR types=[o, o]
+trait Setter<T> { //~ ERROR [o, o]
     fn get(&self, T);
 }
 
 #[rustc_variance]
-struct TestStruct<U,T:Setter<U>> { //~ ERROR types=[+, +]
+struct TestStruct<U,T:Setter<U>> { //~ ERROR [+, +]
     t: T, u: U
 }
 
 #[rustc_variance]
-enum TestEnum<U,T:Setter<U>> {//~ ERROR types=[*, +]
+enum TestEnum<U,T:Setter<U>> {//~ ERROR [*, +]
     //~^ ERROR parameter `U` is never used
     Foo(T)
 }
 
 #[rustc_variance]
-trait TestTrait<U,T:Setter<U>> { //~ ERROR types=[o, o, o]
+trait TestTrait<U,T:Setter<U>> { //~ ERROR [o, o, o]
     fn getter(&self, u: U) -> T;
 }
 
 #[rustc_variance]
-trait TestTrait2<U> : Getter<U> { //~ ERROR types=[o, o]
+trait TestTrait2<U> : Getter<U> { //~ ERROR [o, o]
 }
 
 #[rustc_variance]
-trait TestTrait3<U> { //~ ERROR types=[o, o]
+trait TestTrait3<U> { //~ ERROR [o, o]
     fn getter<T:Getter<U>>(&self);
 }
 
 #[rustc_variance]
-struct TestContraStruct<U,T:Setter<U>> { //~ ERROR types=[*, +]
+struct TestContraStruct<U,T:Setter<U>> { //~ ERROR [*, +]
     //~^ ERROR parameter `U` is never used
     t: T
 }
 
 #[rustc_variance]
-struct TestBox<U,T:Getter<U>+Setter<U>> { //~ ERROR types=[*, +]
+struct TestBox<U,T:Getter<U>+Setter<U>> { //~ ERROR [*, +]
     //~^ ERROR parameter `U` is never used
     t: T
 }
index 4244b0e1d8b8b27104150a40cd03449694e724b0..b120588ecab52318f4d014f6ed4230d38dc72246 100644 (file)
@@ -21,7 +21,7 @@
 trait T { fn foo(&self); }
 
 #[rustc_variance]
-struct TOption<'a> { //~ ERROR regions=[-]
+struct TOption<'a> { //~ ERROR [-]
     v: Option<Box<T + 'a>>,
 }
 
index c47710d6d376d0e2bcdf1354fd62cf2c7411687e..2df94cc907a9cf88517497712bb4218e90caca3b 100644 (file)
 #![feature(rustc_attrs)]
 
 #[rustc_variance]
-struct TestImm<A, B> { //~ ERROR types=[+, +]
+struct TestImm<A, B> { //~ ERROR [+, +]
     x: A,
     y: B,
 }
 
 #[rustc_variance]
-struct TestMut<A, B:'static> { //~ ERROR types=[+, o]
+struct TestMut<A, B:'static> { //~ ERROR [+, o]
     x: A,
     y: &'static mut B,
 }
 
 #[rustc_variance]
-struct TestIndirect<A:'static, B:'static> { //~ ERROR types=[+, o]
+struct TestIndirect<A:'static, B:'static> { //~ ERROR [+, o]
     m: TestMut<A, B>
 }
 
 #[rustc_variance]
-struct TestIndirect2<A:'static, B:'static> { //~ ERROR types=[o, o]
+struct TestIndirect2<A:'static, B:'static> { //~ ERROR [o, o]
     n: TestMut<A, B>,
     m: TestMut<B, A>
 }
 
 #[rustc_variance]
-trait Getter<A> { //~ ERROR types=[o, o]
+trait Getter<A> { //~ ERROR [o, o]
     fn get(&self) -> A;
 }
 
 #[rustc_variance]
-trait Setter<A> { //~ ERROR types=[o, o]
+trait Setter<A> { //~ ERROR [o, o]
     fn set(&mut self, a: A);
 }
 
 #[rustc_variance]
-trait GetterSetter<A> { //~ ERROR types=[o, o]
+trait GetterSetter<A> { //~ ERROR [o, o]
     fn get(&self) -> A;
     fn set(&mut self, a: A);
 }
 
 #[rustc_variance]
-trait GetterInTypeBound<A> { //~ ERROR types=[o, o]
+trait GetterInTypeBound<A> { //~ ERROR [o, o]
     // Here, the use of `A` in the method bound *does* affect
     // variance.  Think of it as if the method requested a dictionary
     // for `T:Getter<A>`.  Since this dictionary is an input, it is
@@ -63,12 +63,12 @@ trait GetterInTypeBound<A> { //~ ERROR types=[o, o]
 }
 
 #[rustc_variance]
-trait SetterInTypeBound<A> { //~ ERROR types=[o, o]
+trait SetterInTypeBound<A> { //~ ERROR [o, o]
     fn do_it<T:Setter<A>>(&self);
 }
 
 #[rustc_variance]
-struct TestObject<A, R> { //~ ERROR types=[o, o]
+struct TestObject<A, R> { //~ ERROR [o, o]
     n: Box<Setter<A>+Send>,
     m: Box<Getter<R>+Send>,
 }
index d5164412358fc4dbba312b0e7dab4858ee6f61d5..7667972c9d251edcd9d8e85115fb05b848c1e4fc 100644 (file)
 // not considered bivariant.
 
 #[rustc_variance]
-struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR types=[o, o], regions=[-]
+struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR [-, o, o]
     t: &'a mut (A,B)
 }
 
 #[rustc_variance]
-struct InvariantCell<A> { //~ ERROR types=[o]
+struct InvariantCell<A> { //~ ERROR [o]
     t: Cell<A>
 }
 
 #[rustc_variance]
-struct InvariantIndirect<A> { //~ ERROR types=[o]
+struct InvariantIndirect<A> { //~ ERROR [o]
     t: InvariantCell<A>
 }
 
 #[rustc_variance]
-struct Covariant<A> { //~ ERROR types=[+]
+struct Covariant<A> { //~ ERROR [+]
     t: A, u: fn() -> A
 }
 
 #[rustc_variance]
-struct Contravariant<A> { //~ ERROR types=[-]
+struct Contravariant<A> { //~ ERROR [-]
     t: fn(A)
 }
 
 #[rustc_variance]
-enum Enum<A,B,C> { //~ ERROR types=[+, -, o]
+enum Enum<A,B,C> { //~ ERROR [+, -, o]
     Foo(Covariant<A>),
     Bar(Contravariant<B>),
     Zed(Covariant<C>,Contravariant<C>)
diff --git a/src/test/debuginfo/auxiliary/macro-stepping.rs b/src/test/debuginfo/auxiliary/macro-stepping.rs
new file mode 100644 (file)
index 0000000..1006b68
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2013-2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags:-g
+
+#![crate_type = "rlib"]
+
+#[macro_export]
+macro_rules! new_scope {
+    () => {
+        let x = 1;
+    }
+}
index a00d0f74f1e4e45771e9d166c1b8fae1f8cbdb7c..eb5798dc7cc486746d250e2ca2481ea0eabeaab6 100644 (file)
@@ -10,7 +10,7 @@
 
 // min-lldb-version: 310
 
-// compile-flags:-g
+// compile-flags:-g -Zdebug-macros
 
 // === GDB TESTS ===================================================================================
 
diff --git a/src/test/debuginfo/macro-stepping.rs b/src/test/debuginfo/macro-stepping.rs
new file mode 100644 (file)
index 0000000..52a2a58
--- /dev/null
@@ -0,0 +1,103 @@
+// Copyright 2013-2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-windows
+// ignore-android
+// min-lldb-version: 310
+
+// aux-build:macro-stepping.rs
+
+#![allow(unused)]
+
+#[macro_use]
+extern crate macro_stepping; // exports new_scope!()
+
+// compile-flags:-g
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command:run
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc1[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc2[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc3[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc4[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc5[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc6[...]
+
+// === LLDB TESTS ==================================================================================
+
+// lldb-command:set set stop-line-count-before 0
+// lldb-command:set set stop-line-count-after 1
+// Can't set both to zero or lldb will stop printing source at all.  So it will output the current
+// line and the next.  We deal with this by having at least 2 lines between the #loc's
+
+// lldb-command:run
+// lldb-command:next
+// lldb-command:frame select
+// lldb-check:[...]#loc1[...]
+// lldb-command:next
+// lldb-command:frame select
+// lldb-check:[...]#loc2[...]
+// lldb-command:next
+// lldb-command:frame select
+// lldb-check:[...]#loc3[...]
+// lldb-command:next
+// lldb-command:frame select
+// lldb-check:[...]#loc4[...]
+// lldb-command:next
+// lldb-command:frame select
+// lldb-check:[...]#loc5[...]
+
+macro_rules! foo {
+    () => {
+        let a = 1;
+        let b = 2;
+        let c = 3;
+    }
+}
+
+macro_rules! foo2 {
+    () => {
+        foo!();
+        let x = 1;
+        foo!();
+    }
+}
+
+fn main() {
+    zzz(); // #break
+
+    foo!(); // #loc1
+
+    foo2!(); // #loc2
+
+    let x = vec![42]; // #loc3
+
+    new_scope!(); // #loc4
+
+    println!("Hello {}", // #loc5
+             "world");
+
+    zzz(); // #loc6
+}
+
+fn zzz() {()}
index 604933d40a12c688d4ee26a13033dbbc8eb2c24c..f7b046b30cad7397c1652726fe6824e9b508d8bd 100644 (file)
@@ -19,7 +19,7 @@
 extern crate syntax;
 
 use rustc::mir::transform::{self, MirPass, MirSource};
-use rustc::mir::repr::{Mir, Literal};
+use rustc::mir::repr::{Mir, Literal, Location};
 use rustc::mir::visit::MutVisitor;
 use rustc::ty::TyCtxt;
 use rustc::middle::const_val::ConstVal;
@@ -40,7 +40,7 @@ fn run_pass<'a>(&mut self, _: TyCtxt<'a, 'tcx, 'tcx>,
 struct Visitor;
 
 impl<'tcx> MutVisitor<'tcx> for Visitor {
-    fn visit_literal(&mut self, literal: &mut Literal<'tcx>) {
+    fn visit_literal(&mut self, literal: &mut Literal<'tcx>, _: Location) {
         if let Literal::Value { ref mut value } = *literal {
             if let ConstVal::Integral(ConstInt::I32(ref mut i @ 11)) = *value {
                 *i = 42;
index c2916ccd75b8e4a58e8d926714b02b35b608c60f..7d49bd25309f5ad2b0479331265e36e834527413 100644 (file)
@@ -34,7 +34,7 @@ fn main() {
 }
 
 fn parent() {
-    let file = File::open("Makefile").unwrap();
+    let file = File::open(file!()).unwrap();
     let tcp1 = TcpListener::bind("127.0.0.1:0").unwrap();
     let tcp2 = tcp1.try_clone().unwrap();
     let addr = tcp1.local_addr().unwrap();
diff --git a/src/test/run-pass/mir_heavy_promoted.rs b/src/test/run-pass/mir_heavy_promoted.rs
new file mode 100644 (file)
index 0000000..9e03342
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+const TEST_DATA: [u8; 32 * 1024 * 1024] = [42; 32 * 1024 * 1024];
+
+// Check that the promoted copy of TEST_DATA doesn't
+// leave an alloca from an unused temp behind, which,
+// without optimizations, can still blow the stack.
+fn main() {
+    println!("{}", TEST_DATA.len());
+}
index a20dd3ef72a54cd831eebf714931095419dd00ad..2efd9333999b24ca0f83834b7be300b849cb7f19 100644 (file)
@@ -8,8 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(repr_simd, platform_intrinsics, concat_idents,
-           type_macros, test)]
+#![feature(repr_simd, platform_intrinsics, concat_idents, test)]
 #![allow(non_camel_case_types)]
 
 extern crate test;
index 803b0eae99e887f1ff72a0fdc86c8856354ab1e2..84c0983de80c83abfb580d9dedcd2b4f9122ff16 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(type_macros)]
-
 use std::ops::*;
 
 #[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
index 22dfd507f7e2e6e0c2e65021b1a62f805f640e37..7d1045cf3f1a82e0950e2298044b30c4dfada22e 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(type_macros)]
-
 macro_rules! Tuple {
     { $A:ty,$B:ty } => { ($A, $B) }
 }