about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--src/librustc/hir/lowering.rs10
-rw-r--r--src/librustc/hir/map/def_collector.rs5
-rw-r--r--src/librustc/middle/lang_items.rs4
-rw-r--r--src/librustc/middle/mem_categorization.rs4
-rw-r--r--src/librustc/middle/stability.rs4
-rw-r--r--src/librustc/session/config.rs19
-rw-r--r--src/librustc_allocator/expand.rs6
-rw-r--r--src/librustc_interface/util.rs2
-rw-r--r--src/librustc_lint/builtin.rs6
-rw-r--r--src/librustc_macros/src/symbols.rs20
-rw-r--r--src/librustc_metadata/cstore_impl.rs4
-rw-r--r--src/librustc_mir/interpret/validity.rs4
-rw-r--r--src/librustc_target/Cargo.toml1
-rw-r--r--src/librustc_target/abi/mod.rs8
-rw-r--r--src/librustc_typeck/check/mod.rs16
-rw-r--r--src/libsyntax/ast.rs24
-rw-r--r--src/libsyntax/ext/base.rs4
-rw-r--r--src/libsyntax/ext/build.rs38
-rw-r--r--src/libsyntax/ext/derive.rs7
-rw-r--r--src/libsyntax/ext/expand.rs2
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs54
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs2
-rw-r--r--src/libsyntax/parse/diagnostics.rs6
-rw-r--r--src/libsyntax/parse/lexer/mod.rs4
-rw-r--r--src/libsyntax/parse/literal.rs21
-rw-r--r--src/libsyntax/parse/parser.rs8
-rw-r--r--src/libsyntax/parse/token.rs4
-rw-r--r--src/libsyntax/std_inject.rs6
-rw-r--r--src/libsyntax/test.rs12
-rw-r--r--src/libsyntax_ext/asm.rs4
-rw-r--r--src/libsyntax_ext/assert.rs4
-rw-r--r--src/libsyntax_ext/deriving/clone.rs8
-rw-r--r--src/libsyntax_ext/deriving/cmp/eq.rs10
-rw-r--r--src/libsyntax_ext/deriving/cmp/ord.rs8
-rw-r--r--src/libsyntax_ext/deriving/cmp/partial_eq.rs4
-rw-r--r--src/libsyntax_ext/deriving/cmp/partial_ord.rs31
-rw-r--r--src/libsyntax_ext/deriving/debug.rs5
-rw-r--r--src/libsyntax_ext/deriving/default.rs7
-rw-r--r--src/libsyntax_ext/deriving/generic/mod.rs5
-rw-r--r--src/libsyntax_ext/deriving/hash.rs3
-rw-r--r--src/libsyntax_ext/deriving/mod.rs4
-rw-r--r--src/libsyntax_ext/env.rs4
-rw-r--r--src/libsyntax_ext/format.rs10
-rw-r--r--src/libsyntax_ext/lib.rs18
-rw-r--r--src/libsyntax_ext/proc_macro_decls.rs6
-rw-r--r--src/libsyntax_ext/proc_macro_server.rs4
-rw-r--r--src/libsyntax_ext/test.rs15
-rw-r--r--src/libsyntax_ext/test_case.rs11
-rw-r--r--src/libsyntax_pos/symbol.rs60
50 files changed, 299 insertions, 228 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 39364bad6f1..d5e2969e964 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3009,6 +3009,7 @@ dependencies = [
  "rustc_cratesio_shim 0.0.0",
  "rustc_data_structures 0.0.0",
  "serialize 0.0.0",
+ "syntax_pos 0.0.0",
 ]
 
 [[package]]
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 3d83918bd0a..1d51e7cd742 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -1145,9 +1145,7 @@ impl<'a> LoweringContext<'a> {
         let unstable_span = self.sess.source_map().mark_span_with_reason(
             CompilerDesugaringKind::Async,
             span,
-            Some(vec![
-                Symbol::intern("gen_future"),
-            ].into()),
+            Some(vec![sym::gen_future].into()),
         );
         let gen_future = self.expr_std_path(
             unstable_span, &[sym::future, sym::from_generator], None, ThinVec::new());
@@ -2958,7 +2956,7 @@ impl<'a> LoweringContext<'a> {
             ident: match f.ident {
                 Some(ident) => ident,
                 // FIXME(jseyfried): positional field hygiene
-                None => Ident::new(Symbol::intern(&index.to_string()), f.span),
+                None => Ident::new(sym::integer(index), f.span),
             },
             vis: self.lower_visibility(&f.vis, None),
             ty: self.lower_ty(&f.ty, ImplTraitContext::disallowed()),
@@ -4177,9 +4175,7 @@ impl<'a> LoweringContext<'a> {
                     let unstable_span = this.sess.source_map().mark_span_with_reason(
                         CompilerDesugaringKind::TryBlock,
                         body.span,
-                        Some(vec![
-                            Symbol::intern("try_trait"),
-                        ].into()),
+                        Some(vec![sym::try_trait].into()),
                     );
                     let mut block = this.lower_block(body, true).into_inner();
                     let tail = block.expr.take().map_or_else(
diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs
index bb9e76f0262..bde27c71f9a 100644
--- a/src/librustc/hir/map/def_collector.rs
+++ b/src/librustc/hir/map/def_collector.rs
@@ -5,8 +5,7 @@ use crate::session::CrateDisambiguator;
 use syntax::ast::*;
 use syntax::ext::hygiene::Mark;
 use syntax::visit;
-use syntax::symbol::kw;
-use syntax::symbol::Symbol;
+use syntax::symbol::{kw, sym};
 use syntax::parse::token::{self, Token};
 use syntax_pos::Span;
 
@@ -221,7 +220,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
                           _: &'a Generics, _: NodeId, _: Span) {
         for (index, field) in data.fields().iter().enumerate() {
             let name = field.ident.map(|ident| ident.name)
-                .unwrap_or_else(|| Symbol::intern(&index.to_string()));
+                .unwrap_or_else(|| sym::integer(index));
             let def = self.create_def(field.id,
                                       DefPathData::ValueNs(name.as_interned_str()),
                                       field.span);
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 103580a598f..034ef32aafe 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -210,8 +210,8 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> {
 pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
     attrs.iter().find_map(|attr| Some(match attr {
         _ if attr.check_name(sym::lang) => (attr.value_str()?, attr.span),
-        _ if attr.check_name(sym::panic_handler) => (Symbol::intern("panic_impl"), attr.span),
-        _ if attr.check_name(sym::alloc_error_handler) => (Symbol::intern("oom"), attr.span),
+        _ if attr.check_name(sym::panic_handler) => (sym::panic_impl, attr.span),
+        _ if attr.check_name(sym::alloc_error_handler) => (sym::oom, attr.span),
         _ => return None,
     }))
 }
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index c7f8cf684e6..6af43b04a7d 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -1316,7 +1316,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
 
                 for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
                     let subpat_ty = self.pat_ty_adjusted(&subpat)?; // see (*2)
-                    let interior = InteriorField(FieldIndex(i, Name::intern(&i.to_string())));
+                    let interior = InteriorField(FieldIndex(i, sym::integer(i)));
                     let subcmt = Rc::new(
                         self.cat_imm_interior(pat, cmt.clone(), subpat_ty, interior));
                     self.cat_pattern_(subcmt, &subpat, op)?;
@@ -1363,7 +1363,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
                 };
                 for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
                     let subpat_ty = self.pat_ty_adjusted(&subpat)?; // see (*2)
-                    let interior = InteriorField(FieldIndex(i, Name::intern(&i.to_string())));
+                    let interior = InteriorField(FieldIndex(i, sym::integer(i)));
                     let subcmt = Rc::new(
                         self.cat_imm_interior(pat, cmt.clone(), subpat_ty, interior));
                     self.cat_pattern_(subcmt, &subpat, op)?;
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index ac0e99137cb..66fa9a5c6f1 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -437,7 +437,7 @@ impl<'a, 'tcx> Index<'tcx> {
                         reason: Some(Symbol::intern(reason)),
                         issue: 27812,
                     },
-                    feature: Symbol::intern("rustc_private"),
+                    feature: sym::rustc_private,
                     rustc_depr: None,
                     const_stability: None,
                     promotable: false,
@@ -880,7 +880,7 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     // FIXME: only remove `libc` when `stdbuild` is active.
     // FIXME: remove special casing for `test`.
     remaining_lib_features.remove(&Symbol::intern("libc"));
-    remaining_lib_features.remove(&Symbol::intern("test"));
+    remaining_lib_features.remove(&sym::test);
 
     let check_features =
         |remaining_lib_features: &mut FxHashMap<_, _>, defined_features: &[_]| {
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index f16137bd2c2..49cd3eff21a 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -19,7 +19,7 @@ use syntax::source_map::{FileName, FilePathMapping};
 use syntax::edition::{Edition, EDITION_NAME_LIST, DEFAULT_EDITION};
 use syntax::parse::token;
 use syntax::parse;
-use syntax::symbol::Symbol;
+use syntax::symbol::{sym, Symbol};
 use syntax::feature_gate::UnstableFeatures;
 use errors::emitter::HumanReadableErrorType;
 
@@ -1503,31 +1503,31 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
         Some(Symbol::intern(vendor)),
     ));
     if sess.target.target.options.has_elf_tls {
-        ret.insert((Symbol::intern("target_thread_local"), None));
+        ret.insert((sym::target_thread_local, None));
     }
     for &i in &[8, 16, 32, 64, 128] {
         if i >= min_atomic_width && i <= max_atomic_width {
             let s = i.to_string();
             ret.insert((
-                Symbol::intern("target_has_atomic"),
+                sym::target_has_atomic,
                 Some(Symbol::intern(&s)),
             ));
             if &s == wordsz {
                 ret.insert((
-                    Symbol::intern("target_has_atomic"),
+                    sym::target_has_atomic,
                     Some(Symbol::intern("ptr")),
                 ));
             }
         }
     }
     if atomic_cas {
-        ret.insert((Symbol::intern("target_has_atomic"), Some(Symbol::intern("cas"))));
+        ret.insert((sym::target_has_atomic, Some(Symbol::intern("cas"))));
     }
     if sess.opts.debug_assertions {
         ret.insert((Symbol::intern("debug_assertions"), None));
     }
     if sess.opts.crate_types.contains(&CrateType::ProcMacro) {
-        ret.insert((Symbol::intern("proc_macro"), None));
+        ret.insert((sym::proc_macro, None));
     }
     ret
 }
@@ -1547,7 +1547,7 @@ pub fn build_configuration(sess: &Session, mut user_cfg: ast::CrateConfig) -> as
     let default_cfg = default_configuration(sess);
     // If the user wants a test runner, then add the test cfg
     if sess.opts.test {
-        user_cfg.insert((Symbol::intern("test"), None));
+        user_cfg.insert((sym::test, None));
     }
     user_cfg.extend(default_cfg.iter().cloned());
     user_cfg
@@ -2702,7 +2702,7 @@ mod tests {
     use std::path::PathBuf;
     use super::{Externs, OutputType, OutputTypes};
     use rustc_target::spec::{MergeFunctions, PanicStrategy, RelroLevel};
-    use syntax::symbol::Symbol;
+    use syntax::symbol::sym;
     use syntax::edition::{Edition, DEFAULT_EDITION};
     use syntax;
     use super::Options;
@@ -2744,7 +2744,7 @@ mod tests {
             let (sessopts, cfg) = build_session_options_and_crate_config(matches);
             let sess = build_session(sessopts, None, registry);
             let cfg = build_configuration(&sess, to_crate_config(cfg));
-            assert!(cfg.contains(&(Symbol::intern("test"), None)));
+            assert!(cfg.contains(&(sym::test, None)));
         });
     }
 
