about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-03-07 21:59:15 +0000
committerbors <bors@rust-lang.org>2018-03-07 21:59:15 +0000
commit5430c0c5c0fbdfb8e89358a187d2f9a8d4b796d4 (patch)
tree99f6ed796a60eef5a806809bd02146d3463ddf0b /src
parent4cdbac639af2074b8a07b4391b4e3e28b4118487 (diff)
parent16cc9ce8a27eac42950d8413f46c648e35e10cb3 (diff)
downloadrust-5430c0c5c0fbdfb8e89358a187d2f9a8d4b796d4.tar.gz
rust-5430c0c5c0fbdfb8e89358a187d2f9a8d4b796d4.zip
Auto merge of #48806 - alexcrichton:rollup, r=alexcrichton
Rollup of 9 pull requests

- Successful merges: #48511, #48549, #48618, #48624, #48651, #48698, #48778, #48787, #48802
- Failed merges: #48669, #48710
Diffstat (limited to 'src')
-rw-r--r--src/Cargo.lock58
-rw-r--r--src/bootstrap/mk/Makefile.in9
-rwxr-xr-xsrc/ci/run.sh2
-rwxr-xr-xsrc/etc/ziggurat_tables.py127
-rw-r--r--src/libcore/option.rs3
-rw-r--r--src/librustc/dep_graph/dep_node.rs4
-rw-r--r--src/librustc/hir/check_attr.rs2
-rw-r--r--src/librustc/hir/mod.rs50
-rw-r--r--src/librustc/ich/impls_hir.rs38
-rw-r--r--src/librustc/ich/impls_ty.rs4
-rw-r--r--src/librustc/infer/error_reporting/mod.rs2
-rw-r--r--src/librustc/infer/mod.rs17
-rw-r--r--src/librustc/infer/outlives/bounds.rs2
-rw-r--r--src/librustc/middle/cstore.rs7
-rw-r--r--src/librustc/middle/reachable.rs21
-rw-r--r--src/librustc/mir/mono.rs2
-rw-r--r--src/librustc/traits/error_reporting.rs11
-rw-r--r--src/librustc/traits/fulfill.rs13
-rw-r--r--src/librustc/traits/mod.rs16
-rw-r--r--src/librustc/traits/object_safety.rs2
-rw-r--r--src/librustc/traits/select.rs121
-rw-r--r--src/librustc/traits/structural_impls.rs3
-rw-r--r--src/librustc/traits/util.rs8
-rw-r--r--src/librustc/ty/instance.rs5
-rw-r--r--src/librustc/ty/layout.rs4
-rw-r--r--src/librustc/ty/maps/config.rs2
-rw-r--r--src/librustc/ty/maps/mod.rs10
-rw-r--r--src/librustc/ty/maps/on_disk_cache.rs2
-rw-r--r--src/librustc/ty/maps/plumbing.rs8
-rw-r--r--src/librustc/ty/mod.rs20
-rw-r--r--src/librustc/ty/structural_impls.rs24
-rw-r--r--src/librustc/ty/util.rs9
-rw-r--r--src/librustc/ty/wf.rs4
-rw-r--r--src/librustc/util/ppaux.rs11
-rw-r--r--src/librustc_data_structures/owning_ref/mod.rs47
-rw-r--r--src/librustc_data_structures/sync.rs3
-rw-r--r--src/librustc_llvm/archive_ro.rs2
-rw-r--r--src/librustc_llvm/lib.rs2
-rw-r--r--src/librustc_metadata/cstore.rs5
-rw-r--r--src/librustc_metadata/encoder.rs4
-rw-r--r--src/librustc_metadata/lib.rs1
-rw-r--r--src/librustc_metadata/locator.rs10
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs2
-rw-r--r--src/librustc_mir/interpret/eval_context.rs2
-rw-r--r--src/librustc_mir/monomorphize/collector.rs10
-rw-r--r--src/librustc_mir/monomorphize/item.rs49
-rw-r--r--src/librustc_mir/transform/inline.rs10
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs22
-rw-r--r--src/librustc_trans/attributes.rs139
-rw-r--r--src/librustc_trans/back/symbol_export.rs9
-rw-r--r--src/librustc_trans/base.rs1
-rw-r--r--src/librustc_trans/common.rs2
-rw-r--r--src/librustc_trans/consts.rs10
-rw-r--r--src/librustc_trans/context.rs2
-rw-r--r--src/librustc_trans/lib.rs2
-rw-r--r--src/librustc_trans/metadata.rs12
-rw-r--r--src/librustc_trans_utils/diagnostics.rs38
-rw-r--r--src/librustc_trans_utils/lib.rs4
-rw-r--r--src/librustc_trans_utils/symbol_names.rs25
-rw-r--r--src/librustc_trans_utils/trans_crate.rs26
-rw-r--r--src/librustc_typeck/check/closure.rs1
-rw-r--r--src/librustc_typeck/check/method/probe.rs1
-rw-r--r--src/librustc_typeck/collect.rs192
-rw-r--r--src/librustc_typeck/diagnostics.rs92
-rw-r--r--src/librustdoc/clean/mod.rs11
-rw-r--r--src/librustdoc/html/layout.rs27
-rw-r--r--src/librustdoc/html/render.rs51
-rw-r--r--src/librustdoc/html/static/storage.js4
-rw-r--r--src/librustdoc/lib.rs9
-rw-r--r--src/libstd/process.rs71
-rw-r--r--src/libstd/sys/cloudabi/shims/process.rs12
-rw-r--r--src/libstd/sys/redox/process.rs13
-rw-r--r--src/libstd/sys/unix/process/mod.rs2
-rw-r--r--src/libstd/sys/unix/process/process_common.rs14
-rw-r--r--src/libstd/sys/wasm/process.rs12
-rw-r--r--src/libstd/sys/windows/process.rs14
-rw-r--r--src/libsyntax/attr.rs46
-rw-r--r--src/libsyntax/diagnostic_list.rs69
m---------src/llvm0
-rw-r--r--src/rustllvm/llvm-rebuild-trigger2
-rw-r--r--src/test/run-make/save-analysis-fail/foo.rs7
-rw-r--r--src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs2
-rw-r--r--src/tools/compiletest/Cargo.toml8
-rw-r--r--src/tools/compiletest/src/json.rs13
-rw-r--r--src/tools/compiletest/src/main.rs4
-rw-r--r--src/tools/compiletest/src/read2.rs2
m---------src/tools/rust-installer0
87 files changed, 820 insertions, 919 deletions
diff --git a/src/Cargo.lock b/src/Cargo.lock
index 1bf31b2a67c..b70a01ebb3c 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -398,10 +398,12 @@ dependencies = [
  "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -926,12 +928,11 @@ dependencies = [
  "clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "tar 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)",
