about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-11-06 06:14:03 +0000
committerbors <bors@rust-lang.org>2019-11-06 06:14:03 +0000
commite8b190ac4ad79e58d21ee1d573529ff74d8eedaa (patch)
tree4d022868d407cf1bed36883037e4e97d1fa5094a
parente4931eaaa3d95189b30e90d3af9f0db17c41bbb0 (diff)
parent4f9651b85409a1e6ad5199211947d124ebbab935 (diff)
downloadrust-e8b190ac4ad79e58d21ee1d573529ff74d8eedaa.tar.gz
rust-e8b190ac4ad79e58d21ee1d573529ff74d8eedaa.zip
Auto merge of #66143 - Centril:rollup-qmzuex0, r=Centril
Rollup of 9 pull requests

Successful merges:

 - #65776 (Rename `LocalInternedString` and more)
 - #65973 (caller_location: point to macro invocation sites, like file!/line!, and use in core::panic!.)
 - #66015 (librustc_lexer: Refactor the module)
 - #66062 (Configure LLVM module PIC level)
 - #66086 (bump smallvec to 1.0)
 - #66092 (Use KERN_ARND syscall for random numbers on NetBSD, same as FreeBSD.)
 - #66103 (Add target thumbv7neon-unknown-linux-musleabihf)
 - #66133 (Update the bundled `wasi-libc` repository)
 - #66139 (use American spelling for `pluralize!`)

Failed merges:

r? @ghost
-rw-r--r--Cargo.lock56
-rwxr-xr-xsrc/ci/docker/dist-various-2/build-wasi-toolchain.sh14
-rw-r--r--src/libarena/Cargo.toml2
-rw-r--r--src/libcore/macros.rs32
-rw-r--r--src/librustc/Cargo.toml2
-rw-r--r--src/librustc/arena.rs2
-rw-r--r--src/librustc/dep_graph/dep_node.rs2
-rw-r--r--src/librustc/hir/lowering.rs4
-rw-r--r--src/librustc/hir/print.rs4
-rw-r--r--src/librustc/ich/impls_syntax.rs14
-rw-r--r--src/librustc/lint/builtin.rs4
-rw-r--r--src/librustc/middle/resolve_lifetime.rs4
-rw-r--r--src/librustc/mir/mono.rs2
-rw-r--r--src/librustc/traits/error_reporting.rs6
-rw-r--r--src/librustc/traits/on_unimplemented.rs2
-rw-r--r--src/librustc/ty/error.rs14
-rw-r--r--src/librustc/ty/inhabitedness/def_id_forest.rs10
-rw-r--r--src/librustc/ty/query/on_disk_cache.rs2
-rw-r--r--src/librustc_apfloat/Cargo.toml2
-rw-r--r--src/librustc_codegen_llvm/attributes.rs2
-rw-r--r--src/librustc_codegen_llvm/context.rs4
-rw-r--r--src/librustc_codegen_llvm/debuginfo/namespace.rs6
-rw-r--r--src/librustc_codegen_llvm/llvm/ffi.rs1
-rw-r--r--src/librustc_codegen_ssa/back/command.rs2
-rw-r--r--src/librustc_codegen_ssa/back/symbol_export.rs6
-rw-r--r--src/librustc_codegen_ssa/base.rs6
-rw-r--r--src/librustc_codegen_ssa/mir/block.rs3
-rw-r--r--src/librustc_codegen_utils/symbol_names/legacy.rs5
-rw-r--r--src/librustc_data_structures/Cargo.toml2
-rw-r--r--src/librustc_errors/emitter.rs4
-rw-r--r--src/librustc_errors/lib.rs2
-rw-r--r--src/librustc_incremental/assert_module_sources.rs16
-rw-r--r--src/librustc_incremental/persist/dirty_clean.rs4
-rw-r--r--src/librustc_index/Cargo.toml2
-rw-r--r--src/librustc_interface/Cargo.toml2
-rw-r--r--src/librustc_lexer/src/cursor.rs12
-rw-r--r--src/librustc_lexer/src/lib.rs269
-rw-r--r--src/librustc_lint/builtin.rs6
-rw-r--r--src/librustc_lint/unused.rs4
-rw-r--r--src/librustc_metadata/Cargo.toml2
-rw-r--r--src/librustc_metadata/creader.rs2
-rw-r--r--src/librustc_metadata/native_libs.rs2
-rw-r--r--src/librustc_mir/Cargo.toml2
-rw-r--r--src/librustc_mir/borrow_check/conflict_errors.rs2
-rw-r--r--src/librustc_mir/hair/pattern/check_match.rs2
-rw-r--r--src/librustc_mir/interpret/intrinsics.rs5
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs12
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs4
-rw-r--r--src/librustc_mir/transform/qualify_min_const_fn.rs2
-rw-r--r--src/librustc_resolve/Cargo.toml2
-rw-r--r--src/librustc_resolve/check_unused.rs4
-rw-r--r--src/librustc_resolve/late.rs2
-rw-r--r--src/librustc_resolve/resolve_imports.rs4
-rw-r--r--src/librustc_target/spec/mod.rs1
-rw-r--r--src/librustc_target/spec/thumbv7neon_unknown_linux_musleabihf.rs37
-rw-r--r--src/librustc_traits/Cargo.toml2
-rw-r--r--src/librustc_typeck/Cargo.toml2
-rw-r--r--src/librustc_typeck/astconv.rs6
-rw-r--r--src/librustc_typeck/check/compare_method.rs10
-rw-r--r--src/librustc_typeck/check/demand.rs6
-rw-r--r--src/librustc_typeck/check/expr.rs4
-rw-r--r--src/librustc_typeck/check/method/suggest.rs8
-rw-r--r--src/librustc_typeck/check/mod.rs4
-rw-r--r--src/librustc_typeck/check/pat.rs16
-rw-r--r--src/librustc_typeck/collect.rs2
-rw-r--r--src/librustdoc/clean/cfg.rs2
-rw-r--r--src/librustdoc/clean/mod.rs4
-rw-r--r--src/librustdoc/html/render.rs2
-rw-r--r--src/libserialize/Cargo.toml2
-rw-r--r--src/libstd/sys/unix/rand.rs3
-rw-r--r--src/libsyntax/Cargo.toml2
-rw-r--r--src/libsyntax/ast.rs2
-rw-r--r--src/libsyntax/feature_gate/check.rs2
-rw-r--r--src/libsyntax/parse/literal.rs4
-rw-r--r--src/libsyntax/parse/parser/diagnostics.rs6
-rw-r--r--src/libsyntax/parse/parser/module.rs10
-rw-r--r--src/libsyntax/parse/parser/path.rs6
-rw-r--r--src/libsyntax/parse/parser/ty.rs4
-rw-r--r--src/libsyntax/print/pprust.rs6
-rw-r--r--src/libsyntax/tokenstream.rs2
-rw-r--r--src/libsyntax_expand/Cargo.toml2
-rw-r--r--src/libsyntax_expand/base.rs13
-rw-r--r--src/libsyntax_expand/mbe/macro_rules.rs2
-rw-r--r--src/libsyntax_expand/mbe/transcribe.rs6
-rw-r--r--src/libsyntax_ext/Cargo.toml2
-rw-r--r--src/libsyntax_ext/env.rs2
-rw-r--r--src/libsyntax_ext/format.rs6
-rw-r--r--src/libsyntax_pos/hygiene.rs19
-rw-r--r--src/libsyntax_pos/symbol.rs52
-rw-r--r--src/rustllvm/PassWrapper.cpp4
-rw-r--r--src/test/ui/rfc-2091-track-caller/caller-location-intrinsic.rs14
91 files changed, 479 insertions, 381 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 873f5da0537..a6dca2048d4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -68,7 +68,7 @@ name = "arena"
 version = "0.0.0"
 dependencies = [
  "rustc_data_structures",
- "smallvec",
+ "smallvec 1.0.0",
 ]
 
 [[package]]