@@ -2752,7 +2752,6 @@ mod tests {
     // another --cfg test
     #[test]
     fn test_switch_implies_cfg_test_unless_cfg_test() {
-        use syntax::symbol::sym;
         syntax::with_default_globals(|| {
             let matches = &match optgroups().parse(&["--test".to_string(),
                                                      "--cfg=test".to_string()]) {
diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs
index b9cd30694f6..3ec06b17aff 100644
--- a/src/librustc_allocator/expand.rs
+++ b/src/librustc_allocator/expand.rs
@@ -91,9 +91,7 @@ impl MutVisitor for ExpandAllocatorDirectives<'_> {
             call_site: item.span, // use the call site of the static
             def_site: None,
             format: MacroAttribute(Symbol::intern(name)),
-            allow_internal_unstable: Some(vec![
-                Symbol::intern("rustc_attrs"),
-            ].into()),
+            allow_internal_unstable: Some(vec![sym::rustc_attrs].into()),
             allow_internal_unsafe: false,
             local_inner_macros: false,
             edition: self.sess.edition,
@@ -223,7 +221,7 @@ impl AllocFnFactory<'_> {
     }
 
     fn attrs(&self) -> Vec<Attribute> {
-        let special = Symbol::intern("rustc_std_internal_symbol");
+        let special = sym::rustc_std_internal_symbol;
         let special = self.cx.meta_word(self.span, special);
         vec![self.cx.attribute(self.span, special)]
     }
diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs
index 09bb547191f..4ff996d1f57 100644
--- a/src/librustc_interface/util.rs
+++ b/src/librustc_interface/util.rs
@@ -68,7 +68,7 @@ pub fn add_configuration(
     sess: &Session,
     codegen_backend: &dyn CodegenBackend,
 ) {
-    let tf = Symbol::intern("target_feature");
+    let tf = sym::target_feature;
 
     cfg.extend(
         codegen_backend
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index d52e497cf63..d184c671bba 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -1439,8 +1439,8 @@ impl KeywordIdents {
     {
         let next_edition = match cx.sess.edition() {
             Edition::Edition2015 => {
-                match &ident.as_str()[..] {
-                    "async" | "await" | "try" => Edition::Edition2018,
+                match ident.name {
+                    kw::Async | kw::Await | kw::Try => Edition::Edition2018,
 
                     // rust-lang/rust#56327: Conservatively do not
                     // attempt to report occurrences of `dyn` within
@@ -1454,7 +1454,7 @@ impl KeywordIdents {
                     // its precise role in the parsed AST and thus are
                     // assured this is truly an attempt to use it as
                     // an identifier.
-                    "dyn" if !under_macro => Edition::Edition2018,
+                    kw::Dyn if !under_macro => Edition::Edition2018,
 
                     _ => return,
                 }
diff --git a/src/librustc_macros/src/symbols.rs b/src/librustc_macros/src/symbols.rs
index 3883682fa9d..1f6e54807d8 100644
--- a/src/librustc_macros/src/symbols.rs
+++ b/src/librustc_macros/src/symbols.rs
@@ -96,6 +96,7 @@ pub fn symbols(input: TokenStream) -> TokenStream {
 
     let mut keyword_stream = quote! {};
     let mut symbols_stream = quote! {};
+    let mut digits_stream = quote! {};
     let mut prefill_stream = quote! {};
     let mut counter = 0u32;
     let mut keys = HashSet::<String>::new();
@@ -106,6 +107,7 @@ pub fn symbols(input: TokenStream) -> TokenStream {
         }
     };
 
+    // Generate the listed keywords.
     for keyword in &input.keywords.0 {
         let name = &keyword.name;
         let value = &keyword.value;
@@ -119,6 +121,7 @@ pub fn symbols(input: TokenStream) -> TokenStream {
         counter += 1;
     }
 
+    // Generate the listed symbols.
     for symbol in &input.symbols.0 {
         let name = &symbol.name;
         let value = match &symbol.value {
@@ -135,6 +138,19 @@ pub fn symbols(input: TokenStream) -> TokenStream {
         counter += 1;
     }
 
+    // Generate symbols for the strings "0", "1", ..., "9".
+    for n in 0..10 {
+        let n = n.to_string();
+        check_dup(&n);
+        prefill_stream.extend(quote! {
+            #n,
+        });
+        digits_stream.extend(quote! {
+            Symbol::new(#counter),
+        });
+        counter += 1;
+    }
+
     let tt = TokenStream::from(quote! {
         macro_rules! keywords {
             () => {
@@ -145,6 +161,10 @@ pub fn symbols(input: TokenStream) -> TokenStream {
         macro_rules! symbols {
             () => {
                 #symbols_stream
+
+                pub const digits_array: &[Symbol; 10] = &[
+                    #digits_stream
+                ];
             }
         }
 
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index fae4c244d6e..c2c40ea79e8 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -431,9 +431,7 @@ impl cstore::CStore {
             let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
             let ext = SyntaxExtension::ProcMacro {
                 expander: Box::new(BangProcMacro { client }),
-                allow_internal_unstable: Some(vec![
-                    Symbol::intern("proc_macro_def_site"),
-                ].into()),
+                allow_internal_unstable: Some(vec![sym::proc_macro_def_site].into()),
                 edition: data.root.edition,
             };
             return LoadedMacro::ProcMacro(Lrc::new(ext));
diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index 0d3ee830574..ccc38191a93 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -2,7 +2,7 @@ use std::fmt::Write;
 use std::hash::Hash;
 use std::ops::RangeInclusive;
 
-use syntax_pos::symbol::Symbol;
+use syntax_pos::symbol::{sym, Symbol};
 use rustc::hir;
 use rustc::ty::layout::{self, Size, Align, TyLayout, LayoutOf, VariantIdx};
 use rustc::ty;
@@ -188,7 +188,7 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> ValidityVisitor<'rt, 'a, '
 
                 PathElem::ClosureVar(name.unwrap_or_else(|| {
                     // Fall back to showing the field index.
-                    Symbol::intern(&field.to_string())
+                    sym::integer(field)
                 }))
             }
 
diff --git a/src/librustc_target/Cargo.toml b/src/librustc_target/Cargo.toml
index ecea15a9922..3ab25146331 100644
--- a/src/librustc_target/Cargo.toml
+++ b/src/librustc_target/Cargo.toml
@@ -15,3 +15,4 @@ log = "0.4"
 rustc_cratesio_shim = { path = "../librustc_cratesio_shim" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 serialize = { path = "../libserialize" }
+syntax_pos = { path = "../libsyntax_pos" }
diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs
index 4b61057e5cf..8fc5e6aae34 100644
--- a/src/librustc_target/abi/mod.rs
+++ b/src/librustc_target/abi/mod.rs
@@ -7,6 +7,7 @@ use std::fmt;
 use std::ops::{Add, Deref, Sub, Mul, AddAssign, Range, RangeInclusive};
 
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
+use syntax_pos::symbol::{sym, Symbol};
 
 pub mod call;
 
@@ -552,6 +553,13 @@ impl FloatTy {
         }
     }
 
+    pub fn to_symbol(self) -> Symbol {
+        match self {
+            FloatTy::F32 => sym::f32,
+            FloatTy::F64 => sym::f64,
+        }
+    }
+
     pub fn bit_width(self) -> usize {
         match self {
             FloatTy::F32 => 32,
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index b9713e844d6..bfe30488f9c 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2697,16 +2697,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
     fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, ast::Ident) {
         let (tr, name) = match (op, is_mut) {
-            (PlaceOp::Deref, false) =>
-                (self.tcx.lang_items().deref_trait(), "deref"),
-            (PlaceOp::Deref, true) =>
-                (self.tcx.lang_items().deref_mut_trait(), "deref_mut"),
-            (PlaceOp::Index, false) =>
-                (self.tcx.lang_items().index_trait(), "index"),
-            (PlaceOp::Index, true) =>
-                (self.tcx.lang_items().index_mut_trait(), "index_mut"),
+            (PlaceOp::Deref, false) => (self.tcx.lang_items().deref_trait(), sym::deref),
+            (PlaceOp::Deref, true) => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
+            (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
+            (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
         };
-        (tr, ast::Ident::from_str(name))
+        (tr, ast::Ident::with_empty_ctxt(name))
     }
 
     fn try_overloaded_place_op(&self,
@@ -4948,7 +4944,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 // This is less than ideal, it will not suggest a return type span on any
                 // method called `main`, regardless of whether it is actually the entry point,
                 // but it will still present it as the reason for the expected type.
-                Some((decl, ident, ident.name != Symbol::intern("main")))
+                Some((decl, ident, ident.name != sym::main))
             }),
             Node::TraitItem(&hir::TraitItem {
                 ident, node: hir::TraitItemKind::Method(hir::MethodSig {
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 3276f152575..75e83bd9f9c 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -10,7 +10,7 @@ use crate::parse::token;
 use crate::print::pprust;
 use crate::ptr::P;
 use crate::source_map::{dummy_spanned, respan, Spanned};
-use crate::symbol::{kw, Symbol};
+use crate::symbol::{kw, sym, Symbol};
 use crate::tokenstream::TokenStream;
 use crate::ThinVec;
 
@@ -1531,6 +1531,17 @@ impl IntTy {
         }
     }
 
+    pub fn to_symbol(&self) -> Symbol {
+        match *self {
+            IntTy::Isize => sym::isize,
+            IntTy::I8 => sym::i8,
+            IntTy::I16 => sym::i16,
+            IntTy::I32 => sym::i32,
+            IntTy::I64 => sym::i64,
+            IntTy::I128 => sym::i128,
+        }
+    }
+
     pub fn val_to_string(&self, val: i128) -> String {
         // Cast to a `u128` so we can correctly print `INT128_MIN`. All integral types
         // are parsed as `u128`, so we wouldn't want to print an extra negative
@@ -1572,6 +1583,17 @@ impl UintTy {
         }
     }
 
+    pub fn to_symbol(&self) -> Symbol {
+        match *self {
+            UintTy::Usize => sym::usize,
+            UintTy::U8 => sym::u8,
+            UintTy::U16 => sym::u16,
+            UintTy::U32 => sym::u32,
+            UintTy::U64 => sym::u64,
+            UintTy::U128 => sym::u128,
+        }
+    }
+
     pub fn val_to_string(&self, val: u128) -> String {
         format!("{}{}", val, self.ty_to_string())
     }
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index dbec379e769..d72193ffe12 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -969,10 +969,10 @@ impl<'a> ExtCtxt<'a> {
     pub fn ident_of(&self, st: &str) -> ast::Ident {
         ast::Ident::from_str(st)
     }
-    pub fn std_path(&self, components: &[&str]) -> Vec<ast::Ident> {
+    pub fn std_path(&self, components: &[Symbol]) -> Vec<ast::Ident> {
         let def_site = DUMMY_SP.apply_mark(self.current_expansion.mark);
         iter::once(Ident::new(kw::DollarCrate, def_site))
-            .chain(components.iter().map(|s| self.ident_of(s)))
+            .chain(components.iter().map(|&s| Ident::with_empty_ctxt(s)))
             .collect()
     }
     pub fn name_of(&self, st: &str) -> ast::Name {
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index ad8fb12deb7..9c0ffc1f6e8 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -3,11 +3,11 @@ use crate::attr;
 use crate::source_map::{dummy_spanned, respan, Spanned};
 use crate::ext::base::ExtCtxt;
 use crate::ptr::P;
-use crate::symbol::{Symbol, kw};
+use crate::symbol::{kw, sym, Symbol};
 use crate::ThinVec;
 
 use rustc_target::spec::abi::Abi;
-use syntax_pos::{Pos, Span, DUMMY_SP};
+use syntax_pos::{Pos, Span};
 
 pub trait AstBuilder {
     // paths
@@ -49,7 +49,6 @@ pub trait AstBuilder {
               ty: P<ast::Ty>,
               mutbl: ast::Mutability) -> P<ast::Ty>;
 
-    fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty>;
     fn ty_infer(&self, sp: Span) -> P<ast::Ty>;
 
     fn typaram(&self,
@@ -425,15 +424,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
                 ast::TyKind::Ptr(self.ty_mt(ty, mutbl)))
     }
 
-    fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty> {
-        self.ty_path(
-            self.path_all(DUMMY_SP,
-                          true,
-                          self.std_path(&["option", "Option"]),
-                          vec![ast::GenericArg::Type(ty)],
-                          Vec::new()))
-    }
-
     fn ty_infer(&self, span: Span) -> P<ast::Ty> {
         self.ty(span, ast::TyKind::Infer)
     }
@@ -735,7 +725,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         self.expr(sp, ast::ExprKind::Array(exprs))
     }
     fn expr_vec_ng(&self, sp: Span) -> P<ast::Expr> {
-        self.expr_call_global(sp, self.std_path(&["vec", "Vec", "new"]),
+        self.expr_call_global(sp, self.std_path(&[sym::vec, sym::Vec, sym::new]),
                               Vec::new())
     }
     fn expr_vec_slice(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
@@ -751,12 +741,12 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
 
 
     fn expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
-        let some = self.std_path(&["option", "Option", "Some"]);
+        let some = self.std_path(&[sym::option, sym::Option, sym::Some]);
         self.expr_call_global(sp, some, vec![expr])
     }
 
     fn expr_none(&self, sp: Span) -> P<ast::Expr> {
-        let none = self.std_path(&["option", "Option", "None"]);
+        let none = self.std_path(&[sym::option, sym::Option, sym::None]);
         let none = self.path_global(sp, none);
         self.expr_path(none)
     }
@@ -780,7 +770,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         let expr_loc_ptr = self.expr_addr_of(span, expr_loc_tuple);
         self.expr_call_global(
             span,
-            self.std_path(&["rt", "begin_panic"]),
+            self.std_path(&[sym::rt, sym::begin_panic]),
             vec![
                 self.expr_str(span, msg),
                 expr_loc_ptr])
@@ -791,19 +781,19 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
     }
 
     fn expr_ok(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
-        let ok = self.std_path(&["result", "Result", "Ok"]);
+        let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]);
         self.expr_call_global(sp, ok, vec![expr])
     }
 
     fn expr_err(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
-        let err = self.std_path(&["result", "Result", "Err"]);
+        let err = self.std_path(&[sym::result, sym::Result, sym::Err]);
         self.expr_call_global(sp, err, vec![expr])
     }
 
     fn expr_try(&self, sp: Span, head: P<ast::Expr>) -> P<ast::Expr> {
-        let ok = self.std_path(&["result", "Result", "Ok"]);
+        let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]);
         let ok_path = self.path_global(sp, ok);
-        let err = self.std_path(&["result", "Result", "Err"]);
+        let err = self.std_path(&[sym::result, sym::Result, sym::Err]);
         let err_path = self.path_global(sp, err);
 
         let binding_variable = self.ident_of("__try_var");
@@ -867,25 +857,25 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
     }
 
     fn pat_some(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
-        let some = self.std_path(&["option", "Option", "Some"]);
+        let some = self.std_path(&[sym::option, sym::Option, sym::Some]);
         let path = self.path_global(span, some);
         self.pat_tuple_struct(span, path, vec![pat])
     }
 
     fn pat_none(&self, span: Span) -> P<ast::Pat> {
-        let some = self.std_path(&["option", "Option", "None"]);
+        let some = self.std_path(&[sym::option, sym::Option, sym::None]);
         let path = self.path_global(span, some);
         self.pat_path(span, path)
     }
 
     fn pat_ok(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
-        let some = self.std_path(&["result", "Result", "Ok"]);
+        let some = self.std_path(&[sym::result, sym::Result, sym::Ok]);
         let path = self.path_global(span, some);
         self.pat_tuple_struct(span, path, vec![pat])
     }
 
     fn pat_err(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
-        let some = self.std_path(&["result", "Result", "Err"]);
+        let some = self.std_path(&[sym::result, sym::Result, sym::Err]);
         let path = self.path_global(span, some);
         self.pat_tuple_struct(span, path, vec![pat])
     }
diff --git a/src/libsyntax/ext/derive.rs b/src/libsyntax/ext/derive.rs
index 6e789c4c708..c47224ca0ce 100644
--- a/src/libsyntax/ext/derive.rs
+++ b/src/libsyntax/ext/derive.rs
@@ -58,10 +58,7 @@ pub fn add_derived_markers<T>(cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::P
         call_site: span,
         def_site: None,
         format: ExpnFormat::MacroAttribute(Symbol::intern(&pretty_name)),
-        allow_internal_unstable: Some(vec![
-            Symbol::intern("rustc_attrs"),
-            Symbol::intern("structural_match"),
-        ].into()),
+        allow_internal_unstable: Some(vec![sym::rustc_attrs, sym::structural_match].into()),
         allow_internal_unsafe: false,
         local_inner_macros: false,
         edition: cx.parse_sess.edition,
@@ -74,7 +71,7 @@ pub fn add_derived_markers<T>(cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::P
             attrs.push(cx.attribute(span, meta));
         }
         if names.contains(&Symbol::intern("Copy")) {
-            let meta = cx.meta_word(span, Symbol::intern("rustc_copy_clone_marker"));
+            let meta = cx.meta_word(span, sym::rustc_copy_clone_marker);
             attrs.push(cx.attribute(span, meta));
         }
     });
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index fbe052252a1..c2a73b662c6 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -938,7 +938,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             }
             BuiltinDerive(func) => {
                 expn_info.allow_internal_unstable = Some(vec![
-                    Symbol::intern("rustc_attrs"),
+                    sym::rustc_attrs,
                     Symbol::intern("derive_clone_copy"),
                     Symbol::intern("derive_eq"),
                     Symbol::intern("libstd_sys_internals"), // RustcDeserialize and RustcSerialize
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index e55226b8579..7b7cf80760f 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -80,7 +80,7 @@ use crate::parse::{Directory, ParseSess};
 use crate::parse::parser::{Parser, PathStyle};
 use crate::parse::token::{self, DocComment, Nonterminal, Token};
 use crate::print::pprust;
-use crate::symbol::kw;
+use crate::symbol::{kw, sym, Symbol};
 use crate::tokenstream::{DelimSpan, TokenStream};
 
 use errors::FatalError;
@@ -598,7 +598,7 @@ fn inner_parse_loop<'root, 'tt>(
                 TokenTree::MetaVarDecl(_, _, id) => {
                     // Built-in nonterminals never start with these tokens,
                     // so we can eliminate them from consideration.
-                    if may_begin_with(&*id.as_str(), token) {
+                    if may_begin_with(id.name, token) {
                         bb_items.push(item);
                     }
                 }
@@ -791,7 +791,7 @@ pub fn parse(
                 let match_cur = item.match_cur;
                 item.push_match(
                     match_cur,
-                    MatchedNonterminal(Lrc::new(parse_nt(&mut parser, span, &ident.as_str()))),
+                    MatchedNonterminal(Lrc::new(parse_nt(&mut parser, span, ident.name))),
                 );
                 item.idx += 1;
                 item.match_cur += 1;
@@ -819,7 +819,7 @@ fn get_macro_ident(token: &Token) -> Option<(Ident, bool)> {
 ///
 /// Returning `false` is a *stability guarantee* that such a matcher will *never* begin with that
 /// token. Be conservative (return true) if not sure.
-fn may_begin_with(name: &str, token: &Token) -> bool {
+fn may_begin_with(name: Symbol, token: &Token) -> bool {
     /// Checks whether the non-terminal may contain a single (non-keyword) identifier.
     fn may_be_ident(nt: &token::Nonterminal) -> bool {
         match *nt {
@@ -829,16 +829,16 @@ fn may_begin_with(name: &str, token: &Token) -> bool {
     }
 
     match name {
-        "expr" => token.can_begin_expr(),
-        "ty" => token.can_begin_type(),
-        "ident" => get_macro_ident(token).is_some(),
-        "literal" => token.can_begin_literal_or_bool(),
-        "vis" => match *token {
+        sym::expr => token.can_begin_expr(),
+        sym::ty => token.can_begin_type(),
+        sym::ident => get_macro_ident(token).is_some(),
+        sym::literal => token.can_begin_literal_or_bool(),
+        sym::vis => match *token {
             // The follow-set of :vis + "priv" keyword + interpolated
             Token::Comma | Token::Ident(..) | Token::Interpolated(_) => true,
             _ => token.can_begin_type(),
         },
-        "block" => match *token {
+        sym::block => match *token {
             Token::OpenDelim(token::Brace) => true,
             Token::Interpolated(ref nt) => match **nt {
                 token::NtItem(_)
@@ -852,7 +852,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool {
             },
             _ => false,
         },
-        "path" | "meta" => match *token {
+        sym::path | sym::meta => match *token {
             Token::ModSep | Token::Ident(..) => true,
             Token::Interpolated(ref nt) => match **nt {
                 token::NtPath(_) | token::NtMeta(_) => true,
@@ -860,7 +860,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool {
             },
             _ => false,
         },
-        "pat" => match *token {
+        sym::pat => match *token {
             Token::Ident(..) |               // box, ref, mut, and other identifiers (can stricten)
             Token::OpenDelim(token::Paren) |    // tuple pattern
             Token::OpenDelim(token::Bracket) |  // slice pattern
@@ -876,7 +876,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool {
             Token::Interpolated(ref nt) => may_be_ident(nt),
             _ => false,
         },
-        "lifetime" => match *token {
+        sym::lifetime => match *token {
             Token::Lifetime(_) => true,
             Token::Interpolated(ref nt) => match **nt {
                 token::NtLifetime(_) | token::NtTT(_) => true,
@@ -903,34 +903,34 @@ fn may_begin_with(name: &str, token: &Token) -> bool {
 /// # Returns
 ///
 /// The parsed non-terminal.
-fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal {
-    if name == "tt" {
+fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> Nonterminal {
+    if name == sym::tt {
         return token::NtTT(p.parse_token_tree());
     }
     // check at the beginning and the parser checks after each bump
     p.process_potential_macro_variable();
     match name {
-        "item" => match panictry!(p.parse_item()) {
+        sym::item => match panictry!(p.parse_item()) {
             Some(i) => token::NtItem(i),
             None => {
                 p.fatal("expected an item keyword").emit();
                 FatalError.raise();
             }
         },
-        "block" => token::NtBlock(panictry!(p.parse_block())),
-        "stmt" => match panictry!(p.parse_stmt()) {
+        sym::block => token::NtBlock(panictry!(p.parse_block())),
+        sym::stmt => match panictry!(p.parse_stmt()) {
             Some(s) => token::NtStmt(s),
             None => {
                 p.fatal("expected a statement").emit();
                 FatalError.raise();
             }
         },
-        "pat" => token::NtPat(panictry!(p.parse_pat(None))),
-        "expr" => token::NtExpr(panictry!(p.parse_expr())),
-        "literal" => token::NtLiteral(panictry!(p.parse_literal_maybe_minus())),
-        "ty" => token::NtTy(panictry!(p.parse_ty())),
+        sym::pat => token::NtPat(panictry!(p.parse_pat(None))),
+        sym::expr => token::NtExpr(panictry!(p.parse_expr())),
+        sym::literal => token::NtLiteral(panictry!(p.parse_literal_maybe_minus())),
+        sym::ty => token::NtTy(panictry!(p.parse_ty())),
         // this could be handled like a token, since it is one
-        "ident" => if let Some((ident, is_raw)) = get_macro_ident(&p.token) {
+        sym::ident => if let Some((ident, is_raw)) = get_macro_ident(&p.token) {
             let span = p.span;
             p.bump();
             token::NtIdent(Ident::new(ident.name, span), is_raw)
@@ -939,10 +939,10 @@ fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal {
             p.fatal(&format!("expected ident, found {}", &token_str)).emit();
             FatalError.raise()
         }
-        "path" => token::NtPath(panictry!(p.parse_path(PathStyle::Type))),
-        "meta" => token::NtMeta(panictry!(p.parse_meta_item())),
-        "vis" => token::NtVis(panictry!(p.parse_visibility(true))),
-        "lifetime" => if p.check_lifetime() {
+        sym::path => token::NtPath(panictry!(p.parse_path(PathStyle::Type))),
+        sym::meta => token::NtMeta(panictry!(p.parse_meta_item())),
+        sym::vis => token::NtVis(panictry!(p.parse_visibility(true))),
+        sym::lifetime => if p.check_lifetime() {
             token::NtLifetime(p.expect_lifetime().ident)
         } else {
             let token_str = pprust::token_to_string(&p.token);
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 2debd8f048b..285c88357a6 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -396,7 +396,7 @@ pub fn compile(
                         future this will become a hard error. Please use `allow_internal_unstable(\
                         foo, bar)` to only allow the `foo` and `bar` features",
                     );
-                    vec![Symbol::intern("allow_internal_unstable_backcompat_hack")].into()
+                    vec![sym::allow_internal_unstable_backcompat_hack].into()
                 })
             );
         let allow_internal_unsafe = attr::contains_name(&def.attrs, sym::allow_internal_unsafe);
diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs
index 9431b559da5..b3d49524d76 100644
--- a/src/libsyntax/parse/diagnostics.rs
+++ b/src/libsyntax/parse/diagnostics.rs
@@ -8,7 +8,7 @@ use crate::parse::parser::{BlockMode, PathStyle, SemiColonMode, TokenType, Token
 use crate::print::pprust;
 use crate::ptr::P;
 use crate::source_map::Spanned;
-use crate::symbol::kw;
+use crate::symbol::{kw, sym};
 use crate::ThinVec;
 use crate::util::parser::AssocOp;
 use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
@@ -263,7 +263,7 @@ impl<'a> Parser<'a> {
         };
         self.last_unexpected_token_span = Some(self.span);
         let mut err = self.fatal(&msg_exp);
-        if self.token.is_ident_named("and") {
+        if self.token.is_ident_named(sym::and) {
             err.span_suggestion_short(
                 self.span,
                 "use `&&` instead of `and` for the boolean operator",
@@ -271,7 +271,7 @@ impl<'a> Parser<'a> {
                 Applicability::MaybeIncorrect,
             );
         }
-        if self.token.is_ident_named("or") {
+        if self.token.is_ident_named(sym::or) {
             err.span_suggestion_short(
                 self.span,
                 "use `||` instead of `or` for the boolean operator",
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index deb76d6d70a..a06a84f162a 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -1,7 +1,7 @@
 use crate::ast::{self, Ident};
 use crate::parse::ParseSess;
 use crate::parse::token::{self, Token};
-use crate::symbol::Symbol;
+use crate::symbol::{sym, Symbol};
 use crate::parse::unescape;
 use crate::parse::unescape_error_reporting::{emit_unescape_error, push_escaped_char};
 
@@ -754,7 +754,7 @@ impl<'a> StringReader<'a> {
                 }
                 _ => {
                     // just a 0
-                    return (token::Integer, self.name_from(start_bpos));
+                    return (token::Integer, sym::integer(0));
                 }
             }
         } else if c.is_digit(10) {
diff --git a/src/libsyntax/parse/literal.rs b/src/libsyntax/parse/literal.rs
index 0305b1f59b9..18019a89130 100644
--- a/src/libsyntax/parse/literal.rs
+++ b/src/libsyntax/parse/literal.rs
@@ -171,12 +171,15 @@ impl LitKind {
     /// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing).
     pub fn to_lit_token(&self) -> token::Lit {
         let (kind, symbol, suffix) = match *self {
-            LitKind::Str(string, ast::StrStyle::Cooked) => {
-                let escaped = string.as_str().escape_default().to_string();
-                (token::Str, Symbol::intern(&escaped), None)
+            LitKind::Str(symbol, ast::StrStyle::Cooked) => {
+                // Don't re-intern unless the escaped string is different.
+                let s = &symbol.as_str();
+                let escaped = s.escape_default().to_string();
+                let symbol = if escaped == *s { symbol } else { Symbol::intern(&escaped) };
+                (token::Str, symbol, None)
             }
-            LitKind::Str(string, ast::StrStyle::Raw(n)) => {
-                (token::StrRaw(n), string, None)
+            LitKind::Str(symbol, ast::StrStyle::Raw(n)) => {
+                (token::StrRaw(n), symbol, None)
             }
             LitKind::ByteStr(ref bytes) => {
                 let string = bytes.iter().cloned().flat_map(ascii::escape_default)
@@ -193,14 +196,14 @@ impl LitKind {
             }
             LitKind::Int(n, ty) => {
                 let suffix = match ty {
-                    ast::LitIntType::Unsigned(ty) => Some(Symbol::intern(ty.ty_to_string())),
-                    ast::LitIntType::Signed(ty) => Some(Symbol::intern(ty.ty_to_string())),
+                    ast::LitIntType::Unsigned(ty) => Some(ty.to_symbol()),
+                    ast::LitIntType::Signed(ty) => Some(ty.to_symbol()),
                     ast::LitIntType::Unsuffixed => None,
                 };
-                (token::Integer, Symbol::intern(&n.to_string()), suffix)
+                (token::Integer, sym::integer(n), suffix)
             }
             LitKind::Float(symbol, ty) => {
-                (token::Float, symbol, Some(Symbol::intern(ty.ty_to_string())))
+                (token::Float, symbol, Some(ty.to_symbol()))
             }
             LitKind::FloatUnsuffixed(symbol) => {
                 (token::Float, symbol, None)
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 6c29437362c..07efeaa4cf2 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2759,7 +2759,7 @@ impl<'a> Parser<'a> {
                 let (span, e) = self.interpolated_or_expr_span(e)?;
                 (lo.to(span), ExprKind::Box(e))
             }
-            token::Ident(..) if self.token.is_ident_named("not") => {
+            token::Ident(..) if self.token.is_ident_named(sym::not) => {
                 // `not` is just an ordinary identifier in Rust-the-language,
                 // but as `rustc`-the-compiler, we can issue clever diagnostics
                 // for confused users who really want to say `!`
@@ -4592,7 +4592,7 @@ impl<'a> Parser<'a> {
             let do_not_suggest_help =
                 self.token.is_keyword(kw::In) || self.token == token::Colon;
 
-            if self.token.is_ident_named("and") {
+            if self.token.is_ident_named(sym::and) {
                 e.span_suggestion_short(
                     self.span,
                     "use `&&` instead of `and` for the boolean operator",
@@ -4600,7 +4600,7 @@ impl<'a> Parser<'a> {
                     Applicability::MaybeIncorrect,
                 );
             }
-            if self.token.is_ident_named("or") {
+            if self.token.is_ident_named(sym::or) {
                 e.span_suggestion_short(
                     self.span,
                     "use `||` instead of `or` for the boolean operator",
@@ -5787,7 +5787,7 @@ impl<'a> Parser<'a> {
             VisibilityKind::Inherited => {}
             _ => {
                 let is_macro_rules: bool = match self.token {
-                    token::Ident(sid, _) => sid.name == Symbol::intern("macro_rules"),
+                    token::Ident(sid, _) => sid.name == sym::macro_rules,
                     _ => false,
                 };
                 let mut err = if is_macro_rules {
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index e5361b2db4e..47185df8d61 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -391,9 +391,9 @@ impl Token {
 
     /// Returns `true` if the token is a identifier whose name is the given
     /// string slice.
-    crate fn is_ident_named(&self, name: &str) -> bool {
+    crate fn is_ident_named(&self, name: Symbol) -> bool {
         match self.ident() {
-            Some((ident, _)) => ident.as_str() == name,
+            Some((ident, _)) => ident.name == name,
             None => false
         }
     }
diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs
index 398705857bb..eea94f0d194 100644
--- a/src/libsyntax/std_inject.rs
+++ b/src/libsyntax/std_inject.rs
@@ -20,9 +20,7 @@ fn ignored_span(sp: Span, edition: Edition) -> Span {
         call_site: DUMMY_SP,
         def_site: None,
         format: MacroAttribute(Symbol::intern("std_inject")),
-        allow_internal_unstable: Some(vec![
-            Symbol::intern("prelude_import"),
-        ].into()),
+        allow_internal_unstable: Some(vec![sym::prelude_import].into()),
         allow_internal_unsafe: false,
         local_inner_macros: false,
         edition,
@@ -98,7 +96,7 @@ pub fn maybe_inject_crates_ref(
     krate.module.items.insert(0, P(ast::Item {
         attrs: vec![ast::Attribute {
             style: ast::AttrStyle::Outer,
-            path: ast::Path::from_ident(ast::Ident::new(Symbol::intern("prelude_import"), span)),
+            path: ast::Path::from_ident(ast::Ident::new(sym::prelude_import, span)),
             tokens: TokenStream::empty(),
             id: attr::mk_attr_id(),
             is_sugared_doc: false,
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index d1e11da4e7c..1998ec19f13 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -283,12 +283,8 @@ fn generate_test_harness(sess: &ParseSess,
     mark.set_expn_info(ExpnInfo {
         call_site: DUMMY_SP,
         def_site: None,
-        format: MacroAttribute(Symbol::intern("test_case")),
-        allow_internal_unstable: Some(vec![
-            Symbol::intern("main"),
-            Symbol::intern("test"),
-            Symbol::intern("rustc_attrs"),
-        ].into()),
+        format: MacroAttribute(sym::test_case),
+        allow_internal_unstable: Some(vec![sym::main, sym::test, sym::rustc_attrs].into()),
         allow_internal_unsafe: false,
         local_inner_macros: false,
         edition: sess.edition,
@@ -347,14 +343,14 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
     let call_test_main = ecx.stmt_expr(call_test_main);
 
     // #![main]
-    let main_meta = ecx.meta_word(sp, Symbol::intern("main"));
+    let main_meta = ecx.meta_word(sp, sym::main);
     let main_attr = ecx.attribute(sp, main_meta);
 
     // extern crate test as test_gensym
     let test_extern_stmt = ecx.stmt_item(sp, ecx.item(sp,
         test_id,
         vec![],
-        ast::ItemKind::ExternCrate(Some(Symbol::intern("test")))
+        ast::ItemKind::ExternCrate(Some(sym::test))
     ));
 
     // pub fn main() { ... }
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs
index 704665e0a84..4d7083c1a79 100644
--- a/src/libsyntax_ext/asm.rs
+++ b/src/libsyntax_ext/asm.rs
@@ -11,7 +11,7 @@ use syntax::ext::base::{self, *};
 use syntax::feature_gate;
 use syntax::parse::{self, token};
 use syntax::ptr::P;
-use syntax::symbol::{Symbol, sym};
+use syntax::symbol::{kw, sym, Symbol};
 use syntax::ast::AsmDialect;
 use syntax_pos::Span;
 use syntax::tokenstream;
@@ -93,7 +93,7 @@ fn parse_inline_asm<'a>(
         })
         .unwrap_or(tts.len());
     let mut p = cx.new_parser_from_tts(&tts[first_colon..]);
-    let mut asm = Symbol::intern("");
+    let mut asm = kw::Invalid;
     let mut asm_str_style = None;
     let mut outputs = Vec::new();
     let mut inputs = Vec::new();
diff --git a/src/libsyntax_ext/assert.rs b/src/libsyntax_ext/assert.rs
index a11cd9c6f76..13342c8e28e 100644
--- a/src/libsyntax_ext/assert.rs
+++ b/src/libsyntax_ext/assert.rs
@@ -8,7 +8,7 @@ use syntax::parse::token::{self, Token};
 use syntax::parse::parser::Parser;
 use syntax::print::pprust;
 use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::{sym, Symbol};
 use syntax::tokenstream::{TokenStream, TokenTree};
 use syntax_pos::{Span, DUMMY_SP};
 
@@ -27,7 +27,7 @@ pub fn expand_assert<'cx>(
 
     let sp = sp.apply_mark(cx.current_expansion.mark);
     let panic_call = Mac_ {
-        path: Path::from_ident(Ident::new(Symbol::intern("panic"), sp)),
+        path: Path::from_ident(Ident::new(sym::panic, sp)),
         tts: custom_message.unwrap_or_else(|| {
             TokenStream::from(TokenTree::Token(
                 DUMMY_SP,
diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs
index a39e0a6e973..b3b6328e2ca 100644
--- a/src/libsyntax_ext/deriving/clone.rs
+++ b/src/libsyntax_ext/deriving/clone.rs
@@ -7,7 +7,7 @@ use syntax::attr;
 use syntax::ext::base::{Annotatable, ExtCtxt};
 use syntax::ext::build::AstBuilder;
 use syntax::ptr::P;
-use syntax::symbol::{Symbol, kw, sym};
+use syntax::symbol::{kw, sym, Symbol};
 use syntax_pos::Span;
 
 pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>,
@@ -76,7 +76,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>,
         _ => cx.span_bug(span, "#[derive(Clone)] on trait item or impl item"),
     }
 
-    let inline = cx.meta_word(span, Symbol::intern("inline"));
+    let inline = cx.meta_word(span, sym::inline);
     let attrs = vec![cx.attribute(span, inline)];
     let trait_def = TraitDef {
         span,
@@ -115,7 +115,7 @@ fn cs_clone_shallow(name: &str,
         // set the expn ID so we can use the unstable struct.
         let span = span.with_ctxt(cx.backtrace());
         let assert_path = cx.path_all(span, true,
-                                        cx.std_path(&["clone", helper_name]),
+                                        cx.std_path(&[sym::clone, Symbol::intern(helper_name)]),
                                         vec![GenericArg::Type(ty)], vec![]);
         stmts.push(cx.stmt_let_type_only(span, cx.ty_path(assert_path)));
     }
@@ -157,7 +157,7 @@ fn cs_clone(name: &str,
             -> P<Expr> {
     let ctor_path;
     let all_fields;
-    let fn_path = cx.std_path(&["clone", "Clone", "clone"]);
+    let fn_path = cx.std_path(&[sym::clone, sym::Clone, sym::clone]);
     let subcall = |cx: &mut ExtCtxt<'_>, field: &FieldInfo<'_>| {
         let args = vec![cx.expr_addr_of(field.span, field.self_.clone())];
         cx.expr_call_global(field.span, fn_path.clone(), args)
diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs
index a1035ff641f..1d981e0ff79 100644
--- a/src/libsyntax_ext/deriving/cmp/eq.rs
+++ b/src/libsyntax_ext/deriving/cmp/eq.rs
@@ -6,7 +6,7 @@ use syntax::ast::{self, Expr, MetaItem, GenericArg};
 use syntax::ext::base::{Annotatable, ExtCtxt};
 use syntax::ext::build::AstBuilder;
 use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::{sym, Symbol};
 use syntax_pos::Span;
 
 pub fn expand_deriving_eq(cx: &mut ExtCtxt<'_>,
@@ -14,9 +14,9 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt<'_>,
                           mitem: &MetaItem,
                           item: &Annotatable,
                           push: &mut dyn FnMut(Annotatable)) {
-    let inline = cx.meta_word(span, Symbol::intern("inline"));
-    let hidden = cx.meta_list_item_word(span, Symbol::intern("hidden"));
-    let doc = cx.meta_list(span, Symbol::intern("doc"), vec![hidden]);
+    let inline = cx.meta_word(span, sym::inline);
+    let hidden = cx.meta_list_item_word(span, sym::hidden);
+    let doc = cx.meta_list(span, sym::doc, vec![hidden]);
     let attrs = vec![cx.attribute(span, inline), cx.attribute(span, doc)];
     let trait_def = TraitDef {
         span,
@@ -54,7 +54,7 @@ fn cs_total_eq_assert(cx: &mut ExtCtxt<'_>,
         // set the expn ID so we can use the unstable struct.
         let span = span.with_ctxt(cx.backtrace());
         let assert_path = cx.path_all(span, true,
-                                        cx.std_path(&["cmp", helper_name]),
+                                        cx.std_path(&[sym::cmp, Symbol::intern(helper_name)]),
                                         vec![GenericArg::Type(ty)], vec![]);
         stmts.push(cx.stmt_let_type_only(span, cx.ty_path(assert_path)));
     }
diff --git a/src/libsyntax_ext/deriving/cmp/ord.rs b/src/libsyntax_ext/deriving/cmp/ord.rs
index e4f939c151f..b25a9e4c50f 100644
--- a/src/libsyntax_ext/deriving/cmp/ord.rs
+++ b/src/libsyntax_ext/deriving/cmp/ord.rs
@@ -6,7 +6,7 @@ use syntax::ast::{self, Expr, MetaItem};
 use syntax::ext::base::{Annotatable, ExtCtxt};
 use syntax::ext::build::AstBuilder;
 use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::sym;
 use syntax_pos::Span;
 
 pub fn expand_deriving_ord(cx: &mut ExtCtxt<'_>,
@@ -14,7 +14,7 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt<'_>,
                            mitem: &MetaItem,
                            item: &Annotatable,
                            push: &mut dyn FnMut(Annotatable)) {
-    let inline = cx.meta_word(span, Symbol::intern("inline"));
+    let inline = cx.meta_word(span, sym::inline);
     let attrs = vec![cx.attribute(span, inline)];
     let trait_def = TraitDef {
         span,
@@ -55,9 +55,9 @@ pub fn ordering_collapsed(cx: &mut ExtCtxt<'_>,
 
 pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> {
     let test_id = cx.ident_of("cmp").gensym();
-    let equals_path = cx.path_global(span, cx.std_path(&["cmp", "Ordering", "Equal"]));
+    let equals_path = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal]));
 
-    let cmp_path = cx.std_path(&["cmp", "Ord", "cmp"]);
+    let cmp_path = cx.std_path(&[sym::cmp, sym::Ord, sym::cmp]);
 
     // Builds:
     //
diff --git a/src/libsyntax_ext/deriving/cmp/partial_eq.rs b/src/libsyntax_ext/deriving/cmp/partial_eq.rs
index 07026ae3739..6172f27261e 100644
--- a/src/libsyntax_ext/deriving/cmp/partial_eq.rs
+++ b/src/libsyntax_ext/deriving/cmp/partial_eq.rs
@@ -6,7 +6,7 @@ use syntax::ast::{BinOpKind, Expr, MetaItem};
 use syntax::ext::base::{Annotatable, ExtCtxt};
 use syntax::ext::build::AstBuilder;
 use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::sym;
 use syntax_pos::Span;
 
 pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt<'_>,
@@ -62,7 +62,7 @@ pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt<'_>,
 
     macro_rules! md {
         ($name:expr, $f:ident) => { {
-            let inline = cx.meta_word(span, Symbol::intern("inline"));
+            let inline = cx.meta_word(span, sym::inline);
             let attrs = vec![cx.attribute(span, inline)];
             MethodDef {
                 name: $name,
diff --git a/src/libsyntax_ext/deriving/cmp/partial_ord.rs b/src/libsyntax_ext/deriving/cmp/partial_ord.rs
index e99abeb118e..3980741f252 100644
--- a/src/libsyntax_ext/deriving/cmp/partial_ord.rs
+++ b/src/libsyntax_ext/deriving/cmp/partial_ord.rs
@@ -8,7 +8,7 @@ use syntax::ast::{self, BinOpKind, Expr, MetaItem};
 use syntax::ext::base::{Annotatable, ExtCtxt};
 use syntax::ext::build::AstBuilder;
 use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::{sym, Symbol};
 use syntax_pos::Span;
 
 pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt<'_>,
@@ -18,7 +18,7 @@ pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt<'_>,
                                    push: &mut dyn FnMut(Annotatable)) {
     macro_rules! md {
         ($name:expr, $op:expr, $equal:expr) => { {
-            let inline = cx.meta_word(span, Symbol::intern("inline"));
+            let inline = cx.meta_word(span, sym::inline);
             let attrs = vec![cx.attribute(span, inline)];
             MethodDef {
                 name: $name,
@@ -42,7 +42,7 @@ pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt<'_>,
                                     vec![Box::new(ordering_ty)],
                                     PathKind::Std));
 
-    let inline = cx.meta_word(span, Symbol::intern("inline"));
+    let inline = cx.meta_word(span, sym::inline);
     let attrs = vec![cx.attribute(span, inline)];
 
     let partial_cmp_def = MethodDef {
@@ -114,11 +114,11 @@ pub fn some_ordering_collapsed(cx: &mut ExtCtxt<'_>,
 
 pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> {
     let test_id = cx.ident_of("cmp").gensym();
-    let ordering = cx.path_global(span, cx.std_path(&["cmp", "Ordering", "Equal"]));
+    let ordering = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal]));
     let ordering_expr = cx.expr_path(ordering.clone());
     let equals_expr = cx.expr_some(span, ordering_expr);
 
-    let partial_cmp_path = cx.std_path(&["cmp", "PartialOrd", "partial_cmp"]);
+    let partial_cmp_path = cx.std_path(&[sym::cmp, sym::PartialOrd, sym::partial_cmp]);
 
     // Builds:
     //
@@ -188,7 +188,8 @@ fn cs_op(less: bool,
          span: Span,
          substr: &Substructure<'_>) -> P<Expr> {
     let ordering_path = |cx: &mut ExtCtxt<'_>, name: &str| {
-        cx.expr_path(cx.path_global(span, cx.std_path(&["cmp", "Ordering", name])))
+        cx.expr_path(cx.path_global(
+            span, cx.std_path(&[sym::cmp, sym::Ordering, Symbol::intern(name)])))
     };
 
     let par_cmp = |cx: &mut ExtCtxt<'_>, span, self_f: P<Expr>, other_fs: &[P<Expr>], default| {
@@ -198,9 +199,9 @@ fn cs_op(less: bool,
         };
 
         // `PartialOrd::partial_cmp(self.fi, other.fi)`
-        let cmp_path = cx.expr_path(cx.path_global(span, cx.std_path(&["cmp",
-                                                                       "PartialOrd",
-                                                                       "partial_cmp"])));
+        let cmp_path = cx.expr_path(cx.path_global(span, cx.std_path(&[sym::cmp,
+                                                                       sym::PartialOrd,
+                                                                       sym::partial_cmp])));
         let cmp = cx.expr_call(span,
                                cmp_path,
                                vec![cx.expr_addr_of(span, self_f),
@@ -208,9 +209,9 @@ fn cs_op(less: bool,
 
         let default = ordering_path(cx, default);
         // `Option::unwrap_or(_, Ordering::Equal)`
-        let unwrap_path = cx.expr_path(cx.path_global(span, cx.std_path(&["option",
-                                                                          "Option",
-                                                                          "unwrap_or"])));
+        let unwrap_path = cx.expr_path(cx.path_global(span, cx.std_path(&[sym::option,
+                                                                          sym::Option,
+                                                                          sym::unwrap_or])));
         cx.expr_call(span, unwrap_path, vec![cmp, default])
     };
 
@@ -256,9 +257,9 @@ fn cs_op(less: bool,
 
             // `Ordering::then_with(Option::unwrap_or(..), ..)`
             let then_with_path = cx.expr_path(cx.path_global(span,
-                                                             cx.std_path(&["cmp",
-                                                                           "Ordering",
-                                                                           "then_with"])));
+                                                             cx.std_path(&[sym::cmp,
+                                                                           sym::Ordering,
+                                                                           sym::then_with])));
             cx.expr_call(span, then_with_path, vec![par_cmp, cx.lambda0(span, subexpr)])
         },
         |cx, args| {
diff --git a/src/libsyntax_ext/deriving/debug.rs b/src/libsyntax_ext/deriving/debug.rs
index 2fc1fc9140d..dec4c2dfc3b 100644
--- a/src/libsyntax_ext/deriving/debug.rs
+++ b/src/libsyntax_ext/deriving/debug.rs
@@ -9,6 +9,7 @@ use syntax::ast::{Expr, MetaItem};
 use syntax::ext::base::{Annotatable, ExtCtxt};
 use syntax::ext::build::AstBuilder;
 use syntax::ptr::P;
+use syntax::symbol::sym;
 use syntax_pos::{DUMMY_SP, Span};
 
 pub fn expand_deriving_debug(cx: &mut ExtCtxt<'_>,
@@ -82,7 +83,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
 
                 let expr = cx.expr_method_call(span,
                                                 builder_expr.clone(),
-                                                Ident::from_str("field"),
+                                                Ident::with_empty_ctxt(sym::field),
                                                 vec![field]);
 
                 // Use `let _ = expr;` to avoid triggering the
@@ -106,7 +107,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
                 let field = cx.expr_addr_of(field.span, field);
                 let expr = cx.expr_method_call(span,
                                                 builder_expr.clone(),
-                                                Ident::from_str("field"),
+                                                Ident::with_empty_ctxt(sym::field),
                                                 vec![name, field]);
                 stmts.push(stmt_let_undescore(cx, span, expr));
             }
diff --git a/src/libsyntax_ext/deriving/default.rs b/src/libsyntax_ext/deriving/default.rs
index 6db0a29165a..fd8e87e2fef 100644
--- a/src/libsyntax_ext/deriving/default.rs
+++ b/src/libsyntax_ext/deriving/default.rs
@@ -6,7 +6,7 @@ use syntax::ast::{Expr, MetaItem};
 use syntax::ext::base::{Annotatable, DummyResult, ExtCtxt};
 use syntax::ext::build::AstBuilder;
 use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::{kw, sym};
 use syntax::span_err;
 use syntax_pos::Span;
 
@@ -15,7 +15,7 @@ pub fn expand_deriving_default(cx: &mut ExtCtxt<'_>,
                                mitem: &MetaItem,
                                item: &Annotatable,
                                push: &mut dyn FnMut(Annotatable)) {
-    let inline = cx.meta_word(span, Symbol::intern("inline"));
+    let inline = cx.meta_word(span, sym::inline);
     let attrs = vec![cx.attribute(span, inline)];
     let trait_def = TraitDef {
         span,
@@ -47,7 +47,8 @@ fn default_substructure(cx: &mut ExtCtxt<'_>,
                         trait_span: Span,
                         substr: &Substructure<'_>)
                         -> P<Expr> {
-    let default_ident = cx.std_path(&["default", "Default", "default"]);
+    // Note that `kw::Default` is "default" and `sym::Default` is "Default"!
+    let default_ident = cx.std_path(&[kw::Default, sym::Default, kw::Default]);
     let default_call = |span| cx.expr_call_global(span, default_ident.clone(), Vec::new());
 
     return match *substr.fields {
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index 0689eb50f9c..7e3082a87d9 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -666,14 +666,13 @@ impl<'a> TraitDef<'a> {
         let self_type = cx.ty_path(path);
 
         let attr = cx.attribute(self.span,
-                                cx.meta_word(self.span,
-                                             Symbol::intern("automatically_derived")));
+                                cx.meta_word(self.span, sym::automatically_derived));
         // Just mark it now since we know that it'll end up used downstream
         attr::mark_used(&attr);
         let opt_trait_ref = Some(trait_ref);
         let unused_qual = {
             let word = cx.meta_list_item_word(self.span, Symbol::intern("unused_qualifications"));
-            cx.attribute(self.span, cx.meta_list(self.span, Symbol::intern("allow"), vec![word]))
+            cx.attribute(self.span, cx.meta_list(self.span, sym::allow, vec![word]))
         };
 
         let mut a = vec![attr, unused_qual];
diff --git a/src/libsyntax_ext/deriving/hash.rs b/src/libsyntax_ext/deriving/hash.rs
index 0d4f2ddc3be..e7f99d45782 100644
--- a/src/libsyntax_ext/deriving/hash.rs
+++ b/src/libsyntax_ext/deriving/hash.rs
@@ -6,6 +6,7 @@ use syntax::ast::{Expr, MetaItem, Mutability};
 use syntax::ext::base::{Annotatable, ExtCtxt};
 use syntax::ext::build::AstBuilder;
 use syntax::ptr::P;
+use syntax::symbol::sym;
 use syntax_pos::Span;
 
 pub fn expand_deriving_hash(cx: &mut ExtCtxt<'_>,
@@ -60,7 +61,7 @@ fn hash_substructure(cx: &mut ExtCtxt<'_>, trait_span: Span, substr: &Substructu
     };
     let call_hash = |span, thing_expr| {
         let hash_path = {
-            let strs = cx.std_path(&["hash", "Hash", "hash"]);
+            let strs = cx.std_path(&[sym::hash, sym::Hash, sym::hash]);
 
             cx.expr_path(cx.path_global(span, strs))
         };
diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs
index c27de692d88..ac41f30e6b3 100644
--- a/src/libsyntax_ext/deriving/mod.rs
+++ b/src/libsyntax_ext/deriving/mod.rs
@@ -145,12 +145,12 @@ fn call_intrinsic(cx: &ExtCtxt<'_>,
         span = span.with_ctxt(cx.backtrace());
     } else { // Avoid instability errors with user defined curstom derives, cc #36316
         let mut info = cx.current_expansion.mark.expn_info().unwrap();
-        info.allow_internal_unstable = Some(vec![Symbol::intern("core_intrinsics")].into());
+        info.allow_internal_unstable = Some(vec![sym::core_intrinsics].into());
         let mark = Mark::fresh(Mark::root());
         mark.set_expn_info(info);
         span = span.with_ctxt(SyntaxContext::empty().apply_mark(mark));
     }
-    let path = cx.std_path(&["intrinsics", intrinsic]);
+    let path = cx.std_path(&[sym::intrinsics, Symbol::intern(intrinsic)]);
     let call = cx.expr_call_global(span, path, args);
 
     cx.expr_block(P(ast::Block {
diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs
index 72a66ae3845..b7f2ecf0f91 100644
--- a/src/libsyntax_ext/env.rs
+++ b/src/libsyntax_ext/env.rs
@@ -27,7 +27,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
             let lt = cx.lifetime(sp, Ident::with_empty_ctxt(kw::StaticLifetime));
             cx.expr_path(cx.path_all(sp,
                                      true,
-                                     cx.std_path(&["option", "Option", "None"]),
+                                     cx.std_path(&[sym::option, sym::Option, sym::None]),
                                      vec![GenericArg::Type(cx.ty_rptr(sp,
                                                      cx.ty_ident(sp,
                                                                  Ident::with_empty_ctxt(sym::str)),
@@ -37,7 +37,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
         }
         Ok(s) => {
             cx.expr_call_global(sp,
-                                cx.std_path(&["option", "Option", "Some"]),
+                                cx.std_path(&[sym::option, sym::Option, sym::Some]),
                                 vec![cx.expr_str(sp, Symbol::intern(&s))])
         }
     };
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 9e54c0634b6..b5be45547cf 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -387,7 +387,7 @@ impl<'a, 'b> Context<'a, 'b> {
     }
 
     fn rtpath(ecx: &ExtCtxt<'_>, s: &str) -> Vec<ast::Ident> {
-        ecx.std_path(&["fmt", "rt", "v1", s])
+        ecx.std_path(&[sym::fmt, sym::rt, sym::v1, Symbol::intern(s)])
     }
 
     fn build_count(&self, c: parse::Count<'_>) -> P<ast::Expr> {
@@ -644,7 +644,7 @@ impl<'a, 'b> Context<'a, 'b> {
             ("new_v1_formatted", vec![pieces, args_slice, fmt])
         };
 
-        let path = self.ecx.std_path(&["fmt", "Arguments", fn_name]);
+        let path = self.ecx.std_path(&[sym::fmt, sym::Arguments, Symbol::intern(fn_name)]);
         self.ecx.expr_call_global(self.macsp, path, fn_args)
     }
 
@@ -675,14 +675,14 @@ impl<'a, 'b> Context<'a, 'b> {
                 }
             }
             Count => {
-                let path = ecx.std_path(&["fmt", "ArgumentV1", "from_usize"]);
+                let path = ecx.std_path(&[sym::fmt, sym::ArgumentV1, sym::from_usize]);
                 return ecx.expr_call_global(macsp, path, vec![arg]);
             }
         };
 
-        let path = ecx.std_path(&["fmt", trait_, "fmt"]);
+        let path = ecx.std_path(&[sym::fmt, Symbol::intern(trait_), sym::fmt]);
         let format_fn = ecx.path_global(sp, path);
-        let path = ecx.std_path(&["fmt", "ArgumentV1", "new"]);
+        let path = ecx.std_path(&[sym::fmt, sym::ArgumentV1, sym::new]);
         ecx.expr_call_global(macsp, path, vec![arg, ecx.expr_path(format_fn)])
     }
 }
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs
index e5fc7aab61d..fc001544275 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -42,8 +42,8 @@ pub mod proc_macro_impl;
 use rustc_data_structures::sync::Lrc;
 use syntax::ast;
 use syntax::ext::base::{MacroExpanderFn, NormalTT, NamedSyntaxExtension, MultiModifier};
-use syntax::symbol::Symbol;
 use syntax::edition::Edition;
+use syntax::symbol::{sym, Symbol};
 
 pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver,
                          user_exts: Vec<NamedSyntaxExtension>,
@@ -93,30 +93,26 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver,
         assert: assert::expand_assert,
     }
 
-    register(Symbol::intern("test_case"), MultiModifier(Box::new(test_case::expand)));
-    register(Symbol::intern("test"), MultiModifier(Box::new(test::expand_test)));
-    register(Symbol::intern("bench"), MultiModifier(Box::new(test::expand_bench)));
+    register(sym::test_case, MultiModifier(Box::new(test_case::expand)));
+    register(sym::test, MultiModifier(Box::new(test::expand_test)));
+    register(sym::bench, MultiModifier(Box::new(test::expand_bench)));
 
     // format_args uses `unstable` things internally.
     register(Symbol::intern("format_args"),
              NormalTT {
                 expander: Box::new(format::expand_format_args),
                 def_info: None,
-                allow_internal_unstable: Some(vec![
-                    Symbol::intern("fmt_internals"),
-                ].into()),
+                allow_internal_unstable: Some(vec![sym::fmt_internals].into()),
                 allow_internal_unsafe: false,
                 local_inner_macros: false,
                 unstable_feature: None,
                 edition,
             });
-    register(Symbol::intern("format_args_nl"),
+    register(sym::format_args_nl,
              NormalTT {
                  expander: Box::new(format::expand_format_args_nl),
                  def_info: None,
-                 allow_internal_unstable: Some(vec![
-                     Symbol::intern("fmt_internals"),
-                 ].into()),
+                 allow_internal_unstable: Some(vec![sym::fmt_internals].into()),
                  allow_internal_unsafe: false,
                  local_inner_macros: false,
                  unstable_feature: None,
diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs
index a485bb19808..5b8f4f35f2d 100644
--- a/src/libsyntax_ext/proc_macro_decls.rs
+++ b/src/libsyntax_ext/proc_macro_decls.rs
@@ -351,9 +351,9 @@ fn mk_decls(
     mark.set_expn_info(ExpnInfo {
         call_site: DUMMY_SP,
         def_site: None,
-        format: MacroAttribute(Symbol::intern("proc_macro")),
+        format: MacroAttribute(sym::proc_macro),
         allow_internal_unstable: Some(vec![
-            Symbol::intern("rustc_attrs"),
+            sym::rustc_attrs,
             Symbol::intern("proc_macro_internals"),
         ].into()),
         allow_internal_unsafe: false,
@@ -420,7 +420,7 @@ fn mk_decls(
         ast::Mutability::Immutable,
         cx.expr_vec_slice(span, decls),
     ).map(|mut i| {
-        let attr = cx.meta_word(span, Symbol::intern("rustc_proc_macro_decls"));
+        let attr = cx.meta_word(span, sym::rustc_proc_macro_decls);
         i.attrs.push(cx.attribute(span, attr));
         i.vis = respan(span, ast::VisibilityKind::Public);
         i
diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax_ext/proc_macro_server.rs
index beac92894b7..53730d2d080 100644
--- a/src/libsyntax_ext/proc_macro_server.rs
+++ b/src/libsyntax_ext/proc_macro_server.rs
@@ -14,7 +14,7 @@ use syntax::parse::lexer::comments;
 use syntax::parse::{self, token, ParseSess};
 use syntax::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint};
 use syntax_pos::hygiene::{SyntaxContext, Transparency};
-use syntax_pos::symbol::{kw, Symbol};
+use syntax_pos::symbol::{kw, sym, Symbol};
 use syntax_pos::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span};
 
 trait FromInternal<T> {
@@ -159,7 +159,7 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
                     escaped.extend(ch.escape_debug());
                 }
                 let stream = vec![
-                    Ident(ast::Ident::new(Symbol::intern("doc"), span), false),
+                    Ident(ast::Ident::new(sym::doc, span), false),
                     Eq,
                     Token::lit(token::Str, Symbol::intern(&escaped), None),
                 ]
diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs
index 8ee61a3f67f..c20dc6cb2d7 100644
--- a/src/libsyntax_ext/test.rs
+++ b/src/libsyntax_ext/test.rs
@@ -65,11 +65,8 @@ pub fn expand_test_or_bench(
         mark.set_expn_info(ExpnInfo {
             call_site: DUMMY_SP,
             def_site: None,
-            format: MacroAttribute(Symbol::intern("test")),
-            allow_internal_unstable: Some(vec![
-                Symbol::intern("rustc_attrs"),
-                Symbol::intern("test"),
-            ].into()),
+            format: MacroAttribute(sym::test),
+            allow_internal_unstable: Some(vec![sym::rustc_attrs, sym::test].into()),
             allow_internal_unsafe: false,
             local_inner_macros: false,
             edition: cx.parse_sess.edition,
@@ -130,11 +127,11 @@ pub fn expand_test_or_bench(
     let mut test_const = cx.item(sp, ast::Ident::new(item.ident.name, sp).gensym(),
         vec![
             // #[cfg(test)]
-            cx.attribute(attr_sp, cx.meta_list(attr_sp, Symbol::intern("cfg"), vec![
-                cx.meta_list_item_word(attr_sp, Symbol::intern("test"))
+            cx.attribute(attr_sp, cx.meta_list(attr_sp, sym::cfg, vec![
+                cx.meta_list_item_word(attr_sp, sym::test)
             ])),
             // #[rustc_test_marker]
-            cx.attribute(attr_sp, cx.meta_word(attr_sp, Symbol::intern("rustc_test_marker"))),
+            cx.attribute(attr_sp, cx.meta_word(attr_sp, sym::rustc_test_marker)),
         ],
         // const $ident: test::TestDescAndFn =
         ast::ItemKind::Const(cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
@@ -180,7 +177,7 @@ pub fn expand_test_or_bench(
     let test_extern = cx.item(sp,
         test_id,
         vec![],
-        ast::ItemKind::ExternCrate(Some(Symbol::intern("test")))
+        ast::ItemKind::ExternCrate(Some(sym::test))
     );
 
     log::debug!("Synthetic test item:\n{}\n", pprust::item_to_string(&test_const));
diff --git a/src/libsyntax_ext/test_case.rs b/src/libsyntax_ext/test_case.rs
index 5b1ae167ce3..cffecdd0f18 100644
--- a/src/libsyntax_ext/test_case.rs
+++ b/src/libsyntax_ext/test_case.rs
@@ -14,7 +14,7 @@ use syntax::ext::build::AstBuilder;
 use syntax::ext::hygiene::{Mark, SyntaxContext};
 use syntax::ast;
 use syntax::source_map::respan;
-use syntax::symbol::{Symbol, sym};
+use syntax::symbol::sym;
 use syntax_pos::{DUMMY_SP, Span};
 use syntax::source_map::{ExpnInfo, MacroAttribute};
 use syntax::feature_gate;
@@ -40,11 +40,8 @@ pub fn expand(
         mark.set_expn_info(ExpnInfo {
             call_site: DUMMY_SP,
             def_site: None,
-            format: MacroAttribute(Symbol::intern("test_case")),
-            allow_internal_unstable: Some(vec![
-                Symbol::intern("test"),
-                Symbol::intern("rustc_attrs"),
-            ].into()),
+            format: MacroAttribute(sym::test_case),
+            allow_internal_unstable: Some(vec![sym::test, sym::rustc_attrs].into()),
             allow_internal_unsafe: false,
             local_inner_macros: false,
             edition: ecx.parse_sess.edition,
@@ -59,7 +56,7 @@ pub fn expand(
         item.ident = item.ident.gensym();
         item.attrs.push(
             ecx.attribute(sp,
-                ecx.meta_word(sp, Symbol::intern("rustc_test_marker")))
+                ecx.meta_word(sp, sym::rustc_test_marker))
         );
         item
     });
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 26422e891c5..60f87783b3e 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -9,10 +9,10 @@ use rustc_data_structures::newtype_index;
 use rustc_macros::symbols;
 use serialize::{Decodable, Decoder, Encodable, Encoder};
 
-use std::fmt;
-use std::str;
 use std::cmp::{PartialEq, Ordering, PartialOrd, Ord};
+use std::fmt;
 use std::hash::{Hash, Hasher};
+use std::str;
 
 use crate::hygiene::SyntaxContext;
 use crate::{Span, DUMMY_SP, GLOBALS};
@@ -102,6 +102,9 @@ symbols! {
     // Symbols that can be referred to with syntax_pos::sym::*. The symbol is
     // the stringified identifier unless otherwise specified (e.g.
     // `proc_dash_macro` represents "proc-macro").
+    //
+    // As well as the symbols listed, there are symbols for the the strings
+    // "0", "1", ..., "9", which are accessible via `sym::integer`.
     Symbols {
         aarch64_target_feature,
         abi,
@@ -130,8 +133,11 @@ symbols! {
         allow_internal_unstable,
         allow_internal_unstable_backcompat_hack,
         always,
+        and,
         any,
         arbitrary_self_types,
+        Arguments,
+        ArgumentV1,
         arm_target_feature,
         asm,
         associated_consts,
@@ -145,6 +151,8 @@ symbols! {
         automatically_derived,
         avx512_target_feature,
         await_macro,
+        begin_panic,
+        bench,
         bin,
         bind_by_move_pattern_guards,
         block,
@@ -163,9 +171,11 @@ symbols! {
         cfg_target_thread_local,
         cfg_target_vendor,
         clone,
+        Clone,
         clone_closures,
         clone_from,
         closure_to_fn_coercion,
+        cmp,
         cmpxchg16b_target_feature,
         cold,
         compile_error,
@@ -199,11 +209,14 @@ symbols! {
         custom_test_frameworks,
         c_variadic,
         decl_macro,
+        Default,
         default_lib_allocator,
         default_type_parameter_fallback,
         default_type_params,
         deny,
         deprecated,
+        deref,
+        deref_mut,
         derive,
         doc,
         doc_alias,
@@ -231,6 +244,7 @@ symbols! {
         enable,
         err,
         Err,
+        Equal,
         except,
         exclusive_range_pattern,
         exhaustive_integer_patterns,
@@ -238,6 +252,7 @@ symbols! {
         existential_type,
         expected,
         export_name,
+        expr,
         extern_absolute_paths,
         external_doc,
         extern_crate_item_prelude,
@@ -250,8 +265,11 @@ symbols! {
         f64,
         feature,
         ffi_returns_twice,
+        field,
         field_init_shorthand,
         file,
+        fmt,
+        fmt_internals,
         fn_must_use,
         forbid,
         format_args_nl,
@@ -260,6 +278,7 @@ symbols! {
         from_error,
         from_generator,
         from_ok,
+        from_usize,
         fundamental,
         future,
         Future,
@@ -270,6 +289,8 @@ symbols! {
         global_allocator,
         global_asm,
         globs,
+        hash,
+        Hash,
         hexagon_target_feature,
         hidden,
         homogeneous_aggregate,
@@ -291,6 +312,8 @@ symbols! {
         impl_header_lifetime_elision,
         impl_trait_in_bindings,
         import_shadowing,
+        index,
+        index_mut,
         in_band_lifetimes,
         include,
         inclusive_range_syntax,
@@ -307,6 +330,7 @@ symbols! {
         issue,
         issue_5723_bootstrap,
         issue_tracker_base_url,
+        item,
         item_like_imports,
         iter,
         Iterator,
@@ -317,6 +341,7 @@ symbols! {
         lang,
         lang_items,
         lib,
+        lifetime,
         link,
         linkage,
         link_args,
@@ -325,6 +350,7 @@ symbols! {
         link_name,
         link_section,
         lint_reasons,
+        literal,
         local_inner_macros,
         log_syntax,
         loop_break_value,
@@ -364,6 +390,7 @@ symbols! {
         negate_unsigned,
         never,
         never_type,
+        new,
         next,
         __next,
         nll,
@@ -398,14 +425,21 @@ symbols! {
         option,
         Option,
         opt_out_copy,
+        or,
+        Ord,
+        Ordering,
         Output,
         overlapping_marker_traits,
         packed,
+        panic,
         panic_handler,
         panic_impl,
         panic_implementation,
         panic_runtime,
+        partial_cmp,
+        PartialOrd,
         passes,
+        pat,
         path,
         pattern_parentheses,
         Pending,
@@ -426,6 +460,7 @@ symbols! {
         proc_dash_macro: "proc-macro",
         proc_macro,
         proc_macro_attribute,
+        proc_macro_def_site,
         proc_macro_derive,
         proc_macro_expr,
         proc_macro_gen,
@@ -464,6 +499,7 @@ symbols! {
         Result,
         Return,
         rlib,
+        rt,
         rtm_target_feature,
         rust,
         rust_2015_preview,
@@ -547,6 +583,7 @@ symbols! {
         static_recursion,
         std,
         str,
+        stmt,
         stmt_expr_attributes,
         stop_after_dataflow,
         struct_field_attributes,
@@ -564,8 +601,10 @@ symbols! {
         test,
         test_2018_feature,
         test_accepted_feature,
+        test_case,
         test_removed_feature,
         test_runner,
+        then_with,
         thread_local,
         tool_attributes,
         tool_lints,
@@ -577,6 +616,7 @@ symbols! {
         Try,
         try_blocks,
         try_trait,
+        tt,
         tuple_indexing,
         ty,
         type_alias_enum_variants,
@@ -605,12 +645,15 @@ symbols! {
         untagged_unions,
         unwind,
         unwind_attributes,
+        unwrap_or,
         used,
         use_extern_macros,
         use_nested_groups,
         usize,
         v1,
         val,
+        vec,
+        Vec,
         vis,
         visible_private_types,
         volatile,
@@ -935,8 +978,21 @@ pub mod kw {
 
 // This module has a very short name because it's used a lot.
 pub mod sym {
+    use std::convert::TryInto;
     use super::Symbol;
+
     symbols!();
+
+    // Get the symbol for an integer. The first few non-negative integers each
+    // have a static symbol and therefore are fast.
+    pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol {
+        if let Result::Ok(idx) = n.try_into() {
+            if let Option::Some(&sym) = digits_array.get(idx) {
+                return sym;
+            }
+        }
+        Symbol::intern(&n.to_string())
+    }
 }
 
 impl Symbol {