- "walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "walkdir 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "xz2 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1186,6 +1187,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "miow"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "socket2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "miri"
 version = "0.1.0"
 dependencies = [
@@ -1513,15 +1523,6 @@ dependencies = [
 
 [[package]]
 name = "rayon"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "rayon"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
@@ -2227,15 +2228,6 @@ dependencies = [
 
 [[package]]
 name = "same-file"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "same-file"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
@@ -2781,16 +2773,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "walkdir"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "walkdir"
 version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
@@ -2971,6 +2953,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
 "checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4"
 "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
+"checksum miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9224c91f82b3c47cf53dcf78dfaa20d6888fbcc5d272d5f2fcdf8a697f3c987d"
 "checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09"
 "checksum nibble_vec 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "62e678237a4c70c5f2b917cefd7d080dfbf800421f06e8a59d4e28ef5130fd9e"
 "checksum nix 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "47e49f6982987135c5e9620ab317623e723bd06738fd85377e8d55f57c8b6487"
@@ -3004,7 +2987,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum racer 2.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "034f1c4528581c40a60e96875467c03315868084e08ff4ceb46a00f7be3b16b4"
 "checksum radix_trie 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "211c49b6a9995cac0fd1dd9ca60b42cf3a51e151a12eb954b3a9e75513426ee8"
 "checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1"
-"checksum rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed02d09394c94ffbdfdc755ad62a132e94c3224a8354e78a1200ced34df12edf"
 "checksum rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "485541959c8ecc49865526fe6c4de9653dd6e60d829d6edf0be228167b60372d"
 "checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8"
 "checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
@@ -3027,7 +3009,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum rustc-ap-syntax_pos 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db9de2e927e280c75b8efab9c5f591ad31082d5d2c4c562c68fdba2ee77286b0"
 "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e"
 "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
-"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
 "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
 "checksum schannel 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "acece75e0f987c48863a6c792ec8b7d6c4177d4a027f8ccc72f849794f437016"
 "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d"
@@ -3085,7 +3066,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b"
 "checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
 "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
-"checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff"
 "checksum walkdir 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40b6d201f4f8998a837196b6de9c73e35af14c992cbb92c4ab641d2c2dce52de"
 "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
 "checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in
index 925a361f0b2..c62fa0ede70 100644
--- a/src/bootstrap/mk/Makefile.in
+++ b/src/bootstrap/mk/Makefile.in
@@ -16,6 +16,12 @@ Q := @
 BOOTSTRAP_ARGS :=
 endif
 
+ifdef EXCLUDE_CARGO
+AUX_ARGS := src/tools/cargo src/tools/cargotest
+else
+AUX_ARGS :=
+endif
+
 BOOTSTRAP := $(CFG_PYTHON) $(CFG_SRC_DIR)src/bootstrap/bootstrap.py
 
 all:
@@ -52,14 +58,13 @@ check:
 	$(Q)$(BOOTSTRAP) test $(BOOTSTRAP_ARGS)
 check-aux:
 	$(Q)$(BOOTSTRAP) test \
-		src/tools/cargo \
-		src/tools/cargotest \
 		src/test/pretty \
 		src/test/run-pass/pretty \
 		src/test/run-fail/pretty \
 		src/test/run-pass-valgrind/pretty \
 		src/test/run-pass-fulldeps/pretty \
 		src/test/run-fail-fulldeps/pretty \
+		$(AUX_ARGS) \
 		$(BOOTSTRAP_ARGS)
 check-bootstrap:
 	$(Q)$(CFG_PYTHON) $(CFG_SRC_DIR)src/bootstrap/bootstrap_test.py
diff --git a/src/ci/run.sh b/src/ci/run.sh
index 3be1c255c16..79300e08a7d 100755
--- a/src/ci/run.sh
+++ b/src/ci/run.sh
@@ -104,7 +104,7 @@ else
     travis_fold start "make-$1"
     travis_time_start
     echo "make -j $ncpus $1"
-    make -j $ncpus "$1"
+    make -j $ncpus $1
     local retval=$?
     travis_fold end "make-$1"
     travis_time_finish
diff --git a/src/etc/ziggurat_tables.py b/src/etc/ziggurat_tables.py
deleted file mode 100755
index 762f9565b78..00000000000
--- a/src/etc/ziggurat_tables.py
+++ /dev/null
@@ -1,127 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-# file at the top-level directory of this distribution and at
-# http://rust-lang.org/COPYRIGHT.
-#
-# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-# option. This file may not be copied, modified, or distributed
-# except according to those terms.
-
-# This creates the tables used for distributions implemented using the
-# ziggurat algorithm in `rand::distributions;`. They are
-# (basically) the tables as used in the ZIGNOR variant (Doornik 2005).
-# They are changed rarely, so the generated file should be checked in
-# to git.
-#
-# It creates 3 tables: X as in the paper, F which is f(x_i), and
-# F_DIFF which is f(x_i) - f(x_{i-1}). The latter two are just cached
-# values which is not done in that paper (but is done in other
-# variants). Note that the adZigR table is unnecessary because of
-# algebra.
-#
-# It is designed to be compatible with Python 2 and 3.
-
-from math import exp, sqrt, log, floor
-import random
-
-# The order should match the return value of `tables`
-TABLE_NAMES = ['X', 'F']
-
-# The actual length of the table is 1 more, to stop
-# index-out-of-bounds errors. This should match the bitwise operation
-# to find `i` in `zigurrat` in `libstd/rand/mod.rs`. Also the *_R and
-# *_V constants below depend on this value.
-TABLE_LEN = 256
-
-# equivalent to `zigNorInit` in Doornik2005, but generalised to any
-# distribution. r = dR, v = dV, f = probability density function,
-# f_inv = inverse of f
-def tables(r, v, f, f_inv):
-    # compute the x_i
-    xvec = [0]*(TABLE_LEN+1)
-
-    xvec[0] = v / f(r)
-    xvec[1] = r
-
-    for i in range(2, TABLE_LEN):
-        last = xvec[i-1]
-        xvec[i] = f_inv(v / last + f(last))
-
-    # cache the f's
-    fvec = [0]*(TABLE_LEN+1)
-    for i in range(TABLE_LEN+1):
-        fvec[i] = f(xvec[i])
-
-    return xvec, fvec
-
-# Distributions
-# N(0, 1)
-def norm_f(x):
-    return exp(-x*x/2.0)
-def norm_f_inv(y):
-    return sqrt(-2.0*log(y))
-
-NORM_R = 3.6541528853610088
-NORM_V = 0.00492867323399
-
-NORM = tables(NORM_R, NORM_V,
-              norm_f, norm_f_inv)
-
-# Exp(1)
-def exp_f(x):
-    return exp(-x)
-def exp_f_inv(y):
-    return -log(y)
-
-EXP_R = 7.69711747013104972
-EXP_V = 0.0039496598225815571993
-
-EXP = tables(EXP_R, EXP_V,
-             exp_f, exp_f_inv)
-
-
-# Output the tables/constants/types
-
-def render_static(name, type, value):
-    # no space or
-    return 'pub static %s: %s =%s;\n' % (name, type, value)
-
-# static `name`: [`type`, .. `len(values)`] =
-#     [values[0], ..., values[3],
-#      values[4], ..., values[7],
-#      ... ];
-def render_table(name, values):
-    rows = []
-    # 4 values on each row
-    for i in range(0, len(values), 4):
-        row = values[i:i+4]
-        rows.append(', '.join('%.18f' % f for f in row))
-
-    rendered = '\n    [%s]' % ',\n     '.join(rows)
-    return render_static(name, '[f64, .. %d]' % len(values), rendered)
-
-
-with open('ziggurat_tables.rs', 'w') as f:
-    f.write('''// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Tables for distributions which are sampled using the ziggurat
-// algorithm. Autogenerated by `ziggurat_tables.py`.
-
-pub type ZigTable = &\'static [f64, .. %d];
-'''  % (TABLE_LEN + 1))
-    for name, tables, r in [('NORM', NORM, NORM_R),
-                            ('EXP', EXP, EXP_R)]:
-        f.write(render_static('ZIG_%s_R' % name, 'f64', ' %.18f' % r))
-        for (tabname, table) in zip(TABLE_NAMES, tables):
-            f.write(render_table('ZIG_%s_%s' % (name, tabname), table))
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 25f57d8c0f7..570f745f833 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -829,14 +829,13 @@ impl<'a, T: Clone> Option<&'a mut T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(option_ref_mut_cloned)]
     /// let mut x = 12;
     /// let opt_x = Some(&mut x);
     /// assert_eq!(opt_x, Some(&mut 12));
     /// let cloned = opt_x.cloned();
     /// assert_eq!(cloned, Some(12));
     /// ```
-    #[unstable(feature = "option_ref_mut_cloned", issue = "43738")]
+    #[stable(since = "1.26.0", feature = "option_ref_mut_cloned")]
     pub fn cloned(self) -> Option<T> {
         self.map(|t| t.clone())
     }
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 84fdeba4ab3..ed46296389d 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -559,6 +559,7 @@ define_dep_nodes!( <'tcx>
     [] IsReachableNonGeneric(DefId),
     [] IsMirAvailable(DefId),
     [] ItemAttrs(DefId),
+    [] TransFnAttrs(DefId),
     [] FnArgNames(DefId),
     [] DylibDepFormats(CrateNum),
     [] IsPanicRuntime(CrateNum),
@@ -626,8 +627,6 @@ define_dep_nodes!( <'tcx>
     [input] AllCrateNums,
     [] ExportedSymbols(CrateNum),
     [eval_always] CollectAndPartitionTranslationItems,
-    [] ExportName(DefId),
-    [] ContainsExternIndicator(DefId),
     [] IsTranslatedItem(DefId),
     [] CodegenUnit(InternedString),
     [] CompileCodegenUnit(InternedString),
@@ -637,7 +636,6 @@ define_dep_nodes!( <'tcx>
     [] SubstituteNormalizeAndTestPredicates { key: (DefId, &'tcx Substs<'tcx>) },
 
     [input] TargetFeaturesWhitelist,
-    [] TargetFeaturesEnabled(DefId),
 
     [] InstanceDefSizeEstimate { instance_def: InstanceDef<'tcx> },
 
diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs
index a073910fdc8..d2270345260 100644
--- a/src/librustc/hir/check_attr.rs
+++ b/src/librustc/hir/check_attr.rs
@@ -47,7 +47,7 @@ struct CheckAttrVisitor<'a, 'tcx: 'a> {
 impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
     /// Check any attribute.
     fn check_attributes(&self, item: &hir::Item, target: Target) {
-        self.tcx.target_features_enabled(self.tcx.hir.local_def_id(item.id));
+        self.tcx.trans_fn_attrs(self.tcx.hir.local_def_id(item.id));
 
         for attr in &item.attrs {
             if let Some(name) = attr.name() {
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index c4873cb8307..f4638c23c5f 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -30,12 +30,14 @@ pub use self::Visibility::{Public, Inherited};
 use hir::def::Def;
 use hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX};
 use util::nodemap::{NodeMap, FxHashSet};
+use mir::mono::Linkage;
 
 use syntax_pos::{Span, DUMMY_SP};
 use syntax::codemap::{self, Spanned};
 use syntax::abi::Abi;
 use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID, AsmDialect};
 use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
+use syntax::attr::InlineAttr;
 use syntax::ext::hygiene::SyntaxContext;
 use syntax::ptr::P;
 use syntax::symbol::{Symbol, keywords};
@@ -2210,3 +2212,51 @@ pub type GlobMap = NodeMap<FxHashSet<Name>>;
 pub fn provide(providers: &mut Providers) {
     providers.describe_def = map::describe_def;
 }
+
+#[derive(Clone, RustcEncodable, RustcDecodable, Hash)]
+pub struct TransFnAttrs {
+    pub flags: TransFnAttrFlags,
+    pub inline: InlineAttr,
+    pub export_name: Option<Symbol>,
+    pub target_features: Vec<Symbol>,
+    pub linkage: Option<Linkage>,
+}
+
+bitflags! {
+    #[derive(RustcEncodable, RustcDecodable)]
+    pub struct TransFnAttrFlags: u8 {
+        const COLD                      = 0b0000_0001;
+        const ALLOCATOR                 = 0b0000_0010;
+        const UNWIND                    = 0b0000_0100;
+        const RUSTC_ALLOCATOR_NOUNWIND  = 0b0000_1000;
+        const NAKED                     = 0b0001_0000;
+        const NO_MANGLE                 = 0b0010_0000;
+        const RUSTC_STD_INTERNAL_SYMBOL = 0b0100_0000;
+    }
+}
+
+impl TransFnAttrs {
+    pub fn new() -> TransFnAttrs {
+        TransFnAttrs {
+            flags: TransFnAttrFlags::empty(),
+            inline: InlineAttr::None,
+            export_name: None,
+            target_features: vec![],
+            linkage: None,
+        }
+    }
+
+    /// True if `#[inline]` or `#[inline(always)]` is present.
+    pub fn requests_inline(&self) -> bool {
+        match self.inline {
+            InlineAttr::Hint | InlineAttr::Always => true,
+            InlineAttr::None | InlineAttr::Never => false,
+        }
+    }
+
+    /// True if `#[no_mangle]` or `#[export_name(...)]` is present.
+    pub fn contains_extern_indicator(&self) -> bool {
+        self.flags.contains(TransFnAttrFlags::NO_MANGLE) || self.export_name.is_some()
+    }
+}
+
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
index 7dca96f94e6..faad3f35631 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc/ich/impls_hir.rs
@@ -19,6 +19,7 @@ use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
                                            StableHasher, StableHasherResult};
 use std::mem;
 use syntax::ast;
+use syntax::attr;
 
 impl<'gcx> HashStable<StableHashingContext<'gcx>> for DefId {
     #[inline]
@@ -1138,6 +1139,43 @@ impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for hir::TraitCandidate {
     }
 }
 
+impl<'hir> HashStable<StableHashingContext<'hir>> for hir::TransFnAttrs
+{
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'hir>,
+                                          hasher: &mut StableHasher<W>) {
+        let hir::TransFnAttrs {
+            flags,
+            inline,
+            export_name,
+            ref target_features,
+            linkage,
+        } = *self;
+
+        flags.hash_stable(hcx, hasher);
+        inline.hash_stable(hcx, hasher);
+        export_name.hash_stable(hcx, hasher);
+        target_features.hash_stable(hcx, hasher);
+        linkage.hash_stable(hcx, hasher);
+    }
+}
+
+impl<'hir> HashStable<StableHashingContext<'hir>> for hir::TransFnAttrFlags
+{
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'hir>,
+                                          hasher: &mut StableHasher<W>) {
+        self.bits().hash_stable(hcx, hasher);
+    }
+}
+
+impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'hir>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+    }
+}
 
 impl_stable_hash_for!(struct hir::Freevar {
     def,
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index 7b2cfa0a3ff..a8ed885e78d 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -244,7 +244,6 @@ impl_stable_hash_for!(enum ty::Visibility {
 
 impl_stable_hash_for!(struct ty::TraitRef<'tcx> { def_id, substs });
 impl_stable_hash_for!(struct ty::TraitPredicate<'tcx> { trait_ref });
-impl_stable_hash_for!(tuple_struct ty::EquatePredicate<'tcx> { t1, t2 });
 impl_stable_hash_for!(struct ty::SubtypePredicate<'tcx> { a_is_expected, a, b });
 
 impl<'gcx, A, B> HashStable<StableHashingContext<'gcx>>
@@ -274,9 +273,6 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::Predicate<'gcx> {
             ty::Predicate::Trait(ref pred) => {
                 pred.hash_stable(hcx, hasher);
             }
-            ty::Predicate::Equate(ref pred) => {
-                pred.hash_stable(hcx, hasher);
-            }
             ty::Predicate::Subtype(ref pred) => {
                 pred.hash_stable(hcx, hasher);
             }
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 559b2720076..0645bffafe7 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -1280,7 +1280,6 @@ impl<'tcx> ObligationCause<'tcx> {
             }),
             IfExpression => Error0308("if and else have incompatible types"),
             IfExpressionWithNoElse => Error0317("if may be missing an else clause"),
-            EquatePredicate => Error0308("equality predicate not satisfied"),
             MainFunctionType => Error0580("main function has wrong type"),
             StartFunctionType => Error0308("start function has wrong type"),
             IntrinsicType => Error0308("intrinsic has wrong type"),
@@ -1309,7 +1308,6 @@ impl<'tcx> ObligationCause<'tcx> {
             },
             IfExpression => "if and else have compatible types",
             IfExpressionWithNoElse => "if missing an else returns ()",
-            EquatePredicate => "equality where clause is satisfied",
             MainFunctionType => "`main` function has the correct type",
             StartFunctionType => "`start` function has the correct type",
             IntrinsicType => "intrinsic has the correct type",
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 402cb6a8fef..5d44b2043e2 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -943,23 +943,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         self.borrow_region_constraints().make_subregion(origin, a, b);
     }
 
-    pub fn equality_predicate(&self,
-                              cause: &ObligationCause<'tcx>,
-                              param_env: ty::ParamEnv<'tcx>,
-                              predicate: &ty::PolyEquatePredicate<'tcx>)
-        -> InferResult<'tcx, ()>
-    {
-        self.commit_if_ok(|snapshot| {
-            let (ty::EquatePredicate(a, b), skol_map) =
-                self.skolemize_late_bound_regions(predicate, snapshot);
-            let cause_span = cause.span;
-            let eqty_ok = self.at(cause, param_env).eq(b, a)?;
-            self.leak_check(false, cause_span, &skol_map, snapshot)?;
-            self.pop_skolemized(skol_map, snapshot);
-            Ok(eqty_ok.unit())
-        })
-    }
-
     pub fn subtype_predicate(&self,
                              cause: &ObligationCause<'tcx>,
                              param_env: ty::ParamEnv<'tcx>,
diff --git a/src/librustc/infer/outlives/bounds.rs b/src/librustc/infer/outlives/bounds.rs
index 8a562471ac5..abb35d24d79 100644
--- a/src/librustc/infer/outlives/bounds.rs
+++ b/src/librustc/infer/outlives/bounds.rs
@@ -117,7 +117,6 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
                 assert!(!obligation.has_escaping_regions());
                 match obligation.predicate {
                     ty::Predicate::Trait(..) |
-                    ty::Predicate::Equate(..) |
                     ty::Predicate::Subtype(..) |
                     ty::Predicate::Projection(..) |
                     ty::Predicate::ClosureKind(..) |
@@ -204,7 +203,6 @@ pub fn explicit_outlives_bounds<'tcx>(
         .filter_map(move |predicate| match predicate {
             ty::Predicate::Projection(..) |
             ty::Predicate::Trait(..) |
-            ty::Predicate::Equate(..) |
             ty::Predicate::Subtype(..) |
             ty::Predicate::WellFormed(..) |
             ty::Predicate::ObjectSafe(..) |
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index 5dbe2ef516c..3c451d7ae46 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -36,13 +36,12 @@ use session::search_paths::PathKind;
 use std::any::Any;
 use std::collections::BTreeMap;
 use std::path::{Path, PathBuf};
-use rustc_data_structures::owning_ref::ErasedBoxRef;
 use syntax::ast;
 use syntax::ext::base::SyntaxExtension;
 use syntax::symbol::Symbol;
 use syntax_pos::Span;
 use rustc_back::target::Target;
-use rustc_data_structures::sync::Lrc;
+use rustc_data_structures::sync::{MetadataRef, Lrc};
 
 pub use self::NativeLibraryKind::*;
 
@@ -186,11 +185,11 @@ pub trait MetadataLoader {
     fn get_rlib_metadata(&self,
                          target: &Target,
                          filename: &Path)
-                         -> Result<ErasedBoxRef<[u8]>, String>;
+                         -> Result<MetadataRef, String>;
     fn get_dylib_metadata(&self,
                           target: &Target,
                           filename: &Path)
-                          -> Result<ErasedBoxRef<[u8]>, String>;
+                          -> Result<MetadataRef, String>;
 }
 
 #[derive(Clone)]
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 5658b5b6832..48a62c8c14d 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -15,6 +15,7 @@
 // makes all other generics or inline functions that it references
 // reachable as well.
 
+use hir::TransFnAttrs;
 use hir::map as hir_map;
 use hir::def::Def;
 use hir::def_id::{DefId, CrateNum};
@@ -43,8 +44,8 @@ fn generics_require_inlining(generics: &hir::Generics) -> bool {
 // Returns true if the given item must be inlined because it may be
 // monomorphized or it was marked with `#[inline]`. This will only return
 // true for functions.
-fn item_might_be_inlined(item: &hir::Item) -> bool {
-    if attr::requests_inline(&item.attrs) {
+fn item_might_be_inlined(item: &hir::Item, attrs: TransFnAttrs) -> bool {
+    if attrs.requests_inline() {
         return true
     }
 
@@ -60,14 +61,15 @@ fn item_might_be_inlined(item: &hir::Item) -> bool {
 fn method_might_be_inlined<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                      impl_item: &hir::ImplItem,
                                      impl_src: DefId) -> bool {
-    if attr::requests_inline(&impl_item.attrs) ||
+    let trans_fn_attrs = tcx.trans_fn_attrs(impl_item.hir_id.owner_def_id());
+    if trans_fn_attrs.requests_inline() ||
         generics_require_inlining(&impl_item.generics) {
         return true
     }
     if let Some(impl_node_id) = tcx.hir.as_local_node_id(impl_src) {
         match tcx.hir.find(impl_node_id) {
             Some(hir_map::NodeItem(item)) =>
-                item_might_be_inlined(&item),
+                item_might_be_inlined(&item, trans_fn_attrs),
             Some(..) | None =>
                 span_bug!(impl_item.span, "impl did is not an item")
         }
@@ -160,7 +162,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
         match self.tcx.hir.find(node_id) {
             Some(hir_map::NodeItem(item)) => {
                 match item.node {
-                    hir::ItemFn(..) => item_might_be_inlined(&item),
+                    hir::ItemFn(..) =>
+                        item_might_be_inlined(&item, self.tcx.trans_fn_attrs(def_id)),
                     _ => false,
                 }
             }
@@ -176,8 +179,9 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                 match impl_item.node {
                     hir::ImplItemKind::Const(..) => true,
                     hir::ImplItemKind::Method(..) => {
+                        let attrs = self.tcx.trans_fn_attrs(def_id);
                         if generics_require_inlining(&impl_item.generics) ||
-                                attr::requests_inline(&impl_item.attrs) {
+                                attrs.requests_inline() {
                             true
                         } else {
                             let impl_did = self.tcx
@@ -229,7 +233,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                     false
                 };
                 let def_id = self.tcx.hir.local_def_id(item.id);
-                let is_extern = self.tcx.contains_extern_indicator(def_id);
+                let is_extern = self.tcx.trans_fn_attrs(def_id).contains_extern_indicator();
                 if reachable || is_extern {
                     self.reachable_symbols.insert(search_item);
                 }
@@ -246,7 +250,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
             hir_map::NodeItem(item) => {
                 match item.node {
                     hir::ItemFn(.., body) => {
-                        if item_might_be_inlined(&item) {
+                        let def_id = self.tcx.hir.local_def_id(item.id);
+                        if item_might_be_inlined(&item, self.tcx.trans_fn_attrs(def_id)) {
                             self.visit_nested_body(body);
                         }
                     }
diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs
index 7f8f2e9b906..d8eac2b4159 100644
--- a/src/librustc/mir/mono.rs
+++ b/src/librustc/mir/mono.rs
@@ -73,7 +73,7 @@ pub struct CodegenUnit<'tcx> {
     size_estimate: Option<usize>,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
 pub enum Linkage {
     External,
     AvailableExternally,
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index b1d21420606..ce23cb23496 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -631,16 +631,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                         span_bug!(span, "subtype requirement gave wrong error: `{:?}`", predicate)
                     }
 
-                    ty::Predicate::Equate(ref predicate) => {
-                        let predicate = self.resolve_type_vars_if_possible(predicate);
-                        let err = self.equality_predicate(&obligation.cause,
-                                                          obligation.param_env,
-                                                          &predicate).err().unwrap();
-                        struct_span_err!(self.tcx.sess, span, E0278,
-                            "the requirement `{}` is not satisfied (`{}`)",
-                            predicate, err)
-                    }
-
                     ty::Predicate::RegionOutlives(ref predicate) => {
                         let predicate = self.resolve_type_vars_if_possible(predicate);
                         let err = self.region_outlives_predicate(&obligation.cause,
@@ -1270,7 +1260,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             ObligationCauseCode::MatchExpressionArm { .. } |
             ObligationCauseCode::IfExpression |
             ObligationCauseCode::IfExpressionWithNoElse |
-            ObligationCauseCode::EquatePredicate |
             ObligationCauseCode::MainFunctionType |
             ObligationCauseCode::StartFunctionType |
             ObligationCauseCode::IntrinsicType |
diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs
index 93e33836818..2f3e19d92bc 100644
--- a/src/librustc/traits/fulfill.rs
+++ b/src/librustc/traits/fulfill.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use infer::{RegionObligation, InferCtxt, InferOk};
+use infer::{RegionObligation, InferCtxt};
 use ty::{self, Ty, TypeFoldable, ToPolyTraitRef, ToPredicate};
 use ty::error::ExpectedFound;
 use rustc_data_structures::obligation_forest::{ObligationForest, Error};
@@ -380,17 +380,6 @@ fn process_predicate<'a, 'gcx, 'tcx>(
             }
         }
 
-        ty::Predicate::Equate(ref binder) => {
-            match selcx.infcx().equality_predicate(&obligation.cause,
-                                                   obligation.param_env,
-                                                   binder) {
-                Ok(InferOk { obligations, value: () }) => {
-                    Ok(Some(obligations))
-                },
-                Err(_) => Err(CodeSelectionError(Unimplemented)),
-            }
-        }
-
         ty::Predicate::RegionOutlives(ref binder) => {
             match selcx.infcx().region_outlives_predicate(&obligation.cause, binder) {
                 Ok(()) => Ok(Some(Vec::new())),
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index b9ae4599d80..8ac69c4b528 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -204,9 +204,6 @@ pub enum ObligationCauseCode<'tcx> {
     /// Computing common supertype of an if expression with no else counter-part
     IfExpressionWithNoElse,
 
-    /// `where a == b`
-    EquatePredicate,
-
     /// `main` has wrong type
     MainFunctionType,
 
@@ -854,19 +851,6 @@ impl<'tcx, N> Vtable<'tcx, N> {
         }
     }
 
-    fn nested_obligations_mut(&mut self) -> &mut Vec<N> {
-        match self {
-            &mut VtableImpl(ref mut i) => &mut i.nested,
-            &mut VtableParam(ref mut n) => n,
-            &mut VtableBuiltin(ref mut i) => &mut i.nested,
-            &mut VtableAutoImpl(ref mut d) => &mut d.nested,
-            &mut VtableGenerator(ref mut c) => &mut c.nested,
-            &mut VtableClosure(ref mut c) => &mut c.nested,
-            &mut VtableObject(ref mut d) => &mut d.nested,
-            &mut VtableFnPointer(ref mut d) => &mut d.nested,
-        }
-    }
-
     pub fn map<M, F>(self, f: F) -> Vtable<'tcx, M> where F: FnMut(N) -> M {
         match self {
             VtableImpl(i) => VtableImpl(VtableImplData {
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index 4151661b593..52a0a897595 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -175,7 +175,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                     ty::Predicate::RegionOutlives(..) |
                     ty::Predicate::ClosureKind(..) |
                     ty::Predicate::Subtype(..) |
-                    ty::Predicate::Equate(..) |
                     ty::Predicate::ConstEvaluatable(..) => {
                         false
                     }
@@ -204,7 +203,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                     }
                     ty::Predicate::Projection(..) |
                     ty::Predicate::Trait(..) |
-                    ty::Predicate::Equate(..) |
                     ty::Predicate::Subtype(..) |
                     ty::Predicate::RegionOutlives(..) |
                     ty::Predicate::WellFormed(..) |
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 9e24a4e6afa..600b4a515f0 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -44,12 +44,10 @@ use ty::relate::TypeRelation;
 use middle::lang_items;
 
 use rustc_data_structures::bitvec::BitVector;
-use rustc_data_structures::snapshot_vec::{SnapshotVecDelegate, SnapshotVec};
 use std::iter;
 use std::cell::RefCell;
 use std::cmp;
 use std::fmt;
-use std::marker::PhantomData;
 use std::mem;
 use std::rc::Rc;
 use syntax::abi::Abi;
@@ -57,14 +55,6 @@ use hir;
 use lint;
 use util::nodemap::{FxHashMap, FxHashSet};
 
-struct InferredObligationsSnapshotVecDelegate<'tcx> {
-    phantom: PhantomData<&'tcx i32>,
-}
-impl<'tcx> SnapshotVecDelegate for InferredObligationsSnapshotVecDelegate<'tcx> {
-    type Value = PredicateObligation<'tcx>;
-    type Undo = ();
-    fn reverse(_: &mut Vec<Self::Value>, _: Self::Undo) {}
-}
 
 pub struct SelectionContext<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
     infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
@@ -92,8 +82,6 @@ pub struct SelectionContext<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
     /// would satisfy it. This avoids crippling inference, basically.
     intercrate: Option<IntercrateMode>,
 
-    inferred_obligations: SnapshotVec<InferredObligationsSnapshotVecDelegate<'tcx>>,
-
     intercrate_ambiguity_causes: Option<Vec<IntercrateAmbiguityCause>>,
 
     /// Controls whether or not to filter out negative impls when selecting.
@@ -429,7 +417,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
             infcx,
             freshener: infcx.freshener(),
             intercrate: None,
-            inferred_obligations: SnapshotVec::new(),
             intercrate_ambiguity_causes: None,
             allow_negative_impls: false,
         }
@@ -442,7 +429,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
             infcx,
             freshener: infcx.freshener(),
             intercrate: Some(mode),
-            inferred_obligations: SnapshotVec::new(),
             intercrate_ambiguity_causes: None,
             allow_negative_impls: false,
         }
@@ -455,7 +441,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
             infcx,
             freshener: infcx.freshener(),
             intercrate: None,
-            inferred_obligations: SnapshotVec::new(),
             intercrate_ambiguity_causes: None,
             allow_negative_impls,
         }
@@ -498,8 +483,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
     fn in_snapshot<R, F>(&mut self, f: F) -> R
         where F: FnOnce(&mut Self, &infer::CombinedSnapshot<'cx, 'tcx>) -> R
     {
-        // The irrefutable nature of the operation means we don't need to snapshot the
-        // inferred_obligations vector.
         self.infcx.in_snapshot(|snapshot| f(self, snapshot))
     }
 
@@ -508,10 +491,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
     fn probe<R, F>(&mut self, f: F) -> R
         where F: FnOnce(&mut Self, &infer::CombinedSnapshot<'cx, 'tcx>) -> R
     {
-        let inferred_obligations_snapshot = self.inferred_obligations.start_snapshot();
-        let result = self.infcx.probe(|snapshot| f(self, snapshot));
-        self.inferred_obligations.rollback_to(inferred_obligations_snapshot);
-        result
+        self.infcx.probe(|snapshot| f(self, snapshot))
     }
 
     /// Wraps a commit_if_ok s.t. obligations collected during it are not returned in selection if
@@ -519,17 +499,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
     fn commit_if_ok<T, E, F>(&mut self, f: F) -> Result<T, E> where
         F: FnOnce(&mut Self, &infer::CombinedSnapshot) -> Result<T, E>
     {
-        let inferred_obligations_snapshot = self.inferred_obligations.start_snapshot();
-        match self.infcx.commit_if_ok(|snapshot| f(self, snapshot)) {
-            Ok(ok) => {
-                self.inferred_obligations.commit(inferred_obligations_snapshot);
-                Ok(ok)
-            },
-            Err(err) => {
-                self.inferred_obligations.rollback_to(inferred_obligations_snapshot);
-                Err(err)
-            }
-        }
+        self.infcx.commit_if_ok(|snapshot| f(self, snapshot))
     }
 
 
@@ -560,12 +530,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
         let stack = self.push_stack(TraitObligationStackList::empty(), obligation);
         let ret = match self.candidate_from_obligation(&stack)? {
             None => None,
-            Some(candidate) => {
-                let mut candidate = self.confirm_candidate(obligation, candidate)?;
-                let inferred_obligations = (*self.inferred_obligations).into_iter().cloned();
-                candidate.nested_obligations_mut().extend(inferred_obligations);
-                Some(candidate)
-            },
+            Some(candidate) => Some(self.confirm_candidate(obligation, candidate)?)
         };
 
         // Test whether this is a `()` which was produced by defaulting a
@@ -658,7 +623,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                                                 stack: TraitObligationStackList<'o, 'tcx>,
                                                 predicates: I)
                                                 -> EvaluationResult
-        where I : Iterator<Item=&'a PredicateObligation<'tcx>>, 'tcx:'a
+        where I : IntoIterator<Item=&'a PredicateObligation<'tcx>>, 'tcx:'a
     {
         let mut result = EvaluatedToOk;
         for obligation in predicates {
@@ -691,22 +656,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                 self.evaluate_trait_predicate_recursively(previous_stack, obligation)
             }
 
-            ty::Predicate::Equate(ref p) => {
-                // does this code ever run?
-                match self.infcx.equality_predicate(&obligation.cause, obligation.param_env, p) {
-                    Ok(InferOk { obligations, .. }) => {
-                        self.inferred_obligations.extend(obligations);
-                        EvaluatedToOk
-                    },
-                    Err(_) => EvaluatedToErr
-                }
-            }
-
             ty::Predicate::Subtype(ref p) => {
                 // does this code ever run?
                 match self.infcx.subtype_predicate(&obligation.cause, obligation.param_env, p) {
                     Some(Ok(InferOk { obligations, .. })) => {
-                        self.inferred_obligations.extend(obligations);
+                        self.evaluate_predicates_recursively(previous_stack, &obligations);
                         EvaluatedToOk
                     },
                     Some(Err(_)) => EvaluatedToErr,
@@ -1553,12 +1507,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                         -> bool
     {
         assert!(!skol_trait_ref.has_escaping_regions());
-        match self.infcx.at(&obligation.cause, obligation.param_env)
-                        .sup(ty::Binder(skol_trait_ref), trait_bound) {
-            Ok(InferOk { obligations, .. }) => {
-                self.inferred_obligations.extend(obligations);
-            }
-            Err(_) => { return false; }
+        if let Err(_) = self.infcx.at(&obligation.cause, obligation.param_env)
+                                  .sup(ty::Binder(skol_trait_ref), trait_bound) {
+            return false;
         }
 
         self.infcx.leak_check(false, obligation.cause.span, skol_map, snapshot).is_ok()
@@ -2644,6 +2595,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
         };
 
         let mut upcast_trait_ref = None;
+        let mut nested = vec![];
         let vtable_base;
 
         {
@@ -2662,7 +2614,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                         self.commit_if_ok(
                             |this, _| this.match_poly_trait_ref(obligation, t))
                     {
-                        Ok(_) => { upcast_trait_ref = Some(t); false }
+                        Ok(obligations) => {
+                            upcast_trait_ref = Some(t);
+                            nested.extend(obligations);
+                            false
+                        }
                         Err(_) => { true }
                     }
                 });
@@ -2680,7 +2636,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
         VtableObjectData {
             upcast_trait_ref: upcast_trait_ref.unwrap(),
             vtable_base,
-            nested: vec![]
+            nested,
         }
     }
 
@@ -2737,7 +2693,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
             self.generator_trait_ref_unnormalized(obligation, closure_def_id, substs);
         let Normalized {
             value: trait_ref,
-            obligations
+            mut obligations
         } = normalize_with_depth(self,
                                  obligation.param_env,
                                  obligation.cause.clone(),
@@ -2749,10 +2705,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                trait_ref,
                obligations);
 
-        self.confirm_poly_trait_refs(obligation.cause.clone(),
-                                     obligation.param_env,
-                                     obligation.predicate.to_poly_trait_ref(),
-                                     trait_ref)?;
+        obligations.extend(
+            self.confirm_poly_trait_refs(obligation.cause.clone(),
+                                        obligation.param_env,
+                                        obligation.predicate.to_poly_trait_ref(),
+                                        trait_ref)?);
 
         Ok(VtableGeneratorData {
             closure_def_id: closure_def_id,
@@ -2798,10 +2755,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                trait_ref,
                obligations);
 
-        self.confirm_poly_trait_refs(obligation.cause.clone(),
-                                     obligation.param_env,
-                                     obligation.predicate.to_poly_trait_ref(),
-                                     trait_ref)?;
+        obligations.extend(
+            self.confirm_poly_trait_refs(obligation.cause.clone(),
+                                        obligation.param_env,
+                                        obligation.predicate.to_poly_trait_ref(),
+                                        trait_ref)?);
 
         obligations.push(Obligation::new(
             obligation.cause.clone(),
@@ -2845,13 +2803,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                                obligation_param_env: ty::ParamEnv<'tcx>,
                                obligation_trait_ref: ty::PolyTraitRef<'tcx>,
                                expected_trait_ref: ty::PolyTraitRef<'tcx>)
-                               -> Result<(), SelectionError<'tcx>>
+                               -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>
     {
         let obligation_trait_ref = obligation_trait_ref.clone();
         self.infcx
             .at(&obligation_cause, obligation_param_env)
             .sup(obligation_trait_ref, expected_trait_ref)
-            .map(|InferOk { obligations, .. }| self.inferred_obligations.extend(obligations))
+            .map(|InferOk { obligations, .. }| obligations)
             .map_err(|e| OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e))
     }
 
@@ -2888,7 +2846,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                     self.infcx.at(&obligation.cause, obligation.param_env)
                               .eq(target, new_trait)
                               .map_err(|_| Unimplemented)?;
-                self.inferred_obligations.extend(obligations);
+                nested.extend(obligations);
 
                 // Register one obligation for 'a: 'b.
                 let cause = ObligationCause::new(obligation.cause.span,
@@ -2950,7 +2908,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                     self.infcx.at(&obligation.cause, obligation.param_env)
                               .eq(b, a)
                               .map_err(|_| Unimplemented)?;
-                self.inferred_obligations.extend(obligations);
+                nested.extend(obligations);
             }
 
             // Struct<T> -> Struct<U>.
@@ -3014,7 +2972,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                     self.infcx.at(&obligation.cause, obligation.param_env)
                               .eq(target, new_struct)
                               .map_err(|_| Unimplemented)?;
-                self.inferred_obligations.extend(obligations);
+                nested.extend(obligations);
 
                 // Construct the nested Field<T>: Unsize<Field<U>> predicate.
                 nested.push(tcx.predicate_for_trait_def(
@@ -3045,7 +3003,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                     self.infcx.at(&obligation.cause, obligation.param_env)
                               .eq(target, new_tuple)
                               .map_err(|_| Unimplemented)?;
-                self.inferred_obligations.extend(obligations);
+                nested.extend(obligations);
 
                 // Construct the nested T: Unsize<U> predicate.
                 nested.push(tcx.predicate_for_trait_def(
@@ -3118,7 +3076,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
         let impl_trait_ref = impl_trait_ref.subst(self.tcx(),
                                                   impl_substs);
 
-        let impl_trait_ref =
+        let Normalized { value: impl_trait_ref, obligations: mut nested_obligations } =
             project::normalize_with_depth(self,
                                           obligation.param_env,
                                           obligation.cause.clone(),
@@ -3134,12 +3092,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
 
         let InferOk { obligations, .. } =
             self.infcx.at(&obligation.cause, obligation.param_env)
-                      .eq(skol_obligation_trait_ref, impl_trait_ref.value)
+                      .eq(skol_obligation_trait_ref, impl_trait_ref)
                       .map_err(|e| {
                           debug!("match_impl: failed eq_trait_refs due to `{}`", e);
                           ()
                       })?;
-        self.inferred_obligations.extend(obligations);
+        nested_obligations.extend(obligations);
 
         if let Err(e) = self.infcx.leak_check(false,
                                               obligation.cause.span,
@@ -3152,7 +3110,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
         debug!("match_impl: success impl_substs={:?}", impl_substs);
         Ok((Normalized {
             value: impl_substs,
-            obligations: impl_trait_ref.obligations
+            obligations: nested_obligations
         }, skol_map))
     }
 
@@ -3189,8 +3147,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                                     where_clause_trait_ref: ty::PolyTraitRef<'tcx>)
                                     -> Result<Vec<PredicateObligation<'tcx>>,()>
     {
-        self.match_poly_trait_ref(obligation, where_clause_trait_ref)?;
-        Ok(Vec::new())
+        self.match_poly_trait_ref(obligation, where_clause_trait_ref)
     }
 
     /// Returns `Ok` if `poly_trait_ref` being true implies that the
@@ -3198,7 +3155,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
     fn match_poly_trait_ref(&mut self,
                             obligation: &TraitObligation<'tcx>,
                             poly_trait_ref: ty::PolyTraitRef<'tcx>)
-                            -> Result<(),()>
+                            -> Result<Vec<PredicateObligation<'tcx>>,()>
     {
         debug!("match_poly_trait_ref: obligation={:?} poly_trait_ref={:?}",
                obligation,
@@ -3206,7 +3163,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
 
         self.infcx.at(&obligation.cause, obligation.param_env)
                   .sup(obligation.predicate.to_poly_trait_ref(), poly_trait_ref)
-                  .map(|InferOk { obligations, .. }| self.inferred_obligations.extend(obligations))
+                  .map(|InferOk { obligations, .. }| obligations)
                   .map_err(|_| ())
     }
 
diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs
index 1eb14a22278..9dd5aaee7b7 100644
--- a/src/librustc/traits/structural_impls.rs
+++ b/src/librustc/traits/structural_impls.rs
@@ -236,7 +236,6 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
             }
             super::IfExpression => Some(super::IfExpression),
             super::IfExpressionWithNoElse => Some(super::IfExpressionWithNoElse),
-            super::EquatePredicate => Some(super::EquatePredicate),
             super::MainFunctionType => Some(super::MainFunctionType),
             super::StartFunctionType => Some(super::StartFunctionType),
             super::IntrinsicType => Some(super::IntrinsicType),
@@ -512,7 +511,6 @@ impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
             super::MatchExpressionArm { arm_span: _, source: _ } |
             super::IfExpression |
             super::IfExpressionWithNoElse |
-            super::EquatePredicate |
             super::MainFunctionType |
             super::StartFunctionType |
             super::IntrinsicType |
@@ -561,7 +559,6 @@ impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
             super::MatchExpressionArm { arm_span: _, source: _ } |
             super::IfExpression |
             super::IfExpressionWithNoElse |
-            super::EquatePredicate |
             super::MainFunctionType |
             super::StartFunctionType |
             super::IntrinsicType |
diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs
index 898accb9021..c562f2cd48d 100644
--- a/src/librustc/traits/util.rs
+++ b/src/librustc/traits/util.rs
@@ -25,9 +25,6 @@ fn anonymize_predicate<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
         ty::Predicate::Trait(ref data) =>
             ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data)),
 
-        ty::Predicate::Equate(ref data) =>
-            ty::Predicate::Equate(tcx.anonymize_late_bound_regions(data)),
-
         ty::Predicate::RegionOutlives(ref data) =>
             ty::Predicate::RegionOutlives(tcx.anonymize_late_bound_regions(data)),
 
@@ -163,11 +160,6 @@ impl<'cx, 'gcx, 'tcx> Elaborator<'cx, 'gcx, 'tcx> {
                 // Currently, we do not elaborate object-safe
                 // predicates.
             }
-            ty::Predicate::Equate(..) => {
-                // Currently, we do not "elaborate" predicates like
-                // `X == Y`, though conceivably we might. For example,
-                // `&X == &Y` implies that `X == Y`.
-            }
             ty::Predicate::Subtype(..) => {
                 // Currently, we do not "elaborate" predicates like `X
                 // <: Y`, though conceivably we might.
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs
index f4b5ffbb7dc..a5f0abb9bc0 100644
--- a/src/librustc/ty/instance.rs
+++ b/src/librustc/ty/instance.rs
@@ -96,7 +96,6 @@ impl<'tcx> InstanceDef<'tcx> {
         &self,
         tcx: TyCtxt<'a, 'tcx, 'tcx>
     ) -> bool {
-        use syntax::attr::requests_inline;
         if self.is_inline(tcx) {
             return true
         }
@@ -106,8 +105,8 @@ impl<'tcx> InstanceDef<'tcx> {
             // available to normal end-users.
             return true
         }
-        requests_inline(&self.attrs(tcx)[..]) ||
-            tcx.is_const_fn(self.def_id())
+        let trans_fn_attrs = tcx.trans_fn_attrs(self.def_id());
+        trans_fn_attrs.requests_inline() || tcx.is_const_fn(self.def_id())
     }
 }
 
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index c3cd65230bd..5069c595626 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -1203,7 +1203,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
                 }
 
                 let pointee = tcx.normalize_associated_type_in_env(&pointee, param_env);
-                if pointee.is_sized(tcx, param_env, DUMMY_SP) {
+                if pointee.is_sized(tcx.at(DUMMY_SP), param_env) {
                     return Ok(tcx.intern_layout(LayoutDetails::scalar(self, data_ptr)));
                 }
 
@@ -1428,7 +1428,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
                         let param_env = tcx.param_env(def.did);
                         let last_field = def.variants[v].fields.last().unwrap();
                         let always_sized = tcx.type_of(last_field.did)
-                          .is_sized(tcx, param_env, DUMMY_SP);
+                          .is_sized(tcx.at(DUMMY_SP), param_env);
                         if !always_sized { StructKind::MaybeUnsized }
                         else { StructKind::AlwaysSized }
                     };
diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs
index cfc552bdc85..d880b022e2f 100644
--- a/src/librustc/ty/maps/config.rs
+++ b/src/librustc/ty/maps/config.rs
@@ -687,8 +687,8 @@ impl_disk_cacheable_query!(borrowck, |def_id| def_id.is_local());
 impl_disk_cacheable_query!(mir_borrowck, |def_id| def_id.is_local());
 impl_disk_cacheable_query!(mir_const_qualif, |def_id| def_id.is_local());
 impl_disk_cacheable_query!(check_match, |def_id| def_id.is_local());
-impl_disk_cacheable_query!(contains_extern_indicator, |_| true);
 impl_disk_cacheable_query!(def_symbol_name, |_| true);
 impl_disk_cacheable_query!(type_of, |def_id| def_id.is_local());
 impl_disk_cacheable_query!(predicates_of, |def_id| def_id.is_local());
 impl_disk_cacheable_query!(used_trait_imports, |def_id| def_id.is_local());
+impl_disk_cacheable_query!(trans_fn_attrs, |_| true);
diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs
index 2ef97b2673d..43a71f1c0d3 100644
--- a/src/librustc/ty/maps/mod.rs
+++ b/src/librustc/ty/maps/mod.rs
@@ -12,7 +12,7 @@ use dep_graph::{DepConstructor, DepNode};
 use errors::DiagnosticBuilder;
 use hir::def_id::{CrateNum, DefId, DefIndex};
 use hir::def::{Def, Export};
-use hir::{self, TraitCandidate, ItemLocalId};
+use hir::{self, TraitCandidate, ItemLocalId, TransFnAttrs};
 use hir::svh::Svh;
 use lint;
 use middle::borrowck::BorrowCheckResult;
@@ -235,6 +235,7 @@ define_maps! { <'tcx>
     [] fn lookup_stability: LookupStability(DefId) -> Option<&'tcx attr::Stability>,
     [] fn lookup_deprecation_entry: LookupDeprecationEntry(DefId) -> Option<DeprecationEntry>,
     [] fn item_attrs: ItemAttrs(DefId) -> Lrc<[ast::Attribute]>,
+    [] fn trans_fn_attrs: trans_fn_attrs(DefId) -> TransFnAttrs,
     [] fn fn_arg_names: FnArgNames(DefId) -> Vec<ast::Name>,
     [] fn impl_parent: ImplParent(DefId) -> Option<DefId>,
     [] fn trait_of_item: TraitOfItem(DefId) -> Option<DefId>,
@@ -362,8 +363,6 @@ define_maps! { <'tcx>
     [] fn collect_and_partition_translation_items:
         collect_and_partition_translation_items_node(CrateNum)
         -> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'tcx>>>>),
-    [] fn export_name: ExportName(DefId) -> Option<Symbol>,
-    [] fn contains_extern_indicator: ContainsExternIndicator(DefId) -> bool,
     [] fn symbol_export_level: GetSymbolExportLevel(DefId) -> SymbolExportLevel,
     [] fn is_translated_item: IsTranslatedItem(DefId) -> bool,
     [] fn codegen_unit: CodegenUnit(InternedString) -> Arc<CodegenUnit<'tcx>>,
@@ -385,7 +384,6 @@ define_maps! { <'tcx>
 
     [] fn target_features_whitelist:
         target_features_whitelist_node(CrateNum) -> Lrc<FxHashSet<String>>,
-    [] fn target_features_enabled: TargetFeaturesEnabled(DefId) -> Lrc<Vec<String>>,
 
     // Get an estimate of the size of an InstanceDef based on its MIR for CGU partitioning.
     [] fn instance_def_size_estimate: instance_def_size_estimate_dep_node(ty::InstanceDef<'tcx>)
@@ -403,6 +401,10 @@ fn features_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
     DepConstructor::Features
 }
 
+fn trans_fn_attrs<'tcx>(id: DefId) -> DepConstructor<'tcx> {
+    DepConstructor::TransFnAttrs { 0: id }
+}
+
 fn erase_regions_ty<'tcx>(ty: Ty<'tcx>) -> DepConstructor<'tcx> {
     DepConstructor::EraseRegionsTy { ty }
 }
diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs
index 65f2d476475..b18837ff35a 100644
--- a/src/librustc/ty/maps/on_disk_cache.rs
+++ b/src/librustc/ty/maps/on_disk_cache.rs
@@ -217,9 +217,9 @@ impl<'sess> OnDiskCache<'sess> {
                 encode_query_results::<mir_const_qualif, _>(tcx, enc, qri)?;
                 encode_query_results::<def_symbol_name, _>(tcx, enc, qri)?;
                 encode_query_results::<const_is_rvalue_promotable_to_static, _>(tcx, enc, qri)?;
-                encode_query_results::<contains_extern_indicator, _>(tcx, enc, qri)?;
                 encode_query_results::<symbol_name, _>(tcx, enc, qri)?;
                 encode_query_results::<check_match, _>(tcx, enc, qri)?;
+                encode_query_results::<trans_fn_attrs, _>(tcx, enc, qri)?;
             }
 
             // Encode diagnostics
diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs
index 13f286d6a26..fcc69f3b2c3 100644
--- a/src/librustc/ty/maps/plumbing.rs
+++ b/src/librustc/ty/maps/plumbing.rs
@@ -854,6 +854,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
         DepKind::IsReachableNonGeneric => { force!(is_reachable_non_generic, def_id!()); }
         DepKind::IsMirAvailable => { force!(is_mir_available, def_id!()); }
         DepKind::ItemAttrs => { force!(item_attrs, def_id!()); }
+        DepKind::TransFnAttrs => { force!(trans_fn_attrs, def_id!()); }
         DepKind::FnArgNames => { force!(fn_arg_names, def_id!()); }
         DepKind::DylibDepFormats => { force!(dylib_dependency_formats, krate!()); }
         DepKind::IsPanicRuntime => { force!(is_panic_runtime, krate!()); }
@@ -925,15 +926,10 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
         DepKind::CollectAndPartitionTranslationItems => {
             force!(collect_and_partition_translation_items, LOCAL_CRATE);
         }
-        DepKind::ExportName => { force!(export_name, def_id!()); }
-        DepKind::ContainsExternIndicator => {
-            force!(contains_extern_indicator, def_id!());
-        }
         DepKind::IsTranslatedItem => { force!(is_translated_item, def_id!()); }
         DepKind::OutputFilenames => { force!(output_filenames, LOCAL_CRATE); }
 
         DepKind::TargetFeaturesWhitelist => { force!(target_features_whitelist, LOCAL_CRATE); }
-        DepKind::TargetFeaturesEnabled => { force!(target_features_enabled, def_id!()); }
 
         DepKind::GetSymbolExportLevel => { force!(symbol_export_level, def_id!()); }
         DepKind::Features => { force!(features_query, LOCAL_CRATE); }
@@ -997,10 +993,10 @@ impl_load_from_cache!(
     MirConstQualif => mir_const_qualif,
     SymbolName => def_symbol_name,
     ConstIsRvaluePromotableToStatic => const_is_rvalue_promotable_to_static,
-    ContainsExternIndicator => contains_extern_indicator,
     CheckMatch => check_match,
     TypeOfItem => type_of,
     GenericsOfItem => generics_of,
     PredicatesOfItem => predicates_of,
     UsedTraitImports => used_trait_imports,
+    TransFnAttrs => trans_fn_attrs,
 );
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index a7c55880e2e..be27e3d5152 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -912,9 +912,6 @@ pub enum Predicate<'tcx> {
     /// would be the type parameters.
     Trait(PolyTraitPredicate<'tcx>),
 
-    /// where `T1 == T2`.
-    Equate(PolyEquatePredicate<'tcx>),
-
     /// where 'a : 'b
     RegionOutlives(PolyRegionOutlivesPredicate<'tcx>),
 
@@ -1023,8 +1020,6 @@ impl<'a, 'gcx, 'tcx> Predicate<'tcx> {
         match *self {
             Predicate::Trait(ty::Binder(ref data)) =>
                 Predicate::Trait(ty::Binder(data.subst(tcx, substs))),
-            Predicate::Equate(ty::Binder(ref data)) =>
-                Predicate::Equate(ty::Binder(data.subst(tcx, substs))),
             Predicate::Subtype(ty::Binder(ref data)) =>
                 Predicate::Subtype(ty::Binder(data.subst(tcx, substs))),
             Predicate::RegionOutlives(ty::Binder(ref data)) =>
@@ -1073,10 +1068,6 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
-pub struct EquatePredicate<'tcx>(pub Ty<'tcx>, pub Ty<'tcx>); // `0 == 1`
-pub type PolyEquatePredicate<'tcx> = ty::Binder<EquatePredicate<'tcx>>;
-
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
 pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B`
 pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
 pub type PolyRegionOutlivesPredicate<'tcx> = PolyOutlivesPredicate<ty::Region<'tcx>,
@@ -1166,12 +1157,6 @@ impl<'tcx> ToPredicate<'tcx> for PolyTraitRef<'tcx> {
     }
 }
 
-impl<'tcx> ToPredicate<'tcx> for PolyEquatePredicate<'tcx> {
-    fn to_predicate(&self) -> Predicate<'tcx> {
-        Predicate::Equate(self.clone())
-    }
-}
-
 impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> {
     fn to_predicate(&self) -> Predicate<'tcx> {
         Predicate::RegionOutlives(self.clone())
@@ -1199,9 +1184,6 @@ impl<'tcx> Predicate<'tcx> {
             ty::Predicate::Trait(ref data) => {
                 data.skip_binder().input_types().collect()
             }
-            ty::Predicate::Equate(ty::Binder(ref data)) => {
-                vec![data.0, data.1]
-            }
             ty::Predicate::Subtype(ty::Binder(SubtypePredicate { a, b, a_is_expected: _ })) => {
                 vec![a, b]
             }
@@ -1242,7 +1224,6 @@ impl<'tcx> Predicate<'tcx> {
                 Some(t.to_poly_trait_ref())
             }
             Predicate::Projection(..) |
-            Predicate::Equate(..) |
             Predicate::Subtype(..) |
             Predicate::RegionOutlives(..) |
             Predicate::WellFormed(..) |
@@ -1262,7 +1243,6 @@ impl<'tcx> Predicate<'tcx> {
             }
             Predicate::Trait(..) |
             Predicate::Projection(..) |
-            Predicate::Equate(..) |
             Predicate::Subtype(..) |
             Predicate::RegionOutlives(..) |
             Predicate::WellFormed(..) |
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index 6147b52844f..055835ed69c 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -282,14 +282,6 @@ impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
     }
 }
 
-impl<'a, 'tcx> Lift<'tcx> for ty::EquatePredicate<'a> {
-    type Lifted = ty::EquatePredicate<'tcx>;
-    fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
-                             -> Option<ty::EquatePredicate<'tcx>> {
-        tcx.lift(&(self.0, self.1)).map(|(a, b)| ty::EquatePredicate(a, b))
-    }
-}
-
 impl<'a, 'tcx> Lift<'tcx> for ty::SubtypePredicate<'a> {
     type Lifted = ty::SubtypePredicate<'tcx>;
     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
@@ -355,9 +347,6 @@ impl<'a, 'tcx> Lift<'tcx> for ty::Predicate<'a> {
             ty::Predicate::Trait(ref binder) => {
                 tcx.lift(binder).map(ty::Predicate::Trait)
             }
-            ty::Predicate::Equate(ref binder) => {
-                tcx.lift(binder).map(ty::Predicate::Equate)
-            }
             ty::Predicate::Subtype(ref binder) => {
                 tcx.lift(binder).map(ty::Predicate::Subtype)
             }
@@ -1049,8 +1038,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
         match *self {
             ty::Predicate::Trait(ref a) =>
                 ty::Predicate::Trait(a.fold_with(folder)),
-            ty::Predicate::Equate(ref binder) =>
-                ty::Predicate::Equate(binder.fold_with(folder)),
             ty::Predicate::Subtype(ref binder) =>
                 ty::Predicate::Subtype(binder.fold_with(folder)),
             ty::Predicate::RegionOutlives(ref binder) =>
@@ -1073,7 +1060,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
         match *self {
             ty::Predicate::Trait(ref a) => a.visit_with(visitor),
-            ty::Predicate::Equate(ref binder) => binder.visit_with(visitor),
             ty::Predicate::Subtype(ref binder) => binder.visit_with(visitor),
             ty::Predicate::RegionOutlives(ref binder) => binder.visit_with(visitor),
             ty::Predicate::TypeOutlives(ref binder) => binder.visit_with(visitor),
@@ -1111,16 +1097,6 @@ BraceStructTypeFoldableImpl! {
     }
 }
 
-impl<'tcx> TypeFoldable<'tcx> for ty::EquatePredicate<'tcx> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
-        ty::EquatePredicate(self.0.fold_with(folder), self.1.fold_with(folder))
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.0.visit_with(visitor) || self.1.visit_with(visitor)
-    }
-}
-
 impl<'tcx> TypeFoldable<'tcx> for ty::SubtypePredicate<'tcx> {
     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
         ty::SubtypePredicate {
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 47ad7cbcb56..785035ee5f4 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -20,6 +20,7 @@ use traits::{self, Reveal};
 use ty::{self, Ty, TyCtxt, TypeFoldable};
 use ty::fold::TypeVisitor;
 use ty::subst::{Subst, UnpackedKind};
+use ty::maps::TyCtxtAt;
 use ty::TypeVariants::*;
 use util::common::ErrorReported;
 use middle::lang_items;
@@ -385,7 +386,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                 match predicate {
                     ty::Predicate::Projection(..) |
                     ty::Predicate::Trait(..) |
-                    ty::Predicate::Equate(..) |
                     ty::Predicate::Subtype(..) |
                     ty::Predicate::WellFormed(..) |
                     ty::Predicate::ObjectSafe(..) |
@@ -864,11 +864,10 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
     }
 
     pub fn is_sized(&'tcx self,
-                    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                    param_env: ty::ParamEnv<'tcx>,
-                    span: Span)-> bool
+                    tcx_at: TyCtxtAt<'a, 'tcx, 'tcx>,
+                    param_env: ty::ParamEnv<'tcx>)-> bool
     {
-        tcx.at(span).is_sized_raw(param_env.and(self))
+        tcx_at.is_sized_raw(param_env.and(self))
     }
 
     pub fn is_freeze(&'tcx self,
diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs
index ce44448ef79..ea99bd39e87 100644
--- a/src/librustc/ty/wf.rs
+++ b/src/librustc/ty/wf.rs
@@ -77,10 +77,6 @@ pub fn predicate_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
         ty::Predicate::Trait(ref t) => {
             wf.compute_trait_ref(&t.skip_binder().trait_ref, Elaborate::None); // (*)
         }
-        ty::Predicate::Equate(ref t) => {
-            wf.compute(t.skip_binder().0);
-            wf.compute(t.skip_binder().1);
-        }
         ty::Predicate::RegionOutlives(..) => {
         }
         ty::Predicate::TypeOutlives(ref t) => {
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 40c8e8aa4a2..a2620da4c10 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -939,7 +939,6 @@ define_print_multi! {
     ('tcx) ty::Binder<ty::TraitRef<'tcx>>,
     ('tcx) ty::Binder<ty::FnSig<'tcx>>,
     ('tcx) ty::Binder<ty::TraitPredicate<'tcx>>,
-    ('tcx) ty::Binder<ty::EquatePredicate<'tcx>>,
     ('tcx) ty::Binder<ty::SubtypePredicate<'tcx>>,
     ('tcx) ty::Binder<ty::ProjectionPredicate<'tcx>>,
     ('tcx) ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>,
@@ -1218,14 +1217,6 @@ define_print! {
 }
 
 define_print! {
-    ('tcx) ty::EquatePredicate<'tcx>, (self, f, cx) {
-        display {
-            print!(f, cx, print(self.0), write(" == "), print(self.1))
-        }
-    }
-}
-
-define_print! {
     ('tcx) ty::SubtypePredicate<'tcx>, (self, f, cx) {
         display {
             print!(f, cx, print(self.a), write(" <: "), print(self.b))
@@ -1292,7 +1283,6 @@ define_print! {
         display {
             match *self {
                 ty::Predicate::Trait(ref data) => data.print(f, cx),
-                ty::Predicate::Equate(ref predicate) => predicate.print(f, cx),
                 ty::Predicate::Subtype(ref predicate) => predicate.print(f, cx),
                 ty::Predicate::RegionOutlives(ref predicate) => predicate.print(f, cx),
                 ty::Predicate::TypeOutlives(ref predicate) => predicate.print(f, cx),
@@ -1317,7 +1307,6 @@ define_print! {
         debug {
             match *self {
                 ty::Predicate::Trait(ref a) => a.print(f, cx),
-                ty::Predicate::Equate(ref pair) => pair.print(f, cx),
                 ty::Predicate::Subtype(ref pair) => pair.print(f, cx),
                 ty::Predicate::RegionOutlives(ref pair) => pair.print(f, cx),
                 ty::Predicate::TypeOutlives(ref pair) => pair.print(f, cx),
diff --git a/src/librustc_data_structures/owning_ref/mod.rs b/src/librustc_data_structures/owning_ref/mod.rs
index 23e0733748b..c466b8f8ad1 100644
--- a/src/librustc_data_structures/owning_ref/mod.rs
+++ b/src/librustc_data_structures/owning_ref/mod.rs
@@ -243,6 +243,7 @@ fn main() {
 ```
 */
 
+use std::mem;
 pub use stable_deref_trait::{StableDeref as StableAddress, CloneStableDeref as CloneStableAddress};
 
 /// An owning reference.
@@ -279,7 +280,7 @@ pub struct OwningRefMut<O, T: ?Sized> {
 pub trait Erased {}
 impl<T> Erased for T {}
 
-/// Helper trait for erasing the concrete type of what an owner derferences to,
+/// Helper trait for erasing the concrete type of what an owner dereferences to,
 /// for example `Box<T> -> Box<Erased>`. This would be unneeded with
 /// higher kinded types support in the language.
 pub unsafe trait IntoErased<'a> {
@@ -289,10 +290,20 @@ pub unsafe trait IntoErased<'a> {
     fn into_erased(self) -> Self::Erased;
 }
 
-/// Helper trait for erasing the concrete type of what an owner derferences to,
+/// Helper trait for erasing the concrete type of what an owner dereferences to,
+/// for example `Box<T> -> Box<Erased + Send>`. This would be unneeded with
+/// higher kinded types support in the language.
+pub unsafe trait IntoErasedSend<'a> {
+    /// Owner with the dereference type substituted to `Erased + Send`.
+    type Erased: Send;
+    /// Perform the type erasure.
+    fn into_erased_send(self) -> Self::Erased;
+}
+
+/// Helper trait for erasing the concrete type of what an owner dereferences to,
 /// for example `Box<T> -> Box<Erased + Send + Sync>`. This would be unneeded with
 /// higher kinded types support in the language.
-pub unsafe trait IntoErasedSendSync<'a>: Send + Sync {
+pub unsafe trait IntoErasedSendSync<'a> {
     /// Owner with the dereference type substituted to `Erased + Send + Sync`.
     type Erased: Send + Sync;
     /// Perform the type erasure.
@@ -472,6 +483,18 @@ impl<O, T: ?Sized> OwningRef<O, T> {
         }
     }
 
+    /// Erases the concrete base type of the owner with a trait object which implements `Send`.
+    ///
+    /// This allows mixing of owned references with different owner base types.
+    pub fn erase_send_owner<'a>(self) -> OwningRef<O::Erased, T>
+        where O: IntoErasedSend<'a>,
+    {
+        OwningRef {
+            reference: self.reference,
+            owner: self.owner.into_erased_send(),
+        }
+    }
+
     /// Erases the concrete base type of the owner with a trait object which implements `Send` and `Sync`.
     ///
     /// This allows mixing of owned references with different owner base types.
@@ -1161,13 +1184,25 @@ unsafe impl<'a, T: 'a> IntoErased<'a> for Arc<T> {
     }
 }
 
-unsafe impl<'a, T: Send + Sync + 'a> IntoErasedSendSync<'a> for Box<T> {
-    type Erased = Box<Erased + Send + Sync + 'a>;
-    fn into_erased_send_sync(self) -> Self::Erased {
+unsafe impl<'a, T: Send + 'a> IntoErasedSend<'a> for Box<T> {
+    type Erased = Box<Erased + Send + 'a>;
+    fn into_erased_send(self) -> Self::Erased {
         self
     }
 }
 
+unsafe impl<'a, T: Send + 'a> IntoErasedSendSync<'a> for Box<T> {
+    type Erased = Box<Erased + Sync + Send + 'a>;
+    fn into_erased_send_sync(self) -> Self::Erased {
+        let result: Box<Erased + Send + 'a> = self;
+        // This is safe since Erased can always implement Sync
+        // Only the destructor is available and it takes &mut self
+        unsafe {
+            mem::transmute(result)
+        }
+    }
+}
+
 unsafe impl<'a, T: Send + Sync + 'a> IntoErasedSendSync<'a> for Arc<T> {
     type Erased = Arc<Erased + Send + Sync + 'a>;
     fn into_erased_send_sync(self) -> Self::Erased {
diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs
index b1ab4eaa069..69fc9ef785e 100644
--- a/src/librustc_data_structures/sync.rs
+++ b/src/librustc_data_structures/sync.rs
@@ -177,7 +177,7 @@ cfg_if! {
         macro_rules! rustc_erase_owner {
             ($v:expr) => {{
                 let v = $v;
-                ::rustc_data_structures::sync::assert_send_sync_val(&v);
+                ::rustc_data_structures::sync::assert_send_val(&v);
                 v.erase_send_sync_owner()
             }}
         }
@@ -262,6 +262,7 @@ cfg_if! {
 }
 
 pub fn assert_sync<T: ?Sized + Sync>() {}
+pub fn assert_send_val<T: ?Sized + Send>(_t: &T) {}
 pub fn assert_send_sync_val<T: ?Sized + Sync + Send>(_t: &T) {}
 
 #[macro_export]
diff --git a/src/librustc_llvm/archive_ro.rs b/src/librustc_llvm/archive_ro.rs
index 6c3626cd880..9d869007270 100644
--- a/src/librustc_llvm/archive_ro.rs
+++ b/src/librustc_llvm/archive_ro.rs
@@ -22,6 +22,8 @@ pub struct ArchiveRO {
     ptr: ArchiveRef,
 }
 
+unsafe impl Send for ArchiveRO {}
+
 pub struct Iter<'a> {
     archive: &'a ArchiveRO,
     ptr: ::ArchiveIteratorRef,
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index 8dcf7444dd1..16bee5b987e 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -221,6 +221,8 @@ pub struct ObjectFile {
     pub llof: ObjectFileRef,
 }
 
+unsafe impl Send for ObjectFile {}
+
 impl ObjectFile {
     // This will take ownership of llmb
     pub fn new(llmb: MemoryBufferRef) -> Option<ObjectFile> {
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index 2e95c23b4ae..202efb9276a 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -24,7 +24,6 @@ use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap};
 
 use std::cell::{RefCell, Cell};
 use rustc_data_structures::sync::Lrc;
-use rustc_data_structures::owning_ref::ErasedBoxRef;
 use syntax::{ast, attr};
 use syntax::ext::base::SyntaxExtension;
 use syntax::symbol::Symbol;
@@ -42,7 +41,9 @@ pub use cstore_impl::{provide, provide_extern};
 // own crate numbers.
 pub type CrateNumMap = IndexVec<CrateNum, CrateNum>;
 
-pub struct MetadataBlob(pub ErasedBoxRef<[u8]>);
+pub use rustc_data_structures::sync::MetadataRef;
+
+pub struct MetadataBlob(pub MetadataRef);
 
 /// Holds information about a syntax_pos::FileMap imported from another crate.
 /// See `imported_filemaps()` for more information.
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index d19ab894591..830121b446f 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -832,7 +832,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
         } else if let hir::ImplItemKind::Method(ref sig, body) = ast_item.node {
             let generics = self.tcx.generics_of(def_id);
             let types = generics.parent_types as usize + generics.types.len();
-            let needs_inline = types > 0 || attr::requests_inline(&ast_item.attrs);
+            let needs_inline = types > 0 || tcx.trans_fn_attrs(def_id).requests_inline();
             let is_const_fn = sig.constness == hir::Constness::Const;
             let ast = if is_const_fn { Some(body) } else { None };
             let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
@@ -1123,7 +1123,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
                 hir::ItemConst(..) => self.encode_optimized_mir(def_id),
                 hir::ItemFn(_, _, constness, _, ref generics, _) => {
                     let has_tps = generics.ty_params().next().is_some();
-                    let needs_inline = has_tps || attr::requests_inline(&item.attrs);
+                    let needs_inline = has_tps || tcx.trans_fn_attrs(def_id).requests_inline();
                     let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
                     if needs_inline || constness == hir::Constness::Const || always_encode_mir {
                         self.encode_optimized_mir(def_id)
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index 2d015fa81f9..da0da622d52 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -39,6 +39,7 @@ extern crate proc_macro;
 #[macro_use]
 extern crate rustc;
 extern crate rustc_back;
+#[macro_use]
 extern crate rustc_data_structures;
 
 mod diagnostics;
diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs
index e0fb924f1aa..c56674bd6c5 100644
--- a/src/librustc_metadata/locator.rs
+++ b/src/librustc_metadata/locator.rs
@@ -219,7 +219,7 @@
 //! no means all of the necessary details. Take a look at the rest of
 //! metadata::locator or metadata::creader for all the juicy details!
 
-use cstore::MetadataBlob;
+use cstore::{MetadataRef, MetadataBlob};
 use creader::Library;
 use schema::{METADATA_HEADER, rustc_version};
 
@@ -243,8 +243,8 @@ use std::path::{Path, PathBuf};
 use std::time::Instant;
 
 use flate2::read::DeflateDecoder;
-use rustc_data_structures::owning_ref::{ErasedBoxRef, OwningRef};
 
+use rustc_data_structures::owning_ref::OwningRef;
 pub struct CrateMismatch {
     path: PathBuf,
     got: String,
@@ -842,7 +842,7 @@ fn get_metadata_section_imp(target: &Target,
     if !filename.exists() {
         return Err(format!("no such file: '{}'", filename.display()));
     }
-    let raw_bytes: ErasedBoxRef<[u8]> = match flavor {
+    let raw_bytes: MetadataRef = match flavor {
         CrateFlavor::Rlib => loader.get_rlib_metadata(target, filename)?,
         CrateFlavor::Dylib => {
             let buf = loader.get_dylib_metadata(target, filename)?;
@@ -862,7 +862,7 @@ fn get_metadata_section_imp(target: &Target,
             match DeflateDecoder::new(compressed_bytes).read_to_end(&mut inflated) {
                 Ok(_) => {
                     let buf = unsafe { OwningRef::new_assert_stable_address(inflated) };
-                    buf.map_owner_box().erase_owner()
+                    rustc_erase_owner!(buf.map_owner_box())
                 }
                 Err(_) => {
                     return Err(format!("failed to decompress metadata: {}", filename.display()));
@@ -872,7 +872,7 @@ fn get_metadata_section_imp(target: &Target,
         CrateFlavor::Rmeta => {
             let buf = fs::read(filename).map_err(|_|
                 format!("failed to read rmeta metadata: '{}'", filename.display()))?;
-            OwningRef::new(buf).map_owner_box().erase_owner()
+            rustc_erase_owner!(OwningRef::new(buf).map_owner_box())
         }
     };
     let blob = MetadataBlob(raw_bytes);
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 3af10c5c251..bbf4357e5b0 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -1208,7 +1208,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
         // shouldn't affect `is_sized`.
         let gcx = self.tcx().global_tcx();
         let erased_ty = gcx.lift(&self.tcx().erase_regions(&ty)).unwrap();
-        if !erased_ty.is_sized(gcx, self.param_env, span) {
+        if !erased_ty.is_sized(gcx.at(span), self.param_env) {
             // in current MIR construction, all non-control-flow rvalue
             // expressions evaluate through `as_temp` or `into` a return
             // slot or local, so to find all unsized rvalues it is enough
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 08c16fed5dd..25f933c5da6 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -286,7 +286,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
     }
 
     pub(super) fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
-        ty.is_sized(self.tcx, self.param_env, DUMMY_SP)
+        ty.is_sized(self.tcx.at(DUMMY_SP), self.param_env)
     }
 
     pub fn load_mir(
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 10c2f9f758f..0f512569adf 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -188,7 +188,7 @@
 //! this is not implemented however: a mono item will be produced
 //! regardless of whether it is actually needed or not.
 
-use rustc::hir;
+use rustc::hir::{self, TransFnAttrFlags};
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 
 use rustc::hir::map as hir_map;
@@ -211,8 +211,6 @@ use monomorphize::item::{MonoItemExt, DefPathBasedNames, InstantiationMode};
 
 use rustc_data_structures::bitvec::BitVector;
 
-use syntax::attr;
-
 use std::iter;
 
 #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
@@ -796,7 +794,7 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let ptr_vtable = |inner_source: Ty<'tcx>, inner_target: Ty<'tcx>| {
         let type_has_metadata = |ty: Ty<'tcx>| -> bool {
             use syntax_pos::DUMMY_SP;
-            if ty.is_sized(tcx, ty::ParamEnv::empty(traits::Reveal::All), DUMMY_SP) {
+            if ty.is_sized(tcx.at(DUMMY_SP), ty::ParamEnv::empty(traits::Reveal::All)) {
                 return false;
             }
             let tail = tcx.struct_tail(ty);
@@ -985,8 +983,8 @@ impl<'b, 'a, 'v> RootCollector<'b, 'a, 'v> {
             MonoItemCollectionMode::Lazy => {
                 self.entry_fn == Some(def_id) ||
                 self.tcx.is_reachable_non_generic(def_id) ||
-                attr::contains_name(&self.tcx.get_attrs(def_id),
-                                    "rustc_std_internal_symbol")
+                self.tcx.trans_fn_attrs(def_id).flags.contains(
+                    TransFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
             }
         }
     }
diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs
index 7c86f5a4b1a..38b8ffc6b9c 100644
--- a/src/librustc_mir/monomorphize/item.rs
+++ b/src/librustc_mir/monomorphize/item.rs
@@ -21,7 +21,7 @@ use rustc::session::config::OptLevel;
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::subst::Substs;
 use syntax::ast;
-use syntax::attr::{self, InlineAttr};
+use syntax::attr::InlineAttr;
 use std::fmt::{self, Write};
 use std::iter;
 use rustc::mir::mono::Linkage;
@@ -29,33 +29,6 @@ use syntax_pos::symbol::Symbol;
 use syntax::codemap::Span;
 pub use rustc::mir::mono::MonoItem;
 
-pub fn linkage_by_name(name: &str) -> Option<Linkage> {
-    use rustc::mir::mono::Linkage::*;
-
-    // Use the names from src/llvm/docs/LangRef.rst here. Most types are only
-    // applicable to variable declarations and may not really make sense for
-    // Rust code in the first place but whitelist them anyway and trust that
-    // the user knows what s/he's doing. Who knows, unanticipated use cases
-    // may pop up in the future.
-    //
-    // ghost, dllimport, dllexport and linkonce_odr_autohide are not supported
-    // and don't have to be, LLVM treats them as no-ops.
-    match name {
-        "appending" => Some(Appending),
-        "available_externally" => Some(AvailableExternally),
-        "common" => Some(Common),
-        "extern_weak" => Some(ExternalWeak),
-        "external" => Some(External),
-        "internal" => Some(Internal),
-        "linkonce" => Some(LinkOnceAny),
-        "linkonce_odr" => Some(LinkOnceODR),
-        "private" => Some(Private),
-        "weak" => Some(WeakAny),
-        "weak_odr" => Some(WeakODR),
-        _ => None,
-    }
-}
-
 /// Describes how a translation item will be instantiated in object files.
 #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
 pub enum InstantiationMode {
@@ -141,8 +114,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
                 // creating one copy of this `#[inline]` function which may
                 // conflict with upstream crates as it could be an exported
                 // symbol.
-                let attrs = instance.def.attrs(tcx);
-                match attr::find_inline_attr(Some(tcx.sess.diagnostic()), &attrs) {
+                match tcx.trans_fn_attrs(instance.def_id()).inline {
                     InlineAttr::Always => InstantiationMode::LocalCopy,
                     _ => {
                         InstantiationMode::GloballyShared  { may_conflict: true }
@@ -165,21 +137,8 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
             MonoItem::GlobalAsm(..) => return None,
         };
 
-        let attributes = tcx.get_attrs(def_id);
-        if let Some(name) = attr::first_attr_value_str_by_name(&attributes, "linkage") {
-            if let Some(linkage) = linkage_by_name(&name.as_str()) {
-                Some(linkage)
-            } else {
-                let span = tcx.hir.span_if_local(def_id);
-                if let Some(span) = span {
-                    tcx.sess.span_fatal(span, "invalid linkage specified")
-                } else {
-                    tcx.sess.fatal(&format!("invalid linkage specified: {}", name))
-                }
-            }
-        } else {
-            None
-        }
+        let trans_fn_attrs = tcx.trans_fn_attrs(def_id);
+        trans_fn_attrs.linkage
     }
 
     /// Returns whether this instance is instantiable - whether it has no unsatisfied
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 08a9757fb32..64c702b99cd 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -11,6 +11,7 @@
 //! Inlining pass for MIR functions
 
 use rustc::hir;
+use rustc::hir::TransFnAttrFlags;
 use rustc::hir::def_id::DefId;
 
 use rustc_data_structures::bitvec::BitVector;
@@ -206,10 +207,9 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
             return false;
         }
 
-        let attrs = tcx.get_attrs(callsite.callee);
-        let hint = attr::find_inline_attr(None, &attrs[..]);
+        let trans_fn_attrs = tcx.trans_fn_attrs(callsite.callee);
 
-        let hinted = match hint {
+        let hinted = match trans_fn_attrs.inline {
             // Just treat inline(always) as a hint for now,
             // there are cases that prevent inlining that we
             // need to check for first.
@@ -239,7 +239,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
         };
 
         // Significantly lower the threshold for inlining cold functions
-        if attr::contains_name(&attrs[..], "cold") {
+        if trans_fn_attrs.flags.contains(TransFnAttrFlags::COLD) {
             threshold /= 5;
         }
 
@@ -344,7 +344,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
             }
         }
 
-        if let attr::InlineAttr::Always = hint {
+        if let attr::InlineAttr::Always = trans_fn_attrs.inline {
             debug!("INLINING {:?} because inline(always) [cost={}]", callsite, cost);
             true
         } else {
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 6e986041013..d92025a6787 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -1665,17 +1665,23 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
                         if !self.span.filter_generated(sub_span, ex.span) {
                             let span =
                                 self.span_from_span(sub_span.expect("No span found for var ref"));
-                            let ref_id =
-                                ::id_from_def_id(def.non_enum_variant().fields[idx.node].did);
-                            self.dumper.dump_ref(Ref {
-                                kind: RefKind::Variable,
-                                span,
-                                ref_id,
-                            });
+                            if let Some(field) = def.non_enum_variant().fields.get(idx.node) {
+                                let ref_id = ::id_from_def_id(field.did);
+                                self.dumper.dump_ref(Ref {
+                                    kind: RefKind::Variable,
+                                    span,
+                                    ref_id,
+                                });
+                            } else {
+                                return;
+                            }
                         }
                     }
                     ty::TyTuple(..) => {}
-                    _ => span_bug!(ex.span, "Expected struct or tuple type, found {:?}", ty),
+                    _ => {
+                        debug!("Expected struct or tuple type, found {:?}", ty);
+                        return;
+                    }
                 }
             }
             ast::ExprKind::Closure(_, _, ref decl, ref body, _fn_decl_span) => {
diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs
index ffa3f7f4011..d5ec8d1b552 100644
--- a/src/librustc_trans/attributes.rs
+++ b/src/librustc_trans/attributes.rs
@@ -11,19 +11,16 @@
 
 use std::ffi::{CStr, CString};
 
-use rustc::hir::Unsafety;
+use rustc::hir::TransFnAttrFlags;
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::session::config::Sanitizer;
-use rustc::ty::TyCtxt;
 use rustc::ty::maps::Providers;
-use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::sync::Lrc;
 
 use llvm::{self, Attribute, ValueRef};
 use llvm::AttributePlace::Function;
 use llvm_util;
 pub use syntax::attr::{self, InlineAttr};
-use syntax::ast;
 use context::CodegenCx;
 
 /// Mark LLVM function to use provided inline heuristic.
@@ -102,31 +99,42 @@ pub fn set_probestack(cx: &CodegenCx, llfn: ValueRef) {
 /// Composite function which sets LLVM attributes for function depending on its AST (#[attribute])
 /// attributes.
 pub fn from_fn_attrs(cx: &CodegenCx, llfn: ValueRef, id: DefId) {
-    use syntax::attr::*;
-    let attrs = cx.tcx.get_attrs(id);
-    inline(llfn, find_inline_attr(Some(cx.sess().diagnostic()), &attrs));
+    let trans_fn_attrs = cx.tcx.trans_fn_attrs(id);
+
+    inline(llfn, trans_fn_attrs.inline);
 
     set_frame_pointer_elimination(cx, llfn);
     set_probestack(cx, llfn);
 
-    for attr in attrs.iter() {
-        if attr.check_name("cold") {
-            Attribute::Cold.apply_llfn(Function, llfn);
-        } else if attr.check_name("naked") {
-            naked(llfn, true);
-        } else if attr.check_name("allocator") {
-            Attribute::NoAlias.apply_llfn(
-                llvm::AttributePlace::ReturnValue, llfn);
-        } else if attr.check_name("unwind") {
-            unwind(llfn, true);
-        } else if attr.check_name("rustc_allocator_nounwind") {
-            unwind(llfn, false);
-        }
+    if trans_fn_attrs.flags.contains(TransFnAttrFlags::COLD) {
+        Attribute::Cold.apply_llfn(Function, llfn);
+    }
+    if trans_fn_attrs.flags.contains(TransFnAttrFlags::NAKED) {
+        naked(llfn, true);
+    }
+    if trans_fn_attrs.flags.contains(TransFnAttrFlags::ALLOCATOR) {
+        Attribute::NoAlias.apply_llfn(
+            llvm::AttributePlace::ReturnValue, llfn);
+    }
+    if trans_fn_attrs.flags.contains(TransFnAttrFlags::UNWIND) {
+        unwind(llfn, true);
+    }
+    if trans_fn_attrs.flags.contains(TransFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) {
+        unwind(llfn, false);
     }
 
-    let target_features = cx.tcx.target_features_enabled(id);
-    if !target_features.is_empty() {
-        let val = CString::new(target_features.join(",")).unwrap();
+    let features =
+        trans_fn_attrs.target_features
+        .iter()
+        .map(|f| {
+            let feature = &*f.as_str();
+            format!("+{}", llvm_util::to_llvm_feature(cx.tcx.sess, feature))
+        })
+        .collect::<Vec<String>>()
+        .join(",");
+
+    if !features.is_empty() {
+        let val = CString::new(features).unwrap();
         llvm::AddFunctionAttrStringValue(
             llfn, llvm::AttributePlace::Function,
             cstr("target-features\0"), &val);
@@ -145,89 +153,4 @@ pub fn provide(providers: &mut Providers) {
             .map(|c| c.to_string())
             .collect())
     };
-
-    providers.target_features_enabled = |tcx, id| {
-        let whitelist = tcx.target_features_whitelist(LOCAL_CRATE);
-        let mut target_features = Vec::new();
-        for attr in tcx.get_attrs(id).iter() {
-            if !attr.check_name("target_feature") {
-                continue
-            }
-            if let Some(val) = attr.value_str() {
-                for feat in val.as_str().split(",").map(|f| f.trim()) {
-                    if !feat.is_empty() && !feat.contains('\0') {
-                        target_features.push(feat.to_string());
-                    }
-                }
-                let msg = "#[target_feature = \"..\"] is deprecated and will \
-                           eventually be removed, use \
-                           #[target_feature(enable = \"..\")] instead";
-                tcx.sess.span_warn(attr.span, &msg);
-                continue
-            }
-
-            if tcx.fn_sig(id).unsafety() == Unsafety::Normal {
-                let msg = "#[target_feature(..)] can only be applied to \
-                           `unsafe` function";
-                tcx.sess.span_err(attr.span, msg);
-            }
-            from_target_feature(tcx, attr, &whitelist, &mut target_features);
-        }
-        Lrc::new(target_features)
-    };
-}
-
-fn from_target_feature(
-    tcx: TyCtxt,
-    attr: &ast::Attribute,
-    whitelist: &FxHashSet<String>,
-    target_features: &mut Vec<String>,
-) {
-    let list = match attr.meta_item_list() {
-        Some(list) => list,
-        None => {
-            let msg = "#[target_feature] attribute must be of the form \
-                       #[target_feature(..)]";
-            tcx.sess.span_err(attr.span, &msg);
-            return
-        }
-    };
-
-    for item in list {
-        if !item.check_name("enable") {
-            let msg = "#[target_feature(..)] only accepts sub-keys of `enable` \
-                       currently";
-            tcx.sess.span_err(item.span, &msg);
-            continue
-        }
-        let value = match item.value_str() {
-            Some(list) => list,
-            None => {
-                let msg = "#[target_feature] attribute must be of the form \
-                           #[target_feature(enable = \"..\")]";
-                tcx.sess.span_err(item.span, &msg);
-                continue
-            }
-        };
-        let value = value.as_str();
-        for feature in value.split(',') {
-            if whitelist.contains(feature) {
-                let llvm_feature = llvm_util::to_llvm_feature(&tcx.sess, feature);
-                target_features.push(format!("+{}", llvm_feature));
-                continue
-            }
-
-            let msg = format!("the feature named `{}` is not valid for \
-                               this target", feature);
-            let mut err = tcx.sess.struct_span_err(item.span, &msg);
-
-            if feature.starts_with("+") {
-                let valid = whitelist.contains(&feature[1..]);
-                if valid {
-                    err.help("consider removing the leading `+` in the feature name");
-                }
-            }
-            err.emit();
-        }
-    }
 }
diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs
index 739ae768ca2..fd79ae7435e 100644
--- a/src/librustc_trans/back/symbol_export.rs
+++ b/src/librustc_trans/back/symbol_export.rs
@@ -13,6 +13,7 @@ use std::sync::Arc;
 
 use monomorphize::Instance;
 use rustc::hir;
+use rustc::hir::TransFnAttrFlags;
 use rustc::hir::def_id::CrateNum;
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::middle::exported_symbols::{SymbolExportLevel, ExportedSymbol, metadata_symbol_name};
@@ -21,7 +22,6 @@ use rustc::ty::{TyCtxt, SymbolName};
 use rustc::ty::maps::Providers;
 use rustc::util::nodemap::{FxHashMap, DefIdSet};
 use rustc_allocator::ALLOCATOR_METHODS;
-use syntax::attr;
 
 pub type ExportedSymbols = FxHashMap<
     CrateNum,
@@ -256,9 +256,10 @@ fn symbol_export_level_provider(tcx: TyCtxt, sym_def_id: DefId) -> SymbolExportL
     // special symbols in the standard library for various plumbing between
     // core/std/allocators/etc. For example symbols used to hook up allocation
     // are not considered for export
-    let is_extern = tcx.contains_extern_indicator(sym_def_id);
-    let std_internal = attr::contains_name(&tcx.get_attrs(sym_def_id),
-                                           "rustc_std_internal_symbol");
+    let trans_fn_attrs = tcx.trans_fn_attrs(sym_def_id);
+    let is_extern = trans_fn_attrs.contains_extern_indicator();
+    let std_internal = trans_fn_attrs.flags.contains(TransFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL);
+
     if is_extern && !std_internal {
         SymbolExportLevel::C
     } else {
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs
index beb7a091bdc..3708f6f6ec4 100644
--- a/src/librustc_trans/base.rs
+++ b/src/librustc_trans/base.rs
@@ -90,7 +90,6 @@ use syntax::ast;
 use mir::operand::OperandValue;
 
 pub use rustc_trans_utils::check_for_rustc_errors_attr;
-pub use rustc_mir::monomorphize::item::linkage_by_name;
 
 pub struct StatRecorder<'a, 'tcx: 'a> {
     cx: &'a CodegenCx<'a, 'tcx>,
diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs
index 37bd225a7d9..7c4e2340d5b 100644
--- a/src/librustc_trans/common.rs
+++ b/src/librustc_trans/common.rs
@@ -44,7 +44,7 @@ pub fn type_needs_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> b
 }
 
 pub fn type_is_sized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool {
-    ty.is_sized(tcx, ty::ParamEnv::empty(traits::Reveal::All), DUMMY_SP)
+    ty.is_sized(tcx.at(DUMMY_SP), ty::ParamEnv::empty(traits::Reveal::All))
 }
 
 pub fn type_is_freeze<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool {
diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs
index fd9cb8c5a6b..0ce3f729305 100644
--- a/src/librustc_trans/consts.rs
+++ b/src/librustc_trans/consts.rs
@@ -146,20 +146,12 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
             hir_map::NodeForeignItem(&hir::ForeignItem {
                 ref attrs, span, node: hir::ForeignItemStatic(..), ..
             }) => {
-
-                let g = if let Some(name) =
-                        attr::first_attr_value_str_by_name(&attrs, "linkage") {
+                let g = if let Some(linkage) = cx.tcx.trans_fn_attrs(def_id).linkage {
                     // If this is a static with a linkage specified, then we need to handle
                     // it a little specially. The typesystem prevents things like &T and
                     // extern "C" fn() from being non-null, so we can't just declare a
                     // static and call it a day. Some linkages (like weak) will make it such
                     // that the static actually has a null value.
-                    let linkage = match base::linkage_by_name(&name.as_str()) {
-                        Some(linkage) => linkage,
-                        None => {
-                            cx.sess().span_fatal(span, "invalid linkage specified");
-                        }
-                    };
                     let llty2 = match ty.sty {
                         ty::TyRawPtr(ref mt) => cx.layout_of(mt.ty).llvm_type(cx),
                         _ => {
diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs
index b93e8c2ad21..dc5e7889594 100644
--- a/src/librustc_trans/context.rs
+++ b/src/librustc_trans/context.rs
@@ -435,7 +435,7 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
 
     pub fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
         use syntax_pos::DUMMY_SP;
-        if ty.is_sized(self.tcx, ty::ParamEnv::empty(traits::Reveal::All), DUMMY_SP) {
+        if ty.is_sized(self.tcx.at(DUMMY_SP), ty::ParamEnv::empty(traits::Reveal::All)) {
             return false;
         }
 
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index 0b8da10b78e..74df5127269 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -50,7 +50,7 @@ extern crate rustc_allocator;
 extern crate rustc_apfloat;
 extern crate rustc_back;
 extern crate rustc_const_math;
-extern crate rustc_data_structures;
+#[macro_use] extern crate rustc_data_structures;
 extern crate rustc_demangle;
 extern crate rustc_incremental;
 extern crate rustc_llvm as llvm;
diff --git a/src/librustc_trans/metadata.rs b/src/librustc_trans/metadata.rs
index d57624da0c6..9483420f2f0 100644
--- a/src/librustc_trans/metadata.rs
+++ b/src/librustc_trans/metadata.rs
@@ -15,17 +15,19 @@ use llvm;
 use llvm::{False, ObjectFile, mk_section_iter};
 use llvm::archive_ro::ArchiveRO;
 
-use rustc_data_structures::owning_ref::{ErasedBoxRef, OwningRef};
+use rustc_data_structures::owning_ref::OwningRef;
 use std::path::Path;
 use std::ptr;
 use std::slice;
 
+pub use rustc_data_structures::sync::MetadataRef;
+
 pub const METADATA_FILENAME: &str = "rust.metadata.bin";
 
 pub struct LlvmMetadataLoader;
 
 impl MetadataLoader for LlvmMetadataLoader {
-    fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<ErasedBoxRef<[u8]>, String> {
+    fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<MetadataRef, String> {
         // Use ArchiveRO for speed here, it's backed by LLVM and uses mmap
         // internally to read the file. We also avoid even using a memcpy by
         // just keeping the archive along while the metadata is in use.
@@ -47,13 +49,13 @@ impl MetadataLoader for LlvmMetadataLoader {
                                 filename.display())
                     })
             })?;
-        Ok(buf.erase_owner())
+        Ok(rustc_erase_owner!(buf))
     }
 
     fn get_dylib_metadata(&self,
                           target: &Target,
                           filename: &Path)
-                          -> Result<ErasedBoxRef<[u8]>, String> {
+                          -> Result<MetadataRef, String> {
         unsafe {
             let buf = common::path2cstr(filename);
             let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr());
@@ -65,7 +67,7 @@ impl MetadataLoader for LlvmMetadataLoader {
                 .ok_or_else(|| format!("provided path not an object file: '{}'",
                                         filename.display()))?;
             let buf = of.try_map(|of| search_meta_section(of, target, filename))?;
-            Ok(buf.erase_owner())
+            Ok(rustc_erase_owner!(buf))
         }
     }
 }
diff --git a/src/librustc_trans_utils/diagnostics.rs b/src/librustc_trans_utils/diagnostics.rs
deleted file mode 100644
index 13fa15faf41..00000000000
--- a/src/librustc_trans_utils/diagnostics.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![allow(non_snake_case)]
-
-register_long_diagnostics! {
-
-E0558: r##"
-The `export_name` attribute was malformed.
-
-Erroneous code example:
-
-```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail)
-#[export_name] // error: export_name attribute has invalid format
-pub fn something() {}
-
-fn main() {}
-```
-
-The `export_name` attribute expects a string in order to determine the name of
-the exported symbol. Example:
-
-```
-#[export_name = "some_function"] // ok!
-pub fn something() {}
-
-fn main() {}
-```
-"##,
-
-}
diff --git a/src/librustc_trans_utils/lib.rs b/src/librustc_trans_utils/lib.rs
index d636a5f2e64..6a3fd21f3a7 100644
--- a/src/librustc_trans_utils/lib.rs
+++ b/src/librustc_trans_utils/lib.rs
@@ -37,16 +37,14 @@ extern crate rustc;
 extern crate rustc_back;
 extern crate rustc_mir;
 extern crate rustc_incremental;
-#[macro_use]
 extern crate syntax;
 extern crate syntax_pos;
-extern crate rustc_data_structures;
+#[macro_use] extern crate rustc_data_structures;
 
 pub extern crate rustc as __rustc;
 
 use rustc::ty::TyCtxt;
 
-pub mod diagnostics;
 pub mod link;
 pub mod trans_crate;
 pub mod symbol_names;
diff --git a/src/librustc_trans_utils/symbol_names.rs b/src/librustc_trans_utils/symbol_names.rs
index fb299bf7eea..f9f93730255 100644
--- a/src/librustc_trans_utils/symbol_names.rs
+++ b/src/librustc_trans_utils/symbol_names.rs
@@ -120,29 +120,6 @@ pub fn provide(providers: &mut Providers) {
         def_symbol_name,
         symbol_name,
 
-        export_name: |tcx, id| {
-            tcx.get_attrs(id).iter().fold(None, |ia, attr| {
-                if attr.check_name("export_name") {
-                    if let s @ Some(_) = attr.value_str() {
-                        s
-                    } else {
-                        struct_span_err!(tcx.sess, attr.span, E0558,
-                                         "export_name attribute has invalid format")
-                            .span_label(attr.span, "did you mean #[export_name=\"*\"]?")
-                            .emit();
-                        None
-                    }
-                } else {
-                    ia
-                }
-            })
-        },
-
-        contains_extern_indicator: |tcx, id| {
-            attr::contains_name(&tcx.get_attrs(id), "no_mangle") ||
-                tcx.export_name(id).is_some()
-        },
-
         ..*providers
     };
 }
@@ -287,7 +264,7 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
         return tcx.item_name(def_id).to_string();
     }
 
-    if let Some(name) = tcx.export_name(def_id) {
+    if let Some(name) = tcx.trans_fn_attrs(def_id).export_name {
         // Use provided name
         return name.to_string();
     }
diff --git a/src/librustc_trans_utils/trans_crate.rs b/src/librustc_trans_utils/trans_crate.rs
index 7b2cbe140ae..0d4811c4b02 100644
--- a/src/librustc_trans_utils/trans_crate.rs
+++ b/src/librustc_trans_utils/trans_crate.rs
@@ -28,7 +28,7 @@ use std::fs::File;
 use std::path::Path;
 use std::sync::mpsc;
 
-use rustc_data_structures::owning_ref::{ErasedBoxRef, OwningRef};
+use rustc_data_structures::owning_ref::OwningRef;
 use rustc_data_structures::sync::Lrc;
 use ar::{Archive, Builder, Header};
 use flate2::Compression;
@@ -44,9 +44,12 @@ use rustc::middle::cstore::EncodedMetadata;
 use rustc::middle::cstore::MetadataLoader;
 use rustc::dep_graph::DepGraph;
 use rustc_back::target::Target;
+use rustc_data_structures::fx::FxHashSet;
 use rustc_mir::monomorphize::collector;
 use link::{build_link_meta, out_filename};
 
+pub use rustc_data_structures::sync::MetadataRef;
+
 pub trait TransCrate {
     fn init(&self, _sess: &Session) {}
     fn print(&self, _req: PrintRequest, _sess: &Session) {}
@@ -119,7 +122,7 @@ impl MetadataLoader for DummyMetadataLoader {
         &self,
         _target: &Target,
         _filename: &Path
-    ) -> Result<ErasedBoxRef<[u8]>, String> {
+    ) -> Result<MetadataRef, String> {
         bug!("DummyMetadataLoader::get_rlib_metadata");
     }
 
@@ -127,7 +130,7 @@ impl MetadataLoader for DummyMetadataLoader {
         &self,
         _target: &Target,
         _filename: &Path
-    ) -> Result<ErasedBoxRef<[u8]>, String> {
+    ) -> Result<MetadataRef, String> {
         bug!("DummyMetadataLoader::get_dylib_metadata");
     }
 }
@@ -135,7 +138,7 @@ impl MetadataLoader for DummyMetadataLoader {
 pub struct NoLlvmMetadataLoader;
 
 impl MetadataLoader for NoLlvmMetadataLoader {
-    fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<ErasedBoxRef<[u8]>, String> {
+    fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<MetadataRef, String> {
         let file = File::open(filename)
             .map_err(|e| format!("metadata file open err: {:?}", e))?;
         let mut archive = Archive::new(file);
@@ -147,7 +150,7 @@ impl MetadataLoader for NoLlvmMetadataLoader {
                 let mut buf = Vec::new();
                 io::copy(&mut entry, &mut buf).unwrap();
                 let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(buf).into();
-                return Ok(buf.map_owner_box().erase_owner());
+                return Ok(rustc_erase_owner!(buf.map_owner_box()));
             }
         }
 
@@ -158,7 +161,7 @@ impl MetadataLoader for NoLlvmMetadataLoader {
         &self,
         _target: &Target,
         _filename: &Path,
-    ) -> Result<ErasedBoxRef<[u8]>, String> {
+    ) -> Result<MetadataRef, String> {
         // FIXME: Support reading dylibs from llvm enabled rustc
         self.get_rlib_metadata(_target, _filename)
     }
@@ -198,8 +201,9 @@ impl TransCrate for MetadataOnlyTransCrate {
 
     fn provide(&self, providers: &mut Providers) {
         ::symbol_names::provide(providers);
-        providers.target_features_enabled = |_tcx, _id| {
-            Lrc::new(Vec::new()) // Just a dummy
+
+        providers.target_features_whitelist = |_tcx, _cnum| {
+            Lrc::new(FxHashSet()) // Just a dummy
         };
     }
     fn provide_extern(&self, _providers: &mut Providers) {}
@@ -233,12 +237,8 @@ impl TransCrate for MetadataOnlyTransCrate {
                 MonoItem::Fn(inst) => {
                     let def_id = inst.def_id();
                     if def_id.is_local()  {
-                        let _ = tcx.export_name(def_id);
-                        let _ = tcx.contains_extern_indicator(def_id);
                         let _ = inst.def.is_inline(tcx);
-                        let attrs = inst.def.attrs(tcx);
-                        let _ =
-                            ::syntax::attr::find_inline_attr(Some(tcx.sess.diagnostic()), &attrs);
+                        let _ = tcx.trans_fn_attrs(def_id);
                     }
                 }
                 _ => {}
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 5e0c47f18bf..72e4b726a22 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -255,7 +255,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 let opt_trait_ref = match obligation.predicate {
                     ty::Predicate::Projection(ref data) => Some(data.to_poly_trait_ref(self.tcx)),
                     ty::Predicate::Trait(ref data) => Some(data.to_poly_trait_ref()),
-                    ty::Predicate::Equate(..) => None,
                     ty::Predicate::Subtype(..) => None,
                     ty::Predicate::RegionOutlives(..) => None,
                     ty::Predicate::TypeOutlives(..) => None,
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 841559013a0..4d344eb2799 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -635,7 +635,6 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
                             _ => None,
                         }
                     }
-                    ty::Predicate::Equate(..) |
                     ty::Predicate::Subtype(..) |
                     ty::Predicate::Projection(..) |
                     ty::Predicate::RegionOutlives(..) |
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index f7158593f0b..1a7d8bb5678 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -30,25 +30,29 @@ use constrained_type_params as ctp;
 use middle::lang_items::SizedTraitLangItem;
 use middle::const_val::ConstVal;
 use middle::resolve_lifetime as rl;
+use rustc::mir::mono::Linkage;
 use rustc::traits::Reveal;
 use rustc::ty::subst::Substs;
 use rustc::ty::{ToPredicate, ReprOptions};
 use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt};
 use rustc::ty::maps::Providers;
 use rustc::ty::util::IntTypeExt;
+use rustc::util::nodemap::FxHashSet;
 use util::nodemap::FxHashMap;
 
 use rustc_const_math::ConstInt;
 
 use syntax::{abi, ast};
+use syntax::ast::MetaItemKind;
+use syntax::attr::{InlineAttr, list_contains_name, mark_used};
 use syntax::codemap::Spanned;
 use syntax::symbol::{Symbol, keywords};
 use syntax_pos::{Span, DUMMY_SP};
 
-use rustc::hir::{self, map as hir_map};
+use rustc::hir::{self, map as hir_map, TransFnAttrs, TransFnAttrFlags, Unsafety};
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::hir::def::{Def, CtorKind};
-use rustc::hir::def_id::DefId;
+use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 
 ///////////////////////////////////////////////////////////////////////////
 // Main entry point
@@ -71,6 +75,7 @@ pub fn provide(providers: &mut Providers) {
         impl_trait_ref,
         impl_polarity,
         is_foreign_item,
+        trans_fn_attrs,
         ..*providers
     };
 }
@@ -1723,3 +1728,186 @@ fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         _ => bug!("is_foreign_item applied to non-local def-id {:?}", def_id)
     }
 }
+
+fn from_target_feature(
+    tcx: TyCtxt,
+    attr: &ast::Attribute,
+    whitelist: &FxHashSet<String>,
+    target_features: &mut Vec<Symbol>,
+) {
+    let list = match attr.meta_item_list() {
+        Some(list) => list,
+        None => {
+            let msg = "#[target_feature] attribute must be of the form \
+                       #[target_feature(..)]";
+            tcx.sess.span_err(attr.span, &msg);
+            return
+        }
+    };
+
+    for item in list {
+        if !item.check_name("enable") {
+            let msg = "#[target_feature(..)] only accepts sub-keys of `enable` \
+                       currently";
+            tcx.sess.span_err(item.span, &msg);
+            continue
+        }
+        let value = match item.value_str() {
+            Some(list) => list,
+            None => {
+                let msg = "#[target_feature] attribute must be of the form \
+                           #[target_feature(enable = \"..\")]";
+                tcx.sess.span_err(item.span, &msg);
+                continue
+            }
+        };
+        let value = value.as_str();
+        for feature in value.split(',') {
+            if whitelist.contains(feature) {
+                target_features.push(Symbol::intern(feature));
+                continue
+            }
+
+            let msg = format!("the feature named `{}` is not valid for \
+                               this target", feature);
+            let mut err = tcx.sess.struct_span_err(item.span, &msg);
+
+            if feature.starts_with("+") {
+                let valid = whitelist.contains(&feature[1..]);
+                if valid {
+                    err.help("consider removing the leading `+` in the feature name");
+                }
+            }
+            err.emit();
+        }
+    }
+}
+
+fn linkage_by_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, name: &str) -> Linkage {
+    use rustc::mir::mono::Linkage::*;
+
+    // Use the names from src/llvm/docs/LangRef.rst here. Most types are only
+    // applicable to variable declarations and may not really make sense for
+    // Rust code in the first place but whitelist them anyway and trust that
+    // the user knows what s/he's doing. Who knows, unanticipated use cases
+    // may pop up in the future.
+    //
+    // ghost, dllimport, dllexport and linkonce_odr_autohide are not supported
+    // and don't have to be, LLVM treats them as no-ops.
+    match name {
+        "appending" => Appending,
+        "available_externally" => AvailableExternally,
+        "common" => Common,
+        "extern_weak" => ExternalWeak,
+        "external" => External,
+        "internal" => Internal,
+        "linkonce" => LinkOnceAny,
+        "linkonce_odr" => LinkOnceODR,
+        "private" => Private,
+        "weak" => WeakAny,
+        "weak_odr" => WeakODR,
+        _ => {
+            let span = tcx.hir.span_if_local(def_id);
+            if let Some(span) = span {
+                tcx.sess.span_fatal(span, "invalid linkage specified")
+            } else {
+                tcx.sess.fatal(&format!("invalid linkage specified: {}", name))
+            }
+        }
+    }
+}
+
+fn trans_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> TransFnAttrs {
+    let attrs = tcx.get_attrs(id);
+
+    let mut trans_fn_attrs = TransFnAttrs::new();
+
+    let whitelist = tcx.target_features_whitelist(LOCAL_CRATE);
+
+    for attr in attrs.iter() {
+        if attr.check_name("cold") {
+            trans_fn_attrs.flags |= TransFnAttrFlags::COLD;
+        } else if attr.check_name("allocator") {
+            trans_fn_attrs.flags |= TransFnAttrFlags::ALLOCATOR;
+        } else if attr.check_name("unwind") {
+            trans_fn_attrs.flags |= TransFnAttrFlags::UNWIND;
+        } else if attr.check_name("rustc_allocator_nounwind") {
+            trans_fn_attrs.flags |= TransFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND;
+        } else if attr.check_name("naked") {
+            trans_fn_attrs.flags |= TransFnAttrFlags::NAKED;
+        } else if attr.check_name("no_mangle") {
+            trans_fn_attrs.flags |= TransFnAttrFlags::NO_MANGLE;
+        } else if attr.check_name("rustc_std_internal_symbol") {
+            trans_fn_attrs.flags |= TransFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
+        } else if attr.check_name("inline") {
+            trans_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| {
+                if attr.path != "inline" {
+                    return ia;
+                }
+                let meta = match attr.meta() {
+                    Some(meta) => meta.node,
+                    None => return ia,
+                };
+                match meta {
+                    MetaItemKind::Word => {
+                        mark_used(attr);
+                        InlineAttr::Hint
+                    }
+                    MetaItemKind::List(ref items) => {
+                        mark_used(attr);
+                        if items.len() != 1 {
+                            span_err!(tcx.sess.diagnostic(), attr.span, E0534,
+                                        "expected one argument");
+                            InlineAttr::None
+                        } else if list_contains_name(&items[..], "always") {
+                            InlineAttr::Always
+                        } else if list_contains_name(&items[..], "never") {
+                            InlineAttr::Never
+                        } else {
+                            span_err!(tcx.sess.diagnostic(), items[0].span, E0535,
+                                        "invalid argument");
+
+                            InlineAttr::None
+                        }
+                    }
+                    _ => ia,
+                }
+            });
+        } else if attr.check_name("export_name") {
+            if let s @ Some(_) = attr.value_str() {
+                trans_fn_attrs.export_name = s;
+            } else {
+                struct_span_err!(tcx.sess, attr.span, E0558,
+                                    "export_name attribute has invalid format")
+                    .span_label(attr.span, "did you mean #[export_name=\"*\"]?")
+                    .emit();
+            }
+        } else if attr.check_name("target_feature") {
+            if let Some(val) = attr.value_str() {
+                for feat in val.as_str().split(",").map(|f| f.trim()) {
+                    if !feat.is_empty() && !feat.contains('\0') {
+                        trans_fn_attrs.target_features.push(Symbol::intern(feat));
+                    }
+                }
+                let msg = "#[target_feature = \"..\"] is deprecated and will \
+                           eventually be removed, use \
+                           #[target_feature(enable = \"..\")] instead";
+                tcx.sess.span_warn(attr.span, &msg);
+                continue
+            }
+
+            if tcx.fn_sig(id).unsafety() == Unsafety::Normal {
+                let msg = "#[target_feature(..)] can only be applied to \
+                           `unsafe` function";
+                tcx.sess.span_err(attr.span, msg);
+            }
+            from_target_feature(tcx, attr, &whitelist, &mut trans_fn_attrs.target_features);
+        } else if attr.check_name("linkage") {
+            if let Some(val) = attr.value_str() {
+                trans_fn_attrs.linkage = Some(linkage_by_name(tcx, id, &val.as_str()));
+            }
+        }
+    }
+
+    trans_fn_attrs
+}
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index 6c195a991c2..96b2ec745f1 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -3705,6 +3705,98 @@ match r {
 ```
 "##,
 
+E0534: r##"
+The `inline` attribute was malformed.
+
+Erroneous code example:
+
+```ignore (compile_fail not working here; see Issue #43707)
+#[inline()] // error: expected one argument
+pub fn something() {}
+
+fn main() {}
+```
+
+The parenthesized `inline` attribute requires the parameter to be specified:
+
+```
+#[inline(always)]
+fn something() {}
+```
+
+or:
+
+```
+#[inline(never)]
+fn something() {}
+```
+
+Alternatively, a paren-less version of the attribute may be used to hint the
+compiler about inlining opportunity:
+
+```
+#[inline]
+fn something() {}
+```
+
+For more information about the inline attribute, read:
+https://doc.rust-lang.org/reference.html#inline-attributes
+"##,
+
+E0535: r##"
+An unknown argument was given to the `inline` attribute.
+
+Erroneous code example:
+
+```ignore (compile_fail not working here; see Issue #43707)
+#[inline(unknown)] // error: invalid argument
+pub fn something() {}
+
+fn main() {}
+```
+
+The `inline` attribute only supports two arguments:
+
+ * always
+ * never
+
+All other arguments given to the `inline` attribute will return this error.
+Example:
+
+```
+#[inline(never)] // ok!
+pub fn something() {}
+
+fn main() {}
+```
+
+For more information about the inline attribute, https:
+read://doc.rust-lang.org/reference.html#inline-attributes
+"##,
+
+E0558: r##"
+The `export_name` attribute was malformed.
+
+Erroneous code example:
+
+```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail)
+#[export_name] // error: export_name attribute has invalid format
+pub fn something() {}
+
+fn main() {}
+```
+
+The `export_name` attribute expects a string in order to determine the name of
+the exported symbol. Example:
+
+```
+#[export_name = "some_function"] // ok!
+pub fn something() {}
+
+fn main() {}
+```
+"##,
+
 E0559: r##"
 An unknown field was specified into an enum's structure variant.
 
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index f9f1c330494..d0230a69374 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1535,7 +1535,6 @@ impl<'a> Clean<WherePredicate> for ty::Predicate<'a> {
 
         match *self {
             Predicate::Trait(ref pred) => pred.clean(cx),
-            Predicate::Equate(ref pred) => pred.clean(cx),
             Predicate::Subtype(ref pred) => pred.clean(cx),
             Predicate::RegionOutlives(ref pred) => pred.clean(cx),
             Predicate::TypeOutlives(ref pred) => pred.clean(cx),
@@ -1557,16 +1556,6 @@ impl<'a> Clean<WherePredicate> for ty::TraitPredicate<'a> {
     }
 }
 
-impl<'tcx> Clean<WherePredicate> for ty::EquatePredicate<'tcx> {
-    fn clean(&self, cx: &DocContext) -> WherePredicate {
-        let ty::EquatePredicate(ref lhs, ref rhs) = *self;
-        WherePredicate::EqPredicate {
-            lhs: lhs.clean(cx),
-            rhs: rhs.clean(cx)
-        }
-    }
-}
-
 impl<'tcx> Clean<WherePredicate> for ty::SubtypePredicate<'tcx> {
     fn clean(&self, _cx: &DocContext) -> WherePredicate {
         panic!("subtype predicates are an internal rustc artifact \
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index fd14513cac4..0151a8c3ab7 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -28,6 +28,7 @@ pub struct Page<'a> {
     pub root_path: &'a str,
     pub description: &'a str,
     pub keywords: &'a str,
+    pub resource_suffix: &'a str,
 }
 
 pub fn render<T: fmt::Display, S: fmt::Display>(
@@ -47,12 +48,13 @@ r##"<!DOCTYPE html>
 
     <title>{title}</title>
 
-    <link rel="stylesheet" type="text/css" href="{root_path}normalize.css">
-    <link rel="stylesheet" type="text/css" href="{root_path}rustdoc.css" id="mainThemeStyle">
+    <link rel="stylesheet" type="text/css" href="{root_path}normalize{suffix}.css">
+    <link rel="stylesheet" type="text/css" href="{root_path}rustdoc{suffix}.css"
+          id="mainThemeStyle">
     {themes}
-    <link rel="stylesheet" type="text/css" href="{root_path}dark.css">
-    <link rel="stylesheet" type="text/css" href="{root_path}main.css" id="themeStyle">
-    <script src="{root_path}storage.js"></script>
+    <link rel="stylesheet" type="text/css" href="{root_path}dark{suffix}.css">
+    <link rel="stylesheet" type="text/css" href="{root_path}main{suffix}.css" id="themeStyle">
+    <script src="{root_path}storage{suffix}.js"></script>
     {css_extension}
 
     {favicon}
@@ -76,11 +78,11 @@ r##"<!DOCTYPE html>
 
     <div class="theme-picker">
         <button id="theme-picker" aria-label="Pick another theme!">
-            <img src="{root_path}brush.svg" width="18" alt="Pick another theme!">
+            <img src="{root_path}brush{suffix}.svg" width="18" alt="Pick another theme!">
         </button>
         <div id="theme-choices"></div>
     </div>
-    <script src="{root_path}theme.js"></script>
+    <script src="{root_path}theme{suffix}.js"></script>
     <nav class="sub">
         <form class="search-form js-only">
             <div class="search-container">
@@ -153,13 +155,14 @@ r##"<!DOCTYPE html>
         window.rootPath = "{root_path}";
         window.currentCrate = "{krate}";
     </script>
-    <script src="{root_path}main.js"></script>
+    <script src="{root_path}main{suffix}.js"></script>
     <script defer src="{root_path}search-index.js"></script>
 </body>
 </html>"##,
     css_extension = if css_file_extension {
-        format!("<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}theme.css\">",
-                root_path = page.root_path)
+        format!("<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}theme{suffix}.css\">",
+                root_path = page.root_path,
+                suffix=page.resource_suffix)
     } else {
         "".to_owned()
     },
@@ -191,8 +194,10 @@ r##"<!DOCTYPE html>
                    .filter_map(|t| t.file_stem())
                    .filter_map(|t| t.to_str())
                    .map(|t| format!(r#"<link rel="stylesheet" type="text/css" href="{}{}">"#,
-                                    page.root_path, t))
+                                    page.root_path,
+                                    t.replace(".css", &format!("{}.css", page.resource_suffix))))
                    .collect::<String>(),
+    suffix=page.resource_suffix,
     )
 }
 
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index e7bb0b03ce2..6945a6f3724 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -32,6 +32,7 @@
 //! for creating the corresponding search index and source file renderings.
 //! These threads are not parallelized (they haven't been a bottleneck yet), and
 //! both occur before the crate is rendered.
+
 pub use self::ExternalLocation::*;
 
 use std::borrow::Cow;
@@ -128,6 +129,9 @@ pub struct SharedContext {
     pub sort_modules_alphabetically: bool,
     /// Additional themes to be added to the generated docs.
     pub themes: Vec<PathBuf>,
+    /// Suffix to be added on resource files (if suffix is "-v2" then "main.css" becomes
+    /// "main-v2.css").
+    pub resource_suffix: String,
 }
 
 impl SharedContext {
@@ -492,6 +496,7 @@ pub fn run(mut krate: clean::Crate,
            external_html: &ExternalHtml,
            playground_url: Option<String>,
            dst: PathBuf,
+           resource_suffix: String,
            passes: FxHashSet<String>,
            css_file_extension: Option<PathBuf>,
            renderinfo: RenderInfo,
@@ -520,6 +525,7 @@ pub fn run(mut krate: clean::Crate,
         created_dirs: RefCell::new(FxHashSet()),
         sort_modules_alphabetically,
         themes,
+        resource_suffix,
     };
 
     // If user passed in `--playground-url` arg, we fill in crate name here
@@ -734,7 +740,7 @@ fn write_shared(cx: &Context,
     // Add all the static files. These may already exist, but we just
     // overwrite them anyway to make sure that they're fresh and up-to-date.
 
-    write(cx.dst.join("rustdoc.css"),
+    write(cx.dst.join(&format!("rustdoc{}.css", cx.shared.resource_suffix)),
           include_bytes!("static/rustdoc.css"))?;
 
     // To avoid "main.css" to be overwritten, we'll first run over the received themes and only
@@ -746,16 +752,19 @@ fn write_shared(cx: &Context,
 
         let mut f = try_err!(File::open(&entry), &entry);
         try_err!(f.read_to_end(&mut content), &entry);
-        write(cx.dst.join(try_none!(entry.file_name(), &entry)), content.as_slice())?;
-        themes.insert(try_none!(try_none!(entry.file_stem(), &entry).to_str(), &entry).to_owned());
+        let theme = try_none!(try_none!(entry.file_stem(), &entry).to_str(), &entry);
+        let extension = try_none!(try_none!(entry.extension(), &entry).to_str(), &entry);
+        write(cx.dst.join(format!("{}{}.{}", theme, cx.shared.resource_suffix, extension)),
+              content.as_slice())?;
+        themes.insert(theme.to_owned());
     }
 
-    write(cx.dst.join("brush.svg"),
+    write(cx.dst.join(&format!("brush{}.svg", cx.shared.resource_suffix)),
           include_bytes!("static/brush.svg"))?;
-    write(cx.dst.join("main.css"),
+    write(cx.dst.join(&format!("main{}.css", cx.shared.resource_suffix)),
           include_bytes!("static/themes/main.css"))?;
     themes.insert("main".to_owned());
-    write(cx.dst.join("dark.css"),
+    write(cx.dst.join(&format!("dark{}.css", cx.shared.resource_suffix)),
           include_bytes!("static/themes/dark.css"))?;
     themes.insert("dark".to_owned());
 
@@ -763,7 +772,8 @@ fn write_shared(cx: &Context,
     themes.sort();
     // To avoid theme switch latencies as much as possible, we put everything theme related
     // at the beginning of the html files into another js file.
-    write(cx.dst.join("theme.js"), format!(
+    write(cx.dst.join(&format!("theme{}.js", cx.shared.resource_suffix)),
+          format!(
 r#"var themes = document.getElementById("theme-choices");
 var themePicker = document.getElementById("theme-picker");
 themePicker.onclick = function() {{
@@ -785,19 +795,28 @@ themePicker.onclick = function() {{
     }};
     themes.appendChild(but);
 }});
-"#, themes.iter()
-          .map(|s| format!("\"{}\"", s))
-          .collect::<Vec<String>>()
-          .join(",")).as_bytes())?;
+"#,
+                 themes.iter()
+                       .map(|s| format!("\"{}\"", s))
+                       .collect::<Vec<String>>()
+                       .join(",")).as_bytes(),
+    )?;
+
+    write(cx.dst.join(&format!("main{}.js", cx.shared.resource_suffix)),
+                      include_bytes!("static/main.js"))?;
 
-    write(cx.dst.join("main.js"), include_bytes!("static/main.js"))?;
-    write(cx.dst.join("storage.js"), include_bytes!("static/storage.js"))?;
+    {
+        let mut data = format!("var resourcesSuffix = \"{}\";\n",
+                               cx.shared.resource_suffix).into_bytes();
+        data.extend_from_slice(include_bytes!("static/storage.js"));
+        write(cx.dst.join(&format!("storage{}.js", cx.shared.resource_suffix)), &data)?;
+    }
 
     if let Some(ref css) = cx.shared.css_file_extension {
-        let out = cx.dst.join("theme.css");
+        let out = cx.dst.join(&format!("theme{}.css", cx.shared.resource_suffix));
         try_err!(fs::copy(css, out), css);
     }
-    write(cx.dst.join("normalize.css"),
+    write(cx.dst.join(&format!("normalize{}.css", cx.shared.resource_suffix)),
           include_bytes!("static/normalize.css"))?;
     write(cx.dst.join("FiraSans-Regular.woff"),
           include_bytes!("static/FiraSans-Regular.woff"))?;
@@ -1084,6 +1103,7 @@ impl<'a> SourceCollector<'a> {
             root_path: &root_path,
             description: &desc,
             keywords: BASIC_KEYWORDS,
+            resource_suffix: &self.scx.resource_suffix,
         };
         layout::render(&mut w, &self.scx.layout,
                        &page, &(""), &Source(contents),
@@ -1446,6 +1466,7 @@ impl Context {
             title: &title,
             description: &desc,
             keywords: &keywords,
+            resource_suffix: &self.shared.resource_suffix,
         };
 
         reset_ids(true);
diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js
index f21dfc8af92..7e9cfbd6763 100644
--- a/src/librustdoc/html/static/storage.js
+++ b/src/librustdoc/html/static/storage.js
@@ -41,7 +41,9 @@ function getCurrentValue(name) {
 }
 
 function switchTheme(styleElem, mainStyleElem, newTheme) {
-    var newHref = mainStyleElem.href.replace("rustdoc.css", newTheme + ".css");
+    var fullBasicCss = "rustdoc" + resourcesSuffix + ".css";
+    var fullNewTheme = newTheme + resourcesSuffix + ".css";
+    var newHref = mainStyleElem.href.replace(fullBasicCss, fullNewTheme);
     var found = false;
 
     if (savedHref.length === 0) {
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 23b3c20c0ed..702031cfaca 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -261,6 +261,13 @@ pub fn opts() -> Vec<RustcOptGroup> {
                        "check if given theme is valid",
                        "FILES")
         }),
+        unstable("resource-suffix", |o| {
+            o.optopt("",
+                     "resource-suffix",
+                     "suffix to add to CSS and JavaScript files, e.g. \"main.css\" will become \
+                      \"main-suffix.css\"",
+                     "PATH")
+        }),
     ]
 }
 
@@ -417,6 +424,7 @@ pub fn main_args(args: &[String]) -> isize {
     let display_warnings = matches.opt_present("display-warnings");
     let linker = matches.opt_str("linker").map(PathBuf::from);
     let sort_modules_alphabetically = !matches.opt_present("sort-modules-by-appearance");
+    let resource_suffix = matches.opt_str("resource-suffix");
 
     match (should_test, markdown_input) {
         (true, true) => {
@@ -442,6 +450,7 @@ pub fn main_args(args: &[String]) -> isize {
             Some("html") | None => {
                 html::render::run(krate, &external_html, playground_url,
                                   output.unwrap_or(PathBuf::from("doc")),
+                                  resource_suffix.unwrap_or(String::new()),
                                   passes.into_iter().collect(),
                                   css_file_extension,
                                   renderinfo,
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index e5fc33e241c..d5ac2d19e83 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -1080,14 +1080,45 @@ impl fmt::Display for ExitStatus {
     }
 }
 
-/// This is ridiculously unstable, as it's a completely-punted-upon part
-/// of the `?`-in-`main` RFC.  It's here only to allow experimenting with
-/// returning a code directly from main.  It will definitely change
-/// drastically before being stabilized, if it doesn't just get deleted.
-#[doc(hidden)]
+/// This type represents the status code a process can return to its
+/// parent under normal termination.
+///
+/// Numeric values used in this type don't have portable meanings, and
+/// different platforms may mask different amounts of them.
+///
+/// For the platform's canonical successful and unsuccessful codes, see
+/// the [`SUCCESS`] and [`FAILURE`] associated items.
+///
+/// [`SUCCESS`]: #associatedconstant.SUCCESS
+/// [`FAILURE`]: #associatedconstant.FAILURE
+///
+/// **Warning**: While various forms of this were discussed in [RFC #1937],
+/// it was ultimately cut from that RFC, and thus this type is more subject
+/// to change even than the usual unstable item churn.
+///
+/// [RFC #1937]: https://github.com/rust-lang/rfcs/pull/1937
 #[derive(Clone, Copy, Debug)]
-#[unstable(feature = "process_exitcode_placeholder", issue = "43301")]
-pub struct ExitCode(pub i32);
+#[unstable(feature = "process_exitcode_placeholder", issue = "48711")]
+pub struct ExitCode(imp::ExitCode);
+
+#[unstable(feature = "process_exitcode_placeholder", issue = "48711")]
+impl ExitCode {
+    /// The canonical ExitCode for successful termination on this platform.
+    ///
+    /// Note that a `()`-returning `main` implicitly results in a successful
+    /// termination, so there's no need to return this from `main` unless
+    /// you're also returning other possible codes.
+    #[unstable(feature = "process_exitcode_placeholder", issue = "48711")]
+    pub const SUCCESS: ExitCode = ExitCode(imp::ExitCode::SUCCESS);
+
+    /// The canonical ExitCode for unsuccessful termination on this platform.
+    ///
+    /// If you're only returning this and `SUCCESS` from `main`, consider
+    /// instead returning `Err(_)` and `Ok(())` respectively, which will
+    /// return the same codes (but will also `eprintln!` the error).
+    #[unstable(feature = "process_exitcode_placeholder", issue = "48711")]
+    pub const FAILURE: ExitCode = ExitCode(imp::ExitCode::FAILURE);
+}
 
 impl Child {
     /// Forces the child to exit. This is equivalent to sending a
@@ -1401,18 +1432,6 @@ pub fn id() -> u32 {
     ::sys::os::getpid()
 }
 
-#[cfg(target_arch = "wasm32")]
-mod exit {
-    pub const SUCCESS: i32 = 0;
-    pub const FAILURE: i32 = 1;
-}
-#[cfg(not(target_arch = "wasm32"))]
-mod exit {
-    use libc;
-    pub const SUCCESS: i32 = libc::EXIT_SUCCESS;
-    pub const FAILURE: i32 = libc::EXIT_FAILURE;
-}
-
 /// A trait for implementing arbitrary return types in the `main` function.
 ///
 /// The c-main function only supports to return integers as return type.
@@ -1433,18 +1452,15 @@ pub trait Termination {
 
 #[unstable(feature = "termination_trait_lib", issue = "43301")]
 impl Termination for () {
-    fn report(self) -> i32 { exit::SUCCESS }
+    fn report(self) -> i32 { ExitCode::SUCCESS.report() }
 }
 
 #[unstable(feature = "termination_trait_lib", issue = "43301")]
 impl<E: fmt::Debug> Termination for Result<(), E> {
     fn report(self) -> i32 {
         match self {
-            Ok(val) => val.report(),
-            Err(err) => {
-                eprintln!("Error: {:?}", err);
-                exit::FAILURE
-            }
+            Ok(()) => ().report(),
+            Err(err) => Err::<!, _>(err).report(),
         }
     }
 }
@@ -1459,15 +1475,14 @@ impl<E: fmt::Debug> Termination for Result<!, E> {
     fn report(self) -> i32 {
         let Err(err) = self;
         eprintln!("Error: {:?}", err);
-        exit::FAILURE
+        ExitCode::FAILURE.report()
     }
 }
 
 #[unstable(feature = "termination_trait_lib", issue = "43301")]
 impl Termination for ExitCode {
     fn report(self) -> i32 {
-        let ExitCode(code) = self;
-        code
+        self.0.as_i32()
     }
 }
 
diff --git a/src/libstd/sys/cloudabi/shims/process.rs b/src/libstd/sys/cloudabi/shims/process.rs
index 52e8c82e2b2..fcd40c15c17 100644
--- a/src/libstd/sys/cloudabi/shims/process.rs
+++ b/src/libstd/sys/cloudabi/shims/process.rs
@@ -126,6 +126,18 @@ impl fmt::Display for ExitStatus {
     }
 }
 
+#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+pub struct ExitCode(bool);
+
+impl ExitCode {
+    pub const SUCCESS: ExitCode = ExitCode(false);
+    pub const FAILURE: ExitCode = ExitCode(true);
+
+    pub fn as_i32(&self) -> i32 {
+        self.0 as i32
+    }
+}
+
 pub struct Process(Void);
 
 impl Process {
diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs
index 3fd54973896..d0b94e14f54 100644
--- a/src/libstd/sys/redox/process.rs
+++ b/src/libstd/sys/redox/process.rs
@@ -13,6 +13,7 @@ use ffi::OsStr;
 use os::unix::ffi::OsStrExt;
 use fmt;
 use io::{self, Error, ErrorKind};
+use libc::{EXIT_SUCCESS, EXIT_FAILURE};
 use path::{Path, PathBuf};
 use sys::fd::FileDesc;
 use sys::fs::{File, OpenOptions};
@@ -480,6 +481,18 @@ impl fmt::Display for ExitStatus {
     }
 }
 
+#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+pub struct ExitCode(u8);
+
+impl ExitCode {
+    pub const SUCCESS: ExitCode = ExitCode(EXIT_SUCCESS as _);
+    pub const FAILURE: ExitCode = ExitCode(EXIT_FAILURE as _);
+
+    pub fn as_i32(&self) -> i32 {
+        self.0 as i32
+    }
+}
+
 /// The unique id of the process (this should never be negative).
 pub struct Process {
     pid: usize,
diff --git a/src/libstd/sys/unix/process/mod.rs b/src/libstd/sys/unix/process/mod.rs
index 2a331069bc2..d8ac26c45b1 100644
--- a/src/libstd/sys/unix/process/mod.rs
+++ b/src/libstd/sys/unix/process/mod.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub use self::process_common::{Command, ExitStatus, Stdio, StdioPipes};
+pub use self::process_common::{Command, ExitStatus, ExitCode, Stdio, StdioPipes};
 pub use self::process_inner::Process;
 
 mod process_common;
diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs
index 7e057401fab..d0486f06a14 100644
--- a/src/libstd/sys/unix/process/process_common.rs
+++ b/src/libstd/sys/unix/process/process_common.rs
@@ -13,7 +13,7 @@ use os::unix::prelude::*;
 use ffi::{OsString, OsStr, CString, CStr};
 use fmt;
 use io;
-use libc::{self, c_int, gid_t, uid_t, c_char};
+use libc::{self, c_int, gid_t, uid_t, c_char, EXIT_SUCCESS, EXIT_FAILURE};
 use ptr;
 use sys::fd::FileDesc;
 use sys::fs::{File, OpenOptions};
@@ -393,6 +393,18 @@ impl fmt::Display for ExitStatus {
     }
 }
 
+#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+pub struct ExitCode(u8);
+
+impl ExitCode {
+    pub const SUCCESS: ExitCode = ExitCode(EXIT_SUCCESS as _);
+    pub const FAILURE: ExitCode = ExitCode(EXIT_FAILURE as _);
+
+    pub fn as_i32(&self) -> i32 {
+        self.0 as i32
+    }
+}
+
 #[cfg(all(test, not(target_os = "emscripten")))]
 mod tests {
     use super::*;
diff --git a/src/libstd/sys/wasm/process.rs b/src/libstd/sys/wasm/process.rs
index f3f5de350f1..433e9cec7c8 100644
--- a/src/libstd/sys/wasm/process.rs
+++ b/src/libstd/sys/wasm/process.rs
@@ -129,6 +129,18 @@ impl fmt::Display for ExitStatus {
     }
 }
 
+#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+pub struct ExitCode(bool);
+
+impl ExitCode {
+    pub const SUCCESS: ExitCode = ExitCode(false);
+    pub const FAILURE: ExitCode = ExitCode(true);
+
+    pub fn as_i32(&self) -> i32 {
+        self.0 as i32
+    }
+}
+
 pub struct Process(Void);
 
 impl Process {
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs
index c93179869a6..f1ab9c47609 100644
--- a/src/libstd/sys/windows/process.rs
+++ b/src/libstd/sys/windows/process.rs
@@ -18,7 +18,7 @@ use ffi::{OsString, OsStr};
 use fmt;
 use fs;
 use io::{self, Error, ErrorKind};
-use libc::c_void;
+use libc::{c_void, EXIT_SUCCESS, EXIT_FAILURE};
 use mem;
 use os::windows::ffi::OsStrExt;
 use path::Path;
@@ -408,6 +408,18 @@ impl fmt::Display for ExitStatus {
     }
 }
 
+#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+pub struct ExitCode(c::DWORD);
+
+impl ExitCode {
+    pub const SUCCESS: ExitCode = ExitCode(EXIT_SUCCESS as _);
+    pub const FAILURE: ExitCode = ExitCode(EXIT_FAILURE as _);
+
+    pub fn as_i32(&self) -> i32 {
+        self.0 as i32
+    }
+}
+
 fn zeroed_startupinfo() -> c::STARTUPINFO {
     c::STARTUPINFO {
         cb: 0,
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index d0822b69aa6..4818248129e 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -520,7 +520,7 @@ pub fn find_crate_name(attrs: &[Attribute]) -> Option<Symbol> {
     first_attr_value_str_by_name(attrs, "crate_name")
 }
 
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Hash, PartialEq, RustcEncodable, RustcDecodable)]
 pub enum InlineAttr {
     None,
     Hint,
@@ -528,43 +528,6 @@ pub enum InlineAttr {
     Never,
 }
 
-/// Determine what `#[inline]` attribute is present in `attrs`, if any.
-pub fn find_inline_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> InlineAttr {
-    attrs.iter().fold(InlineAttr::None, |ia, attr| {
-        if attr.path != "inline" {
-            return ia;
-        }
-        let meta = match attr.meta() {
-            Some(meta) => meta.node,
-            None => return ia,
-        };
-        match meta {
-            MetaItemKind::Word => {
-                mark_used(attr);
-                InlineAttr::Hint
-            }
-            MetaItemKind::List(ref items) => {
-                mark_used(attr);
-                if items.len() != 1 {
-                    diagnostic.map(|d|{ span_err!(d, attr.span, E0534, "expected one argument"); });
-                    InlineAttr::None
-                } else if list_contains_name(&items[..], "always") {
-                    InlineAttr::Always
-                } else if list_contains_name(&items[..], "never") {
-                    InlineAttr::Never
-                } else {
-                    diagnostic.map(|d| {
-                        span_err!(d, items[0].span, E0535, "invalid argument");
-                    });
-
-                    InlineAttr::None
-                }
-            }
-            _ => ia,
-        }
-    })
-}
-
 #[derive(Copy, Clone, PartialEq)]
 pub enum UnwindAttr {
     Allowed,
@@ -610,13 +573,6 @@ pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Op
     })
 }
 
-/// True if `#[inline]` or `#[inline(always)]` is present in `attrs`.
-pub fn requests_inline(attrs: &[Attribute]) -> bool {
-    match find_inline_attr(None, attrs) {
-        InlineAttr::Hint | InlineAttr::Always => true,
-        InlineAttr::None | InlineAttr::Never => false,
-    }
-}
 
 /// Tests if a cfg-pattern matches the cfg set
 pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Features>) -> bool {
diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs
index 84ab0336f16..549ef88afcc 100644
--- a/src/libsyntax/diagnostic_list.rs
+++ b/src/libsyntax/diagnostic_list.rs
@@ -37,75 +37,6 @@ More details can be found in [RFC 438].
 [RFC 438]: https://github.com/rust-lang/rfcs/pull/438
 "##,
 
-E0534: r##"
-The `inline` attribute was malformed.
-
-Erroneous code example:
-
-```ignore (compile_fail not working here; see Issue #43707)
-#[inline()] // error: expected one argument
-pub fn something() {}
-
-fn main() {}
-```
-
-The parenthesized `inline` attribute requires the parameter to be specified:
-
-```
-#[inline(always)]
-fn something() {}
-```
-
-or:
-
-```
-#[inline(never)]
-fn something() {}
-```
-
-Alternatively, a paren-less version of the attribute may be used to hint the
-compiler about inlining opportunity:
-
-```
-#[inline]
-fn something() {}
-```
-
-For more information about the inline attribute, read:
-https://doc.rust-lang.org/reference.html#inline-attributes
-"##,
-
-E0535: r##"
-An unknown argument was given to the `inline` attribute.
-
-Erroneous code example:
-
-```ignore (compile_fail not working here; see Issue #43707)
-#[inline(unknown)] // error: invalid argument
-pub fn something() {}
-
-fn main() {}
-```
-
-The `inline` attribute only supports two arguments:
-
- * always
- * never
-
-All other arguments given to the `inline` attribute will return this error.
-Example:
-
-```
-#[inline(never)] // ok!
-pub fn something() {}
-
-fn main() {}
-```
-
-For more information about the inline attribute, https:
-read://doc.rust-lang.org/reference.html#inline-attributes
-"##,
-
 E0536: r##"
 The `not` cfg-predicate was malformed.
 
diff --git a/src/llvm b/src/llvm
-Subproject ba2edd794c7def715007931fcd1b4ce62aa711c
+Subproject 0903c72cbbc3dafcb5c88820e4a8a98c3a764cf
diff --git a/src/rustllvm/llvm-rebuild-trigger b/src/rustllvm/llvm-rebuild-trigger
index 3cd044708ce..63af7a0d538 100644
--- a/src/rustllvm/llvm-rebuild-trigger
+++ b/src/rustllvm/llvm-rebuild-trigger
@@ -1,4 +1,4 @@
 # If this file is modified, then llvm will be (optionally) cleaned and then rebuilt.
 # The actual contents of this file do not matter, but to trigger a change on the
 # build bots then the contents should be changed so git updates the mtime.
-2018-02-09
+2018-03-06
diff --git a/src/test/run-make/save-analysis-fail/foo.rs b/src/test/run-make/save-analysis-fail/foo.rs
index 07322d8bbc3..b844f2e49e7 100644
--- a/src/test/run-make/save-analysis-fail/foo.rs
+++ b/src/test/run-make/save-analysis-fail/foo.rs
@@ -459,3 +459,10 @@ struct Rls699 {
 fn new(f: u32) -> Rls699 {
     Rls699 { fs }
 }
+
+fn invalid_tuple_struct_access() {
+    bar.0;
+
+    struct S;
+    S.0;
+}
diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs
index 30ecc4e8937..80fa4d17b61 100644
--- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs
+++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs
@@ -14,5 +14,5 @@
 use std::process::ExitCode;
 
 fn main() -> ExitCode {
-    ExitCode(0)
+    ExitCode::SUCCESS
 }
diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml
index fb7125ffa01..7d02f0b746d 100644
--- a/src/tools/compiletest/Cargo.toml
+++ b/src/tools/compiletest/Cargo.toml
@@ -10,11 +10,13 @@ filetime = "0.1"
 getopts = "0.2"
 log = "0.4"
 regex = "0.2"
-rustc-serialize = "0.3"
+serde = "1.0"
+serde_json = "1.0"
+serde_derive = "1.0"
 
 [target.'cfg(unix)'.dependencies]
 libc = "0.2"
 
 [target.'cfg(windows)'.dependencies]
-miow = "0.2"
-winapi = "0.2"
+miow = "0.3"
+winapi = { version = "0.3", features = ["winerror"] }
diff --git a/src/tools/compiletest/src/json.rs b/src/tools/compiletest/src/json.rs
index 8e9cd1a12fa..08630628b71 100644
--- a/src/tools/compiletest/src/json.rs
+++ b/src/tools/compiletest/src/json.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use errors::{Error, ErrorKind};
-use rustc_serialize::json;
+use serde_json;
 use std::str::FromStr;
 use std::path::Path;
 use runtest::ProcRes;
@@ -17,17 +17,16 @@ use runtest::ProcRes;
 // These structs are a subset of the ones found in
 // `syntax::json`.
 
-#[derive(RustcEncodable, RustcDecodable)]
+#[derive(Deserialize)]
 struct Diagnostic {
     message: String,
     code: Option<DiagnosticCode>,
     level: String,
     spans: Vec<DiagnosticSpan>,
     children: Vec<Diagnostic>,
-    rendered: Option<String>,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Clone)]
+#[derive(Deserialize, Clone)]
 struct DiagnosticSpan {
     file_name: String,
     line_start: usize,
@@ -40,7 +39,7 @@ struct DiagnosticSpan {
     expansion: Option<Box<DiagnosticSpanMacroExpansion>>,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Clone)]
+#[derive(Deserialize, Clone)]
 struct DiagnosticSpanMacroExpansion {
     /// span where macro was applied to generate this code
     span: DiagnosticSpan,
@@ -49,7 +48,7 @@ struct DiagnosticSpanMacroExpansion {
     macro_decl_name: String,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Clone)]
+#[derive(Deserialize, Clone)]
 struct DiagnosticCode {
     /// The code itself.
     code: String,
@@ -67,7 +66,7 @@ fn parse_line(file_name: &str, line: &str, output: &str, proc_res: &ProcRes) ->
     // The compiler sometimes intermingles non-JSON stuff into the
     // output.  This hack just skips over such lines. Yuck.
     if line.starts_with('{') {
-        match json::decode::<Diagnostic>(line) {
+        match serde_json::from_str::<Diagnostic>(line) {
             Ok(diagnostic) => {
                 let mut expected_errors = vec![];
                 push_expected_errors(&mut expected_errors, &diagnostic, &[], file_name);
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 7928cab74fe..e65c03a6e57 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -21,8 +21,10 @@ extern crate getopts;
 extern crate libc;
 #[macro_use]
 extern crate log;
-extern crate rustc_serialize;
 extern crate regex;
+#[macro_use]
+extern crate serde_derive;
+extern crate serde_json;
 extern crate test;
 
 use std::env;
diff --git a/src/tools/compiletest/src/read2.rs b/src/tools/compiletest/src/read2.rs
index 486c0d81e3f..4f55edc58ef 100644
--- a/src/tools/compiletest/src/read2.rs
+++ b/src/tools/compiletest/src/read2.rs
@@ -119,7 +119,7 @@ mod imp {
     use self::miow::iocp::{CompletionPort, CompletionStatus};
     use self::miow::pipe::NamedPipe;
     use self::miow::Overlapped;
-    use self::winapi::ERROR_BROKEN_PIPE;
+    use self::winapi::shared::winerror::ERROR_BROKEN_PIPE;
 
     struct Pipe<'a> {
         dst: &'a mut Vec<u8>,
diff --git a/src/tools/rust-installer b/src/tools/rust-installer
-Subproject b55e0fc77590cf5d23a01dedeb2104d8cbb48ef
+Subproject 118e078c5badd520d18b92813fd88789c8d341a