@@ -487,7 +487,7 @@ dependencies = [
  "regex-syntax",
  "semver",
  "serde",
- "smallvec",
+ "smallvec 0.6.10",
  "toml",
  "unicode-normalization",
  "url 2.1.0",
@@ -655,7 +655,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0f0ed1a4de2235cabda8558ff5840bffb97fcb64c97827f354a451307df5f72b"
 dependencies = [
  "crossbeam-utils 0.6.5",
- "smallvec",
+ "smallvec 0.6.10",
 ]
 
 [[package]]
@@ -2392,7 +2392,7 @@ dependencies = [
  "libc",
  "rand 0.6.1",
  "rustc_version",
- "smallvec",
+ "smallvec 0.6.10",
  "winapi 0.3.6",
 ]
 
@@ -2407,7 +2407,7 @@ dependencies = [
  "libc",
  "redox_syscall",
  "rustc_version",
- "smallvec",
+ "smallvec 0.6.10",
  "winapi 0.3.6",
 ]
 
@@ -3135,7 +3135,7 @@ dependencies = [
  "rustc_target",
  "scoped-tls",
  "serialize",
- "smallvec",
+ "smallvec 1.0.0",
  "syntax",
  "syntax_pos",
 ]
@@ -3147,7 +3147,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a623fd4805842e9bd0bb6e6dace63efede0ee22de4522a0b03b7c3d15a22f009"
 dependencies = [
  "rustc-ap-rustc_data_structures",
- "smallvec",
+ "smallvec 0.6.10",
 ]
 
 [[package]]
@@ -3176,7 +3176,7 @@ dependencies = [
  "rustc-hash",
  "rustc-rayon 0.2.0",
  "rustc-rayon-core 0.2.0",
- "smallvec",
+ "smallvec 0.6.10",
  "stable_deref_trait",
 ]
 
@@ -3204,7 +3204,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "457a5c204ae2fdaa5bdb5b196e58ca59896870d80445fe423063c9453496e3ea"
 dependencies = [
  "rustc-ap-serialize",
- "smallvec",
+ "smallvec 0.6.10",
 ]
 
 [[package]]
@@ -3250,7 +3250,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "92679240e86f4583cc05f8dcf6439bdab87bac9e6555718469176de9bd52ba20"
 dependencies = [
  "indexmap",
- "smallvec",
+ "smallvec 0.6.10",
 ]
 
 [[package]]
@@ -3270,7 +3270,7 @@ dependencies = [
  "rustc-ap-serialize",
  "rustc-ap-syntax_pos",
  "scoped-tls",
- "smallvec",
+ "smallvec 0.6.10",
 ]
 
 [[package]]
@@ -3393,7 +3393,7 @@ dependencies = [
  "crossbeam-utils 0.6.5",
  "serde",
  "serde_json",
- "smallvec",
+ "smallvec 0.6.10",
  "syn 0.15.35",
  "url 2.1.0",
  "winapi 0.3.6",
@@ -3404,7 +3404,7 @@ name = "rustc_apfloat"
 version = "0.0.0"
 dependencies = [
  "bitflags",
- "smallvec",
+ "smallvec 1.0.0",
 ]
 
 [[package]]
@@ -3484,7 +3484,7 @@ dependencies = [
  "rustc-rayon-core 0.3.0",
  "rustc_index",
  "serialize",
- "smallvec",
+ "smallvec 1.0.0",
  "stable_deref_trait",
 ]
 
@@ -3552,7 +3552,7 @@ name = "rustc_index"
 version = "0.0.0"
 dependencies = [
  "serialize",
- "smallvec",
+ "smallvec 1.0.0",
 ]
 
 [[package]]
@@ -3579,7 +3579,7 @@ dependencies = [
  "rustc_traits",
  "rustc_typeck",
  "serialize",
- "smallvec",
+ "smallvec 1.0.0",
  "syntax",
  "syntax_expand",
  "syntax_ext",
@@ -3650,7 +3650,7 @@ dependencies = [
  "rustc_index",
  "rustc_target",
  "serialize",
- "smallvec",
+ "smallvec 1.0.0",
  "stable_deref_trait",
  "syntax",
  "syntax_expand",
@@ -3675,7 +3675,7 @@ dependencies = [
  "rustc_lexer",
  "rustc_target",
  "serialize",
- "smallvec",
+ "smallvec 1.0.0",
  "syntax",
  "syntax_pos",
 ]
@@ -3746,7 +3746,7 @@ dependencies = [
  "rustc_data_structures",
  "rustc_errors",
  "rustc_metadata",
- "smallvec",
+ "smallvec 1.0.0",
  "syntax",
  "syntax_expand",
  "syntax_pos",
@@ -3799,7 +3799,7 @@ dependencies = [
  "rustc",
  "rustc_data_structures",
  "rustc_target",
- "smallvec",
+ "smallvec 1.0.0",
  "syntax",
  "syntax_pos",
 ]
@@ -3826,7 +3826,7 @@ dependencies = [
  "rustc_errors",
  "rustc_index",
  "rustc_target",
- "smallvec",
+ "smallvec 1.0.0",
  "syntax",
  "syntax_pos",
 ]
@@ -4070,7 +4070,7 @@ name = "serialize"
 version = "0.0.0"
 dependencies = [
  "indexmap",
- "smallvec",
+ "smallvec 1.0.0",
 ]
 
 [[package]]
@@ -4135,6 +4135,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7"
 
 [[package]]
+name = "smallvec"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86"
+
+[[package]]
 name = "socket2"
 version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4359,7 +4365,7 @@ dependencies = [
  "rustc_target",
  "scoped-tls",
  "serialize",
- "smallvec",
+ "smallvec 1.0.0",
  "syntax_pos",
 ]
 
@@ -4377,7 +4383,7 @@ dependencies = [
  "rustc_target",
  "scoped-tls",
  "serialize",
- "smallvec",
+ "smallvec 1.0.0",
  "syntax",
  "syntax_pos",
 ]
@@ -4391,7 +4397,7 @@ dependencies = [
  "rustc_data_structures",
  "rustc_errors",
  "rustc_target",
- "smallvec",
+ "smallvec 1.0.0",
  "syntax",
  "syntax_expand",
  "syntax_pos",
diff --git a/src/ci/docker/dist-various-2/build-wasi-toolchain.sh b/src/ci/docker/dist-various-2/build-wasi-toolchain.sh
index f04ee781571..c63ea6facca 100755
--- a/src/ci/docker/dist-various-2/build-wasi-toolchain.sh
+++ b/src/ci/docker/dist-various-2/build-wasi-toolchain.sh
@@ -4,17 +4,17 @@
 
 set -ex
 
-# Originally from https://releases.llvm.org/8.0.0/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz
-curl https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/clang%2Bllvm-8.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz | \
+# Originally from https://releases.llvm.org/9.0.0/clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz
+curl https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/clang%2Bllvm-9.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz | \
   tar xJf -
-export PATH=`pwd`/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-14.04/bin:$PATH
+export PATH=`pwd`/clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-14.04/bin:$PATH
 
-git clone https://github.com/CraneStation/wasi-sysroot
+git clone https://github.com/CraneStation/wasi-libc
 
-cd wasi-sysroot
-git reset --hard e5f14be38362f1ab83302895a6e74b2ffd0e2302
+cd wasi-libc
+git reset --hard a94d2d04e7722b323573da2bd04e909a5763d35b
 make -j$(nproc) INSTALL_DIR=/wasm32-wasi install
 
 cd ..
-rm -rf reference-sysroot-wasi
+rm -rf wasi-libc
 rm -rf clang+llvm*
diff --git a/src/libarena/Cargo.toml b/src/libarena/Cargo.toml
index 2643912f6d7..5158aab8b7d 100644
--- a/src/libarena/Cargo.toml
+++ b/src/libarena/Cargo.toml
@@ -10,4 +10,4 @@ path = "lib.rs"
 
 [dependencies]
 rustc_data_structures = { path = "../librustc_data_structures" }
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index 8ccd31c95d5..131fb52e2d2 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -26,31 +26,29 @@ macro_rules! panic {
 /// For details, see `std::macros`.
 #[cfg(not(bootstrap))]
 #[macro_export]
-#[allow_internal_unstable(core_panic, panic_internals)]
+#[allow_internal_unstable(core_panic,
+    // FIXME(anp, eddyb) `core_intrinsics` is used here to allow calling
+    // the `caller_location` intrinsic, but once  `#[track_caller]` is implemented,
+    // `panicking::{panic, panic_fmt}` can use that instead of a `Location` argument.
+    core_intrinsics,
+)]
 #[stable(feature = "core", since = "1.6.0")]
 macro_rules! panic {
     () => (
         $crate::panic!("explicit panic")
     );
-    ($msg:expr) => ({
-        const LOC: &$crate::panic::Location<'_> = &$crate::panic::Location::internal_constructor(
-            $crate::file!(),
-            $crate::line!(),
-            $crate::column!(),
-        );
-        $crate::panicking::panic($msg, LOC)
-    });
+    ($msg:expr) => (
+        $crate::panicking::panic($msg, $crate::intrinsics::caller_location())
+    );
     ($msg:expr,) => (
         $crate::panic!($msg)
     );
-    ($fmt:expr, $($arg:tt)+) => ({
-        const LOC: &$crate::panic::Location<'_> = &$crate::panic::Location::internal_constructor(
-            $crate::file!(),
-            $crate::line!(),
-            $crate::column!(),
-        );
-        $crate::panicking::panic_fmt($crate::format_args!($fmt, $($arg)+), LOC)
-    });
+    ($fmt:expr, $($arg:tt)+) => (
+        $crate::panicking::panic_fmt(
+            $crate::format_args!($fmt, $($arg)+),
+            $crate::intrinsics::caller_location(),
+        )
+    );
 }
 
 /// Asserts that two expressions are equal to each other (using [`PartialEq`]).
diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml
index de67f46eba6..92b94af75d7 100644
--- a/src/librustc/Cargo.toml
+++ b/src/librustc/Cargo.toml
@@ -39,5 +39,5 @@ parking_lot = "0.9"
 byteorder = { version = "1.3" }
 chalk-engine = { version = "0.9.0", default-features=false }
 rustc_fs_util = { path = "../librustc_fs_util" }
-smallvec = { version = "0.6.8", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 measureme = "0.4"
diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index 3daf0fc9df7..9b13a910c61 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -304,7 +304,7 @@ impl DropArena {
         // Move the content to the arena by copying it and then forgetting
         // the content of the SmallVec
         vec.as_ptr().copy_to_nonoverlapping(start_ptr, len);
-        mem::forget(vec.drain());
+        mem::forget(vec.drain(..));
 
         // Record the destructors after doing the allocation as that may panic
         // and would cause `object`'s destuctor to run twice if it was recorded before
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index dea8d70aaf4..cea790375fc 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -525,7 +525,7 @@ impl<'tcx> DepNodeParams<'tcx> for CrateNum {
     }
 
     fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
-        tcx.crate_name(*self).as_str().to_string()
+        tcx.crate_name(*self).to_string()
     }
 }
 
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index c6acdf53de3..c8bb35202f5 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -3382,7 +3382,7 @@ pub fn is_range_literal(sess: &Session, expr: &hir::Expr) -> bool {
     // either in std or core, i.e. has either a `::std::ops::Range` or
     // `::core::ops::Range` prefix.
     fn is_range_path(path: &Path) -> bool {
-        let segs: Vec<_> = path.segments.iter().map(|seg| seg.ident.as_str().to_string()).collect();
+        let segs: Vec<_> = path.segments.iter().map(|seg| seg.ident.to_string()).collect();
         let segs: Vec<_> = segs.iter().map(|seg| &**seg).collect();
 
         // "{{root}}" is the equivalent of `::` prefix in `Path`.
@@ -3423,7 +3423,7 @@ pub fn is_range_literal(sess: &Session, expr: &hir::Expr) -> bool {
         ExprKind::Call(ref func, _) => {
             if let ExprKind::Path(QPath::TypeRelative(ref ty, ref segment)) = func.kind {
                 if let TyKind::Path(QPath::Resolved(None, ref path)) = ty.kind {
-                    let new_call = segment.ident.as_str() == "new";
+                    let new_call = segment.ident.name == sym::new;
                     return is_range_path(&path) && is_lit(sess, &expr.span) && new_call;
                 }
             }
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 64b355f6ec9..328d475be06 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -564,7 +564,7 @@ impl<'a> State<'a> {
             }
             hir::ItemKind::GlobalAsm(ref ga) => {
                 self.head(visibility_qualified(&item.vis, "global asm"));
-                self.s.word(ga.asm.as_str().to_string());
+                self.s.word(ga.asm.to_string());
                 self.end()
             }
             hir::ItemKind::TyAlias(ref ty, ref generics) => {
@@ -1855,7 +1855,7 @@ impl<'a> State<'a> {
         self.commasep(Inconsistent, &decl.inputs, |s, ty| {
             s.ibox(INDENT_UNIT);
             if let Some(arg_name) = arg_names.get(i) {
-                s.s.word(arg_name.as_str().to_string());
+                s.s.word(arg_name.to_string());
                 s.s.word(":");
                 s.s.space();
             } else if let Some(body_id) = body_id {
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 4fd4e25f641..304735fb1c7 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -9,7 +9,7 @@ use std::mem;
 use syntax::ast;
 use syntax::feature_gate;
 use syntax::parse::token;
-use syntax::symbol::LocalInternedString;
+use syntax::symbol::SymbolStr;
 use syntax::tokenstream;
 use syntax_pos::SourceFile;
 
@@ -18,7 +18,7 @@ use crate::hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};
 use smallvec::SmallVec;
 use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHasher};
 
-impl<'a> HashStable<StableHashingContext<'a>> for LocalInternedString {
+impl<'a> HashStable<StableHashingContext<'a>> for SymbolStr {
     #[inline]
     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
         let str = self as &str;
@@ -26,13 +26,13 @@ impl<'a> HashStable<StableHashingContext<'a>> for LocalInternedString {
     }
 }
 
-impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalInternedString {
-    type KeyType = LocalInternedString;
+impl<'a> ToStableHashKey<StableHashingContext<'a>> for SymbolStr {
+    type KeyType = SymbolStr;
 
     #[inline]
     fn to_stable_hash_key(&self,
                           _: &StableHashingContext<'a>)
-                          -> LocalInternedString {
+                          -> SymbolStr {
         self.clone()
     }
 }
@@ -45,12 +45,12 @@ impl<'a> HashStable<StableHashingContext<'a>> for ast::Name {
 }
 
 impl<'a> ToStableHashKey<StableHashingContext<'a>> for ast::Name {
-    type KeyType = LocalInternedString;
+    type KeyType = SymbolStr;
 
     #[inline]
     fn to_stable_hash_key(&self,
                           _: &StableHashingContext<'a>)
-                          -> LocalInternedString {
+                          -> SymbolStr {
         self.as_str()
     }
 }
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 5c871bb6b69..65777fe78db 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -7,7 +7,7 @@
 use crate::lint::{LintPass, LateLintPass, LintArray, FutureIncompatibleInfo};
 use crate::middle::stability;
 use crate::session::Session;
-use errors::{Applicability, DiagnosticBuilder, pluralise};
+use errors::{Applicability, DiagnosticBuilder, pluralize};
 use syntax::ast;
 use syntax::edition::Edition;
 use syntax::source_map::Span;
@@ -651,7 +651,7 @@ pub(crate) fn add_elided_lifetime_in_path_suggestion(
     };
     db.span_suggestion(
         replace_span,
-        &format!("indicate the anonymous lifetime{}", pluralise!(n)),
+        &format!("indicate the anonymous lifetime{}", pluralize!(n)),
         suggestion,
         Applicability::MachineApplicable
     );
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index a122d84a5aa..488d6332f7e 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -17,7 +17,7 @@ use crate::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
 use crate::rustc::lint;
 use crate::session::Session;
 use crate::util::nodemap::{DefIdMap, FxHashMap, FxHashSet, HirIdMap, HirIdSet};
-use errors::{Applicability, DiagnosticBuilder, pluralise};
+use errors::{Applicability, DiagnosticBuilder, pluralize};
 use rustc_macros::HashStable;
 use std::borrow::Cow;
 use std::cell::Cell;
@@ -3044,7 +3044,7 @@ pub fn report_missing_lifetime_specifiers(
         span,
         E0106,
         "missing lifetime specifier{}",
-        pluralise!(count)
+        pluralize!(count)
     )
 }
 
diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs
index 58f99667cb3..a54635c3d51 100644
--- a/src/librustc/mir/mono.rs
+++ b/src/librustc/mir/mono.rs
@@ -486,7 +486,7 @@ impl CodegenUnitNameBuilder<'tcx> {
         if self.tcx.sess.opts.debugging_opts.human_readable_cgu_names {
             cgu_name
         } else {
-            let cgu_name = &cgu_name.as_str()[..];
+            let cgu_name = &cgu_name.as_str();
             Symbol::intern(&CodegenUnit::mangle_name(cgu_name))
         }
     }
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 888d84d69fa..fe18a14d890 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -33,7 +33,7 @@ use crate::ty::subst::Subst;
 use crate::ty::SubtypePredicate;
 use crate::util::nodemap::{FxHashMap, FxHashSet};
 
-use errors::{Applicability, DiagnosticBuilder, pluralise};
+use errors::{Applicability, DiagnosticBuilder, pluralize};
 use std::fmt;
 use syntax::ast;
 use syntax::symbol::{sym, kw};
@@ -1130,7 +1130,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     let restrict_msg = "consider further restricting this bound";
                     let param_name = self_ty.to_string();
                     for param in generics.params.iter().filter(|p| {
-                        &param_name == std::convert::AsRef::<str>::as_ref(&p.name.ident().as_str())
+                        p.name.ident().as_str() == param_name
                     }) {
                         if param_name.starts_with("impl ") {
                             // `impl Trait` in argument:
@@ -1553,7 +1553,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 _ => format!("{} {}argument{}",
                              arg_length,
                              if distinct && arg_length > 1 { "distinct " } else { "" },
-                             pluralise!(arg_length))
+                             pluralize!(arg_length))
             }
         };
 
diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs
index b39c00a56e3..b64e44b6a5a 100644
--- a/src/librustc/traits/on_unimplemented.rs
+++ b/src/librustc/traits/on_unimplemented.rs
@@ -180,7 +180,7 @@ impl<'tcx> OnUnimplementedDirective {
                     c.ident().map_or(false, |ident| {
                         options.contains(&(
                             ident.name,
-                            c.value_str().map(|s| s.as_str().to_string())
+                            c.value_str().map(|s| s.to_string())
                         ))
                     })
                 }) {
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index 0639a70ed0c..723ed6b03da 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -4,7 +4,7 @@ use std::borrow::Cow;
 use std::fmt;
 use rustc_target::spec::abi;
 use syntax::ast;
-use syntax::errors::pluralise;
+use syntax::errors::pluralize;
 use errors::{Applicability, DiagnosticBuilder};
 use syntax_pos::Span;
 
@@ -100,17 +100,17 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
                 write!(f, "expected a tuple with {} element{}, \
                            found one with {} element{}",
                        values.expected,
-                       pluralise!(values.expected),
+                       pluralize!(values.expected),
                        values.found,
-                       pluralise!(values.found))
+                       pluralize!(values.found))
             }
             FixedArraySize(values) => {
                 write!(f, "expected an array with a fixed size of {} element{}, \
                            found one with {} element{}",
                        values.expected,
-                       pluralise!(values.expected),
+                       pluralize!(values.expected),
                        values.found,
-                       pluralise!(values.found))
+                       pluralize!(values.found))
             }
             ArgCount => {
                 write!(f, "incorrect number of function parameters")
@@ -165,7 +165,7 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
             ProjectionBoundsLength(ref values) => {
                 write!(f, "expected {} associated type binding{}, found {}",
                        values.expected,
-                       pluralise!(values.expected),
+                       pluralize!(values.expected),
                        values.found)
             },
             ExistentialMismatch(ref values) => {
@@ -196,7 +196,7 @@ impl<'tcx> ty::TyS<'tcx> {
                 let n = tcx.lift(&n).unwrap();
                 match n.try_eval_usize(tcx, ty::ParamEnv::empty()) {
                     Some(n) => {
-                        format!("array of {} element{}", n, pluralise!(n)).into()
+                        format!("array of {} element{}", n, pluralize!(n)).into()
                     }
                     None => "array".into(),
                 }
diff --git a/src/librustc/ty/inhabitedness/def_id_forest.rs b/src/librustc/ty/inhabitedness/def_id_forest.rs
index 63cc60d80aa..227fbf967c0 100644
--- a/src/librustc/ty/inhabitedness/def_id_forest.rs
+++ b/src/librustc/ty/inhabitedness/def_id_forest.rs
@@ -76,19 +76,19 @@ impl<'tcx> DefIdForest {
                 break;
             }
 
-            for id in ret.root_ids.drain() {
+            for id in ret.root_ids.drain(..) {
                 if next_forest.contains(tcx, id) {
                     next_ret.push(id);
                 } else {
                     old_ret.push(id);
                 }
             }
-            ret.root_ids.extend(old_ret.drain());
+            ret.root_ids.extend(old_ret.drain(..));
 
             next_ret.extend(next_forest.root_ids.into_iter().filter(|&id| ret.contains(tcx, id)));
 
             mem::swap(&mut next_ret, &mut ret.root_ids);
-            next_ret.drain();
+            next_ret.drain(..);
         }
         ret
     }
@@ -101,7 +101,7 @@ impl<'tcx> DefIdForest {
         let mut ret = DefIdForest::empty();
         let mut next_ret = SmallVec::new();
         for next_forest in iter {
-            next_ret.extend(ret.root_ids.drain().filter(|&id| !next_forest.contains(tcx, id)));
+            next_ret.extend(ret.root_ids.drain(..).filter(|&id| !next_forest.contains(tcx, id)));
 
             for id in next_forest.root_ids {
                 if !next_ret.contains(&id) {
@@ -110,7 +110,7 @@ impl<'tcx> DefIdForest {
             }
 
             mem::swap(&mut next_ret, &mut ret.root_ids);
-            next_ret.drain();
+            next_ret.drain(..);
         }
         ret
     }
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index 4dabea01c9e..4031eb62194 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -264,7 +264,7 @@ impl<'sess> OnDiskCache<'sess> {
             let sorted_cnums = sorted_cnums_including_local_crate(tcx);
             let prev_cnums: Vec<_> = sorted_cnums.iter()
                 .map(|&cnum| {
-                    let crate_name = tcx.original_crate_name(cnum).as_str().to_string();
+                    let crate_name = tcx.original_crate_name(cnum).to_string();
                     let crate_disambiguator = tcx.crate_disambiguator(cnum);
                     (cnum.as_u32(), crate_name, crate_disambiguator)
                 })
diff --git a/src/librustc_apfloat/Cargo.toml b/src/librustc_apfloat/Cargo.toml
index 4fc15f99e48..726965e1e71 100644
--- a/src/librustc_apfloat/Cargo.toml
+++ b/src/librustc_apfloat/Cargo.toml
@@ -10,4 +10,4 @@ path = "lib.rs"
 
 [dependencies]
 bitflags = "1.2.1"
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs
index 6a36a4a50cb..6f4e7d0f0ca 100644
--- a/src/librustc_codegen_llvm/attributes.rs
+++ b/src/librustc_codegen_llvm/attributes.rs
@@ -314,7 +314,7 @@ pub fn from_fn_attrs(
             codegen_fn_attrs.target_features
                 .iter()
                 .map(|f| {
-                    let feature = &*f.as_str();
+                    let feature = &f.as_str();
                     format!("+{}", llvm_util::to_llvm_feature(cx.tcx.sess, feature))
                 })
         )
diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs
index 2da93877172..4a40349cb73 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/src/librustc_codegen_llvm/context.rs
@@ -203,6 +203,10 @@ pub unsafe fn create_module(
     let llvm_target = SmallCStr::new(&sess.target.target.llvm_target);
     llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
 
+    if get_reloc_model(sess) == llvm::RelocMode::PIC {
+        llvm::LLVMRustSetModulePICLevel(llmod);
+    }
+
     if is_pie_binary(sess) {
         llvm::LLVMRustSetModulePIELevel(llmod);
     }
diff --git a/src/librustc_codegen_llvm/debuginfo/namespace.rs b/src/librustc_codegen_llvm/debuginfo/namespace.rs
index 628d1372b57..482bcf2aa58 100644
--- a/src/librustc_codegen_llvm/debuginfo/namespace.rs
+++ b/src/librustc_codegen_llvm/debuginfo/namespace.rs
@@ -34,11 +34,11 @@ pub fn item_namespace(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope {
     });
 
     let namespace_name = match def_key.disambiguated_data.data {
-        DefPathData::CrateRoot => cx.tcx.crate_name(def_id.krate).as_str(),
-        data => data.as_symbol().as_str()
+        DefPathData::CrateRoot => cx.tcx.crate_name(def_id.krate),
+        data => data.as_symbol()
     };
 
-    let namespace_name = SmallCStr::new(&namespace_name);
+    let namespace_name = SmallCStr::new(&namespace_name.as_str());
 
     let scope = unsafe {
         llvm::LLVMRustDIBuilderCreateNameSpace(
diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index 4dad6ff793c..548e8c732a7 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -1807,6 +1807,7 @@ extern "C" {
 
     pub fn LLVMRustSetComdat(M: &'a Module, V: &'a Value, Name: *const c_char);
     pub fn LLVMRustUnsetComdat(V: &Value);
+    pub fn LLVMRustSetModulePICLevel(M: &Module);
     pub fn LLVMRustSetModulePIELevel(M: &Module);
     pub fn LLVMRustModuleBufferCreate(M: &Module) -> &'static mut ModuleBuffer;
     pub fn LLVMRustModuleBufferPtr(p: &ModuleBuffer) -> *const u8;
diff --git a/src/librustc_codegen_ssa/back/command.rs b/src/librustc_codegen_ssa/back/command.rs
index 2d84d67e3c8..b8501f0e12a 100644
--- a/src/librustc_codegen_ssa/back/command.rs
+++ b/src/librustc_codegen_ssa/back/command.rs
@@ -53,7 +53,7 @@ impl Command {
     }
 
     pub fn sym_arg(&mut self, arg: Symbol) -> &mut Command {
-        self.arg(&arg.as_str());
+        self.arg(&*arg.as_str());
         self
     }
 
diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs
index 85a90459f5e..35b62603b07 100644
--- a/src/librustc_codegen_ssa/back/symbol_export.rs
+++ b/src/librustc_codegen_ssa/back/symbol_export.rs
@@ -129,9 +129,9 @@ fn reachable_non_generics_provider(
                 //
                 // In general though we won't link right if these
                 // symbols are stripped, and LTO currently strips them.
-                if &*name == "rust_eh_personality" ||
-                   &*name == "rust_eh_register_frames" ||
-                   &*name == "rust_eh_unregister_frames" {
+                if name == "rust_eh_personality" ||
+                   name == "rust_eh_register_frames" ||
+                   name == "rust_eh_unregister_frames" {
                     SymbolExportLevel::C
                 } else {
                     SymbolExportLevel::Rust
diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs
index ee4ec7fb41e..c3f2a5161ae 100644
--- a/src/librustc_codegen_ssa/base.rs
+++ b/src/librustc_codegen_ssa/base.rs
@@ -552,8 +552,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
     } else if let Some(kind) = *tcx.sess.allocator_kind.get() {
         let llmod_id = cgu_name_builder.build_cgu_name(LOCAL_CRATE,
                                                        &["crate"],
-                                                       Some("allocator")).as_str()
-                                                                         .to_string();
+                                                       Some("allocator")).to_string();
         let mut modules = backend.new_metadata(tcx, &llmod_id);
         time(tcx.sess, "write allocator module", || {
             backend.codegen_allocator(tcx, &mut modules, kind)
@@ -576,8 +575,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
         // Codegen the encoded metadata.
         let metadata_cgu_name = cgu_name_builder.build_cgu_name(LOCAL_CRATE,
                                                                 &["crate"],
-                                                                Some("metadata")).as_str()
-                                                                                 .to_string();
+                                                                Some("metadata")).to_string();
         let mut metadata_llvm_module = backend.new_metadata(tcx, &metadata_cgu_name);
         time(tcx.sess, "write compressed metadata", || {
             backend.write_compressed_metadata(tcx, &ongoing_codegen.metadata,
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index 07e904300a6..13cd202158b 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -995,7 +995,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         bx: &mut Bx,
         span: Span,
     ) -> OperandRef<'tcx, Bx::Value> {
-        let caller = bx.tcx().sess.source_map().lookup_char_pos(span.lo());
+        let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
+        let caller = bx.tcx().sess.source_map().lookup_char_pos(topmost.lo());
         let const_loc = bx.tcx().const_caller_location((
             Symbol::intern(&caller.file.name.to_string()),
             caller.line as u32,
diff --git a/src/librustc_codegen_utils/symbol_names/legacy.rs b/src/librustc_codegen_utils/symbol_names/legacy.rs
index 601a33a66bb..66e1b6d949e 100644
--- a/src/librustc_codegen_utils/symbol_names/legacy.rs
+++ b/src/librustc_codegen_utils/symbol_names/legacy.rs
@@ -121,9 +121,10 @@ fn get_symbol_hash<'tcx>(
         substs.hash_stable(&mut hcx, &mut hasher);
 
         if let Some(instantiating_crate) = instantiating_crate {
-            (&tcx.original_crate_name(instantiating_crate).as_str()[..])
+            tcx.original_crate_name(instantiating_crate).as_str()
+                .hash_stable(&mut hcx, &mut hasher);
+            tcx.crate_disambiguator(instantiating_crate)
                 .hash_stable(&mut hcx, &mut hasher);
-            (&tcx.crate_disambiguator(instantiating_crate)).hash_stable(&mut hcx, &mut hasher);
         }
 
         // We want to avoid accidental collision between different types of instances.
diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml
index 065c8436ae0..e79b3a81b96 100644
--- a/src/librustc_data_structures/Cargo.toml
+++ b/src/librustc_data_structures/Cargo.toml
@@ -23,7 +23,7 @@ stable_deref_trait = "1.0.0"
 rayon = { version = "0.3.0", package = "rustc-rayon" }
 rayon-core = { version = "0.3.0", package = "rustc-rayon-core" }
 rustc-hash = "1.0.1"
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 rustc_index = { path = "../librustc_index", package = "rustc_index" }
 
 [dependencies.parking_lot]
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 5f74df13fae..291920f17f6 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -12,7 +12,7 @@ use Destination::*;
 use syntax_pos::{SourceFile, Span, MultiSpan};
 
 use crate::{
-    Level, CodeSuggestion, Diagnostic, SubDiagnostic, pluralise,
+    Level, CodeSuggestion, Diagnostic, SubDiagnostic, pluralize,
     SuggestionStyle, SourceMapper, SourceMapperDyn, DiagnosticId,
 };
 use crate::Level::Error;
@@ -1581,7 +1581,7 @@ impl EmitterWriter {
         }
         if suggestions.len() > MAX_SUGGESTIONS {
             let others = suggestions.len() - MAX_SUGGESTIONS;
-            let msg = format!("and {} other candidate{}", others, pluralise!(others));
+            let msg = format!("and {} other candidate{}", others, pluralize!(others));
             buffer.puts(row_num, max_line_num_len + 3, &msg, Style::NoStyle);
         } else if notice_capitalization {
             let msg = "notice the capitalization difference";
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 9743cf0d805..67c180a05e9 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -1027,7 +1027,7 @@ impl Level {
 }
 
 #[macro_export]
-macro_rules! pluralise {
+macro_rules! pluralize {
     ($x:expr) => {
         if $x != 1 { "s" } else { "" }
     };
diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs
index ca035d0cdcb..483b515f2ba 100644
--- a/src/librustc_incremental/assert_module_sources.rs
+++ b/src/librustc_incremental/assert_module_sources.rs
@@ -31,10 +31,6 @@ use syntax::symbol::{Symbol, sym};
 use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_CODEGENED,
                  ATTR_EXPECTED_CGU_REUSE};
 
-const MODULE: Symbol = sym::module;
-const CFG: Symbol = sym::cfg;
-const KIND: Symbol = sym::kind;
-
 pub fn assert_module_sources(tcx: TyCtxt<'_>) {
     tcx.dep_graph.with_ignore(|| {
         if tcx.sess.opts.incremental.is_none() {
@@ -71,7 +67,7 @@ impl AssertModuleSource<'tcx> {
         } else if attr.check_name(ATTR_PARTITION_CODEGENED) {
             (CguReuse::No, ComparisonKind::Exact)
         } else if attr.check_name(ATTR_EXPECTED_CGU_REUSE) {
-            match &self.field(attr, KIND).as_str()[..] {
+            match &*self.field(attr, sym::kind).as_str() {
                 "no" => (CguReuse::No, ComparisonKind::Exact),
                 "pre-lto" => (CguReuse::PreLto, ComparisonKind::Exact),
                 "post-lto" => (CguReuse::PostLto, ComparisonKind::Exact),
@@ -98,8 +94,8 @@ impl AssertModuleSource<'tcx> {
             return;
         }
 
-        let user_path = self.field(attr, MODULE).as_str().to_string();
-        let crate_name = self.tcx.crate_name(LOCAL_CRATE).as_str().to_string();
+        let user_path = self.field(attr, sym::module).to_string();
+        let crate_name = self.tcx.crate_name(LOCAL_CRATE).to_string();
 
         if !user_path.starts_with(&crate_name) {
             let msg = format!("Found malformed codegen unit name `{}`. \
@@ -125,7 +121,7 @@ impl AssertModuleSource<'tcx> {
                                                        cgu_path_components,
                                                        cgu_special_suffix);
 
-        debug!("mapping '{}' to cgu name '{}'", self.field(attr, MODULE), cgu_name);
+        debug!("mapping '{}' to cgu name '{}'", self.field(attr, sym::module), cgu_name);
 
         if !self.available_cgus.contains(&cgu_name) {
             self.tcx.sess.span_err(attr.span,
@@ -135,7 +131,7 @@ impl AssertModuleSource<'tcx> {
                     cgu_name,
                     self.available_cgus
                         .iter()
-                        .map(|cgu| cgu.as_str().to_string())
+                        .map(|cgu| cgu.to_string())
                         .collect::<Vec<_>>()
                         .join(", ")));
         }
@@ -169,7 +165,7 @@ impl AssertModuleSource<'tcx> {
     /// cfg flag called `foo`.
     fn check_config(&self, attr: &ast::Attribute) -> bool {
         let config = &self.tcx.sess.parse_sess.config;
-        let value = self.field(attr, CFG);
+        let value = self.field(attr, sym::cfg);
         debug!("check_config(config={:?}, value={:?})", config, value);
         if config.iter().any(|&(name, _)| name == value) {
             debug!("check_config: matched");
diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs
index abe0ffb0e02..ea156a94ea1 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -303,7 +303,7 @@ impl DirtyCleanVisitor<'tcx> {
         for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
             if item.check_name(LABEL) {
                 let value = expect_associated_value(self.tcx, &item);
-                return Some(self.resolve_labels(&item, value.as_str().as_ref()));
+                return Some(self.resolve_labels(&item, &value.as_str()));
             }
         }
         None
@@ -314,7 +314,7 @@ impl DirtyCleanVisitor<'tcx> {
         for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
             if item.check_name(EXCEPT) {
                 let value = expect_associated_value(self.tcx, &item);
-                return self.resolve_labels(&item, value.as_str().as_ref());
+                return self.resolve_labels(&item, &value.as_str());
             }
         }
         // if no `label` or `except` is given, only the node's group are asserted
diff --git a/src/librustc_index/Cargo.toml b/src/librustc_index/Cargo.toml
index b1ebc95e488..1435297f27a 100644
--- a/src/librustc_index/Cargo.toml
+++ b/src/librustc_index/Cargo.toml
@@ -11,4 +11,4 @@ doctest = false
 
 [dependencies]
 rustc_serialize = { path = "../libserialize", package = "serialize" }
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml
index 0d8d765a572..98e4f974a9f 100644
--- a/src/librustc_interface/Cargo.toml
+++ b/src/librustc_interface/Cargo.toml
@@ -12,7 +12,7 @@ doctest = false
 [dependencies]
 log = "0.4"
 rayon = { version = "0.3.0", package = "rustc-rayon" }
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 syntax = { path = "../libsyntax" }
 syntax_ext = { path = "../libsyntax_ext" }
 syntax_expand = { path = "../libsyntax_expand" }
diff --git a/src/librustc_lexer/src/cursor.rs b/src/librustc_lexer/src/cursor.rs
index 73d305c6d4f..ed0911379c4 100644
--- a/src/librustc_lexer/src/cursor.rs
+++ b/src/librustc_lexer/src/cursor.rs
@@ -41,10 +41,20 @@ impl<'a> Cursor<'a> {
     /// If requested position doesn't exist, `EOF_CHAR` is returned.
     /// However, getting `EOF_CHAR` doesn't always mean actual end of file,
     /// it should be checked with `is_eof` method.
-    pub(crate) fn nth_char(&self, n: usize) -> char {
+    fn nth_char(&self, n: usize) -> char {
         self.chars().nth(n).unwrap_or(EOF_CHAR)
     }
 
+    /// Peeks the next symbol from the input stream without consuming it.
+    pub(crate) fn first(&self) -> char {
+        self.nth_char(0)
+    }
+
+    /// Peeks the second symbol from the input stream without consuming it.
+    pub(crate) fn second(&self) -> char {
+        self.nth_char(1)
+    }
+
     /// Checks if there is nothing more to consume.
     pub(crate) fn is_eof(&self) -> bool {
         self.chars.as_str().is_empty()
diff --git a/src/librustc_lexer/src/lib.rs b/src/librustc_lexer/src/lib.rs
index d55ef46d750..c50808adec1 100644
--- a/src/librustc_lexer/src/lib.rs
+++ b/src/librustc_lexer/src/lib.rs
@@ -18,6 +18,8 @@ mod cursor;
 pub mod unescape;
 
 use crate::cursor::{Cursor, EOF_CHAR};
+use self::TokenKind::*;
+use self::LiteralKind::*;
 
 /// Parsed token.
 /// It doesn't contain information about data that has been parsed,
@@ -116,7 +118,6 @@ pub enum TokenKind {
     /// Unknown token, not expected by the lexer, e.g. "â„–"
     Unknown,
 }
-use self::TokenKind::*;
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
 pub enum LiteralKind {
@@ -137,7 +138,6 @@ pub enum LiteralKind {
     /// "br"abc"", "br#"abc"#", "br####"ab"###"c"####", "br#"a"
     RawByteStr { n_hashes: usize, started: bool, terminated: bool },
 }
-use self::LiteralKind::*;
 
 /// Base of numeric literal encoding according to its prefix.
 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
@@ -241,14 +241,13 @@ pub fn is_id_continue(c: char) -> bool {
         || (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_continue(c))
 }
 
-
 impl Cursor<'_> {
     /// Parses a token from the input string.
     fn advance_token(&mut self) -> Token {
         let first_char = self.bump().unwrap();
         let token_kind = match first_char {
             // Slash, comment or block comment.
-            '/' => match self.nth_char(0) {
+            '/' => match self.first() {
                 '/' => self.line_comment(),
                 '*' => self.block_comment(),
                 _ => Slash,
@@ -257,8 +256,8 @@ impl Cursor<'_> {
             // Whitespace sequence.
             c if is_whitespace(c) => self.whitespace(),
 
-            // Raw string literal or identifier.
-            'r' => match (self.nth_char(0), self.nth_char(1)) {
+            // Raw identifier, raw string literal or identifier.
+            'r' => match (self.first(), self.second()) {
                 ('#', c1) if is_id_start(c1) => self.raw_ident(),
                 ('#', _) | ('"', _) => {
                     let (n_hashes, started, terminated) = self.raw_double_quoted_string();
@@ -273,7 +272,7 @@ impl Cursor<'_> {
             },
 
             // Byte literal, byte string literal, raw byte string literal or identifier.
-            'b' => match (self.nth_char(0), self.nth_char(1)) {
+            'b' => match (self.first(), self.second()) {
                 ('\'', _) => {
                     self.bump();
                     let terminated = self.single_quoted_string();
@@ -366,31 +365,23 @@ impl Cursor<'_> {
     }
 
     fn line_comment(&mut self) -> TokenKind {
-        debug_assert!(self.prev() == '/' && self.nth_char(0) == '/');
+        debug_assert!(self.prev() == '/' && self.first() == '/');
         self.bump();
-        loop {
-            match self.nth_char(0) {
-                '\n' => break,
-                EOF_CHAR if self.is_eof() => break,
-                _ => {
-                    self.bump();
-                }
-            }
-        }
+        self.eat_while(|c| c != '\n');
         LineComment
     }
 
     fn block_comment(&mut self) -> TokenKind {
-        debug_assert!(self.prev() == '/' && self.nth_char(0) == '*');
+        debug_assert!(self.prev() == '/' && self.first() == '*');
         self.bump();
         let mut depth = 1usize;
         while let Some(c) = self.bump() {
             match c {
-                '/' if self.nth_char(0) == '*' => {
+                '/' if self.first() == '*' => {
                     self.bump();
                     depth += 1;
                 }
-                '*' if self.nth_char(0) == '/' => {
+                '*' if self.first() == '/' => {
                     self.bump();
                     depth -= 1;
                     if depth == 0 {
@@ -409,31 +400,27 @@ impl Cursor<'_> {
 
     fn whitespace(&mut self) -> TokenKind {
         debug_assert!(is_whitespace(self.prev()));
-        while is_whitespace(self.nth_char(0)) {
-            self.bump();
-        }
+        self.eat_while(is_whitespace);
         Whitespace
     }
 
     fn raw_ident(&mut self) -> TokenKind {
         debug_assert!(
             self.prev() == 'r'
-                && self.nth_char(0) == '#'
-                && is_id_start(self.nth_char(1))
+                && self.first() == '#'
+                && is_id_start(self.second())
         );
+        // Eat "#" symbol.
         self.bump();
-        self.bump();
-        while is_id_continue(self.nth_char(0)) {
-            self.bump();
-        }
+        // Eat the identifier part of RawIdent.
+        self.eat_identifier();
         RawIdent
     }
 
     fn ident(&mut self) -> TokenKind {
         debug_assert!(is_id_start(self.prev()));
-        while is_id_continue(self.nth_char(0)) {
-            self.bump();
-        }
+        // Start is already eaten, eat the rest of identifier.
+        self.eat_while(is_id_continue);
         Ident
     }
 
@@ -442,7 +429,7 @@ impl Cursor<'_> {
         let mut base = Base::Decimal;
         if first_digit == '0' {
             // Attempt to parse encoding base.
-            let has_digits = match self.nth_char(0) {
+            let has_digits = match self.first() {
                 'b' => {
                     base = Base::Binary;
                     self.bump();
@@ -476,23 +463,23 @@ impl Cursor<'_> {
             self.eat_decimal_digits();
         };
 
-        match self.nth_char(0) {
+        match self.first() {
             // Don't be greedy if this is actually an
             // integer literal followed by field/method access or a range pattern
             // (`0..2` and `12.foo()`)
-            '.' if self.nth_char(1) != '.'
-                && !is_id_start(self.nth_char(1)) =>
+            '.' if self.second() != '.'
+                && !is_id_start(self.second()) =>
             {
                 // might have stuff after the ., and if it does, it needs to start
                 // with a number
                 self.bump();
                 let mut empty_exponent = false;
-                if self.nth_char(0).is_digit(10) {
+                if self.first().is_digit(10) {
                     self.eat_decimal_digits();
-                    match self.nth_char(0) {
+                    match self.first() {
                         'e' | 'E' => {
                             self.bump();
-                            empty_exponent = self.float_exponent().is_err()
+                            empty_exponent = !self.eat_float_exponent();
                         }
                         _ => (),
                     }
@@ -501,7 +488,7 @@ impl Cursor<'_> {
             }
             'e' | 'E' => {
                 self.bump();
-                let empty_exponent = self.float_exponent().is_err();
+                let empty_exponent = !self.eat_float_exponent();
                 Float { base, empty_exponent }
             }
             _ => Int { base, empty_int: false },
@@ -510,65 +497,76 @@ impl Cursor<'_> {
 
     fn lifetime_or_char(&mut self) -> TokenKind {
         debug_assert!(self.prev() == '\'');
-        let mut starts_with_number = false;
-
-        // Check if the first symbol after '\'' is a valid identifier
-        // character or a number (not a digit followed by '\'').
-        if (is_id_start(self.nth_char(0))
-            || self.nth_char(0).is_digit(10) && {
-                starts_with_number = true;
-                true
-            })
-            && self.nth_char(1) != '\''
-        {
-            self.bump();
 
-            // Skip the identifier.
-            while is_id_continue(self.nth_char(0)) {
-                self.bump();
-            }
+        let can_be_a_lifetime = if self.second() == '\'' {
+            // It's surely not a lifetime.
+            false
+        } else {
+            // If the first symbol is valid for identifier, it can be a lifetime.
+            // Also check if it's a number for a better error reporting (so '0 will
+            // be reported as invalid lifetime and not as unterminated char literal).
+            is_id_start(self.first()) || self.first().is_digit(10)
+        };
 
-            return if self.nth_char(0) == '\'' {
-                self.bump();
-                let kind = Char { terminated: true };
-                Literal { kind, suffix_start: self.len_consumed() }
-            } else {
-                Lifetime { starts_with_number }
-            };
+        if !can_be_a_lifetime {
+            let terminated = self.single_quoted_string();
+            let suffix_start = self.len_consumed();
+            if terminated {
+                self.eat_literal_suffix();
+            }
+            let kind = Char { terminated };
+            return Literal { kind, suffix_start };
         }
 
-        // This is not a lifetime (checked above), parse a char literal.
-        let terminated = self.single_quoted_string();
-        let suffix_start = self.len_consumed();
-        if terminated {
-            self.eat_literal_suffix();
+        // Either a lifetime or a character literal with
+        // length greater than 1.
+
+        let starts_with_number = self.first().is_digit(10);
+
+        // Skip the literal contents.
+        // First symbol can be a number (which isn't a valid identifier start),
+        // so skip it without any checks.
+        self.bump();
+        self.eat_while(is_id_continue);
+
+        // Check if after skipping literal contents we've met a closing
+        // single quote (which means that user attempted to create a
+        // string with single quotes).
+        if self.first() == '\'' {
+            self.bump();
+            let kind = Char { terminated: true };
+            return Literal { kind, suffix_start: self.len_consumed() };
         }
-        let kind = Char { terminated };
-        return Literal { kind, suffix_start };
+
+        return Lifetime { starts_with_number };
     }
 
     fn single_quoted_string(&mut self) -> bool {
         debug_assert!(self.prev() == '\'');
-        // Parse `'''` as a single char literal.
-        if self.nth_char(0) == '\'' && self.nth_char(1) == '\'' {
+        // Check if it's a one-symbol literal.
+        if self.second() == '\'' && self.first() != '\\' {
+            self.bump();
             self.bump();
+            return true;
         }
+
+        // Literal has more than one symbol.
+
         // Parse until either quotes are terminated or error is detected.
-        let mut first = true;
         loop {
-            match self.nth_char(0) {
-                // Probably beginning of the comment, which we don't want to include
-                // to the error report.
-                '/' if !first => break,
-                // Newline without following '\'' means unclosed quote, stop parsing.
-                '\n' if self.nth_char(1) != '\'' => break,
-                // End of file, stop parsing.
-                EOF_CHAR if self.is_eof() => break,
+            match self.first() {
                 // Quotes are terminated, finish parsing.
                 '\'' => {
                     self.bump();
                     return true;
                 }
+                // Probably beginning of the comment, which we don't want to include
+                // to the error report.
+                '/' => break,
+                // Newline without following '\'' means unclosed quote, stop parsing.
+                '\n' if self.second() != '\'' => break,
+                // End of file, stop parsing.
+                EOF_CHAR if self.is_eof() => break,
                 // Escaped slash is considered one character, so bump twice.
                 '\\' => {
                     self.bump();
@@ -579,8 +577,8 @@ impl Cursor<'_> {
                     self.bump();
                 }
             }
-            first = false;
         }
+        // String was not terminated.
         false
     }
 
@@ -588,62 +586,71 @@ impl Cursor<'_> {
     /// if string is terminated.
     fn double_quoted_string(&mut self) -> bool {
         debug_assert!(self.prev() == '"');
-        loop {
-            match self.nth_char(0) {
+        while let Some(c) = self.bump() {
+            match c {
                 '"' => {
-                    self.bump();
                     return true;
                 }
-                EOF_CHAR if self.is_eof() => return false,
-                '\\' if self.nth_char(1) == '\\' || self.nth_char(1) == '"' => {
+                '\\' if self.first() == '\\' || self.first() == '"' => {
+                    // Bump again to skip escaped character.
                     self.bump();
                 }
                 _ => (),
             }
-            self.bump();
         }
+        // End of file reached.
+        false
     }
 
     /// Eats the double-quoted string and returns a tuple of
     /// (amount of the '#' symbols, raw string started, raw string terminated)
     fn raw_double_quoted_string(&mut self) -> (usize, bool, bool) {
         debug_assert!(self.prev() == 'r');
+        let mut started: bool = false;
+        let mut finished: bool = false;
+
         // Count opening '#' symbols.
-        let n_hashes = {
-            let mut acc: usize = 0;
-            loop {
-                match self.bump() {
-                    Some('#') => acc += 1,
-                    Some('"') => break acc,
-                    None | Some(_) => return (acc, false, false),
-                }
+        let n_hashes = self.eat_while(|c| c == '#');
+
+        // Check that string is started.
+        match self.bump() {
+            Some('"') => started = true,
+            _ => return (n_hashes, started, finished),
+        }
+
+        // Skip the string contents and on each '#' character met, check if this is
+        // a raw string termination.
+        while !finished {
+            self.eat_while(|c| c != '"');
+
+            if self.is_eof() {
+                return (n_hashes, started, finished);
             }
-        };
 
-        // Skip the string itself and check that amount of closing '#'
-        // symbols is equal to the amount of opening ones.
-        loop {
-            match self.bump() {
-                Some('"') => {
-                    let mut acc = n_hashes;
-                    while self.nth_char(0) == '#' && acc > 0 {
-                        self.bump();
-                        acc -= 1;
-                    }
-                    if acc == 0 {
-                        return (n_hashes, true, true);
-                    }
+            // Eat closing double quote.
+            self.bump();
+
+            // Check that amount of closing '#' symbols
+            // is equal to the amount of opening ones.
+            let mut hashes_left = n_hashes;
+            let is_closing_hash = |c| {
+                if c == '#' && hashes_left != 0 {
+                    hashes_left -= 1;
+                    true
+                } else {
+                    false
                 }
-                Some(_) => (),
-                None => return (n_hashes, true, false),
-            }
+            };
+            finished = self.eat_while(is_closing_hash) == n_hashes;
         }
+
+        (n_hashes, started, finished)
     }
 
     fn eat_decimal_digits(&mut self) -> bool {
         let mut has_digits = false;
         loop {
-            match self.nth_char(0) {
+            match self.first() {
                 '_' => {
                     self.bump();
                 }
@@ -660,7 +667,7 @@ impl Cursor<'_> {
     fn eat_hexadecimal_digits(&mut self) -> bool {
         let mut has_digits = false;
         loop {
-            match self.nth_char(0) {
+            match self.first() {
                 '_' => {
                     self.bump();
                 }
@@ -674,23 +681,43 @@ impl Cursor<'_> {
         has_digits
     }
 
-    fn float_exponent(&mut self) -> Result<(), ()> {
+    /// Eats the float exponent. Returns true if at least one digit was met,
+    /// and returns false otherwise.
+    fn eat_float_exponent(&mut self) -> bool {
         debug_assert!(self.prev() == 'e' || self.prev() == 'E');
-        if self.nth_char(0) == '-' || self.nth_char(0) == '+' {
+        if self.first() == '-' || self.first() == '+' {
             self.bump();
         }
-        if self.eat_decimal_digits() { Ok(()) } else { Err(()) }
+        self.eat_decimal_digits()
     }
 
-    // Eats the suffix if it's an identifier.
+    // Eats the suffix of the literal, e.g. "_u8".
     fn eat_literal_suffix(&mut self) {
-        if !is_id_start(self.nth_char(0)) {
+        self.eat_identifier();
+    }
+
+    // Eats the identifier.
+    fn eat_identifier(&mut self) {
+        if !is_id_start(self.first()) {
             return;
         }
         self.bump();
 
-        while is_id_continue(self.nth_char(0)) {
+        self.eat_while(is_id_continue);
+    }
+
+    /// Eats symbols while predicate returns true or until the end of file is reached.
+    /// Returns amount of eaten symbols.
+    fn eat_while<F>(&mut self, mut predicate: F) -> usize
+    where
+        F: FnMut(char) -> bool
+    {
+        let mut eaten: usize = 0;
+        while predicate(self.first()) && !self.is_eof() {
+            eaten += 1;
             self.bump();
         }
+
+        eaten
     }
 }
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index e3c3966c2f5..30d68fd0bfc 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -1476,14 +1476,12 @@ impl KeywordIdents {
         let mut lint = cx.struct_span_lint(
             KEYWORD_IDENTS,
             ident.span,
-            &format!("`{}` is a keyword in the {} edition",
-                     ident.as_str(),
-                     next_edition),
+            &format!("`{}` is a keyword in the {} edition", ident, next_edition),
         );
         lint.span_suggestion(
             ident.span,
             "you can use a raw identifier to stay compatible",
-            format!("r#{}", ident.as_str()),
+            format!("r#{}", ident),
             Applicability::MachineApplicable,
         );
         lint.emit()
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 3f85e6d772e..642b8e3279d 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -10,7 +10,7 @@ use lint::{LintPass, EarlyLintPass, LateLintPass};
 
 use syntax::ast;
 use syntax::attr;
-use syntax::errors::{Applicability, pluralise};
+use syntax::errors::{Applicability, pluralize};
 use syntax::feature_gate::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
 use syntax::print::pprust;
 use syntax::symbol::{kw, sym};
@@ -144,7 +144,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
                 return true;
             }
 
-            let plural_suffix = pluralise!(plural_len);
+            let plural_suffix = pluralize!(plural_len);
 
             match ty.kind {
                 ty::Adt(..) if ty.is_box() => {
diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml
index 18192e35f8a..5bc047e001b 100644
--- a/src/librustc_metadata/Cargo.toml
+++ b/src/librustc_metadata/Cargo.toml
@@ -13,7 +13,7 @@ doctest = false
 flate2 = "1.0"
 log = "0.4"
 memmap = "0.6"
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 rustc = { path = "../librustc" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 errors = { path = "../librustc_errors", package = "rustc_errors" }
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index 07c49d91797..483b1a40e44 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -121,7 +121,7 @@ impl<'a> CrateLoader<'a> {
             // `source` stores paths which are normalized which may be different
             // from the strings on the command line.
             let source = &self.cstore.get_crate_data(cnum).source;
-            if let Some(entry) = self.sess.opts.externs.get(&*name.as_str()) {
+            if let Some(entry) = self.sess.opts.externs.get(&name.as_str()) {
                 // Only use `--extern crate_name=path` here, not `--extern crate_name`.
                 let found = entry.locations.iter().filter_map(|l| l.as_ref()).any(|l| {
                     let l = fs::canonicalize(l).ok();
diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs
index a58db6a903b..c9de66a5c87 100644
--- a/src/librustc_metadata/native_libs.rs
+++ b/src/librustc_metadata/native_libs.rs
@@ -68,7 +68,7 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> {
                         Some(name) => name,
                         None => continue, // skip like historical compilers
                     };
-                    lib.kind = match &kind.as_str()[..] {
+                    lib.kind = match &*kind.as_str() {
                         "static" => cstore::NativeStatic,
                         "static-nobundle" => cstore::NativeStaticNobundle,
                         "dylib" => cstore::NativeUnknown,
diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml
index f0cdcf2136b..8c62640353a 100644
--- a/src/librustc_mir/Cargo.toml
+++ b/src/librustc_mir/Cargo.toml
@@ -26,4 +26,4 @@ rustc_serialize = { path = "../libserialize", package = "serialize" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
 rustc_apfloat = { path = "../librustc_apfloat" }
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs
index 36db68a3372..0913d743328 100644
--- a/src/librustc_mir/borrow_check/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/conflict_errors.rs
@@ -974,7 +974,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         let mut err = self.cannot_borrow_across_destructor(borrow_span);
 
         let what_was_dropped = match self.describe_place(place.as_ref()) {
-            Some(name) => format!("`{}`", name.as_str()),
+            Some(name) => format!("`{}`", name),
             None => String::from("temporary value"),
         };
 
diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index 9d370554e86..29423536e65 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -548,7 +548,7 @@ fn joined_uncovered_patterns(witnesses: &[super::Pat<'_>]) -> String {
 }
 
 fn pattern_not_covered_label(witnesses: &[super::Pat<'_>], joined_patterns: &str) -> String {
-    format!("pattern{} {} not covered", rustc_errors::pluralise!(witnesses.len()), joined_patterns)
+    format!("pattern{} {} not covered", rustc_errors::pluralize!(witnesses.len()), joined_patterns)
 }
 
 /// Point at the definition of non-covered `enum` variants.
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs
index 04032847385..1b5cc2f0948 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/src/librustc_mir/interpret/intrinsics.rs
@@ -95,10 +95,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     ) -> InterpResult<'tcx, bool> {
         let substs = instance.substs;
 
-        let intrinsic_name = &self.tcx.item_name(instance.def_id()).as_str()[..];
+        let intrinsic_name = &*self.tcx.item_name(instance.def_id()).as_str();
         match intrinsic_name {
             "caller_location" => {
-                let caller = self.tcx.sess.source_map().lookup_char_pos(span.lo());
+                let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
+                let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo());
                 let location = self.alloc_caller_location(
                     Symbol::intern(&caller.file.name.to_string()),
                     caller.line as u32,
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index d9b983ab790..7d550716858 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -642,8 +642,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: DefId) {
                 struct_span_err!(
                     tcx.sess, source_info.span, E0133,
                     "{} is unsafe and requires unsafe function or block", description)
-                    .span_label(source_info.span, &description.as_str()[..])
-                    .note(&details.as_str()[..])
+                    .span_label(source_info.span, &*description.as_str())
+                    .note(&details.as_str())
                     .emit();
             }
             UnsafetyViolationKind::ExternStatic(lint_hir_id) => {
@@ -651,8 +651,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: DefId) {
                               lint_hir_id,
                               source_info.span,
                               &format!("{} is unsafe and requires unsafe function or block \
-                                        (error E0133)", &description.as_str()[..]),
-                              &details.as_str()[..]);
+                                        (error E0133)", description),
+                              &details.as_str());
             }
             UnsafetyViolationKind::BorrowPacked(lint_hir_id) => {
                 if let Some(impl_def_id) = builtin_derive_def_id(tcx, def_id) {
@@ -662,8 +662,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: DefId) {
                                   lint_hir_id,
                                   source_info.span,
                                   &format!("{} is unsafe and requires unsafe function or block \
-                                            (error E0133)", &description.as_str()[..]),
-                                  &details.as_str()[..]);
+                                            (error E0133)", description),
+                                  &details.as_str());
                 }
             }
         }
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 5463b944473..76899dad41a 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -537,7 +537,7 @@ impl Qualif for IsNotPromotable {
                     Abi::RustIntrinsic |
                     Abi::PlatformIntrinsic => {
                         assert!(!cx.tcx.is_const_fn(def_id));
-                        match &cx.tcx.item_name(def_id).as_str()[..] {
+                        match &*cx.tcx.item_name(def_id).as_str() {
                             | "size_of"
                             | "min_align_of"
                             | "needs_drop"
@@ -1477,7 +1477,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                         Abi::RustIntrinsic |
                         Abi::PlatformIntrinsic => {
                             assert!(!self.tcx.is_const_fn(def_id));
-                            match &self.tcx.item_name(def_id).as_str()[..] {
+                            match &*self.tcx.item_name(def_id).as_str() {
                                 // special intrinsic that can be called diretly without an intrinsic
                                 // feature gate needs a language feature gate
                                 "transmute" => {
diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs
index c4e44091bc9..da1fba2518a 100644
--- a/src/librustc_mir/transform/qualify_min_const_fn.rs
+++ b/src/librustc_mir/transform/qualify_min_const_fn.rs
@@ -402,7 +402,7 @@ fn check_terminator(
 ///
 /// Adding more intrinsics requires sign-off from @rust-lang/lang.
 fn is_intrinsic_whitelisted(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
-    match &tcx.item_name(def_id).as_str()[..] {
+    match &*tcx.item_name(def_id).as_str() {
         | "size_of"
         | "min_align_of"
         | "needs_drop"
diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml
index 08ce7fd520e..33b2bd36b7d 100644
--- a/src/librustc_resolve/Cargo.toml
+++ b/src/librustc_resolve/Cargo.toml
@@ -21,4 +21,4 @@ errors = { path = "../librustc_errors", package = "rustc_errors" }
 syntax_pos = { path = "../libsyntax_pos" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_metadata = { path = "../librustc_metadata" }
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs
index 44b7a9fa047..0624b5eedfb 100644
--- a/src/librustc_resolve/check_unused.rs
+++ b/src/librustc_resolve/check_unused.rs
@@ -26,7 +26,7 @@
 use crate::Resolver;
 use crate::resolve_imports::ImportDirectiveSubclass;
 
-use errors::pluralise;
+use errors::pluralize;
 
 use rustc::util::nodemap::NodeMap;
 use rustc::{lint, ty};
@@ -297,7 +297,7 @@ impl Resolver<'_> {
                 }).collect::<Vec<String>>();
             span_snippets.sort();
             let msg = format!("unused import{}{}",
-                            pluralise!(len),
+                            pluralize!(len),
                             if !span_snippets.is_empty() {
                                 format!(": {}", span_snippets.join(", "))
                             } else {
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 004d86cee8d..58af4b817d2 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -1876,7 +1876,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                                     None
                                 }
                             });
-                            find_best_match_for_name(names, &*ident.as_str(), None)
+                            find_best_match_for_name(names, &ident.as_str(), None)
                         });
                         self.r.record_partial_res(expr.id, PartialRes::new(Res::Err));
                         self.r.report_error(
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index c39f0c90f98..c06be18dc2c 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -11,7 +11,7 @@ use crate::{Resolver, ResolutionError, BindingKey, Segment, ModuleKind};
 use crate::{names_to_string, module_to_string};
 use crate::diagnostics::Suggestion;
 
-use errors::{Applicability, pluralise};
+use errors::{Applicability, pluralize};
 
 use rustc_data_structures::ptr_key::PtrKey;
 use rustc::ty;
@@ -730,7 +730,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
 
             let msg = format!(
                 "unresolved import{} {}",
-                pluralise!(paths.len()),
+                pluralize!(paths.len()),
                 paths.join(", "),
             );
 
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index e51772220b7..4cd2f13d09c 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -362,6 +362,7 @@ supported_targets! {
     ("armv7-unknown-linux-gnueabi", armv7_unknown_linux_gnueabi),
     ("armv7-unknown-linux-gnueabihf", armv7_unknown_linux_gnueabihf),
     ("thumbv7neon-unknown-linux-gnueabihf", thumbv7neon_unknown_linux_gnueabihf),
+    ("thumbv7neon-unknown-linux-musleabihf", thumbv7neon_unknown_linux_musleabihf),
     ("armv7-unknown-linux-musleabi", armv7_unknown_linux_musleabi),
     ("armv7-unknown-linux-musleabihf", armv7_unknown_linux_musleabihf),
     ("aarch64-unknown-linux-gnu", aarch64_unknown_linux_gnu),
diff --git a/src/librustc_target/spec/thumbv7neon_unknown_linux_musleabihf.rs b/src/librustc_target/spec/thumbv7neon_unknown_linux_musleabihf.rs
new file mode 100644
index 00000000000..1270f391731
--- /dev/null
+++ b/src/librustc_target/spec/thumbv7neon_unknown_linux_musleabihf.rs
@@ -0,0 +1,37 @@
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+
+// This target is for musl Linux on ARMv7 with thumb mode enabled
+// (for consistency with Android and Debian-based distributions)
+// and with NEON unconditionally enabled and, therefore, with 32 FPU
+// registers enabled as well. See section A2.6.2 on page A2-56 in
+// https://static.docs.arm.com/ddi0406/cd/DDI0406C_d_armv7ar_arm.pdf
+
+pub fn target() -> TargetResult {
+    let base = super::linux_musl_base::opts();
+    Ok(Target {
+        // It's important we use "gnueabihf" and not "musleabihf" here. LLVM
+        // uses it to determine the calling convention and float ABI, and LLVM
+        // doesn't support the "musleabihf" value.
+        llvm_target: "armv7-unknown-linux-gnueabihf".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "32".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
+        arch: "arm".to_string(),
+        target_os: "linux".to_string(),
+        target_env: "musl".to_string(),
+        target_vendor: "unknown".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+
+        // Most of these settings are copied from the thumbv7neon_unknown_linux_gnueabihf
+        // target.
+        options: TargetOptions {
+            features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".to_string(),
+            cpu: "generic".to_string(),
+            max_atomic_width: Some(64),
+            abi_blacklist: super::arm_base::abi_blacklist(),
+            target_mcount: "\u{1}mcount".to_string(),
+            .. base
+        }
+    })
+}
diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml
index b86a3a5e963..a9b184a7b30 100644
--- a/src/librustc_traits/Cargo.toml
+++ b/src/librustc_traits/Cargo.toml
@@ -16,4 +16,4 @@ rustc_target = { path = "../librustc_target" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
 chalk-engine = { version = "0.9.0", default-features=false }
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml
index a6644258be2..60a7a2f4598 100644
--- a/src/librustc_typeck/Cargo.toml
+++ b/src/librustc_typeck/Cargo.toml
@@ -17,7 +17,7 @@ rustc = { path = "../librustc" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 errors = { path = "../librustc_errors", package = "rustc_errors" }
 rustc_target = { path = "../librustc_target" }
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
 rustc_index = { path = "../librustc_index" }
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index b14121da79f..5c661513382 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -23,7 +23,7 @@ use rustc_target::spec::abi;
 use crate::require_c_abi_if_c_variadic;
 use smallvec::SmallVec;
 use syntax::ast;
-use syntax::errors::pluralise;
+use syntax::errors::pluralize;
 use syntax::feature_gate::{GateIssue, emit_feature_err};
 use syntax::util::lev_distance::find_best_match_for_name;
 use syntax::symbol::sym;
@@ -392,7 +392,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     quantifier,
                     bound,
                     kind,
-                    pluralise!(bound),
+                    pluralize!(bound),
                 ))
             };
 
@@ -1360,7 +1360,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 span,
                 E0191,
                 "the value of the associated type{} {} must be specified",
-                pluralise!(associated_types.len()),
+                pluralize!(associated_types.len()),
                 names,
             );
             let (suggest, potential_assoc_types_spans) =
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 6818d5f521d..af0943db4cc 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -10,7 +10,7 @@ use rustc::util::common::ErrorReported;
 use errors::{Applicability, DiagnosticId};
 
 use syntax_pos::Span;
-use syntax::errors::pluralise;
+use syntax::errors::pluralize;
 
 use super::{Inherited, FnCtxt, potentially_plural_count};
 
@@ -649,9 +649,9 @@ fn compare_number_of_generics<'tcx>(
                      declaration has {} {kind} parameter{}",
                     trait_.ident,
                     impl_count,
-                    pluralise!(impl_count),
+                    pluralize!(impl_count),
                     trait_count,
-                    pluralise!(trait_count),
+                    pluralize!(trait_count),
                     kind = kind,
                 ),
                 DiagnosticId::Error("E0049".into()),
@@ -666,7 +666,7 @@ fn compare_number_of_generics<'tcx>(
                         "expected {} {} parameter{}",
                         trait_count,
                         kind,
-                        pluralise!(trait_count),
+                        pluralize!(trait_count),
                     ));
                 }
                 for span in spans {
@@ -681,7 +681,7 @@ fn compare_number_of_generics<'tcx>(
                     "found {} {} parameter{}{}",
                     impl_count,
                     kind,
-                    pluralise!(impl_count),
+                    pluralize!(impl_count),
                     suffix.unwrap_or_else(|| String::new()),
                 ));
             }
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index af892bf8179..309e73f57c9 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -308,7 +308,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }) = parent {
                 if let Ok(src) = cm.span_to_snippet(sp) {
                     for field in fields {
-                        if field.ident.as_str() == src.as_str() && field.is_shorthand {
+                        if field.ident.as_str() == src && field.is_shorthand {
                             return true;
                         }
                     }
@@ -409,13 +409,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     let mut sugg_sp = sp;
                     if let hir::ExprKind::MethodCall(segment, _sp, args) = &expr.kind {
                         let clone_trait = self.tcx.lang_items().clone_trait().unwrap();
-                        if let ([arg], Some(true), "clone") = (
+                        if let ([arg], Some(true), sym::clone) = (
                             &args[..],
                             self.tables.borrow().type_dependent_def_id(expr.hir_id).map(|did| {
                                 let ai = self.tcx.associated_item(did);
                                 ai.container == ty::TraitContainer(clone_trait)
                             }),
-                            &segment.ident.as_str()[..],
+                            segment.ident.name,
                         ) {
                             // If this expression had a clone call when suggesting borrowing
                             // we want to suggest removing it because it'd now be unecessary.
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 81e4bb6f2ad..35870abbaef 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -17,7 +17,7 @@ use crate::util::common::ErrorReported;
 use crate::util::nodemap::FxHashMap;
 use crate::astconv::AstConv as _;
 
-use errors::{Applicability, DiagnosticBuilder, pluralise};
+use errors::{Applicability, DiagnosticBuilder, pluralize};
 use syntax_pos::hygiene::DesugaringKind;
 use syntax::ast;
 use syntax::symbol::{Symbol, kw, sym};
@@ -1218,7 +1218,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             struct_span_err!(tcx.sess, span, E0063,
                              "missing field{} {}{} in initializer of `{}`",
-                             pluralise!(remaining_fields.len()),
+                             pluralize!(remaining_fields.len()),
                              remaining_fields_names,
                              truncated_fields_error,
                              adt_ty)
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index d90ed2a790b..0b1657c4494 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -5,7 +5,7 @@ use crate::check::FnCtxt;
 use crate::middle::lang_items::FnOnceTraitLangItem;
 use crate::namespace::Namespace;
 use crate::util::nodemap::FxHashSet;
-use errors::{Applicability, DiagnosticBuilder, pluralise};
+use errors::{Applicability, DiagnosticBuilder, pluralize};
 use rustc::hir::{self, ExprKind, Node, QPath};
 use rustc::hir::def::{Res, DefKind};
 use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
@@ -601,7 +601,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         "{an}other candidate{s} {were} found in the following trait{s}, perhaps \
                          add a `use` for {one_of_them}:",
                         an = if candidates.len() == 1 {"an" } else { "" },
-                        s = pluralise!(candidates.len()),
+                        s = pluralize!(candidates.len()),
                         were = if candidates.len() == 1 { "was" } else { "were" },
                         one_of_them = if candidates.len() == 1 {
                             "it"
@@ -835,11 +835,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                     sp,
                                     &message(format!(
                                         "restrict type parameter `{}` with",
-                                        param.name.ident().as_str(),
+                                        param.name.ident(),
                                     )),
                                     candidates.iter().map(|t| format!(
                                         "{}{} {}{}",
-                                        param.name.ident().as_str(),
+                                        param.name.ident(),
                                         if impl_trait { " +" } else { ":" },
                                         self.tcx.def_path_str(t.def_id),
                                         if has_bounds.is_some() { " + "} else { "" },
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index fcafb0e88da..26f04081046 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -88,7 +88,7 @@ pub mod intrinsic;
 mod op;
 
 use crate::astconv::{AstConv, PathSeg};
-use errors::{Applicability, DiagnosticBuilder, DiagnosticId, pluralise};
+use errors::{Applicability, DiagnosticBuilder, DiagnosticId, pluralize};
 use rustc::hir::{self, ExprKind, GenericArg, ItemKind, Node, PatKind, QPath};
 use rustc::hir::def::{CtorOf, Res, DefKind};
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
@@ -5162,5 +5162,5 @@ fn fatally_break_rust(sess: &Session) {
 }
 
 fn potentially_plural_count(count: usize, word: &str) -> String {
-    format!("{} {}{}", count, word, pluralise!(count))
+    format!("{} {}{}", count, word, pluralize!(count))
 }
diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 950ae7c1d62..a520ae13c58 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -1,6 +1,6 @@
 use crate::check::FnCtxt;
 use crate::util::nodemap::FxHashMap;
-use errors::{Applicability, DiagnosticBuilder, pluralise};
+use errors::{Applicability, DiagnosticBuilder, pluralize};
 use rustc::hir::{self, PatKind, Pat, HirId};
 use rustc::hir::def::{Res, DefKind, CtorKind};
 use rustc::hir::pat_util::EnumerateAndAdjustIterator;
@@ -703,8 +703,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         fields: &[ty::FieldDef],
         expected: Ty<'tcx>
     ) {
-        let subpats_ending = pluralise!(subpats.len());
-        let fields_ending = pluralise!(fields.len());
+        let subpats_ending = pluralize!(subpats.len());
+        let fields_ending = pluralize!(fields.len());
         let res_span = self.tcx.def_span(res.def_id());
         let mut err = struct_span_err!(
             self.tcx.sess,
@@ -978,7 +978,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     );
 
                     // we don't want to throw `E0027` in case we have thrown `E0026` for them
-                    unmentioned_fields.retain(|&x| x.as_str() != suggested_name.as_str());
+                    unmentioned_fields.retain(|&x| x.name != suggested_name);
                 }
             }
         }
@@ -1174,10 +1174,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             E0527,
             "pattern requires {} element{} but array has {}",
             min_len,
-            pluralise!(min_len),
+            pluralize!(min_len),
             size,
         )
-        .span_label(span, format!("expected {} element{}", size, pluralise!(size)))
+        .span_label(span, format!("expected {} element{}", size, pluralize!(size)))
         .emit();
     }
 
@@ -1188,14 +1188,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             E0528,
             "pattern requires at least {} element{} but array has {}",
             min_len,
-            pluralise!(min_len),
+            pluralize!(min_len),
             size,
         ).span_label(
             span,
             format!(
                 "pattern cannot match array of {} element{}",
                 size,
-                pluralise!(size),
+                pluralize!(size),
             ),
         ).emit();
     }
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 7ef842cb757..ffe034759a8 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -2408,7 +2408,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
     abi: abi::Abi,
 ) -> ty::PolyFnSig<'tcx> {
     let unsafety = if abi == abi::Abi::RustIntrinsic {
-        intrinsic_operation_unsafety(&*tcx.item_name(def_id).as_str())
+        intrinsic_operation_unsafety(&tcx.item_name(def_id).as_str())
     } else {
         hir::Unsafety::Unsafe
     };
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index 11f45c5f6d0..09f4873967e 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -404,7 +404,7 @@ impl<'a> fmt::Display for Html<'a> {
                 if !human_readable.is_empty() {
                     fmt.write_str(human_readable)
                 } else if let Some(v) = value {
-                    write!(fmt, "<code>{}=\"{}\"</code>", Escape(n), Escape(&*v.as_str()))
+                    write!(fmt, "<code>{}=\"{}\"</code>", Escape(n), Escape(&v.as_str()))
                 } else {
                     write!(fmt, "<code>{}</code>", Escape(n))
                 }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index bdc02062230..e7f76155252 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1167,7 +1167,7 @@ fn external_path(cx: &DocContext<'_>, name: Symbol, trait_did: Option<DefId>, ha
         global: false,
         res: Res::Err,
         segments: vec![PathSegment {
-            name: name.as_str().to_string(),
+            name: name.to_string(),
             args: external_generic_args(cx, trait_did, has_self, bindings, substs)
         }],
     }
@@ -3704,7 +3704,7 @@ fn qpath_to_string(p: &hir::QPath) -> String {
             s.push_str("::");
         }
         if seg.ident.name != kw::PathRoot {
-            s.push_str(&*seg.ident.as_str());
+            s.push_str(&seg.ident.as_str());
         }
     }
     s
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index c4ee84d33f3..29f0b99d8ee 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -2964,7 +2964,7 @@ fn render_attribute(attr: &ast::MetaItem) -> Option<String> {
     if attr.is_word() {
         Some(path)
     } else if let Some(v) = attr.value_str() {
-        Some(format!("{} = {:?}", path, v.as_str()))
+        Some(format!("{} = {:?}", path, v))
     } else if let Some(values) = attr.meta_item_list() {
         let display: Vec<_> = values.iter().filter_map(|attr| {
             attr.meta_item().and_then(|mi| render_attribute(mi))
diff --git a/src/libserialize/Cargo.toml b/src/libserialize/Cargo.toml
index c302bcf95dc..96a0d51bc71 100644
--- a/src/libserialize/Cargo.toml
+++ b/src/libserialize/Cargo.toml
@@ -10,4 +10,4 @@ path = "lib.rs"
 
 [dependencies]
 indexmap = "1"
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/libstd/sys/unix/rand.rs b/src/libstd/sys/unix/rand.rs
index be112f6fc03..bc387544c4c 100644
--- a/src/libstd/sys/unix/rand.rs
+++ b/src/libstd/sys/unix/rand.rs
@@ -15,6 +15,7 @@ pub fn hashmap_random_keys() -> (u64, u64) {
           not(target_os = "ios"),
           not(target_os = "openbsd"),
           not(target_os = "freebsd"),
+          not(target_os = "netbsd"),
           not(target_os = "fuchsia"),
           not(target_os = "redox")))]
 mod imp {
@@ -142,7 +143,7 @@ mod imp {
     }
 }
 
-#[cfg(target_os = "freebsd")]
+#[cfg(any(target_os = "freebsd", target_os = "netbsd"))]
 mod imp {
     use crate::ptr;
 
diff --git a/src/libsyntax/Cargo.toml b/src/libsyntax/Cargo.toml
index 3ce47e6a7b8..b1839cc05cd 100644
--- a/src/libsyntax/Cargo.toml
+++ b/src/libsyntax/Cargo.toml
@@ -21,4 +21,4 @@ rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_index = { path = "../librustc_index" }
 rustc_lexer = { path = "../librustc_lexer" }
 rustc_target = { path = "../librustc_target" }
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 8b967048848..8af38507b48 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -90,7 +90,7 @@ impl fmt::Debug for Lifetime {
 
 impl fmt::Display for Lifetime {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}", self.ident.name.as_str())
+        write!(f, "{}", self.ident.name)
     }
 }
 
diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
index 13a24ca046d..d9cc5f6c169 100644
--- a/src/libsyntax/feature_gate/check.rs
+++ b/src/libsyntax/feature_gate/check.rs
@@ -823,7 +823,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
             }
 
             if let Some(allowed) = allow_features.as_ref() {
-                if allowed.iter().find(|&f| f == &name.as_str() as &str).is_none() {
+                if allowed.iter().find(|&f| name.as_str() == *f).is_none() {
                     span_err!(span_handler, mi.span(), E0725,
                               "the feature `{}` is not in the list of allowed features",
                               name);
diff --git a/src/libsyntax/parse/literal.rs b/src/libsyntax/parse/literal.rs
index 7952e293a53..c42f4aa25cc 100644
--- a/src/libsyntax/parse/literal.rs
+++ b/src/libsyntax/parse/literal.rs
@@ -134,9 +134,9 @@ impl LitKind {
         let (kind, symbol, suffix) = match *self {
             LitKind::Str(symbol, ast::StrStyle::Cooked) => {
                 // Don't re-intern unless the escaped string is different.
-                let s: &str = &symbol.as_str();
+                let s = symbol.as_str();
                 let escaped = s.escape_default().to_string();
-                let symbol = if escaped == *s { symbol } else { Symbol::intern(&escaped) };
+                let symbol = if s == escaped { symbol } else { Symbol::intern(&escaped) };
                 (token::Str, symbol, None)
             }
             LitKind::Str(symbol, ast::StrStyle::Raw(n)) => {
diff --git a/src/libsyntax/parse/parser/diagnostics.rs b/src/libsyntax/parse/parser/diagnostics.rs
index 453ef5963be..49a517a5c44 100644
--- a/src/libsyntax/parse/parser/diagnostics.rs
+++ b/src/libsyntax/parse/parser/diagnostics.rs
@@ -12,7 +12,7 @@ use crate::ptr::P;
 use crate::symbol::{kw, sym};
 use crate::ThinVec;
 use crate::util::parser::AssocOp;
-use errors::{Applicability, DiagnosticBuilder, DiagnosticId, pluralise};
+use errors::{Applicability, DiagnosticBuilder, DiagnosticId, pluralize};
 use rustc_data_structures::fx::FxHashSet;
 use syntax_pos::{Span, DUMMY_SP, MultiSpan, SpanSnippetError};
 use log::{debug, trace};
@@ -515,11 +515,11 @@ impl<'a> Parser<'a> {
             self.diagnostic()
                 .struct_span_err(
                     span,
-                    &format!("unmatched angle bracket{}", pluralise!(total_num_of_gt)),
+                    &format!("unmatched angle bracket{}", pluralize!(total_num_of_gt)),
                 )
                 .span_suggestion(
                     span,
-                    &format!("remove extra angle bracket{}", pluralise!(total_num_of_gt)),
+                    &format!("remove extra angle bracket{}", pluralize!(total_num_of_gt)),
                     String::new(),
                     Applicability::MachineApplicable,
                 )
diff --git a/src/libsyntax/parse/parser/module.rs b/src/libsyntax/parse/parser/module.rs
index a0e4d2bbb7a..242a17659a0 100644
--- a/src/libsyntax/parse/parser/module.rs
+++ b/src/libsyntax/parse/parser/module.rs
@@ -210,7 +210,7 @@ impl<'a> Parser<'a> {
             // `/` to `\`.
             #[cfg(windows)]
             let s = s.replace("/", "\\");
-            Some(dir_path.join(s))
+            Some(dir_path.join(&*s))
         } else {
             None
         }
@@ -229,7 +229,7 @@ impl<'a> Parser<'a> {
         // `./<id>.rs` and `./<id>/mod.rs`.
         let relative_prefix_string;
         let relative_prefix = if let Some(ident) = relative {
-            relative_prefix_string = format!("{}{}", ident.as_str(), path::MAIN_SEPARATOR);
+            relative_prefix_string = format!("{}{}", ident, path::MAIN_SEPARATOR);
             &relative_prefix_string
         } else {
             ""
@@ -314,7 +314,7 @@ impl<'a> Parser<'a> {
 
     fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) {
         if let Some(path) = attr::first_attr_value_str_by_name(attrs, sym::path) {
-            self.directory.path.to_mut().push(&path.as_str());
+            self.directory.path.to_mut().push(&*path.as_str());
             self.directory.ownership = DirectoryOwnership::Owned { relative: None };
         } else {
             // We have to push on the current module name in the case of relative
@@ -325,10 +325,10 @@ impl<'a> Parser<'a> {
             // directory path to `/x/y/z`, not `/x/z` with a relative offset of `y`.
             if let DirectoryOwnership::Owned { relative } = &mut self.directory.ownership {
                 if let Some(ident) = relative.take() { // remove the relative offset
-                    self.directory.path.to_mut().push(ident.as_str());
+                    self.directory.path.to_mut().push(&*ident.as_str());
                 }
             }
-            self.directory.path.to_mut().push(&id.as_str());
+            self.directory.path.to_mut().push(&*id.as_str());
         }
     }
 }
diff --git a/src/libsyntax/parse/parser/path.rs b/src/libsyntax/parse/parser/path.rs
index 38a28224dab..f9944e36e2f 100644
--- a/src/libsyntax/parse/parser/path.rs
+++ b/src/libsyntax/parse/parser/path.rs
@@ -9,7 +9,7 @@ use crate::symbol::kw;
 
 use std::mem;
 use log::debug;
-use errors::{Applicability, pluralise};
+use errors::{Applicability, pluralize};
 
 /// Specifies how to parse a path.
 #[derive(Copy, Clone, PartialEq)]
@@ -368,14 +368,14 @@ impl<'a> Parser<'a> {
                         span,
                         &format!(
                             "unmatched angle bracket{}",
-                            pluralise!(snapshot.unmatched_angle_bracket_count)
+                            pluralize!(snapshot.unmatched_angle_bracket_count)
                         ),
                     )
                     .span_suggestion(
                         span,
                         &format!(
                             "remove extra angle bracket{}",
-                            pluralise!(snapshot.unmatched_angle_bracket_count)
+                            pluralize!(snapshot.unmatched_angle_bracket_count)
                         ),
                         String::new(),
                         Applicability::MachineApplicable,
diff --git a/src/libsyntax/parse/parser/ty.rs b/src/libsyntax/parse/parser/ty.rs
index e8f718a2483..b770b90705c 100644
--- a/src/libsyntax/parse/parser/ty.rs
+++ b/src/libsyntax/parse/parser/ty.rs
@@ -10,7 +10,7 @@ use crate::parse::token::{self, Token};
 use crate::source_map::Span;
 use crate::symbol::{kw};
 
-use errors::{Applicability, pluralise};
+use errors::{Applicability, pluralize};
 
 /// Returns `true` if `IDENT t` can start a type -- `IDENT::a::b`, `IDENT<u8, u8>`,
 /// `IDENT<<u8 as Trait>::AssocTy>`.
@@ -412,7 +412,7 @@ impl<'a> Parser<'a> {
                 }
                 err.span_suggestion_hidden(
                     bound_list,
-                    &format!("remove the trait bound{}", pluralise!(negative_bounds_len)),
+                    &format!("remove the trait bound{}", pluralize!(negative_bounds_len)),
                     new_bound_list,
                     Applicability::MachineApplicable,
                 );
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 136fc355f89..74ab5c79019 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -623,7 +623,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
         }
         self.maybe_print_comment(attr.span.lo());
         if attr.is_sugared_doc {
-            self.word(attr.value_str().unwrap().as_str().to_string());
+            self.word(attr.value_str().unwrap().to_string());
             self.hardbreak()
         } else {
             match attr.style {
@@ -1234,7 +1234,7 @@ impl<'a> State<'a> {
             }
             ast::ItemKind::GlobalAsm(ref ga) => {
                 self.head(visibility_qualified(&item.vis, "global_asm!"));
-                self.s.word(ga.asm.as_str().to_string());
+                self.s.word(ga.asm.to_string());
                 self.end();
             }
             ast::ItemKind::TyAlias(ref ty, ref generics) => {
@@ -2335,7 +2335,7 @@ impl<'a> State<'a> {
     }
 
     crate fn print_name(&mut self, name: ast::Name) {
-        self.s.word(name.as_str().to_string());
+        self.s.word(name.to_string());
         self.ann.post(self, AnnNode::Name(&name))
     }
 
diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs
index 7e0582797c7..a51d208704a 100644
--- a/src/libsyntax/tokenstream.rs
+++ b/src/libsyntax/tokenstream.rs
@@ -243,7 +243,7 @@ impl TokenStream {
 
                 // Get the first stream. If it's `None`, create an empty
                 // stream.
-                let mut iter = streams.drain();
+                let mut iter = streams.drain(..);
                 let mut first_stream_lrc = iter.next().unwrap().0;
 
                 // Append the elements to the first stream, after reserving
diff --git a/src/libsyntax_expand/Cargo.toml b/src/libsyntax_expand/Cargo.toml
index f063753f599..d98b9457a62 100644
--- a/src/libsyntax_expand/Cargo.toml
+++ b/src/libsyntax_expand/Cargo.toml
@@ -22,5 +22,5 @@ rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_index = { path = "../librustc_index" }
 rustc_lexer = { path = "../librustc_lexer" }
 rustc_target = { path = "../librustc_target" }
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 syntax = { path = "../libsyntax" }
diff --git a/src/libsyntax_expand/base.rs b/src/libsyntax_expand/base.rs
index 6cc7b7da53b..d02251eb746 100644
--- a/src/libsyntax_expand/base.rs
+++ b/src/libsyntax_expand/base.rs
@@ -953,18 +953,7 @@ impl<'a> ExtCtxt<'a> {
     ///
     /// Stops backtracing at include! boundary.
     pub fn expansion_cause(&self) -> Option<Span> {
-        let mut expn_id = self.current_expansion.id;
-        let mut last_macro = None;
-        loop {
-            let expn_data = expn_id.expn_data();
-            // Stop going up the backtrace once include! is encountered
-            if expn_data.is_root() || expn_data.kind.descr() == sym::include {
-                break;
-            }
-            expn_id = expn_data.call_site.ctxt().outer_expn();
-            last_macro = Some(expn_data.call_site);
-        }
-        last_macro
+        self.current_expansion.id.expansion_cause()
     }
 
     pub fn struct_span_warn<S: Into<MultiSpan>>(&self,
diff --git a/src/libsyntax_expand/mbe/macro_rules.rs b/src/libsyntax_expand/mbe/macro_rules.rs
index bfdc4c52b5a..7a772b0d31d 100644
--- a/src/libsyntax_expand/mbe/macro_rules.rs
+++ b/src/libsyntax_expand/mbe/macro_rules.rs
@@ -225,7 +225,7 @@ fn generic_extension<'cx>(
                 };
                 let mut p = Parser::new(cx.parse_sess(), tts, Some(directory), true, false, None);
                 p.root_module_name =
-                    cx.current_expansion.module.mod_path.last().map(|id| id.as_str().to_string());
+                    cx.current_expansion.module.mod_path.last().map(|id| id.to_string());
                 p.last_type_ascription = cx.current_expansion.prior_type_ascription;
 
                 p.process_potential_macro_variable();
diff --git a/src/libsyntax_expand/mbe/transcribe.rs b/src/libsyntax_expand/mbe/transcribe.rs
index 94523bbf91b..6f060103ef4 100644
--- a/src/libsyntax_expand/mbe/transcribe.rs
+++ b/src/libsyntax_expand/mbe/transcribe.rs
@@ -9,7 +9,7 @@ use syntax::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint};
 
 use smallvec::{smallvec, SmallVec};
 
-use errors::pluralise;
+use errors::pluralize;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
 use syntax_pos::hygiene::{ExpnId, Transparency};
@@ -350,10 +350,10 @@ impl LockstepIterSize {
                         "meta-variable `{}` repeats {} time{}, but `{}` repeats {} time{}",
                         l_id,
                         l_len,
-                        pluralise!(l_len),
+                        pluralize!(l_len),
                         r_id,
                         r_len,
-                        pluralise!(r_len),
+                        pluralize!(r_len),
                     );
                     LockstepIterSize::Contradiction(msg)
                 }
diff --git a/src/libsyntax_ext/Cargo.toml b/src/libsyntax_ext/Cargo.toml
index 440873f3c2b..703d51e1c4c 100644
--- a/src/libsyntax_ext/Cargo.toml
+++ b/src/libsyntax_ext/Cargo.toml
@@ -15,7 +15,7 @@ fmt_macros = { path = "../libfmt_macros" }
 log = "0.4"
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_target = { path = "../librustc_target" }
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 syntax = { path = "../libsyntax" }
 syntax_expand = { path = "../libsyntax_expand" }
 syntax_pos = { path = "../libsyntax_pos" }
diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs
index 58fe56bd235..6fb48bf8173 100644
--- a/src/libsyntax_ext/env.rs
+++ b/src/libsyntax_ext/env.rs
@@ -21,7 +21,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
     };
 
     let sp = cx.with_def_site_ctxt(sp);
-    let e = match env::var(&*var.as_str()) {
+    let e = match env::var(&var.as_str()) {
         Err(..) => {
             let lt = cx.lifetime(sp, Ident::new(kw::StaticLifetime, sp));
             cx.expr_path(cx.path_all(sp,
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 3c7f80aa399..314c2eefd4c 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -5,7 +5,7 @@ use fmt_macros as parse;
 
 use errors::DiagnosticBuilder;
 use errors::Applicability;
-use errors::pluralise;
+use errors::pluralize;
 
 use syntax::ast;
 use syntax_expand::base::{self, *};
@@ -300,7 +300,7 @@ impl<'a, 'b> Context<'a, 'b> {
                 &format!(
                     "{} positional argument{} in format string, but {}",
                     count,
-                    pluralise!(count),
+                    pluralize!(count),
                     self.describe_num_args(),
                 ),
             );
@@ -994,7 +994,7 @@ pub fn expand_preparsed_format_args(
         vec![]
     };
 
-    let fmt_str = &*fmt_str.as_str();  // for the suggestions below
+    let fmt_str = &fmt_str.as_str();  // for the suggestions below
     let mut parser = parse::Parser::new(fmt_str, str_style, skips, append_newline);
 
     let mut unverified_pieces = Vec::new();
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index e28d9326757..2a48f8e44aa 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -28,7 +28,7 @@
 use crate::GLOBALS;
 use crate::{Span, DUMMY_SP};
 use crate::edition::Edition;
-use crate::symbol::{kw, Symbol};
+use crate::symbol::{kw, sym, Symbol};
 
 use rustc_serialize::{Encodable, Decodable, Encoder, Decoder};
 use rustc_data_structures::fx::FxHashMap;
@@ -119,6 +119,23 @@ impl ExpnId {
     pub fn outer_expn_is_descendant_of(self, ctxt: SyntaxContext) -> bool {
         HygieneData::with(|data| data.is_descendant_of(self, data.outer_expn(ctxt)))
     }
+
+    /// Returns span for the macro which originally caused this expansion to happen.
+    ///
+    /// Stops backtracing at include! boundary.
+    pub fn expansion_cause(mut self) -> Option<Span> {
+        let mut last_macro = None;
+        loop {
+            let expn_data = self.expn_data();
+            // Stop going up the backtrace once include! is encountered
+            if expn_data.is_root() || expn_data.kind.descr() == sym::include {
+                break;
+            }
+            self = expn_data.call_site.ctxt().outer_expn();
+            last_macro = Some(expn_data.call_site);
+        }
+        last_macro
+    }
 }
 
 #[derive(Debug)]
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 57131ffe18c..3f7b3e5b3d8 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -806,9 +806,9 @@ impl Ident {
         Ident::new(self.name, self.span.modern_and_legacy())
     }
 
-    /// Convert the name to a `LocalInternedString`. This is a slowish
-    /// operation because it requires locking the symbol interner.
-    pub fn as_str(self) -> LocalInternedString {
+    /// Convert the name to a `SymbolStr`. This is a slowish operation because
+    /// it requires locking the symbol interner.
+    pub fn as_str(self) -> SymbolStr {
         self.name.as_str()
     }
 }
@@ -896,11 +896,11 @@ impl Symbol {
         })
     }
 
-    /// Convert to a `LocalInternedString`. This is a slowish operation because
-    /// it requires locking the symbol interner.
-    pub fn as_str(self) -> LocalInternedString {
+    /// Convert to a `SymbolStr`. This is a slowish operation because it
+    /// requires locking the symbol interner.
+    pub fn as_str(self) -> SymbolStr {
         with_interner(|interner| unsafe {
-            LocalInternedString {
+            SymbolStr {
                 string: std::mem::transmute::<&str, &str>(interner.get(self))
             }
         })
@@ -973,6 +973,7 @@ impl Interner {
         self.names.insert(string, name);
         name
     }
+
     // Get the symbol as a string. `Symbol::as_str()` should be used in
     // preference to this function.
     pub fn get(&self, symbol: Symbol) -> &str {
@@ -1078,7 +1079,6 @@ impl Ident {
     }
 }
 
-// If an interner exists, return it. Otherwise, prepare a fresh one.
 #[inline]
 fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
     GLOBALS.with(|globals| f(&mut *globals.symbol_interner.lock()))
@@ -1092,46 +1092,42 @@ fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
 /// safely treat `string` which points to interner data, as an immortal string,
 /// as long as this type never crosses between threads.
 //
-// FIXME: ensure that the interner outlives any thread which uses
-// `LocalInternedString`, by creating a new thread right after constructing the
-// interner.
+// FIXME: ensure that the interner outlives any thread which uses `SymbolStr`,
+// by creating a new thread right after constructing the interner.
 #[derive(Clone, Eq, PartialOrd, Ord)]
-pub struct LocalInternedString {
+pub struct SymbolStr {
     string: &'static str,
 }
 
-impl<U: ?Sized> std::convert::AsRef<U> for LocalInternedString
-where
-    str: std::convert::AsRef<U>
-{
-    #[inline]
-    fn as_ref(&self) -> &U {
-        self.string.as_ref()
-    }
-}
-
-impl<T: std::ops::Deref<Target = str>> std::cmp::PartialEq<T> for LocalInternedString {
+// This impl allows a `SymbolStr` to be directly equated with a `String` or
+// `&str`.
+impl<T: std::ops::Deref<Target = str>> std::cmp::PartialEq<T> for SymbolStr {
     fn eq(&self, other: &T) -> bool {
         self.string == other.deref()
     }
 }
 
-impl !Send for LocalInternedString {}
-impl !Sync for LocalInternedString {}
+impl !Send for SymbolStr {}
+impl !Sync for SymbolStr {}
 
-impl std::ops::Deref for LocalInternedString {
+/// This impl means that if `ss` is a `SymbolStr`:
+/// - `*ss` is a `str`;
+/// - `&*ss` is a `&str`;
+/// - `&ss as &str` is a `&str`, which means that `&ss` can be passed to a
+///   function expecting a `&str`.
+impl std::ops::Deref for SymbolStr {
     type Target = str;
     #[inline]
     fn deref(&self) -> &str { self.string }
 }
 
-impl fmt::Debug for LocalInternedString {
+impl fmt::Debug for SymbolStr {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Debug::fmt(self.string, f)
     }
 }
 
-impl fmt::Display for LocalInternedString {
+impl fmt::Display for SymbolStr {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Display::fmt(self.string, f)
     }
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index 5b3900ab496..3451346869d 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -755,6 +755,10 @@ LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module,
   unwrap(Module)->setDataLayout(Target->createDataLayout());
 }
 
+extern "C" void LLVMRustSetModulePICLevel(LLVMModuleRef M) {
+  unwrap(M)->setPICLevel(PICLevel::Level::BigPIC);
+}
+
 extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M) {
   unwrap(M)->setPIELevel(PIELevel::Level::Large);
 }
diff --git a/src/test/ui/rfc-2091-track-caller/caller-location-intrinsic.rs b/src/test/ui/rfc-2091-track-caller/caller-location-intrinsic.rs
index ab6c59384c4..1c4d4666fa1 100644
--- a/src/test/ui/rfc-2091-track-caller/caller-location-intrinsic.rs
+++ b/src/test/ui/rfc-2091-track-caller/caller-location-intrinsic.rs
@@ -1,9 +1,21 @@
 // run-pass
 
 #![feature(core_intrinsics)]
+
+macro_rules! caller_location_from_macro {
+    () => (core::intrinsics::caller_location());
+}
+
 fn main() {
     let loc = core::intrinsics::caller_location();
     assert_eq!(loc.file(), file!());
-    assert_eq!(loc.line(), 5);
+    assert_eq!(loc.line(), 10);
     assert_eq!(loc.column(), 15);
+
+    // `caller_location()` in a macro should behave similarly to `file!` and `line!`,
+    // i.e. point to where the macro was invoked, instead of the macro itself.
+    let loc2 = caller_location_from_macro!();
+    assert_eq!(loc2.file(), file!());
+    assert_eq!(loc2.line(), 17);
+    assert_eq!(loc2.column(), 16);
 }